mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 09:58:01 +00:00
Merge the looking up of channel numbers for SSH-2 channel messages into
a single function which also handles checking that channels exist and are properly open. This should make PuTTY a little less tolerant of servers that send bogus messages. [originally from svn r7751]
This commit is contained in:
parent
ef370ee6fa
commit
da5d553afc
82
ssh.c
82
ssh.c
@ -6276,6 +6276,30 @@ static void ssh2_set_window(struct ssh_channel *c, int newwin)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the channel associated with a message. If there's no channel,
|
||||||
|
* or it's not properly open, make a noise about it and return NULL.
|
||||||
|
*/
|
||||||
|
static struct ssh_channel *ssh2_channel_msg(Ssh ssh, struct Packet *pktin)
|
||||||
|
{
|
||||||
|
unsigned localid = ssh_pkt_getuint32(pktin);
|
||||||
|
struct ssh_channel *c;
|
||||||
|
|
||||||
|
c = find234(ssh->channels, &localid, ssh_channelfind);
|
||||||
|
if (!c ||
|
||||||
|
(c->halfopen && pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION &&
|
||||||
|
pktin->type != SSH2_MSG_CHANNEL_OPEN_FAILURE)) {
|
||||||
|
char *buf = dupprintf("Received %s for %s channel %u",
|
||||||
|
ssh2_pkt_type(ssh->pkt_kctx, ssh->pkt_actx,
|
||||||
|
pktin->type),
|
||||||
|
c ? "half-open" : "nonexistent", localid);
|
||||||
|
ssh_disconnect(ssh, NULL, buf, SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
|
||||||
|
sfree(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
static void ssh2_msg_channel_failure(Ssh ssh, struct Packet *pktin)
|
static void ssh2_msg_channel_failure(Ssh ssh, struct Packet *pktin)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -6284,13 +6308,12 @@ static void ssh2_msg_channel_failure(Ssh ssh, struct Packet *pktin)
|
|||||||
* sent with want_reply false or are sent before this handler gets
|
* sent with want_reply false or are sent before this handler gets
|
||||||
* installed.
|
* installed.
|
||||||
*/
|
*/
|
||||||
unsigned i = ssh_pkt_getuint32(pktin);
|
|
||||||
struct ssh_channel *c;
|
struct ssh_channel *c;
|
||||||
struct winadj *wa;
|
struct winadj *wa;
|
||||||
|
|
||||||
c = find234(ssh->channels, &i, ssh_channelfind);
|
c = ssh2_channel_msg(ssh, pktin);
|
||||||
if (!c)
|
if (!c)
|
||||||
return; /* nonexistent channel */
|
return;
|
||||||
wa = c->v.v2.winadj_head;
|
wa = c->v.v2.winadj_head;
|
||||||
if (!wa)
|
if (!wa)
|
||||||
logevent("excess SSH_MSG_CHANNEL_FAILURE");
|
logevent("excess SSH_MSG_CHANNEL_FAILURE");
|
||||||
@ -6310,10 +6333,11 @@ static void ssh2_msg_channel_failure(Ssh ssh, struct Packet *pktin)
|
|||||||
|
|
||||||
static void ssh2_msg_channel_window_adjust(Ssh ssh, struct Packet *pktin)
|
static void ssh2_msg_channel_window_adjust(Ssh ssh, struct Packet *pktin)
|
||||||
{
|
{
|
||||||
unsigned i = ssh_pkt_getuint32(pktin);
|
|
||||||
struct ssh_channel *c;
|
struct ssh_channel *c;
|
||||||
c = find234(ssh->channels, &i, ssh_channelfind);
|
c = ssh2_channel_msg(ssh, pktin);
|
||||||
if (c && !c->closes) {
|
if (!c)
|
||||||
|
return;
|
||||||
|
if (!c->closes) {
|
||||||
c->v.v2.remwindow += ssh_pkt_getuint32(pktin);
|
c->v.v2.remwindow += ssh_pkt_getuint32(pktin);
|
||||||
ssh2_try_send_and_unthrottle(c);
|
ssh2_try_send_and_unthrottle(c);
|
||||||
}
|
}
|
||||||
@ -6323,11 +6347,10 @@ static void ssh2_msg_channel_data(Ssh ssh, struct Packet *pktin)
|
|||||||
{
|
{
|
||||||
char *data;
|
char *data;
|
||||||
int length;
|
int length;
|
||||||
unsigned i = ssh_pkt_getuint32(pktin);
|
|
||||||
struct ssh_channel *c;
|
struct ssh_channel *c;
|
||||||
c = find234(ssh->channels, &i, ssh_channelfind);
|
c = ssh2_channel_msg(ssh, pktin);
|
||||||
if (!c)
|
if (!c)
|
||||||
return; /* nonexistent channel */
|
return;
|
||||||
if (pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA &&
|
if (pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA &&
|
||||||
ssh_pkt_getuint32(pktin) != SSH2_EXTENDED_DATA_STDERR)
|
ssh_pkt_getuint32(pktin) != SSH2_EXTENDED_DATA_STDERR)
|
||||||
return; /* extended but not stderr */
|
return; /* extended but not stderr */
|
||||||
@ -6414,12 +6437,11 @@ static void ssh2_msg_channel_data(Ssh ssh, struct Packet *pktin)
|
|||||||
|
|
||||||
static void ssh2_msg_channel_eof(Ssh ssh, struct Packet *pktin)
|
static void ssh2_msg_channel_eof(Ssh ssh, struct Packet *pktin)
|
||||||
{
|
{
|
||||||
unsigned i = ssh_pkt_getuint32(pktin);
|
|
||||||
struct ssh_channel *c;
|
struct ssh_channel *c;
|
||||||
|
|
||||||
c = find234(ssh->channels, &i, ssh_channelfind);
|
c = ssh2_channel_msg(ssh, pktin);
|
||||||
if (!c)
|
if (!c)
|
||||||
return; /* nonexistent channel */
|
return;
|
||||||
|
|
||||||
if (c->type == CHAN_X11) {
|
if (c->type == CHAN_X11) {
|
||||||
/*
|
/*
|
||||||
@ -6438,16 +6460,12 @@ static void ssh2_msg_channel_eof(Ssh ssh, struct Packet *pktin)
|
|||||||
|
|
||||||
static void ssh2_msg_channel_close(Ssh ssh, struct Packet *pktin)
|
static void ssh2_msg_channel_close(Ssh ssh, struct Packet *pktin)
|
||||||
{
|
{
|
||||||
unsigned i = ssh_pkt_getuint32(pktin);
|
|
||||||
struct ssh_channel *c;
|
struct ssh_channel *c;
|
||||||
struct Packet *pktout;
|
struct Packet *pktout;
|
||||||
|
|
||||||
c = find234(ssh->channels, &i, ssh_channelfind);
|
c = ssh2_channel_msg(ssh, pktin);
|
||||||
if (!c || c->halfopen) {
|
if (!c)
|
||||||
bombout(("Received CHANNEL_CLOSE for %s channel %d\n",
|
|
||||||
c ? "half-open" : "nonexistent", i));
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
/* Do pre-close processing on the channel. */
|
/* Do pre-close processing on the channel. */
|
||||||
switch (c->type) {
|
switch (c->type) {
|
||||||
case CHAN_MAINSESSION:
|
case CHAN_MAINSESSION:
|
||||||
@ -6500,13 +6518,12 @@ static void ssh2_msg_channel_close(Ssh ssh, struct Packet *pktin)
|
|||||||
|
|
||||||
static void ssh2_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
|
static void ssh2_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
|
||||||
{
|
{
|
||||||
unsigned i = ssh_pkt_getuint32(pktin);
|
|
||||||
struct ssh_channel *c;
|
struct ssh_channel *c;
|
||||||
struct Packet *pktout;
|
struct Packet *pktout;
|
||||||
|
|
||||||
c = find234(ssh->channels, &i, ssh_channelfind);
|
c = ssh2_channel_msg(ssh, pktin);
|
||||||
if (!c)
|
if (!c)
|
||||||
return; /* nonexistent channel */
|
return;
|
||||||
if (c->type != CHAN_SOCKDATA_DORMANT)
|
if (c->type != CHAN_SOCKDATA_DORMANT)
|
||||||
return; /* dunno why they're confirming this */
|
return; /* dunno why they're confirming this */
|
||||||
c->remoteid = ssh_pkt_getuint32(pktin);
|
c->remoteid = ssh_pkt_getuint32(pktin);
|
||||||
@ -6538,14 +6555,13 @@ static void ssh2_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
|
|||||||
"Unknown channel type",
|
"Unknown channel type",
|
||||||
"Resource shortage",
|
"Resource shortage",
|
||||||
};
|
};
|
||||||
unsigned i = ssh_pkt_getuint32(pktin);
|
|
||||||
unsigned reason_code;
|
unsigned reason_code;
|
||||||
char *reason_string;
|
char *reason_string;
|
||||||
int reason_length;
|
int reason_length;
|
||||||
struct ssh_channel *c;
|
struct ssh_channel *c;
|
||||||
c = find234(ssh->channels, &i, ssh_channelfind);
|
c = ssh2_channel_msg(ssh, pktin);
|
||||||
if (!c)
|
if (!c)
|
||||||
return; /* nonexistent channel */
|
return;
|
||||||
if (c->type != CHAN_SOCKDATA_DORMANT)
|
if (c->type != CHAN_SOCKDATA_DORMANT)
|
||||||
return; /* dunno why they're failing this */
|
return; /* dunno why they're failing this */
|
||||||
|
|
||||||
@ -6564,30 +6580,18 @@ static void ssh2_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
|
|||||||
|
|
||||||
static void ssh2_msg_channel_request(Ssh ssh, struct Packet *pktin)
|
static void ssh2_msg_channel_request(Ssh ssh, struct Packet *pktin)
|
||||||
{
|
{
|
||||||
unsigned localid;
|
|
||||||
char *type;
|
char *type;
|
||||||
int typelen, want_reply;
|
int typelen, want_reply;
|
||||||
int reply = SSH2_MSG_CHANNEL_FAILURE; /* default */
|
int reply = SSH2_MSG_CHANNEL_FAILURE; /* default */
|
||||||
struct ssh_channel *c;
|
struct ssh_channel *c;
|
||||||
struct Packet *pktout;
|
struct Packet *pktout;
|
||||||
|
|
||||||
localid = ssh_pkt_getuint32(pktin);
|
c = ssh2_channel_msg(ssh, pktin);
|
||||||
|
if (!c)
|
||||||
|
return;
|
||||||
ssh_pkt_getstring(pktin, &type, &typelen);
|
ssh_pkt_getstring(pktin, &type, &typelen);
|
||||||
want_reply = ssh2_pkt_getbool(pktin);
|
want_reply = ssh2_pkt_getbool(pktin);
|
||||||
|
|
||||||
/*
|
|
||||||
* First, check that the channel exists. Otherwise,
|
|
||||||
* we can instantly disconnect with a rude message.
|
|
||||||
*/
|
|
||||||
c = find234(ssh->channels, &localid, ssh_channelfind);
|
|
||||||
if (!c) {
|
|
||||||
char *buf = dupprintf("Received channel request for nonexistent"
|
|
||||||
" channel %d", localid);
|
|
||||||
ssh_disconnect(ssh, NULL, buf, SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
|
|
||||||
sfree(buf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Having got the channel number, we now look at
|
* Having got the channel number, we now look at
|
||||||
* the request type string to see if it's something
|
* the request type string to see if it's something
|
||||||
|
Loading…
Reference in New Issue
Block a user