diff options
author | dtucker@openbsd.org@openbsd.org <dtucker@openbsd.org@openbsd.org> | 2017-11-03 03:18:53 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-11-03 16:20:41 +1100 |
commit | 0208a48517b5e8e8b091f32fa4addcd67c31ca9e (patch) | |
tree | 46491aae590608502d7a3ef3a1510b361093c07d | |
parent | c357eed5a52cd2f4ff358b17e30e3f9a800644da (diff) |
upstream commit
When doing a config test with sshd -T, only require the
attributes that are actually used in Match criteria rather than (an
incomplete list of) all criteria. ok djm@, man page help jmc@
OpenBSD-Commit-ID: b4e773c4212d3dea486d0259ae977551aab2c1fc
-rw-r--r-- | servconf.c | 47 | ||||
-rw-r--r-- | sshd.8 | 23 | ||||
-rw-r--r-- | sshd.c | 18 |
3 files changed, 46 insertions, 42 deletions
diff --git a/servconf.c b/servconf.c index 53d81fb3c..44de35367 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | /* $OpenBSD: servconf.c,v 1.318 2017/10/25 02:10:39 djm Exp $ */ | 2 | /* $OpenBSD: servconf.c,v 1.319 2017/11/03 03:18:53 dtucker Exp $ */ |
3 | /* | 3 | /* |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
5 | * All rights reserved | 5 | * All rights reserved |
@@ -927,6 +927,13 @@ out: | |||
927 | return result; | 927 | return result; |
928 | } | 928 | } |
929 | 929 | ||
930 | static void | ||
931 | match_test_missing_fatal(const char *criteria, const char *attrib) | ||
932 | { | ||
933 | fatal("'Match %s' in configuration but '%s' not in connection " | ||
934 | "test specification.", criteria, attrib); | ||
935 | } | ||
936 | |||
930 | /* | 937 | /* |
931 | * All of the attributes on a single Match line are ANDed together, so we need | 938 | * All of the attributes on a single Match line are ANDed together, so we need |
932 | * to check every attribute and set the result to zero if any attribute does | 939 | * to check every attribute and set the result to zero if any attribute does |
@@ -964,20 +971,24 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) | |||
964 | return -1; | 971 | return -1; |
965 | } | 972 | } |
966 | if (strcasecmp(attrib, "user") == 0) { | 973 | if (strcasecmp(attrib, "user") == 0) { |
967 | if (ci == NULL || ci->user == NULL) { | 974 | if (ci == NULL) { |
968 | result = 0; | 975 | result = 0; |
969 | continue; | 976 | continue; |
970 | } | 977 | } |
978 | if (ci->user == NULL) | ||
979 | match_test_missing_fatal("User", "user"); | ||
971 | if (match_pattern_list(ci->user, arg, 0) != 1) | 980 | if (match_pattern_list(ci->user, arg, 0) != 1) |
972 | result = 0; | 981 | result = 0; |
973 | else | 982 | else |
974 | debug("user %.100s matched 'User %.100s' at " | 983 | debug("user %.100s matched 'User %.100s' at " |
975 | "line %d", ci->user, arg, line); | 984 | "line %d", ci->user, arg, line); |
976 | } else if (strcasecmp(attrib, "group") == 0) { | 985 | } else if (strcasecmp(attrib, "group") == 0) { |
977 | if (ci == NULL || ci->user == NULL) { | 986 | if (ci == NULL) { |
978 | result = 0; | 987 | result = 0; |
979 | continue; | 988 | continue; |
980 | } | 989 | } |
990 | if (ci->user == NULL) | ||
991 | match_test_missing_fatal("Group", "user"); | ||
981 | switch (match_cfg_line_group(arg, line, ci->user)) { | 992 | switch (match_cfg_line_group(arg, line, ci->user)) { |
982 | case -1: | 993 | case -1: |
983 | return -1; | 994 | return -1; |
@@ -985,20 +996,24 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) | |||
985 | result = 0; | 996 | result = 0; |
986 | } | 997 | } |
987 | } else if (strcasecmp(attrib, "host") == 0) { | 998 | } else if (strcasecmp(attrib, "host") == 0) { |
988 | if (ci == NULL || ci->host == NULL) { | 999 | if (ci == NULL) { |
989 | result = 0; | 1000 | result = 0; |
990 | continue; | 1001 | continue; |
991 | } | 1002 | } |
1003 | if (ci->host == NULL) | ||
1004 | match_test_missing_fatal("Host", "host"); | ||
992 | if (match_hostname(ci->host, arg) != 1) | 1005 | if (match_hostname(ci->host, arg) != 1) |
993 | result = 0; | 1006 | result = 0; |
994 | else | 1007 | else |
995 | debug("connection from %.100s matched 'Host " | 1008 | debug("connection from %.100s matched 'Host " |
996 | "%.100s' at line %d", ci->host, arg, line); | 1009 | "%.100s' at line %d", ci->host, arg, line); |
997 | } else if (strcasecmp(attrib, "address") == 0) { | 1010 | } else if (strcasecmp(attrib, "address") == 0) { |
998 | if (ci == NULL || ci->address == NULL) { | 1011 | if (ci == NULL) { |
999 | result = 0; | 1012 | result = 0; |
1000 | continue; | 1013 | continue; |
1001 | } | 1014 | } |
1015 | if (ci->address == NULL) | ||
1016 | match_test_missing_fatal("Address", "addr"); | ||
1002 | switch (addr_match_list(ci->address, arg)) { | 1017 | switch (addr_match_list(ci->address, arg)) { |
1003 | case 1: | 1018 | case 1: |
1004 | debug("connection from %.100s matched 'Address " | 1019 | debug("connection from %.100s matched 'Address " |
@@ -1012,10 +1027,13 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) | |||
1012 | return -1; | 1027 | return -1; |
1013 | } | 1028 | } |
1014 | } else if (strcasecmp(attrib, "localaddress") == 0){ | 1029 | } else if (strcasecmp(attrib, "localaddress") == 0){ |
1015 | if (ci == NULL || ci->laddress == NULL) { | 1030 | if (ci == NULL) { |
1016 | result = 0; | 1031 | result = 0; |
1017 | continue; | 1032 | continue; |
1018 | } | 1033 | } |
1034 | if (ci->laddress == NULL) | ||
1035 | match_test_missing_fatal("LocalAddress", | ||
1036 | "laddr"); | ||
1019 | switch (addr_match_list(ci->laddress, arg)) { | 1037 | switch (addr_match_list(ci->laddress, arg)) { |
1020 | case 1: | 1038 | case 1: |
1021 | debug("connection from %.100s matched " | 1039 | debug("connection from %.100s matched " |
@@ -1035,10 +1053,12 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) | |||
1035 | arg); | 1053 | arg); |
1036 | return -1; | 1054 | return -1; |
1037 | } | 1055 | } |
1038 | if (ci == NULL || ci->lport == 0) { | 1056 | if (ci == NULL) { |
1039 | result = 0; | 1057 | result = 0; |
1040 | continue; | 1058 | continue; |
1041 | } | 1059 | } |
1060 | if (ci->lport == 0) | ||
1061 | match_test_missing_fatal("LocalPort", "lport"); | ||
1042 | /* TODO support port lists */ | 1062 | /* TODO support port lists */ |
1043 | if (port == ci->lport) | 1063 | if (port == ci->lport) |
1044 | debug("connection from %.100s matched " | 1064 | debug("connection from %.100s matched " |
@@ -2117,19 +2137,6 @@ int parse_server_match_testspec(struct connection_info *ci, char *spec) | |||
2117 | } | 2137 | } |
2118 | 2138 | ||
2119 | /* | 2139 | /* |
2120 | * returns 1 for a complete spec, 0 for partial spec and -1 for an | ||
2121 | * empty spec. | ||
2122 | */ | ||
2123 | int server_match_spec_complete(struct connection_info *ci) | ||
2124 | { | ||
2125 | if (ci->user && ci->host && ci->address) | ||
2126 | return 1; /* complete */ | ||
2127 | if (!ci->user && !ci->host && !ci->address) | ||
2128 | return -1; /* empty */ | ||
2129 | return 0; /* partial */ | ||
2130 | } | ||
2131 | |||
2132 | /* | ||
2133 | * Copy any supported values that are set. | 2140 | * Copy any supported values that are set. |
2134 | * | 2141 | * |
2135 | * If the preauth flag is set, we do not bother copying the string or | 2142 | * If the preauth flag is set, we do not bother copying the string or |
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: sshd.8,v 1.292 2017/10/25 00:19:47 djm Exp $ | 36 | .\" $OpenBSD: sshd.8,v 1.293 2017/11/03 03:18:53 dtucker Exp $ |
37 | .Dd $Mdocdate: October 25 2017 $ | 37 | .Dd $Mdocdate: November 3 2017 $ |
38 | .Dt SSHD 8 | 38 | .Dt SSHD 8 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -100,21 +100,22 @@ Specify the connection parameters to use for the | |||
100 | extended test mode. | 100 | extended test mode. |
101 | If provided, any | 101 | If provided, any |
102 | .Cm Match | 102 | .Cm Match |
103 | directives in the configuration file | 103 | directives in the configuration file that would apply are applied before the |
104 | that would apply to the specified user, host, and address will be set before | 104 | configuration is written to standard output. |
105 | the configuration is written to standard output. | 105 | The connection parameters are supplied as keyword=value pairs and may be |
106 | The connection parameters are supplied as keyword=value pairs. | 106 | supplied in any order, either with multiple |
107 | .Fl C | ||
108 | options or as a comma-separated list. | ||
107 | The keywords are | 109 | The keywords are |
110 | .Dq addr, | ||
108 | .Dq user , | 111 | .Dq user , |
109 | .Dq host , | 112 | .Dq host , |
110 | .Dq laddr , | 113 | .Dq laddr , |
111 | .Dq lport , | 114 | .Dq lport , |
112 | .Dq rdomain | ||
113 | and | 115 | and |
114 | .Dq addr . | 116 | .Dq rdomain |
115 | All are required and may be supplied in any order, either with multiple | 117 | and correspond to source address, user, resolved source host name, |
116 | .Fl C | 118 | local address, local port number and routing domain respectively. |
117 | options or as a comma-separated list. | ||
118 | .It Fl c Ar host_certificate_file | 119 | .It Fl c Ar host_certificate_file |
119 | Specifies a path to a certificate file to identify | 120 | Specifies a path to a certificate file to identify |
120 | .Nm | 121 | .Nm |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.497 2017/10/27 00:18:41 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.498 2017/11/03 03:18:53 dtucker 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 |
@@ -1429,7 +1429,7 @@ main(int ac, char **av) | |||
1429 | struct sshkey *pubkey; | 1429 | struct sshkey *pubkey; |
1430 | int keytype; | 1430 | int keytype; |
1431 | Authctxt *authctxt; | 1431 | Authctxt *authctxt; |
1432 | struct connection_info *connection_info = get_connection_info(0, 0); | 1432 | struct connection_info *connection_info = NULL; |
1433 | 1433 | ||
1434 | ssh_malloc_init(); /* must be called before any mallocs */ | 1434 | ssh_malloc_init(); /* must be called before any mallocs */ |
1435 | 1435 | ||
@@ -1545,6 +1545,7 @@ main(int ac, char **av) | |||
1545 | test_flag = 2; | 1545 | test_flag = 2; |
1546 | break; | 1546 | break; |
1547 | case 'C': | 1547 | case 'C': |
1548 | connection_info = get_connection_info(0, 0); | ||
1548 | if (parse_server_match_testspec(connection_info, | 1549 | if (parse_server_match_testspec(connection_info, |
1549 | optarg) == -1) | 1550 | optarg) == -1) |
1550 | exit(1); | 1551 | exit(1); |
@@ -1613,14 +1614,10 @@ main(int ac, char **av) | |||
1613 | sensitive_data.have_ssh2_key = 0; | 1614 | sensitive_data.have_ssh2_key = 0; |
1614 | 1615 | ||
1615 | /* | 1616 | /* |
1616 | * If we're doing an extended config test, make sure we have all of | 1617 | * If we're not doing an extended test do not silently ignore connection |
1617 | * the parameters we need. If we're not doing an extended test, | 1618 | * test params. |
1618 | * do not silently ignore connection test params. | ||
1619 | */ | 1619 | */ |
1620 | if (test_flag >= 2 && server_match_spec_complete(connection_info) == 0) | 1620 | if (test_flag < 2 && connection_info != NULL) |
1621 | fatal("user, host and addr are all required when testing " | ||
1622 | "Match configs"); | ||
1623 | if (test_flag < 2 && server_match_spec_complete(connection_info) >= 0) | ||
1624 | fatal("Config test connection parameter (-C) provided without " | 1621 | fatal("Config test connection parameter (-C) provided without " |
1625 | "test mode (-T)"); | 1622 | "test mode (-T)"); |
1626 | 1623 | ||
@@ -1827,8 +1824,7 @@ main(int ac, char **av) | |||
1827 | } | 1824 | } |
1828 | 1825 | ||
1829 | if (test_flag > 1) { | 1826 | if (test_flag > 1) { |
1830 | if (server_match_spec_complete(connection_info) == 1) | 1827 | parse_server_match_config(&options, connection_info); |
1831 | parse_server_match_config(&options, connection_info); | ||
1832 | dump_config(&options); | 1828 | dump_config(&options); |
1833 | } | 1829 | } |
1834 | 1830 | ||