summaryrefslogtreecommitdiffhomepage
path: root/common-session.c
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2013-03-31 00:40:00 +0800
committerMatt Johnston <matt@ucc.asn.au>2013-03-31 00:40:00 +0800
commita0e931005b6f9de407ba2ac5b5df9e34d4a7fb7e (patch)
treedac556bfd732ac24af552b92713afcd77d57a3cb /common-session.c
parent9be0d6b53d6b85a8f273ee28876405fbca49b9fd (diff)
send out our kexinit packet before blocking to read the SSH version string
Diffstat (limited to 'common-session.c')
-rw-r--r--common-session.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/common-session.c b/common-session.c
index f4fa579..ec5c9ed 100644
--- a/common-session.c
+++ b/common-session.c
@@ -39,6 +39,7 @@
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 */
@@ -141,7 +142,10 @@ void session_loop(void(*loophandler)()) {
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 +199,12 @@ void session_loop(void(*loophandler)()) {
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
@@ -245,20 +254,20 @@ void common_session_cleanup() {
}
-void session_identification() {
-
- /* max length of 255 chars */
- char linebuf[256];
- int len = 0;
- char done = 0;
- int i;
-
+void send_session_identification() {
/* 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();
}
+}
+static void read_session_identification() {
+ /* max length of 255 chars */
+ char linebuf[256];
+ int len = 0;
+ char done = 0;
+ int i;
/* 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));