From 99d9cf500b30c77107bf8477dd55831626f9beaf Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Fri, 29 Mar 2013 23:29:48 +0800 Subject: Add kexguess2 behaviour --HG-- branch : kexguess --- common-algo.c | 1 + 1 file changed, 1 insertion(+) (limited to 'common-algo.c') diff --git a/common-algo.c b/common-algo.c index 4a14651..46dbe74 100644 --- a/common-algo.c +++ b/common-algo.c @@ -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} }; -- cgit v1.2.3 From 9c7485331a581d1ff32f9caf005e7b13fa1c051e Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Sat, 30 Mar 2013 23:55:05 +0800 Subject: Get rid of client/server specific buf_match_algo, use single function with a couple of if statements instead --HG-- branch : kexguess --- Makefile.in | 4 +- algo.h | 4 +- cli-algo.c | 121 -------------------------------------------------------- cli-session.c | 1 - common-algo.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ common-kex.c | 16 ++++---- session.h | 7 ---- svr-algo.c | 124 ---------------------------------------------------------- svr-session.c | 1 - 9 files changed, 128 insertions(+), 267 deletions(-) delete mode 100644 cli-algo.c delete mode 100644 svr-algo.c (limited to 'common-algo.c') diff --git a/Makefile.in b/Makefile.in index cec35f1..108566c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -28,12 +28,12 @@ COMMONOBJS=dbutil.o buffer.o \ queue.o \ atomicio.o compat.o fake-rfc2553.o -SVROBJS=svr-kex.o svr-algo.o svr-auth.o sshpty.o \ +SVROBJS=svr-kex.o svr-auth.o sshpty.o \ svr-authpasswd.o svr-authpubkey.o svr-authpubkeyoptions.o svr-session.o svr-service.o \ svr-chansession.o svr-runopts.o svr-agentfwd.o svr-main.o svr-x11fwd.o\ svr-tcpfwd.o svr-authpam.o -CLIOBJS=cli-algo.o cli-main.o cli-auth.o cli-authpasswd.o cli-kex.o \ +CLIOBJS=cli-main.o cli-auth.o cli-authpasswd.o cli-kex.o \ cli-session.o cli-service.o cli-runopts.o cli-chansession.o \ cli-authpubkey.o cli-tcpfwd.o cli-channel.o cli-authinteract.o \ cli-agentfwd.o list.o diff --git a/algo.h b/algo.h index 755cfcd..ad40c0d 100644 --- a/algo.h +++ b/algo.h @@ -93,9 +93,7 @@ enum kexguess2_used { #define KEXGUESS2_ALGO_ID 99 -algo_type * svr_buf_match_algo(buffer* buf, algo_type localalgos[], - enum kexguess2_used *kexguess2, int *goodguess); -algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[], +algo_type * buf_match_algo(buffer* buf, algo_type localalgos[], enum kexguess2_used *kexguess2, int *goodguess); #ifdef ENABLE_USER_ALGO_LIST diff --git a/cli-algo.c b/cli-algo.c deleted file mode 100644 index ec8c541..0000000 --- a/cli-algo.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Dropbear - a SSH2 server - * SSH client implementation - * - * Copyright (c) 2002,2003 Matt Johnston - * Copyright (c) 2004 by Mihnea Stoenescu - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. */ - -#include "algo.h" -#include "dbutil.h" - - -/* - * The chosen [encryption | MAC | compression] algorithm to each - * direction MUST be the first algorithm on the client's list - * that is also on the server's list. - */ -algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[], - enum kexguess2_used *kexguess2, int *goodguess) { - - unsigned char * algolist = NULL; - unsigned char * remotealgos[MAX_PROPOSED_ALGO]; - unsigned int len; - unsigned int count, i, j; - algo_type * ret = NULL; - - if (goodguess) { - *goodguess = 0; - } - - /* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */ - algolist = buf_getstring(buf, &len); - TRACE(("cli_buf_match_algo: %s", algolist)) - if (len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) { - goto out; /* just a sanity check, no other use */ - } - - /* remotealgos will contain a list of the strings parsed out */ - /* We will have at least one string (even if it's just "") */ - remotealgos[0] = algolist; - count = 1; - /* Iterate through, replacing ','s with NULs, to split it into - * words. */ - for (i = 0; i < len; i++) { - if (algolist[i] == '\0') { - /* someone is trying something strange */ - goto out; - } - if (algolist[i] == ',') { - algolist[i] = '\0'; - remotealgos[count] = &algolist[i+1]; - count++; - } - if (count >= MAX_PROPOSED_ALGO) { - break; - } - } - - 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++) { - if (localalgos[j].usable) { - len = strlen(localalgos[j].name); - for (i = 0; i < count; i++) { - if (len == strlen(remotealgos[i]) - && strncmp(localalgos[j].name, - remotealgos[i], len) == 0) { - 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; - } - } - } - } - -out: - m_free(algolist); - return ret; -} - diff --git a/cli-session.c b/cli-session.c index cc514bb..590bfcc 100644 --- a/cli-session.c +++ b/cli-session.c @@ -148,7 +148,6 @@ static void cli_session_init() { /* For printing "remote host closed" for the user */ ses.remoteclosed = cli_remoteclosed; - ses.buf_match_algo = cli_buf_match_algo; /* packet handlers */ ses.packettypes = cli_packettypes; diff --git a/common-algo.c b/common-algo.c index 46dbe74..8267852 100644 --- a/common-algo.c +++ b/common-algo.c @@ -24,6 +24,7 @@ * SOFTWARE. */ #include "algo.h" +#include "session.h" #include "dbutil.h" /* This file (algo.c) organises the ciphers which can be used, and is used to @@ -308,6 +309,122 @@ void buf_put_algolist(buffer * buf, algo_type localalgos[]) { buf_free(algolist); } +/* match the first algorithm in the comma-separated list in buf which is + * also in localalgos[], or return NULL on failure. + * (*goodguess) is set to 1 if the preferred client/server algos match, + * 0 otherwise. This is used for checking if the kexalgo/hostkeyalgos are + * guessed correctly */ +algo_type * buf_match_algo(buffer* buf, algo_type localalgos[], + enum kexguess2_used *kexguess2, int *goodguess) +{ + + unsigned char * algolist = NULL; + const unsigned char *remotenames[MAX_PROPOSED_ALGO], *localnames[MAX_PROPOSED_ALGO]; + unsigned int len; + unsigned int remotecount, localcount, clicount, servcount, i, j; + algo_type * ret = NULL; + const unsigned char **clinames, **servnames; + + if (goodguess) { + *goodguess = 0; + } + + /* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */ + algolist = buf_getstring(buf, &len); + TRACE(("buf_match_algo: %s", algolist)) + if (len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) { + goto out; + } + + /* remotenames will contain a list of the strings parsed out */ + /* We will have at least one string (even if it's just "") */ + remotenames[0] = algolist; + remotecount = 1; + for (i = 0; i < len; i++) { + if (algolist[i] == '\0') { + /* someone is trying something strange */ + goto out; + } + if (algolist[i] == ',') { + algolist[i] = '\0'; + remotenames[remotecount] = &algolist[i+1]; + remotecount++; + } + if (remotecount >= MAX_PROPOSED_ALGO) { + break; + } + } + if (kexguess2 && *kexguess2 == KEXGUESS2_LOOK) { + for (i = 0; i < remotecount; i++) + { + if (strcmp(remotenames[i], KEXGUESS2_ALGO_NAME) == 0) { + *kexguess2 = KEXGUESS2_YES; + break; + } + } + if (*kexguess2 == KEXGUESS2_LOOK) { + *kexguess2 = KEXGUESS2_NO; + } + } + + for (i = 0; localalgos[i].name != NULL; i++) { + if (localalgos[i].usable) { + localnames[i] = localalgos[i].name; + } else { + localnames[i] = NULL; + } + } + localcount = i; + + if (IS_DROPBEAR_SERVER) { + clinames = remotenames; + clicount = remotecount; + servnames = localnames; + servcount = localcount; + } else { + clinames = localnames; + clicount = localcount; + servnames = remotenames; + servcount = remotecount; + } + + /* iterate and find the first match */ + for (i = 0; i < clicount; i++) { + for (j = 0; j < servcount; j++) { + if (!(servnames[j] && clinames[i])) { + // unusable algos are NULL + continue; + } + if (strcmp(servnames[j], clinames[i]) == 0) { + /* 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) { + *goodguess = 1; + } + } + } + /* set the algo to return */ + if (IS_DROPBEAR_SERVER) { + ret = &localalgos[j]; + } else { + ret = &localalgos[i]; + } + goto out; + } + } + } + +out: + m_free(algolist); + return ret; +} + #ifdef DROPBEAR_NONE_CIPHER void diff --git a/common-kex.c b/common-kex.c index 0640b9f..eb1fd7b 100644 --- a/common-kex.c +++ b/common-kex.c @@ -695,7 +695,7 @@ static void read_kex_algos() { enum kexguess2_used kexguess2 = KEXGUESS2_LOOK; /* kex_algorithms */ - algo = ses.buf_match_algo(ses.payload, sshkex, &kexguess2, &goodguess); + algo = buf_match_algo(ses.payload, sshkex, &kexguess2, &goodguess); allgood &= goodguess; if (algo == NULL || algo->val == KEXGUESS2_ALGO_ID) { erralgo = "kex"; @@ -706,7 +706,7 @@ static void read_kex_algos() { ses.newkeys->algo_kex = algo->val; /* server_host_key_algorithms */ - algo = ses.buf_match_algo(ses.payload, sshhostkey, &kexguess2, &goodguess); + algo = buf_match_algo(ses.payload, sshhostkey, &kexguess2, &goodguess); allgood &= goodguess; if (algo == NULL) { erralgo = "hostkey"; @@ -716,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, NULL, NULL); + c2s_cipher_algo = buf_match_algo(ses.payload, sshciphers, NULL, NULL); if (c2s_cipher_algo == NULL) { erralgo = "enc c->s"; goto error; @@ -724,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, NULL, NULL); + s2c_cipher_algo = buf_match_algo(ses.payload, sshciphers, NULL, NULL); if (s2c_cipher_algo == NULL) { erralgo = "enc s->c"; goto error; @@ -732,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, NULL, NULL); + c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL); if (c2s_hash_algo == NULL) { erralgo = "mac c->s"; goto error; @@ -740,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, NULL, NULL); + s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL); if (s2c_hash_algo == NULL) { erralgo = "mac s->c"; goto error; @@ -748,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, NULL, NULL); + c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL); if (c2s_comp_algo == NULL) { erralgo = "comp c->s"; goto error; @@ -756,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, NULL, NULL); + s2c_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL); if (s2c_comp_algo == NULL) { erralgo = "comp s->c"; goto error; diff --git a/session.h b/session.h index 3b9e957..8e71bdc 100644 --- a/session.h +++ b/session.h @@ -169,13 +169,6 @@ struct sshsession { concluded (ie, while dataallowed was unset)*/ 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, - hence the function-pointer callback.*/ - void(*remoteclosed)(); /* A callback to handle closure of the remote connection */ diff --git a/svr-algo.c b/svr-algo.c deleted file mode 100644 index 620cfeb..0000000 --- a/svr-algo.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Dropbear - a SSH2 server - * SSH client implementation - * - * Copyright (c) 2002,2003 Matt Johnston - * Copyright (c) 2004 by Mihnea Stoenescu - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. */ - -#include "algo.h" -#include "dbutil.h" - -/* match the first algorithm in the comma-separated list in buf which is - * also in localalgos[], or return NULL on failure. - * (*goodguess) is set to 1 if the preferred client/server algos match, - * 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[], - enum kexguess2_used *kexguess2, int *goodguess) -{ - - unsigned char * algolist = NULL; - unsigned char * remotealgos[MAX_PROPOSED_ALGO]; - unsigned int len; - unsigned int count, i, j; - algo_type * ret = NULL; - - if (goodguess) { - *goodguess = 0; - } - - /* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */ - algolist = buf_getstring(buf, &len); - /* Debug this */ - TRACE(("buf_match_algo: %s", algolist)) - if (len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) { - goto out; /* just a sanity check, no other use */ - } - - /* remotealgos will contain a list of the strings parsed out */ - /* We will have at least one string (even if it's just "") */ - remotealgos[0] = algolist; - count = 1; - /* Iterate through, replacing ','s with NULs, to split it into - * words. */ - for (i = 0; i < len; i++) { - if (algolist[i] == '\0') { - /* someone is trying something strange */ - goto out; - } - if (algolist[i] == ',') { - algolist[i] = '\0'; - remotealgos[count] = &algolist[i+1]; - count++; - } - if (count >= MAX_PROPOSED_ALGO) { - break; - } - } - - 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++) { - - len = strlen(remotealgos[i]); - - for (j = 0; localalgos[j].name != NULL; j++) { - if (localalgos[j].usable) { - if (len == strlen(localalgos[j].name) && - strncmp(localalgos[j].name, remotealgos[i], len) == 0) { - /* 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) { - *goodguess = 1; - } - } - } - /* set the algo to return */ - ret = &localalgos[j]; - goto out; - } - } - } - } - -out: - m_free(algolist); - return ret; -} diff --git a/svr-session.c b/svr-session.c index cf82289..a564525 100644 --- a/svr-session.c +++ b/svr-session.c @@ -106,7 +106,6 @@ void svr_session(int sock, int childpipe) { /* packet handlers */ ses.packettypes = svr_packettypes; - ses.buf_match_algo = svr_buf_match_algo; ses.isserver = 1; -- cgit v1.2.3 From 78fbed8c3eda1d7f3e0ffa41b54cd3c6ae31a0fe Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Wed, 3 Apr 2013 00:32:55 +0800 Subject: Don't usually need to recalculate dh_e for the repeated kexdh_init packet --HG-- branch : kexguess --- cli-kex.c | 17 +++++++++++++---- cli-session.c | 10 +++++++--- common-algo.c | 2 +- session.h | 1 + sysoptions.h | 5 +++-- 5 files changed, 25 insertions(+), 10 deletions(-) (limited to 'common-algo.c') diff --git a/cli-kex.c b/cli-kex.c index 833529a..1158aa6 100644 --- a/cli-kex.c +++ b/cli-kex.c @@ -43,11 +43,19 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen); void send_msg_kexdh_init() { TRACE(("send_msg_kexdh_init()")) - cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int)); - cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int)); - m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL); + if ((cli_ses.dh_e && cli_ses.dh_x + && cli_ses.dh_val_algo == ses.newkeys->algo_kex)) { + TRACE(("reusing existing dh_e from first_kex_packet_follows")) + } else { + if (!cli_ses.dh_e || !cli_ses.dh_e) { + cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int)); + cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int)); + m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL); + } - gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x); + gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x); + cli_ses.dh_val_algo = ses.newkeys->algo_kex; + } CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT); @@ -99,6 +107,7 @@ void recv_msg_kexdh_reply() { mp_clear_multi(cli_ses.dh_e, cli_ses.dh_x, NULL); m_free(cli_ses.dh_e); m_free(cli_ses.dh_x); + cli_ses.dh_val_algo = DROPBEAR_KEX_NONE; if (buf_verify(ses.payload, hostkey, ses.hash, SHA1_HASH_SIZE) != DROPBEAR_SUCCESS) { diff --git a/cli-session.c b/cli-session.c index 600827f..9e64281 100644 --- a/cli-session.c +++ b/cli-session.c @@ -182,6 +182,11 @@ static void cli_sessionloop() { TRACE2(("enter cli_sessionloop")) + if (ses.lastpacket == 0) { + TRACE2(("exit cli_sessionloop: no real packets yet")) + return; + } + if (ses.lastpacket == SSH_MSG_KEXINIT && cli_ses.kex_state == KEX_NOTHING) { /* We initiate the KEXDH. If DH wasn't the correct type, the KEXINIT * negotiation would have failed. */ @@ -206,10 +211,9 @@ static void cli_sessionloop() { return; } - /* We should exit if we haven't donefirstkex: we shouldn't reach here - * in normal operation */ if (ses.kexstate.donefirstkex == 0) { - TRACE(("XXX XXX might be bad! leave cli_sessionloop: haven't donefirstkex")) + /* We might reach here if we have partial packet reads or have + * received SSG_MSG_IGNORE etc. Just skip it */ return; } diff --git a/common-algo.c b/common-algo.c index 8267852..b698611 100644 --- a/common-algo.c +++ b/common-algo.c @@ -214,8 +214,8 @@ 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}, + {"diffie-hellman-group1-sha1", DROPBEAR_KEX_DH_GROUP1, NULL, 1, NULL}, {KEXGUESS2_ALGO_NAME, KEXGUESS2_ALGO_ID, NULL, 1, NULL}, {NULL, 0, NULL, 0, NULL} }; diff --git a/session.h b/session.h index 33c1539..9bbeac4 100644 --- a/session.h +++ b/session.h @@ -241,6 +241,7 @@ typedef enum { struct clientsession { mp_int *dh_e, *dh_x; /* Used during KEX */ + int dh_val_algo; /* KEX algorithm corresponding to current dh_e and dh_x */ 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 */ diff --git a/sysoptions.h b/sysoptions.h index 6e60294..4d648c1 100644 --- a/sysoptions.h +++ b/sysoptions.h @@ -61,8 +61,9 @@ #define DROPBEAR_FAILURE -1 /* various algorithm identifiers */ -#define DROPBEAR_KEX_DH_GROUP1 0 -#define DROPBEAR_KEX_DH_GROUP14 1 +#define DROPBEAR_KEX_NONE 0 +#define DROPBEAR_KEX_DH_GROUP1 1 +#define DROPBEAR_KEX_DH_GROUP14 2 #define DROPBEAR_SIGNKEY_ANY 0 #define DROPBEAR_SIGNKEY_RSA 1 -- cgit v1.2.3 From cbd3d5e3a535111b4cd6736d6aff432a252845d2 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Wed, 3 Apr 2013 00:43:31 +0800 Subject: Put some #ifdef options around first-follows options in case they need to be disabled --HG-- branch : kexguess --- cli-session.c | 5 ++++- common-algo.c | 2 ++ common-kex.c | 4 ++++ sysoptions.h | 9 +++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) (limited to 'common-algo.c') diff --git a/cli-session.c b/cli-session.c index 9e64281..32b7ac7 100644 --- a/cli-session.c +++ b/cli-session.c @@ -110,11 +110,12 @@ void cli_session(int sock_in, int sock_out) { } +#ifdef USE_KEX_FIRST_FOLLOWS static void cli_send_kex_first_guess() { send_msg_kexdh_init(); dropbear_log(LOG_INFO, "kexdh_init guess sent"); - //cli_ses.kex_state = KEXDH_INIT_SENT; } +#endif static void cli_session_init() { @@ -155,7 +156,9 @@ static void cli_session_init() { ses.isserver = 0; +#ifdef USE_KEX_FIRST_FOLLOWS ses.send_kex_first_guess = cli_send_kex_first_guess; +#endif } diff --git a/common-algo.c b/common-algo.c index b698611..c74463c 100644 --- a/common-algo.c +++ b/common-algo.c @@ -216,7 +216,9 @@ algo_type sshhostkey[] = { algo_type sshkex[] = { {"diffie-hellman-group14-sha1", DROPBEAR_KEX_DH_GROUP14, NULL, 1, NULL}, {"diffie-hellman-group1-sha1", DROPBEAR_KEX_DH_GROUP1, NULL, 1, NULL}, +#ifdef USE_KEXGUESS2 {KEXGUESS2_ALGO_NAME, KEXGUESS2_ALGO_ID, NULL, 1, NULL}, +#endif {NULL, 0, NULL, 0, NULL} }; diff --git a/common-kex.c b/common-kex.c index eb1fd7b..6c22600 100644 --- a/common-kex.c +++ b/common-kex.c @@ -692,7 +692,11 @@ static void read_kex_algos() { memset(ses.newkeys, 0x0, sizeof(*ses.newkeys)); +#ifdef USE_KEXGUESS2 enum kexguess2_used kexguess2 = KEXGUESS2_LOOK; +#else + enum kexguess2_used kexguess2 = KEXGUESS2_NO; +#endif /* kex_algorithms */ algo = buf_match_algo(ses.payload, sshkex, &kexguess2, &goodguess); diff --git a/sysoptions.h b/sysoptions.h index 4d648c1..22c2a4d 100644 --- a/sysoptions.h +++ b/sysoptions.h @@ -23,6 +23,15 @@ #define AUTH_TIMEOUT 300 /* we choose 5 minutes */ #endif +/* A client should try and send an initial key exchange packet guessing + * the algorithm that will match - saves a round trip connecting, has little + * overhead if the guess was "wrong". */ +#define USE_KEX_FIRST_FOLLOWS +/* Use protocol extension to allow "first follows" to succeed more frequently. + * This is currently Dropbear-specific but will gracefully fallback when connecting + * to other implementations. */ +#define USE_KEXGUESS2 + /* Minimum key sizes for DSS and RSA */ #ifndef MIN_DSS_KEYLEN #define MIN_DSS_KEYLEN 512 -- cgit v1.2.3