diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-08 09:32:13 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-08 09:32:13 +0200 |
| commit | 91b83a9ffcabf7264888cf84b95f08b8cc88c832 (patch) | |
| tree | 009b7bded9db99dcb02e3a55314c4b624304bdba /internal/ssh/server | |
| parent | 2007054d77b5bc40c943a9fd64874e850c750f2d (diff) | |
task: scope auth key dependencies to server instances (task 375)
Diffstat (limited to 'internal/ssh/server')
| -rw-r--r-- | internal/ssh/server/publickeycallback.go | 48 | ||||
| -rw-r--r-- | internal/ssh/server/publickeycallback_test.go | 8 |
2 files changed, 42 insertions, 14 deletions
diff --git a/internal/ssh/server/publickeycallback.go b/internal/ssh/server/publickeycallback.go index c4624f4..ccf9111 100644 --- a/internal/ssh/server/publickeycallback.go +++ b/internal/ssh/server/publickeycallback.go @@ -17,20 +17,44 @@ import ( func PublicKeyCallback(c gossh.ConnMetadata, offeredPubKey gossh.PublicKey) (*gossh.Permissions, error) { + authKeyEnabled := config.Server != nil && config.Server.AuthKeyEnabled + cacheDir := "" + if config.Common != nil { + cacheDir = config.Common.CacheDir + } + return publicKeyCallback(c, offeredPubKey, authKeyEnabled, cacheDir, authKeyStore) +} + +// NewPublicKeyCallback creates an instance-scoped SSH public key callback. +// It avoids relying on package-level mutable configuration/state. +func NewPublicKeyCallback(authKeyEnabled bool, cacheDir string, + keyStore *AuthKeyStore) func(gossh.ConnMetadata, gossh.PublicKey) (*gossh.Permissions, error) { + + if keyStore == nil { + keyStore = authKeyStore + } + return func(c gossh.ConnMetadata, offeredPubKey gossh.PublicKey) (*gossh.Permissions, error) { + return publicKeyCallback(c, offeredPubKey, authKeyEnabled, cacheDir, keyStore) + } +} + +func publicKeyCallback(c gossh.ConnMetadata, offeredPubKey gossh.PublicKey, + authKeyEnabled bool, cacheDir string, keyStore *AuthKeyStore) (*gossh.Permissions, error) { + user, err := user.New(c.User(), c.RemoteAddr().String()) if err != nil { return nil, err } dlog.Server.Info(user, "Incoming authorization") - if config.Server != nil && config.Server.AuthKeyEnabled { - if permissions := authKeyStorePermissions(user.Name, offeredPubKey); permissions != nil { + if authKeyEnabled { + if permissions := authKeyStorePermissions(keyStore, user.Name, offeredPubKey); permissions != nil { dlog.Server.Info(user, "Authorized by in-memory auth key store") return permissions, nil } } - authorizedKeysFile, err := authorizedKeysFile(user) + authorizedKeysFile, err := authorizedKeysFile(user, cacheDir) if err != nil { return nil, err } @@ -69,8 +93,10 @@ func verifyAuthorizedKeys(user *user.User, authorizedKeysBytes []byte, return nil, fmt.Errorf("%s|public key of user not authorized", user) } -func authKeyStorePermissions(userName string, offeredPubKey gossh.PublicKey) *gossh.Permissions { - if !authKeyStore.Has(userName, offeredPubKey) { +func authKeyStorePermissions(keyStore *AuthKeyStore, userName string, + offeredPubKey gossh.PublicKey) *gossh.Permissions { + + if keyStore == nil || !keyStore.Has(userName, offeredPubKey) { return nil } @@ -83,7 +109,7 @@ func permissionsFromPublicKey(offeredPubKey gossh.PublicKey) *gossh.Permissions } } -func authorizedKeysFile(user *user.User) (string, error) { +func authorizedKeysFile(user *user.User, cacheDir string) (string, error) { if config.Env("DTAIL_INTEGRATION_TEST_RUN_MODE") { // In this case, we expect a pub key in the current directory. return "./id_rsa.pub", nil @@ -95,10 +121,12 @@ func authorizedKeysFile(user *user.User) (string, error) { } // Check for cached version in the dserver directory. - authorizedKeysFile := fmt.Sprintf("%s/%s/%s.authorized_keys", cwd, - config.Common.CacheDir, user.Name) - if _, err = os.Stat(authorizedKeysFile); err == nil { - return authorizedKeysFile, nil + var authorizedKeysFile string + if cacheDir != "" { + authorizedKeysFile = fmt.Sprintf("%s/%s/%s.authorized_keys", cwd, cacheDir, user.Name) + if _, err = os.Stat(authorizedKeysFile); err == nil { + return authorizedKeysFile, nil + } } // As the last option, check the regular SSH path. diff --git a/internal/ssh/server/publickeycallback_test.go b/internal/ssh/server/publickeycallback_test.go index 7ded4f3..97baa72 100644 --- a/internal/ssh/server/publickeycallback_test.go +++ b/internal/ssh/server/publickeycallback_test.go @@ -16,13 +16,13 @@ func TestAuthKeyStorePermissions(t *testing.T) { key := testPublicKey(t, 21) - if permissions := authKeyStorePermissions("alice", key); permissions != nil { + if permissions := authKeyStorePermissions(authKeyStore, "alice", key); permissions != nil { t.Fatalf("Expected nil permissions when no key is cached") } authKeyStore.Add("alice", key) - permissions := authKeyStorePermissions("alice", key) + permissions := authKeyStorePermissions(authKeyStore, "alice", key) if permissions == nil { t.Fatalf("Expected permissions when key is cached") } @@ -30,12 +30,12 @@ func TestAuthKeyStorePermissions(t *testing.T) { t.Fatalf("Unexpected fingerprint: %s", fingerprint) } - if permissions := authKeyStorePermissions("bob", key); permissions != nil { + if permissions := authKeyStorePermissions(authKeyStore, "bob", key); permissions != nil { t.Fatalf("Expected nil permissions for different user") } unknownKey := testPublicKey(t, 22) - if permissions := authKeyStorePermissions("alice", unknownKey); permissions != nil { + if permissions := authKeyStorePermissions(authKeyStore, "alice", unknownKey); permissions != nil { t.Fatalf("Expected nil permissions for unknown key") } } |
