summaryrefslogtreecommitdiff
path: root/readconf.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2018-11-23 05:08:07 +0000
committerDamien Miller <djm@mindrot.org>2018-11-23 16:09:12 +1100
commit9e34e0c59ab04514f9de9934a772283f7f372afe (patch)
tree4306e1438b1efe0283b635d4d4ed1256cff0fe59 /readconf.c
parent4da58d58736b065b1182b563d10ad6765d811c6d (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.c44
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
134static int read_config_file_depth(const char *filename, struct passwd *pw, 134static 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);
137static int process_config_line_depth(Options *options, struct passwd *pw, 137static 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 */
540static int 541static int
541match_cfg_line(Options *options, char **condition, struct passwd *pw, 542match_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"
831static int 840static int
832process_config_line_depth(Options *options, struct passwd *pw, const char *host, 841process_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 */
1752int 1762int
1753read_config_file(const char *filename, struct passwd *pw, const char *host, 1763read_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
1763static int 1774static int
1764read_config_file_depth(const char *filename, struct passwd *pw, 1775read_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);