"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
cosmetic gotwebd fix for logged-in user name
To:
gameoftrees@openbsd.org
Date:
Sun, 12 Apr 2026 09:39:48 +0200

Download raw body.

Thread
  • Stefan Sperling:

    cosmetic gotwebd fix for logged-in user name

When users authenticate via group membership, gotwebd displayed a banner
saying "Logged in as :groupname" rather than "Logged in as username".

This patch makes gotwebd always display the logged-in username and
adds test coverage for authentication via groups.

ok?

M  gotwebd/auth.c                   |   10+  0-
M  gotwebd/gotwebd.h                |    1+  0-
M  gotwebd/pages.tmpl               |    3+  2-
M  regress/gotsysd/test_gotwebd.sh  |  144+  0-

4 files changed, 158 insertions(+), 2 deletions(-)

commit - 1008b9596f1b9e09fed8e4c87d0bfaf879d3c1bd
commit + b378afbafa418e2fb964b5e8b0e46f0efad22025
blob - e71a43b08f78c7bc51cb3c2ef665e4ea6296ac9f
blob + 9ce13d25fe65a225dbd3f2f1a8a98f4acd96fbd2
--- gotwebd/auth.c
+++ gotwebd/auth.c
@@ -521,6 +521,7 @@ process_request(struct request *c)
 	const char *identifier = NULL;
 	char *request_path = NULL;
 	int is_repository_request = 0;
+	struct passwd *pw = NULL;
 
 	srv = gotweb_get_server(c->fcgi_params.server_name);
 	if (srv == NULL) {
@@ -688,6 +689,15 @@ permitted:
 		    "identifier too long");
 		goto done;
 	}
+	pw = getpwuid(uid);
+	if (pw) {
+		if (strlcpy(c->client_username, pw->pw_name,
+		    sizeof(c->client_username)) >= sizeof(c->client_username)) {
+			error = got_error_msg(GOT_ERR_NO_SPACE,
+			    "username too long");
+			goto done;
+		}
+	}
 
 	if (gotwebd_env->gotwebd_verbose > 0) {
 		log_info("authenticated UID %u as %s for server \"%s\"",
blob - f1f75864d29a9d230bb8305b3676479dbe0f5669
blob + ec9668b156a1cadb11e21ae4905edc9752a45453
--- gotwebd/gotwebd.h
+++ gotwebd/gotwebd.h
@@ -353,6 +353,7 @@ struct request {
 
 	uid_t				 client_uid;
 	char				 access_identifier[MAX_IDENTIFIER_SIZE];
+	char				 client_username[MAX_IDENTIFIER_SIZE];
 };
 TAILQ_HEAD(requestlist, request);
 
blob - beff41e33d5297ee17e32c8a55bcd1dbbb057228
blob + 892402a866c859317430fd61139d234250479f7d
--- gotwebd/pages.tmpl
+++ gotwebd/pages.tmpl
@@ -226,9 +226,10 @@ nextsep(char *s, char **t)
           <img src="{{ prefix }}/{{ srv->logo }}" />
         </a>
       </div>
-      {{ if (c->access_identifier[0]) }}	
+      {{ if (c->client_username[0] || c->access_identifier[0]) }}	
       <div id="login_status">
-        Logged in as: <b>{{ c->access_identifier }}</b> &nbsp;
+        Logged in as: <b>{{ c->client_username[0] ?
+	    c->client_username : c->access_identifier }}</b> &nbsp;
 	(<a href="{{ render gotweb_render_url(c, &u_logout) }}">Logout</a>)
       </div>
       {{ end }}
blob - 74d98394522484f6d2749c8a686246dff5e3f61d
blob + a781e0909f76a85602368ca7c427f6c9ce17a268
--- regress/gotsysd/test_gotwebd.sh
+++ regress/gotsysd/test_gotwebd.sh
@@ -738,7 +738,151 @@ EOF
 		return 1
 	fi
 
+	# Test authentication via group membership.
+	crypted_vm_pw=`echo ${GOTSYSD_VM_PASSWORD} | encrypt | tr -d '\n'`
+	crypted_pw=`echo ${GOTSYSD_DEV_PASSWORD} | encrypt | tr -d '\n'`
+	sshkey=`cat ${GOTSYSD_SSH_PUBKEY}`
+	cat > ${testroot}/wt/gotsys.conf <<EOF
+group writers
+group devs
+group testers
 
+user ${GOTSYSD_TEST_USER} {
+	password "${crypted_vm_pw}" 
+	authorized key ${sshkey}
+	group writers
+	group testers
+}
+user ${GOTSYSD_DEV_USER} {
+	password "${crypted_pw}" 
+	authorized key ${sshkey}
+	group writers
+	group devs
+}
+repository gotsys.git {
+	permit rw :writers
+}
+repository public.git {
+	permit rw :writers
+}
+repository gottestdev.git {
+	permit rw :devs
+}
+repository gottest.git {
+	permit rw :testers
+}
+repository hidden.git {
+	permit rw :testers
+}
+web server "${VMIP}" {
+	repository public {
+		disable authentication
+	}
+	repository gottestdev.git {
+		permit :devs
+		deny :testers
+	}
+	repository gottest.git {
+		permit :testers
+	}
+	repository hidden {
+		permit :testers
+		deny :devs
+		hide repository on
+	}
+}
+EOF
+	(cd ${testroot}/wt && gotsys check -q)
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "bad gotsys.conf written by test" >&2
+		test_done "$testroot" 1
+		return 1
+	fi
+
+	(cd ${testroot}/wt && got commit -m "use group auth" >/dev/null)
+	local commit_id=`git_show_head $testroot/${GOTSYS_REPO}`
+
+	got send -q -i ${GOTSYSD_SSH_KEY} -r ${testroot}/${GOTSYS_REPO}
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got send failed unexpectedly" >&2
+		test_done "$testroot" 1
+		return 1
+	fi
+
+	# Wait for gotsysd to apply the new configuration.
+	echo "$commit_id" > $testroot/stdout.expected
+	for i in 1 2 3 4 5; do
+		sleep 1
+		ssh -i ${GOTSYSD_SSH_KEY} root@${VMIP} \
+			cat /var/db/gotsysd/commit > $testroot/stdout
+		if cmp -s $testroot/stdout.expected $testroot/stdout; then
+			break;
+		fi
+	done
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "gotsysd failed to apply configuration" >&2
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# Obtain a login token over ssh.
+	ssh -q -i ${GOTSYSD_SSH_KEY} ${GOTSYSD_TEST_USER}@${VMIP} \
+		'gotsh -c weblogin' > $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "ssh login failed failed unexpectedly" >&2
+		test_done "$testroot" 1
+		return 1
+	fi
+
+	url=$(cut -d: -f 2,3 < $testroot/stdout | sed -e 's/ https:/http:/')
+	w3m -cookie-jar "$testroot/cookies" "$url" -dump > $testroot/stdout
+	cat > $testroot/stdout.expected <<EOF
+[got]
+Logged in as: ${GOTSYSD_TEST_USER}  (Logout)
+Repositories
+Repository
+gottest.git
+summary | briefs | commits | tags | tree | rss
+-------------------------------------------------------------------------------
+public.git
+summary | briefs | commits | tags | tree | rss
+-------------------------------------------------------------------------------
+
+EOF
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# Attempt to access the private repository's tree again with cookie
+	w3m -cookie-jar $testroot/cookies \
+		"http://${VMIP}/?action=tree&path=gottest.git" -dump \
+		> $testroot/stdout
+
+	cat > $testroot/stdout.expected <<EOF
+[got]
+Logged in as: ${GOTSYSD_TEST_USER}  (Logout)
+Repositories / gottest.git / tree /
+reference refs/heads/main not found
+
+EOF
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
 	test_done "$testroot" "$ret"
 }