From: djm Date: Tue, 8 Jun 2021 06:54:40 +0000 (+0000) Subject: Allow argv_split() to optionally terminate tokenisation when it X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=86a8bd52db7b583922339da4f948c4412c57d25e;p=openbsd Allow argv_split() to optionally terminate tokenisation when it encounters an unquoted comment. Add some additional utility function for working with argument vectors, since we'll be switching to using them to parse ssh/sshd_config shortly. ok markus@ as part of a larger diff; tested in snaps --- diff --git a/usr.bin/ssh/auth2-pubkey.c b/usr.bin/ssh/auth2-pubkey.c index b77d353afa1..7c6fe33c2f3 100644 --- a/usr.bin/ssh/auth2-pubkey.c +++ b/usr.bin/ssh/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.107 2021/04/03 06:18:40 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.108 2021/06/08 06:54:40 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -472,7 +472,8 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw, } /* Turn the command into an argument vector */ - if (argv_split(options.authorized_principals_command, &ac, &av) != 0) { + if (argv_split(options.authorized_principals_command, + &ac, &av, 0) != 0) { error("AuthorizedPrincipalsCommand \"%s\" contains " "invalid quotes", options.authorized_principals_command); goto out; @@ -923,7 +924,7 @@ user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw, } /* Turn the command into an argument vector */ - if (argv_split(options.authorized_keys_command, &ac, &av) != 0) { + if (argv_split(options.authorized_keys_command, &ac, &av, 0) != 0) { error("AuthorizedKeysCommand \"%s\" contains invalid quotes", options.authorized_keys_command); goto out; diff --git a/usr.bin/ssh/misc.c b/usr.bin/ssh/misc.c index 94a1ea8266c..ea45b00c742 100644 --- a/usr.bin/ssh/misc.c +++ b/usr.bin/ssh/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.165 2021/06/04 05:02:40 djm Exp $ */ +/* $OpenBSD: misc.c,v 1.166 2021/06/08 06:54:40 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005-2020 Damien Miller. All rights reserved. @@ -71,6 +71,20 @@ chop(char *s) } +/* remove whitespace from end of string */ +void +rtrim(char *s) +{ + size_t i; + + if ((i = strlen(s)) == 0) + return; + for (i--; i > 0; i--) { + if (isspace((int)s[i])) + s[i] = '\0'; + } +} + /* set/unset filedescriptor to non-blocking */ int set_nonblock(int fd) @@ -1823,14 +1837,13 @@ daemonized(void) return 1; } - /* * Splits 's' into an argument vector. Handles quoted string and basic * escape characters (\\, \", \'). Caller must free the argument vector * and its members. */ int -argv_split(const char *s, int *argcp, char ***argvp) +argv_split(const char *s, int *argcp, char ***argvp, int terminate_on_comment) { int r = SSH_ERR_INTERNAL_ERROR; int argc = 0, quote, i, j; @@ -1843,7 +1856,8 @@ argv_split(const char *s, int *argcp, char ***argvp) /* Skip leading whitespace */ if (s[i] == ' ' || s[i] == '\t') continue; - + if (terminate_on_comment && s[i] == '#') + break; /* Start of a token */ quote = 0; @@ -1856,7 +1870,8 @@ argv_split(const char *s, int *argcp, char ***argvp) if (s[i] == '\\') { if (s[i + 1] == '\'' || s[i + 1] == '\"' || - s[i + 1] == '\\') { + s[i + 1] == '\\' || + (quote == 0 && s[i + 1] == ' ')) { i++; /* Skip '\' */ arg[j++] = s[i]; } else { @@ -1950,6 +1965,36 @@ argv_assemble(int argc, char **argv) return ret; } +char * +argv_next(int *argcp, char ***argvp) +{ + char *ret = (*argvp)[0]; + + if (*argcp > 0 && ret != NULL) { + (*argcp)--; + (*argvp)++; + } + return ret; +} + +void +argv_consume(int *argcp) +{ + *argcp = 0; +} + +void +argv_free(char **av, int ac) +{ + int i; + + if (av == NULL) + return; + for (i = 0; i < ac; i++) + free(av[i]); + free(av); +} + /* Returns 0 if pid exited cleanly, non-zero otherwise */ int exited_cleanly(pid_t pid, const char *tag, const char *cmd, int quiet) diff --git a/usr.bin/ssh/misc.h b/usr.bin/ssh/misc.h index eba125c88c6..7c65d2370af 100644 --- a/usr.bin/ssh/misc.h +++ b/usr.bin/ssh/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.96 2021/06/04 05:02:40 djm Exp $ */ +/* $OpenBSD: misc.h,v 1.97 2021/06/08 06:54:40 djm Exp $ */ /* * Author: Tatu Ylonen @@ -45,6 +45,7 @@ struct ForwardOptions { /* misc.c */ char *chop(char *); +void rtrim(char *); void skip_space(char **); char *strdelim(char **); char *strdelimw(char **); @@ -176,8 +177,12 @@ void child_set_env(char ***envp, u_int *envsizep, const char *name, const char *lookup_env_in_list(const char *env, char * const *envs, size_t nenvs); -int argv_split(const char *, int *, char ***); +int argv_split(const char *, int *, char ***, int); char *argv_assemble(int, char **argv); +char *argv_next(int *, char ***); +void argv_consume(int *); +void argv_free(char **, int); + int exited_cleanly(pid_t, const char *, const char *, int); struct stat; diff --git a/usr.bin/ssh/sshconnect.c b/usr.bin/ssh/sshconnect.c index 72fdad1166c..983c0f0a4c2 100644 --- a/usr.bin/ssh/sshconnect.c +++ b/usr.bin/ssh/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.352 2021/04/03 06:18:41 djm Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.353 2021/06/08 06:54:40 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -827,7 +827,7 @@ load_hostkeys_command(struct hostkeys *hostkeys, const char *command_template, osigchld = ssh_signal(SIGCHLD, SIG_DFL); /* Turn the command into an argument vector */ - if (argv_split(command_template, &ac, &av) != 0) { + if (argv_split(command_template, &ac, &av, 0) != 0) { error("%s \"%s\" contains invalid quotes", tag, command_template); goto out;