mirror of
https://github.com/clearml/dropbear
synced 2025-04-25 16:39:28 +00:00
Add kexguess2 behaviour
--HG-- branch : kexguess
This commit is contained in:
parent
4f62da0f0d
commit
99d9cf500b
14
algo.h
14
algo.h
@ -83,10 +83,20 @@ void crypto_init();
|
||||
int have_algo(char* algo, size_t algolen, algo_type algos[]);
|
||||
void buf_put_algolist(buffer * buf, algo_type localalgos[]);
|
||||
|
||||
enum kexguess2_used {
|
||||
KEXGUESS2_LOOK,
|
||||
KEXGUESS2_NO,
|
||||
KEXGUESS2_YES,
|
||||
};
|
||||
|
||||
#define KEXGUESS2_ALGO_NAME "kexguess2@matt.ucc.asn.au"
|
||||
#define KEXGUESS2_ALGO_ID 99
|
||||
|
||||
|
||||
algo_type * svr_buf_match_algo(buffer* buf, algo_type localalgos[],
|
||||
int *goodguess);
|
||||
enum kexguess2_used *kexguess2, int *goodguess);
|
||||
algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[],
|
||||
int *goodguess);
|
||||
enum kexguess2_used *kexguess2, int *goodguess);
|
||||
|
||||
#ifdef ENABLE_USER_ALGO_LIST
|
||||
int check_user_algos(const char* user_algo_list, algo_type * algos,
|
||||
|
32
cli-algo.c
32
cli-algo.c
@ -34,7 +34,7 @@
|
||||
* that is also on the server's list.
|
||||
*/
|
||||
algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[],
|
||||
int *goodguess) {
|
||||
enum kexguess2_used *kexguess2, int *goodguess) {
|
||||
|
||||
unsigned char * algolist = NULL;
|
||||
unsigned char * remotealgos[MAX_PROPOSED_ALGO];
|
||||
@ -42,7 +42,9 @@ algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[],
|
||||
unsigned int count, i, j;
|
||||
algo_type * ret = NULL;
|
||||
|
||||
*goodguess = 0;
|
||||
if (goodguess) {
|
||||
*goodguess = 0;
|
||||
}
|
||||
|
||||
/* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */
|
||||
algolist = buf_getstring(buf, &len);
|
||||
@ -72,6 +74,19 @@ algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[],
|
||||
}
|
||||
}
|
||||
|
||||
if (kexguess2 && *kexguess2 == KEXGUESS2_LOOK) {
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (strcmp(remotealgos[i], KEXGUESS2_ALGO_NAME) == 0) {
|
||||
*kexguess2 = KEXGUESS2_YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*kexguess2 == KEXGUESS2_LOOK) {
|
||||
*kexguess2 = KEXGUESS2_NO;
|
||||
}
|
||||
}
|
||||
|
||||
/* iterate and find the first match */
|
||||
|
||||
for (j = 0; localalgos[j].name != NULL; j++) {
|
||||
@ -81,9 +96,16 @@ algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[],
|
||||
if (len == strlen(remotealgos[i])
|
||||
&& strncmp(localalgos[j].name,
|
||||
remotealgos[i], len) == 0) {
|
||||
if (i == 0 && j == 0) {
|
||||
/* was a good guess */
|
||||
*goodguess = 1;
|
||||
if (goodguess && kexguess2) {
|
||||
if (*kexguess2 == KEXGUESS2_YES) {
|
||||
if (j == 0) {
|
||||
*goodguess = 1;
|
||||
}
|
||||
} else {
|
||||
if (i == 0 && j == 0) {
|
||||
*goodguess = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = &localalgos[j];
|
||||
goto out;
|
||||
|
@ -215,6 +215,7 @@ algo_type sshhostkey[] = {
|
||||
algo_type sshkex[] = {
|
||||
{"diffie-hellman-group1-sha1", DROPBEAR_KEX_DH_GROUP1, NULL, 1, NULL},
|
||||
{"diffie-hellman-group14-sha1", DROPBEAR_KEX_DH_GROUP14, NULL, 1, NULL},
|
||||
{KEXGUESS2_ALGO_NAME, KEXGUESS2_ALGO_ID, NULL, 1, NULL},
|
||||
{NULL, 0, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
21
common-kex.c
21
common-kex.c
@ -692,18 +692,21 @@ static void read_kex_algos() {
|
||||
|
||||
memset(ses.newkeys, 0x0, sizeof(*ses.newkeys));
|
||||
|
||||
enum kexguess2_used kexguess2 = KEXGUESS2_LOOK;
|
||||
|
||||
/* kex_algorithms */
|
||||
algo = ses.buf_match_algo(ses.payload, sshkex, &goodguess);
|
||||
algo = ses.buf_match_algo(ses.payload, sshkex, &kexguess2, &goodguess);
|
||||
allgood &= goodguess;
|
||||
if (algo == NULL) {
|
||||
if (algo == NULL || algo->val == KEXGUESS2_ALGO_ID) {
|
||||
erralgo = "kex";
|
||||
goto error;
|
||||
}
|
||||
TRACE(("kexguess2 %d", kexguess2))
|
||||
TRACE(("kex algo %s", algo->name))
|
||||
ses.newkeys->algo_kex = algo->val;
|
||||
|
||||
/* server_host_key_algorithms */
|
||||
algo = ses.buf_match_algo(ses.payload, sshhostkey, &goodguess);
|
||||
algo = ses.buf_match_algo(ses.payload, sshhostkey, &kexguess2, &goodguess);
|
||||
allgood &= goodguess;
|
||||
if (algo == NULL) {
|
||||
erralgo = "hostkey";
|
||||
@ -713,7 +716,7 @@ static void read_kex_algos() {
|
||||
ses.newkeys->algo_hostkey = algo->val;
|
||||
|
||||
/* encryption_algorithms_client_to_server */
|
||||
c2s_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess);
|
||||
c2s_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, NULL, NULL);
|
||||
if (c2s_cipher_algo == NULL) {
|
||||
erralgo = "enc c->s";
|
||||
goto error;
|
||||
@ -721,7 +724,7 @@ static void read_kex_algos() {
|
||||
TRACE(("enc c2s is %s", c2s_cipher_algo->name))
|
||||
|
||||
/* encryption_algorithms_server_to_client */
|
||||
s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess);
|
||||
s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, NULL, NULL);
|
||||
if (s2c_cipher_algo == NULL) {
|
||||
erralgo = "enc s->c";
|
||||
goto error;
|
||||
@ -729,7 +732,7 @@ static void read_kex_algos() {
|
||||
TRACE(("enc s2c is %s", s2c_cipher_algo->name))
|
||||
|
||||
/* mac_algorithms_client_to_server */
|
||||
c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess);
|
||||
c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, NULL, NULL);
|
||||
if (c2s_hash_algo == NULL) {
|
||||
erralgo = "mac c->s";
|
||||
goto error;
|
||||
@ -737,7 +740,7 @@ static void read_kex_algos() {
|
||||
TRACE(("hash c2s is %s", c2s_hash_algo->name))
|
||||
|
||||
/* mac_algorithms_server_to_client */
|
||||
s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess);
|
||||
s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, NULL, NULL);
|
||||
if (s2c_hash_algo == NULL) {
|
||||
erralgo = "mac s->c";
|
||||
goto error;
|
||||
@ -745,7 +748,7 @@ static void read_kex_algos() {
|
||||
TRACE(("hash s2c is %s", s2c_hash_algo->name))
|
||||
|
||||
/* compression_algorithms_client_to_server */
|
||||
c2s_comp_algo = ses.buf_match_algo(ses.payload, ses.compress_algos, &goodguess);
|
||||
c2s_comp_algo = ses.buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL);
|
||||
if (c2s_comp_algo == NULL) {
|
||||
erralgo = "comp c->s";
|
||||
goto error;
|
||||
@ -753,7 +756,7 @@ static void read_kex_algos() {
|
||||
TRACE(("hash c2s is %s", c2s_comp_algo->name))
|
||||
|
||||
/* compression_algorithms_server_to_client */
|
||||
s2c_comp_algo = ses.buf_match_algo(ses.payload, ses.compress_algos, &goodguess);
|
||||
s2c_comp_algo = ses.buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL);
|
||||
if (s2c_comp_algo == NULL) {
|
||||
erralgo = "comp s->c";
|
||||
goto error;
|
||||
|
4
debug.h
4
debug.h
@ -39,7 +39,7 @@
|
||||
* Caution: Don't use this in an unfriendly environment (ie unfirewalled),
|
||||
* since the printing may not sanitise strings etc. This will add a reasonable
|
||||
* amount to your executable size. */
|
||||
/*#define DEBUG_TRACE */
|
||||
#define DEBUG_TRACE
|
||||
|
||||
/* All functions writing to the cleartext payload buffer call
|
||||
* CHECKCLEARTOWRITE() before writing. This is only really useful if you're
|
||||
@ -69,7 +69,7 @@
|
||||
|
||||
/* To debug with GDB it is easier to run with no forking of child processes.
|
||||
You will need to pass "-F" as well. */
|
||||
/* #define DEBUG_NOFORK */
|
||||
#define DEBUG_NOFORK
|
||||
|
||||
|
||||
/* For testing as non-root on shadowed systems, include the crypt of a password
|
||||
|
1
kex.h
1
kex.h
@ -66,6 +66,7 @@ struct KEXState {
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define MAX_KEXHASHBUF 2000
|
||||
|
||||
#endif /* _KEX_H_ */
|
||||
|
@ -174,9 +174,9 @@ much traffic. */
|
||||
* PAM challenge/response.
|
||||
* You can't enable both PASSWORD and PAM. */
|
||||
|
||||
#define ENABLE_SVR_PASSWORD_AUTH
|
||||
//#define ENABLE_SVR_PASSWORD_AUTH
|
||||
/* PAM requires ./configure --enable-pam */
|
||||
/*#define ENABLE_SVR_PAM_AUTH*/
|
||||
#define ENABLE_SVR_PAM_AUTH
|
||||
#define ENABLE_SVR_PUBKEY_AUTH
|
||||
|
||||
/* Whether to take public key options in
|
||||
|
@ -170,6 +170,7 @@ struct sshsession {
|
||||
struct packetlist *reply_queue_head, *reply_queue_tail;
|
||||
|
||||
algo_type*(*buf_match_algo)(buffer*buf, algo_type localalgos[],
|
||||
enum kexguess2_used *kexguess2,
|
||||
int *goodguess); /* The function to use to choose which algorithm
|
||||
to use from the ones presented by the remote
|
||||
side. Is specific to the client/server mode,
|
||||
|
32
svr-algo.c
32
svr-algo.c
@ -33,7 +33,7 @@
|
||||
* 0 otherwise. This is used for checking if the kexalgo/hostkeyalgos are
|
||||
* guessed correctly */
|
||||
algo_type * svr_buf_match_algo(buffer* buf, algo_type localalgos[],
|
||||
int *goodguess)
|
||||
enum kexguess2_used *kexguess2, int *goodguess)
|
||||
{
|
||||
|
||||
unsigned char * algolist = NULL;
|
||||
@ -42,7 +42,9 @@ algo_type * svr_buf_match_algo(buffer* buf, algo_type localalgos[],
|
||||
unsigned int count, i, j;
|
||||
algo_type * ret = NULL;
|
||||
|
||||
*goodguess = 0;
|
||||
if (goodguess) {
|
||||
*goodguess = 0;
|
||||
}
|
||||
|
||||
/* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */
|
||||
algolist = buf_getstring(buf, &len);
|
||||
@ -73,6 +75,19 @@ algo_type * svr_buf_match_algo(buffer* buf, algo_type localalgos[],
|
||||
}
|
||||
}
|
||||
|
||||
if (kexguess2 && *kexguess2 == KEXGUESS2_LOOK) {
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (strcmp(remotealgos[i], KEXGUESS2_ALGO_NAME) == 0) {
|
||||
*kexguess2 = KEXGUESS2_YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*kexguess2 == KEXGUESS2_LOOK) {
|
||||
*kexguess2 = KEXGUESS2_NO;
|
||||
}
|
||||
}
|
||||
|
||||
/* iterate and find the first match */
|
||||
for (i = 0; i < count; i++) {
|
||||
|
||||
@ -83,8 +98,17 @@ algo_type * svr_buf_match_algo(buffer* buf, algo_type localalgos[],
|
||||
if (len == strlen(localalgos[j].name) &&
|
||||
strncmp(localalgos[j].name, remotealgos[i], len) == 0) {
|
||||
/* set if it was a good guess */
|
||||
if (i == 0 && j == 0) {
|
||||
*goodguess = 1;
|
||||
if (goodguess && kexguess2) {
|
||||
if (*kexguess2 == KEXGUESS2_YES) {
|
||||
if (i == 0) {
|
||||
*goodguess = 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (i == 0 && j == 0) {
|
||||
*goodguess = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* set the algo to return */
|
||||
ret = &localalgos[j];
|
||||
|
Loading…
Reference in New Issue
Block a user