summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2013-03-30 23:55:05 +0800
committerMatt Johnston <matt@ucc.asn.au>2013-03-30 23:55:05 +0800
commit8705c2efa79f3f6364c289fe8bec70ad7ca6c279 (patch)
treeeccd0fb9963eacfc1797ca6c718bf7f09de66ef5
parent8abeeaa532be547d3dc08a86a6e475ccd25d832d (diff)
downloaddropbear-8705c2efa79f3f6364c289fe8bec70ad7ca6c279.tar.gz
Get rid of client/server specific buf_match_algo, use single
function with a couple of if statements instead
-rw-r--r--Makefile.in4
-rw-r--r--algo.h4
-rw-r--r--cli-algo.c121
-rw-r--r--cli-session.c1
-rw-r--r--common-algo.c117
-rw-r--r--common-kex.c16
-rw-r--r--session.h7
-rw-r--r--svr-algo.c124
-rw-r--r--svr-session.c1
9 files changed, 128 insertions, 267 deletions
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;