# HG changeset patch # User Matt Johnston # Date 1422452434 -28800 # Node ID e753169068525723da0114fed3acb5a633be6870 # Parent 8d0c33e8ddab763131064783636e1b1123810067# Parent 47643024fc9062b0e9ed22ab4252b53d339d0cdc merge diff -r 8d0c33e8ddab -r e75316906852 Makefile.in --- a/Makefile.in Sun Jan 04 22:33:12 2015 +0800 +++ b/Makefile.in Wed Jan 28 21:40:34 2015 +0800 @@ -131,7 +131,7 @@ -rm -f $(DESTDIR)$(sbindir)/dropbear$(EXEEXT) -ln -s $(bindir)/dropbearmulti$(EXEEXT) $(DESTDIR)$(sbindir)/dropbear$(EXEEXT) $(INSTALL) -d $(DESTDIR)$(mandir)/man8 - $(INSTALL) -m 644 dropbear.8 $(DESTDIR)$(mandir)/man8/dropbear.8 + $(INSTALL) -m 644 $(srcdir)/dropbear.8 $(DESTDIR)$(mandir)/man8/dropbear.8 insmulti%: dropbearmulti $(INSTALL) -d $(DESTDIR)$(bindir) @@ -145,7 +145,7 @@ $(INSTALL) -d $(DESTDIR)$(sbindir) $(INSTALL) dropbear$(EXEEXT) $(DESTDIR)$(sbindir) $(INSTALL) -d $(DESTDIR)$(mandir)/man8 - $(INSTALL) -m 644 dropbear.8 $(DESTDIR)$(mandir)/man8/dropbear.8 + $(INSTALL) -m 644 $(srcdir)/dropbear.8 $(DESTDIR)$(mandir)/man8/dropbear.8 inst_%: % $(INSTALL) -d $(DESTDIR)$(bindir) diff -r 8d0c33e8ddab -r e75316906852 algo.h --- a/algo.h Sun Jan 04 22:33:12 2015 +0800 +++ b/algo.h Wed Jan 28 21:40:34 2015 +0800 @@ -51,6 +51,7 @@ extern algo_type sshciphers[]; extern algo_type sshhashes[]; extern algo_type ssh_compress[]; +extern algo_type ssh_delaycompress[]; extern algo_type ssh_nocompress[]; extern const struct dropbear_cipher dropbear_nocipher; diff -r 8d0c33e8ddab -r e75316906852 cli-runopts.c --- a/cli-runopts.c Sun Jan 04 22:33:12 2015 +0800 +++ b/cli-runopts.c Wed Jan 28 21:40:34 2015 +0800 @@ -38,7 +38,7 @@ static void parse_multihop_hostname(const char* orighostarg, const char* argv0); static void fill_own_user(); #ifdef ENABLE_CLI_PUBKEY_AUTH -static void loadidentityfile(const char* filename); +static void loadidentityfile(const char* filename, int warnfail); #endif #ifdef ENABLE_CLI_ANYTCPFWD static void addforward(const char* str, m_list *fwdlist); @@ -65,7 +65,7 @@ "-y -y Don't perform any remote host key checking (caution)\n" "-s Request a subsystem (use by external sftp)\n" #ifdef ENABLE_CLI_PUBKEY_AUTH - "-i (multiple allowed)\n" + "-i (multiple allowed, default %s)\n" #endif #ifdef ENABLE_CLI_AGENTFWD "-A Enable agent auth forwarding\n" @@ -95,6 +95,9 @@ "-v verbose (compiled with DEBUG_TRACE)\n" #endif ,DROPBEAR_VERSION, cli_opts.progname, +#ifdef ENABLE_CLI_PUBKEY_AUTH + DROPBEAR_DEFAULT_CLI_AUTHKEY, +#endif DEFAULT_RECV_WINDOW, DEFAULT_KEEPALIVE, DEFAULT_IDLE_TIMEOUT); } @@ -153,7 +156,7 @@ cli_opts.proxycmd = NULL; #endif #ifndef DISABLE_ZLIB - opts.enable_compress = 1; + opts.compress_mode = DROPBEAR_COMPRESS_ON; #endif #ifdef ENABLE_USER_ALGO_LIST opts.cipher_list = NULL; @@ -174,7 +177,7 @@ #ifdef ENABLE_CLI_PUBKEY_AUTH if (nextiskey) { /* Load a hostkey since the previous argument was "-i" */ - loadidentityfile(argv[i]); + loadidentityfile(argv[i], 1); nextiskey = 0; continue; } @@ -231,7 +234,7 @@ case 'i': /* an identityfile */ /* Keep scp happy when it changes "-i file" to "-ifile" */ if (strlen(argv[i]) > 2) { - loadidentityfile(&argv[i][2]); + loadidentityfile(&argv[i][2], 1); } else { nextiskey = 1; } @@ -444,6 +447,14 @@ } #endif +#ifdef DROPBEAR_DEFAULT_CLI_AUTHKEY + { + char *expand_path = expand_tilde(DROPBEAR_DEFAULT_CLI_AUTHKEY); + loadidentityfile(expand_path, 0); + m_free(expand_path); + } +#endif + /* The hostname gets set up last, since * in multi-hop mode it will require knowledge * of other flags such as -i */ @@ -455,14 +466,18 @@ } #ifdef ENABLE_CLI_PUBKEY_AUTH -static void loadidentityfile(const char* filename) { +static void loadidentityfile(const char* filename, int warnfail) { sign_key *key; enum signkey_type keytype; + TRACE(("loadidentityfile %s", filename)) + key = new_sign_key(); keytype = DROPBEAR_SIGNKEY_ANY; if ( readhostkey(filename, key, &keytype) != DROPBEAR_SUCCESS ) { - fprintf(stderr, "Failed loading keyfile '%s'\n", filename); + if (warnfail) { + fprintf(stderr, "Failed loading keyfile '%s'\n", filename); + } sign_key_free(key); } else { key->type = keytype; @@ -594,7 +609,7 @@ passthrough_args, remainder); #ifndef DISABLE_ZLIB /* The stream will be incompressible since it's encrypted. */ - opts.enable_compress = 0; + opts.compress_mode = DROPBEAR_COMPRESS_OFF; #endif m_free(passthrough_args); } diff -r 8d0c33e8ddab -r e75316906852 common-algo.c --- a/common-algo.c Sun Jan 04 22:33:12 2015 +0800 +++ b/common-algo.c Wed Jan 28 21:40:34 2015 +0800 @@ -84,10 +84,14 @@ /* A few void* s are required to silence warnings * about the symmetric_CBC vs symmetric_CTR cipher_state pointer */ +#ifdef DROPBEAR_ENABLE_CBC_MODE const struct dropbear_cipher_mode dropbear_mode_cbc = {(void*)cbc_start, (void*)cbc_encrypt, (void*)cbc_decrypt}; +#endif // DROPBEAR_ENABLE_CBC_MODE + const struct dropbear_cipher_mode dropbear_mode_none = {void_start, void_cipher, void_cipher}; + #ifdef DROPBEAR_ENABLE_CTR_MODE /* a wrapper to make ctr_start and cbc_start look the same */ static int dropbear_big_endian_ctr_start(int cipher, @@ -98,7 +102,7 @@ } const struct dropbear_cipher_mode dropbear_mode_ctr = {(void*)dropbear_big_endian_ctr_start, (void*)ctr_encrypt, (void*)ctr_decrypt}; -#endif +#endif // DROPBEAR_ENABLE_CTR_MODE /* Mapping of ssh hashes to libtomcrypt hashes, including keysize etc. {&hash_desc, keysize, hashsize} */ @@ -137,21 +141,15 @@ #ifdef DROPBEAR_AES128 {"aes128-ctr", 0, &dropbear_aes128, 1, &dropbear_mode_ctr}, #endif -#ifdef DROPBEAR_3DES - {"3des-ctr", 0, &dropbear_3des, 1, &dropbear_mode_ctr}, -#endif #ifdef DROPBEAR_AES256 {"aes256-ctr", 0, &dropbear_aes256, 1, &dropbear_mode_ctr}, #endif #endif /* DROPBEAR_ENABLE_CTR_MODE */ -/* CBC modes are always enabled */ +#ifdef DROPBEAR_ENABLE_CBC_MODE #ifdef DROPBEAR_AES128 {"aes128-cbc", 0, &dropbear_aes128, 1, &dropbear_mode_cbc}, #endif -#ifdef DROPBEAR_3DES - {"3des-cbc", 0, &dropbear_3des, 1, &dropbear_mode_cbc}, -#endif #ifdef DROPBEAR_AES256 {"aes256-cbc", 0, &dropbear_aes256, 1, &dropbear_mode_cbc}, #endif @@ -162,9 +160,16 @@ #ifdef DROPBEAR_TWOFISH128 {"twofish128-cbc", 0, &dropbear_twofish128, 1, &dropbear_mode_cbc}, #endif +#ifdef DROPBEAR_3DES + {"3des-ctr", 0, &dropbear_3des, 1, &dropbear_mode_ctr}, +#endif +#ifdef DROPBEAR_3DES + {"3des-cbc", 0, &dropbear_3des, 1, &dropbear_mode_cbc}, +#endif #ifdef DROPBEAR_BLOWFISH {"blowfish-cbc", 0, &dropbear_blowfish, 1, &dropbear_mode_cbc}, #endif +#endif /* DROPBEAR_ENABLE_CBC_MODE */ #ifdef DROPBEAR_NONE_CIPHER {"none", 0, (void*)&dropbear_nocipher, 1, &dropbear_mode_none}, #endif @@ -195,7 +200,13 @@ #ifndef DISABLE_ZLIB algo_type ssh_compress[] = { + {"zlib@openssh.com", DROPBEAR_COMP_ZLIB_DELAY, NULL, 1, NULL}, {"zlib", DROPBEAR_COMP_ZLIB, NULL, 1, NULL}, + {"none", DROPBEAR_COMP_NONE, NULL, 1, NULL}, + {NULL, 0, NULL, 0, NULL} +}; + +algo_type ssh_delaycompress[] = { {"zlib@openssh.com", DROPBEAR_COMP_ZLIB_DELAY, NULL, 1, NULL}, {"none", DROPBEAR_COMP_NONE, NULL, 1, NULL}, {NULL, 0, NULL, 0, NULL} @@ -265,8 +276,8 @@ {"ecdh-sha2-nistp256", 0, &kex_ecdh_nistp256, 1, NULL}, #endif #endif + {"diffie-hellman-group14-sha1", 0, &kex_dh_group14, 1, NULL}, {"diffie-hellman-group1-sha1", 0, &kex_dh_group1, 1, NULL}, - {"diffie-hellman-group14-sha1", 0, &kex_dh_group14, 1, NULL}, #ifdef USE_KEXGUESS2 {KEXGUESS2_ALGO_NAME, KEXGUESS2_ALGO_ID, NULL, 1, NULL}, #endif diff -r 8d0c33e8ddab -r e75316906852 common-kex.c --- a/common-kex.c Sun Jan 04 22:33:12 2015 +0800 +++ b/common-kex.c Wed Jan 28 21:40:34 2015 +0800 @@ -238,14 +238,24 @@ void kexfirstinitialise() { ses.kexstate.donefirstkex = 0; -#ifndef DISABLE_ZLIB - if (opts.enable_compress) { - ses.compress_algos = ssh_compress; - } else +#ifdef DISABLE_ZLIB + ses.compress_algos = ssh_nocompress; +#else + switch (opts.compress_mode) + { + case DROPBEAR_COMPRESS_DELAYED: + ses.compress_algos = ssh_delaycompress; + break; + + case DROPBEAR_COMPRESS_ON: + ses.compress_algos = ssh_compress; + break; + + case DROPBEAR_COMPRESS_OFF: + ses.compress_algos = ssh_nocompress; + break; + } #endif - { - ses.compress_algos = ssh_nocompress; - } kexinitialise(); } @@ -303,7 +313,7 @@ hash_desc->done(&hs2, tmpout); memcpy(&out[offset], tmpout, MIN(outlen - offset, hash_desc->hashsize)); } - + m_burn(&hs2, sizeof(hash_state)); } /* Generate the actual encryption/integrity keys, using the results of the @@ -403,6 +413,7 @@ m_burn(C2S_key, sizeof(C2S_key)); m_burn(S2C_IV, sizeof(S2C_IV)); m_burn(S2C_key, sizeof(S2C_key)); + m_burn(&hs, sizeof(hash_state)); TRACE(("leave gen_new_keys")) } @@ -798,6 +809,7 @@ buf_burn(ses.kexhashbuf); buf_free(ses.kexhashbuf); + m_burn(&hs, sizeof(hash_state)); ses.kexhashbuf = NULL; /* first time around, we set the session_id to H */ @@ -805,7 +817,6 @@ /* create the session_id, this never needs freeing */ ses.session_id = buf_newcopy(ses.hash); } - } /* read the other side's algo list. buf_match_algo is a callback to match diff -r 8d0c33e8ddab -r e75316906852 dbutil.c --- a/dbutil.c Sun Jan 04 22:33:12 2015 +0800 +++ b/dbutil.c Wed Jan 28 21:40:34 2015 +0800 @@ -936,6 +936,23 @@ } } +/* Returns malloced path. Only expands ~ in first character */ +char * expand_tilde(const char *inpath) { + struct passwd *pw = NULL; + if (inpath[0] == '~') { + pw = getpwuid(getuid()); + if (pw && pw->pw_dir) { + int len = strlen(inpath) + strlen(pw->pw_dir) + 1; + char *buf = m_malloc(len); + snprintf(buf, len, "%s/%s", pw->pw_dir, &inpath[1]); + return buf; + } + } + + /* Fallback */ + return m_strdup(inpath); +} + int constant_time_memcmp(const void* a, const void *b, size_t n) { const char *xa = a, *xb = b; diff -r 8d0c33e8ddab -r e75316906852 dbutil.h --- a/dbutil.h Sun Jan 04 22:33:12 2015 +0800 +++ b/dbutil.h Wed Jan 28 21:40:34 2015 +0800 @@ -110,5 +110,6 @@ a real-world clock */ time_t monotonic_now(); +char * expand_tilde(const char *inpath); #endif /* _DBUTIL_H_ */ diff -r 8d0c33e8ddab -r e75316906852 dropbearkey.c --- a/dropbearkey.c Sun Jan 04 22:33:12 2015 +0800 +++ b/dropbearkey.c Wed Jan 28 21:40:34 2015 +0800 @@ -76,7 +76,8 @@ #ifdef DROPBEAR_ECDSA " ecdsa\n" #endif - "-f filename Use filename for the secret key\n" + "-f filename Use filename for the secret key.\n" + " ~/.ssh/id_dropbear is recommended for client keys.\n" "-s bits Key size in bits, should be a multiple of 8 (optional)\n" #ifdef DROPBEAR_DSS " DSS has a fixed size of 1024 bits\n" diff -r 8d0c33e8ddab -r e75316906852 keyimport.c --- a/keyimport.c Sun Jan 04 22:33:12 2015 +0800 +++ b/keyimport.c Wed Jan 28 21:40:34 2015 +0800 @@ -627,7 +627,7 @@ if (i == 0) { /* First integer is a version indicator */ - int expected; + int expected = -1; switch (key->type) { case OSSH_RSA: case OSSH_DSA: @@ -826,7 +826,7 @@ unsigned char *outblob = NULL; int outlen = -9999; struct mpint_pos numbers[9]; - int nnumbers = -1, pos, len, seqlen, i; + int nnumbers = -1, pos = 0, len = 0, seqlen, i; char *header = NULL, *footer = NULL; char zero[1]; int ret = 0; diff -r 8d0c33e8ddab -r e75316906852 options.h --- a/options.h Sun Jan 04 22:33:12 2015 +0800 +++ b/options.h Wed Jan 28 21:40:34 2015 +0800 @@ -95,8 +95,12 @@ #define DROPBEAR_AES256 /* Compiling in Blowfish will add ~6kB to runtime heap memory usage */ /*#define DROPBEAR_BLOWFISH*/ -#define DROPBEAR_TWOFISH256 -#define DROPBEAR_TWOFISH128 +/*#define DROPBEAR_TWOFISH256*/ +/*#define DROPBEAR_TWOFISH128*/ + +/* Enable CBC mode for ciphers. This has security issues though + * is the most compatible with older SSH implementations */ +#define DROPBEAR_ENABLE_CBC_MODE /* Enable "Counter Mode" for ciphers. This is more secure than normal * CBC mode against certain attacks. This adds around 1kB to binary @@ -123,8 +127,8 @@ * which are not the standard form. */ #define DROPBEAR_SHA1_HMAC #define DROPBEAR_SHA1_96_HMAC -/*#define DROPBEAR_SHA2_256_HMAC*/ -/*#define DROPBEAR_SHA2_512_HMAC*/ +#define DROPBEAR_SHA2_256_HMAC +#define DROPBEAR_SHA2_512_HMAC #define DROPBEAR_MD5_HMAC /* You can also disable integrity. Don't bother disabling this if you're @@ -170,6 +174,11 @@ #define DROPBEAR_ZLIB_WINDOW_BITS 15 #endif +/* Server won't allow zlib compression until after authentication. Prevents + flaws in the zlib library being unauthenticated exploitable flaws. + Some old ssh clients may not support the alternative zlib@openssh.com method */ +#define DROPBEAR_SERVER_DELAY_ZLIB 1 + /* Whether to do reverse DNS lookups. */ /*#define DO_HOST_LOOKUP */ @@ -207,6 +216,10 @@ #define ENABLE_CLI_PUBKEY_AUTH #define ENABLE_CLI_INTERACT_AUTH +/* A default argument for dbclient -i . + leading "~" is expanded */ +#define DROPBEAR_DEFAULT_CLI_AUTHKEY "~/.ssh/id_dropbear" + /* This variable can be used to set a password for client * authentication on the commandline. Beware of platforms * that don't protect environment variables of processes etc. Also diff -r 8d0c33e8ddab -r e75316906852 packet.c --- a/packet.c Sun Jan 04 22:33:12 2015 +0800 +++ b/packet.c Wed Jan 28 21:40:34 2015 +0800 @@ -283,14 +283,14 @@ } len = buf_getint(ses.readbuf) + 4 + macsize; - TRACE2(("packet size is %d, block %d mac %d", len, blocksize, macsize)) + TRACE2(("packet size is %u, block %u mac %u", len, blocksize, macsize)) /* check packet length */ if ((len > RECV_MAX_PACKET_LEN) || (len < MIN_PACKET_LEN + macsize) || ((len - macsize) % blocksize != 0)) { - dropbear_exit("Integrity error (bad packet size %d)", len); + dropbear_exit("Integrity error (bad packet size %u)", len); } if (len > ses.readbuf->size) { @@ -342,7 +342,7 @@ /* - 4 - 1 is for LEN and PADLEN values */ len = ses.readbuf->len - padlen - 4 - 1 - macsize; if ((len > RECV_MAX_PAYLOAD_LEN+ZLIB_COMPRESS_EXPANSION) || (len < 1)) { - dropbear_exit("Bad packet size %d", len); + dropbear_exit("Bad packet size %u", len); } buf_setpos(ses.readbuf, PACKET_PAYLOAD_OFF); diff -r 8d0c33e8ddab -r e75316906852 runopts.h --- a/runopts.h Sun Jan 04 22:33:12 2015 +0800 +++ b/runopts.h Wed Jan 28 21:40:34 2015 +0800 @@ -44,7 +44,11 @@ /* TODO: add a commandline flag. Currently this is on by default if compression * is compiled in, but disabled for a client's non-final multihop stages. (The * intermediate stages are compressed streams, so are uncompressible. */ - int enable_compress; + enum { + DROPBEAR_COMPRESS_DELAYED, /* Server only */ + DROPBEAR_COMPRESS_ON, + DROPBEAR_COMPRESS_OFF, + } compress_mode; #endif #ifdef ENABLE_USER_ALGO_LIST diff -r 8d0c33e8ddab -r e75316906852 svr-runopts.c --- a/svr-runopts.c Sun Jan 04 22:33:12 2015 +0800 +++ b/svr-runopts.c Wed Jan 28 21:40:34 2015 +0800 @@ -140,9 +140,15 @@ #ifdef ENABLE_SVR_REMOTETCPFWD svr_opts.noremotetcp = 0; #endif + #ifndef DISABLE_ZLIB - opts.enable_compress = 1; +#if DROPBEAR_SERVER_DELAY_ZLIB + opts.compress_mode = DROPBEAR_COMPRESS_DELAYED; +#else + opts.compress_mode = DROPBEAR_COMPRESS_ON; #endif +#endif + /* not yet opts.ipv4 = 1; opts.ipv6 = 1;