Commit Diff


commit - ed02a561a607a7db70edde4e93eb965e7ba7549f
commit + ba61c78b3aec77e1f1eeb8c70436273d9dad9219
blob - 461fdb3accfd2a73e6df504e7971e045204c924e
blob + 970773d8d9c33955439e30233a5b829c655dfaad
--- gotwebd/config.c
+++ gotwebd/config.c
@@ -212,3 +212,46 @@ config_getfd(struct gotwebd *env, struct imsg *imsg)
 
 	return 1;
 }
+
+void
+config_set_access_rules(struct imsgev *iev,
+    struct gotwebd_access_rule_list *rules)
+{
+	struct gotwebd_access_rule *rule;
+
+	STAILQ_FOREACH(rule, rules, entry) {
+		if (imsg_compose_event(iev, GOTWEBD_IMSG_CFG_ACCESS_RULE,
+		    0, -1, -1, rule, sizeof(*rule)) == -1)
+			fatal("imsg_compose_event "
+			    "GOTWEBD_IMSG_CFG_ACCESS_RULE");
+	}
+}
+
+void
+config_get_access_rule(struct gotwebd_access_rule_list *rules,
+    struct imsg *imsg)
+{
+	struct gotwebd_access_rule *rule;
+	size_t len;
+
+	rule = calloc(1, sizeof(*rule));
+	if (rule == NULL)
+		fatal("malloc");
+
+	if (imsg_get_data(imsg, rule, sizeof(*rule)))
+		fatalx("%s: invalid CFG_ACCESS_RULE message", __func__);
+	
+	switch (rule->access) {
+	case GOTWEBD_ACCESS_DENIED:
+	case GOTWEBD_ACCESS_PERMITTED:
+		break;
+	default:
+		fatalx("%s: invalid CFG_ACCESS_RULE message", __func__);
+	}
+
+	len = strnlen(rule->identifier, sizeof(rule->identifier));
+	if (len == 0 || len >= sizeof(rule->identifier))
+		fatalx("%s: invalid CFG_ACCESS_RULE message", __func__);
+
+	STAILQ_INSERT_TAIL(rules, rule, entry);
+}
blob - cda9f986eae46750c070d4c92907eb869dc1ce42
blob + bf90c2001f8ab845bffc292ddabbd0da93fa3221
--- gotwebd/gotweb.c
+++ gotwebd/gotweb.c
@@ -1599,6 +1599,30 @@ gotweb_dispatch_main(int fd, short event, void *arg)
 			break;
 
 		switch (imsg.hdr.type) {
+		case GOTWEBD_IMSG_CFG_ACCESS_RULE:
+			if (TAILQ_EMPTY(&env->servers)) {
+				/* global access rule */
+				config_get_access_rule(&env->access_rules,
+				    &imsg);
+			} else {
+				struct server *srv;
+
+				srv = TAILQ_LAST(&env->servers, serverlist);
+				if (TAILQ_EMPTY(&srv->repos)) {
+					/* per-server access rule */
+					config_get_access_rule(
+					    &srv->access_rules, &imsg);
+				} else {
+					struct gotwebd_repo *repo;
+
+					/* per-repository access rule */
+					repo = TAILQ_LAST(&srv->repos,
+					    gotwebd_repolist);
+					config_get_access_rule(
+					    &repo->access_rules, &imsg);
+				}
+			}
+			break;
 		case GOTWEBD_IMSG_CFG_SRV:
 			config_getserver(env, &imsg);
 			break;
blob - b62716ce1e8a2f3653daefcdb42db84353da659c
blob + 69f105491d4a849d9231fe8547d59084d175025b
--- gotwebd/gotwebd.c
+++ gotwebd/gotwebd.c
@@ -773,6 +773,7 @@ gotwebd_configure(struct gotwebd *env, uid_t uid, gid_
 	struct server *srv;
 	struct socket *sock;
 	char auth_token_secret[32];
+	int i;
 
 	/* gotweb need to reload its config. */
 	env->servers_pending = env->prefork_gotwebd;
@@ -781,6 +782,14 @@ gotwebd_configure(struct gotwebd *env, uid_t uid, gid_
 
 	arc4random_buf(auth_token_secret, sizeof(auth_token_secret));
 
+	/* send our global access rules */
+	for (i = 0; i < env->nserver; ++i) {
+		config_set_access_rules(&env->iev_login[i],
+		    &env->access_rules);
+		config_set_access_rules(&env->iev_gotweb[i],
+		    &env->access_rules);
+	}
+
 	/* send our gotweb servers */
 	TAILQ_FOREACH(srv, &env->servers, entry) {
 		if (main_compose_sockets(env, GOTWEBD_IMSG_CFG_SRV,
@@ -792,6 +801,16 @@ gotwebd_configure(struct gotwebd *env, uid_t uid, gid_
 		if (main_compose_gotweb(env, GOTWEBD_IMSG_CFG_SRV,
 		    -1, srv, sizeof(*srv)) == -1)
 			fatal("main_compose_gotweb GOTWEBD_IMSG_CFG_SRV");
+
+		/* send per-server access rules */
+		for (i = 0; i < env->nserver; ++i) {
+			config_set_access_rules(&env->iev_login[i],
+			    &srv->access_rules);
+			config_set_access_rules(&env->iev_gotweb[i],
+			    &srv->access_rules);
+		}
+
+		/* TODO: send repositories and per-repo access rules */
 	}
 
 	/* send our sockets */
blob - 8169c11f1d7782271f727508f61407829f6f307b
blob + f7efb51b844b9b62895cd011fdae0d444d6e8ae4
--- gotwebd/gotwebd.h
+++ gotwebd/gotwebd.h
@@ -60,6 +60,7 @@
 #define MAX_DOCUMENT_URI	 255
 #define MAX_SERVER_NAME		 255
 #define MAX_AUTH_COOKIE		 255
+#define MAX_IDENTIFIER_SIZE	 32
 
 #define GOTWEB_GIT_DIR		 ".git"
 
@@ -138,6 +139,7 @@ enum imsg_type {
 	GOTWEBD_IMSG_CFG_SRV,
 	GOTWEBD_IMSG_CFG_SOCK,
 	GOTWEBD_IMSG_CFG_FD,
+	GOTWEBD_IMSG_CFG_ACCESS_RULE,
 	GOTWEBD_IMSG_CFG_DONE,
 	GOTWEBD_IMSG_CTL_PIPE,
 	GOTWEBD_IMSG_CTL_START,
@@ -324,7 +326,7 @@ struct gotwebd_access_rule {
 	STAILQ_ENTRY(gotwebd_access_rule) entry;
 
 	enum gotwebd_access access;
-	char *identifier;
+	char identifier[MAX_IDENTIFIER_SIZE];
 };
 STAILQ_HEAD(gotwebd_access_rule_list, gotwebd_access_rule);
 
@@ -611,6 +613,9 @@ int config_getsock(struct gotwebd *, struct imsg *);
 int config_setfd(struct gotwebd *);
 int config_getfd(struct gotwebd *, struct imsg *);
 int config_getcfg(struct gotwebd *, struct imsg *);
+void config_set_access_rules(struct imsgev *,
+    struct gotwebd_access_rule_list *);
+void config_get_access_rule(struct gotwebd_access_rule_list *, struct imsg *);
 int config_init(struct gotwebd *);
 
 /* auth.c */
blob - 3c32e5f0726ecd2ae24607939e2d98ac6393ed9d
blob + b91e56a07f7b0fd10a0ca6c989f76d599a26c2d0
--- gotwebd/login.c
+++ gotwebd/login.c
@@ -516,6 +516,30 @@ login_dispatch_main(int fd, short event, void *arg)
 			break;
 
 		switch (imsg.hdr.type) {
+		case GOTWEBD_IMSG_CFG_ACCESS_RULE:
+			if (TAILQ_EMPTY(&env->servers)) {
+				/* global access rule */
+				config_get_access_rule(&env->access_rules,
+				    &imsg);
+			} else {
+				struct server *srv;
+
+				srv = TAILQ_LAST(&env->servers, serverlist);
+				if (TAILQ_EMPTY(&srv->repos)) {
+					/* per-server access rule */
+					config_get_access_rule(
+					    &srv->access_rules, &imsg);
+				} else {
+					struct gotwebd_repo *repo;
+
+					/* per-repository access rule */
+					repo = TAILQ_LAST(&srv->repos,
+					    gotwebd_repolist);
+					config_get_access_rule(
+					    &repo->access_rules, &imsg);
+				}
+			}
+			break;
 		case GOTWEBD_IMSG_CFG_SRV:
 			config_getserver(gotwebd_env, &imsg);
 			break;
blob - 9d3b654730ec2f623f12354a7b55a35241f1ee9e
blob + af28d0ef5aa4e162504499d52de142d0d4be75e5
--- gotwebd/parse.y
+++ gotwebd/parse.y
@@ -1384,7 +1384,10 @@ conf_new_access_rule(struct gotwebd_access_rule_list *
 		fatal("calloc");
 
 	rule->access = access;
-	rule->identifier = identifier;
+	if (strlcpy(rule->identifier, identifier,
+	    sizeof(rule->identifier)) >= sizeof(rule->identifier))
+		fatalx("identifier too long (max %zu bytes): %s",
+		    sizeof(rule->identifier) - 1, identifier);
 
 	STAILQ_INSERT_TAIL(rules, rule, entry);
 }