- dtucker@cvs.openbsd.org 2007/02/19 10:45:58
     [monitor_wrap.c servconf.c servconf.h monitor.c sshd_config.5]
     Teach Match how handle config directives that are used before
     authentication.  This allows configurations such as permitting password
     authentication from the local net only while requiring pubkey from
     offsite.  ok djm@, man page bits ok jmc@
diff --git a/servconf.c b/servconf.c
index 872ff4a..86949c3 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.c,v 1.167 2006/12/14 10:01:14 dtucker Exp $ */
+/* $OpenBSD: servconf.c,v 1.168 2007/02/19 10:45:58 dtucker Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -325,14 +325,14 @@
 	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
 	{ "loglevel", sLogLevel, SSHCFG_GLOBAL },
 	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
-	{ "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
-	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
+	{ "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
+	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
-	{ "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
-	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
+	{ "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
+	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
 	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },	/* alias */
 #ifdef KRB5
-	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
+	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
 	{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
 #ifdef USE_AFS
@@ -341,7 +341,7 @@
 	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
 #endif
 #else
-	{ "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
+	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
 	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
 	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
 	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
@@ -349,15 +349,15 @@
 	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
 	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
 #ifdef GSSAPI
-	{ "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
+	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
 	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
 #else
-	{ "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
+	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
 	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
 #endif
-	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
-	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
-	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
+	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
+	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
+	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_ALL },
 	{ "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
 	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
 	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
@@ -389,7 +389,7 @@
 	{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
 	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
 	{ "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
-	{ "banner", sBanner, SSHCFG_GLOBAL },
+	{ "banner", sBanner, SSHCFG_ALL },
 	{ "usedns", sUseDNS, SSHCFG_GLOBAL },
 	{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
 	{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
@@ -1317,30 +1317,56 @@
 
 	initialize_server_options(&mo);
 	parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
-	copy_set_server_options(options, &mo);
+	copy_set_server_options(options, &mo, 0);
 }
 
-/* Copy any (supported) values that are set */
+/* Helper macros */
+#define M_CP_INTOPT(n) do {\
+	if (src->n != -1) \
+		dst->n = src->n; \
+} while (0)
+#define M_CP_STROPT(n) do {\
+	if (src->n != NULL) { \
+		if (dst->n != NULL) \
+			xfree(dst->n); \
+		dst->n = src->n; \
+	} \
+} while(0)
+
+/*
+ * Copy any supported values that are set.
+ *
+ * If the preauth flag is set, we do not bother copying the the string or
+ * array values that are not used pre-authentication, because any that we
+ * do use must be explictly sent in mm_getpwnamallow().
+ */
 void
-copy_set_server_options(ServerOptions *dst, ServerOptions *src)
+copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
 {
-	if (src->allow_tcp_forwarding != -1)
-		dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
-	if (src->gateway_ports != -1)
-		dst->gateway_ports = src->gateway_ports;
-	if (src->adm_forced_command != NULL) {
-		if (dst->adm_forced_command != NULL)
-			xfree(dst->adm_forced_command);
-		dst->adm_forced_command = src->adm_forced_command;
-	}
-	if (src->x11_display_offset != -1)
-		dst->x11_display_offset = src->x11_display_offset;
-	if (src->x11_forwarding != -1)
-		dst->x11_forwarding = src->x11_forwarding;
-	if (src->x11_use_localhost != -1)
-		dst->x11_use_localhost = src->x11_use_localhost;
+	M_CP_INTOPT(password_authentication);
+	M_CP_INTOPT(gss_authentication);
+	M_CP_INTOPT(rsa_authentication);
+	M_CP_INTOPT(pubkey_authentication);
+	M_CP_INTOPT(kerberos_authentication);
+	M_CP_INTOPT(hostbased_authentication);
+	M_CP_INTOPT(kbd_interactive_authentication);
+	M_CP_INTOPT(challenge_response_authentication);
+
+	M_CP_INTOPT(allow_tcp_forwarding);
+	M_CP_INTOPT(gateway_ports);
+	M_CP_INTOPT(x11_display_offset);
+	M_CP_INTOPT(x11_forwarding);
+	M_CP_INTOPT(x11_use_localhost);
+
+	M_CP_STROPT(banner);
+	if (preauth)
+		return;
+	M_CP_STROPT(adm_forced_command);
 }
 
+#undef M_CP_INTOPT
+#undef M_CP_STROPT
+
 void
 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
     const char *user, const char *host, const char *address)