From 6bbce591e72352b2ce5e4915e7ab05f316083ab7 Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 12 May 2005 15:09:35 +0000 Subject: [PATCH] Use the packet dispatch table to handle USERAUTH_BANNER messages, which should hopefully solve `drop-banner'. I haven't been able to test the failure case, but the behaviour with OpenSSH appears no worse. git-svn-id: svn://svn.tartarus.org/sgt/putty@5772 cda61777-01e9-0310-a592-d414129be87e --- ssh.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/ssh.c b/ssh.c index 8b986ffa..520f6fa7 100644 --- a/ssh.c +++ b/ssh.c @@ -748,6 +748,7 @@ struct ssh_tag { */ int fallback_cmd; + bufchain banner; /* accumulates banners during do_ssh2_authconn */ /* * Used for username and password input. */ @@ -6387,6 +6388,21 @@ static void ssh2_msg_channel_open(Ssh ssh, struct Packet *pktin) } } +/* + * Buffer banner messages for later display at some convenient point. + */ +static void ssh2_msg_userauth_banner(Ssh ssh, struct Packet *pktin) +{ + /* Arbitrary limit to prevent unbounded inflation of buffer */ + if (bufchain_size(&ssh->banner) <= 131072) { + char *banner = NULL; + int size = 0; + ssh_pkt_getstring(pktin, &banner, &size); + if (banner) + bufchain_add(&ssh->banner, banner, size); + } +} + /* Helper function to deal with sending tty modes for "pty-req" */ static void ssh2_send_ttymode(void *data, char *mode, char *val) { @@ -6511,6 +6527,9 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, */ s->username[0] = '\0'; s->got_username = FALSE; + bufchain_init(&ssh->banner); + ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = + ssh2_msg_userauth_banner; while (!s->we_are_in) { /* * Get a username. @@ -6611,9 +6630,14 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, */ if (!s->gotit) crWaitUntilV(pktin); - while (pktin->type == SSH2_MSG_USERAUTH_BANNER) { - char *banner; - int size; + /* + * Now is a convenient point to spew any banner material + * that we've accumulated. (This should ensure that when + * we exit the auth loop, we haven't any left to deal + * with.) + */ + { + int size = bufchain_size(&ssh->banner); /* * Don't show the banner if we're operating in * non-verbose non-interactive mode. (It's probably @@ -6622,12 +6646,13 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, * the banner will screw up processing on the * output of (say) plink.) */ - if (flags & (FLAG_VERBOSE | FLAG_INTERACTIVE)) { - ssh_pkt_getstring(pktin, &banner, &size); - if (banner) - c_write_untrusted(ssh, banner, size); + if (size && (flags & (FLAG_VERBOSE | FLAG_INTERACTIVE))) { + char *banner = snewn(size, char); + bufchain_fetch(&ssh->banner, banner, size); + c_write_untrusted(ssh, banner, size); + sfree(banner); } - crWaitUntilV(pktin); + bufchain_clear(&ssh->banner); } if (pktin->type == SSH2_MSG_USERAUTH_SUCCESS) { logevent("Access granted"); @@ -7253,6 +7278,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, } } } + ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL; /* * Now the connection protocol has started, one way or another. -- 2.11.0