changeset 1681:435cfb9ec96e

send and handle SSH_MSG_EXT_INFO only at the correct point - other fixes for rsa pubkey auth - only include ext-info handling when rsa pubkey auth is compiled
author Matt Johnston <matt@ucc.asn.au>
date Sun, 24 May 2020 14:16:58 +0800
parents 5e763ad6e2e0
children a53e7d2d60be
files cli-authpubkey.c cli-kex.c common-algo.c common-kex.c dropbearkey.c kex.h process-packet.c session.h signkey.c svr-kex.c svr-runopts.c svr-session.c sysoptions.h
diffstat 13 files changed, 46 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/cli-authpubkey.c	Sun May 24 13:34:19 2020 +0800
+++ b/cli-authpubkey.c	Sun May 24 14:16:58 2020 +0800
@@ -200,7 +200,7 @@
  	while (cli_opts.privkeys->first) {
 		sign_key * key = (sign_key*)cli_opts.privkeys->first->item;
 		if (cli_ses.server_sig_algs) {
-#ifdef DROPBEAR_RSA
+#if DROPBEAR_RSA
 			if (key->type == DROPBEAR_SIGNKEY_RSA) {
 #if DROPBEAR_RSA_SHA256
 				if (buf_has_algo(cli_ses.server_sig_algs, SSH_SIGNATURE_RSA_SHA256) 
@@ -242,7 +242,7 @@
 			   assume all except rsa-sha256 are OK. */
 #if DROPBEAR_RSA
 			if (key->type == DROPBEAR_SIGNKEY_RSA) {
-#ifdef DROPBEAR_RSA_SHA1
+#if DROPBEAR_RSA_SHA1
 				sigtype = DROPBEAR_SIGNATURE_RSA_SHA1;
 				TRACE(("no server-sig-algs, using rsa sha1"))
 				break;
--- a/cli-kex.c	Sun May 24 13:34:19 2020 +0800
+++ b/cli-kex.c	Sun May 24 14:16:58 2020 +0800
@@ -418,6 +418,15 @@
 	unsigned int num_ext;
 	unsigned int i;
 
+	TRACE(("enter recv_msg_ext_info"))
+
+	/* Must be after the first SSH_MSG_NEWKEYS */
+	TRACE(("last %d, donefirst %d, donescond %d", ses.lastpacket, ses.kexstate.donefirstkex, ses.kexstate.donesecondkex))
+	if (!(ses.lastpacket == SSH_MSG_NEWKEYS && !ses.kexstate.donesecondkex)) {
+		TRACE(("leave recv_msg_ext_info: ignoring packet received at the wrong time"))
+		return;
+	}
+
 	num_ext = buf_getint(ses.payload);
 	TRACE(("received SSH_MSG_EXT_INFO with %d items", num_ext))
 
@@ -435,4 +444,5 @@
 		}
 		m_free(ext_name);
 	}
+	TRACE(("leave recv_msg_ext_info"))
 }
--- a/common-algo.c	Sun May 24 13:34:19 2020 +0800
+++ b/common-algo.c	Sun May 24 14:16:58 2020 +0800
@@ -313,10 +313,12 @@
 #if DROPBEAR_KEXGUESS2
 	{KEXGUESS2_ALGO_NAME, 0, NULL, 1, NULL},
 #endif
+#if DROPBEAR_EXT_INFO
 #if DROPBEAR_CLIENT
 	/* Set unusable by svr_algos_initialise() */
 	{SSH_EXT_INFO_C, 0, NULL, 1, NULL},
 #endif
+#endif
 	{NULL, 0, NULL, 0, NULL}
 };
 
--- a/common-kex.c	Sun May 24 13:34:19 2020 +0800
+++ b/common-kex.c	Sun May 24 14:16:58 2020 +0800
@@ -175,6 +175,9 @@
 	
 	/* set up our state */
 	ses.kexstate.sentnewkeys = 1;
+	if (ses.kexstate.donefirstkex) {
+		ses.kexstate.donesecondkex = 1;
+	}
 	ses.kexstate.donefirstkex = 1;
 	ses.dataallowed = 1; /* we can send other packets again now */
 	gen_new_keys();
@@ -197,8 +200,6 @@
 
 /* Set up the kex for the first time */
 void kexfirstinitialise() {
-	ses.kexstate.donefirstkex = 0;
-
 #ifdef DISABLE_ZLIB
 	ses.compress_algos = ssh_nocompress;
 #else
@@ -833,6 +834,7 @@
 	}
 #endif
 
+#if DROPBEAR_EXT_INFO
 	/* Determine if SSH_MSG_EXT_INFO messages should be sent.
 	Should be done for the first key exchange. Only required on server side
     for server-sig-algs */
@@ -843,6 +845,7 @@
 			}
 		}
 	}
+#endif
 
 	algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess);
 	allgood &= goodguess;
--- a/dropbearkey.c	Sun May 24 13:34:19 2020 +0800
+++ b/dropbearkey.c	Sun May 24 14:16:58 2020 +0800
@@ -133,7 +133,7 @@
 			}
 			break;
 #endif
-#ifdef DROPEAR_DSS
+#if DROPEAR_DSS
 		case DROPBEAR_SIGNKEY_DSS:
 			if (bits != 1024) {
 				dropbear_exit("DSS keys have a fixed size of 1024 bits\n");
--- a/kex.h	Sun May 24 13:34:19 2020 +0800
+++ b/kex.h	Sun May 24 14:16:58 2020 +0800
@@ -61,7 +61,6 @@
 #endif
 
 void recv_msg_kexdh_init(void); /* server */
-void send_msg_ext_info(void); /* server */
 
 void send_msg_kexdh_init(void); /* client */
 void recv_msg_kexdh_reply(void); /* client */
@@ -76,8 +75,9 @@
 	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,
+	unsigned int donefirstkex; /* Set to 1 after the first kex has completed,
 								  ie the transport layer has been set up */
+	unsigned int donesecondkex; /* Set to 1 after the second kex has completed */
 
 	unsigned our_first_follows_matches : 1;
 
--- a/process-packet.c	Sun May 24 13:34:19 2020 +0800
+++ b/process-packet.c	Sun May 24 14:16:58 2020 +0800
@@ -51,8 +51,6 @@
 	type = buf_getbyte(ses.payload);
 	TRACE(("process_packet: packet type = %d,  len %d", type, ses.payload->len))
 
-	ses.lastpacket = type;
-
 	now = monotonic_now();
 	ses.last_packet_time_keepalive_recv = now;
 
@@ -154,6 +152,7 @@
 	recv_unimplemented();
 
 out:
+	ses.lastpacket = type;
 	buf_free(ses.payload);
 	ses.payload = NULL;
 
--- a/session.h	Sun May 24 13:34:19 2020 +0800
+++ b/session.h	Sun May 24 14:16:58 2020 +0800
@@ -186,7 +186,7 @@
 	/* Enables/disables compression */
 	algo_type *compress_algos;
 
-	/* Other side allows SSH_MSG_EXT_INFO */
+	/* Other side allows SSH_MSG_EXT_INFO. Currently only set for server */
 	int allow_ext_info;
 							
 	/* a list of queued replies that should be sent after a KEX has
@@ -253,13 +253,12 @@
 #endif
 
 #if DROPBEAR_PLUGIN
-        /* The shared library handle */
-        void *plugin_handle;
+	/* The shared library handle */
+	void *plugin_handle;
 
-        /* The instance created by the plugin_new function */
-        struct PluginInstance *plugin_instance;
+	/* The instance created by the plugin_new function */
+	struct PluginInstance *plugin_instance;
 #endif
-
 };
 
 typedef enum {
@@ -288,7 +287,6 @@
 
 	cli_kex_state kex_state; /* Used for progressing KEX */
 	cli_state state; /* Used to progress auth/channelsession etc */
-	unsigned donefirstkex : 1; /* Set when we set sentnewkeys, never reset */
 
 	int tty_raw_mode; /* Whether we're in raw mode (and have to clean up) */
 	struct termios saved_tio;
--- a/signkey.c	Sun May 24 13:34:19 2020 +0800
+++ b/signkey.c	Sun May 24 14:16:58 2020 +0800
@@ -139,7 +139,7 @@
 		return DROPBEAR_SIGNATURE_RSA_SHA256;
 	}
 #endif
-#if DROPBEAR_RSA_SHA256
+#if DROPBEAR_RSA_SHA1
 	if (namelen == strlen(SSH_SIGNKEY_RSA) 
 		&& memcmp(name, SSH_SIGNKEY_RSA, namelen) == 0) {
 		return DROPBEAR_SIGNATURE_RSA_SHA1;
--- a/svr-kex.c	Sun May 24 13:34:19 2020 +0800
+++ b/svr-kex.c	Sun May 24 14:16:58 2020 +0800
@@ -38,13 +38,15 @@
 #include "gensignkey.h"
 
 static void send_msg_kexdh_reply(mp_int *dh_e, buffer *ecdh_qs);
+#if DROPBEAR_EXT_INFO
+static void send_msg_ext_info(void);
+#endif
 
 /* Handle a diffie-hellman key exchange initialisation. This involves
  * calculating a session key reply value, and corresponding hash. These
  * are carried out by send_msg_kexdh_reply(). recv_msg_kexdh_init() calls
  * that function, then brings the new keys into use */
 void recv_msg_kexdh_init() {
-
 	DEF_MP_INT(dh_e);
 	buffer *ecdh_qs = NULL;
 
@@ -87,9 +89,12 @@
 
 	send_msg_newkeys();
 
-	if (ses.allow_ext_info) {
+#if DROPBEAR_EXT_INFO
+	/* Only send it following the first newkeys */
+	if (!ses.kexstate.donesecondkex && ses.allow_ext_info) {
 		send_msg_ext_info();
 	}
+#endif
 
 	ses.requirenext = SSH_MSG_NEWKEYS;
 	TRACE(("leave recv_msg_kexdh_init"))
@@ -247,8 +252,9 @@
 	TRACE(("leave send_msg_kexdh_reply"))
 }
 
+#if DROPBEAR_EXT_INFO
 /* Only used for server-sig-algs on the server side */
-void send_msg_ext_info(void) {
+static void send_msg_ext_info(void) {
 	TRACE(("enter send_msg_ext_info"))
 
 	buf_putbyte(ses.writepayload, SSH_MSG_EXT_INFO);
@@ -261,5 +267,5 @@
 	encrypt_packet();
 
 	TRACE(("leave send_msg_ext_info"))
-
 }
+#endif
--- a/svr-runopts.c	Sun May 24 13:34:19 2020 +0800
+++ b/svr-runopts.c	Sun May 24 14:16:58 2020 +0800
@@ -567,7 +567,7 @@
 void load_all_hostkeys() {
 	int i;
 	int any_keys = 0;
-#ifdef DROPBEAR_ECDSA
+#if DROPBEAR_ECDSA
 	int loaded_any_ecdsa = 0;
 #endif
 
--- a/svr-session.c	Sun May 24 13:34:19 2020 +0800
+++ b/svr-session.c	Sun May 24 14:16:58 2020 +0800
@@ -337,9 +337,11 @@
 			algo->usable = 0;
 		}
 #endif
+#if DROPBEAR_EXT_INFO
 		if (strcmp(algo->name, SSH_EXT_INFO_C) == 0) {
 			algo->usable = 0;
 		}
+#endif
 	}
 }
 
--- a/sysoptions.h	Sun May 24 13:34:19 2020 +0800
+++ b/sysoptions.h	Sun May 24 14:16:58 2020 +0800
@@ -161,6 +161,10 @@
 
 #define DROPBEAR_NORMAL_DH ((DROPBEAR_DH_GROUP1) || (DROPBEAR_DH_GROUP14) || (DROPBEAR_DH_GROUP16))
 
+/* Dropbear only uses server-sig-algs, only needed if we have rsa-sha256 pubkey auth */
+#define DROPBEAR_EXT_INFO ((DROPBEAR_RSA_SHA256) \
+		&& ((DROPBEAR_CLI_PUBKEY_AUTH) || (DROPBEAR_SVR_PUBKEY_AUTH)))
+
 /* roughly 2x 521 bits */
 #define MAX_ECC_SIZE 140