From: Stefan Sperling Subject: remove gotsys.conf macro support To: gameoftrees@openbsd.org Date: Thu, 8 Jan 2026 11:21:05 +0100 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); -}