openssh/upstream-fix-sshd-T-without-C.patch
2019-12-25 16:00:14 +08:00

169 lines
5.2 KiB
Diff

From: Darren Tucker
Date: 2019-04-18 19:42:28 EST
Subject: [PATCH] ssh-T
---
regress/cfgmatch.sh | 47 +++++++++++++++++++++++++++++++++++++++++++--
servconf.c | 14 ++++++++------
servconf.h | 2 ++
sshd.c | 1 +
4 files changed, 56 insertions(+), 8 deletions(-)
diff --git a/regress/cfgmatch.sh b/regress/cfgmatch.sh
index dd11e40..37fe6f8 100644
--- a/regress/cfgmatch.sh
+++ b/regress/cfgmatch.sh
@@ -51,9 +51,10 @@ echo "AuthorizedKeysFile /dev/null $OBJ/authorized_keys_%u" >>$OBJ/sshd_proxy
echo "Match Address 127.0.0.1" >>$OBJ/sshd_proxy
echo "PermitOpen 127.0.0.1:2 127.0.0.1:3 127.0.0.1:$PORT" >>$OBJ/sshd_proxy
-start_sshd
+${SUDO} ${SSHD} -f $OBJ/sshd_config -T >/dev/null || \
+ fail "config w/match fails config test"
-#set -x
+start_sshd
# Test Match + PermitOpen in sshd_config. This should be permitted
trace "match permitopen localhost"
@@ -113,3 +114,45 @@ start_client -F $OBJ/ssh_proxy
${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true || \
fail "nomatch override permitopen"
stop_client
+
+
+# Test parsing of available Match criteria (with the exception of Group which
+# requires knowledge of actual group memberships user running the test).
+params="user:user:u1 host:host:h1 address:addr:1.2.3.4 \
+ localaddress:laddr:5.6.7.8 rdomain:rdomain:rdom1"
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_config
+echo 'Banner /nomatch' >>$OBJ/sshd_config
+for i in $params; do
+ config=`echo $i | cut -f1 -d:`
+ criteria=`echo $i | cut -f2 -d:`
+ value=`echo $i | cut -f3 -d:`
+ cat >>$OBJ/sshd_config <<EOD
+ Match $config $value
+ Banner /$value
+EOD
+done
+${SUDO} ${SSHD} -f $OBJ/sshd_config -T >/dev/null || \
+ fail "validate config for w/out spec"
+
+# Test matching each criteria.
+for i in $params; do
+ testcriteria=`echo $i | cut -f2 -d:`
+ expected=/`echo $i | cut -f3 -d:`
+ spec=""
+ for j in $params; do
+ config=`echo $j | cut -f1 -d:`
+ criteria=`echo $j | cut -f2 -d:`
+ value=`echo $j | cut -f3 -d:`
+ if [ "$criteria" = "$testcriteria" ]; then
+ spec="$criteria=$value,$spec"
+ else
+ spec="$criteria=1$value,$spec"
+ fi
+ done
+ trace "test spec $spec"
+ result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \
+ awk '$1=="banner"{print $2}'`
+ if [ "$result" != "$expected" ]; then
+ fail "match $config expected $expected got $result"
+ fi
+done
diff --git a/servconf.c b/servconf.c
index 434f0bc..9f363c9 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1075,7 +1075,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
return -1;
}
if (strcasecmp(attrib, "user") == 0) {
- if (ci == NULL) {
+ if (ci == NULL || (ci->test && ci->user == NULL)) {
result = 0;
continue;
}
@@ -1087,7 +1087,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
debug("user %.100s matched 'User %.100s' at "
"line %d", ci->user, arg, line);
} else if (strcasecmp(attrib, "group") == 0) {
- if (ci == NULL) {
+ if (ci == NULL || (ci->test && ci->user == NULL)) {
result = 0;
continue;
}
@@ -1100,7 +1100,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
result = 0;
}
} else if (strcasecmp(attrib, "host") == 0) {
- if (ci == NULL) {
+ if (ci == NULL || (ci->test && ci->host == NULL)) {
result = 0;
continue;
}
@@ -1112,7 +1112,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
debug("connection from %.100s matched 'Host "
"%.100s' at line %d", ci->host, arg, line);
} else if (strcasecmp(attrib, "address") == 0) {
- if (ci == NULL) {
+ if (ci == NULL || (ci->test && ci->address == NULL)) {
result = 0;
continue;
}
@@ -1131,7 +1131,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
return -1;
}
} else if (strcasecmp(attrib, "localaddress") == 0){
- if (ci == NULL) {
+ if (ci == NULL || (ci->test && ci->laddress == NULL)) {
result = 0;
continue;
}
@@ -1157,7 +1157,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
arg);
return -1;
}
- if (ci == NULL) {
+ if (ci == NULL || (ci->test && ci->lport == -1)) {
result = 0;
continue;
}
@@ -1175,6 +1175,8 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
result = 0;
continue;
}
+ if (ci->rdomain == NULL)
+ match_test_missing_fatal("RDomain", "rdomain");
if (match_pattern_list(ci->rdomain, arg, 0) != 1)
result = 0;
else
diff --git a/servconf.h b/servconf.h
index fdbae24..381ed25 100644
--- a/servconf.h
+++ b/servconf.h
@@ -231,6 +231,8 @@ struct connection_info {
const char *laddress; /* local address */
int lport; /* local port */
const char *rdomain; /* routing domain if available */
+ int test; /* test mode, allow some attributes to be
+ * unspecified */
};
diff --git a/sshd.c b/sshd.c
index 6d081e4..a00b1af 100644
--- a/sshd.c
+++ b/sshd.c
@@ -2001,6 +2001,7 @@ main(int ac, char **av)
*/
if (connection_info == NULL)
connection_info = get_connection_info(0, 0);
+ connection_info->test = 1;
parse_server_match_config(&options, connection_info);
dump_config(&options);
}
--
2.19.1