Mercurial > dropbear
diff common-session.c @ 801:7dcb46da72d9 ecc
merge in HEAD
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 21 May 2013 12:09:35 +0800 |
parents | ac2158e3e403 2f1c199b6e4b |
children | c19acba28590 |
line wrap: on
line diff
--- a/common-session.c Thu May 09 23:27:23 2013 +0800 +++ b/common-session.c Tue May 21 12:09:35 2013 +0800 @@ -33,12 +33,12 @@ #include "random.h" #include "kex.h" #include "channel.h" -#include "atomicio.h" #include "runopts.h" static void checktimeouts(); static long select_timeout(); static int ident_readln(int fd, char* buf, int count); +static void read_session_identification(); struct sshsession ses; /* GLOBAL */ @@ -49,8 +49,6 @@ /* this is set when we get SIGINT or SIGTERM, the handler is in main.c */ int exitflag = 0; /* GLOBAL */ - - /* called only at the start of a session, set up initial state */ void common_session_init(int sock_in, int sock_out) { @@ -84,7 +82,7 @@ initqueue(&ses.writequeue); - ses.requirenext = SSH_MSG_KEXINIT; + ses.requirenext[0] = SSH_MSG_KEXINIT; ses.dataallowed = 1; /* we can send data until we actually send the SSH_MSG_KEXINIT */ ses.ignorenext = 0; @@ -141,7 +139,10 @@ FD_ZERO(&writefd); FD_ZERO(&readfd); dropbear_assert(ses.payload == NULL); - if (ses.sock_in != -1) { + + /* during initial setup we flush out the KEXINIT packet before + * attempting to read the remote version string, which might block */ + if (ses.sock_in != -1 && (ses.remoteident || isempty(&ses.writequeue))) { FD_SET(ses.sock_in, &readfd); } if (ses.sock_out != -1 && !isempty(&ses.writequeue)) { @@ -195,7 +196,12 @@ if (ses.sock_in != -1) { if (FD_ISSET(ses.sock_in, &readfd)) { - read_packet(); + if (!ses.remoteident) { + /* blocking read of the version string */ + read_session_identification(); + } else { + read_packet(); + } } /* Process the decrypted packet. After this, the read buffer @@ -225,7 +231,7 @@ } /* clean up a session on exit */ -void common_session_cleanup() { +void session_cleanup() { TRACE(("enter session_cleanup")) @@ -234,6 +240,10 @@ TRACE(("leave session_cleanup: !sessinitdone")) return; } + + if (ses.extra_session_cleanup) { + ses.extra_session_cleanup(); + } if (ses.session_id) { buf_burn(ses.session_id); @@ -253,21 +263,20 @@ TRACE(("leave session_cleanup")) } +void send_session_identification() { + buffer *writebuf = buf_new(strlen(LOCAL_IDENT "\r\n") + 1); + buf_putbytes(writebuf, LOCAL_IDENT "\r\n", strlen(LOCAL_IDENT "\r\n")); + buf_putbyte(writebuf, 0x0); // packet type + buf_setpos(writebuf, 0); + enqueue(&ses.writequeue, writebuf); +} -void session_identification() { - +static void read_session_identification() { /* max length of 255 chars */ char linebuf[256]; int len = 0; char done = 0; int i; - - /* write our version string, this blocks */ - if (atomicio(write, ses.sock_out, LOCAL_IDENT "\r\n", - strlen(LOCAL_IDENT "\r\n")) == DROPBEAR_FAILURE) { - ses.remoteclosed(); - } - /* If they send more than 50 lines, something is wrong */ for (i = 0; i < 50; i++) { len = ident_readln(ses.sock_in, linebuf, sizeof(linebuf));