Merge in "-m"/"-c" code

--HG--
branch : insecure-nocrypto
This commit is contained in:
Matt Johnston 2012-05-17 08:09:19 +08:00
commit f2cd610750
7 changed files with 163 additions and 4 deletions

7
algo.h
View File

@ -88,4 +88,11 @@ algo_type * svr_buf_match_algo(buffer* buf, algo_type localalgos[],
algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[], algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[],
int *goodguess); 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_ */ #endif /* _ALGO_H_ */

View File

@ -86,6 +86,10 @@ static void printhelp() {
#ifdef ENABLE_CLI_PROXYCMD #ifdef ENABLE_CLI_PROXYCMD
"-J <proxy_program> Use program pipe rather than TCP connection\n" "-J <proxy_program> Use program pipe rather than TCP connection\n"
#endif #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 #ifdef DEBUG_TRACE
"-v verbose (compiled with DEBUG_TRACE)\n" "-v verbose (compiled with DEBUG_TRACE)\n"
#endif #endif
@ -148,6 +152,10 @@ void cli_getopts(int argc, char ** argv) {
#endif #endif
#ifndef DISABLE_ZLIB #ifndef DISABLE_ZLIB
opts.enable_compress = 1; opts.enable_compress = 1;
#endif
#ifdef ENABLE_USER_ALGO_LIST
opts.cipher_list = NULL;
opts.mac_list = NULL;
#endif #endif
/* not yet /* not yet
opts.ipv4 = 1; opts.ipv4 = 1;
@ -283,6 +291,14 @@ void cli_getopts(int argc, char ** argv) {
cli_opts.agent_fwd = 1; cli_opts.agent_fwd = 1;
break; break;
#endif #endif
#ifdef ENABLE_USER_ALGO_LIST
case 'c':
next = &opts.cipher_list;
break;
case 'm':
next = &opts.mac_list;
break;
#endif
#ifdef DEBUG_TRACE #ifdef DEBUG_TRACE
case 'v': case 'v':
debug_trace = 1; debug_trace = 1;
@ -290,8 +306,10 @@ void cli_getopts(int argc, char ** argv) {
#endif #endif
case 'F': case 'F':
case 'e': case 'e':
#ifndef ENABLE_USER_ALGO_LIST
case 'c': case 'c':
case 'm': case 'm':
#endif
case 'D': case 'D':
#ifndef ENABLE_CLI_REMOTETCPFWD #ifndef ENABLE_CLI_REMOTETCPFWD
case 'R': case 'R':
@ -351,6 +369,10 @@ void cli_getopts(int argc, char ** argv) {
/* And now a few sanity checks and setup */ /* And now a few sanity checks and setup */
#ifdef ENABLE_USER_ALGO_LIST
parse_ciphers_macs();
#endif
if (host_arg == NULL) { if (host_arg == NULL) {
printhelp(); printhelp();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@ -280,8 +280,6 @@ int have_algo(char* algo, size_t algolen, algo_type algos[]) {
return DROPBEAR_FAILURE; return DROPBEAR_FAILURE;
} }
/* Output a comma separated list of algorithms to a buffer */ /* Output a comma separated list of algorithms to a buffer */
void buf_put_algolist(buffer * buf, algo_type localalgos[]) { void buf_put_algolist(buffer * buf, algo_type localalgos[]) {
@ -302,3 +300,83 @@ void buf_put_algolist(buffer * buf, algo_type localalgos[]) {
buf_putstring(buf, algolist->data, algolist->len); buf_putstring(buf, algolist->data, algolist->len);
buf_free(algolist); 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

View File

@ -118,6 +118,7 @@ void send_msg_kexinit() {
/* mac_algorithms_server_to_client */ /* mac_algorithms_server_to_client */
buf_put_algolist(ses.writepayload, sshhashes); buf_put_algolist(ses.writepayload, sshhashes);
/* compression_algorithms_client_to_server */ /* compression_algorithms_client_to_server */
buf_put_algolist(ses.writepayload, ses.compress_algos); buf_put_algolist(ses.writepayload, ses.compress_algos);

View File

@ -28,6 +28,7 @@
#include "buffer.h" #include "buffer.h"
#include "dbutil.h" #include "dbutil.h"
#include "auth.h" #include "auth.h"
#include "algo.h"
runopts opts; /* GLOBAL */ runopts opts; /* GLOBAL */
@ -55,3 +56,42 @@ out:
buf_free(buf); buf_free(buf);
return ret; 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

View File

@ -80,6 +80,9 @@ much traffic. */
* to a remote TCP-forwarded connection */ * to a remote TCP-forwarded connection */
#define ENABLE_CLI_NETCAT #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. /* Encryption - at least one required.
* Protocol RFC requires 3DES and recommends AES128 for interoperability. * Protocol RFC requires 3DES and recommends AES128 for interoperability.
* Including multiple keysize variants the same cipher * Including multiple keysize variants the same cipher
@ -107,7 +110,7 @@ much traffic. */
* The best way to do things is probably make normal compile of dropbear with * 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 * all ciphers including "none" as the server, then recompile a special
* "dbclient-insecure" client. */ * "dbclient-insecure" client. */
/* #define DROPBEAR_NONE_CIPHER */ #define DROPBEAR_NONE_CIPHER
/* Message Integrity - at least one required. /* Message Integrity - at least one required.
* Protocol RFC requires sha1 and recommends sha1-96. * Protocol RFC requires sha1 and recommends sha1-96.
@ -132,7 +135,7 @@ much traffic. */
* simple to run arbitrary commands on the remote host. Beware. * simple to run arbitrary commands on the remote host. Beware.
* Note again, for the client you will have to disable other hashes above * Note again, for the client you will have to disable other hashes above
* to use this. */ * to use this. */
/* #define DROPBEAR_NONE_INTEGRITY */ #define DROPBEAR_NONE_INTEGRITY
/* Hostkey/public key algorithms - at least one required, these are used /* Hostkey/public key algorithms - at least one required, these are used
* for hostkey as well as for verifying signatures with pubkey auth. * for hostkey as well as for verifying signatures with pubkey auth.

View File

@ -47,6 +47,10 @@ typedef struct runopts {
int enable_compress; int enable_compress;
#endif #endif
#ifdef ENABLE_USER_ALGO_LIST
char *cipher_list;
char *mac_list;
#endif
} runopts; } runopts;
@ -148,4 +152,8 @@ typedef struct cli_runopts {
extern cli_runopts cli_opts; extern cli_runopts cli_opts;
void cli_getopts(int argc, char ** argv); void cli_getopts(int argc, char ** argv);
#ifdef ENABLE_USER_ALGO_LIST
void parse_ciphers_macs();
#endif
#endif /* _RUNOPTS_H_ */ #endif /* _RUNOPTS_H_ */