From 4343c50f6d426ae4d5abd48742a8e26e2445a3bf Mon Sep 17 00:00:00 2001 From: djm Date: Sun, 15 Sep 2024 00:57:36 +0000 Subject: [PATCH] switch "Match" directive processing over to the argv string tokeniser, making it possible to use shell-like quoting in Match directives, particularly "Match exec". ok markus@ --- usr.bin/ssh/readconf.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c index d8bd498ba2a..33bb91adbfe 100644 --- a/usr.bin/ssh/readconf.c +++ b/usr.bin/ssh/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.389 2024/09/03 05:29:55 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.390 2024/09/15 00:57:36 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -683,11 +683,11 @@ expand_match_exec_or_include_path(const char *path, Options *options, * Parse and execute a Match directive. */ static int -match_cfg_line(Options *options, char **condition, struct passwd *pw, - const char *host_arg, const char *original_host, int final_pass, - int *want_final_pass, const char *filename, int linenum) +match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, + struct passwd *pw, const char *host_arg, const char *original_host, + int final_pass, int *want_final_pass, const char *filename, int linenum) { - char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; + char *arg, *oattrib, *attrib, *cmd, *host, *criteria; const char *ruser; int r, this_result, result = 1, attributes = 0, negate; @@ -707,11 +707,11 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, } debug2("checking match for '%s' host %s originally %s", - cp, host, original_host); - while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { + full_line, host, original_host); + while ((oattrib = attrib = argv_next(acp, avp)) != NULL) { /* Terminate on comment */ if (*attrib == '#') { - cp = NULL; /* mark all arguments consumed */ + argv_consume(acp); break; } arg = criteria = NULL; @@ -720,7 +720,8 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, attrib++; /* Criterion "all" has no argument and must appear alone */ if (strcasecmp(attrib, "all") == 0) { - if (attributes > 1 || ((arg = strdelim(&cp)) != NULL && + if (attributes > 1 || + ((arg = argv_next(acp, avp)) != NULL && *arg != '\0' && *arg != '#')) { error("%.200s line %d: '%s' cannot be combined " "with other Match attributes", @@ -729,7 +730,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, goto out; } if (arg != NULL && *arg == '#') - cp = NULL; /* mark all arguments consumed */ + argv_consume(acp); /* consume remaining args */ if (result) result = negate ? 0 : 1; goto out; @@ -754,7 +755,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, continue; } /* All other criteria require an argument */ - if ((arg = strdelim(&cp)) == NULL || + if ((arg = argv_next(acp, avp)) == NULL || *arg == '\0' || *arg == '#') { error("Missing Match criteria for %s", attrib); result = -1; @@ -841,7 +842,6 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, out: if (result != -1) debug2("match %sfound", result ? "" : "not "); - *condition = cp; free(host); return result; } @@ -1784,8 +1784,8 @@ parse_pubkey_algos: "option"); goto out; } - value = match_cfg_line(options, &str, pw, host, original_host, - flags & SSHCONF_FINAL, want_final_pass, + value = match_cfg_line(options, str, &ac, &av, pw, host, + original_host, flags & SSHCONF_FINAL, want_final_pass, filename, linenum); if (value < 0) { error("%.200s line %d: Bad Match condition", filename, @@ -1793,13 +1793,6 @@ parse_pubkey_algos: goto out; } *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value; - /* - * If match_cfg_line() didn't consume all its arguments then - * arrange for the extra arguments check below to fail. - */ - - if (str == NULL || *str == '\0') - argv_consume(&ac); break; case oEscapeChar: -- 2.20.1