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