mirror of
https://github.com/clearml/dropbear
synced 2025-04-22 07:05:13 +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) {
|
while (cli_opts.privkeys->first) {
|
||||||
sign_key * key = (sign_key*)cli_opts.privkeys->first->item;
|
sign_key * key = (sign_key*)cli_opts.privkeys->first->item;
|
||||||
if (cli_ses.server_sig_algs) {
|
if (cli_ses.server_sig_algs) {
|
||||||
#ifdef DROPBEAR_RSA
|
#if DROPBEAR_RSA
|
||||||
if (key->type == DROPBEAR_SIGNKEY_RSA) {
|
if (key->type == DROPBEAR_SIGNKEY_RSA) {
|
||||||
#if DROPBEAR_RSA_SHA256
|
#if DROPBEAR_RSA_SHA256
|
||||||
if (buf_has_algo(cli_ses.server_sig_algs, SSH_SIGNATURE_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. */
|
assume all except rsa-sha256 are OK. */
|
||||||
#if DROPBEAR_RSA
|
#if DROPBEAR_RSA
|
||||||
if (key->type == DROPBEAR_SIGNKEY_RSA) {
|
if (key->type == DROPBEAR_SIGNKEY_RSA) {
|
||||||
#ifdef DROPBEAR_RSA_SHA1
|
#if DROPBEAR_RSA_SHA1
|
||||||
sigtype = DROPBEAR_SIGNATURE_RSA_SHA1;
|
sigtype = DROPBEAR_SIGNATURE_RSA_SHA1;
|
||||||
TRACE(("no server-sig-algs, using rsa sha1"))
|
TRACE(("no server-sig-algs, using rsa sha1"))
|
||||||
break;
|
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 num_ext;
|
||||||
unsigned int i;
|
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);
|
num_ext = buf_getint(ses.payload);
|
||||||
TRACE(("received SSH_MSG_EXT_INFO with %d items", num_ext))
|
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);
|
m_free(ext_name);
|
||||||
}
|
}
|
||||||
|
TRACE(("leave recv_msg_ext_info"))
|
||||||
}
|
}
|
||||||
|
@ -313,9 +313,11 @@ algo_type sshkex[] = {
|
|||||||
#if DROPBEAR_KEXGUESS2
|
#if DROPBEAR_KEXGUESS2
|
||||||
{KEXGUESS2_ALGO_NAME, 0, NULL, 1, NULL},
|
{KEXGUESS2_ALGO_NAME, 0, NULL, 1, NULL},
|
||||||
#endif
|
#endif
|
||||||
|
#if DROPBEAR_EXT_INFO
|
||||||
#if DROPBEAR_CLIENT
|
#if DROPBEAR_CLIENT
|
||||||
/* Set unusable by svr_algos_initialise() */
|
/* Set unusable by svr_algos_initialise() */
|
||||||
{SSH_EXT_INFO_C, 0, NULL, 1, NULL},
|
{SSH_EXT_INFO_C, 0, NULL, 1, NULL},
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
{NULL, 0, NULL, 0, NULL}
|
{NULL, 0, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
@ -175,6 +175,9 @@ void send_msg_newkeys() {
|
|||||||
|
|
||||||
/* set up our state */
|
/* set up our state */
|
||||||
ses.kexstate.sentnewkeys = 1;
|
ses.kexstate.sentnewkeys = 1;
|
||||||
|
if (ses.kexstate.donefirstkex) {
|
||||||
|
ses.kexstate.donesecondkex = 1;
|
||||||
|
}
|
||||||
ses.kexstate.donefirstkex = 1;
|
ses.kexstate.donefirstkex = 1;
|
||||||
ses.dataallowed = 1; /* we can send other packets again now */
|
ses.dataallowed = 1; /* we can send other packets again now */
|
||||||
gen_new_keys();
|
gen_new_keys();
|
||||||
@ -197,8 +200,6 @@ void recv_msg_newkeys() {
|
|||||||
|
|
||||||
/* Set up the kex for the first time */
|
/* Set up the kex for the first time */
|
||||||
void kexfirstinitialise() {
|
void kexfirstinitialise() {
|
||||||
ses.kexstate.donefirstkex = 0;
|
|
||||||
|
|
||||||
#ifdef DISABLE_ZLIB
|
#ifdef DISABLE_ZLIB
|
||||||
ses.compress_algos = ssh_nocompress;
|
ses.compress_algos = ssh_nocompress;
|
||||||
#else
|
#else
|
||||||
@ -833,6 +834,7 @@ static void read_kex_algos() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if DROPBEAR_EXT_INFO
|
||||||
/* Determine if SSH_MSG_EXT_INFO messages should be sent.
|
/* Determine if SSH_MSG_EXT_INFO messages should be sent.
|
||||||
Should be done for the first key exchange. Only required on server side
|
Should be done for the first key exchange. Only required on server side
|
||||||
for server-sig-algs */
|
for server-sig-algs */
|
||||||
@ -843,6 +845,7 @@ static void read_kex_algos() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess);
|
algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess);
|
||||||
allgood &= goodguess;
|
allgood &= goodguess;
|
||||||
|
@ -133,7 +133,7 @@ static void check_signkey_bits(enum signkey_type type, int bits)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef DROPEAR_DSS
|
#if DROPEAR_DSS
|
||||||
case DROPBEAR_SIGNKEY_DSS:
|
case DROPBEAR_SIGNKEY_DSS:
|
||||||
if (bits != 1024) {
|
if (bits != 1024) {
|
||||||
dropbear_exit("DSS keys have a fixed size of 1024 bits\n");
|
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
|
#endif
|
||||||
|
|
||||||
void recv_msg_kexdh_init(void); /* server */
|
void recv_msg_kexdh_init(void); /* server */
|
||||||
void send_msg_ext_info(void); /* server */
|
|
||||||
|
|
||||||
void send_msg_kexdh_init(void); /* client */
|
void send_msg_kexdh_init(void); /* client */
|
||||||
void recv_msg_kexdh_reply(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 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 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 */
|
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;
|
unsigned our_first_follows_matches : 1;
|
||||||
|
|
||||||
|
@ -51,8 +51,6 @@ void process_packet() {
|
|||||||
type = buf_getbyte(ses.payload);
|
type = buf_getbyte(ses.payload);
|
||||||
TRACE(("process_packet: packet type = %d, len %d", type, ses.payload->len))
|
TRACE(("process_packet: packet type = %d, len %d", type, ses.payload->len))
|
||||||
|
|
||||||
ses.lastpacket = type;
|
|
||||||
|
|
||||||
now = monotonic_now();
|
now = monotonic_now();
|
||||||
ses.last_packet_time_keepalive_recv = now;
|
ses.last_packet_time_keepalive_recv = now;
|
||||||
|
|
||||||
@ -154,6 +152,7 @@ void process_packet() {
|
|||||||
recv_unimplemented();
|
recv_unimplemented();
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
ses.lastpacket = type;
|
||||||
buf_free(ses.payload);
|
buf_free(ses.payload);
|
||||||
ses.payload = NULL;
|
ses.payload = NULL;
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ struct sshsession {
|
|||||||
/* Enables/disables compression */
|
/* Enables/disables compression */
|
||||||
algo_type *compress_algos;
|
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;
|
int allow_ext_info;
|
||||||
|
|
||||||
/* a list of queued replies that should be sent after a KEX has
|
/* a list of queued replies that should be sent after a KEX has
|
||||||
@ -259,7 +259,6 @@ struct serversession {
|
|||||||
/* The instance created by the plugin_new function */
|
/* The instance created by the plugin_new function */
|
||||||
struct PluginInstance *plugin_instance;
|
struct PluginInstance *plugin_instance;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -288,7 +287,6 @@ struct clientsession {
|
|||||||
|
|
||||||
cli_kex_state kex_state; /* Used for progressing KEX */
|
cli_kex_state kex_state; /* Used for progressing KEX */
|
||||||
cli_state state; /* Used to progress auth/channelsession etc */
|
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) */
|
int tty_raw_mode; /* Whether we're in raw mode (and have to clean up) */
|
||||||
struct termios saved_tio;
|
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;
|
return DROPBEAR_SIGNATURE_RSA_SHA256;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if DROPBEAR_RSA_SHA256
|
#if DROPBEAR_RSA_SHA1
|
||||||
if (namelen == strlen(SSH_SIGNKEY_RSA)
|
if (namelen == strlen(SSH_SIGNKEY_RSA)
|
||||||
&& memcmp(name, SSH_SIGNKEY_RSA, namelen) == 0) {
|
&& memcmp(name, SSH_SIGNKEY_RSA, namelen) == 0) {
|
||||||
return DROPBEAR_SIGNATURE_RSA_SHA1;
|
return DROPBEAR_SIGNATURE_RSA_SHA1;
|
||||||
|
14
svr-kex.c
14
svr-kex.c
@ -38,13 +38,15 @@
|
|||||||
#include "gensignkey.h"
|
#include "gensignkey.h"
|
||||||
|
|
||||||
static void send_msg_kexdh_reply(mp_int *dh_e, buffer *ecdh_qs);
|
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
|
/* Handle a diffie-hellman key exchange initialisation. This involves
|
||||||
* calculating a session key reply value, and corresponding hash. These
|
* calculating a session key reply value, and corresponding hash. These
|
||||||
* are carried out by send_msg_kexdh_reply(). recv_msg_kexdh_init() calls
|
* are carried out by send_msg_kexdh_reply(). recv_msg_kexdh_init() calls
|
||||||
* that function, then brings the new keys into use */
|
* that function, then brings the new keys into use */
|
||||||
void recv_msg_kexdh_init() {
|
void recv_msg_kexdh_init() {
|
||||||
|
|
||||||
DEF_MP_INT(dh_e);
|
DEF_MP_INT(dh_e);
|
||||||
buffer *ecdh_qs = NULL;
|
buffer *ecdh_qs = NULL;
|
||||||
|
|
||||||
@ -87,9 +89,12 @@ void recv_msg_kexdh_init() {
|
|||||||
|
|
||||||
send_msg_newkeys();
|
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();
|
send_msg_ext_info();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ses.requirenext = SSH_MSG_NEWKEYS;
|
ses.requirenext = SSH_MSG_NEWKEYS;
|
||||||
TRACE(("leave recv_msg_kexdh_init"))
|
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"))
|
TRACE(("leave send_msg_kexdh_reply"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DROPBEAR_EXT_INFO
|
||||||
/* Only used for server-sig-algs on the server side */
|
/* 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"))
|
TRACE(("enter send_msg_ext_info"))
|
||||||
|
|
||||||
buf_putbyte(ses.writepayload, SSH_MSG_EXT_INFO);
|
buf_putbyte(ses.writepayload, SSH_MSG_EXT_INFO);
|
||||||
@ -261,5 +267,5 @@ void send_msg_ext_info(void) {
|
|||||||
encrypt_packet();
|
encrypt_packet();
|
||||||
|
|
||||||
TRACE(("leave send_msg_ext_info"))
|
TRACE(("leave send_msg_ext_info"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -567,7 +567,7 @@ static void addhostkey(const char *keyfile) {
|
|||||||
void load_all_hostkeys() {
|
void load_all_hostkeys() {
|
||||||
int i;
|
int i;
|
||||||
int any_keys = 0;
|
int any_keys = 0;
|
||||||
#ifdef DROPBEAR_ECDSA
|
#if DROPBEAR_ECDSA
|
||||||
int loaded_any_ecdsa = 0;
|
int loaded_any_ecdsa = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -337,9 +337,11 @@ static void svr_algos_initialise(void) {
|
|||||||
algo->usable = 0;
|
algo->usable = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if DROPBEAR_EXT_INFO
|
||||||
if (strcmp(algo->name, SSH_EXT_INFO_C) == 0) {
|
if (strcmp(algo->name, SSH_EXT_INFO_C) == 0) {
|
||||||
algo->usable = 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))
|
#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 */
|
/* roughly 2x 521 bits */
|
||||||
#define MAX_ECC_SIZE 140
|
#define MAX_ECC_SIZE 140
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user