From 837d6ba65e2511747da1c8e5a096f59d1f48c475 Mon Sep 17 00:00:00 2001 From: ben Date: Mon, 1 Oct 2007 21:11:11 +0000 Subject: [PATCH] Rather than rejecting spurious SSH_MSG_CHANNEL_SUCCESSes, and ignoring spurious SSH_MSG_CHANNEL_FAILUREs, treat them as the protocol errors they are and forcibly disconnect. Inspired by recent traffic on comp.security.ssh. git-svn-id: svn://svn.tartarus.org/sgt/putty@7752 cda61777-01e9-0310-a592-d414129be87e --- ssh.c | 53 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/ssh.c b/ssh.c index 0c878c91..fb24f435 100644 --- a/ssh.c +++ b/ssh.c @@ -6300,6 +6300,30 @@ static struct ssh_channel *ssh2_channel_msg(Ssh ssh, struct Packet *pktin) return c; } +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. + */ + 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 + ssh_disconnect(ssh, NULL, + "Received unsolicited SSH_MSG_CHANNEL_SUCCESS", + SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE); +} + static void ssh2_msg_channel_failure(Ssh ssh, struct Packet *pktin) { /* @@ -6315,20 +6339,22 @@ static void ssh2_msg_channel_failure(Ssh ssh, struct Packet *pktin) if (!c) return; wa = c->v.v2.winadj_head; - if (!wa) - logevent("excess SSH_MSG_CHANNEL_FAILURE"); - else { - 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; + if (!wa) { + 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) @@ -8462,6 +8488,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, * All the initial channel requests are done, so install the default * failure handler. */ + ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = ssh2_msg_channel_success; ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = ssh2_msg_channel_failure; /* -- 2.11.0