summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2020-05-24 14:16:58 +0800
committerMatt Johnston <matt@ucc.asn.au>2020-05-24 14:16:58 +0800
commit7871273feb1a2e76857ddcc80b1fe7e7081b60b1 (patch)
tree092ae0172714b15d062ed9c47a1ae913321a0c96
parent71a3cec2995291047445255e3159a7867f05f947 (diff)
downloaddropbear-7871273feb1a2e76857ddcc80b1fe7e7081b60b1.tar.gz
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
-rw-r--r--cli-authpubkey.c4
-rw-r--r--cli-kex.c10
-rw-r--r--common-algo.c2
-rw-r--r--common-kex.c7
-rw-r--r--dropbearkey.c2
-rw-r--r--kex.h4
-rw-r--r--process-packet.c3
-rw-r--r--session.h12
-rw-r--r--signkey.c2
-rw-r--r--svr-kex.c14
-rw-r--r--svr-runopts.c2
-rw-r--r--svr-session.c2
-rw-r--r--sysoptions.h4
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;
diff --git a/cli-kex.c b/cli-kex.c
index 99370eb..98b0245 100644
--- a/cli-kex.c
+++ b/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"))
}
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");
diff --git a/kex.h b/kex.h
index cdec673..7406f65 100644
--- a/kex.h
+++ b/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;
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;
diff --git a/session.h b/session.h
index 1059537..a91401e 100644
--- a/session.h
+++ b/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;
diff --git a/signkey.c b/signkey.c
index 6ed1667..49801f3 100644
--- a/signkey.c
+++ b/signkey.c
@@ -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;
diff --git a/svr-kex.c b/svr-kex.c
index 44e10ff..df1008b 100644
--- a/svr-kex.c
+++ b/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
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