]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - ssh.c
pscp: pull out upload block size into a constant.
[PuTTY.git] / ssh.c
diff --git a/ssh.c b/ssh.c
index a94ebd4110f058c42a6da885b9ca792415f860c5..ab1d78ab9567a0e205ed474d592411a09f874ce0 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -384,7 +384,7 @@ static void ssh2_msg_something_unimplemented(Ssh ssh, struct Packet *pktin);
  *    ensure that the server never has any need to throttle its end
  *    of the connection), so we set this high as well.
  * 
- *  - OUR_V2_WINSIZE is the maximum window size we present on SSH-2
+ *  - OUR_V2_WINSIZE is the default window size we present on SSH-2
  *    channels.
  *
  *  - OUR_V2_BIGWIN is the window size we advertise for the only
@@ -3138,15 +3138,21 @@ static int do_ssh_init(Ssh ssh, unsigned char c)
     /* Anything greater or equal to "1.99" means protocol 2 is supported. */
     s->proto2 = ssh_versioncmp(s->version, "1.99") >= 0;
 
-    if (conf_get_int(ssh->conf, CONF_sshprot) == 0 && !s->proto1) {
-       bombout(("SSH protocol version 1 required by configuration but "
-                "not provided by server"));
-       crStop(0);
-    }
-    if (conf_get_int(ssh->conf, CONF_sshprot) == 3 && !s->proto2) {
-       bombout(("SSH protocol version 2 required by configuration but "
-                "not provided by server"));
-       crStop(0);
+    if (conf_get_int(ssh->conf, CONF_sshprot) == 0) {
+       if (!s->proto1) {
+           bombout(("SSH protocol version 1 required by our configuration "
+                    "but not provided by server"));
+           crStop(0);
+       }
+    } else if (conf_get_int(ssh->conf, CONF_sshprot) == 3) {
+       if (!s->proto2) {
+           bombout(("SSH protocol version 2 required by our configuration "
+                    "but server only provides (old, insecure) SSH-1"));
+           crStop(0);
+       }
+    } else {
+       /* No longer support values 1 or 2 for CONF_sshprot */
+       assert(!"Unexpected value for CONF_sshprot");
     }
 
     if (s->proto2 && (conf_get_int(ssh->conf, CONF_sshprot) >= 2 || !s->proto1))
@@ -3708,13 +3714,17 @@ static const char *connect_to_host(Ssh ssh, const char *host, int port,
     }
 
     /*
-     * If the SSH version number's fixed, set it now, and if it's SSH-2,
-     * send the version string too.
+     * The SSH version number is always fixed (since we no longer support
+     * fallback between versions), so set it now, and if it's SSH-2,
+     * send the version string now too.
      */
     sshprot = conf_get_int(ssh->conf, CONF_sshprot);
+    assert(sshprot == 0 || sshprot == 3);
     if (sshprot == 0)
+       /* SSH-1 only */
        ssh->version = 1;
     if (sshprot == 3 && !ssh->bare_connection) {
+       /* SSH-2 only */
        ssh->version = 2;
        ssh_send_verstring(ssh, "SSH-", NULL);
     }
@@ -6813,10 +6823,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;