mirror of
				https://github.com/clearml/dropbear
				synced 2025-06-26 18:17:32 +00:00 
			
		
		
		
	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
This commit is contained in:
		
							parent
							
								
									79bedc90a1
								
							
						
					
					
						commit
						701d43b859
					
				| @ -200,7 +200,7 @@ int cli_auth_pubkey() { | ||||
|  	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 @@ int cli_auth_pubkey() { | ||||
| 			   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; | ||||
|  | ||||
							
								
								
									
										10
									
								
								cli-kex.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								cli-kex.c
									
									
									
									
									
								
							| @ -418,6 +418,15 @@ void recv_msg_ext_info(void) { | ||||
| 	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 @@ void recv_msg_ext_info(void) { | ||||
| 		} | ||||
| 		m_free(ext_name); | ||||
| 	} | ||||
| 	TRACE(("leave recv_msg_ext_info")) | ||||
| } | ||||
|  | ||||
| @ -313,9 +313,11 @@ algo_type sshkex[] = { | ||||
| #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} | ||||
| }; | ||||
|  | ||||
| @ -175,6 +175,9 @@ void send_msg_newkeys() { | ||||
| 	 | ||||
| 	/* 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 @@ void recv_msg_newkeys() { | ||||
| 
 | ||||
| /* 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 @@ static void read_kex_algos() { | ||||
| 	} | ||||
| #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 @@ static void read_kex_algos() { | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess); | ||||
| 	allgood &= goodguess; | ||||
|  | ||||
| @ -133,7 +133,7 @@ static void check_signkey_bits(enum signkey_type type, int bits) | ||||
| 			} | ||||
| 			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"); | ||||
|  | ||||
							
								
								
									
										4
									
								
								kex.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								kex.h
									
									
									
									
									
								
							| @ -61,7 +61,6 @@ int is_compress_recv(void); | ||||
| #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 @@ struct KEXState { | ||||
| 	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; | ||||
| 
 | ||||
|  | ||||
| @ -51,8 +51,6 @@ void process_packet() { | ||||
| 	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 @@ void process_packet() { | ||||
| 	recv_unimplemented(); | ||||
| 
 | ||||
| out: | ||||
| 	ses.lastpacket = type; | ||||
| 	buf_free(ses.payload); | ||||
| 	ses.payload = NULL; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										12
									
								
								session.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								session.h
									
									
									
									
									
								
							| @ -186,7 +186,7 @@ struct sshsession { | ||||
| 	/* 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 @@ struct serversession { | ||||
| #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 @@ struct clientsession { | ||||
| 
 | ||||
| 	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; | ||||
|  | ||||
| @ -139,7 +139,7 @@ enum signature_type signature_type_from_name(const char* name, unsigned int name | ||||
| 		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; | ||||
|  | ||||
							
								
								
									
										14
									
								
								svr-kex.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								svr-kex.c
									
									
									
									
									
								
							| @ -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 @@ void recv_msg_kexdh_init() { | ||||
| 
 | ||||
| 	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 @@ static void send_msg_kexdh_reply(mp_int *dh_e, buffer *ecdh_qs) { | ||||
| 	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 @@ void send_msg_ext_info(void) { | ||||
| 	encrypt_packet(); | ||||
| 
 | ||||
| 	TRACE(("leave send_msg_ext_info")) | ||||
| 
 | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @ -567,7 +567,7 @@ static void addhostkey(const char *keyfile) { | ||||
| void load_all_hostkeys() { | ||||
| 	int i; | ||||
| 	int any_keys = 0; | ||||
| #ifdef DROPBEAR_ECDSA | ||||
| #if DROPBEAR_ECDSA | ||||
| 	int loaded_any_ecdsa = 0; | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -337,9 +337,11 @@ static void svr_algos_initialise(void) { | ||||
| 			algo->usable = 0; | ||||
| 		} | ||||
| #endif | ||||
| #if DROPBEAR_EXT_INFO | ||||
| 		if (strcmp(algo->name, SSH_EXT_INFO_C) == 0) { | ||||
| 			algo->usable = 0; | ||||
| 		} | ||||
| #endif | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -161,6 +161,10 @@ If you test it please contact the Dropbear author */ | ||||
| 
 | ||||
| #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 | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user