From 2bcb60fe56b7107d23c00a4aba0a4e0810448ddc Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Tue, 7 Jun 2011 11:55:44 +0000
Subject: [PATCH] Fix case where "-K 1" would cause a SSH_MSG_IGNORE packet to
 be sent with the wrong encryption key ("bad packet length" symptom) while key
 exchange was happening.

--HG--
extra : convert_revision : f7d27ec094c4aba2a4289c523c722fcb3c3f58ca
---
 kex.h    | 4 ++--
 packet.c | 8 +++++++-
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/kex.h b/kex.h
index a3bdc7a7..c89b0a3c 100644
--- a/kex.h
+++ b/kex.h
@@ -52,8 +52,8 @@ 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 sentnewkeys : 1; /* set once we've send/recv'ed MSG_NEWKEYS*/
-	unsigned recvnewkeys : 1;
+	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 */
diff --git a/packet.c b/packet.c
index 80eb1775..349ed400 100644
--- a/packet.c
+++ b/packet.c
@@ -441,10 +441,16 @@ void encrypt_packet() {
 
 	TRACE(("encrypt_packet type is %d", packet_type))
 	
-	if (!ses.dataallowed && !packet_is_okay_kex(packet_type)) {
+	if ((!ses.dataallowed && !packet_is_okay_kex(packet_type))
+			|| ses.kexstate.sentnewkeys) {
 		/* During key exchange only particular packets are allowed.
 			Since this packet_type isn't OK we just enqueue it to send 
 			after the KEX, see maybe_flush_reply_queue */
+
+		/* We also enqueue packets here when we have sent a MSG_NEWKEYS
+		 * packet but are yet to received one. For simplicity we just switch
+		 * over all the keys at once. This is the 'ses.kexstate.sentnewkeys'
+		 * case. */
 		enqueue_reply_packet();
 		return;
 	}
-- 
GitLab