Diff
1diff --git a/main.go b/main.go
2index c36ff2a90ee21008d65c8f55d22e1b214b59d918..34c7c444bfef7f505bab53c414e76f5c83ffe084 100644
3--- a/main.go
4+++ b/main.go
5@@ -13,9 +13,10 @@ import (
6 )
7
8 type Config struct {
9- Port int `env:"SMOOTHIE_PORT" default:"23231"`
10- KeyPath string `env:"SMOOTHIE_KEY_PATH" default:".ssh/smoothie_server_ed25519"`
11- RepoPath string `env:"SMOOTHIE_REPO_PATH" default:".repos"`
12+ Port int `env:"SMOOTHIE_PORT" default:"23231"`
13+ KeyPath string `env:"SMOOTHIE_KEY_PATH" default:".ssh/smoothie_server_ed25519"`
14+ RepoAuthPath string `env:"SMOOTHIE_KEY_PATH" default:".ssh/smoothie_git_authorized_keys"`
15+ RepoPath string `env:"SMOOTHIE_REPO_PATH" default:".repos"`
16 }
17
18 func main() {
19@@ -28,7 +29,7 @@ func main() {
20 cfg.Port,
21 cfg.KeyPath,
22 bm.Middleware(tui.SessionHandler, tea.WithAltScreen()),
23- gm.Middleware(cfg.RepoPath),
24+ gm.Middleware(cfg.RepoPath, cfg.RepoAuthPath),
25 lm.Middleware(),
26 )
27 if err != nil {
28diff --git a/server/middleware/git/git.go b/server/middleware/git/git.go
29index 33ef2f0c32a2c626ce117b179ce91f86ae7173a8..d098a62bb6a1bd4d68da089fc2a3e2888f96b755 100644
30--- a/server/middleware/git/git.go
31+++ b/server/middleware/git/git.go
32@@ -1,8 +1,10 @@
33 package git
34
35 import (
36+ "bufio"
37 "context"
38 "fmt"
39+ "log"
40 "os"
41 "os/exec"
42 "smoothie/server/middleware"
43@@ -10,13 +12,50 @@ import (
44 "github.com/gliderlabs/ssh"
45 )
46
47-func Middleware(repoDir string) middleware.Middleware {
48+func Middleware(repoDir string, authorizedKeysPath string) middleware.Middleware {
49+ authedKeys := make([]ssh.PublicKey, 0)
50+ hasAuth, err := fileExists(authorizedKeysPath)
51+ if err != nil {
52+ log.Fatal(err)
53+ }
54+ if hasAuth {
55+ f, err := os.Open(authorizedKeysPath)
56+ if err != nil {
57+ log.Fatal(err)
58+ }
59+ defer f.Close()
60+ scanner := bufio.NewScanner(f)
61+ for scanner.Scan() {
62+ pt := scanner.Text()
63+ log.Printf("Adding authorized key: %s", pt)
64+ pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pt))
65+ if err != nil {
66+ log.Fatal(err)
67+ }
68+ authedKeys = append(authedKeys, pk)
69+ }
70+ if err := scanner.Err(); err != nil {
71+ log.Fatal(err)
72+ }
73+ }
74 return func(sh ssh.Handler) ssh.Handler {
75 return func(s ssh.Session) {
76 cmd := s.Command()
77 if len(cmd) == 2 {
78 switch cmd[0] {
79- case "git-upload-pack", "git-receive-pack", "git-upload-archive":
80+ case "git-upload-pack", "git-upload-archive", "git-receive-pack":
81+ if hasAuth && cmd[0] == "git-receive-pack" {
82+ authed := false
83+ for _, pk := range authedKeys {
84+ if ssh.KeysEqual(pk, s.PublicKey()) {
85+ authed = true
86+ }
87+ }
88+ if !authed {
89+ fatalGit(s, fmt.Errorf("you are not authorized to do this"))
90+ break
91+ }
92+ }
93 r := cmd[1]
94 rp := fmt.Sprintf("%s%s", repoDir, r)
95 ctx := s.Context()