"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
remove gotsys.conf macro support
To:
gameoftrees@openbsd.org
Date:
Thu, 8 Jan 2026 11:21:05 +0100

Download raw body.

Thread
At present, use of SSH keys where the base64-encoded form ends with an
equal sign ('=') results in a gotsys.conf syntax error, unless the key
is wrapped in qoutes.

The = symbol isn't allowed in strings because the implementation supports
the use of macros in gotsys.conf, even though this feature is not documented.

I would rather keep gotsys.conf dumb and simple, disallow use of macros,
and avoid the syntax errors caused by SSH keys.

ok?


M  gotsys/gotsys.conf.5  |  1+    2-
M  gotsys/parse.y        |  3+  147-

2 files changed, 4 insertions(+), 149 deletions(-)

commit - 9020aec6a967ee14d24daff89a02c587527defb9
commit + f1845c8b1f4b2184d5fdd285ab7ca4841146f905
blob - 1041a66a18ada806fb52cd57b11c618bd86ea2a1
blob + c9c7bfeca5a00b8b60ac22bf91def73339364ed8
--- gotsys/gotsys.conf.5
+++ gotsys/gotsys.conf.5
@@ -192,7 +192,6 @@ ssh-rsa
 .Pp
 The key type must be followed by the base64-encoded public
 .Ar key .
-To avoid syntax errors the base64 string might need to be wrapped in quotes.
 .Pp
 The optional
 .Ar comment
@@ -640,7 +639,7 @@ user flan_hacker {
 user flan_squee {
 	group porters
 	authorized key ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAQ2ZWscmMeCYLwm07gDSf0jApFJ58bMNxiErDqUrFz4
-	authorized key ecdsa-sha2-nistp256 "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBVqRHzWh20u49JoZPc34pBFo7w+0KGRCnkuNbeR7ufJUbXceDwzgssQHDVILD1QK0Mmku2jLo1MG/BtwTVpsWc=" flan_squee@localhost
+	authorized key ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBVqRHzWh20u49JoZPc34pBFo7w+0KGRCnkuNbeR7ufJUbXceDwzgssQHDVILD1QK0Mmku2jLo1MG/BtwTVpsWc= flan_squee@localhost
 }
 
 repository "src" {
blob - ef20e27f07da6976269078abc7570f14fa0825d7
blob + 4a6a13014eb14989935248fa3407aa5d15bbba7a
--- gotsys/parse.y
+++ gotsys/parse.y
@@ -78,18 +78,6 @@ int		 lgetc(int);
 int		 lungetc(int);
 int		 findeol(void);
 
-TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
-struct sym {
-	TAILQ_ENTRY(sym)	 entry;
-	int			 used;
-	int			 persist;
-	char			*nam;
-	char			*val;
-};
-
-int	 symset(const char *, const char *, int);
-char	*symget(const char *);
-
 static const struct got_error	*gerror;
 
 static struct gotsys_conf	*gotsysconf;
@@ -144,24 +132,6 @@ grammar		:
 		| grammar repository '\n'
 		;
 
-varset		: STRING '=' STRING	{
-			char *s = $1;
-			while (*s++) {
-				if (isspace((unsigned char)*s)) {
-					yyerror("macro name cannot contain "
-					    "whitespace");
-					free($1);
-					free($3);
-					YYERROR;
-				}
-			}
-			if (symset($1, $3, 0) == -1)
-				yyerror("cannot store variable");
-			free($1);
-			free($3);
-		}
-		;
-
 numberstring	: STRING
 		| NUMBER {
 			if (asprintf(&$$, "%lld", (long long)$1) == -1) {
@@ -680,8 +650,6 @@ lookup(char *s)
 
 #define MAXPUSHBACK	128
 
-unsigned char *parsebuf;
-int parseindex;
 unsigned char pushback_buffer[MAXPUSHBACK];
 int pushback_index = 0;
 
@@ -690,17 +658,6 @@ lgetc(int quotec)
 {
 	int c, next;
 
-	if (parsebuf) {
-		/* Read character from the parsebuffer instead of input. */
-		if (parseindex >= 0) {
-			c = parsebuf[parseindex++];
-			if (c != '\0')
-				return (c);
-			parsebuf = NULL;
-		} else
-			parseindex++;
-	}
-
 	if (pushback_index)
 		return (pushback_buffer[--pushback_index]);
 
@@ -732,11 +689,7 @@ lungetc(int c)
 {
 	if (c == EOF)
 		return (EOF);
-	if (parsebuf) {
-		parseindex--;
-		if (parseindex >= 0)
-			return (c);
-	}
+
 	if (pushback_index < MAXPUSHBACK-1)
 		return (pushback_buffer[pushback_index++] = c);
 	else
@@ -748,8 +701,6 @@ findeol(void)
 {
 	int c;
 
-	parsebuf = NULL;
-
 	/* Skip to either EOF or the first real EOL. */
 	while (1) {
 		if (pushback_index)
@@ -770,11 +721,10 @@ int
 yylex(void)
 {
 	unsigned char buf[8096];
-	unsigned char *p, *val;
+	unsigned char *p;
 	int quotec, next, c;
 	int token;
 
-top:
 	p = buf;
 	c = lgetc(0);
 	while (c == ' ' || c == '\t')
@@ -786,34 +736,7 @@ top:
 		while (c != '\n' && c != EOF)
 			c = lgetc(0); /* nothing */
 	}
-	if (c == '$' && parsebuf == NULL) {
-		while (1) {
-			c = lgetc(0);
-			if (c == EOF)
-				return (0);
 
-			if (p + 1 >= buf + sizeof(buf) - 1) {
-				yyerror("string too long");
-				return (findeol());
-			}
-			if (isalnum((unsigned char)c) || c == '_') {
-				*p++ = c;
-				continue;
-			}
-			*p = '\0';
-			lungetc(c);
-			break;
-		}
-		val = symget(buf);
-		if (val == NULL) {
-			yyerror("macro '%s' not defined", buf);
-			return (findeol());
-		}
-		parsebuf = val;
-		parseindex = 0;
-		goto top;
-	}
-
 	switch (c) {
 	case '\'':
 	case '"':
@@ -899,7 +822,7 @@ nodigits:
 	(isalnum((unsigned char)x) || \
 	(ispunct((unsigned char)x) && x != '(' && x != ')' && \
 	x != '{' && x != '}' && \
-	x != '!' && x != '=' && x != '#' && \
+	x != '!' && x != '#' && \
 	x != ','))
 
 	if (isalnum((unsigned char)c) || c == ':' || c == '_') {
@@ -974,7 +897,6 @@ gotsys_conf_parse(const char *filename, struct gotsys_
     int *fd)
 {
 	const struct got_error *error;
-	struct sym *sym, *next;
 	struct gotsys_user *user;
 	struct gotsys_repo *repo;
 	struct gotsys_access_rule *rule;
@@ -988,17 +910,6 @@ gotsys_conf_parse(const char *filename, struct gotsys_
 	yyparse();
 	closefile(file);
 
-	/* Free macros and check which have not been used. */
-	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
-		fprintf(stderr, "warning: macro '%s' not used\n", sym->nam);
-		if (!sym->persist) {
-			free(sym->nam);
-			free(sym->val);
-			TAILQ_REMOVE(&symhead, sym, entry);
-			free(sym);
-		}
-	}
-
 	if (gerror)
 		return gerror;
 
@@ -1879,58 +1790,3 @@ done:
 	}
 	return ret;
 }
-
-int
-symset(const char *nam, const char *val, int persist)
-{
-	struct sym *sym;
-
-	TAILQ_FOREACH(sym, &symhead, entry) {
-		if (strcmp(nam, sym->nam) == 0)
-			break;
-	}
-
-	if (sym != NULL) {
-		if (sym->persist == 1)
-			return (0);
-		else {
-			free(sym->nam);
-			free(sym->val);
-			TAILQ_REMOVE(&symhead, sym, entry);
-			free(sym);
-		}
-	}
-	sym = calloc(1, sizeof(*sym));
-	if (sym == NULL)
-		return (-1);
-
-	sym->nam = strdup(nam);
-	if (sym->nam == NULL) {
-		free(sym);
-		return (-1);
-	}
-	sym->val = strdup(val);
-	if (sym->val == NULL) {
-		free(sym->nam);
-		free(sym);
-		return (-1);
-	}
-	sym->used = 0;
-	sym->persist = persist;
-	TAILQ_INSERT_TAIL(&symhead, sym, entry);
-	return (0);
-}
-
-char *
-symget(const char *nam)
-{
-	struct sym *sym;
-
-	TAILQ_FOREACH(sym, &symhead, entry) {
-		if (strcmp(nam, sym->nam) == 0) {
-			sym->used = 1;
-			return (sym->val);
-		}
-	}
-	return (NULL);
-}