Detailed changes
@@ -8,14 +8,14 @@ replace github.com/charmbracelet/bubbletea => ../bubbletea
require (
github.com/charmbracelet/bubbles v0.8.0
- github.com/charmbracelet/bubbletea v0.14.0
- github.com/charmbracelet/charm v0.8.6
+ github.com/charmbracelet/bubbletea v0.14.1
github.com/charmbracelet/glamour v0.3.0
github.com/charmbracelet/lipgloss v0.3.0
+ github.com/charmbracelet/wish v0.0.0-20210816211645-088e4d8b1b04
github.com/dustin/go-humanize v1.0.0
github.com/gliderlabs/ssh v0.3.3
github.com/go-git/go-git/v5 v5.4.2
github.com/meowgorithm/babyenv v1.3.0
github.com/muesli/termenv v0.8.1
- golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
+ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
)
@@ -32,18 +32,23 @@ github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuP
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/calmh/randomart v1.1.0 h1:evl+iwc10LXtHdMZhzLxmsCQVmWnkXs44SbC6Uk0Il8=
github.com/calmh/randomart v1.1.0/go.mod h1:DQUbPVyP+7PAs21w/AnfMKG5NioxS3TbZ2F9MSK/jFM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/charmbracelet/bubbles v0.7.5/go.mod h1:IRTORFvhEI6OUH7WhN2Ks8Z8miNGimk1BE6cmHijOkM=
github.com/charmbracelet/bubbles v0.8.0 h1:+l2op90Ag37Vn+30O1hbg/0wBl+e+sxHhgY1F/rvdHs=
github.com/charmbracelet/bubbles v0.8.0/go.mod h1:5WX1sSSjNCgCrzvRMN/z23HxvWaa+AI16Ch0KPZPeDs=
+github.com/charmbracelet/charm v0.8.6 h1:/U6rxGj4J6zZ1Ex8+wTr4hNMr4ESBzNZbC1UyrJPVbg=
+github.com/charmbracelet/charm v0.8.6/go.mod h1:8dE3uX+TYSpa7Q6e/CmjN6WSd7koSAKNQTGWugFREx4=
github.com/charmbracelet/glamour v0.3.0 h1:3H+ZrKlSg8s+WU6V7eF2eRVYt8lCueffbi7r2+ffGkc=
github.com/charmbracelet/glamour v0.3.0/go.mod h1:TzF0koPZhqq0YVBNL100cPHznAAjVj7fksX2RInwjGw=
github.com/charmbracelet/lipgloss v0.1.2/go.mod h1:5D8zradw52m7QmxRF6QgwbwJi9je84g8MkWiGN07uKg=
-github.com/charmbracelet/lipgloss v0.2.1 h1:knjqLRtlcDsxss6i0CUhNLuXrNW3TQhFDXlXII2UaZA=
github.com/charmbracelet/lipgloss v0.2.1/go.mod h1:uiZUfrHLQN14I0lJ5591WtcHyY1X76pOIPSaRKPY6dE=
github.com/charmbracelet/lipgloss v0.3.0 h1:5MysOD6sHr4RP4jkZNWGVIul5GKoOsP12NgbgXPvAlA=
github.com/charmbracelet/lipgloss v0.3.0/go.mod h1:VkhdBS2eNAmRkTwRKLJCFhCOVkjntMusBDxv7TXahuk=
+github.com/charmbracelet/wish v0.0.0-20210816211645-088e4d8b1b04 h1:0jw7kvrrhf3a+GSD1AQwQCPxU4GIQL3jsK5nDrcXsXI=
+github.com/charmbracelet/wish v0.0.0-20210816211645-088e4d8b1b04/go.mod h1:vhGzR3x3nG4Rb9Msb5rZJ8zu81nhEOKdXqHveyAPr+U=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
github.com/containerd/console v1.0.2 h1:Pi6D+aZXM+oUw1czuKgH5IJ+y0jhYcwBJfx5/Ghn9dE=
@@ -65,6 +70,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgraph-io/badger/v3 v3.2011.1/go.mod h1:0rLLrQpKVQAL0or/lBLMQznhr6dWWX7h5AKnmnqx268=
github.com/dgraph-io/ristretto v0.0.4-0.20210122082011-bb5d392ed82d/go.mod h1:tv2ec8nA7vRpSYX7/MbP52ihrUMXIHit54CQMq8npXQ=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
@@ -120,13 +126,14 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/flatbuffers v1.12.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-dap v0.2.0/go.mod h1:5q8aYQFnHOAZEMP+6vmq25HKYAEwE+LF5yh7JKrrhSQ=
+github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -168,7 +175,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
@@ -179,9 +186,9 @@ github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
-github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
@@ -198,11 +205,15 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mmcloughlin/avo v0.0.0-20201105074841-5d2f697d268f/go.mod h1:6aKT4zZIrpGqB3RpFU14ByCSSyKY6LfJz4J/JJChHfI=
+github.com/muesli/go-app-paths v0.2.1 h1:Qi+2igkDX2aPqyRddp7P0sMQIBwBqhkfQfNcjdGjL6Y=
github.com/muesli/go-app-paths v0.2.1/go.mod h1:SxS3Umca63pcFcLtbjVb+J0oD7cl4ixQWoBKhGEtEho=
+github.com/muesli/reflow v0.1.0/go.mod h1:I9bWAt7QTg/que/qmUCJBGlj7wEq8OAFBjPNjc6xK4I=
github.com/muesli/reflow v0.2.0/go.mod h1:qT22vjVmM9MIUeLgsVYe/Ye7eZlbv9dZjL3dVhUqLX8=
github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 h1:y1p/ycavWjGT9FnmSjdbWUlLGvcxrY0Rw3ATltrxOhk=
github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ=
+github.com/muesli/sasquatch v0.0.0-20200811221207-66979d92330a h1:Hw/15RYEOUD6T9UCRkUmNBa33kJkH33Fui6hE4sRLKU=
github.com/muesli/sasquatch v0.0.0-20200811221207-66979d92330a/go.mod h1:+XG0ne5zXWBTSbbe7Z3/RWxaT8PZY6zaZ1dX6KjprYY=
+github.com/muesli/termenv v0.7.4/go.mod h1:pZ7qY9l3F7e5xsAOS0zCew2tME+p7bWeBkotCEcIIcc=
github.com/muesli/termenv v0.8.1 h1:9q230czSP3DHVpkaPDXGp0TOfAwyjyYwXlUCQxQSaBk=
github.com/muesli/termenv v0.8.1/go.mod h1:kzt/D/4a88RoheZmwfqorY3A+tnsSMA9HJC/fQSFKo0=
github.com/muesli/toktok v0.0.0-20201007181047-c74187025f3f/go.mod h1:FmV+MTLqgtVrOUfvwWxUZXyoiCGzYt8siG4BqrY4Mb8=
@@ -351,6 +362,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1,19 +1,22 @@
package main
import (
+ "fmt"
"log"
- "smoothie/server"
- bm "smoothie/server/middleware/bubbletea"
- gm "smoothie/server/middleware/git"
- lm "smoothie/server/middleware/logging"
"smoothie/tui"
"time"
+ "github.com/charmbracelet/wish"
+ bm "github.com/charmbracelet/wish/bubbletea"
+ gm "github.com/charmbracelet/wish/git"
+ lm "github.com/charmbracelet/wish/logging"
+
"github.com/meowgorithm/babyenv"
)
type Config struct {
Port int `env:"SMOOTHIE_PORT" default:"23231"`
+ Host string `env:"SMOOTHIE_HOST" default:""`
KeyPath string `env:"SMOOTHIE_KEY_PATH" default:".ssh/smoothie_server_ed25519"`
RepoAuth string `env:"SMOOTHIE_REPO_KEYS" default:""`
RepoAuthFile string `env:"SMOOTHIE_REPO_KEYS_PATH" default:".ssh/smoothie_git_authorized_keys"`
@@ -26,8 +29,8 @@ func main() {
if err != nil {
log.Fatalln(err)
}
- s, err := server.NewServer(
- cfg.Port,
+ s, err := wish.NewServer(
+ fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),
cfg.KeyPath,
bm.Middleware(tui.SessionHandler(cfg.RepoPath, time.Second*5)),
gm.Middleware(cfg.RepoPath, cfg.RepoAuth, cfg.RepoAuthFile),
@@ -36,7 +39,8 @@ func main() {
if err != nil {
log.Fatalln(err)
}
- err = s.Start()
+ log.Printf("Starting SSH server on %s:%d\n", cfg.Host, cfg.Port)
+ err = s.ListenAndServe()
if err != nil {
log.Fatalln(err)
}
@@ -1,24 +0,0 @@
-package bubbletea
-
-import (
- "smoothie/server/middleware"
-
- tea "github.com/charmbracelet/bubbletea"
- "github.com/gliderlabs/ssh"
-)
-
-type BubbleTeaHandler func(ssh.Session) (tea.Model, []tea.ProgramOption)
-
-func Middleware(bth BubbleTeaHandler) middleware.Middleware {
- return func(sh ssh.Handler) ssh.Handler {
- return func(s ssh.Session) {
- m, opts := bth(s)
- if m != nil {
- opts = append(opts, tea.WithInput(s), tea.WithOutput(s))
- p := tea.NewProgram(m, opts...)
- _ = p.Start()
- }
- sh(s)
- }
- }
-}
@@ -1,170 +0,0 @@
-package git
-
-import (
- "bufio"
- "context"
- "fmt"
- "log"
- "os"
- "os/exec"
- "smoothie/server/middleware"
- "strings"
-
- "github.com/gliderlabs/ssh"
-)
-
-func gitMiddleware(repoDir string, authedKeys []ssh.PublicKey) middleware.Middleware {
- return func(sh ssh.Handler) ssh.Handler {
- return func(s ssh.Session) {
- cmd := s.Command()
- if len(cmd) == 2 {
- switch cmd[0] {
- case "git-upload-pack", "git-upload-archive", "git-receive-pack":
- if len(authedKeys) > 0 && cmd[0] == "git-receive-pack" {
- authed := false
- for _, pk := range authedKeys {
- if ssh.KeysEqual(pk, s.PublicKey()) {
- authed = true
- }
- }
- if !authed {
- fatalGit(s, fmt.Errorf("you are not authorized to do this"))
- break
- }
- }
- r := cmd[1]
- rp := fmt.Sprintf("%s%s", repoDir, r)
- ctx := s.Context()
- err := ensureRepo(ctx, repoDir, r)
- if err != nil {
- fatalGit(s, err)
- break
- }
- c := exec.CommandContext(ctx, cmd[0], rp)
- c.Dir = "./"
- c.Stdout = s
- c.Stdin = s
- err = c.Run()
- if err != nil {
- fatalGit(s, err)
- break
- }
- }
- }
- sh(s)
- }
- }
-}
-
-func Middleware(repoDir, authorizedKeys, authorizedKeysFile string) middleware.Middleware {
- ak1, err := parseKeysFromString(authorizedKeys)
- if err != nil {
- log.Fatal(err)
- }
- ak2, err := parseKeysFromFile(authorizedKeysFile)
- if err != nil {
- log.Fatal(err)
- }
- authedKeys := append(ak1, ak2...)
- return gitMiddleware(repoDir, authedKeys)
-}
-
-func MiddlewareWithKeys(repoDir, authorizedKeys string) middleware.Middleware {
- return Middleware(repoDir, authorizedKeys, "")
-}
-
-func MiddlewareWithKeyPath(repoDir, authorizedKeysFile string) middleware.Middleware {
- return Middleware(repoDir, "", authorizedKeysFile)
-}
-
-func parseKeysFromFile(path string) ([]ssh.PublicKey, error) {
- authedKeys := make([]ssh.PublicKey, 0)
- hasAuth, err := fileExists(path)
- if err != nil {
- return nil, err
- }
- if hasAuth {
- f, err := os.Open(path)
- if err != nil {
- log.Fatal(err)
- }
- defer f.Close()
- scanner := bufio.NewScanner(f)
- err = addKeys(scanner, &authedKeys)
- if err != nil {
- return nil, err
- }
- }
- return authedKeys, nil
-}
-
-func parseKeysFromString(keys string) ([]ssh.PublicKey, error) {
- authedKeys := make([]ssh.PublicKey, 0)
- scanner := bufio.NewScanner(strings.NewReader(keys))
- err := addKeys(scanner, &authedKeys)
- if err != nil {
- return nil, err
- }
- return authedKeys, nil
-}
-
-func addKeys(s *bufio.Scanner, keys *[]ssh.PublicKey) error {
- for s.Scan() {
- pt := s.Text()
- log.Printf("Adding authorized key: %s", pt)
- pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pt))
- if err != nil {
- return err
- }
- *keys = append(*keys, pk)
- }
- if err := s.Err(); err != nil {
- return err
- }
- return nil
-}
-
-func fileExists(path string) (bool, error) {
- _, err := os.Stat(path)
- if err == nil {
- return true, nil
- }
- if os.IsNotExist(err) {
- return false, nil
- }
- return true, err
-}
-
-func fatalGit(s ssh.Session, err error) {
- // hex length includes 4 byte length prefix and ending newline
- msg := err.Error()
- pktLine := fmt.Sprintf("%04x%s\n", len(msg)+5, msg)
- _, _ = s.Write([]byte(pktLine))
- s.Exit(1)
-}
-
-func ensureRepo(ctx context.Context, dir string, repo string) error {
- exists, err := fileExists(dir)
- if err != nil {
- return err
- }
- if !exists {
- err = os.MkdirAll(dir, os.ModeDir|os.FileMode(0700))
- if err != nil {
- return err
- }
- }
- rp := fmt.Sprintf("%s%s", dir, repo)
- exists, err = fileExists(rp)
- if err != nil {
- return err
- }
- if !exists {
- c := exec.CommandContext(ctx, "git", "init", "--bare", rp)
- err = c.Run()
- if err != nil {
- return err
- }
- }
- return nil
-}
@@ -1,20 +0,0 @@
-package logging
-
-import (
- "log"
- "smoothie/server/middleware"
-
- "github.com/gliderlabs/ssh"
-)
-
-func Middleware() middleware.Middleware {
- return func(sh ssh.Handler) ssh.Handler {
- return func(s ssh.Session) {
- hpk := s.PublicKey() != nil
- pty, _, _ := s.Pty()
- log.Printf("%s connect %v %v %s %v %v\n", s.RemoteAddr().String(), hpk, s.Command(), pty.Term, pty.Window.Width, pty.Window.Height)
- sh(s)
- log.Printf("%s disconnect\n", s.RemoteAddr().String())
- }
- }
-}
@@ -1,5 +0,0 @@
-package middleware
-
-import "github.com/gliderlabs/ssh"
-
-type Middleware func(ssh.Handler) ssh.Handler
@@ -1,57 +0,0 @@
-package server
-
-import (
- "fmt"
- "log"
- "path/filepath"
- "smoothie/server/middleware"
- "strings"
-
- "github.com/charmbracelet/charm/keygen"
- "github.com/gliderlabs/ssh"
- gossh "golang.org/x/crypto/ssh"
-)
-
-type Server struct {
- server *ssh.Server
- key gossh.PublicKey
-}
-
-func NewServer(port int, keyPath string, mw ...middleware.Middleware) (*Server, error) {
- s := &Server{server: &ssh.Server{}}
- s.server.Version = "OpenSSH_7.6p1"
- s.server.Addr = fmt.Sprintf(":%d", port)
- s.server.PasswordHandler = s.passHandler
- s.server.PublicKeyHandler = s.authHandler
- kps := strings.Split(keyPath, string(filepath.Separator))
- kp := strings.Join(kps[:len(kps)-1], string(filepath.Separator))
- n := strings.TrimRight(kps[len(kps)-1], "_ed25519")
- _, err := keygen.NewSSHKeyPair(kp, n, nil, "ed25519")
- if err != nil {
- return nil, err
- }
- k := ssh.HostKeyFile(keyPath)
- err = s.server.SetOption(k)
- if err != nil {
- return nil, err
- }
- h := func(s ssh.Session) {}
- for _, m := range mw {
- h = m(h)
- }
- s.server.Handler = h
- return s, nil
-}
-
-func (srv *Server) authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
- return true
-}
-
-func (srv *Server) passHandler(ctx ssh.Context, pass string) bool {
- return true
-}
-
-func (srv *Server) Start() error {
- log.Printf("Starting SSH server on %s\n", srv.server.Addr)
- return srv.server.ListenAndServe()
-}