Commit Diff


commit - 1bf2f1a06ee90cababf6787d589e91dd56a02852
commit + 56624d2b65c2b867ab6c9dd5ac2ad51c3a13d47c
blob - b463648c859a1713d622a349df2197f561d994bd
blob + 9b609e44eeac3d33dce8caa01cf42c14e12968fd
--- gotd/auth.c
+++ gotd/auth.c
@@ -128,8 +128,8 @@ match_identifier(const char *identifier, gid_t *groups
 }
 
 static const struct got_error *
-auth_check(struct gotd_access_rule_list *rules, const char *repo_name,
-    uid_t euid, gid_t egid, int required_auth)
+auth_check(char **username, struct gotd_access_rule_list *rules,
+    const char *repo_name, uid_t euid, gid_t egid, int required_auth)
 {
 	struct gotd_access_rule *rule;
 	enum gotd_access access = GOTD_ACCESS_DENIED;
@@ -137,6 +137,8 @@ auth_check(struct gotd_access_rule_list *rules, const 
 	gid_t groups[NGROUPS_MAX];
 	int ngroups = NGROUPS_MAX;
 
+	*username = NULL;
+
 	pw = getpwuid(euid);
 	if (pw == NULL) {
 		if (errno)
@@ -145,6 +147,10 @@ auth_check(struct gotd_access_rule_list *rules, const 
 			return got_error_set_errno(EACCES, repo_name);
 	}
 
+	*username = strdup(pw->pw_name);
+	if (*username == NULL)
+		return got_error_from_errno("strdup");
+
 	if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups) == -1)
 		log_warnx("group membership list truncated");
 
@@ -178,6 +184,9 @@ recv_authreq(struct imsg *imsg, struct gotd_imsgev *ie
 	size_t datalen;
 	uid_t euid;
 	gid_t egid;
+	char *username = NULL;
+	size_t len;
+	const size_t maxlen = MAX_IMSGSIZE - IMSG_HEADER_SIZE;
 
 	log_debug("authentication request received");
 
@@ -200,18 +209,23 @@ recv_authreq(struct imsg *imsg, struct gotd_imsgev *ie
 
 	log_debug("authenticating uid %d gid %d", euid, egid);
 
-	err = auth_check(&gotd_auth.repo->rules, gotd_auth.repo->name,
-	    iauth.euid, iauth.egid, iauth.required_auth);
+	err = auth_check(&username, &gotd_auth.repo->rules,
+	    gotd_auth.repo->name, iauth.euid, iauth.egid, iauth.required_auth);
 	if (err) {
 		gotd_imsg_send_error(ibuf, PROC_AUTH, iauth.client_id, err);
-		return err;
+		goto done;
 	}
 
-	if (gotd_imsg_compose_event(iev, GOTD_IMSG_ACCESS_GRANTED,
-	    PROC_AUTH, -1, NULL, 0) == -1)
-		return got_error_from_errno("imsg compose ACCESS_GRANTED");
+	len = strlen(username);
+	if (len > maxlen)
+		len = maxlen;
 
-	return NULL;
+	if (gotd_imsg_compose_event(iev, GOTD_IMSG_ACCESS_GRANTED,
+	    PROC_AUTH, -1, username, len) == -1)
+		err = got_error_from_errno("imsg compose ACCESS_GRANTED");
+done:
+	free(username);
+	return err;
 }
 
 static void
blob - 892a54d71ecfa0e0dc9b036bdc334a9cbb1e4225
blob + a7e4203b663abc6cc97df5f65ca8390cd9d1ac9e
--- gotd/gotd.c
+++ gotd/gotd.c
@@ -96,6 +96,7 @@ struct gotd_client {
 	struct event			 tmo;
 	uid_t				 euid;
 	gid_t				 egid;
+	char				*username;
 	struct gotd_child_proc		*repo;
 	struct gotd_child_proc		*auth;
 	struct gotd_child_proc		*session;
@@ -368,6 +369,7 @@ disconnect(struct gotd_client *client)
 		close(client->fd);
 	else if (client->iev.ibuf.fd != -1)
 		close(client->iev.ibuf.fd);
+	free(client->username);
 	free(client);
 	client_cnt--;
 }
@@ -1126,6 +1128,7 @@ gotd_dispatch_auth_child(int fd, short event, void *ar
 	struct imsg imsg;
 	uint32_t client_id = 0;
 	int do_disconnect = 0;
+	size_t datalen;
 
 	client = find_client_by_proc_fd(fd);
 	if (client == NULL) {
@@ -1169,13 +1172,18 @@ gotd_dispatch_auth_child(int fd, short event, void *ar
 
 	evtimer_del(&client->tmo);
 
+	datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
+
 	switch (imsg.hdr.type) {
 	case GOTD_IMSG_ERROR:
 		do_disconnect = 1;
 		err = gotd_imsg_recv_error(&client_id, &imsg);
 		break;
 	case GOTD_IMSG_ACCESS_GRANTED:
-		client->state = GOTD_CLIENT_STATE_ACCESS_GRANTED;
+		if (client->state != GOTD_CLIENT_STATE_NEW) {
+			do_disconnect = 1;
+			err = got_error(GOT_ERR_PRIVSEP_MSG);
+		}
 		break;
 	default:
 		do_disconnect = 1;
@@ -1188,14 +1196,24 @@ gotd_dispatch_auth_child(int fd, short event, void *ar
 		log_debug("dropping imsg type %d from PID %d",
 		    imsg.hdr.type, client->auth->pid);
 	}
-	imsg_free(&imsg);
 
 	if (do_disconnect) {
 		if (err)
 			disconnect_on_error(client, err);
 		else
 			disconnect(client);
+		imsg_free(&imsg);
 		return;
+	}
+
+	client->state = GOTD_CLIENT_STATE_ACCESS_GRANTED;
+	if (datalen > 0)
+		client->username = strndup(imsg.data, datalen);
+	imsg_free(&imsg);
+	if (client->username == NULL &&
+	    asprintf(&client->username, "uid %d", client->euid) == -1) {
+		err = got_error_from_errno("asprintf");
+		goto done;
 	}
 
 	repo = gotd_find_repo_by_name(client->auth->repo_name, &gotd);
@@ -1205,8 +1223,8 @@ gotd_dispatch_auth_child(int fd, short event, void *ar
 	}
 	kill_auth_proc(client);
 
-	log_info("authenticated uid %d for repository %s",
-	    client->euid, repo->name);
+	log_info("authenticated %s for repository %s",
+	    client->username, repo->name);
 
 	err = start_session_child(client, repo, gotd.argv0,
 	    gotd.confpath, gotd.daemonize, gotd.verbosity);