diff options
author | djm@openbsd.org <djm@openbsd.org> | 2018-11-23 05:08:07 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2018-11-23 16:09:12 +1100 |
commit | 9e34e0c59ab04514f9de9934a772283f7f372afe (patch) | |
tree | 4306e1438b1efe0283b635d4d4ed1256cff0fe59 /readconf.c | |
parent | 4da58d58736b065b1182b563d10ad6765d811c6d (diff) |
upstream: add a ssh_config "Match final" predicate
Matches in same pass as "Match canonical" but doesn't require
hostname canonicalisation be enabled. bz#2906 ok markus
OpenBSD-Commit-ID: fba1dfe9f6e0cabcd0e2b3be13f7a434199beffa
Diffstat (limited to 'readconf.c')
-rw-r--r-- | readconf.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/readconf.c b/readconf.c index 7850f2f59..7331ef5ad 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.c,v 1.301 2018/11/16 03:26:01 djm Exp $ */ | 1 | /* $OpenBSD: readconf.c,v 1.302 2018/11/23 05:08:07 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -133,10 +133,11 @@ | |||
133 | 133 | ||
134 | static int read_config_file_depth(const char *filename, struct passwd *pw, | 134 | static int read_config_file_depth(const char *filename, struct passwd *pw, |
135 | const char *host, const char *original_host, Options *options, | 135 | const char *host, const char *original_host, Options *options, |
136 | int flags, int *activep, int depth); | 136 | int flags, int *activep, int *want_final_pass, int depth); |
137 | static int process_config_line_depth(Options *options, struct passwd *pw, | 137 | static int process_config_line_depth(Options *options, struct passwd *pw, |
138 | const char *host, const char *original_host, char *line, | 138 | const char *host, const char *original_host, char *line, |
139 | const char *filename, int linenum, int *activep, int flags, int depth); | 139 | const char *filename, int linenum, int *activep, int flags, |
140 | int *want_final_pass, int depth); | ||
140 | 141 | ||
141 | /* Keyword tokens. */ | 142 | /* Keyword tokens. */ |
142 | 143 | ||
@@ -539,8 +540,8 @@ execute_in_shell(const char *cmd) | |||
539 | */ | 540 | */ |
540 | static int | 541 | static int |
541 | match_cfg_line(Options *options, char **condition, struct passwd *pw, | 542 | match_cfg_line(Options *options, char **condition, struct passwd *pw, |
542 | const char *host_arg, const char *original_host, int post_canon, | 543 | const char *host_arg, const char *original_host, int final_pass, |
543 | const char *filename, int linenum) | 544 | int *want_final_pass, const char *filename, int linenum) |
544 | { | 545 | { |
545 | char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; | 546 | char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; |
546 | const char *ruser; | 547 | const char *ruser; |
@@ -554,7 +555,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
554 | */ | 555 | */ |
555 | port = options->port <= 0 ? default_ssh_port() : options->port; | 556 | port = options->port <= 0 ? default_ssh_port() : options->port; |
556 | ruser = options->user == NULL ? pw->pw_name : options->user; | 557 | ruser = options->user == NULL ? pw->pw_name : options->user; |
557 | if (post_canon) { | 558 | if (final_pass) { |
558 | host = xstrdup(options->hostname); | 559 | host = xstrdup(options->hostname); |
559 | } else if (options->hostname != NULL) { | 560 | } else if (options->hostname != NULL) { |
560 | /* NB. Please keep in sync with ssh.c:main() */ | 561 | /* NB. Please keep in sync with ssh.c:main() */ |
@@ -586,8 +587,16 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
586 | goto out; | 587 | goto out; |
587 | } | 588 | } |
588 | attributes++; | 589 | attributes++; |
589 | if (strcasecmp(attrib, "canonical") == 0) { | 590 | if (strcasecmp(attrib, "canonical") == 0 || |
590 | r = !!post_canon; /* force bitmask member to boolean */ | 591 | strcasecmp(attrib, "final") == 0) { |
592 | /* | ||
593 | * If the config requests "Match final" then remember | ||
594 | * this so we can perform a second pass later. | ||
595 | */ | ||
596 | if (strcasecmp(attrib, "final") == 0 && | ||
597 | want_final_pass != NULL) | ||
598 | *want_final_pass = 1; | ||
599 | r = !!final_pass; /* force bitmask member to boolean */ | ||
591 | if (r == (negate ? 1 : 0)) | 600 | if (r == (negate ? 1 : 0)) |
592 | this_result = result = 0; | 601 | this_result = result = 0; |
593 | debug3("%.200s line %d: %smatched '%s'", | 602 | debug3("%.200s line %d: %smatched '%s'", |
@@ -824,14 +833,14 @@ process_config_line(Options *options, struct passwd *pw, const char *host, | |||
824 | int linenum, int *activep, int flags) | 833 | int linenum, int *activep, int flags) |
825 | { | 834 | { |
826 | return process_config_line_depth(options, pw, host, original_host, | 835 | return process_config_line_depth(options, pw, host, original_host, |
827 | line, filename, linenum, activep, flags, 0); | 836 | line, filename, linenum, activep, flags, NULL, 0); |
828 | } | 837 | } |
829 | 838 | ||
830 | #define WHITESPACE " \t\r\n" | 839 | #define WHITESPACE " \t\r\n" |
831 | static int | 840 | static int |
832 | process_config_line_depth(Options *options, struct passwd *pw, const char *host, | 841 | process_config_line_depth(Options *options, struct passwd *pw, const char *host, |
833 | const char *original_host, char *line, const char *filename, | 842 | const char *original_host, char *line, const char *filename, |
834 | int linenum, int *activep, int flags, int depth) | 843 | int linenum, int *activep, int flags, int *want_final_pass, int depth) |
835 | { | 844 | { |
836 | char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; | 845 | char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; |
837 | char **cpptr, fwdarg[256]; | 846 | char **cpptr, fwdarg[256]; |
@@ -1339,7 +1348,8 @@ parse_keytypes: | |||
1339 | fatal("Host directive not supported as a command-line " | 1348 | fatal("Host directive not supported as a command-line " |
1340 | "option"); | 1349 | "option"); |
1341 | value = match_cfg_line(options, &s, pw, host, original_host, | 1350 | value = match_cfg_line(options, &s, pw, host, original_host, |
1342 | flags & SSHCONF_POSTCANON, filename, linenum); | 1351 | flags & SSHCONF_FINAL, want_final_pass, |
1352 | filename, linenum); | ||
1343 | if (value < 0) | 1353 | if (value < 0) |
1344 | fatal("%.200s line %d: Bad Match condition", filename, | 1354 | fatal("%.200s line %d: Bad Match condition", filename, |
1345 | linenum); | 1355 | linenum); |
@@ -1548,7 +1558,7 @@ parse_keytypes: | |||
1548 | pw, host, original_host, options, | 1558 | pw, host, original_host, options, |
1549 | flags | SSHCONF_CHECKPERM | | 1559 | flags | SSHCONF_CHECKPERM | |
1550 | (oactive ? 0 : SSHCONF_NEVERMATCH), | 1560 | (oactive ? 0 : SSHCONF_NEVERMATCH), |
1551 | activep, depth + 1); | 1561 | activep, want_final_pass, depth + 1); |
1552 | if (r != 1 && errno != ENOENT) { | 1562 | if (r != 1 && errno != ENOENT) { |
1553 | fatal("Can't open user config file " | 1563 | fatal("Can't open user config file " |
1554 | "%.100s: %.100s", gl.gl_pathv[i], | 1564 | "%.100s: %.100s", gl.gl_pathv[i], |
@@ -1751,19 +1761,20 @@ parse_keytypes: | |||
1751 | */ | 1761 | */ |
1752 | int | 1762 | int |
1753 | read_config_file(const char *filename, struct passwd *pw, const char *host, | 1763 | read_config_file(const char *filename, struct passwd *pw, const char *host, |
1754 | const char *original_host, Options *options, int flags) | 1764 | const char *original_host, Options *options, int flags, |
1765 | int *want_final_pass) | ||
1755 | { | 1766 | { |
1756 | int active = 1; | 1767 | int active = 1; |
1757 | 1768 | ||
1758 | return read_config_file_depth(filename, pw, host, original_host, | 1769 | return read_config_file_depth(filename, pw, host, original_host, |
1759 | options, flags, &active, 0); | 1770 | options, flags, &active, want_final_pass, 0); |
1760 | } | 1771 | } |
1761 | 1772 | ||
1762 | #define READCONF_MAX_DEPTH 16 | 1773 | #define READCONF_MAX_DEPTH 16 |
1763 | static int | 1774 | static int |
1764 | read_config_file_depth(const char *filename, struct passwd *pw, | 1775 | read_config_file_depth(const char *filename, struct passwd *pw, |
1765 | const char *host, const char *original_host, Options *options, | 1776 | const char *host, const char *original_host, Options *options, |
1766 | int flags, int *activep, int depth) | 1777 | int flags, int *activep, int *want_final_pass, int depth) |
1767 | { | 1778 | { |
1768 | FILE *f; | 1779 | FILE *f; |
1769 | char *line = NULL; | 1780 | char *line = NULL; |
@@ -1798,7 +1809,8 @@ read_config_file_depth(const char *filename, struct passwd *pw, | |||
1798 | /* Update line number counter. */ | 1809 | /* Update line number counter. */ |
1799 | linenum++; | 1810 | linenum++; |
1800 | if (process_config_line_depth(options, pw, host, original_host, | 1811 | if (process_config_line_depth(options, pw, host, original_host, |
1801 | line, filename, linenum, activep, flags, depth) != 0) | 1812 | line, filename, linenum, activep, flags, want_final_pass, |
1813 | depth) != 0) | ||
1802 | bad_options++; | 1814 | bad_options++; |
1803 | } | 1815 | } |
1804 | free(line); | 1816 | free(line); |