From a2cf7867b95a722993441586ef56fa3dc0691291 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Fri, 2 Aug 2024 16:40:02 -0400 Subject: [PATCH] fix: respect anon-access on ssh This will also allow access to anonymous user connections with public-keys Fixes: https://github.com/charmbracelet/soft-serve/issues/524 --- pkg/backend/user.go | 4 ++++ pkg/ssh/ssh.go | 18 +++++++-------- testscript/script_test.go | 7 +++--- testscript/testdata/anon-access.txtar | 33 +++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 testscript/testdata/anon-access.txtar diff --git a/pkg/backend/user.go b/pkg/backend/user.go index 75423048d..4ad846c26 100644 --- a/pkg/backend/user.go +++ b/pkg/backend/user.go @@ -84,6 +84,10 @@ func (d *Backend) AccessLevelForUser(ctx context.Context, repo string, user prot } // Otherwise, the user has read-only access. + if user == nil { + return anon + } + return access.ReadOnlyAccess } diff --git a/pkg/ssh/ssh.go b/pkg/ssh/ssh.go index 54d30dcae..f63b0d389 100644 --- a/pkg/ssh/ssh.go +++ b/pkg/ssh/ssh.go @@ -171,6 +171,7 @@ func (s *SSHServer) PublicKeyHandler(ctx ssh.Context, pk ssh.PublicKey) (allowed return false } + allowed = true defer func(allowed *bool) { publicKeyCounter.WithLabelValues(strconv.FormatBool(*allowed)).Inc() }(&allowed) @@ -178,17 +179,16 @@ func (s *SSHServer) PublicKeyHandler(ctx ssh.Context, pk ssh.PublicKey) (allowed user, _ := s.be.UserByPublicKey(ctx, pk) if user != nil { ctx.SetValue(proto.ContextKeyUser, user) - allowed = true + } - // XXX: store the first "approved" public-key fingerprint in the - // permissions block to use for authentication later. - initializePermissions(ctx) - perms := ctx.Permissions() + // XXX: store the first "approved" public-key fingerprint in the + // permissions block to use for authentication later. + initializePermissions(ctx) + perms := ctx.Permissions() - // Set the public key fingerprint to be used for authentication. - perms.Extensions["pubkey-fp"] = gossh.FingerprintSHA256(pk) - ctx.SetValue(ssh.ContextKeyPermissions, perms) - } + // Set the public key fingerprint to be used for authentication. + perms.Extensions["pubkey-fp"] = gossh.FingerprintSHA256(pk) + ctx.SetValue(ssh.ContextKeyPermissions, perms) return } diff --git a/testscript/script_test.go b/testscript/script_test.go index 9b4b38b28..43fdde900 100644 --- a/testscript/script_test.go +++ b/testscript/script_test.go @@ -70,9 +70,9 @@ func TestScript(t *testing.T) { return path, pair } - key, admin1 := mkkey("admin1") + admin1Key, admin1 := mkkey("admin1") _, admin2 := mkkey("admin2") - _, user1 := mkkey("user1") + user1Key, user1 := mkkey("user1") testscript.Run(t, testscript.Params{ Dir: "./testdata/", @@ -81,7 +81,8 @@ func TestScript(t *testing.T) { Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){ "soft": cmdSoft("admin", admin1.Signer()), "usoft": cmdSoft("user1", user1.Signer()), - "git": cmdGit(key), + "git": cmdGit(admin1Key), + "ugit": cmdGit(user1Key), "curl": cmdCurl, "mkfile": cmdMkfile, "envfile": cmdEnvfile, diff --git a/testscript/testdata/anon-access.txtar b/testscript/testdata/anon-access.txtar new file mode 100644 index 000000000..54958fa11 --- /dev/null +++ b/testscript/testdata/anon-access.txtar @@ -0,0 +1,33 @@ +# vi: set ft=conf + +# start soft serve +exec soft serve & +# wait for server to start +waitforserver + +# set settings +soft settings allow-keyless true +soft settings anon-access no-access + +# create a repo +soft repo create repo1 +git clone ssh://localhost:$SSH_PORT/repo1 repo1 +mkfile ./repo1/README.md '# Hello\n\nwelcome' +git -C repo1 add -A +git -C repo1 commit -m 'first' +git -C repo1 push origin HEAD + +# access repo from anon +! ugit clone ssh://localhost:$SSH_PORT/repo1 urepo1 +stderr 'Error: you are not authorized to do this' + +# list repo as anon +usoft repo list +stdout '' + +# create repo as anon +! usoft repo create urepo2 +stderr 'Error: unauthorized' + +# stop the server +[windows] stopserver