From: Stefan Sperling Subject: hide repositories via gotwebd.conf To: gameoftrees@openbsd.org Date: Wed, 1 Oct 2025 11:03:18 +0200 I would like to add syntax to gotwebd.conf which can be used to hide repositories. This will become useful in combination with another feature I want to add where gotwebd would display contents of a repository as a static web site. Such repositories could then be hidden from the regular gotwebd view if desired. ok? add gotwebd config parameters for hiding repositories Add gotwebd.conf parameters which allow repositories to be hidden from regular gotwebd output. This builds on the per-repository configuration parameter syntax added for the authentication feature. M gotwebd/gotweb.c | 8+ 0- M gotwebd/gotwebd.conf.5 | 41+ 2- M gotwebd/gotwebd.h | 4+ 0- M gotwebd/parse.y | 14+ 2- M regress/gotsysd/Makefile | 14+ 1- 5 files changed, 81 insertions(+), 5 deletions(-) commit - 23cefb96ef5b1220ba62581bfdef2e0f8fbcd624 commit + 553231594e207ed9ca25293255c62ff06584463a blob - 7672772d96f0932203149d91c27b87447771c938 blob + 7f74a54036a708c5ec5bb86222507705111070f1 --- gotwebd/gotweb.c +++ gotwebd/gotweb.c @@ -1022,6 +1022,7 @@ gotweb_load_got_path(struct repo_dir **rp, const char struct gotwebd_repo *repo; enum gotwebd_auth_config auth_config = 0; enum gotwebd_access access = GOTWEBD_ACCESS_DENIED; + int repo_is_hidden = 0; *rp = calloc(1, sizeof(**rp)); if (*rp == NULL) @@ -1067,6 +1068,7 @@ gotweb_load_got_path(struct repo_dir **rp, const char repo = gotweb_get_repository(srv, repo_dir->name); if (repo) { + repo_is_hidden = repo->hidden; auth_config = repo->auth_config; switch (auth_config) { case GOTWEBD_AUTH_DISABLED: @@ -1084,6 +1086,7 @@ gotweb_load_got_path(struct repo_dir **rp, const char break; } } else { + repo_is_hidden = srv->hide_repositories; auth_config = srv->auth_config; switch (auth_config) { case GOTWEBD_AUTH_DISABLED: @@ -1109,6 +1112,11 @@ gotweb_load_got_path(struct repo_dir **rp, const char goto err; } + if (repo_is_hidden) { + error = got_error_path(repo_dir->name, GOT_ERR_NOT_GIT_REPO); + goto err; + } + if (srv->respect_exportok && faccessat(dirfd(dt), "git-daemon-export-ok", F_OK, 0) == -1) { error = got_error_path(repo_dir->name, GOT_ERR_NOT_GIT_REPO); blob - e7b1317a646b64b19e51176196a25ed32a93c186 blob + 8ce5a3ead055f07e224ce103c63dba7a3b4c731d --- gotwebd/gotwebd.conf.5 +++ gotwebd/gotwebd.conf.5 @@ -63,8 +63,11 @@ effectively disables chroot. .It Ic disable authentication Disable authentication, allowing any browser to view any repository not hidden via the +.Ic hide repositories , +.Ic hide repository , +or .Ic respect_exportok -directive. +directives. Authentication is disabled by default. .It Ic enable authentication Oo Ic insecure Oc Enable authentication, requiring browsers to present a login token cookie @@ -197,8 +200,11 @@ will attempt to fetch it. .It Ic disable authentication Disable authentication for this server, allowing any browser to view any repository not hidden via the +.Ic hide repositories , +.Ic hide repository , +or .Ic respect_exportok -directive. +directives. Authentication can also configured on a per-repository basis. .Pp If not specified, the global configuration context determines @@ -210,6 +216,29 @@ Authentication can also configured on a per-repository .Pp If not specified, the global configuration context determines whether authentication is enabled. +.It Ic hide repositories Ar on | off +Controls whether repositories are hidden by default. +Hidden repositories cannot be browsed via +.Xr gotwebd 8 . +.Pp +By default, +.Ic hide repositories +is set to +.Ar off +and all repositories found in the +.Ic repos_path +will be displayed. +.Pp +If +.Ic hide repositories +is set to +.Ar on +then a repository will only be displayed if its repository-specific +.Ic hide repository +parameter is set to +.Ar off . +Repositories will be hidden regardless of whether authentication is +enabled and has failed or succeeded. .It Ic logo_url Ar url Set a hyperlink for the logo. Defaults to @@ -302,6 +331,16 @@ before read-only repository access is granted. .Pp If not specified, the server context or global context determines whether authentication is enabled. +.It Ic hide repository Ar on | off +Controls whether the repository is hidden. +Hidden repositories cannot be browsed via +.Xr gotwebd 8 . +.Pp +If not set, the server context's +.Ic hide repositories +parameter determines whether +.Xr gotwebd 8 +will display the repository. .El .It Ic respect_exportok Ar on | off Set whether to display the repository only if it contains the magic blob - c76a5ca79f14d2b7d419a48d691c48d7af92deae blob + a0e78241ebfc49bb61c5cdd66999b139d270245f --- gotwebd/gotwebd.h +++ gotwebd/gotwebd.h @@ -81,6 +81,7 @@ #define D_SHOWDESC 1 #define D_SHOWURL 1 #define D_RESPECTEXPORTOK 0 +#define D_HIDE_REPOSITORIES 0 #define D_MAXREPODISP 25 #define D_MAXSLCOMMDISP 10 #define D_MAXCOMMITDISP 25 @@ -384,6 +385,8 @@ struct gotwebd_repo { enum gotwebd_auth_config auth_config; struct gotwebd_access_rule_list access_rules; + + int hidden; }; TAILQ_HEAD(gotwebd_repolist, gotwebd_repo); @@ -411,6 +414,7 @@ struct server { int show_repo_description; int show_repo_cloneurl; int respect_exportok; + int hide_repositories; enum gotwebd_auth_config auth_config; struct gotwebd_access_rule_list access_rules; blob - 263ed7737f43df5c22385cc699bb42c5cc0f837e blob + 36f7355865c10eef10094f25ce0d544c4b6a2a5d --- gotwebd/parse.y +++ gotwebd/parse.y @@ -126,7 +126,7 @@ typedef struct { %token SHOW_SITE_OWNER SHOW_REPO_CLONEURL PORT PREFORK RESPECT_EXPORTOK %token SERVER CHROOT CUSTOM_CSS SOCKET %token SUMMARY_COMMITS_DISPLAY SUMMARY_TAGS_DISPLAY USER AUTHENTICATION -%token ENABLE DISABLE INSECURE REPOSITORY PERMIT DENY +%token ENABLE DISABLE INSECURE REPOSITORY REPOSITORIES PERMIT DENY HIDE %token STRING %token NUMBER @@ -446,6 +446,9 @@ serveropts1 : REPOS_PATH STRING { | RESPECT_EXPORTOK boolean { new_srv->respect_exportok = $2; } + | HIDE REPOSITORIES boolean { + new_srv->hide_repositories = $3; + } | MAX_REPOS_DISPLAY NUMBER { if ($2 < 0) { yyerror("max_repos_display is too small: %lld", @@ -578,6 +581,9 @@ repoopts1 : DISABLE AUTHENTICATION { conf_new_access_rule(&new_repo->access_rules, GOTWEBD_ACCESS_DENIED, $2); } + | HIDE REPOSITORY boolean { + new_repo->hidden = $3; + } ; nl : '\n' optnl @@ -627,6 +633,7 @@ lookup(char *s) { "deny", DENY }, { "disable", DISABLE }, { "enable", ENABLE }, + { "hide", HIDE }, { "insecure", INSECURE }, { "listen", LISTEN }, { "login", GOTWEBD_LOGIN }, @@ -639,6 +646,7 @@ lookup(char *s) { "port", PORT }, { "prefork", PREFORK }, { "repos_path", REPOS_PATH }, + { "repositories", REPOSITORIES }, { "repository", REPOSITORY }, { "respect_exportok", RESPECT_EXPORTOK }, { "server", SERVER }, @@ -1075,13 +1083,15 @@ parse_config(const char *filename, struct gotwebd *env break; } - /* Inherit implicit authentication config from parent scope. */ + /* Inherit implicit authentication/hidden config from parent scope. */ TAILQ_FOREACH(srv, &env->servers, entry) { if (srv->auth_config == 0) srv->auth_config = env->auth_config; TAILQ_FOREACH(repo, &srv->repos, entry) { if (repo->auth_config == 0) repo->auth_config = srv->auth_config; + if (repo->hidden == -1) + repo->hidden = srv->hide_repositories; } } @@ -1137,6 +1147,7 @@ conf_new_server(const char *name) srv->show_repo_description = D_SHOWDESC; srv->show_repo_cloneurl = D_SHOWURL; srv->respect_exportok = D_RESPECTEXPORTOK; + srv->hide_repositories = D_HIDE_REPOSITORIES; srv->max_repos_display = D_MAXREPODISP; srv->max_commits_display = D_MAXCOMMITDISP; @@ -1384,6 +1395,7 @@ conf_new_repo(struct server *server, const char *name) if (repo == NULL) fatal("gotwebd_new_repo"); + repo->hidden = -1; TAILQ_INSERT_TAIL(&server->repos, repo, entry); return repo; blob - 0288429b6a3516ebb9f8175cc88833ffe4fe0bff blob + f36eb4030168acdde61eda535b99ef8652b9d22f --- regress/gotsysd/Makefile +++ regress/gotsysd/Makefile @@ -228,21 +228,32 @@ $(GOTWEBD_CONF): @${UNPRIV} 'echo deny ${GOTSYSD_DEV_USER} >> $@' @${UNPRIV} 'echo server \"VMIP\" { >> $@' @${UNPRIV} 'echo \ \ repos_path \"/git\" >> $@' + @${UNPRIV} 'echo \ \ hide repositories on >> $@' @${UNPRIV} 'echo \ \ show_repo_age off >> $@' @${UNPRIV} 'echo \ \ show_repo_description off >> $@' @${UNPRIV} 'echo \ \ show_repo_owner off >> $@' @${UNPRIV} 'echo \ \ show_site_owner off >> $@' @${UNPRIV} 'echo \ \ repository \"public\" { >> $@' @${UNPRIV} 'echo \ \ \ \ disable authentication >> $@' + @${UNPRIV} 'echo \ \ \ \ hide repository off >> $@' @${UNPRIV} 'echo \ \ } >> $@' @${UNPRIV} 'echo \ \ repository \"gotdev\" { >> $@' @${UNPRIV} 'echo \ \ \ \ permit ${GOTSYSD_DEV_USER} >> $@' @${UNPRIV} 'echo \ \ \ \ deny ${GOTSYSD_TEST_USER} >> $@' + @${UNPRIV} 'echo \ \ \ \ hide repository off >> $@' @${UNPRIV} 'echo \ \ } >> $@' @${UNPRIV} 'echo \ \ repository \"gottest\" { >> $@' @${UNPRIV} 'echo \ \ \ \ permit ${GOTSYSD_TEST_USER} >> $@' @${UNPRIV} 'echo \ \ \ \ deny ${GOTSYSD_DEV_USER} >> $@' + @${UNPRIV} 'echo \ \ \ \ hide repository off >> $@' @${UNPRIV} 'echo \ \ } >> $@' + @${UNPRIV} 'echo \ \ repository \"hidden\" { >> $@' + @${UNPRIV} 'echo \ \ \ \ permit ${GOTSYSD_TEST_USER} >> $@' + @${UNPRIV} 'echo \ \ \ \ deny ${GOTSYSD_DEV_USER} >> $@' + @${UNPRIV} 'echo \ \ } >> $@' + @${UNPRIV} 'echo \ \ repository \"gotsys\" { >> $@' + @${UNPRIV} 'echo \ \ \ \ hide repository off >> $@' + @${UNPRIV} 'echo \ \ } >> $@' @${UNPRIV} 'echo } >> $@' build_got: @@ -341,9 +352,11 @@ test_gotwebd: VMIP="100.64.$$VMID.3"; \ GWIP="100.64.$$VMID.2"; \ ${UNPRIV} "${GOTSYSD_SSH_CMD} root@$${VMIP} \ - 'rm -rf /git/gotsys.git /git/foo.git /tmp/gotsys'"; \ + 'rm -rf /git/${GOTSYS_REPO} /git/{foo,hidden}.git /tmp/gotsys'"; \ ${UNPRIV} "${GOTSYSD_SSH_CMD} root@$${VMIP} \ got init /git/${GOTSYS_REPO}"; \ + ${UNPRIV} "${GOTSYSD_SSH_CMD} root@$${VMIP} \ + got init /git/hidden.git"; \ ${UNPRIV} "${GOTSYSD_SCP_CMD} \ ${GOT_CONF} root@$${VMIP}:/git/${GOTSYS_REPO}/got.conf"; \ ${UNPRIV} "${GOTSYSD_SSH_CMD} root@$${VMIP} mkdir /tmp/gotsys "; \