-
Notifications
You must be signed in to change notification settings - Fork 3
/
ssh.go
89 lines (80 loc) · 1.9 KB
/
ssh.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package git
import (
"context"
"fmt"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
"github.com/charmbracelet/ssh"
"github.com/charmbracelet/wish"
)
func authHandler(pr *PrCmd) func(ctx ssh.Context, key ssh.PublicKey) bool {
return func(ctx ssh.Context, key ssh.PublicKey) bool {
pubkey := pr.Backend.Pubkey(key)
userName := ctx.User()
err := pr.IsBanned(pubkey, userName)
if err != nil {
pr.Backend.Logger.Info(
"user denied access",
"err", err,
"username", userName,
"pubkey", pubkey,
)
return false
}
return true
}
}
func GitSshServer(cfg *GitCfg, killCh chan error) {
dbpath := filepath.Join(cfg.DataDir, "pr.db?_fk=on")
dbh, err := SqliteOpen("file:"+dbpath, cfg.Logger)
if err != nil {
panic(fmt.Sprintf("cannot find database file, check folder and perms: %s: %s", dbpath, err))
}
be := &Backend{
DB: dbh,
Logger: cfg.Logger,
Cfg: cfg,
}
prCmd := &PrCmd{
Backend: be,
}
s, err := wish.NewServer(
wish.WithAddress(
fmt.Sprintf("%s:%s", cfg.Host, cfg.SshPort),
),
wish.WithHostKeyPath(
filepath.Join(cfg.DataDir, "term_info_ed25519"),
),
wish.WithPublicKeyAuth(authHandler(prCmd)),
wish.WithMiddleware(
GitPatchRequestMiddleware(be, prCmd),
),
)
if err != nil {
cfg.Logger.Error("could not create server", "err", err)
return
}
done := make(chan os.Signal, 1)
signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
cfg.Logger.Info("starting SSH server", "host", cfg.Host, "port", cfg.SshPort)
go func() {
if err = s.ListenAndServe(); err != nil {
cfg.Logger.Error("serve error", "err", err)
// os.Exit(1)
}
}()
select {
case <-done:
case <-killCh:
}
cfg.Logger.Info("stopping SSH server")
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer func() { cancel() }()
if err := s.Shutdown(ctx); err != nil {
cfg.Logger.Error("shutdown", "err", err)
// os.Exit(1)
}
}