From c9739dba40b647342cbc8b93ac0c431849454c50 Mon Sep 17 00:00:00 2001 From: ben Date: Wed, 5 Dec 2007 00:02:06 +0000 Subject: [PATCH] Add a new bug-compatibility mode that limits the window size we'll 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 | 3 +++ doc/config.but | 16 ++++++++++++++++ putty.h | 2 +- settings.c | 2 ++ ssh.c | 20 ++++++++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/config.c b/config.c index fd1379ab..bd07d951 100644 --- 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))); } } } diff --git a/doc/config.but b/doc/config.but index 98b4a7e2..02ada516 100644 --- a/doc/config.but +++ b/doc/config.but @@ -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 c935efa0..8f6461e6 100644 --- 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 diff --git a/settings.c b/settings.c index 3846715e..ab2dc925 100644 --- a/settings.c +++ b/settings.c @@ -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 a4b78c4d..eec05808 100644 --- 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. -- 2.11.0