# HG changeset patch # User Matt Johnston # Date 1120829283 0 # Node ID 654bc83277871ac0bdd29b5ce6465df64736c48b # Parent 3ee0c2f85e1ea3b77b398f595d21a797eb767d55# Parent 29f8b18cf7944e1aed2f213cf1b9ea06263e744f merge of 9522146cb07d4576f161fc4567c2c2fbd6f61fbb and b11630c15bc4d0649dba51c3572cac6f44e0ab0e diff -r 3ee0c2f85e1e -r 654bc8327787 CHANGES --- a/CHANGES Fri Jul 08 13:27:28 2005 +0000 +++ b/CHANGES Fri Jul 08 13:28:03 2005 +0000 @@ -1,3 +1,24 @@ +0.46 + +- Fix long-standing bug which caused connections to be closed if an ssh-agent + socket was no longer available + +- print a warning if we seem to be blocking on /dev/random + (suggested by Paul Fox) + +- fixed a memory leak in DSS code (thanks to Boris Berezovsky for the patch) + +- dbclient -L no longer segfaults, allocate correct buffer size (thanks + to David Cook for reporting it) + +- added RSA blinding (recommended by Dan Kaminsky) + +- rearranged bignum reading/random generation code + +- Reset the non-blocking status on stderr and stdout as well as stdin, + fixes a problem where the shell running dbclient will exit (thanks to + Brent Roman for reporting it) + 0.45 - Mon March 7 2005 - Makefile no longer appends 'static' to statically linked binaries diff -r 3ee0c2f85e1e -r 654bc8327787 Makefile.in --- a/Makefile.in Fri Jul 08 13:27:28 2005 +0000 +++ b/Makefile.in Fri Jul 08 13:28:03 2005 +0000 @@ -69,7 +69,7 @@ RANLIB=@RANLIB@ STRIP=@STRIP@ INSTALL=@INSTALL@ -CFLAGS=-I. -I$(srcdir)/libtomcrypt @CFLAGS@ +CFLAGS=-I. -I$(srcdir)/libtomcrypt/src/headers/ @CFLAGS@ LIBS=$(LTC) $(LTM) @LIBS@ LDFLAGS=@LDFLAGS@ diff -r 3ee0c2f85e1e -r 654bc8327787 TODO --- a/TODO Fri Jul 08 13:27:28 2005 +0000 +++ b/TODO Fri Jul 08 13:28:03 2005 +0000 @@ -2,12 +2,12 @@ Things which might need doing: +- default private dbclient keys + - Make options.h generated from configure perhaps? - Improved queueing of unauthed connections -- fix agent fwd problems - - handle /etc/environment in AIX - check that there aren't timing issues with valid/invalid user authentication @@ -15,9 +15,9 @@ - Binding to different interfaces -- possible RSA blinding? need to check whether this is vuln to timing attacks - check PRNG -- CTR mode, SSH_MSG_IGNORE sending to improve CBC security +- CTR mode +- SSH_MSG_IGNORE sending to improve CBC security - DH Group Exchange possibly, or just add group14 (whatever it's called today) - fix scp.c for IRIX diff -r 3ee0c2f85e1e -r 654bc8327787 algo.h --- a/algo.h Fri Jul 08 13:27:28 2005 +0000 +++ b/algo.h Fri Jul 08 13:28:03 2005 +0000 @@ -51,13 +51,13 @@ extern const struct dropbear_hash dropbear_nohash; struct dropbear_cipher { - const struct _cipher_descriptor *cipherdesc; + const struct ltc_cipher_descriptor *cipherdesc; unsigned long keysize; unsigned char blocksize; }; struct dropbear_hash { - const struct _hash_descriptor *hashdesc; + const struct ltc_hash_descriptor *hashdesc; unsigned long keysize; unsigned char hashsize; }; diff -r 3ee0c2f85e1e -r 654bc8327787 auth.h --- a/auth.h Fri Jul 08 13:27:28 2005 +0000 +++ b/auth.h Fri Jul 08 13:28:03 2005 +0000 @@ -84,13 +84,13 @@ }; -struct PubkeyList; -/* A singly linked list of pubkeys */ -struct PubkeyList { +struct SignKeyList; +/* A singly linked list of signing keys */ +struct SignKeyList { sign_key *key; int type; /* The type of key */ - struct PubkeyList *next; + struct SignKeyList *next; /* filename? or the buffer? for encrypted keys, so we can later get * the private key portion */ diff -r 3ee0c2f85e1e -r 654bc8327787 bignum.c --- a/bignum.c Fri Jul 08 13:27:28 2005 +0000 +++ b/bignum.c Fri Jul 08 13:28:03 2005 +0000 @@ -52,9 +52,9 @@ va_end(args); } -void bytestomp(mp_int *mp, unsigned char* bytes, unsigned int len) { +void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len) { - if (mp_read_unsigned_bin(mp, bytes, len) != MP_OKAY) { + if (mp_read_unsigned_bin(mp, (unsigned char*)bytes, len) != MP_OKAY) { dropbear_exit("mem alloc error"); } } diff -r 3ee0c2f85e1e -r 654bc8327787 bignum.h --- a/bignum.h Fri Jul 08 13:27:28 2005 +0000 +++ b/bignum.h Fri Jul 08 13:28:03 2005 +0000 @@ -29,7 +29,7 @@ void m_mp_init(mp_int *mp); void m_mp_init_multi(mp_int *mp, ...); -void bytestomp(mp_int *mp, unsigned char* bytes, unsigned int len); +void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len); void sha1_process_mp(hash_state *hs, mp_int *mp); #endif /* _BIGNUM_H_ */ diff -r 3ee0c2f85e1e -r 654bc8327787 buffer.c --- a/buffer.c Fri Jul 08 13:27:28 2005 +0000 +++ b/buffer.c Fri Jul 08 13:28:03 2005 +0000 @@ -160,6 +160,16 @@ return buf->data[buf->pos++]; } +/* Get a bool from the buffer and increment the pos */ +unsigned char buf_getbool(buffer* buf) { + + unsigned char b; + b = buf_getbyte(buf); + if (b != 0) + b = 1; + return b; +} + /* put a byte, incrementing the length if required */ void buf_putbyte(buffer* buf, unsigned char val) { diff -r 3ee0c2f85e1e -r 654bc8327787 buffer.h --- a/buffer.h Fri Jul 08 13:27:28 2005 +0000 +++ b/buffer.h Fri Jul 08 13:28:03 2005 +0000 @@ -50,6 +50,7 @@ void buf_incrpos(buffer* buf, int incr); /* -ve is ok, to go backwards */ void buf_incrwritepos(buffer* buf, unsigned int incr); unsigned char buf_getbyte(buffer* buf); +unsigned char buf_getbool(buffer* buf); void buf_putbyte(buffer* buf, unsigned char val); unsigned char* buf_getptr(buffer* buf, unsigned int len); unsigned char* buf_getwriteptr(buffer* buf, unsigned int len); diff -r 3ee0c2f85e1e -r 654bc8327787 channel.h --- a/channel.h Fri Jul 08 13:27:28 2005 +0000 +++ b/channel.h Fri Jul 08 13:28:03 2005 +0000 @@ -100,7 +100,7 @@ void chancleanup(); void setchannelfds(fd_set *readfd, fd_set *writefd); void channelio(fd_set *readfd, fd_set *writefd); -struct Channel* getchannel(unsigned int chan); +struct Channel* getchannel(); struct Channel* newchannel(unsigned int remotechan, const struct ChanType *type, unsigned int transwindow, unsigned int transmaxpacket); diff -r 3ee0c2f85e1e -r 654bc8327787 cli-auth.c --- a/cli-auth.c Fri Jul 08 13:27:28 2005 +0000 +++ b/cli-auth.c Fri Jul 08 13:28:03 2005 +0000 @@ -127,7 +127,7 @@ methods = buf_getstring(ses.payload, &methlen); - partial = buf_getbyte(ses.payload); + partial = buf_getbool(ses.payload); if (partial) { dropbear_log(LOG_INFO, "Authentication partially succeeded, more attempts required"); diff -r 3ee0c2f85e1e -r 654bc8327787 cli-authpubkey.c --- a/cli-authpubkey.c Fri Jul 08 13:27:28 2005 +0000 +++ b/cli-authpubkey.c Fri Jul 08 13:28:03 2005 +0000 @@ -38,29 +38,29 @@ * We use it to remove the key we tried from the list */ void cli_pubkeyfail() { - struct PubkeyList *keyitem; - struct PubkeyList **previtem; + struct SignKeyList *keyitem; + struct SignKeyList **previtem; TRACE(("enter cli_pubkeyfail")) - previtem = &cli_opts.pubkeys; + previtem = &cli_opts.privkeys; /* Find the key we failed with, and remove it */ - for (keyitem = cli_opts.pubkeys; keyitem != NULL; keyitem = keyitem->next) { - if (keyitem == cli_ses.lastpubkey) { + for (keyitem = cli_opts.privkeys; keyitem != NULL; keyitem = keyitem->next) { + if (keyitem == cli_ses.lastprivkey) { *previtem = keyitem->next; } previtem = &keyitem; } - sign_key_free(cli_ses.lastpubkey->key); /* It won't be used again */ - m_free(cli_ses.lastpubkey); + sign_key_free(cli_ses.lastprivkey->key); /* It won't be used again */ + m_free(cli_ses.lastprivkey); TRACE(("leave cli_pubkeyfail")) } void recv_msg_userauth_pk_ok() { - struct PubkeyList *keyitem; + struct SignKeyList *keyitem; buffer* keybuf; char* algotype = NULL; unsigned int algolen; @@ -80,7 +80,7 @@ /* Iterate through our keys, find which one it was that matched, and * send a real request with that key */ - for (keyitem = cli_opts.pubkeys; keyitem != NULL; keyitem = keyitem->next) { + for (keyitem = cli_opts.privkeys; keyitem != NULL; keyitem = keyitem->next) { if (keyitem->type != keytype) { /* Types differed */ @@ -172,11 +172,11 @@ TRACE(("enter cli_auth_pubkey")) - if (cli_opts.pubkeys != NULL) { + if (cli_opts.privkeys != NULL) { /* Send a trial request */ - send_msg_userauth_pubkey(cli_opts.pubkeys->key, - cli_opts.pubkeys->type, 0); - cli_ses.lastpubkey = cli_opts.pubkeys; + send_msg_userauth_pubkey(cli_opts.privkeys->key, + cli_opts.privkeys->type, 0); + cli_ses.lastprivkey = cli_opts.privkeys; TRACE(("leave cli_auth_pubkey-success")) return 1; } else { diff -r 3ee0c2f85e1e -r 654bc8327787 cli-channel.c --- a/cli-channel.c Fri Jul 08 13:27:28 2005 +0000 +++ b/cli-channel.c Fri Jul 08 13:28:03 2005 +0000 @@ -33,15 +33,12 @@ /* We receive channel data - only used by the client chansession code*/ void recv_msg_channel_extended_data() { - unsigned int chan; struct Channel *channel; unsigned int datatype; TRACE(("enter recv_msg_channel_extended_data")) - chan = buf_getint(ses.payload); - channel = getchannel(chan); - + channel = getchannel(); if (channel == NULL) { dropbear_exit("Unknown channel"); } diff -r 3ee0c2f85e1e -r 654bc8327787 cli-chansession.c --- a/cli-chansession.c Fri Jul 08 13:27:28 2005 +0000 +++ b/cli-chansession.c Fri Jul 08 13:28:03 2005 +0000 @@ -62,7 +62,7 @@ TRACE(("enter cli_chansessreq")) type = buf_getstring(ses.payload, NULL); - wantreply = buf_getbyte(ses.payload); + wantreply = buf_getbool(ses.payload); if (strcmp(type, "exit-status") != 0) { TRACE(("unknown request '%s'", type)) diff -r 3ee0c2f85e1e -r 654bc8327787 cli-runopts.c --- a/cli-runopts.c Fri Jul 08 13:27:28 2005 +0000 +++ b/cli-runopts.c Fri Jul 08 13:28:03 2005 +0000 @@ -53,7 +53,7 @@ "-i (multiple allowed)\n" #endif #ifdef ENABLE_CLI_LOCALTCPFWD - "-L Local port forwarding\n" + "-L Local port forwarding\n" #endif #ifdef ENABLE_CLI_REMOTETCPFWD "-R Remote port forwarding\n" @@ -89,7 +89,7 @@ cli_opts.cmd = NULL; cli_opts.wantpty = 9; /* 9 means "it hasn't been touched", gets set later */ #ifdef ENABLE_CLI_PUBKEY_AUTH - cli_opts.pubkeys = NULL; + cli_opts.privkeys = NULL; #endif #ifdef ENABLE_CLI_LOCALTCPFWD cli_opts.localfwds = NULL; @@ -271,7 +271,7 @@ #ifdef ENABLE_CLI_PUBKEY_AUTH static void loadidentityfile(const char* filename) { - struct PubkeyList * nextkey; + struct SignKeyList * nextkey; sign_key *key; int keytype; @@ -284,11 +284,11 @@ } else { - nextkey = (struct PubkeyList*)m_malloc(sizeof(struct PubkeyList)); + nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList)); nextkey->key = key; - nextkey->next = cli_opts.pubkeys; + nextkey->next = cli_opts.privkeys; nextkey->type = keytype; - cli_opts.pubkeys = nextkey; + cli_opts.privkeys = nextkey; } } #endif diff -r 3ee0c2f85e1e -r 654bc8327787 cli-session.c --- a/cli-session.c Fri Jul 08 13:27:28 2005 +0000 +++ b/cli-session.c Fri Jul 08 13:28:03 2005 +0000 @@ -113,16 +113,20 @@ cli_ses.tty_raw_mode = 0; cli_ses.winchange = 0; - /* We store stdin's flags, so we can set them back on exit (otherwise - * busybox's ash isn't happy */ + /* We store std{in,out,err}'s flags, so we can set them back on exit + * (otherwise busybox's ash isn't happy */ cli_ses.stdincopy = dup(STDIN_FILENO); cli_ses.stdinflags = fcntl(STDIN_FILENO, F_GETFL, 0); + cli_ses.stdoutcopy = dup(STDOUT_FILENO); + cli_ses.stdoutflags = fcntl(STDOUT_FILENO, F_GETFL, 0); + cli_ses.stderrcopy = dup(STDERR_FILENO); + cli_ses.stderrflags = fcntl(STDERR_FILENO, F_GETFL, 0); cli_ses.retval = EXIT_SUCCESS; /* Assume it's clean if we don't get a specific exit status */ /* Auth */ - cli_ses.lastpubkey = NULL; + cli_ses.lastprivkey = NULL; cli_ses.lastauthtype = 0; /* For printing "remote host closed" for the user */ @@ -250,9 +254,11 @@ return; } - /* Set stdin back to non-blocking - busybox ash dies nastily - * if we don't revert the flags */ + /* Set std{in,out,err} back to non-blocking - busybox ash dies nastily if + * we don't revert the flags */ fcntl(cli_ses.stdincopy, F_SETFL, cli_ses.stdinflags); + fcntl(cli_ses.stdoutcopy, F_SETFL, cli_ses.stdoutflags); + fcntl(cli_ses.stderrcopy, F_SETFL, cli_ses.stderrflags); cli_tty_cleanup(); diff -r 3ee0c2f85e1e -r 654bc8327787 cli-tcpfwd.c --- a/cli-tcpfwd.c Fri Jul 08 13:27:28 2005 +0000 +++ b/cli-tcpfwd.c Fri Jul 08 13:28:03 2005 +0000 @@ -94,7 +94,7 @@ TRACE(("enter cli_localtcp: %d %s %d", listenport, remoteaddr, remoteport)); - tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener*)); + tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener)); tcpinfo->sendaddr = m_strdup(remoteaddr); tcpinfo->sendport = remoteport; tcpinfo->listenport = listenport; diff -r 3ee0c2f85e1e -r 654bc8327787 common-algo.c --- a/common-algo.c Fri Jul 08 13:27:28 2005 +0000 +++ b/common-algo.c Fri Jul 08 13:28:03 2005 +0000 @@ -125,7 +125,7 @@ * This should be run before using any of the ciphers/hashes */ void crypto_init() { - const struct _cipher_descriptor *regciphers[] = { + const struct ltc_cipher_descriptor *regciphers[] = { #ifdef DROPBEAR_AES128_CBC &aes_desc, #endif @@ -141,7 +141,7 @@ NULL }; - const struct _hash_descriptor *reghashes[] = { + const struct ltc_hash_descriptor *reghashes[] = { /* we need sha1 for hostkey stuff regardless */ &sha1_desc, #ifdef DROPBEAR_MD5_HMAC diff -r 3ee0c2f85e1e -r 654bc8327787 common-channel.c --- a/common-channel.c Fri Jul 08 13:27:28 2005 +0000 +++ b/common-channel.c Fri Jul 08 13:28:03 2005 +0000 @@ -162,8 +162,13 @@ return newchan; } -/* Get the channel structure corresponding to a channel number */ -struct Channel* getchannel(unsigned int chan) { +/* Returns the channel structure corresponding to the channel in the current + * data packet (ses.payload must be positioned appropriately) */ +struct Channel* getchannel() { + + unsigned int chan; + + chan = buf_getint(ses.payload); if (chan >= ses.chansize || ses.channels[chan] == NULL) { return NULL; } @@ -474,14 +479,11 @@ * etc) FD is also EOF */ void recv_msg_channel_eof() { - unsigned int chan; struct Channel * channel; TRACE(("enter recv_msg_channel_eof")) - chan = buf_getint(ses.payload); - channel = getchannel(chan); - + channel = getchannel(); if (channel == NULL) { dropbear_exit("EOF for unknown channel"); } @@ -500,15 +502,11 @@ /* Handle channel closure(), respond in kind and close the channels */ void recv_msg_channel_close() { - unsigned int chan; struct Channel * channel; TRACE(("enter recv_msg_channel_close")) - chan = buf_getint(ses.payload); - TRACE(("close channel = %d", chan)) - channel = getchannel(chan); - + channel = getchannel(); if (channel == NULL) { /* disconnect ? */ dropbear_exit("Close for unknown channel"); @@ -567,14 +565,11 @@ * such as chansession or x11fwd */ void recv_msg_channel_request() { - unsigned int chan; struct Channel *channel; TRACE(("enter recv_msg_channel_request")) - chan = buf_getint(ses.payload); - channel = getchannel(chan); - + channel = getchannel(); if (channel == NULL) { /* disconnect ? */ dropbear_exit("Unknown channel"); @@ -666,12 +661,9 @@ /* We receive channel data */ void recv_msg_channel_data() { - unsigned int chan; struct Channel *channel; - chan = buf_getint(ses.payload); - channel = getchannel(chan); - + channel = getchannel(); if (channel == NULL) { dropbear_exit("Unknown channel"); } @@ -738,13 +730,10 @@ * as data is sent, and incremented upon receiving window-adjust messages */ void recv_msg_channel_window_adjust() { - unsigned int chan; struct Channel * channel; unsigned int incr; - chan = buf_getint(ses.payload); - channel = getchannel(chan); - + channel = getchannel(); if (channel == NULL) { dropbear_exit("Unknown channel"); } @@ -961,14 +950,12 @@ * successful*/ void recv_msg_channel_open_confirmation() { - unsigned int chan; struct Channel * channel; int ret; TRACE(("enter recv_msg_channel_open_confirmation")) - chan = buf_getint(ses.payload); - channel = getchannel(chan); + channel = getchannel(); if (channel == NULL) { dropbear_exit("Unknown channel"); } @@ -977,7 +964,8 @@ channel->transwindow = buf_getint(ses.payload); channel->transmaxpacket = buf_getint(ses.payload); - TRACE(("new chan remote %d localho %d", channel->remotechan, chan)) + TRACE(("new chan remote %d local %d", + channel->remotechan, channel->index)) /* Run the inithandler callback */ if (channel->type->inithandler) { @@ -995,11 +983,9 @@ /* Notification that our channel open request failed */ void recv_msg_channel_open_failure() { - unsigned int chan; struct Channel * channel; - chan = buf_getbyte(ses.payload); - channel = getchannel(chan); + channel = getchannel(); if (channel == NULL) { dropbear_exit("Unknown channel"); } diff -r 3ee0c2f85e1e -r 654bc8327787 common-kex.c --- a/common-kex.c Fri Jul 08 13:27:28 2005 +0000 +++ b/common-kex.c Fri Jul 08 13:28:03 2005 +0000 @@ -457,7 +457,6 @@ /* the rest of ses.kexhashbuf will be done after DH exchange */ ses.kexstate.recvkexinit = 1; -// ses.expecting = 0; // client matt TRACE(("leave recv_msg_kexinit")) } @@ -470,18 +469,13 @@ DEF_MP_INT(dh_p); DEF_MP_INT(dh_q); DEF_MP_INT(dh_g); - unsigned char randbuf[DH_P_LEN]; - int dh_q_len; TRACE(("enter send_msg_kexdh_reply")) m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL); /* read the prime and generator*/ - if (mp_read_unsigned_bin(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN) - != MP_OKAY) { - dropbear_exit("Diffie-Hellman error"); - } + bytes_to_mp(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN); if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) { dropbear_exit("Diffie-Hellman error"); @@ -496,16 +490,8 @@ dropbear_exit("Diffie-Hellman error"); } - dh_q_len = mp_unsigned_bin_size(&dh_q); - - /* calculate our random value dh_y */ - do { - assert((unsigned int)dh_q_len <= sizeof(randbuf)); - genrandom(randbuf, dh_q_len); - if (mp_read_unsigned_bin(dh_priv, randbuf, dh_q_len) != MP_OKAY) { - dropbear_exit("Diffie-Hellman error"); - } - } while (mp_cmp(dh_priv, &dh_q) == MP_GT || mp_cmp_d(dh_priv, 0) != MP_GT); + /* Generate a private portion 0 < dh_priv < dh_q */ + gen_random_mpint(&dh_q, dh_priv); /* f = g^y mod p */ if (mp_exptmod(&dh_g, dh_priv, &dh_p, dh_pub) != MP_OKAY) { @@ -527,10 +513,7 @@ /* read the prime and generator*/ mp_init(&dh_p); - if (mp_read_unsigned_bin(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN) - != MP_OKAY) { - dropbear_exit("Diffie-Hellman error"); - } + bytes_to_mp(&dh_p, dh_p_val, DH_P_LEN); /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */ if (mp_cmp(dh_pub_them, &dh_p) != MP_LT @@ -683,7 +666,7 @@ buf_eatstring(ses.payload); /* first_kex_packet_follows */ - if (buf_getbyte(ses.payload)) { + if (buf_getbool(ses.payload)) { ses.kexstate.firstfollows = 1; /* if the guess wasn't good, we ignore the packet sent */ if (!allgood) { diff -r 3ee0c2f85e1e -r 654bc8327787 dbclient.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dbclient.1 Fri Jul 08 13:28:03 2005 +0000 @@ -0,0 +1,69 @@ +.TH dbclient 1 +.SH NAME +dbclient \- lightweight SSH2 client +.SH SYNOPSIS +.B dbclient +[\-Tt] [\-p +.I port\fR] [\-i +.I id\fR] [\-L +.I l\fR:\fIh\fR:\fIr\fR] [\-R +.I l\fR:\fIh\fR:\fIr\fR] [\-l +.IR user ] +.I host +.SH DESCRIPTION +.B dbclient +is a SSH 2 client designed to be small enough to be used in small memory +environments, while still being functional and secure enough for general use. +.SH OPTIONS +.TP +.B \-p \fIport +Remote port. +Connect to port +.I port +on the remote host. +Default is 22. +.TP +.B \-i \fIidfile +Identity file. +Read the identity from file +.I idfile +(multiple allowed). +.TP +.B \-L \fIlocalport\fR:\fIremotehost\fR:\fIremoteport\fR +Local port forwarding. +Forward the port +.I localport +on the local host to port +.I remoteport +on the remote host +.IR remotehost . +.TP +.B \-R \fIlocalport\fR:\fIremotehost\fR:\fIremoteport\fR +Remote port forwarding. +Forward the port +.I remoteport +on the remote host +.I remotehost +to port +.I localport +on the local host. +.TP +.B \-l \fIuser +Username. +Login as +.I user +on the remote host. +.TP +.B \-t +Allocate a pty. +.TP +.B \-T +Don't allocate a pty. +.SH AUTHOR +Matt Johnston (matt@ucc.asn.au). +.br +Gerrit Pape (pape@smarden.org) wrote this manual page. +.SH SEE ALSO +dropbear(8), dropbearkey(8) +.P +http://matt.ucc.asn.au/dropbear/dropbear.html diff -r 3ee0c2f85e1e -r 654bc8327787 dbutil.c --- a/dbutil.c Fri Jul 08 13:27:28 2005 +0000 +++ b/dbutil.c Fri Jul 08 13:28:03 2005 +0000 @@ -430,10 +430,11 @@ } #ifdef DEBUG_TRACE -void printhex(unsigned char* buf, int len) { +void printhex(const char * label, const unsigned char * buf, int len) { int i; + fprintf(stderr, "%s\n", label); for (i = 0; i < len; i++) { fprintf(stderr, "%02x", buf[i]); if (i % 16 == 15) { diff -r 3ee0c2f85e1e -r 654bc8327787 dbutil.h --- a/dbutil.h Fri Jul 08 13:27:28 2005 +0000 +++ b/dbutil.h Fri Jul 08 13:28:03 2005 +0000 @@ -41,7 +41,7 @@ void dropbear_log(int priority, const char* format, ...); #ifdef DEBUG_TRACE void dropbear_trace(const char* format, ...); -void printhex(unsigned char* buf, int len); +void printhex(const char * label, const unsigned char * buf, int len); extern int debug_trace; #endif char * stripcontrol(const char * text); diff -r 3ee0c2f85e1e -r 654bc8327787 debian/README.Debian.diet --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian/README.Debian.diet Fri Jul 08 13:28:03 2005 +0000 @@ -0,0 +1,15 @@ +Building with the diet libc +--------------------------- + +This package optionally can be built with the diet libc instead of the +glibc to provide small statically linked programs. The resulting package +has no dependency on any other package. + +To use the diet libc, make sure the latest versions of the dietlibc-dev +package is installed, and set DEB_BUILD_OPTIONS=diet in the environment +when building the package, e.g.: + + # apt-get install dietlibc-dev + $ DEB_BUILD_OPTIONS=diet fakeroot apt-get source -b dropbear + + -- Gerrit Pape , Sat, 17 Jul 2004 19:09:34 +0000 diff -r 3ee0c2f85e1e -r 654bc8327787 debian/changelog diff -r 3ee0c2f85e1e -r 654bc8327787 debian/dropbear.postinst diff -r 3ee0c2f85e1e -r 654bc8327787 debian/rules diff -r 3ee0c2f85e1e -r 654bc8327787 debug.h --- a/debug.h Fri Jul 08 13:27:28 2005 +0000 +++ b/debug.h Fri Jul 08 13:28:03 2005 +0000 @@ -39,7 +39,7 @@ * Caution: Don't use this in an unfriendly environment (ie unfirewalled), * since the printing may not sanitise strings etc. This will add a reasonable * amount to your executable size. */ - //#define DEBUG_TRACE +/*#define DEBUG_TRACE */ /* All functions writing to the cleartext payload buffer call * CHECKCLEARTOWRITE() before writing. This is only really useful if you're diff -r 3ee0c2f85e1e -r 654bc8327787 dropbear.8 --- a/dropbear.8 Fri Jul 08 13:27:28 2005 +0000 +++ b/dropbear.8 Fri Jul 08 13:28:03 2005 +0000 @@ -76,6 +76,6 @@ .br Gerrit Pape (pape@smarden.org) wrote this manual page. .SH SEE ALSO -dropbearkey(8) +dropbearkey(8), dbclient(1) .P http://matt.ucc.asn.au/dropbear/dropbear.html diff -r 3ee0c2f85e1e -r 654bc8327787 dropbearkey.8 --- a/dropbearkey.8 Fri Jul 08 13:27:28 2005 +0000 +++ b/dropbearkey.8 Fri Jul 08 13:28:03 2005 +0000 @@ -42,6 +42,6 @@ .br Gerrit Pape (pape@smarden.org) wrote this manual page. .SH SEE ALSO -dropbear(8) +dropbear(8), dbclient(1) .P http://matt.ucc.asn.au/dropbear/dropbear.html diff -r 3ee0c2f85e1e -r 654bc8327787 dss.c --- a/dss.c Fri Jul 08 13:27:28 2005 +0000 +++ b/dss.c Fri Jul 08 13:28:03 2005 +0000 @@ -190,10 +190,8 @@ /* create the signature - s' and r' are the received signatures in buf */ /* w = (s')-1 mod q */ /* let val1 = s' */ - if (mp_read_unsigned_bin(&val1, &string[SHA1_HASH_SIZE], SHA1_HASH_SIZE) - != MP_OKAY) { - goto out; - } + bytes_to_mp(&val1, &string[SHA1_HASH_SIZE], SHA1_HASH_SIZE); + if (mp_cmp(&val1, key->q) != MP_LT) { TRACE(("verify failed, s' >= q")) goto out; @@ -205,9 +203,8 @@ /* u1 = ((SHA(M')w) mod q */ /* let val1 = SHA(M') = msghash */ - if (mp_read_unsigned_bin(&val1, msghash, SHA1_HASH_SIZE) != MP_OKAY) { - goto out; - } + bytes_to_mp(&val1, msghash, SHA1_HASH_SIZE); + /* let val3 = u1 = ((SHA(M')w) mod q */ if (mp_mulmod(&val1, &val2, key->q, &val3) != MP_OKAY) { goto out; @@ -215,10 +212,7 @@ /* u2 = ((r')w) mod q */ /* let val1 = r' */ - if (mp_read_unsigned_bin(&val1, &string[0], SHA1_HASH_SIZE) - != MP_OKAY) { - goto out; - } + bytes_to_mp(&val1, &string[0], SHA1_HASH_SIZE); if (mp_cmp(&val1, key->q) != MP_LT) { TRACE(("verify failed, r' >= q")) goto out; @@ -261,6 +255,7 @@ } #endif /* DROPBEAR_SIGNKEY_VERIFY */ +#ifdef DSS_PROTOK /* convert an unsigned mp into an array of bytes, malloced. * This array must be freed after use, len contains the length of the array, * if len != NULL */ @@ -279,6 +274,7 @@ } return ret; } +#endif /* Sign the data presented with key, writing the signature contents * to the buffer @@ -304,8 +300,6 @@ unsigned char *privkeytmp; unsigned char proto_k[SHA512_HASH_SIZE]; DEF_MP_INT(dss_protok); -#else - unsigned char kbuf[SHA1_HASH_SIZE]; #endif DEF_MP_INT(dss_k); DEF_MP_INT(dss_m); @@ -343,22 +337,16 @@ /* generate k */ m_mp_init(&dss_protok); - bytestomp(&dss_protok, proto_k, SHA512_HASH_SIZE); + bytes_to_mp(&dss_protok, proto_k, SHA512_HASH_SIZE); mp_mod(&dss_protok, key->q, &dss_k); mp_clear(&dss_protok); m_burn(proto_k, SHA512_HASH_SIZE); #else /* DSS_PROTOK not defined*/ - do { - genrandom(kbuf, SHA1_HASH_SIZE); - if (mp_read_unsigned_bin(&dss_k, kbuf, SHA1_HASH_SIZE) != MP_OKAY) { - dropbear_exit("dss error"); - } - } while (mp_cmp(&dss_k, key->q) == MP_GT || mp_cmp_d(&dss_k, 0) != MP_GT); - m_burn(kbuf, SHA1_HASH_SIZE); + gen_random_mpint(key->q, &dss_k); #endif /* now generate the actual signature */ - bytestomp(&dss_m, msghash, SHA1_HASH_SIZE); + bytes_to_mp(&dss_m, msghash, SHA1_HASH_SIZE); /* g^k mod p */ if (mp_exptmod(key->g, &dss_k, key->p, &dss_temp1) != MP_OKAY) { @@ -417,7 +405,7 @@ mp_clear(&dss_s); buf_incrwritepos(buf, writelen); - mp_clear_multi(&dss_k, &dss_temp1, &dss_temp1, &dss_r, &dss_s, + mp_clear_multi(&dss_k, &dss_temp1, &dss_temp2, &dss_r, &dss_s, &dss_m, NULL); /* create the signature to return */ diff -r 3ee0c2f85e1e -r 654bc8327787 gendss.c --- a/gendss.c Fri Jul 08 13:27:28 2005 +0000 +++ b/gendss.c Fri Jul 08 13:28:03 2005 +0000 @@ -77,10 +77,7 @@ buf[0] |= 0x80; /* top bit high */ buf[QSIZE-1] |= 0x01; /* bottom bit high */ - if (mp_read_unsigned_bin(key->q, buf, QSIZE) != MP_OKAY) { - fprintf(stderr, "dss key generation failed\n"); - exit(1); - } + bytes_to_mp(key->q, buf, QSIZE); /* 18 rounds are required according to HAC */ if (mp_prime_next_prime(key->q, 18, 0) != MP_OKAY) { @@ -116,10 +113,7 @@ buf[0] |= 0x80; /* set the top bit high */ /* X is a random mp_int */ - if (mp_read_unsigned_bin(&tempX, buf, size) != MP_OKAY) { - fprintf(stderr, "dss key generation failed\n"); - exit(1); - } + bytes_to_mp(&tempX, buf, size); /* C = X mod 2q */ if (mp_mod(&tempX, &temp2q, &tempC) != MP_OKAY) { @@ -147,6 +141,7 @@ } while (!result); mp_clear_multi(&tempX, &tempC, &tempP, &temp2q, NULL); + m_burn(buf, size); m_free(buf); } @@ -189,22 +184,7 @@ static void getx(dss_key *key) { - DEF_MP_INT(val); - char buf[QSIZE]; - - m_mp_init(&val); - - do { - genrandom(buf, QSIZE); - - if (mp_read_unsigned_bin(&val, buf, QSIZE) != MP_OKAY) { - fprintf(stderr, "dss key generation failed\n"); - } - } while ((mp_cmp_d(&val, 1) == MP_GT) && (mp_cmp(&val, key->q) == MP_LT)); - - mp_copy(&val, key->x); - mp_clear(&val); - + gen_random_mpint(key->q, key->x); } static void gety(dss_key *key) { diff -r 3ee0c2f85e1e -r 654bc8327787 genrsa.c --- a/genrsa.c Fri Jul 08 13:27:28 2005 +0000 +++ b/genrsa.c Fri Jul 08 13:28:03 2005 +0000 @@ -108,10 +108,7 @@ genrandom(buf, size+1); buf[0] |= 0x80; /* MSB set */ - if (mp_read_unsigned_bin(prime, buf, size+1) != MP_OKAY) { - fprintf(stderr, "rsa generation failed\n"); - exit(1); - } + bytes_to_mp(prime, buf, size+1); /* find the next integer which is prime, 8 round of miller-rabin */ if (mp_prime_next_prime(prime, 8, 0) != MP_OKAY) { diff -r 3ee0c2f85e1e -r 654bc8327787 includes.h --- a/includes.h Fri Jul 08 13:27:28 2005 +0000 +++ b/includes.h Fri Jul 08 13:28:03 2005 +0000 @@ -111,7 +111,7 @@ #include #endif -#include "libtomcrypt/mycrypt.h" +#include "libtomcrypt/src/headers/tomcrypt.h" #include "libtommath/tommath.h" #include "compat.h" diff -r 3ee0c2f85e1e -r 654bc8327787 kex.h --- a/kex.h Fri Jul 08 13:27:28 2005 +0000 +++ b/kex.h Fri Jul 08 13:28:03 2005 +0000 @@ -37,10 +37,10 @@ void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, sign_key *hostkey); -void recv_msg_kexdh_init(); // server +void recv_msg_kexdh_init(); /* server */ -void send_msg_kexdh_init(); // client -void recv_msg_kexdh_reply(); // client +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 */ diff -r 3ee0c2f85e1e -r 654bc8327787 options.h --- a/options.h Fri Jul 08 13:27:28 2005 +0000 +++ b/options.h Fri Jul 08 13:28:03 2005 +0000 @@ -90,6 +90,11 @@ #define DROPBEAR_RSA #define DROPBEAR_DSS +/* RSA can be vulnerable to timing attacks which use the time required for + * signing to guess the private key. Blinding avoids this attack, though makes + * signing operations slightly slower. */ +#define RSA_BLINDING + /* Define DSS_PROTOK to use PuTTY's method of generating the value k for dss, * rather than just from the random byte source. Undefining this will save you * ~4k in binary size with static uclibc, but your DSS hostkey could be exposed @@ -313,14 +318,6 @@ #define DISABLE_AGENTFWD #endif -#ifndef ENABLE_LOCALTCPFWD -#define DISABLE_TCPDIRECT -#endif - -#ifndef ENABLE_REMOTETCPFWD -#define DISABLE_REMOTETCPFWD -#endif - #if defined(ENABLE_CLI_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD) #define ENABLE_CLI_ANYTCPFWD #endif @@ -329,7 +326,8 @@ #define DROPBEAR_TCP_ACCEPT #endif -#if defined(ENABLE_REMOTETCPFWD) || defined(ENABLE_LOCALTCPFWD) || \ +#if defined(ENABLE_CLI_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD) || \ + defined(ENABLE_SVR_REMOTETCPFWD) || defined(ENABLE_SVR_LOCALTCPFWD) || \ defined(ENABLE_AGENTFWD) || defined(ENABLE_X11FWD) #define USING_LISTENERS #endif diff -r 3ee0c2f85e1e -r 654bc8327787 packet.c --- a/packet.c Fri Jul 08 13:27:28 2005 +0000 +++ b/packet.c Fri Jul 08 13:28:03 2005 +0000 @@ -201,6 +201,7 @@ /* decrypt it */ if (cbc_decrypt(buf_getptr(ses.readbuf, blocksize), buf_getwriteptr(ses.decryptreadbuf,blocksize), + blocksize, &ses.keys->recv_symmetric_struct) != CRYPT_OK) { dropbear_exit("error decrypting"); } @@ -254,6 +255,7 @@ while (ses.readbuf->pos < ses.readbuf->len - macsize) { if (cbc_decrypt(buf_getptr(ses.readbuf, blocksize), buf_getwriteptr(ses.decryptreadbuf, blocksize), + blocksize, &ses.keys->recv_symmetric_struct) != CRYPT_OK) { dropbear_exit("error decrypting"); } @@ -491,6 +493,7 @@ while (clearwritebuf->pos < clearwritebuf->len) { if (cbc_encrypt(buf_getptr(clearwritebuf, blocksize), buf_getwriteptr(writebuf, blocksize), + blocksize, &ses.keys->trans_symmetric_struct) != CRYPT_OK) { dropbear_exit("error encrypting"); } diff -r 3ee0c2f85e1e -r 654bc8327787 random.c --- a/random.c Fri Jul 08 13:27:28 2005 +0000 +++ b/random.c Fri Jul 08 13:28:03 2005 +0000 @@ -25,14 +25,15 @@ #include "includes.h" #include "buffer.h" #include "dbutil.h" +#include "bignum.h" -int donerandinit = 0; +static int donerandinit = 0; /* this is used to generate unique output from the same hashpool */ -unsigned int counter = 0; +static unsigned int counter = 0; #define MAX_COUNTER 1000000/* the max value for the counter, so it won't loop */ -unsigned char hashpool[SHA1_HASH_SIZE]; +static unsigned char hashpool[SHA1_HASH_SIZE]; #define INIT_SEED_SIZE 32 /* 256 bits */ @@ -50,6 +51,7 @@ static void readrand(unsigned char* buf, unsigned int buflen) { + static int already_blocked = 0; int readfd; unsigned int readpos; int readlen; @@ -92,6 +94,24 @@ /* read the actual random data */ readpos = 0; do { + if (!already_blocked) + { + int ret; + struct timeval timeout; + fd_set read_fds; + + timeout.tv_sec = 2; /* two seconds should be enough */ + timeout.tv_usec = 0; + + FD_ZERO(&read_fds); + FD_SET(readfd, &read_fds); + ret = select(readfd + 1, &read_fds, NULL, NULL, &timeout); + if (ret == 0) + { + dropbear_log(LOG_INFO, "Warning: Reading the random source seems to have blocked.\nIf you experience problems, you probably need to find a better entropy source."); + already_blocked = 1; + } + } readlen = read(readfd, &buf[readpos], buflen - readpos); if (readlen <= 0) { if (readlen < 0 && errno == EINTR) { @@ -159,3 +179,38 @@ } m_burn(hash, sizeof(hash)); } + +/* Generates a random mp_int. + * max is a *mp_int specifying an upper bound. + * rand must be an initialised *mp_int for the result. + * the result rand satisfies: 0 < rand < max + * */ +void gen_random_mpint(mp_int *max, mp_int *rand) { + + unsigned char *randbuf = NULL; + unsigned int len = 0; + const char masks[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}; + + const int size_bits = mp_count_bits(max); + + len = size_bits / 8; + if ((size_bits % 8) != 0) { + len += 1; + } + + randbuf = (unsigned char*)m_malloc(len); + do { + genrandom(randbuf, len); + /* Mask out the unrequired bits - mp_read_unsigned_bin expects + * MSB first.*/ + randbuf[0] &= masks[size_bits % 8]; + + bytes_to_mp(rand, randbuf, len); + + /* keep regenerating until we get one satisfying + * 0 < rand < max */ + } while ( ( (max != NULL) && (mp_cmp(rand, max) != MP_LT) ) + || (mp_cmp_d(rand, 0) != MP_GT) ); + m_burn(randbuf, len); + m_free(randbuf); +} diff -r 3ee0c2f85e1e -r 654bc8327787 random.h --- a/random.h Fri Jul 08 13:27:28 2005 +0000 +++ b/random.h Fri Jul 08 13:28:03 2005 +0000 @@ -25,8 +25,11 @@ #ifndef _RANDOM_H_ #define _RANDOM_H_ +struct mp_int; + void seedrandom(); void genrandom(unsigned char* buf, int len); void addrandom(unsigned char* buf, int len); +void gen_random_mpint(mp_int *max, mp_int *rand); #endif /* _RANDOM_H_ */ diff -r 3ee0c2f85e1e -r 654bc8327787 rsa.c --- a/rsa.c Fri Jul 08 13:27:28 2005 +0000 +++ b/rsa.c Fri Jul 08 13:28:03 2005 +0000 @@ -38,8 +38,9 @@ #ifdef DROPBEAR_RSA -static mp_int * rsa_pad_em(rsa_key * key, - const unsigned char * data, unsigned int len); +static void rsa_pad_em(rsa_key * key, + const unsigned char * data, unsigned int len, + mp_int * rsa_em); /* Load a public rsa key from a buffer, initialising the values. * The key will have the same format as buf_put_rsa_key. @@ -203,14 +204,14 @@ unsigned int slen; DEF_MP_INT(rsa_s); DEF_MP_INT(rsa_mdash); - mp_int *rsa_em = NULL; + DEF_MP_INT(rsa_em); int ret = DROPBEAR_FAILURE; TRACE(("enter buf_rsa_verify")) assert(key != NULL); - m_mp_init_multi(&rsa_mdash, &rsa_s, NULL); + m_mp_init_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL); slen = buf_getint(buf); if (slen != (unsigned int)mp_unsigned_bin_size(key->n)) { @@ -231,29 +232,25 @@ } /* create the magic PKCS padded value */ - rsa_em = rsa_pad_em(key, data, len); + rsa_pad_em(key, data, len, &rsa_em); if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) { TRACE(("failed exptmod rsa_s")) goto out; } - if (mp_cmp(rsa_em, &rsa_mdash) == MP_EQ) { + if (mp_cmp(&rsa_em, &rsa_mdash) == MP_EQ) { /* signature is valid */ TRACE(("success!")) ret = DROPBEAR_SUCCESS; } out: - if (rsa_em) { - mp_clear(rsa_em); - m_free(rsa_em); - } - mp_clear_multi(&rsa_mdash, &rsa_s, NULL); + mp_clear_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL); TRACE(("leave buf_rsa_verify: ret %d", ret)) return ret; +} -} #endif /* DROPBEAR_SIGNKEY_VERIFY */ /* Sign the data presented with key, writing the signature contents @@ -264,22 +261,55 @@ unsigned int nsize, ssize; unsigned int i; DEF_MP_INT(rsa_s); - mp_int *rsa_em = NULL; + DEF_MP_INT(rsa_tmp1); + DEF_MP_INT(rsa_tmp2); + DEF_MP_INT(rsa_tmp3); + unsigned char *tmpbuf; TRACE(("enter buf_put_rsa_sign")) assert(key != NULL); - rsa_em = rsa_pad_em(key, data, len); + m_mp_init_multi(&rsa_s, &rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL); - m_mp_init(&rsa_s); + rsa_pad_em(key, data, len, &rsa_tmp1); /* the actual signing of the padded data */ + +#ifdef RSA_BLINDING + + /* With blinding, s = (r^(-1))((em)*r^e)^d mod n */ + + /* generate the r blinding value */ + /* rsa_tmp2 is r */ + gen_random_mpint(key->n, &rsa_tmp2); + + /* rsa_tmp1 is em */ + /* em' = em * r^e mod n */ + + mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s); /* rsa_s used as a temp var*/ + mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3); + mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2); + + /* rsa_tmp2 is em' */ + /* s' = (em')^d mod n */ + mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1); + + /* rsa_tmp1 is s' */ + /* rsa_tmp3 is r^(-1) mod n */ + /* s = (s')r^(-1) mod n */ + mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s); + +#else + /* s = em^d mod n */ - if (mp_exptmod(rsa_em, key->d, key->n, &rsa_s) != MP_OKAY) { + /* rsa_tmp1 is em */ + if (mp_exptmod(&rsa_tmp1, key->d, key->n, &rsa_s) != MP_OKAY) { dropbear_exit("rsa error"); } - mp_clear(rsa_em); - m_free(rsa_em); + +#endif /* RSA_BLINDING */ + + mp_clear_multi(&rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL); /* create the signature to return */ buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN); @@ -302,7 +332,7 @@ mp_clear(&rsa_s); #if defined(DEBUG_RSA) && defined(DEBUG_TRACE) - printhex(buf->data, buf->len); + printhex("RSA sig", buf->data, buf->len); #endif @@ -318,19 +348,22 @@ * * prefix is the ASN1 designator prefix, * hex 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 + * + * rsa_em must be a pointer to an initialised mp_int. */ -static mp_int * rsa_pad_em(rsa_key * key, - const unsigned char * data, unsigned int len) { +static void rsa_pad_em(rsa_key * key, + const unsigned char * data, unsigned int len, + mp_int * rsa_em) { /* ASN1 designator (including the 0x00 preceding) */ - const char rsa_asn1_magic[] = + const unsigned char rsa_asn1_magic[] = {0x00, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}; -#define RSA_ASN1_MAGIC_LEN 16 + const unsigned int RSA_ASN1_MAGIC_LEN = 16; + buffer * rsa_EM = NULL; hash_state hs; unsigned int nsize; - mp_int * rsa_em = NULL; assert(key != NULL); assert(data != NULL); @@ -358,16 +391,9 @@ /* Create the mp_int from the encoded bytes */ buf_setpos(rsa_EM, 0); - rsa_em = (mp_int*)m_malloc(sizeof(mp_int)); - m_mp_init(rsa_em); - if (mp_read_unsigned_bin(rsa_em, buf_getptr(rsa_EM, rsa_EM->size), - rsa_EM->size) != MP_OKAY) { - dropbear_exit("rsa error"); - } + bytes_to_mp(rsa_em, buf_getptr(rsa_EM, rsa_EM->size), + rsa_EM->size); buf_free(rsa_EM); - - return rsa_em; - } #endif /* DROPBEAR_RSA */ diff -r 3ee0c2f85e1e -r 654bc8327787 runopts.h --- a/runopts.h Fri Jul 08 13:27:28 2005 +0000 +++ b/runopts.h Fri Jul 08 13:28:03 2005 +0000 @@ -95,7 +95,7 @@ char *cmd; int wantpty; #ifdef ENABLE_CLI_PUBKEY_AUTH - struct PubkeyList *pubkeys; /* Keys to use for public-key auth */ + struct SignKeyList *privkeys; /* Keys to use for public-key auth */ #endif #ifdef ENABLE_CLI_REMOTETCPFWD struct TCPFwdList * remotefwds; diff -r 3ee0c2f85e1e -r 654bc8327787 scp.c --- a/scp.c Fri Jul 08 13:27:28 2005 +0000 +++ b/scp.c Fri Jul 08 13:28:03 2005 +0000 @@ -244,9 +244,6 @@ extern char *optarg; extern int optind; - /* hack, seems to work */ -// __progname = argv[0]; - args.list = NULL; addargs(&args, "ssh"); /* overwritten with ssh_program */ addargs(&args, "-x"); diff -r 3ee0c2f85e1e -r 654bc8327787 session.h --- a/session.h Fri Jul 08 13:27:28 2005 +0000 +++ b/session.h Fri Jul 08 13:28:03 2005 +0000 @@ -211,19 +211,22 @@ mp_int *dh_e, *dh_x; /* Used during KEX */ cli_kex_state kex_state; /* Used for progressing KEX */ cli_state state; /* Used to progress auth/channelsession etc */ - int something; /* XXX */ unsigned donefirstkex : 1; /* Set when we set sentnewkeys, never reset */ int tty_raw_mode; /* Whether we're in raw mode (and have to clean up) */ struct termios saved_tio; int stdincopy; int stdinflags; + int stdoutcopy; + int stdoutflags; + int stderrcopy; + int stderrflags; int winchange; /* Set to 1 when a windowchange signal happens */ int lastauthtype; /* either AUTH_TYPE_PUBKEY or AUTH_TYPE_PASSWORD, for the last type of auth we tried */ - struct PubkeyList *lastpubkey; + struct SignKeyList *lastprivkey; int retval; /* What the command exit status was - we emulate it */ #if 0 diff -r 3ee0c2f85e1e -r 654bc8327787 signkey.c --- a/signkey.c Fri Jul 08 13:27:28 2005 +0000 +++ b/signkey.c Fri Jul 08 13:28:03 2005 +0000 @@ -279,7 +279,7 @@ char * ret; hash_state hs; unsigned char hash[MD5_HASH_SIZE]; - unsigned int h, i; + unsigned int i; unsigned int buflen; md5_init(&hs); @@ -296,10 +296,11 @@ memset(ret, 'Z', buflen); strcpy(ret, "md5 "); - for (i = 4, h = 0; i < buflen; i+=3, h++) { - ret[i] = hexdig(hash[h] >> 4); - ret[i+1] = hexdig(hash[h] & 0x0f); - ret[i+2] = ':'; + for (i = 0; i < MD5_HASH_SIZE; i++) { + unsigned int pos = 4 + i*3; + ret[pos] = hexdig(hash[i] >> 4); + ret[pos+1] = hexdig(hash[i] & 0x0f); + ret[pos+2] = ':'; } ret[buflen-1] = 0x0; @@ -313,7 +314,7 @@ char * ret; hash_state hs; unsigned char hash[SHA1_HASH_SIZE]; - unsigned int h, i; + unsigned int i; unsigned int buflen; sha1_init(&hs); @@ -329,10 +330,11 @@ strcpy(ret, "sha1 "); - for (i = 5, h = 0; i < buflen; i+=3, h++) { - ret[i] = hexdig(hash[h] >> 4); - ret[i+1] = hexdig(hash[h] & 0x0f); - ret[i+2] = ':'; + for (i = 0; i < SHA1_HASH_SIZE; i++) { + unsigned int pos = 5 + 3*i; + ret[pos] = hexdig(hash[i] >> 4); + ret[pos+1] = hexdig(hash[i] & 0x0f); + ret[pos+2] = ':'; } ret[buflen-1] = 0x0; diff -r 3ee0c2f85e1e -r 654bc8327787 svr-authpam.c --- a/svr-authpam.c Fri Jul 08 13:27:28 2005 +0000 +++ b/svr-authpam.c Fri Jul 08 13:28:03 2005 +0000 @@ -155,7 +155,7 @@ unsigned char changepw; /* check if client wants to change password */ - changepw = buf_getbyte(ses.payload); + changepw = buf_getbool(ses.payload); if (changepw) { /* not implemented by this server */ send_msg_userauth_failure(0, 1); diff -r 3ee0c2f85e1e -r 654bc8327787 svr-authpasswd.c --- a/svr-authpasswd.c Fri Jul 08 13:27:28 2005 +0000 +++ b/svr-authpasswd.c Fri Jul 08 13:28:03 2005 +0000 @@ -71,7 +71,7 @@ } /* check if client wants to change password */ - changepw = buf_getbyte(ses.payload); + changepw = buf_getbool(ses.payload); if (changepw) { /* not implemented by this server */ send_msg_userauth_failure(0, 1); diff -r 3ee0c2f85e1e -r 654bc8327787 svr-authpubkey.c --- a/svr-authpubkey.c Fri Jul 08 13:27:28 2005 +0000 +++ b/svr-authpubkey.c Fri Jul 08 13:28:03 2005 +0000 @@ -64,7 +64,7 @@ /* 0 indicates user just wants to check if key can be used, 1 is an * actual attempt*/ - testkey = (buf_getbyte(ses.payload) == 0); + testkey = (buf_getbool(ses.payload) == 0); algo = buf_getstring(ses.payload, &algolen); keybloblen = buf_getint(ses.payload); diff -r 3ee0c2f85e1e -r 654bc8327787 svr-chansession.c --- a/svr-chansession.c Fri Jul 08 13:27:28 2005 +0000 +++ b/svr-chansession.c Fri Jul 08 13:28:03 2005 +0000 @@ -305,7 +305,7 @@ TRACE(("enter chansessionrequest")) type = buf_getstring(ses.payload, &typelen); - wantreply = buf_getbyte(ses.payload); + wantreply = buf_getbool(ses.payload); if (typelen > MAX_NAME_LEN) { TRACE(("leave chansessionrequest: type too long")) /* XXX send error?*/ @@ -837,7 +837,7 @@ /* close file descriptors except stdin/stdout/stderr * Need to be sure FDs are closed here to avoid reading files as root */ - for (i = 3; i < (unsigned int)ses.maxfd; i++) { + for (i = 3; i <= (unsigned int)ses.maxfd; i++) { if (m_close(i) == DROPBEAR_FAILURE) { dropbear_exit("Error closing file desc"); } @@ -862,8 +862,10 @@ if ((setgid(ses.authstate.pw->pw_gid) < 0) || (initgroups(ses.authstate.pw->pw_name, - ses.authstate.pw->pw_gid) < 0) || - (setuid(ses.authstate.pw->pw_uid) < 0)) { + ses.authstate.pw->pw_gid) < 0)) { + dropbear_exit("error changing user group"); + } + if (setuid(ses.authstate.pw->pw_uid) < 0) { dropbear_exit("error changing user"); } } else { diff -r 3ee0c2f85e1e -r 654bc8327787 svr-tcpfwd.c --- a/svr-tcpfwd.c Fri Jul 08 13:27:28 2005 +0000 +++ b/svr-tcpfwd.c Fri Jul 08 13:28:03 2005 +0000 @@ -78,7 +78,7 @@ } reqname = buf_getstring(ses.payload, &namelen); - wantreply = buf_getbyte(ses.payload); + wantreply = buf_getbool(ses.payload); if (namelen > MAXNAMLEN) { TRACE(("name len is wrong: %d", namelen)) diff -r 3ee0c2f85e1e -r 654bc8327787 svr-x11fwd.c --- a/svr-x11fwd.c Fri Jul 08 13:27:28 2005 +0000 +++ b/svr-x11fwd.c Fri Jul 08 13:28:03 2005 +0000 @@ -52,7 +52,7 @@ return DROPBEAR_FAILURE; } - chansess->x11singleconn = buf_getbyte(ses.payload); + chansess->x11singleconn = buf_getbool(ses.payload); chansess->x11authprot = buf_getstring(ses.payload, NULL); chansess->x11authcookie = buf_getstring(ses.payload, NULL); chansess->x11screennum = buf_getint(ses.payload);