From: Stefan Sperling Subject: fix gotwebd login when URL location != "/" To: gameoftrees@openbsd.org Date: Tue, 2 Dec 2025 10:10:12 +0100 Add the gotwebd root URL to login links. Otherwise gotwebd will not receive login requests if the webserver is not running gotwebd at URL location "/". E.g. a config like this just won't work otherwise: httpd.conf: server "example.com" { location "/gotweb" { fastcgi socket "/run/gotweb.sock" } location "/gotweb/*" { fastcgi socket "/run/gotweb.sock" } } gotwebd.conf: server "example.com" { repos_path "/git" gotweb_url_root "/gotweb" repos_url_path "/" # example.com/gotweb/ enable authentication permit anonymous } gotsh would still return login URLs such as https://example.com/?login=token which result in "404 not found" from httpd. ok? Double-slashes are not a concern this time around since srv->gotweb_url_root is normalized to "/some/path" while parsing the configuration file (leading slash will be present, trailing slash won't be). M gotwebd/login.c | 15+ 7- 1 file changed, 15 insertions(+), 7 deletions(-) commit - 222a9d10ecceca6ca66c57d1a0dc84d13f5a2047 commit + 290598312f95a3869921f733a9b67cbe9a0bebf0 blob - 05a894bc5a6b1fdebdf747acaf7d215b24352cbd blob + b951cb0492a42bb97681b5a7909f7ffb83f76726 --- gotwebd/login.c +++ gotwebd/login.c @@ -478,7 +478,7 @@ client_read(struct bufferevent *bev, void *d) struct evbuffer *out = EVBUFFER_OUTPUT(bev); char *line, *cmd, *code; size_t linelen; - const char *hostname; + const char *hostname, *path = NULL; if (client->cmd_done) { log_warnx("%s: client sent data even though login command " @@ -501,12 +501,12 @@ client_read(struct bufferevent *bev, void *d) cmd = line; if (strncmp(cmd, "login", 5) == 0) { + struct server *srv = NULL; + cmd += 5; cmd += strspn(cmd, " \t"); hostname = cmd; if (hostname[0] == '\0') { - struct server *srv; - /* * In a multi-server setup we do not want to leak our * first server's hostname to random people. But if @@ -515,9 +515,13 @@ client_read(struct bufferevent *bev, void *d) srv = TAILQ_FIRST(&gotwebd_env->servers); if (TAILQ_NEXT(srv, entry) == NULL) hostname = srv->name; + else { + log_warnx("%s: no hostname provided for " + "weblogin", __func__); + client_err(bev, EVBUFFER_READ, client); + return; + } } else { - struct server *srv; - /* Match hostname against available servers. */ TAILQ_FOREACH(srv, &gotwebd_env->servers, entry) { if (strcmp(srv->name, hostname) == 0) @@ -541,8 +545,12 @@ client_read(struct bufferevent *bev, void *d) return; } - if (evbuffer_add_printf(out, "ok https://%s/?login=%s\n", - hostname, code) == -1) { + if (srv->gotweb_url_root[0] != '\0' && + !got_path_is_root_dir(srv->gotweb_url_root)) + path = srv->gotweb_url_root; + + if (evbuffer_add_printf(out, "ok https://%s%s/?login=%s\n", + hostname, path ? path : "", code) == -1) { log_warnx("%s: evbuffer_add_printf failed", __func__); client_err(bev, EVBUFFER_READ, client); free(code);