commit 64eb24873b5b63f89f43071f87f0b68d67ade4e6 from: Stefan Sperling date: Fri Aug 29 15:41:39 2025 UTC start putting access checks into login.c; everyone passes, for now commit - f64cf10ded89231621f05a9b05aabd596a63334a commit + 64eb24873b5b63f89f43071f87f0b68d67ade4e6 blob - b1cce23ab2d6c57ab08fca454362fe66b498584a blob + f65c7285ed12b1a7d26ab953399839b996373ff0 --- gotwebd/Makefile +++ gotwebd/Makefile @@ -5,7 +5,7 @@ .include "Makefile.inc" PROG = gotwebd -SRCS = auth.c config.c sockets.c login.c gotwebd.c parse.y \ +SRCS = access.c auth.c config.c sockets.c login.c gotwebd.c parse.y \ fcgi.c gotweb.c got_operations.c tmpl.c pages.c SRCS += blame.c commit_graph.c delta.c diff.c \ diffreg.c error.c object.c object_cache.c \ blob - /dev/null blob + 14c25fdd2c16e640ef31c1abeedcb12aedee9b94 (mode 644) --- /dev/null +++ gotwebd/access.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Stefan Sperling + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include + +#include "got_reference.h" + +#include "gotwebd.h" +#include "log.h" + +enum gotwebd_access +access_check(uid_t uid, struct gotwebd_access_rule_list *rules) +{ + /* TODO */ + return GOTWEBD_ACCESS_PERMITTED; +} blob - 7fa1ab0f5de4526e17c35977ee3c1a068f457846 blob + 6f4d5068996fb62cd514e840c9e6fc1a5570d3ec --- gotwebd/gotweb.c +++ gotwebd/gotweb.c @@ -563,6 +563,28 @@ gotweb_get_server(const char *server_name) /* otherwise, use the first server */ return TAILQ_FIRST(&gotwebd_env->servers); +}; + +struct gotwebd_repo * +gotweb_get_repository(struct server *server, const char *name) +{ + struct gotwebd_repo *repo; + + TAILQ_FOREACH(repo, &server->repos, entry) { + if (strncmp(repo->name, name, strlen(repo->name)) != 0) + continue; + + if (strlen(name) == strlen(repo->name)) + return repo; + + if (strlen(name) != strlen(repo->name) + 4) + continue; + + if (strcmp(name + strlen(repo->name), ".git") == 0) + return repo; + } + + return NULL; }; const struct got_error * blob - 81ed267b63329b626454173f2072d58cb1364aa0 blob + ac8d4da6aca037eb97d5d8c2129641b85fb71305 --- gotwebd/gotwebd.h +++ gotwebd/gotwebd.h @@ -540,6 +540,7 @@ void gotwebd_login(struct gotwebd *, int); const struct got_error *gotweb_init_querystring(struct querystring **); const struct got_error *gotweb_parse_querystring(struct querystring *, char *); struct server *gotweb_get_server(const char *); +struct gotwebd_repo * gotweb_get_repository(struct server *, const char *); int gotweb_reply(struct request *c, int status, const char *ctype, struct gotweb_url *); void gotweb_index_navs(struct request *, struct gotweb_url *, int *, @@ -626,3 +627,6 @@ char *auth_gen_token(uint64_t, const char *, time_t, c int auth_check_token(uid_t *, char **, const char *, const char *, size_t); void gotwebd_auth(struct gotwebd *, int); int auth_privinit(struct gotwebd *env, uid_t, gid_t); + +/* access.c */ +enum gotwebd_access access_check(uid_t, struct gotwebd_access_rule_list *); blob - 6bdcc9df4d1bed48fa079aab23a472e9fc2f15a7 blob + 68741fc55a01a2ca13342f6e819878bbe5a48823 --- gotwebd/login.c +++ gotwebd/login.c @@ -290,6 +290,8 @@ process_request(struct request *c, struct imsg *imsg) struct querystring *qs = NULL; int ret; char *hostname = NULL; + struct gotwebd_repo *repo; + enum gotwebd_access access; switch (env->auth_config) { case GOTWEBD_AUTH_SECURE: @@ -330,6 +332,50 @@ process_request(struct request *c, struct imsg *imsg) log_debug("authenticated uid %u for server \"%s\"", c->client_uid, hostname); + + if (qs->action == INDEX) { + access = access_check(c->client_uid, &c->srv->access_rules); + switch (access) { + case GOTWEBD_ACCESS_PERMITTED: + break; + case GOTWEBD_ACCESS_DENIED: + if (gotweb_reply(c, 401, "text/html", NULL) == -1) + return -1; + gotweb_render_page(c->tp, gotweb_render_unauthorized); + return -1; + default: + log_debug("access check error for uid %u\n", + c->client_uid); + return -1; + } + } else { + if (qs->path == NULL) { + error = got_error(GOT_ERR_BAD_QUERYSTRING); + goto err; + } + + repo = gotweb_get_repository(c->srv, qs->path); + if (repo) { + access = access_check(c->client_uid, + &repo->access_rules); + switch (access) { + case GOTWEBD_ACCESS_PERMITTED: + break; + case GOTWEBD_ACCESS_DENIED: + if (gotweb_reply(c, 401, + "text/html", NULL) == -1) + return -1; + gotweb_render_page(c->tp, + gotweb_render_unauthorized); + return -1; + default: + log_debug("access check error for uid %u\n", + c->client_uid); + return -1; + } + } + } + forward: ret = imsg_compose_event(env->iev_gotweb, GOTWEBD_IMSG_REQ_PROCESS, GOTWEBD_PROC_LOGIN, -1, c->fd, c, sizeof(*c));