Mercurial > dropbear
changeset 247:c07de41b53d7 contrib-blacklist
propagate from branch 'au.asn.ucc.matt.dropbear' (head c9347a030ac9ef5454b7a84f4915e91dc44efd6c)
to branch 'au.asn.ucc.matt.dropbear.contrib.blacklist' (head 8662c7148e4b738e2511a6fce9a4cbd959ecb6b8)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 06 Sep 2005 04:57:14 +0000 |
parents | b24730e11c83 (diff) f4cf0415fec1 (current diff) |
children | 9d110777f345 |
files | options.h svr-main.c |
diffstat | 22 files changed, 235 insertions(+), 138 deletions(-) [+] |
line wrap: on
line diff
--- a/INSTALL Tue Sep 06 04:52:46 2005 +0000 +++ b/INSTALL Tue Sep 06 04:57:14 2005 +0000 @@ -28,6 +28,11 @@ ============================================================================ +If you're compiling for a 386-class CPU, you will probably need to add +CFLAGS=-DLTC_NO_BSWAP so that libtomcrypt doesn't use 486+ instructions. + +============================================================================ + Compiling with uClibc: Firstly, make sure you have at least uclibc 0.9.17, as getusershell() in prior
--- a/buffer.c Tue Sep 06 04:52:46 2005 +0000 +++ b/buffer.c Tue Sep 06 04:57:14 2005 +0000 @@ -153,7 +153,7 @@ unsigned char buf_getbyte(buffer* buf) { /* This check is really just ==, but the >= allows us to check for the - * assert()able case of pos > len, which should _never_ happen. */ + * bad case of pos > len, which should _never_ happen. */ if (buf->pos >= buf->len) { dropbear_exit("bad buf_getbyte"); } @@ -270,7 +270,7 @@ unsigned int len, pad = 0; TRACE(("enter buf_putmpint")) - assert(mp != NULL); + dropbear_assert(mp != NULL); if (SIGN(mp) == MP_NEG) { dropbear_exit("negative bignum");
--- a/channel.h Tue Sep 06 04:52:46 2005 +0000 +++ b/channel.h Tue Sep 06 04:57:14 2005 +0000 @@ -81,6 +81,10 @@ int initconn; /* used for TCP forwarding, whether the channel has been fully initialised */ + int await_open; /* flag indicating whether we've sent an open request + for this channel (and are awaiting a confirmation + or failure). */ + const struct ChanType* type; }; @@ -96,7 +100,7 @@ }; -void chaninitialise(); +void chaninitialise(const struct ChanType *chantypes[]); void chancleanup(); void setchannelfds(fd_set *readfd, fd_set *writefd); void channelio(fd_set *readfd, fd_set *writefd); @@ -119,7 +123,7 @@ circbuffer * buf); #ifdef DROPBEAR_CLIENT -const struct ChanType clichansess; +extern const struct ChanType clichansess; #endif #if defined(USING_LISTENERS) || defined(DROPBEAR_CLIENT)
--- a/circbuffer.c Tue Sep 06 04:52:46 2005 +0000 +++ b/circbuffer.c Tue Sep 06 04:57:14 2005 +0000 @@ -66,8 +66,8 @@ unsigned int cbuf_readlen(circbuffer *cbuf) { - assert(((2*cbuf->size)+cbuf->writepos-cbuf->readpos)%cbuf->size == cbuf->used%cbuf->size); - assert(((2*cbuf->size)+cbuf->readpos-cbuf->writepos)%cbuf->size == (cbuf->size-cbuf->used)%cbuf->size); + dropbear_assert(((2*cbuf->size)+cbuf->writepos-cbuf->readpos)%cbuf->size == cbuf->used%cbuf->size); + dropbear_assert(((2*cbuf->size)+cbuf->readpos-cbuf->writepos)%cbuf->size == (cbuf->size-cbuf->used)%cbuf->size); if (cbuf->used == 0) { TRACE(("cbuf_readlen: unused buffer")) @@ -83,9 +83,9 @@ unsigned int cbuf_writelen(circbuffer *cbuf) { - assert(cbuf->used <= cbuf->size); - assert(((2*cbuf->size)+cbuf->writepos-cbuf->readpos)%cbuf->size == cbuf->used%cbuf->size); - assert(((2*cbuf->size)+cbuf->readpos-cbuf->writepos)%cbuf->size == (cbuf->size-cbuf->used)%cbuf->size); + dropbear_assert(cbuf->used <= cbuf->size); + dropbear_assert(((2*cbuf->size)+cbuf->writepos-cbuf->readpos)%cbuf->size == cbuf->used%cbuf->size); + dropbear_assert(((2*cbuf->size)+cbuf->readpos-cbuf->writepos)%cbuf->size == (cbuf->size-cbuf->used)%cbuf->size); if (cbuf->used == cbuf->size) { TRACE(("cbuf_writelen: full buffer")) @@ -122,7 +122,7 @@ } cbuf->used += len; - assert(cbuf->used <= cbuf->size); + dropbear_assert(cbuf->used <= cbuf->size); cbuf->writepos = (cbuf->writepos + len) % cbuf->size; } @@ -132,7 +132,7 @@ dropbear_exit("bad cbuf read"); } - assert(cbuf->used >= len); + dropbear_assert(cbuf->used >= len); cbuf->used -= len; cbuf->readpos = (cbuf->readpos + len) % cbuf->size; }
--- a/common-algo.c Tue Sep 06 04:52:46 2005 +0000 +++ b/common-algo.c Tue Sep 06 04:57:14 2005 +0000 @@ -32,20 +32,28 @@ /* Mappings for ciphers, parameters are {&cipher_desc, keysize, blocksize} */ +#ifdef DROPBEAR_AES256_CBC +static const struct dropbear_cipher dropbear_aes256 = + {&aes_desc, 32, 16}; +#endif #ifdef DROPBEAR_AES128_CBC -const struct dropbear_cipher dropbear_aes128 = +static const struct dropbear_cipher dropbear_aes128 = {&aes_desc, 16, 16}; #endif #ifdef DROPBEAR_BLOWFISH_CBC -const struct dropbear_cipher dropbear_blowfish = +static const struct dropbear_cipher dropbear_blowfish = {&blowfish_desc, 16, 8}; #endif +#ifdef DROPBEAR_TWOFISH256_CBC +static const struct dropbear_cipher dropbear_twofish256 = + {&twofish_desc, 32, 16}; +#endif #ifdef DROPBEAR_TWOFISH128_CBC -const struct dropbear_cipher dropbear_twofish128 = +static const struct dropbear_cipher dropbear_twofish128 = {&twofish_desc, 16, 16}; #endif #ifdef DROPBEAR_3DES_CBC -const struct dropbear_cipher dropbear_3des = +static const struct dropbear_cipher dropbear_3des = {&des3_desc, 24, 8}; #endif @@ -57,11 +65,15 @@ {&hash_desc, keysize, hashsize} */ #ifdef DROPBEAR_SHA1_HMAC -const struct dropbear_hash dropbear_sha1 = +static const struct dropbear_hash dropbear_sha1 = {&sha1_desc, 20, 20}; #endif +#ifdef DROPBEAR_SHA1_96_HMAC +static const struct dropbear_hash dropbear_sha1_96 = + {&sha1_desc, 20, 12}; +#endif #ifdef DROPBEAR_MD5_HMAC -const struct dropbear_hash dropbear_md5 = +static const struct dropbear_hash dropbear_md5 = {&md5_desc, 16, 16}; #endif @@ -75,19 +87,29 @@ #ifdef DROPBEAR_AES128_CBC {"aes128-cbc", 0, (void*)&dropbear_aes128, 1}, #endif -#ifdef DROPBEAR_BLOWFISH_CBC - {"blowfish-cbc", 0, (void*)&dropbear_blowfish, 1}, +#ifdef DROPBEAR_3DES_CBC + {"3des-cbc", 0, (void*)&dropbear_3des, 1}, +#endif +#ifdef DROPBEAR_AES256_CBC + {"aes256-cbc", 0, (void*)&dropbear_aes256, 1}, +#endif +#ifdef DROPBEAR_TWOFISH256_CBC + {"twofish256-cbc", 0, (void*)&dropbear_twofish256, 1}, + {"twofish-cbc", 0, (void*)&dropbear_twofish256, 1}, #endif #ifdef DROPBEAR_TWOFISH128_CBC - {"twofish-cbc", 0, (void*)&dropbear_twofish128, 1}, + {"twofish128-cbc", 0, (void*)&dropbear_twofish128, 1}, #endif -#ifdef DROPBEAR_3DES_CBC - {"3des-cbc", 0, (void*)&dropbear_3des, 1}, +#ifdef DROPBEAR_BLOWFISH_CBC + {"blowfish-cbc", 0, (void*)&dropbear_blowfish, 1}, #endif {NULL, 0, NULL, 0} }; algo_type sshhashes[] = { +#ifdef DROPBEAR_SHA1_96_HMAC + {"hmac-sha1-96", 0, (void*)&dropbear_sha1_96, 1}, +#endif #ifdef DROPBEAR_SHA1_HMAC {"hmac-sha1", 0, (void*)&dropbear_sha1, 1}, #endif @@ -126,13 +148,13 @@ void crypto_init() { const struct ltc_cipher_descriptor *regciphers[] = { -#ifdef DROPBEAR_AES128_CBC +#ifdef DROPBEAR_AES_CBC &aes_desc, #endif #ifdef DROPBEAR_BLOWFISH_CBC &blowfish_desc, #endif -#ifdef DROPBEAR_TWOFISH128_CBC +#ifdef DROPBEAR_TWOFISH_CBC &twofish_desc, #endif #ifdef DROPBEAR_3DES_CBC @@ -187,21 +209,20 @@ /* Output a comma separated list of algorithms to a buffer */ void buf_put_algolist(buffer * buf, algo_type localalgos[]) { - unsigned int pos = 0, i, len; - char str[50]; /* enough for local algo storage */ + unsigned int i, len; + unsigned int donefirst = 0; + buffer *algolist = NULL; + algolist = buf_new(100); for (i = 0; localalgos[i].name != NULL; i++) { if (localalgos[i].usable) { - /* Avoid generating a trailing comma */ - if (pos) - str[pos++] = ','; + if (donefirst) + buf_putbyte(algolist, ','); + donefirst = 1; len = strlen(localalgos[i].name); - memcpy(&str[pos], localalgos[i].name, len); - pos += len; + buf_putbytes(algolist, localalgos[i].name, len); } } - str[pos]=0; - /* Debug this */ - TRACE(("buf_put_algolist: %s", str)) - buf_putstring(buf, str, pos); + buf_putstring(buf, algolist->data, algolist->len); + buf_free(algolist); }
--- a/common-channel.c Tue Sep 06 04:52:46 2005 +0000 +++ b/common-channel.c Tue Sep 06 04:57:14 2005 +0000 @@ -147,6 +147,7 @@ newchan->outfd = FD_UNINIT; newchan->errfd = FD_CLOSED; /* this isn't always set to start with */ newchan->initconn = 0; + newchan->await_open = 0; newchan->writebuf = cbuf_new(RECV_MAXWINDOW); newchan->extrabuf = NULL; /* The user code can set it up */ @@ -409,9 +410,9 @@ channel->recvdonelen = 0; } - assert(channel->recvwindow <= RECV_MAXWINDOW); - assert(channel->recvwindow <= cbuf_getavail(channel->writebuf)); - assert(channel->extrabuf == NULL || + dropbear_assert(channel->recvwindow <= RECV_MAXWINDOW); + dropbear_assert(channel->recvwindow <= cbuf_getavail(channel->writebuf)); + dropbear_assert(channel->extrabuf == NULL || channel->recvwindow <= cbuf_getavail(channel->extrabuf)); @@ -603,14 +604,14 @@ CHECKCLEARTOWRITE(); - assert(!channel->sentclosed); + dropbear_assert(!channel->sentclosed); if (isextended) { fd = channel->errfd; } else { fd = channel->outfd; } - assert(fd >= 0); + dropbear_assert(fd >= 0); maxlen = MIN(channel->transwindow, channel->transmaxpacket); /* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and @@ -718,9 +719,9 @@ len -= buflen; } - assert(channel->recvwindow >= datalen); + dropbear_assert(channel->recvwindow >= datalen); channel->recvwindow -= datalen; - assert(channel->recvwindow <= RECV_MAXWINDOW); + dropbear_assert(channel->recvwindow <= RECV_MAXWINDOW); TRACE(("leave recv_msg_channel_data")) } @@ -933,6 +934,8 @@ chan->infd = chan->outfd = fd; ses.maxfd = MAX(ses.maxfd, fd); + chan->await_open = 1; + /* now open the channel connection */ CHECKCLEARTOWRITE(); @@ -960,6 +963,11 @@ dropbear_exit("Unknown channel"); } + if (!channel->await_open) { + dropbear_exit("unexpected channel reply"); + } + channel->await_open = 0; + channel->remotechan = buf_getint(ses.payload); channel->transwindow = buf_getint(ses.payload); channel->transmaxpacket = buf_getint(ses.payload); @@ -990,6 +998,11 @@ dropbear_exit("Unknown channel"); } + if (!channel->await_open) { + dropbear_exit("unexpected channel reply"); + } + channel->await_open = 0; + removechannel(channel); } #endif /* USING_LISTENERS */
--- a/common-kex.c Tue Sep 06 04:52:46 2005 +0000 +++ b/common-kex.c Tue Sep 06 04:57:14 2005 +0000 @@ -35,7 +35,7 @@ #include "random.h" /* diffie-hellman-group1-sha1 value for p */ -const unsigned char dh_p_val[] = { +static const unsigned char dh_p_val[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, @@ -47,8 +47,9 @@ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +#define DH_P_LEN sizeof(dh_p_val) -const int DH_G_VAL = 2; +static const int DH_G_VAL = 2; static void kexinitialise(); void gen_new_keys(); @@ -621,7 +622,7 @@ erralgo = "enc c->s"; goto error; } - TRACE(("c2s is %s", c2s_cipher_algo->name)) + TRACE(("enc c2s is %s", c2s_cipher_algo->name)) /* encryption_algorithms_server_to_client */ s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); @@ -629,7 +630,7 @@ erralgo = "enc s->c"; goto error; } - TRACE(("s2c is %s", s2c_cipher_algo->name)) + TRACE(("enc s2c is %s", s2c_cipher_algo->name)) /* mac_algorithms_client_to_server */ c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); @@ -637,6 +638,7 @@ erralgo = "mac c->s"; goto error; } + TRACE(("hash c2s is %s", c2s_hash_algo->name)) /* mac_algorithms_server_to_client */ s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); @@ -644,6 +646,7 @@ erralgo = "mac s->c"; goto error; } + TRACE(("hash s2c is %s", s2c_hash_algo->name)) /* compression_algorithms_client_to_server */ c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); @@ -651,6 +654,7 @@ erralgo = "comp c->s"; goto error; } + TRACE(("hash c2s is %s", c2s_comp_algo->name)) /* compression_algorithms_server_to_client */ s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); @@ -658,6 +662,7 @@ erralgo = "comp s->c"; goto error; } + TRACE(("hash s2c is %s", s2c_comp_algo->name)) /* languages_client_to_server */ buf_eatstring(ses.payload); @@ -700,13 +705,6 @@ ses.newkeys->trans_algo_comp = s2c_comp_algo->val; } - TRACE(("enc algo recv %s", algo->name)) - TRACE(("enc algo trans %s", algo->name)) - TRACE(("mac algo recv %s", algo->name)) - TRACE(("mac algo trans %s", algo->name)) - TRACE(("comp algo recv %s", algo->name)) - TRACE(("comp algo trans %s", algo->name)) - /* reserved for future extensions */ buf_getint(ses.payload); return;
--- a/common-session.c Tue Sep 06 04:52:46 2005 +0000 +++ b/common-session.c Tue Sep 06 04:57:14 2005 +0000 @@ -62,7 +62,6 @@ ses.connecttimeout = 0; kexfirstinitialise(); /* initialise the kex state */ - chaninitialise(); /* initialise the channel state */ ses.writepayload = buf_new(MAX_TRANS_PAYLOAD_LEN); ses.transseq = 0; @@ -126,7 +125,7 @@ timeout.tv_usec = 0; FD_ZERO(&writefd); FD_ZERO(&readfd); - assert(ses.payload == NULL); + dropbear_assert(ses.payload == NULL); if (ses.sock != -1) { FD_SET(ses.sock, &readfd); if (!isempty(&ses.writequeue)) {
--- a/dbutil.c Tue Sep 06 04:52:46 2005 +0000 +++ b/dbutil.c Tue Sep 06 04:57:14 2005 +0000 @@ -110,6 +110,10 @@ exit(exitcode); } +void fail_assert(const char* expr, const char* file, int line) { + dropbear_exit("failed assertion (%s:%d): `%s'", file, line, expr); +} + static void generic_dropbear_log(int UNUSED(priority), const char* format, va_list param) { @@ -186,6 +190,10 @@ *errstring = (char*)m_malloc(len); snprintf(*errstring, len, "Error resolving: %s", gai_strerror(err)); } + if (res0) { + freeaddrinfo(res0); + res0 = NULL; + } TRACE(("leave dropbear_listen: failed resolving")) return -1; } @@ -237,6 +245,11 @@ nsock++; } + if (res0) { + freeaddrinfo(res0); + res0 = NULL; + } + if (nsock == 0) { if (errstring != NULL && *errstring == NULL) { int len;
--- a/dbutil.h Tue Sep 06 04:52:46 2005 +0000 +++ b/dbutil.h Tue Sep 06 04:57:14 2005 +0000 @@ -39,6 +39,7 @@ void dropbear_exit(const char* format, ...); void dropbear_close(const char* format, ...); void dropbear_log(int priority, const char* format, ...); +void fail_assert(const char* expr, const char* file, int line); #ifdef DEBUG_TRACE void dropbear_trace(const char* format, ...); void printhex(const char * label, const unsigned char * buf, int len); @@ -66,4 +67,7 @@ /* Used to force mp_ints to be initialised */ #define DEF_MP_INT(X) mp_int X = {0, 0, 0, NULL} +/* Dropbear assertion */ +#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0) + #endif /* _DBUTIL_H_ */
--- a/dss.c Tue Sep 06 04:52:46 2005 +0000 +++ b/dss.c Tue Sep 06 04:57:14 2005 +0000 @@ -46,7 +46,7 @@ int buf_get_dss_pub_key(buffer* buf, dss_key *key) { TRACE(("enter buf_get_dss_pub_key")) - assert(key != NULL); + dropbear_assert(key != NULL); key->p = m_malloc(sizeof(mp_int)); key->q = m_malloc(sizeof(mp_int)); key->g = m_malloc(sizeof(mp_int)); @@ -80,7 +80,7 @@ int ret = DROPBEAR_FAILURE; - assert(key != NULL); + dropbear_assert(key != NULL); ret = buf_get_dss_pub_key(buf, key); if (ret == DROPBEAR_FAILURE) { @@ -137,7 +137,7 @@ */ void buf_put_dss_pub_key(buffer* buf, dss_key *key) { - assert(key != NULL); + dropbear_assert(key != NULL); buf_putstring(buf, SSH_SIGNKEY_DSS, SSH_SIGNKEY_DSS_LEN); buf_putmpint(buf, key->p); buf_putmpint(buf, key->q); @@ -149,7 +149,7 @@ /* Same as buf_put_dss_pub_key, but with the private "x" key appended */ void buf_put_dss_priv_key(buffer* buf, dss_key *key) { - assert(key != NULL); + dropbear_assert(key != NULL); buf_put_dss_pub_key(buf, key); buf_putmpint(buf, key->x); @@ -172,7 +172,7 @@ int stringlen; TRACE(("enter buf_dss_verify")) - assert(key != NULL); + dropbear_assert(key != NULL); m_mp_init_multi(&val1, &val2, &val3, &val4, NULL); @@ -310,7 +310,7 @@ hash_state hs; TRACE(("enter buf_put_dss_sign")) - assert(key != NULL); + dropbear_assert(key != NULL); /* hash the data */ sha1_init(&hs); @@ -380,7 +380,7 @@ buf_putint(buf, 2*SHA1_HASH_SIZE); writelen = mp_unsigned_bin_size(&dss_r); - assert(writelen <= SHA1_HASH_SIZE); + dropbear_assert(writelen <= SHA1_HASH_SIZE); /* need to pad to 160 bits with leading zeros */ for (i = 0; i < SHA1_HASH_SIZE - writelen; i++) { buf_putbyte(buf, 0); @@ -393,7 +393,7 @@ buf_incrwritepos(buf, writelen); writelen = mp_unsigned_bin_size(&dss_s); - assert(writelen <= SHA1_HASH_SIZE); + dropbear_assert(writelen <= SHA1_HASH_SIZE); /* need to pad to 160 bits with leading zeros */ for (i = 0; i < SHA1_HASH_SIZE - writelen; i++) { buf_putbyte(buf, 0);
--- a/kex.h Tue Sep 06 04:52:46 2005 +0000 +++ b/kex.h Tue Sep 06 04:57:14 2005 +0000 @@ -42,11 +42,6 @@ void send_msg_kexdh_init(); /* client */ void recv_msg_kexdh_reply(); /* client */ -extern const unsigned char dh_p_val[]; -#define DH_P_LEN 128 /* The length of the dh_p_val array */ - -extern const int DH_G_VAL; /* == 2 */ - struct KEXState { unsigned sentkexinit : 1; /*set when we've sent/recv kexinit packet */
--- a/keyimport.c Tue Sep 06 04:52:46 2005 +0000 +++ b/keyimport.c Tue Sep 06 04:57:14 2005 +0000 @@ -203,7 +203,7 @@ unsigned long outlen; int rawcpl; rawcpl = cpl * 3 / 4; - assert((unsigned int)cpl < sizeof(out)); + dropbear_assert((unsigned int)cpl < sizeof(out)); while (datalen > 0) { n = (datalen < rawcpl ? datalen : rawcpl); @@ -714,7 +714,7 @@ } #endif - assert(keytype != -1); + dropbear_assert(keytype != -1); /* * Fetch the key blobs. @@ -913,7 +913,7 @@ * with the same value. Those are all removed and the rest is * returned. */ - assert(pos == len); + dropbear_assert(pos == len); while (pos < outlen) { outblob[pos++] = outlen - len; } @@ -1491,7 +1491,7 @@ privlen = pos - publen; } - assert(privlen > 0); /* should have bombed by now if not */ + dropbear_assert(privlen > 0); /* should have bombed by now if not */ retkey = snew(struct ssh2_userkey); retkey->alg = alg; @@ -1557,7 +1557,7 @@ pos += ssh2_read_mpint(privblob+pos, privlen-pos, &q); pos += ssh2_read_mpint(privblob+pos, privlen-pos, &iqmp); - assert(e.start && iqmp.start); /* can't go wrong */ + dropbear_assert(e.start && iqmp.start); /* can't go wrong */ numbers[0] = e; numbers[1] = d; @@ -1581,7 +1581,7 @@ pos = 0; pos += ssh2_read_mpint(privblob+pos, privlen-pos, &x); - assert(y.start && x.start); /* can't go wrong */ + dropbear_assert(y.start && x.start); /* can't go wrong */ numbers[0] = p; numbers[1] = g; @@ -1593,7 +1593,7 @@ initial_zero = 1; type = "dl-modp{sign{dsa-nist-sha1},dh{plain}}"; } else { - assert(0); /* zoinks! */ + dropbear_assert(0); /* zoinks! */ } /* @@ -1637,13 +1637,13 @@ } ciphertext = (char *)outblob+lenpos+4; cipherlen = pos - (lenpos+4); - assert(!passphrase || cipherlen % 8 == 0); + dropbear_assert(!passphrase || cipherlen % 8 == 0); /* Wrap up the encrypted blob string. */ PUT_32BIT(outblob+lenpos, cipherlen); /* And finally fill in the total length field. */ PUT_32BIT(outblob+4, pos); - assert(pos < outlen); + dropbear_assert(pos < outlen); /* * Encrypt the key.
--- a/options.h Tue Sep 06 04:52:46 2005 +0000 +++ b/options.h Tue Sep 06 04:57:14 2005 +0000 @@ -65,25 +65,30 @@ #define ENABLE_AGENTFWD /* Encryption - at least one required. - * RFC Draft requires 3DES, and recommends Blowfish, AES128 & Twofish128 */ + * RFC Draft requires 3DES and recommends AES128 for interoperability. + * Including multiple keysize variants the same cipher + * (eg AES256 as well as AES128) will result in a minimal size increase.*/ #define DROPBEAR_AES128_CBC -#define DROPBEAR_BLOWFISH_CBC -#define DROPBEAR_TWOFISH128_CBC #define DROPBEAR_3DES_CBC +#define DROPBEAR_AES256_CBC +#define DROPBEAR_BLOWFISH_CBC +#define DROPBEAR_TWOFISH256_CBC +#define DROPBEAR_TWOFISH128_CBC -/* Integrity - at least one required. - * RFC Draft requires sha1-hmac, and recommends md5-hmac. +/* Message Integrity - at least one required. + * RFC Draft requires sha1 and recommends sha1-96. + * sha1-96 may be of use for slow links, as it has a smaller overhead. * - * Note: there's no point disabling sha1 to save space, since it's used in the + * Note: there's no point disabling sha1 to save space, since it's used * for the random number generator and public-key cryptography anyway. * Disabling it here will just stop it from being used as the integrity portion * of the ssh protocol. * - * These are also used for key fingerprints in logs (when pubkey auth is used), - * MD5 fingerprints are printed if available, however SHA1 fingerprints will be - * generated otherwise. This isn't exactly optimal, although SHA1 fingerprints - * are not too hard to create from pubkeys if required. */ + * These hashes are also used for public key fingerprints in logs. + * If you disable MD5, Dropbear will fall back to SHA1 fingerprints, + * which are not the standard form. */ #define DROPBEAR_SHA1_HMAC +#define DROPBEAR_SHA1_96_HMAC #define DROPBEAR_MD5_HMAC /* Hostkey/public key algorithms - at least one required, these are used @@ -276,7 +281,7 @@ #define MAX_MAC_LEN SHA1_HASH_SIZE -#define MAX_KEY_LEN 24 /* 3DES requires a 24 byte key */ +#define MAX_KEY_LEN 32 /* 256 bits for aes256 etc */ #define MAX_IV_LEN 20 /* must be same as max blocksize, and >= SHA1_HASH_SIZE */ #define MAX_MAC_KEY 20 @@ -313,6 +318,14 @@ #define DROPBEAR_MAX_CLI_PASS 1024 +#if defined(DROPBEAR_AES256_CBC) || defined(DROPBEAR_AES128_CBC) +#define DROPBEAR_AES_CBC +#endif + +#if defined(DROPBEAR_TWOFISH256_CBC) || defined(DROPBEAR_TWOFISH128_CBC) +#define DROPBEAR_TWOFISH_CBC +#endif + #ifndef ENABLE_X11FWD #define DISABLE_X11FWD #endif
--- a/packet.c Tue Sep 06 04:52:46 2005 +0000 +++ b/packet.c Tue Sep 06 04:57:14 2005 +0000 @@ -53,13 +53,13 @@ buffer * writebuf = NULL; TRACE(("enter write_packet")) - assert(!isempty(&ses.writequeue)); + dropbear_assert(!isempty(&ses.writequeue)); /* Get the next buffer in the queue of encrypted packets to write*/ writebuf = (buffer*)examine(&ses.writequeue); len = writebuf->len - writebuf->pos; - assert(len > 0); + dropbear_assert(len > 0); /* Try to write as much as possible */ written = write(ses.sock, buf_getptr(writebuf, len), len); @@ -118,7 +118,7 @@ /* Attempt to read the remainder of the packet, note that there * mightn't be any available (EAGAIN) */ - assert(ses.readbuf != NULL); + dropbear_assert(ses.readbuf != NULL); maxlen = ses.readbuf->len - ses.readbuf->pos; len = read(ses.sock, buf_getptr(ses.readbuf, maxlen), maxlen); @@ -162,7 +162,7 @@ if (ses.readbuf == NULL) { /* start of a new packet */ ses.readbuf = buf_new(INIT_READBUF); - assert(ses.decryptreadbuf == NULL); + dropbear_assert(ses.decryptreadbuf == NULL); ses.decryptreadbuf = buf_new(blocksize); } @@ -215,7 +215,7 @@ if ((len > MAX_PACKET_LEN) || (len < MIN_PACKET_LEN + macsize) || ((len - macsize) % blocksize != 0)) { - dropbear_exit("bad packet size"); + dropbear_exit("bad packet size %d", len); } buf_resize(ses.readbuf, len); @@ -314,14 +314,13 @@ * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ static int checkmac(buffer* macbuf, buffer* sourcebuf) { - unsigned char macsize; + unsigned int macsize; hmac_state hmac; unsigned char tempbuf[MAX_MAC_LEN]; - unsigned long hashsize; - int len; + unsigned long bufsize; + unsigned int len; macsize = ses.keys->recv_algo_mac->hashsize; - if (macsize == 0) { return DROPBEAR_SUCCESS; } @@ -347,8 +346,8 @@ dropbear_exit("HMAC error"); } - hashsize = sizeof(tempbuf); - if (hmac_done(&hmac, tempbuf, &hashsize) != CRYPT_OK) { + bufsize = sizeof(tempbuf); + if (hmac_done(&hmac, tempbuf, &bufsize) != CRYPT_OK) { dropbear_exit("HMAC error"); } @@ -524,15 +523,15 @@ /* Create the packet mac, and append H(seqno|clearbuf) to the output */ static void writemac(buffer * outputbuffer, buffer * clearwritebuf) { - int macsize; + unsigned int macsize; unsigned char seqbuf[4]; - unsigned long hashsize; + unsigned char tempbuf[MAX_MAC_LEN]; + unsigned long bufsize; hmac_state hmac; TRACE(("enter writemac")) macsize = ses.keys->trans_algo_mac->hashsize; - if (macsize > 0) { /* calculate the mac */ if (hmac_init(&hmac, @@ -557,12 +556,12 @@ dropbear_exit("HMAC error"); } - hashsize = macsize; - if (hmac_done(&hmac, buf_getwriteptr(outputbuffer, macsize), &hashsize) + bufsize = sizeof(tempbuf); + if (hmac_done(&hmac, tempbuf, &bufsize) != CRYPT_OK) { dropbear_exit("HMAC error"); } - buf_incrwritepos(outputbuffer, macsize); + buf_putbytes(outputbuffer, tempbuf, macsize); } TRACE(("leave writemac")) } @@ -601,7 +600,7 @@ break; } - assert(ses.keys->trans_zstream->avail_out == 0); + dropbear_assert(ses.keys->trans_zstream->avail_out == 0); /* the buffer has been filled, we must extend. This only happens in * unusual circumstances where the data grows in size after deflate(),
--- a/queue.c Tue Sep 06 04:52:46 2005 +0000 +++ b/queue.c Tue Sep 06 04:57:14 2005 +0000 @@ -42,7 +42,7 @@ void* ret; struct Link* oldhead; - assert(!isempty(queue)); + dropbear_assert(!isempty(queue)); ret = queue->head->item; oldhead = queue->head; @@ -62,7 +62,7 @@ void *examine(struct Queue* queue) { - assert(!isempty(queue)); + dropbear_assert(!isempty(queue)); return queue->head->item; }
--- a/rsa.c Tue Sep 06 04:52:46 2005 +0000 +++ b/rsa.c Tue Sep 06 04:57:14 2005 +0000 @@ -49,7 +49,7 @@ int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) { TRACE(("enter buf_get_rsa_pub_key")) - assert(key != NULL); + dropbear_assert(key != NULL); key->e = m_malloc(sizeof(mp_int)); key->n = m_malloc(sizeof(mp_int)); m_mp_init_multi(key->e, key->n, NULL); @@ -80,7 +80,7 @@ * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) { - assert(key != NULL); + dropbear_assert(key != NULL); TRACE(("enter buf_get_rsa_priv_key")) @@ -163,7 +163,7 @@ void buf_put_rsa_pub_key(buffer* buf, rsa_key *key) { TRACE(("enter buf_put_rsa_pub_key")) - assert(key != NULL); + dropbear_assert(key != NULL); buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN); buf_putmpint(buf, key->e); @@ -178,7 +178,7 @@ TRACE(("enter buf_put_rsa_priv_key")) - assert(key != NULL); + dropbear_assert(key != NULL); buf_put_rsa_pub_key(buf, key); buf_putmpint(buf, key->d); @@ -209,7 +209,7 @@ TRACE(("enter buf_rsa_verify")) - assert(key != NULL); + dropbear_assert(key != NULL); m_mp_init_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL); @@ -267,7 +267,7 @@ unsigned char *tmpbuf; TRACE(("enter buf_put_rsa_sign")) - assert(key != NULL); + dropbear_assert(key != NULL); m_mp_init_multi(&rsa_s, &rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL); @@ -320,7 +320,7 @@ buf_putint(buf, nsize); /* pad out s to same length as n */ ssize = mp_unsigned_bin_size(&rsa_s); - assert(ssize <= nsize); + dropbear_assert(ssize <= nsize); for (i = 0; i < nsize-ssize; i++) { buf_putbyte(buf, 0x00); } @@ -365,8 +365,8 @@ hash_state hs; unsigned int nsize; - assert(key != NULL); - assert(data != NULL); + dropbear_assert(key != NULL); + dropbear_assert(data != NULL); nsize = mp_unsigned_bin_size(key->n); rsa_EM = buf_new(nsize-1); @@ -387,7 +387,7 @@ sha1_done(&hs, buf_getwriteptr(rsa_EM, SHA1_HASH_SIZE)); buf_incrwritepos(rsa_EM, SHA1_HASH_SIZE); - assert(rsa_EM->pos == rsa_EM->size); + dropbear_assert(rsa_EM->pos == rsa_EM->size); /* Create the mp_int from the encoded bytes */ buf_setpos(rsa_EM, 0);
--- a/signkey.c Tue Sep 06 04:52:46 2005 +0000 +++ b/signkey.c Tue Sep 06 04:57:14 2005 +0000 @@ -404,6 +404,9 @@ if (bloblen == DSS_SIGNATURE_SIZE && memcmp(ident, SSH_SIGNKEY_DSS, identlen) == 0) { m_free(ident); + if (key->dsskey == NULL) { + dropbear_exit("no dss key to verify signature"); + } return buf_dss_verify(buf, key->dsskey, data, len); } #endif @@ -411,6 +414,9 @@ #ifdef DROPBEAR_RSA if (memcmp(ident, SSH_SIGNKEY_RSA, identlen) == 0) { m_free(ident); + if (key->rsakey == NULL) { + dropbear_exit("no rsa key to verify signature"); + } return buf_rsa_verify(buf, key->rsakey, data, len); } #endif
--- a/svr-authpam.c Tue Sep 06 04:52:46 2005 +0000 +++ b/svr-authpam.c Tue Sep 06 04:57:14 2005 +0000 @@ -54,34 +54,58 @@ int rc = PAM_SUCCESS; struct pam_response* resp = NULL; struct UserDataS* userDatap = (struct UserDataS*) appdata_ptr; + unsigned int msg_len = 0; + unsigned int i = 0; const char* message = (*msg)->msg; + // make a copy we can strip + char * compare_message = m_strdup(message); + TRACE(("enter pamConvFunc")) if (num_msg != 1) { /* If you're getting here - Dropbear probably can't support your pam * modules. This whole file is a bit of a hack around lack of - * asynchronocity in PAM anyway */ + * asynchronocity in PAM anyway. */ dropbear_log(LOG_INFO, "pamConvFunc() called with >1 messages: not supported."); return PAM_CONV_ERR; } TRACE(("msg_style is %d", (*msg)->msg_style)) - if (message) { - TRACE(("message is '%s'", message)) + if (compare_message) { + TRACE(("message is '%s'", compare_message)) } else { TRACE(("null message")) } + + // Make the string lowercase. + msg_len = strlen(compare_message); + for (i = 0; i < msg_len; i++) { + compare_message[i] = tolower(compare_message[i]); + } + + // If the string ends with ": ", remove the space. + // ie "login: " vs "login:" + if (msg_len > 2 + && compare_message[msg_len-2] == ':' + && compare_message[msg_len-1] == ' ') { + compare_message[msg_len-1] = '\0'; + } + switch((*msg)->msg_style) { case PAM_PROMPT_ECHO_OFF: - if (strcmp(message, "Password:") != 0) { - TRACE(("PAM_PROMPT_ECHO_OFF: unrecognized prompt")) - rc = PAM_CONV_ERR; - break; + if (!(strcmp(compare_message, "password:") == 0)) { + // We don't recognise the prompt as asking for a password, + // so can't handle it. Add more above as required for + // different pam modules/implementations + dropbear_log(LOG_NOTICE, "PAM unknown prompt %s (no echo)", + compare_message); + rc = PAM_CONV_ERR; + break; } /* You have to read the PAM module-writers' docs (do we look like @@ -99,10 +123,13 @@ case PAM_PROMPT_ECHO_ON: - if ((strcmp(message, "login: " ) != 0) - && (strcmp(message, "login:" ) != 0) - && (strcmp(message, "Please enter username: " ) != 0)) { - TRACE(("PAM_PROMPT_ECHO_ON: unrecognized prompt")) + if (!((strcmp(compare_message, "login:" ) == 0) + || (strcmp(compare_message, "please enter username:") == 0))) { + // We don't recognise the prompt as asking for a username, + // so can't handle it. Add more above as required for + // different pam modules/implementations + dropbear_log(LOG_NOTICE, "PAM unknown prompt %s (with echo)", + compare_message); rc = PAM_CONV_ERR; break; } @@ -125,6 +152,7 @@ break; } + m_free(compare_message); TRACE(("leave pamConvFunc, rc %d", rc)) return rc;
--- a/svr-authpubkey.c Tue Sep 06 04:52:46 2005 +0000 +++ b/svr-authpubkey.c Tue Sep 06 04:57:14 2005 +0000 @@ -266,7 +266,6 @@ TRACE(("enter checkpubkeyperms")) - assert(ses.authstate.pw); if (ses.authstate.pw->pw_dir == NULL) { goto out; }
--- a/svr-chansession.c Tue Sep 06 04:52:46 2005 +0000 +++ b/svr-chansession.c Tue Sep 06 04:57:14 2005 +0000 @@ -148,8 +148,8 @@ static void send_msg_chansess_exitstatus(struct Channel * channel, struct ChanSess * chansess) { - assert(chansess->exit.exitpid != -1); - assert(chansess->exit.exitsignal == -1); + dropbear_assert(chansess->exit.exitpid != -1); + dropbear_assert(chansess->exit.exitsignal == -1); CHECKCLEARTOWRITE(); @@ -170,8 +170,8 @@ int i; char* signame = NULL; - assert(chansess->exit.exitpid != -1); - assert(chansess->exit.exitsignal > 0); + dropbear_assert(chansess->exit.exitpid != -1); + dropbear_assert(chansess->exit.exitsignal > 0); CHECKCLEARTOWRITE(); @@ -205,7 +205,7 @@ struct ChanSess *chansess; - assert(channel->typedata == NULL); + dropbear_assert(channel->typedata == NULL); chansess = (struct ChanSess*)m_malloc(sizeof(struct ChanSess)); chansess->cmd = NULL; @@ -279,7 +279,7 @@ /* clear child pid entries */ for (i = 0; i < svr_ses.childpidsize; i++) { if (svr_ses.childpids[i].chansess == chansess) { - assert(svr_ses.childpids[i].pid > 0); + dropbear_assert(svr_ses.childpids[i].pid > 0); TRACE(("closing pid %d", svr_ses.childpids[i].pid)) TRACE(("exitpid = %d", chansess->exit.exitpid)) svr_ses.childpids[i].pid = -1; @@ -313,7 +313,7 @@ } chansess = (struct ChanSess*)channel->typedata; - assert(chansess != NULL); + dropbear_assert(chansess != NULL); TRACE(("type is %s", type)) if (strcmp(type, "window-change") == 0) {