summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2013-03-29 20:44:13 +0800
committerMatt Johnston <matt@ucc.asn.au>2013-03-29 20:44:13 +0800
commit538f12d7682b9efb0d4c6001d55e9e8dd8029ac3 (patch)
treed93cf1c116aa4adb0062d91f9a6404e654e8275f
parent97c2588e7f15ecbd92d08d7c29e65bad76aef344 (diff)
downloaddropbear-538f12d7682b9efb0d4c6001d55e9e8dd8029ac3.tar.gz
first_kex_packet_follows working, needs tidying
-rw-r--r--cli-kex.c5
-rw-r--r--cli-session.c21
-rw-r--r--common-kex.c34
-rw-r--r--kex.h4
-rw-r--r--session.h2
5 files changed, 48 insertions, 18 deletions
diff --git a/cli-kex.c b/cli-kex.c
index 9dadb3c..828af9a 100644
--- a/cli-kex.c
+++ b/cli-kex.c
@@ -42,7 +42,7 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen);
#define MAX_KNOWNHOSTS_LINE 4500
void send_msg_kexdh_init() {
-
+ TRACE(("send_msg_kexdh_init()"))
cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int));
cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int));
m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL);
@@ -53,7 +53,8 @@ void send_msg_kexdh_init() {
buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT);
buf_putmpint(ses.writepayload, cli_ses.dh_e);
encrypt_packet();
- ses.requirenext = SSH_MSG_KEXDH_REPLY;
+ // XXX fixme
+ //ses.requirenext = SSH_MSG_KEXDH_REPLY;
}
/* Handle a diffie-hellman key exchange reply. */
diff --git a/cli-session.c b/cli-session.c
index e58fdbd..cc514bb 100644
--- a/cli-session.c
+++ b/cli-session.c
@@ -109,6 +109,12 @@ void cli_session(int sock_in, int sock_out) {
}
+static void cli_send_kex_first_guess() {
+ send_msg_kexdh_init();
+ dropbear_log(LOG_INFO, "kexdh_init guess sent");
+ //cli_ses.kex_state = KEXDH_INIT_SENT;
+}
+
static void cli_session_init() {
cli_ses.state = STATE_NOTHING;
@@ -148,6 +154,9 @@ static void cli_session_init() {
ses.packettypes = cli_packettypes;
ses.isserver = 0;
+
+ ses.send_kex_first_guess = cli_send_kex_first_guess;
+
}
/* This function drives the progress of the session - it initiates KEX,
@@ -157,15 +166,13 @@ static void cli_sessionloop() {
TRACE(("enter cli_sessionloop"))
if (ses.lastpacket == SSH_MSG_KEXINIT && cli_ses.kex_state == KEX_NOTHING) {
- cli_ses.kex_state = KEXINIT_RCVD;
- }
-
- if (cli_ses.kex_state == KEXINIT_RCVD) {
-
/* We initiate the KEXDH. If DH wasn't the correct type, the KEXINIT
* negotiation would have failed. */
- send_msg_kexdh_init();
- cli_ses.kex_state = KEXDH_INIT_SENT;
+ if (!ses.kexstate.our_first_follows_matches) {
+ dropbear_log(LOG_INFO, "kexdh_init after remote's kexinit");
+ send_msg_kexdh_init();
+ }
+ cli_ses.kex_state = KEXDH_INIT_SENT;
TRACE(("leave cli_sessionloop: done with KEXINIT_RCVD"))
return;
}
diff --git a/common-kex.c b/common-kex.c
index 56b206d..e4b4c02 100644
--- a/common-kex.c
+++ b/common-kex.c
@@ -131,8 +131,8 @@ void send_msg_kexinit() {
/* languages_server_to_client */
buf_putstring(ses.writepayload, "", 0);
- /* first_kex_packet_follows - unimplemented for now */
- buf_putbyte(ses.writepayload, 0x00);
+ /* first_kex_packet_follows */
+ buf_putbyte(ses.writepayload, (ses.send_kex_first_guess != NULL));
/* reserved unit32 */
buf_putint(ses.writepayload, 0);
@@ -144,9 +144,19 @@ void send_msg_kexinit() {
encrypt_packet();
ses.dataallowed = 0; /* don't send other packets during kex */
+ ses.kexstate.sentkexinit = 1;
+
+ ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context));
+
+ if (ses.send_kex_first_guess) {
+ ses.newkeys->algo_kex = sshkex[0].val;
+ ses.newkeys->algo_hostkey = sshhostkey[0].val;
+ ses.send_kex_first_guess();
+ }
+
TRACE(("DATAALLOWED=0"))
TRACE(("-> KEXINIT"))
- ses.kexstate.sentkexinit = 1;
+
}
/* *** NOTE regarding (send|recv)_msg_newkeys ***
@@ -236,11 +246,13 @@ static void kexinitialise() {
ses.kexstate.sentnewkeys = 0;
/* first_packet_follows */
- ses.kexstate.firstfollows = 0;
+ ses.kexstate.them_firstfollows = 0;
ses.kexstate.datatrans = 0;
ses.kexstate.datarecv = 0;
+ ses.kexstate.our_first_follows_matches = 0;
+
ses.kexstate.lastkextime = time(NULL);
}
@@ -555,7 +567,7 @@ void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) {
DEF_MP_INT(dh_q);
DEF_MP_INT(dh_g);
- TRACE(("enter send_msg_kexdh_reply"))
+ TRACE(("enter gen_kexdh_vals"))
m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL);
@@ -678,7 +690,7 @@ static void read_kex_algos() {
buf_incrpos(ses.payload, 16); /* start after the cookie */
- ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context));
+ memset(ses.newkeys, 0x0, sizeof(*ses.newkeys));
/* kex_algorithms */
algo = ses.buf_match_algo(ses.payload, sshkex, &goodguess);
@@ -754,9 +766,10 @@ static void read_kex_algos() {
/* languages_server_to_client */
buf_eatstring(ses.payload);
- /* first_kex_packet_follows */
+ /* their first_kex_packet_follows */
if (buf_getbool(ses.payload)) {
- ses.kexstate.firstfollows = 1;
+ TRACE(("them kex firstfollows. allgood %d", allgood))
+ ses.kexstate.them_firstfollows = 1;
/* if the guess wasn't good, we ignore the packet sent */
if (!allgood) {
ses.ignorenext = 1;
@@ -799,6 +812,11 @@ static void read_kex_algos() {
/* reserved for future extensions */
buf_getint(ses.payload);
+
+ if (ses.send_kex_first_guess && allgood) {
+ TRACE(("our_first_follows_matches 1"))
+ ses.kexstate.our_first_follows_matches = 1;
+ }
return;
error:
diff --git a/kex.h b/kex.h
index c89b0a3..dc5f46b 100644
--- a/kex.h
+++ b/kex.h
@@ -51,13 +51,15 @@ struct KEXState {
unsigned sentkexinit : 1; /*set when we've sent/recv kexinit packet */
unsigned recvkexinit : 1;
- unsigned firstfollows : 1; /* true when first_kex_packet_follows is set */
+ unsigned them_firstfollows : 1; /* true when first_kex_packet_follows is set */
unsigned sentnewkeys : 1; /* set once we've send MSG_NEWKEYS (will be cleared once we have also received */
unsigned recvnewkeys : 1; /* set once we've received MSG_NEWKEYS (cleared once we have also sent */
unsigned donefirstkex : 1; /* Set to 1 after the first kex has completed,
ie the transport layer has been set up */
+ unsigned our_first_follows_matches : 1;
+
time_t lastkextime; /* time of the last kex */
unsigned int datatrans; /* data transmitted since last kex */
unsigned int datarecv; /* data received since last kex */
diff --git a/session.h b/session.h
index 0719e34..6b106f5 100644
--- a/session.h
+++ b/session.h
@@ -178,6 +178,8 @@ struct sshsession {
void(*remoteclosed)(); /* A callback to handle closure of the
remote connection */
+ void(*send_kex_first_guess)();
+
struct AuthState authstate; /* Common amongst client and server, since most
struct elements are common */