Add a new bug-compatibility mode that limits the window size we'll
authorben <ben@cda61777-01e9-0310-a592-d414129be87e>
Wed, 5 Dec 2007 00:02:06 +0000 (00:02 +0000)
committerben <ben@cda61777-01e9-0310-a592-d414129be87e>
Wed, 5 Dec 2007 00:02:06 +0000 (00:02 +0000)
advertise so that the server can't exceed our maximum packet size.
Enable it for "1.36_sshlib GlobalSCAPE" which apparently sends oversize
packets otherwise.

git-svn-id: svn://svn.tartarus.org/sgt/putty@7804 cda61777-01e9-0310-a592-d414129be87e

config.c
doc/config.but
putty.h
settings.c
ssh.c

index fd1379a..bd07d95 100644 (file)
--- a/config.c
+++ b/config.c
@@ -2245,6 +2245,9 @@ void setup_config_box(struct controlbox *b, int midsession,
            ctrl_droplist(s, "Handles SSH-2 key re-exchange badly", 'k', 20,
                          HELPCTX(ssh_bugs_rekey2),
                          sshbug_handler, I(offsetof(Config,sshbug_rekey2)));
+           ctrl_droplist(s, "Ignores SSH-2 maximum packet size", 'x', 20,
+                         HELPCTX(ssh_bugs_maxpkt2),
+                         sshbug_handler, I(offsetof(Config,sshbug_maxpkt2)));
        }
     }
 }
index 98b4a7e..02ada51 100644 (file)
@@ -2978,6 +2978,22 @@ would expect.
 
 This is an SSH-2-specific bug.
 
+\S{config-ssh-bug-maxpkt} \q{Ignores SSH-2 \i{maximum packet size}}
+
+\cfg{winhelp-topic}{ssh.bugs.maxpkt2}
+
+When an SSH-2 channel is set up, each end announces the maximum size
+of data packet that it is willing to receive for that channel.  Some
+servers ignore PuTTY's announcement and send packets larger than PuTTY
+is willing to accept, causing it to report \q{Incoming packet was
+garbled on decryption}.
+
+If this bug is detected, PuTTY never allows the channel's
+\i{flow-control window} to grow large enough to allow the server to
+send an over-sized packet.  If this bug is enabled when talking to a
+correct server, the session will work correctly, but download
+performance will be less than it could be.
+
 \H{config-serial} The Serial panel
 
 The \i{Serial} panel allows you to configure options that only apply
diff --git a/putty.h b/putty.h
index c935efa..8f6461e 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -587,7 +587,7 @@ struct config_tag {
     /* SSH bug compatibility modes */
     int sshbug_ignore1, sshbug_plainpw1, sshbug_rsa1,
        sshbug_hmac2, sshbug_derivekey2, sshbug_rsapad2,
-       sshbug_pksessid2, sshbug_rekey2;
+       sshbug_pksessid2, sshbug_rekey2, sshbug_maxpkt2;
     /*
      * ssh_simple means that we promise never to open any channel other
      * than the main one, which means it can safely use a very large
index 3846715..ab2dc92 100644 (file)
@@ -454,6 +454,7 @@ void save_open_settings(void *sesskey, Config *cfg)
     write_setting_i(sesskey, "BugRSAPad2", 2-cfg->sshbug_rsapad2);
     write_setting_i(sesskey, "BugPKSessID2", 2-cfg->sshbug_pksessid2);
     write_setting_i(sesskey, "BugRekey2", 2-cfg->sshbug_rekey2);
+    write_setting_i(sesskey, "BugMaxPkt2", 2-cfg->sshbug_maxpkt2);
     write_setting_i(sesskey, "StampUtmp", cfg->stamp_utmp);
     write_setting_i(sesskey, "LoginShell", cfg->login_shell);
     write_setting_i(sesskey, "ScrollbarOnLeft", cfg->scrollbar_on_left);
@@ -788,6 +789,7 @@ void load_open_settings(void *sesskey, Config *cfg)
     gppi(sesskey, "BugRSAPad2", 0, &i); cfg->sshbug_rsapad2 = 2-i;
     gppi(sesskey, "BugPKSessID2", 0, &i); cfg->sshbug_pksessid2 = 2-i;
     gppi(sesskey, "BugRekey2", 0, &i); cfg->sshbug_rekey2 = 2-i;
+    gppi(sesskey, "BugMaxPkt2", 0, &i); cfg->sshbug_maxpkt2 = 2-i;
     cfg->ssh_simple = FALSE;
     gppi(sesskey, "StampUtmp", 1, &cfg->stamp_utmp);
     gppi(sesskey, "LoginShell", 1, &cfg->login_shell);
diff --git a/ssh.c b/ssh.c
index a4b78c4..eec0580 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -183,6 +183,7 @@ static const char *const ssh2_disconnect_reasons[] = {
 #define BUG_SSH2_DERIVEKEY                       32
 #define BUG_SSH2_REKEY                           64
 #define BUG_SSH2_PK_SESSIONID                   128
+#define BUG_SSH2_MAXPKT                                256
 
 /*
  * Codes for terminal modes.
@@ -2391,6 +2392,16 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
        ssh->remote_bugs |= BUG_SSH2_REKEY;
        logevent("We believe remote version has SSH-2 rekey bug");
     }
+
+    if (ssh->cfg.sshbug_maxpkt2 == FORCE_ON ||
+       (ssh->cfg.sshbug_maxpkt2 == AUTO &&
+        (wc_match("1.36_sshlib GlobalSCAPE", imp)))) {
+       /*
+        * This version ignores our makpkt and needs to be throttled.
+        */
+       ssh->remote_bugs |= BUG_SSH2_MAXPKT;
+       logevent("We believe remote version ignores SSH-2 maximum packet size");
+    }
 }
 
 /*
@@ -6236,6 +6247,15 @@ static void ssh2_set_window(struct ssh_channel *c, int newwin)
        return;
 
     /*
+     * If the remote end has a habit of ignoring maxpkt, limit the
+     * window so that it has no choice (assuming it doesn't ignore the
+     * window as well).
+     */
+    if ((ssh->remote_bugs & BUG_SSH2_MAXPKT) && newwin > OUR_V2_MAXPKT)
+       newwin = OUR_V2_MAXPKT;
+       
+
+    /*
      * Only send a WINDOW_ADJUST if there's significantly more window
      * available than the other end thinks there is.  This saves us
      * sending a WINDOW_ADJUST for every character in a shell session.