X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/4ed34d251770cb8dd7f13217976d1dec9452b5e6..d524be1c2d942affbe81fe35c08b4b7e4338fef3:/ssh.c diff --git a/ssh.c b/ssh.c index 119cd4fe..ef573d42 100644 --- a/ssh.c +++ b/ssh.c @@ -2912,6 +2912,7 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt) if (c && c->type == CHAN_SOCKDATA_DORMANT) { c->remoteid = localid; c->type = CHAN_SOCKDATA; + c->v.v1.throttling = 0; pfd_confirm(c->u.pfd.s); } @@ -3352,6 +3353,11 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) break; } } + if (!cscipher_tobe) { + bombout(("Couldn't agree a client-to-server cipher (available: %s)", str)); + crReturn(0); + } + ssh2_pkt_getstring(&str, &len); /* server->client cipher */ warn = 0; for (i = 0; i < n_preferred_ciphers; i++) { @@ -3372,6 +3378,11 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) break; } } + if (!sccipher_tobe) { + bombout(("Couldn't agree a server-to-client cipher (available: %s)", str)); + crReturn(0); + } + ssh2_pkt_getstring(&str, &len); /* client->server mac */ for (i = 0; i < nmacs; i++) { if (in_commasep_string(maclist[i]->name, str, len)) { @@ -3499,15 +3510,6 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) } /* - * Expect SSH2_MSG_NEWKEYS from server. - */ - crWaitUntil(ispkt); - if (pktin.type != SSH2_MSG_NEWKEYS) { - bombout(("expected new-keys packet from server")); - crReturn(0); - } - - /* * Authenticate remote host: verify host key. (We've already * checked the signature of the exchange hash.) */ @@ -3530,6 +3532,15 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) ssh2_pkt_send(); /* + * Expect SSH2_MSG_NEWKEYS from server. + */ + crWaitUntil(ispkt); + if (pktin.type != SSH2_MSG_NEWKEYS) { + bombout(("expected new-keys packet from server")); + crReturn(0); + } + + /* * Create and initialise session keys. */ cscipher = cscipher_tobe; @@ -4796,8 +4807,6 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) ssh_state = SSH_STATE_CLOSED; logevent("Received disconnect message"); crReturnV; - } else if (pktin.type == SSH2_MSG_CHANNEL_REQUEST) { - continue; /* exit status et al; ignore (FIXME?) */ } else if (pktin.type == SSH2_MSG_CHANNEL_EOF) { unsigned i = ssh2_pkt_getuint32(); struct ssh_channel *c; @@ -4916,6 +4925,46 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) del234(ssh_channels, c); sfree(c); + } else if (pktin.type == SSH2_MSG_CHANNEL_REQUEST) { + unsigned localid; + char *type; + int typelen, want_reply; + struct ssh_channel *c; + + localid = ssh2_pkt_getuint32(); + ssh2_pkt_getstring(&type, &typelen); + want_reply = ssh2_pkt_getbool(); + + /* + * 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[80]; + sprintf(buf, "Received channel request for nonexistent" + " channel %d", localid); + logevent(buf); + ssh2_pkt_init(SSH2_MSG_DISCONNECT); + ssh2_pkt_adduint32(SSH2_DISCONNECT_BY_APPLICATION); + ssh2_pkt_addstring(buf); + ssh2_pkt_addstring("en"); /* language tag */ + ssh2_pkt_send(); + connection_fatal(buf); + ssh_state = SSH_STATE_CLOSED; + crReturnV; + } + + /* + * We don't recognise any form of channel request, + * so we now either ignore the request or respond + * with CHANNEL_FAILURE, depending on want_reply. + */ + if (want_reply) { + ssh2_pkt_init(SSH2_MSG_CHANNEL_FAILURE); + ssh2_pkt_adduint32(c->remoteid); + ssh2_pkt_send(); + } } else if (pktin.type == SSH2_MSG_CHANNEL_OPEN) { char *type; int typelen;