diff options
-rw-r--r-- | cli-authpubkey.c | 4 | ||||
-rw-r--r-- | cli-kex.c | 10 | ||||
-rw-r--r-- | common-algo.c | 2 | ||||
-rw-r--r-- | common-kex.c | 7 | ||||
-rw-r--r-- | dropbearkey.c | 2 | ||||
-rw-r--r-- | kex.h | 4 | ||||
-rw-r--r-- | process-packet.c | 3 | ||||
-rw-r--r-- | session.h | 12 | ||||
-rw-r--r-- | signkey.c | 2 | ||||
-rw-r--r-- | svr-kex.c | 14 | ||||
-rw-r--r-- | svr-runopts.c | 2 | ||||
-rw-r--r-- | svr-session.c | 2 | ||||
-rw-r--r-- | sysoptions.h | 4 |
13 files changed, 46 insertions, 22 deletions
diff --git a/cli-authpubkey.c b/cli-authpubkey.c index 8426e84..49f79c3 100644 --- a/cli-authpubkey.c +++ b/cli-authpubkey.c @@ -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; @@ -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")) } diff --git a/common-algo.c b/common-algo.c index 54bc559..8596831 100644 --- a/common-algo.c +++ b/common-algo.c @@ -313,10 +313,12 @@ 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} }; diff --git a/common-kex.c b/common-kex.c index 7063c81..1ef1946 100644 --- a/common-kex.c +++ b/common-kex.c @@ -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; diff --git a/dropbearkey.c b/dropbearkey.c index f881855..8d8c7c2 100644 --- a/dropbearkey.c +++ b/dropbearkey.c @@ -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"); @@ -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; diff --git a/process-packet.c b/process-packet.c index 4953cf2..9c58c7c 100644 --- a/process-packet.c +++ b/process-packet.c @@ -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; @@ -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; @@ -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 diff --git a/svr-runopts.c b/svr-runopts.c index 770f70a..2c905dd 100644 --- a/svr-runopts.c +++ b/svr-runopts.c @@ -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 diff --git a/svr-session.c b/svr-session.c index 8bc8744..6c3147f 100644 --- a/svr-session.c +++ b/svr-session.c @@ -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 } } diff --git a/sysoptions.h b/sysoptions.h index 0f52431..d5f8da8 100644 --- a/sysoptions.h +++ b/sysoptions.h @@ -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 |