]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream commit
authordjm@openbsd.org <djm@openbsd.org>
Sun, 3 Sep 2017 23:33:13 +0000 (23:33 +0000)
committerDamien Miller <djm@mindrot.org>
Sun, 3 Sep 2017 23:38:57 +0000 (09:38 +1000)
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

readconf.c
readconf.h
ssh_config.5
sshconnect.c

index b11c628f9c8301b632379fe8e4ecc33b1f8deaab..4f38b27cf708b7c907a6ef1b842ba59eed3fa679 100644 (file)
@@ -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:
index 94dd427f57d42ab731ca017bf6d02948db87575a..22fe5c1873c3b79f4cdee02e97633a9c23a2c2d4 100644 (file)
@@ -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 *);
index 15ca0b4f99bb60683f908e934546e5754c0572e4..3823da6f34b6601284fd73b22ebefa58038781ad 100644 (file)
@@ -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),
index 4013ec7dba41faa3a13b02dd09f54c3b5a8d80c8..2842d9e5935f77e72e4907f4a355181532421fc3 100644 (file)
@@ -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);
                }