a2cf7867b95a722993441586ef56fa3dc0691291

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

Message

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

Diff

  1diff --git a/pkg/backend/user.go b/pkg/backend/user.go
  2index 75423048d681a84fcc656e4ba000d26aaab25a50..4ad846c263df2dd42840a937b69d1850051e614f 100644
  3--- a/pkg/backend/user.go
  4+++ b/pkg/backend/user.go
  5@@ -84,6 +84,10 @@ func (d *Backend) AccessLevelForUser(ctx context.Context, repo string, user prot
  6 		}
  7 
  8 		// Otherwise, the user has read-only access.
  9+		if user == nil {
 10+			return anon
 11+		}
 12+
 13 		return access.ReadOnlyAccess
 14 	}
 15 
 16diff --git a/pkg/ssh/ssh.go b/pkg/ssh/ssh.go
 17index 54d30dcaece82df2409895cead5a85e32e9294f3..f63b0d3897f53b95af494a99ee0a4dc00d872ddf 100644
 18--- a/pkg/ssh/ssh.go
 19+++ b/pkg/ssh/ssh.go
 20@@ -171,6 +171,7 @@ func (s *SSHServer) PublicKeyHandler(ctx ssh.Context, pk ssh.PublicKey) (allowed
 21 		return false
 22 	}
 23 
 24+	allowed = true
 25 	defer func(allowed *bool) {
 26 		publicKeyCounter.WithLabelValues(strconv.FormatBool(*allowed)).Inc()
 27 	}(&allowed)
 28@@ -178,17 +179,16 @@ func (s *SSHServer) PublicKeyHandler(ctx ssh.Context, pk ssh.PublicKey) (allowed
 29 	user, _ := s.be.UserByPublicKey(ctx, pk)
 30 	if user != nil {
 31 		ctx.SetValue(proto.ContextKeyUser, user)
 32-		allowed = true
 33+	}
 34 
 35-		// XXX: store the first "approved" public-key fingerprint in the
 36-		// permissions block to use for authentication later.
 37-		initializePermissions(ctx)
 38-		perms := ctx.Permissions()
 39+	// XXX: store the first "approved" public-key fingerprint in the
 40+	// permissions block to use for authentication later.
 41+	initializePermissions(ctx)
 42+	perms := ctx.Permissions()
 43 
 44-		// Set the public key fingerprint to be used for authentication.
 45-		perms.Extensions["pubkey-fp"] = gossh.FingerprintSHA256(pk)
 46-		ctx.SetValue(ssh.ContextKeyPermissions, perms)
 47-	}
 48+	// Set the public key fingerprint to be used for authentication.
 49+	perms.Extensions["pubkey-fp"] = gossh.FingerprintSHA256(pk)
 50+	ctx.SetValue(ssh.ContextKeyPermissions, perms)
 51 
 52 	return
 53 }
 54diff --git a/testscript/script_test.go b/testscript/script_test.go
 55index 9b4b38b28c57812411fbe7c81ff9cc30c688aa51..43fdde90015476a6a974e7e0cf7990b6ed98b076 100644
 56--- a/testscript/script_test.go
 57+++ b/testscript/script_test.go
 58@@ -70,9 +70,9 @@ func TestScript(t *testing.T) {
 59 		return path, pair
 60 	}
 61 
 62-	key, admin1 := mkkey("admin1")
 63+	admin1Key, admin1 := mkkey("admin1")
 64 	_, admin2 := mkkey("admin2")
 65-	_, user1 := mkkey("user1")
 66+	user1Key, user1 := mkkey("user1")
 67 
 68 	testscript.Run(t, testscript.Params{
 69 		Dir:                 "./testdata/",
 70@@ -81,7 +81,8 @@ func TestScript(t *testing.T) {
 71 		Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){
 72 			"soft":          cmdSoft("admin", admin1.Signer()),
 73 			"usoft":         cmdSoft("user1", user1.Signer()),
 74-			"git":           cmdGit(key),
 75+			"git":           cmdGit(admin1Key),
 76+			"ugit":          cmdGit(user1Key),
 77 			"curl":          cmdCurl,
 78 			"mkfile":        cmdMkfile,
 79 			"envfile":       cmdEnvfile,
 80diff --git a/testscript/testdata/anon-access.txtar b/testscript/testdata/anon-access.txtar
 81new file mode 100644
 82index 0000000000000000000000000000000000000000..54958fa11a8f75b8618a4fb760adcc8a27441e7f
 83--- /dev/null
 84+++ b/testscript/testdata/anon-access.txtar
 85@@ -0,0 +1,33 @@
 86+# vi: set ft=conf
 87+
 88+# start soft serve
 89+exec soft serve &
 90+# wait for server to start
 91+waitforserver
 92+
 93+# set settings
 94+soft settings allow-keyless true
 95+soft settings anon-access no-access
 96+
 97+# create a repo
 98+soft repo create repo1
 99+git clone ssh://localhost:$SSH_PORT/repo1 repo1
100+mkfile ./repo1/README.md '# Hello\n\nwelcome'
101+git -C repo1 add -A
102+git -C repo1 commit -m 'first'
103+git -C repo1 push origin HEAD
104+
105+# access repo from anon
106+! ugit clone ssh://localhost:$SSH_PORT/repo1 urepo1
107+stderr 'Error: you are not authorized to do this'
108+
109+# list repo as anon
110+usoft repo list
111+stdout ''
112+
113+# create repo as anon
114+! usoft repo create urepo2
115+stderr 'Error: unauthorized'
116+
117+# stop the server
118+[windows] stopserver