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
diff --git a/servconf.c b/servconf.c
index 53d81fb..44de353 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
 
-/* $OpenBSD: servconf.c,v 1.318 2017/10/25 02:10:39 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.319 2017/11/03 03:18:53 dtucker Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -927,6 +927,13 @@
 	return result;
 }
 
+static void
+match_test_missing_fatal(const char *criteria, const char *attrib)
+{
+	fatal("'Match %s' in configuration but '%s' not in connection "
+	    "test specification.", criteria, attrib);
+}
+
 /*
  * All of the attributes on a single Match line are ANDed together, so we need
  * to check every attribute and set the result to zero if any attribute does
@@ -964,20 +971,24 @@
 			return -1;
 		}
 		if (strcasecmp(attrib, "user") == 0) {
-			if (ci == NULL || ci->user == NULL) {
+			if (ci == NULL) {
 				result = 0;
 				continue;
 			}
+			if (ci->user == NULL)
+				match_test_missing_fatal("User", "user");
 			if (match_pattern_list(ci->user, arg, 0) != 1)
 				result = 0;
 			else
 				debug("user %.100s matched 'User %.100s' at "
 				    "line %d", ci->user, arg, line);
 		} else if (strcasecmp(attrib, "group") == 0) {
-			if (ci == NULL || ci->user == NULL) {
+			if (ci == NULL) {
 				result = 0;
 				continue;
 			}
+			if (ci->user == NULL)
+				match_test_missing_fatal("Group", "user");
 			switch (match_cfg_line_group(arg, line, ci->user)) {
 			case -1:
 				return -1;
@@ -985,20 +996,24 @@
 				result = 0;
 			}
 		} else if (strcasecmp(attrib, "host") == 0) {
-			if (ci == NULL || ci->host == NULL) {
+			if (ci == NULL) {
 				result = 0;
 				continue;
 			}
+			if (ci->host == NULL)
+				match_test_missing_fatal("Host", "host");
 			if (match_hostname(ci->host, arg) != 1)
 				result = 0;
 			else
 				debug("connection from %.100s matched 'Host "
 				    "%.100s' at line %d", ci->host, arg, line);
 		} else if (strcasecmp(attrib, "address") == 0) {
-			if (ci == NULL || ci->address == NULL) {
+			if (ci == NULL) {
 				result = 0;
 				continue;
 			}
+			if (ci->address == NULL)
+				match_test_missing_fatal("Address", "addr");
 			switch (addr_match_list(ci->address, arg)) {
 			case 1:
 				debug("connection from %.100s matched 'Address "
@@ -1012,10 +1027,13 @@
 				return -1;
 			}
 		} else if (strcasecmp(attrib, "localaddress") == 0){
-			if (ci == NULL || ci->laddress == NULL) {
+			if (ci == NULL) {
 				result = 0;
 				continue;
 			}
+			if (ci->laddress == NULL)
+				match_test_missing_fatal("LocalAddress",
+				    "laddr");
 			switch (addr_match_list(ci->laddress, arg)) {
 			case 1:
 				debug("connection from %.100s matched "
@@ -1035,10 +1053,12 @@
 				    arg);
 				return -1;
 			}
-			if (ci == NULL || ci->lport == 0) {
+			if (ci == NULL) {
 				result = 0;
 				continue;
 			}
+			if (ci->lport == 0)
+				match_test_missing_fatal("LocalPort", "lport");
 			/* TODO support port lists */
 			if (port == ci->lport)
 				debug("connection from %.100s matched "
@@ -2117,19 +2137,6 @@
 }
 
 /*
- * returns 1 for a complete spec, 0 for partial spec and -1 for an
- * empty spec.
- */
-int server_match_spec_complete(struct connection_info *ci)
-{
-	if (ci->user && ci->host && ci->address)
-		return 1;	/* complete */
-	if (!ci->user && !ci->host && !ci->address)
-		return -1;	/* empty */
-	return 0;	/* partial */
-}
-
-/*
  * Copy any supported values that are set.
  *
  * If the preauth flag is set, we do not bother copying the string or