1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-02-04 06:02:24 +00:00

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.

[originally from svn r7752]
This commit is contained in:
Ben Harris 2007-10-01 21:11:11 +00:00
parent da5d553afc
commit 2db59b7443

41
ssh.c
View File

@ -6300,6 +6300,30 @@ static struct ssh_channel *ssh2_channel_msg(Ssh ssh, struct Packet *pktin)
return c; 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) static void ssh2_msg_channel_failure(Ssh ssh, struct Packet *pktin)
{ {
/* /*
@ -6315,21 +6339,23 @@ static void ssh2_msg_channel_failure(Ssh ssh, struct Packet *pktin)
if (!c) if (!c)
return; return;
wa = c->v.v2.winadj_head; wa = c->v.v2.winadj_head;
if (!wa) if (!wa) {
logevent("excess SSH_MSG_CHANNEL_FAILURE"); ssh_disconnect(ssh, NULL,
else { "Received unsolicited SSH_MSG_CHANNEL_FAILURE",
SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
return;
}
c->v.v2.winadj_head = wa->next; c->v.v2.winadj_head = wa->next;
c->v.v2.remlocwin += wa->size; c->v.v2.remlocwin += wa->size;
sfree(wa); sfree(wa);
/* /*
* winadj messages are only sent when the window is fully open, * winadj messages are only sent when the window is fully open, so
* so if we get an ack of one, we know any pending unthrottle * if we get an ack of one, we know any pending unthrottle is
* is complete. * complete.
*/ */
if (c->v.v2.throttle_state == UNTHROTTLING) if (c->v.v2.throttle_state == UNTHROTTLING)
c->v.v2.throttle_state = UNTHROTTLED; c->v.v2.throttle_state = UNTHROTTLED;
} }
}
static void ssh2_msg_channel_window_adjust(Ssh ssh, struct Packet *pktin) 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 * All the initial channel requests are done, so install the default
* failure handler. * failure handler.
*/ */
ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = ssh2_msg_channel_success;
ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = ssh2_msg_channel_failure; ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = ssh2_msg_channel_failure;
/* /*