upstream: 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

OpenBSD-Commit-ID: fd9c108cef2f713f24e3bc5848861d221bb3a1ac
This commit is contained in:
djm@openbsd.org 2021-06-08 06:54:40 +00:00 committed by Damien Miller
parent da9f9acaac
commit aae4b4d358
4 changed files with 63 additions and 12 deletions

View File

@ -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.
*
@ -475,7 +475,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;
@ -926,7 +927,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;

55
misc.c
View File

@ -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.
@ -85,6 +85,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)
@ -1912,14 +1926,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;
@ -1932,7 +1945,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;
@ -1945,7 +1959,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 {
@ -2039,6 +2054,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)

9
misc.h
View File

@ -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 <ylo@cs.hut.fi>
@ -45,6 +45,7 @@ struct ForwardOptions {
/* misc.c */
char *chop(char *);
void rtrim(char *);
void skip_space(char **);
char *strdelim(char **);
char *strdelimw(char **);
@ -178,8 +179,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;

View File

@ -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 <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -865,7 +865,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;