summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2017-09-03 23:33:13 +0000
committerDamien Miller <djm@mindrot.org>2017-09-04 09:38:57 +1000
commit22376d27a349f62c502fec3396dfe0fdcb2a40b7 (patch)
tree8368234874273df676d62ffab3bfc184ef58405f
parentff3c42384033514e248ba5d7376aa033f4a2b99a (diff)
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
-rw-r--r--readconf.c19
-rw-r--r--readconf.h7
-rw-r--r--ssh_config.518
-rw-r--r--sshconnect.c30
4 files changed, 52 insertions, 22 deletions
diff --git a/readconf.c b/readconf.c
index b11c628f..4f38b27c 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 @@ static const struct multistate multistate_yesnoask[] = {
{ "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 @@ parse_time:
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 @@ fill_default_options(Options * options)
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 @@ fmt_intarg(OpCodes code, int val)
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:
diff --git a/readconf.h b/readconf.h
index 94dd427f..22fe5c18 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.122 2017/05/30 18:58:37 bluhm Exp $ */
+/* $OpenBSD: readconf.h,v 1.123 2017/09/03 23:33:13 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -190,6 +190,11 @@ typedef struct {
#define SSH_UPDATE_HOSTKEYS_YES 1
#define SSH_UPDATE_HOSTKEYS_ASK 2
+#define SSH_STRICT_HOSTKEY_OFF 0
+#define SSH_STRICT_HOSTKEY_NEW 1
+#define SSH_STRICT_HOSTKEY_YES 2
+#define SSH_STRICT_HOSTKEY_ASK 3
+
void initialize_options(Options *);
void fill_default_options(Options *);
void fill_default_options_for_canonicalization(Options *);
diff --git a/ssh_config.5 b/ssh_config.5
index 15ca0b4f..3823da6f 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: ssh_config.5,v 1.253 2017/07/23 23:37:02 djm Exp $
-.Dd $Mdocdate: July 23 2017 $
+.\" $OpenBSD: ssh_config.5,v 1.254 2017/09/03 23:33:13 djm Exp $
+.Dd $Mdocdate: September 3 2017 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@@ -1459,9 +1459,17 @@ frequently made.
This option forces the user to manually
add all new hosts.
If this flag is set to
-.Cm no ,
-ssh will automatically add new host keys to the
-user known hosts files.
+.Dq accept-new
+then ssh will automatically add new new host keys to the user
+known hosts files, but will not permit connections to hosts with
+changed host keys.
+If this flag is set to
+.Dq no
+or
+.Dq off ,
+ssh will automatically add new host keys to the user known hosts files,
+and allow connections to hosts with changed hostkeys to proceed subject
+to some restrictions.
If this flag is set to
.Cm ask
(the default),
diff --git a/sshconnect.c b/sshconnect.c
index 4013ec7d..2842d9e5 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.284 2017/09/01 05:53:56 djm Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.285 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
@@ -891,7 +891,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
if (readonly || want_cert)
goto fail;
/* The host is new. */
- if (options.strict_host_key_checking == 1) {
+ if (options.strict_host_key_checking ==
+ SSH_STRICT_HOSTKEY_YES) {
/*
* User has requested strict host key checking. We
* will not add the host key automatically. The only
@@ -900,7 +901,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
error("No %s host key is known for %.200s and you "
"have requested strict checking.", type, host);
goto fail;
- } else if (options.strict_host_key_checking == 2) {
+ } else if (options.strict_host_key_checking ==
+ SSH_STRICT_HOSTKEY_ASK) {
char msg1[1024], msg2[1024];
if (show_other_keys(host_hostkeys, host_key))
@@ -944,8 +946,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
hostkey_trusted = 1; /* user explicitly confirmed */
}
/*
- * If not in strict mode, add the key automatically to the
- * local known_hosts file.
+ * If in "new" or "off" strict mode, add the key automatically
+ * to the local known_hosts file.
*/
if (options.check_host_ip && ip_status == HOST_NEW) {
snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
@@ -987,7 +989,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
* If strict host key checking is in use, the user will have
* to edit the key manually and we can only abort.
*/
- if (options.strict_host_key_checking) {
+ if (options.strict_host_key_checking !=
+ SSH_STRICT_HOSTKEY_OFF) {
error("%s host key for %.200s was revoked and you have "
"requested strict checking.", type, host);
goto fail;
@@ -1040,7 +1043,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
* If strict host key checking is in use, the user will have
* to edit the key manually and we can only abort.
*/
- if (options.strict_host_key_checking) {
+ if (options.strict_host_key_checking !=
+ SSH_STRICT_HOSTKEY_OFF) {
error("%s host key for %.200s has changed and you have "
"requested strict checking.", type, host);
goto fail;
@@ -1127,15 +1131,17 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
"\nMatching host key in %s:%lu",
host_found->file, host_found->line);
}
- if (options.strict_host_key_checking == 1) {
- logit("%s", msg);
- error("Exiting, you have requested strict checking.");
- goto fail;
- } else if (options.strict_host_key_checking == 2) {
+ if (options.strict_host_key_checking ==
+ SSH_STRICT_HOSTKEY_ASK) {
strlcat(msg, "\nAre you sure you want "
"to continue connecting (yes/no)? ", sizeof(msg));
if (!confirm(msg))
goto fail;
+ } else if (options.strict_host_key_checking !=
+ SSH_STRICT_HOSTKEY_OFF) {
+ logit("%s", msg);
+ error("Exiting, you have requested strict checking.");
+ goto fail;
} else {
logit("%s", msg);
}