summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2014-01-23 21:56:35 +0800
committerMatt Johnston <matt@ucc.asn.au>2014-01-23 21:56:35 +0800
commit7c83a3cb377390247f205789fd102877f6a51e4a (patch)
tree3d843f70c1992ec9858292e974be29606441b573
parent23cd3027a19cdb9aaa533ea05eeab11a569203f4 (diff)
downloaddropbear-7c83a3cb377390247f205789fd102877f6a51e4a.tar.gz
Fix failing rekeying when we receive a still-in-flight packet
-rw-r--r--cli-kex.c2
-rw-r--r--common-kex.c5
-rw-r--r--process-packet.c29
3 files changed, 25 insertions, 11 deletions
diff --git a/cli-kex.c b/cli-kex.c
index 55b0041..a4fa39a 100644
--- a/cli-kex.c
+++ b/cli-kex.c
@@ -86,8 +86,6 @@ void send_msg_kexdh_init() {
cli_ses.param_kex_algo = ses.newkeys->algo_kex;
encrypt_packet();
- ses.requirenext[0] = SSH_MSG_KEXDH_REPLY;
- ses.requirenext[1] = SSH_MSG_KEXINIT;
}
/* Handle a diffie-hellman key exchange reply. */
diff --git a/common-kex.c b/common-kex.c
index b318515..3c1e604 100644
--- a/common-kex.c
+++ b/common-kex.c
@@ -483,9 +483,6 @@ static void gen_new_zstream_trans() {
* and we calculate the first portion of the key-exchange-hash for used
* later in the key exchange. No response is sent, as the client should
* initiate the diffie-hellman key exchange */
-
-/* Originally from kex.c, generalized for cli/svr mode --mihnea */
-/* Belongs in common_kex.c where it should be moved after review */
void recv_msg_kexinit() {
unsigned int kexhashbuf_len = 0;
@@ -528,7 +525,7 @@ void recv_msg_kexinit() {
/* I_S, the payload of the server's SSH_MSG_KEXINIT */
buf_setpos(ses.payload, 0);
buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len);
-
+ ses.requirenext[0] = SSH_MSG_KEXDH_REPLY;
} else {
/* SERVER */
diff --git a/process-packet.c b/process-packet.c
index 0b92510..97de203 100644
--- a/process-packet.c
+++ b/process-packet.c
@@ -75,15 +75,34 @@ void process_packet() {
/* This applies for KEX, where the spec says the next packet MUST be
* NEWKEYS */
if (ses.requirenext[0] != 0) {
- if (ses.requirenext[0] != type
- && (ses.requirenext[1] == 0 || ses.requirenext[1] != type)) {
- dropbear_exit("Unexpected packet type %d, expected [%d,%d]", type,
- ses.requirenext[0], ses.requirenext[1]);
- } else {
+ if (ses.requirenext[0] == type || ses.requirenext[1] == type)
+ {
/* Got what we expected */
+ TRACE(("got expeced packet %d during kexinit", type))
ses.requirenext[0] = 0;
ses.requirenext[1] = 0;
}
+ else
+ {
+ /* RFC4253 7.1 - various messages are allowed at this point.
+ The only ones we know about have already been handled though,
+ so just return "unimplemented" */
+ if (type >= 1 && type <= 49
+ && type != SSH_MSG_SERVICE_REQUEST
+ && type != SSH_MSG_SERVICE_ACCEPT
+ && type != SSH_MSG_KEXINIT)
+ {
+ TRACE(("unknown allowed packet during kexinit"))
+ recv_unimplemented();
+ goto out;
+ }
+ else
+ {
+ TRACE(("disallowed packet during kexinit"))
+ dropbear_exit("Unexpected packet type %d, expected [%d,%d]", type,
+ ses.requirenext[0], ses.requirenext[1]);
+ }
+ }
}
/* Check if we should ignore this packet. Used currently only for