From: jacob Date: Fri, 1 Jul 2011 21:53:41 +0000 (+0000) Subject: Fix 'winadj-success': since at least one server (boks_sshd) blithely responds X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/commitdiff_plain/e030765f26dba89af7e0136b420bf8229cacefea Fix 'winadj-success': since at least one server (boks_sshd) blithely responds to "winadj@putty.projects.tartarus.org" with SSH_MSG_CHANNEL_SUCCESS despite probably having no idea what it means, treat this just the same as SSH_MSG_CHANNEL_FAILURE instead of killing the connection. Tested only as far as making sure that winadj/FAILURE with a normal server isn't _completely_ broken. git-svn-id: svn://svn.tartarus.org/sgt/putty@9185 cda61777-01e9-0310-a592-d414129be87e --- diff --git a/ssh.c b/ssh.c index 05530fe8..017b48bf 100644 --- a/ssh.c +++ b/ssh.c @@ -6627,25 +6627,44 @@ static struct ssh_channel *ssh2_channel_msg(Ssh ssh, struct Packet *pktin) return c; } +static int ssh2_handle_winadj_response(struct ssh_channel *c) +{ + struct winadj *wa = c->v.v2.winadj_head; + if (!wa) + return FALSE; + c->v.v2.winadj_head = wa->next; + c->v.v2.remlocwin += wa->size; + sfree(wa); + /* + * winadj messages are only sent when the window is fully open, so + * if we get an ack of one, we know any pending unthrottle is + * complete. + */ + if (c->v.v2.throttle_state == UNTHROTTLING) + c->v.v2.throttle_state = UNTHROTTLED; + return TRUE; +} + static void ssh2_msg_channel_success(Ssh ssh, struct Packet *pktin) { /* * This should never get called. All channel requests are either - * sent with want_reply false or are sent before this handler gets - * installed. + * sent with want_reply false, are sent before this handler gets + * installed, or are "winadj@putty" requests, which servers should + * never respond to with success. + * + * However, at least one server ("boks_sshd") is known to return + * SUCCESS for channel requests it's never heard of, such as + * "winadj@putty". Raised with foxt.com as bug 090916-090424, but + * for the sake of a quiet life, we handle it just the same as the + * expected FAILURE. */ struct ssh_channel *c; - struct winadj *wa; c = ssh2_channel_msg(ssh, pktin); if (!c) return; - wa = c->v.v2.winadj_head; - if (wa) - ssh_disconnect(ssh, NULL, "Received SSH_MSG_CHANNEL_SUCCESS for " - "\"winadj@putty.projects.tartarus.org\"", - SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE); - else + if (!ssh2_handle_winadj_response(c)) ssh_disconnect(ssh, NULL, "Received unsolicited SSH_MSG_CHANNEL_SUCCESS", SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE); @@ -6660,28 +6679,14 @@ static void ssh2_msg_channel_failure(Ssh ssh, struct Packet *pktin) * installed. */ struct ssh_channel *c; - struct winadj *wa; c = ssh2_channel_msg(ssh, pktin); if (!c) return; - wa = c->v.v2.winadj_head; - if (!wa) { + if (!ssh2_handle_winadj_response(c)) ssh_disconnect(ssh, NULL, "Received unsolicited SSH_MSG_CHANNEL_FAILURE", SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE); - return; - } - c->v.v2.winadj_head = wa->next; - c->v.v2.remlocwin += wa->size; - sfree(wa); - /* - * winadj messages are only sent when the window is fully open, so - * if we get an ack of one, we know any pending unthrottle is - * complete. - */ - if (c->v.v2.throttle_state == UNTHROTTLING) - c->v.v2.throttle_state = UNTHROTTLED; } static void ssh2_msg_channel_window_adjust(Ssh ssh, struct Packet *pktin)