]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - ssh.c
Extend ACL-restriction to all Windows tools.
[PuTTY.git] / ssh.c
diff --git a/ssh.c b/ssh.c
index 75515df11a4558e77853cc158f0bd150f2622df6..146853dd439fb6d56440c3d5d576fcbfaa929eea 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -6813,10 +6813,53 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen,
        }
 
        if (s->warn_hk) {
+            int j, k;
+            char *betteralgs;
+
            ssh_set_frozen(ssh, 1);
-           s->dlgret = askalg(ssh->frontend, "host key type",
-                              ssh->hostkey->name,
-                              ssh_dialog_callback, ssh);
+
+            /*
+             * Change warning box wording depending on why we chose a
+             * warning-level host key algorithm. If it's because
+             * that's all we have *cached*, use the askhk mechanism,
+             * and list the host keys we could usefully cross-certify.
+             * Otherwise, use askalg for the standard wording.
+             */
+            betteralgs = NULL;
+            for (j = 0; j < ssh->n_uncert_hostkeys; j++) {
+                const struct ssh_signkey_with_user_pref_id *hktype =
+                    &hostkey_algs[ssh->uncert_hostkeys[j]];
+                int better = FALSE;
+                for (k = 0; k < HK_MAX; k++) {
+                    int id = conf_get_int_int(ssh->conf, CONF_ssh_hklist, k);
+                    if (id == HK_WARN) {
+                        break;
+                    } else if (id == hktype->id) {
+                        better = TRUE;
+                        break;
+                    }
+                }
+                if (better) {
+                    if (betteralgs) {
+                        char *old_ba = betteralgs;
+                        betteralgs = dupcat(betteralgs, ",",
+                                            hktype->alg->name,
+                                            (const char *)NULL);
+                        sfree(old_ba);
+                    } else {
+                        betteralgs = dupstr(hktype->alg->name);
+                    }
+                }
+            }
+            if (betteralgs) {
+                s->dlgret = askhk(ssh->frontend, ssh->hostkey->name,
+                                  betteralgs, ssh_dialog_callback, ssh);
+                sfree(betteralgs);
+            } else {
+                s->dlgret = askalg(ssh->frontend, "host key type",
+                                   ssh->hostkey->name,
+                                   ssh_dialog_callback, ssh);
+            }
            if (s->dlgret < 0) {
                do {
                    crReturnV;
@@ -7253,17 +7296,20 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen,
     s->keystr = ssh->hostkey->fmtkey(s->hkey);
     if (!s->got_session_id) {
        /*
-        * Make a note of any host key format we'd have preferred to use,
-        * had we already known the corresponding keys.
+        * Make a note of any other host key formats that are available.
         */
        {
-           int i, j = 0;
+           int i, j;
            char *list = NULL;
            for (i = 0; i < lenof(hostkey_algs); i++) {
                if (hostkey_algs[i].alg == ssh->hostkey)
-                   /* Not worth mentioning key types we wouldn't use */
-                   break;
-               else if (ssh->uncert_hostkeys[j] == i) {
+                   continue;
+
+                for (j = 0; j < ssh->n_uncert_hostkeys; j++)
+                    if (ssh->uncert_hostkeys[j] == i)
+                        break;
+
+                if (j < ssh->n_uncert_hostkeys) {
                    char *newlist;
                    if (list)
                        newlist = dupprintf("%s/%s", list,
@@ -7272,22 +7318,13 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen,
                        newlist = dupprintf("%s", hostkey_algs[i].alg->name);
                    sfree(list);
                    list = newlist;
-                   j++;
-                   /* Assumes that hostkey_algs and uncert_hostkeys are
-                    * sorted in the same order */
-                   if (j == ssh->n_uncert_hostkeys)
-                       break;
-                   else
-                       assert(ssh->uncert_hostkeys[j] >
-                              ssh->uncert_hostkeys[j-1]);
                }
            }
            if (list) {
                logeventf(ssh,
-                         "Server has %s host key%s, but we don't know %s; "
-                         "using %s instead",
-                         list, j ? "s" : "", j ? "any of them" : "it",
-                         ssh->hostkey->name);
+                         "Server also has %s host key%s, but we "
+                         "don't know %s", list,
+                         j > 1 ? "s" : "", j > 1 ? "any of them" : "it");
                sfree(list);
            }
        }