# HG changeset patch # User Matt Johnston # Date 1590301018 -28800 # Node ID 435cfb9ec96ec6c491ade6129426fabe34ad8973 # Parent 5e763ad6e2e09787878a24fb24ff714e46bc0704 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 diff -r 5e763ad6e2e0 -r 435cfb9ec96e cli-authpubkey.c --- 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; diff -r 5e763ad6e2e0 -r 435cfb9ec96e cli-kex.c --- 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")) } diff -r 5e763ad6e2e0 -r 435cfb9ec96e common-algo.c --- 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} }; diff -r 5e763ad6e2e0 -r 435cfb9ec96e common-kex.c --- 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; diff -r 5e763ad6e2e0 -r 435cfb9ec96e dropbearkey.c --- 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"); diff -r 5e763ad6e2e0 -r 435cfb9ec96e kex.h --- 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; diff -r 5e763ad6e2e0 -r 435cfb9ec96e process-packet.c --- 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; diff -r 5e763ad6e2e0 -r 435cfb9ec96e session.h --- 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; diff -r 5e763ad6e2e0 -r 435cfb9ec96e signkey.c --- 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; diff -r 5e763ad6e2e0 -r 435cfb9ec96e svr-kex.c --- 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 diff -r 5e763ad6e2e0 -r 435cfb9ec96e svr-runopts.c --- 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 diff -r 5e763ad6e2e0 -r 435cfb9ec96e svr-session.c --- 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 } } diff -r 5e763ad6e2e0 -r 435cfb9ec96e sysoptions.h --- 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