commit 06efacffbc9efa9ab5a6f1337e8c7acbffa0e6ee from: Omar Polo date: Wed May 28 17:36:43 2025 UTC minor refactor and actually check the cookie commit - 0adbbd328a93482b82c4e5d5650c5311212bf388 commit + 06efacffbc9efa9ab5a6f1337e8c7acbffa0e6ee blob - fa8132a21696068f4db352dd35593a0f5141eaf6 blob + bde278404461202ccc124ec456b9c0009d3e7807 --- gotwebd/auth.c +++ gotwebd/auth.c @@ -28,6 +28,9 @@ #include #include +#include +#include + #include "got_error.h" #include "got_reference.h" @@ -46,8 +49,31 @@ struct gotwebd_auth_client { static volatile int client_cnt; static int inflight; -/* int */ -/* auth_is_allowed(const char *token, ) */ +/* + * The token format is: + * + * "v1"[issued at/64bit][expire/64bit][username]"\0"[host] + * + * followed by the HMAC-SHA256 of it, all encoded in base64. + */ + +/* + * XXX the idea is that this takes the token, the ACLs and the + * repository name (the TODO part) and returns whether the user is + * allowed to access the given repository. + */ +int +auth_is_allowed(const char *token) +{ + return !strcmp(token, "42"); +} + +/* checks whether the token's signature matches, i.e. if it looks good. */ +int +auth_check_token(const char *token) +{ + return !strcmp(token, "42"); +} static int auth_socket_listen(struct gotwebd *env, struct socket *sock, blob - a392cac3f02e8a6e6be4488c768edde81e6d1655 blob + 98b573ad9c778c1a1e852430162d12d1be11dfc4 --- gotwebd/gotweb.c +++ gotwebd/gotweb.c @@ -256,7 +256,42 @@ recv_request(struct imsg *imsg) return c; } + +static int +do_login(struct request *c) +{ + struct querystring *qs = c->t->qs; + int r; + if (gotwebd_env->gotwebd_verbose > 0) + log_info("processing login: code='%s'", qs->login); + + if (!auth_check_token(qs->login)) { + log_warnx("invalid code for login"); + if (gotweb_reply(c, 401, "text/html", NULL) == -1) + return (-1); + return gotweb_render_page(c->tp, + gotweb_render_unauthorized); + } + + /* + * Set cookie -- if not Expire param is given, it becomes a + * "session" cookie which should be cleared when the browser + * gets closed. Depending on user configuration, these might + * still persist though. + */ + r = tp_writef(c->tp, "Set-Cookie: gwdauth=%s;" + " SameSite=Strict; Secure; Path=/; HttpOnly\r\n", + qs->login); + if (r == -1) + return (-1); + + if (gotweb_reply(c, 200, "text/html", NULL) == -1) + return (-1); + + return gotweb_render_page(c->tp, gotweb_render_authorized); +} + int gotweb_process_request(struct request *c) { @@ -283,30 +318,18 @@ gotweb_process_request(struct request *c) goto err; } - if (qs->login) { - if (gotwebd_env->gotwebd_verbose > 0) - log_info("processing login: code='%s'", qs->login); + if (qs->login) + return do_login(c); - /* xxx */ - if (strcmp(qs->login, "42") != 0) { - log_warnx("invalid code for login"); - if (gotweb_reply(c, 401, "text/html", NULL) == -1) - return (-1); - return gotweb_render_page(c->tp, - gotweb_render_unauthorized); - } - - /* Set cookie */ - r = tp_writef(c->tp, "Set-Cookie: gwdauth=%s;" - " SameSite=Strict; Secure; Path=/; HttpOnly\r\n", - qs->login); - if (r == -1) - return (-1); - - if (gotweb_reply(c, 200, "text/html", NULL) == -1) - return (-1); - - return gotweb_render_page(c->tp, gotweb_render_authorized); + /* + * assume all requests have to be from logged users. + * TODO: pass the ACLs and the current repository. + */ + log_info("auth code is %s", c->auth_cookie); + if (!auth_is_allowed(c->auth_cookie)) { + if (gotweb_reply(c, 401, "text/html", NULL) == -1) + return -1; + return gotweb_render_page(c->tp, gotweb_render_unauthorized); } /* Log the request. */ blob - 2f8293f012017b37b7f116ff8eed22b51e241760 blob + b5864d25a22fbb8ba0d3d41cdb8283fbf5873c39 --- gotwebd/gotwebd.h +++ gotwebd/gotwebd.h @@ -559,5 +559,7 @@ int config_getcfg(struct gotwebd *, struct imsg *); int config_init(struct gotwebd *); /* auth.c */ +int auth_is_allowed(const char *); +int auth_check_token(const char *); void gotwebd_auth(struct gotwebd *, int); int auth_privinit(struct gotwebd *env, uid_t, gid_t);