# HG changeset patch # User Matt Johnston # Date 1141099467 0 # Node ID 8438ff0cdb74bbb4afe441e90cc730d0be99e949 # Parent 3be7ae2e8dfaab2cd186a409accd0fbb43672642# Parent 02a80ce2ead454279cda14fdf492d9444a66d94c merge of 50848a51c2f9867bc10e81826190dbc326ea16b9 and 84e3597daa468534c4a34231ae8761f841a0f5ae diff -r 02a80ce2ead4 -r 8438ff0cdb74 auth.h --- a/auth.h Tue Feb 28 04:03:49 2006 +0000 +++ b/auth.h Tue Feb 28 04:04:27 2006 +0000 @@ -52,6 +52,7 @@ void cli_auth_password(); int cli_auth_pubkey(); void cli_auth_interactive(); +char* getpass_or_cancel(); #define MAX_USERNAME_LEN 25 /* arbitrary for the moment */ diff -r 02a80ce2ead4 -r 8438ff0cdb74 cli-auth.c --- a/cli-auth.c Tue Feb 28 04:03:49 2006 +0000 +++ b/cli-auth.c Tue Feb 28 04:04:27 2006 +0000 @@ -278,3 +278,18 @@ TRACE(("leave cli_auth_try")) } + +/* A helper for getpass() that exits if the user cancels. The returned + * password is statically allocated by getpass() */ +char* getpass_or_cancel() +{ + char* password = NULL; + + password = getpass("Password: "); + + /* 0x03 is a ctrl-c character in the buffer. */ + if (password == NULL || strchr(password, '\3') != NULL) { + dropbear_close("Interrupted."); + } + return password; +} diff -r 02a80ce2ead4 -r 8438ff0cdb74 cli-authinteract.c --- a/cli-authinteract.c Tue Feb 28 04:03:49 2006 +0000 +++ b/cli-authinteract.c Tue Feb 28 04:04:27 2006 +0000 @@ -115,7 +115,7 @@ echo = buf_getbool(ses.payload); if (!echo) { - unsigned char* p = getpass(prompt); + unsigned char* p = getpass_or_cancel(prompt); response = m_strdup(p); m_burn(p, strlen(p)); } else { diff -r 02a80ce2ead4 -r 8438ff0cdb74 cli-authpasswd.c --- a/cli-authpasswd.c Tue Feb 28 04:03:49 2006 +0000 +++ b/cli-authpasswd.c Tue Feb 28 04:04:27 2006 +0000 @@ -125,10 +125,7 @@ password = gui_getpass("Password: "); else #endif - password = getpass("Password: "); - - if (password == NULL) - return 0; + password = getpass_or_cancel("Password: "); buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); diff -r 02a80ce2ead4 -r 8438ff0cdb74 cli-session.c --- a/cli-session.c Tue Feb 28 04:03:49 2006 +0000 +++ b/cli-session.c Tue Feb 28 04:04:27 2006 +0000 @@ -76,12 +76,14 @@ void cli_session(int sock, char* remotehost) { + seedrandom(); + crypto_init(); + common_session_init(sock, remotehost); chaninitialise(cli_chantypes); - /* Set up cli_ses vars */ cli_session_init(); @@ -91,12 +93,8 @@ /* Exchange identification */ session_identification(); - seedrandom(); - send_msg_kexinit(); - /* XXX here we do stuff differently */ - session_loop(cli_sessionloop); /* Not reached */ diff -r 02a80ce2ead4 -r 8438ff0cdb74 common-channel.c --- a/common-channel.c Tue Feb 28 04:03:49 2006 +0000 +++ b/common-channel.c Tue Feb 28 04:04:27 2006 +0000 @@ -377,7 +377,7 @@ cbuf_incrread(cbuf, len); channel->recvdonelen += len; - if (fd == channel->writefd && len == maxlen && channel->recveof) { + if (fd == channel->writefd && cbuf_getused(cbuf) == 0 && channel->recveof) { /* Check if we're closing up */ closewritefd(channel); TRACE(("leave writechannel: recveof set")) diff -r 02a80ce2ead4 -r 8438ff0cdb74 random.c --- a/random.c Tue Feb 28 04:03:49 2006 +0000 +++ b/random.c Tue Feb 28 04:04:27 2006 +0000 @@ -30,8 +30,8 @@ static int donerandinit = 0; /* this is used to generate unique output from the same hashpool */ -static unsigned int counter = 0; -#define MAX_COUNTER 1000000/* the max value for the counter, so it won't loop */ +static uint32_t counter = 0; +#define MAX_COUNTER 1<<31 /* the max value for the counter, so it won't loop */ static unsigned char hashpool[SHA1_HASH_SIZE]; @@ -132,7 +132,8 @@ hash_state hs; - /* initialise so compilers will be happy about hashing it */ + /* initialise so that things won't warn about + * hashing an undefined buffer */ if (!donerandinit) { m_burn(hashpool, sizeof(hashpool)); } @@ -150,6 +151,30 @@ donerandinit = 1; } +/* hash the current random pool with some unique identifiers + * for this process and point-in-time. this is used to separate + * the random pools for fork()ed processes. */ +void reseedrandom() { + + pid_t pid; + struct timeval tv; + + if (!donerandinit) { + dropbear_exit("seedrandom not done"); + } + + pid = getpid(); + gettimeofday(&tv, NULL); + + hash_state hs; + unsigned char hash[SHA1_HASH_SIZE]; + sha1_init(&hs); + sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); + sha1_process(&hs, (void*)&pid, sizeof(pid)); + sha1_process(&hs, (void*)&tv, sizeof(tv)); + sha1_done(&hs, hashpool); +} + /* return len bytes of pseudo-random data */ void genrandom(unsigned char* buf, unsigned int len) { diff -r 02a80ce2ead4 -r 8438ff0cdb74 random.h --- a/random.h Tue Feb 28 04:03:49 2006 +0000 +++ b/random.h Tue Feb 28 04:04:27 2006 +0000 @@ -28,6 +28,7 @@ struct mp_int; void seedrandom(); +void reseedrandom(); void genrandom(unsigned char* buf, int len); void addrandom(unsigned char* buf, int len); void gen_random_mpint(mp_int *max, mp_int *rand); diff -r 02a80ce2ead4 -r 8438ff0cdb74 svr-chansession.c --- a/svr-chansession.c Tue Feb 28 04:03:49 2006 +0000 +++ b/svr-chansession.c Tue Feb 28 04:04:27 2006 +0000 @@ -845,7 +845,7 @@ svr_opts.hostkey = NULL; /* overwrite the prng state */ - seedrandom(); + reseedrandom(); #endif /* close file descriptors except stdin/stdout/stderr diff -r 02a80ce2ead4 -r 8438ff0cdb74 svr-main.c --- a/svr-main.c Tue Feb 28 04:03:49 2006 +0000 +++ b/svr-main.c Tue Feb 28 04:04:27 2006 +0000 @@ -83,7 +83,7 @@ int remoteaddrlen; char * addrstring = NULL; - /* Set up handlers, syslog */ + /* Set up handlers, syslog, seed random */ commonsetup(); remoteaddrlen = sizeof(remoteaddr); @@ -359,6 +359,8 @@ /* Now we can setup the hostkeys - needs to be after logging is on, * otherwise we might end up blatting error messages to the socket */ loadhostkeys(); + + seedrandom(); } /* Set up listening sockets for all the requested ports */ diff -r 02a80ce2ead4 -r 8438ff0cdb74 svr-runopts.c --- a/svr-runopts.c Tue Feb 28 04:03:49 2006 +0000 +++ b/svr-runopts.c Tue Feb 28 04:04:27 2006 +0000 @@ -105,8 +105,12 @@ svr_opts.inetdmode = 0; svr_opts.portcount = 0; svr_opts.hostkey = NULL; +#ifdef ENABLE_SVR_LOCALTCPFWD svr_opts.nolocaltcp = 0; +#endif +#ifdef ENABLE_SVR_REMOTETCPFWD svr_opts.noremotetcp = 0; +#endif /* not yet opts.ipv4 = 1; opts.ipv6 = 1; @@ -154,12 +158,12 @@ svr_opts.usingsyslog = 0; break; #endif -#ifndef DISABLE_LOCALTCPFWD +#ifdef ENABLE_SVR_LOCALTCPFWD case 'j': svr_opts.nolocaltcp = 1; break; #endif -#ifndef DISABLE_REMOTETCPFWD +#ifdef ENABLE_SVR_REMOTETCPFWD case 'k': svr_opts.noremotetcp = 1; break; diff -r 02a80ce2ead4 -r 8438ff0cdb74 svr-session.c --- a/svr-session.c Tue Feb 28 04:03:49 2006 +0000 +++ b/svr-session.c Tue Feb 28 04:04:27 2006 +0000 @@ -78,7 +78,9 @@ char* remotehost, char *addrstring) { struct timeval timeout; - + + reseedrandom(); + crypto_init(); common_session_init(sock, remotehost); @@ -110,8 +112,6 @@ /* exchange identification, version etc */ session_identification(); - seedrandom(); - /* start off with key exchange */ send_msg_kexinit(); diff -r 02a80ce2ead4 -r 8438ff0cdb74 svr-tcpfwd.c --- a/svr-tcpfwd.c Tue Feb 28 04:03:49 2006 +0000 +++ b/svr-tcpfwd.c Tue Feb 28 04:04:27 2006 +0000 @@ -80,7 +80,7 @@ reqname = buf_getstring(ses.payload, &namelen); wantreply = buf_getbool(ses.payload); - if (namelen > MAXNAMLEN) { + if (namelen > MAX_NAME_LEN) { TRACE(("name len is wrong: %d", namelen)) goto out; }