changeset 684:c37857676924 insecure-nocrypto

Merge in "-m"/"-c" code
author Matt Johnston <matt@ucc.asn.au>
date Thu, 17 May 2012 08:09:19 +0800
parents a4b7627b3157 (current diff) 63f8d6c469cf (diff)
children 5af8993f7529
files common-algo.c common-kex.c options.h
diffstat 7 files changed, 163 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/algo.h	Wed May 16 22:54:51 2012 +0800
+++ b/algo.h	Thu May 17 08:09:19 2012 +0800
@@ -88,4 +88,11 @@
 algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[],
 		int *goodguess);
 
+#ifdef ENABLE_USER_ALGO_LIST
+int check_user_algos(const char* user_algo_list, algo_type * algos, 
+		const char *algo_desc);
+char * algolist_string(algo_type algos[]);
+#endif
+
+
 #endif /* _ALGO_H_ */
--- a/cli-runopts.c	Wed May 16 22:54:51 2012 +0800
+++ b/cli-runopts.c	Thu May 17 08:09:19 2012 +0800
@@ -86,6 +86,10 @@
 #ifdef ENABLE_CLI_PROXYCMD
 					"-J <proxy_program> Use program pipe rather than TCP connection\n"
 #endif
+#ifdef ENABLE_USER_ALGO_LIST
+					"-c <cipher list> Specify preferred ciphers ('-c help' to list options)\n"
+					"-m <MAC list> Specify preferred MACs for packet verification (or '-m help')\n"
+#endif
 #ifdef DEBUG_TRACE
 					"-v    verbose (compiled with DEBUG_TRACE)\n"
 #endif
@@ -149,6 +153,10 @@
 #ifndef DISABLE_ZLIB
 	opts.enable_compress = 1;
 #endif
+#ifdef ENABLE_USER_ALGO_LIST
+	opts.cipher_list = NULL;
+	opts.mac_list = NULL;
+#endif
 	/* not yet
 	opts.ipv4 = 1;
 	opts.ipv6 = 1;
@@ -283,6 +291,14 @@
 					cli_opts.agent_fwd = 1;
 					break;
 #endif
+#ifdef ENABLE_USER_ALGO_LIST
+				case 'c':
+					next = &opts.cipher_list;
+					break;
+				case 'm':
+					next = &opts.mac_list;
+					break;
+#endif
 #ifdef DEBUG_TRACE
 				case 'v':
 					debug_trace = 1;
@@ -290,8 +306,10 @@
 #endif
 				case 'F':
 				case 'e':
+#ifndef ENABLE_USER_ALGO_LIST
 				case 'c':
 				case 'm':
+#endif
 				case 'D':
 #ifndef ENABLE_CLI_REMOTETCPFWD
 				case 'R':
@@ -351,6 +369,10 @@
 
 	/* And now a few sanity checks and setup */
 
+#ifdef ENABLE_USER_ALGO_LIST
+	parse_ciphers_macs();
+#endif
+
 	if (host_arg == NULL) {
 		printhelp();
 		exit(EXIT_FAILURE);
--- a/common-algo.c	Wed May 16 22:54:51 2012 +0800
+++ b/common-algo.c	Thu May 17 08:09:19 2012 +0800
@@ -280,8 +280,6 @@
 	return DROPBEAR_FAILURE;
 }
 
-
-
 /* Output a comma separated list of algorithms to a buffer */
 void buf_put_algolist(buffer * buf, algo_type localalgos[]) {
 
@@ -302,3 +300,83 @@
 	buf_putstring(buf, algolist->data, algolist->len);
 	buf_free(algolist);
 }
+
+#ifdef ENABLE_USER_ALGO_LIST
+
+char *
+algolist_string(algo_type algos[])
+{
+	char *ret_list;
+	buffer *b = buf_new(200);
+	buf_put_algolist(b, algos);
+	buf_setpos(b, b->len);
+	buf_putbyte(b, '\0');
+	buf_setpos(b, 4);
+	ret_list = m_strdup(buf_getptr(b, b->len - b->pos));
+	buf_free(b);
+	return ret_list;
+}
+
+static algo_type*
+check_algo(const char* algo_name, algo_type *algos)
+{
+	algo_type *a;
+	for (a = algos; a->name != NULL; a++)
+	{
+		if (strcmp(a->name, algo_name) == 0)
+		{
+			return a;
+		}
+	}
+
+	return NULL;
+}
+
+static void
+try_add_algo(const char *algo_name, algo_type *algos, 
+		const char *algo_desc, algo_type * new_algos, int *num_ret)
+{
+	algo_type *match_algo = check_algo(algo_name, algos);
+	if (!match_algo)
+	{
+		dropbear_log(LOG_WARNING, "This Dropbear program does not support '%s' %s algorithm", algo_name, algo_desc);
+		return;
+	}
+
+	new_algos[*num_ret] = *match_algo;
+	(*num_ret)++;
+}
+
+/* Checks a user provided comma-separated algorithm list for available
+ * options. Any that are not acceptable are removed in-place. Returns the
+ * number of valid algorithms. */
+int
+check_user_algos(const char* user_algo_list, algo_type * algos, 
+		const char *algo_desc)
+{
+	algo_type new_algos[MAX_PROPOSED_ALGO];
+	/* this has two passes. first we sweep through the given list of
+	 * algorithms and mark them as usable=2 in the algo_type[] array... */
+	int num_ret = 0;
+	char *work_list = m_strdup(user_algo_list);
+	char *last_name = work_list;
+	char *c;
+	for (c = work_list; *c; c++)
+	{
+		if (*c == ',')
+		{
+			*c = '\0';
+			try_add_algo(last_name, algos, algo_desc, new_algos, &num_ret);
+			last_name = c++;
+		}
+	}
+	try_add_algo(last_name, algos, algo_desc, new_algos, &num_ret);
+	m_free(work_list);
+
+	new_algos[num_ret].name = NULL;
+
+	/* Copy one more as a blank delimiter */
+	memcpy(algos, new_algos, sizeof(*new_algos) * (num_ret+1));
+	return num_ret;
+}
+#endif // ENABLE_USER_ALGO_LIST
--- a/common-kex.c	Wed May 16 22:54:51 2012 +0800
+++ b/common-kex.c	Thu May 17 08:09:19 2012 +0800
@@ -118,6 +118,7 @@
 	/* mac_algorithms_server_to_client */
 	buf_put_algolist(ses.writepayload, sshhashes);
 
+
 	/* compression_algorithms_client_to_server */
 	buf_put_algolist(ses.writepayload, ses.compress_algos);
 
--- a/common-runopts.c	Wed May 16 22:54:51 2012 +0800
+++ b/common-runopts.c	Thu May 17 08:09:19 2012 +0800
@@ -28,6 +28,7 @@
 #include "buffer.h"
 #include "dbutil.h"
 #include "auth.h"
+#include "algo.h"
 
 runopts opts; /* GLOBAL */
 
@@ -55,3 +56,42 @@
 	buf_free(buf);
 	return ret;
 }
+
+#ifdef ENABLE_USER_ALGO_LIST
+void
+parse_ciphers_macs()
+{
+	if (opts.cipher_list)
+	{
+		if (strcmp(opts.cipher_list, "help") == 0)
+		{
+			char *ciphers = algolist_string(sshciphers);
+			dropbear_log(LOG_INFO, "Available ciphers:\n%s\n", ciphers);
+			m_free(ciphers);
+			dropbear_exit(".");
+		}
+
+		if (check_user_algos(opts.cipher_list, sshciphers, "cipher") == 0)
+		{
+			dropbear_exit("No valid ciphers specified for '-c'");
+		}
+	}
+
+	if (opts.mac_list)
+	{
+		if (strcmp(opts.mac_list, "help") == 0)
+		{
+			char *macs = algolist_string(sshhashes);
+			dropbear_log(LOG_INFO, "Available MACs:\n%s\n", macs);
+			m_free(macs);
+			dropbear_exit(".");
+		}
+
+		if (check_user_algos(opts.mac_list, sshhashes, "MAC") == 0)
+		{
+			dropbear_exit("No valid MACs specified for '-m'");
+		}
+	}
+}
+#endif
+
--- a/options.h	Wed May 16 22:54:51 2012 +0800
+++ b/options.h	Thu May 17 08:09:19 2012 +0800
@@ -80,6 +80,9 @@
  * to a remote TCP-forwarded connection */
 #define ENABLE_CLI_NETCAT
 
+/* Whether to support "-c" and "-m" flags to choose ciphers/MACs at runtime */
+#define ENABLE_USER_ALGO_LIST
+
 /* Encryption - at least one required.
  * Protocol RFC requires 3DES and recommends AES128 for interoperability.
  * Including multiple keysize variants the same cipher 
@@ -107,7 +110,7 @@
  * The best way to do things is probably make normal compile of dropbear with
  * all ciphers including "none" as the server, then recompile a special
  * "dbclient-insecure" client. */
-/* #define DROPBEAR_NONE_CIPHER */
+#define DROPBEAR_NONE_CIPHER
 
 /* Message Integrity - at least one required.
  * Protocol RFC requires sha1 and recommends sha1-96.
@@ -132,7 +135,7 @@
  * simple to run arbitrary commands on the remote host. Beware.
  * Note again, for the client you will have to disable other hashes above
  * to use this. */
-/* #define DROPBEAR_NONE_INTEGRITY */
+#define DROPBEAR_NONE_INTEGRITY
 
 /* Hostkey/public key algorithms - at least one required, these are used
  * for hostkey as well as for verifying signatures with pubkey auth.
--- a/runopts.h	Wed May 16 22:54:51 2012 +0800
+++ b/runopts.h	Thu May 17 08:09:19 2012 +0800
@@ -47,6 +47,10 @@
 	int enable_compress;
 #endif
 
+#ifdef ENABLE_USER_ALGO_LIST
+	char *cipher_list;
+	char *mac_list;
+#endif
 
 } runopts;
 
@@ -148,4 +152,8 @@
 extern cli_runopts cli_opts;
 void cli_getopts(int argc, char ** argv);
 
+#ifdef ENABLE_USER_ALGO_LIST
+void parse_ciphers_macs();
+#endif
+
 #endif /* _RUNOPTS_H_ */