fd13d1e2cab7ae131e7d3a5db1c0cfb62aa2527e

Author
Ayman Bagabas <ayman.bagabas@gmail.com>
Committer
Ayman Bagabas <ayman.bagabas@gmail.com>
Date

Message

fix(server): internal key should have admin access

Diff

  1diff --git a/server/backend/sqlite/sqlite.go b/server/backend/sqlite/sqlite.go
  2index 1d07652d26b218a656a531115251abb962528d92..7ee17dfc404247f8f47ad856fa6e01cfb69484fb 100644
  3--- a/server/backend/sqlite/sqlite.go
  4+++ b/server/backend/sqlite/sqlite.go
  5@@ -26,10 +26,9 @@ var (
  6 // SqliteBackend is a backend that uses a SQLite database as a Soft Serve
  7 // backend.
  8 type SqliteBackend struct {
  9-	cfg              *config.Config
 10-	dp               string
 11-	db               *sqlx.DB
 12-	AdditionalAdmins []string
 13+	cfg *config.Config
 14+	dp  string
 15+	db  *sqlx.DB
 16 }
 17 
 18 var _ backend.Backend = (*SqliteBackend)(nil)
 19diff --git a/server/backend/sqlite/user.go b/server/backend/sqlite/user.go
 20index 068c85a3a2b39251b069696c3505eaca4b2659a8..0e3c609caf9b9f4ed131dc181124d49ed9e2d50a 100644
 21--- a/server/backend/sqlite/user.go
 22+++ b/server/backend/sqlite/user.go
 23@@ -120,7 +120,10 @@ func (d *SqliteBackend) AccessLevel(repo string, username string) backend.Access
 24 // It implements backend.Backend.
 25 func (d *SqliteBackend) AccessLevelByPublicKey(repo string, pk ssh.PublicKey) backend.AccessLevel {
 26 	ak := backend.MarshalAuthorizedKey(pk)
 27-	for _, k := range d.AdditionalAdmins {
 28+	if strings.HasPrefix(d.cfg.InternalPublicKey, ak) {
 29+		return backend.AdminAccess
 30+	}
 31+	for _, k := range d.cfg.InitialAdminKeys {
 32 		if k == ak {
 33 			return backend.AdminAccess
 34 		}
 35diff --git a/server/config/config.go b/server/config/config.go
 36index 79ab416df3d5ccc962d3d1f4e5d9d5d1bc0f52df..b0112d93b8b53d1bfa90a59a1d57de1bab559a0f 100644
 37--- a/server/config/config.go
 38+++ b/server/config/config.go
 39@@ -95,6 +95,12 @@ type Config struct {
 40 
 41 	// Backend is the Git backend to use.
 42 	Backend backend.Backend `yaml:"-"`
 43+
 44+	// InternalPublicKey is the public key of the internal SSH key.
 45+	InternalPublicKey string `yaml:"-"`
 46+
 47+	// ClientPublicKey is the public key of the client SSH key.
 48+	ClientPublicKey string `yaml:"-"`
 49 }
 50 
 51 // ParseConfig parses the configuration from the given file.
 52diff --git a/server/server.go b/server/server.go
 53index 992e0c7c13c0a656afd08a3c764481fe393d9b5a..beee1fa744ecc660e0274d5858750ef1e26aa945 100644
 54--- a/server/server.go
 55+++ b/server/server.go
 56@@ -45,12 +45,10 @@ func NewServer(cfg *config.Config) (*Server, error) {
 57 			logger.Fatal(err)
 58 		}
 59 
 60-		// Add the initial admin keys to the list of admins.
 61-		sb.AdditionalAdmins = cfg.InitialAdminKeys
 62 		cfg = cfg.WithBackend(sb)
 63 
 64 		// Create internal key.
 65-		_, err = keygen.NewWithWrite(
 66+		ikp, err := keygen.NewWithWrite(
 67 			filepath.Join(cfg.DataPath, cfg.SSH.InternalKeyPath),
 68 			nil,
 69 			keygen.Ed25519,
 70@@ -58,9 +56,10 @@ func NewServer(cfg *config.Config) (*Server, error) {
 71 		if err != nil {
 72 			return nil, err
 73 		}
 74+		cfg.InternalPublicKey = string(ikp.PublicKey())
 75 
 76 		// Create client key.
 77-		_, err = keygen.NewWithWrite(
 78+		ckp, err := keygen.NewWithWrite(
 79 			filepath.Join(cfg.DataPath, cfg.SSH.ClientKeyPath),
 80 			nil,
 81 			keygen.Ed25519,
 82@@ -68,6 +67,7 @@ func NewServer(cfg *config.Config) (*Server, error) {
 83 		if err != nil {
 84 			return nil, err
 85 		}
 86+		cfg.ClientPublicKey = string(ckp.PublicKey())
 87 	}
 88 
 89 	srv := &Server{
 90diff --git a/server/ssh.go b/server/ssh.go
 91index 9f6da44cfe8005f27db0ab4da3b97dda2a7e80f8..30ea8e498c24245a116733f7d6ca21280a30c6dd 100644
 92--- a/server/ssh.go
 93+++ b/server/ssh.go
 94@@ -148,13 +148,9 @@ func (s *SSHServer) PublicKeyHandler(ctx ssh.Context, pk ssh.PublicKey) (allowed
 95 		}
 96 	}
 97 
 98-	user, _ := s.cfg.Backend.UserByPublicKey(pk)
 99-	if user == nil {
100-		logger.Debug("public key auth user not found")
101-		return s.cfg.Backend.AnonAccess() >= backend.ReadOnlyAccess
102-	}
103-
104-	allowed = s.cfg.Backend.AccessLevel("", user.Username()) >= backend.ReadOnlyAccess
105+	ac := s.cfg.Backend.AccessLevelByPublicKey("", pk)
106+	logger.Debugf("access level for %s: %d", ak, ac)
107+	allowed = ac >= backend.ReadOnlyAccess
108 	return
109 }
110 
111@@ -191,6 +187,7 @@ func (s *SSHServer) Middleware(cfg *config.Config) wish.Middleware {
112 						return
113 					}
114 
115+					logger.Debug("git middleware", "cmd", gc, "access", access.String())
116 					repoDir := filepath.Join(reposDir, repo)
117 					switch gc {
118 					case receivePackBin: