]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Add have_ssh_host_key() and use it to influence algorithm selection.
authorBen Harris <bjh21@bjh21.me.uk>
Fri, 29 May 2015 21:40:50 +0000 (22:40 +0100)
committerBen Harris <bjh21@bjh21.me.uk>
Sat, 30 May 2015 00:01:36 +0000 (01:01 +0100)
The general plan is that if PuTTY knows a host key for a server, it
should preferentially ask for the same type of key so that there's some
chance of actually getting the same key again.  This should mean that
when a server (or PuTTY) adds a new host key type, PuTTY doesn't
gratuitously switch to that key type and then warn the user about an
unrecognised key.

putty.h
ssh.c
unix/uxstore.c
windows/winstore.c

diff --git a/putty.h b/putty.h
index 22ec67b79829f97f6afcac2aad95c518af0ebb61..9d4aa739a3384e2ecd27918a352642cf19bc96fe 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -1197,6 +1197,11 @@ void pgp_fingerprints(void);
 int verify_ssh_host_key(void *frontend, char *host, int port,
                         const char *keytype, char *keystr, char *fingerprint,
                         void (*callback)(void *ctx, int result), void *ctx);
+/*
+ * have_ssh_host_key() just returns true if a key of that type is
+ * already chached and false otherwise.
+ */
+int have_ssh_host_key(const char *host, int port, const char *keytype);
 /*
  * askalg has the same set of return values as verify_ssh_host_key.
  */
diff --git a/ssh.c b/ssh.c
index 9cf64a16beb882f2b13f269b449bbf05d87d0f68..c48eff70e67e3f00eece61a63e1a3abe55bf970e 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -6350,9 +6350,20 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen,
         if (!s->got_session_id) {
             /*
              * In the first key exchange, we list all the algorithms
-             * we're prepared to cope with.
+             * we're prepared to cope with, but prefer those algorithms
+            * for which we have a host key for this host.
              */
            n = 0;
+            for (i = 0; i < lenof(hostkey_algs); i++) {
+               if (have_ssh_host_key(ssh->savedhost, ssh->savedport,
+                                     hostkey_algs[i]->keytype)) {
+                   assert(n < MAXKEXLIST);
+                   s->kexlists[KEXLIST_HOSTKEY][n].name =
+                       hostkey_algs[i]->name;
+                   s->kexlists[KEXLIST_HOSTKEY][n].u.hostkey = hostkey_algs[i];
+                   n++;
+               }
+           }
             for (i = 0; i < lenof(hostkey_algs); i++) {
                assert(n < MAXKEXLIST);
                s->kexlists[KEXLIST_HOSTKEY][n].name = hostkey_algs[i]->name;
index d97185e1efbcab674328d199efa549a2e6b4504d..411953ac1a6ff7bde8327beee7a50c9e1c81bdb7 100644 (file)
@@ -589,6 +589,16 @@ int verify_host_key(const char *hostname, int port,
     return ret;
 }
 
+int have_ssh_host_key(const char *hostname, int port,
+                     const char *keytype)
+{
+    /*
+     * If we have a host key, verify_host_key will return 0 or 2.
+     * If we don't have one, it'll return 1.
+     */
+    return verify_host_key(hostname, port, keytype, "") != 1;
+}
+
 void store_host_key(const char *hostname, int port,
                    const char *keytype, const char *key)
 {
index b1058832e99a11da3e48d44216a555da809aca07..c45b9b0419832d1cb91de16c97c8a05fedfe3232 100644 (file)
@@ -454,6 +454,16 @@ int verify_host_key(const char *hostname, int port,
        return 0;                      /* key matched OK in registry */
 }
 
+int have_ssh_host_key(const char *hostname, int port,
+                     const char *keytype)
+{
+    /*
+     * If we have a host key, verify_host_key will return 0 or 2.
+     * If we don't have one, it'll return 1.
+     */
+    return verify_host_key(hostname, port, keytype, "") != 1;
+}
+
 void store_host_key(const char *hostname, int port,
                    const char *keytype, const char *key)
 {