upstream commit

Expand ssh_config's StrictModes option with two new
settings:

StrictModes=accept-new will automatically accept hitherto-unseen keys
but will refuse connections for changed or invalid hostkeys.

StrictModes=off is the same as StrictModes=no

Motivation:

StrictModes=no combines two behaviours for host key processing:
automatically learning new hostkeys and continuing to connect to hosts
with invalid/changed hostkeys. The latter behaviour is quite dangerous
since it removes most of the protections the SSH protocol is supposed to
provide.

Quite a few users want to automatically learn hostkeys however, so
this makes that feature available with less danger.

At some point in the future, StrictModes=no will change to be a synonym
for accept-new, with its current behaviour remaining available via
StrictModes=off.

bz#2400, suggested by Michael Samuel; ok markus

Upstream-ID: 0f55502bf75fc93a74fb9853264a8276b9680b64
diff --git a/readconf.c b/readconf.c
index b11c628..4f38b27 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.277 2017/05/30 18:58:37 bluhm Exp $ */
+/* $OpenBSD: readconf.c,v 1.278 2017/09/03 23:33:13 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -751,6 +751,16 @@
 	{ "ask",			2 },
 	{ NULL, -1 }
 };
+static const struct multistate multistate_strict_hostkey[] = {
+	{ "true",			SSH_STRICT_HOSTKEY_YES },
+	{ "false",			SSH_STRICT_HOSTKEY_OFF },
+	{ "yes",			SSH_STRICT_HOSTKEY_YES },
+	{ "no",				SSH_STRICT_HOSTKEY_OFF },
+	{ "ask",			SSH_STRICT_HOSTKEY_ASK },
+	{ "off",			SSH_STRICT_HOSTKEY_OFF },
+	{ "accept-new",			SSH_STRICT_HOSTKEY_NEW },
+	{ NULL, -1 }
+};
 static const struct multistate multistate_yesnoaskconfirm[] = {
 	{ "true",			1 },
 	{ "false",			0 },
@@ -984,7 +994,7 @@
 
 	case oStrictHostKeyChecking:
 		intptr = &options->strict_host_key_checking;
-		multistate_ptr = multistate_yesnoask;
+		multistate_ptr = multistate_strict_hostkey;
 		goto parse_multistate;
 
 	case oCompression:
@@ -1927,7 +1937,7 @@
 	if (options->check_host_ip == -1)
 		options->check_host_ip = 1;
 	if (options->strict_host_key_checking == -1)
-		options->strict_host_key_checking = 2;	/* 2 is default */
+		options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
 	if (options->compression == -1)
 		options->compression = 0;
 	if (options->tcp_keep_alive == -1)
@@ -2329,9 +2339,10 @@
 	case oAddressFamily:
 		return fmt_multistate_int(val, multistate_addressfamily);
 	case oVerifyHostKeyDNS:
-	case oStrictHostKeyChecking:
 	case oUpdateHostkeys:
 		return fmt_multistate_int(val, multistate_yesnoask);
+	case oStrictHostKeyChecking:
+		return fmt_multistate_int(val, multistate_strict_hostkey);
 	case oControlMaster:
 		return fmt_multistate_int(val, multistate_controlmaster);
 	case oTunnel: