X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=ssh.c;h=4de741c7b6d0640d916bafe830841fc621e00de4;hb=bd65d477920b8d53833f6161e261fc6139a873ee;hp=a214aa1f9b7985f16eee25168d8c3d0874b2eca7;hpb=4ff22863d895cb7ebfced4cf923a012a614adaa8;p=PuTTY.git diff --git a/ssh.c b/ssh.c index a214aa1f..4de741c7 100644 --- a/ssh.c +++ b/ssh.c @@ -10,6 +10,7 @@ #include #include "putty.h" +#include "pageant.h" /* for AGENT_MAX_MSGLEN */ #include "tree234.h" #include "storage.h" #include "ssh.h" @@ -3857,6 +3858,8 @@ static void ssh_agentf_got_response(struct ssh_channel *c, { c->u.a.pending = NULL; + assert(!(c->closes & CLOSES_SENT_EOF)); + if (!reply) { /* The real agent didn't send any kind of reply at all for * some reason, so fake an SSH_AGENT_FAILURE. */ @@ -3897,6 +3900,15 @@ static void ssh_agentf_try_forward(struct ssh_channel *c) (c->ssh->version == 2 && c->v.v2.remwindow == 0)) return; + if (c->closes & CLOSES_SENT_EOF) { + /* + * If we've already sent outgoing EOF, there's nothing we can + * do with incoming data except consume it and throw it away. + */ + bufchain_clear(&c->u.a.inbuffer); + return; + } + while (1) { /* * Try to extract a complete message from the input buffer. @@ -3907,6 +3919,21 @@ static void ssh_agentf_try_forward(struct ssh_channel *c) bufchain_fetch(&c->u.a.inbuffer, msglen, 4); lengthfield = GET_32BIT(msglen); + + if (lengthfield > AGENT_MAX_MSGLEN) { + /* + * If the remote has sent a message that's just _too_ + * long, we should reject it in advance of seeing the rest + * of the incoming message, and also close the connection + * for good measure (which avoids us having to faff about + * with carefully ignoring just the right number of bytes + * from the overlong message). + */ + ssh_agentf_got_response(c, NULL, 0); + sshfwd_write_eof(c); + return; + } + if (lengthfield > datalen - 4) break; /* a whole message is not yet available */ @@ -3927,6 +3954,7 @@ static void ssh_agentf_try_forward(struct ssh_channel *c) * straight on and go round this loop again. */ ssh_agentf_got_response(c, reply, replylen); + sfree(reply); } /* @@ -9417,21 +9445,25 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen, goto done_agent_query; } bloblen = toint(GET_32BIT(q)); + lenleft -= 4; + q += 4; if (bloblen < 0 || bloblen > lenleft) { logeventf(ssh, "Pageant response was truncated"); s->nkeys = 0; goto done_agent_query; } - lenleft -= 4 + bloblen; - q += 4 + bloblen; + lenleft -= bloblen; + q += bloblen; commentlen = toint(GET_32BIT(q)); + lenleft -= 4; + q += 4; if (commentlen < 0 || commentlen > lenleft) { logeventf(ssh, "Pageant response was truncated"); s->nkeys = 0; goto done_agent_query; } - lenleft -= 4 + commentlen; - q += 4 + commentlen; + lenleft -= commentlen; + q += commentlen; } }