# HG changeset patch # User Matt Johnston # Date 1438953963 -28800 # Node ID 624fc24cfae5fa6642855c0c25097128c2434960 # Parent d41c7b967868871040cd1decfccba442d2edf60b# Parent 924ff1b959a2de9ed40dfb6f2546d3309ed027b1 merge diff -r d41c7b967868 -r 624fc24cfae5 .travis.yml --- a/.travis.yml Tue Jun 23 21:49:04 2015 +0800 +++ b/.travis.yml Fri Aug 07 21:26:03 2015 +0800 @@ -3,7 +3,7 @@ - gcc script: - - autoconf && autoheader && ./configure $BUNDLEDLIBTOM CFLAGS="-O2 -Wall -Wno-pointer-sign" --prefix=$HOME/inst + - autoconf && autoheader && ./configure $BUNDLEDLIBTOM CFLAGS="-O2 -Wall -Wno-pointer-sign $WEXTRAFLAGS" --prefix=$HOME/inst - test "$NOWRITEV" && sed -i s/HAVE_WRITEV/DONT_HAVE_WRITEV/ config.h || true - make install - ~/inst/bin/dropbearkey -t rsa -f testrsa diff -r d41c7b967868 -r 624fc24cfae5 CHANGES --- a/CHANGES Tue Jun 23 21:49:04 2015 +0800 +++ b/CHANGES Fri Aug 07 21:26:03 2015 +0800 @@ -8,7 +8,7 @@ with networks and systems. - Forwarded TCP ports connect asynchronously and retry with other available - addresses (IPv4 or IPv6, round robin IPs) + addresses (IPv4 versus IPv6, round robin IPs) - Free memory before exiting, patch from Thorsten Horstmann. Useful for Dropbear ports to embedded systems and for checking memory leaks @@ -22,10 +22,17 @@ - Fix small ECC memory leaks - Tighten validation of Diffie-Hellman parameters, from Florent Daigniere of - Matt Consulting. Odds of bad values are around 2**-512 -- improbable. + Matta Consulting. Odds of bad values are around 2**-512 -- improbable. - Twofish-ctr cipher is supported though disabled by default +- Fix pre-authentication timeout when waiting for client SSH-2.0 banner, thanks + to CL Ouyang + +- Increase maximum command size to 9000 bytes + +- DROPBEAR_DEFAULT_CLI_AUTHKEY setting now always prepends home directory unless + there is a leading slash (~ isn't treated specially) 2015.67 - Wednesday 28 January 2015 diff -r d41c7b967868 -r 624fc24cfae5 cli-runopts.c --- a/cli-runopts.c Tue Jun 23 21:49:04 2015 +0800 +++ b/cli-runopts.c Fri Aug 07 21:26:03 2015 +0800 @@ -449,7 +449,7 @@ #if defined(DROPBEAR_DEFAULT_CLI_AUTHKEY) && defined(ENABLE_CLI_PUBKEY_AUTH) { - char *expand_path = expand_tilde(DROPBEAR_DEFAULT_CLI_AUTHKEY); + char *expand_path = expand_homedir_path(DROPBEAR_DEFAULT_CLI_AUTHKEY); loadidentityfile(expand_path, 0); m_free(expand_path); } diff -r d41c7b967868 -r 624fc24cfae5 common-session.c --- a/common-session.c Tue Jun 23 21:49:04 2015 +0800 +++ b/common-session.c Fri Aug 07 21:26:03 2015 +0800 @@ -76,6 +76,7 @@ update_channel_prio(); now = monotonic_now(); + ses.connect_time = now; ses.last_packet_time_keepalive_recv = now; ses.last_packet_time_idle = now; ses.last_packet_time_any_sent = 0; @@ -486,6 +487,11 @@ time_t now; now = monotonic_now(); + if (IS_DROPBEAR_SERVER && ses.connect_time != 0 + && now - ses.connect_time >= AUTH_TIMEOUT) { + dropbear_close("Timeout before auth"); + } + /* we can't rekey if we haven't done remote ident exchange yet */ if (ses.remoteident == NULL) { return; @@ -526,20 +532,39 @@ } } +static void update_timeout(long limit, long now, long last_event, long * timeout) { + TRACE2(("update_timeout limit %ld, now %ld, last %ld, timeout %ld", + limit, now, last_event, *timeout)) + if (last_event > 0 && limit > 0) { + *timeout = MIN(*timeout, last_event+limit-now); + TRACE2(("new timeout %ld", *timeout)) + } +} + static long select_timeout() { /* determine the minimum timeout that might be required, so as to avoid waking when unneccessary */ - long ret = LONG_MAX; - if (KEX_REKEY_TIMEOUT > 0) - ret = MIN(KEX_REKEY_TIMEOUT, ret); - /* AUTH_TIMEOUT is only relevant before authdone */ - if (ses.authstate.authdone != 1 && AUTH_TIMEOUT > 0) - ret = MIN(AUTH_TIMEOUT, ret); - if (opts.keepalive_secs > 0) - ret = MIN(opts.keepalive_secs, ret); - if (opts.idle_timeout_secs > 0) - ret = MIN(opts.idle_timeout_secs, ret); - return ret; + long timeout = LONG_MAX; + long now = monotonic_now(); + + update_timeout(KEX_REKEY_TIMEOUT, now, ses.kexstate.lastkextime, &timeout); + + if (ses.authstate.authdone != 1 && IS_DROPBEAR_SERVER) { + /* AUTH_TIMEOUT is only relevant before authdone */ + update_timeout(AUTH_TIMEOUT, now, ses.connect_time, &timeout); + } + + if (ses.authstate.authdone) { + update_timeout(opts.keepalive_secs, now, + MAX(ses.last_packet_time_keepalive_recv, ses.last_packet_time_keepalive_sent), + &timeout); + } + + update_timeout(opts.idle_timeout_secs, now, ses.last_packet_time_idle, + &timeout); + + /* clamp negative timeouts to zero - event has already triggered */ + return MAX(timeout, 0); } const char* get_user_shell() { diff -r d41c7b967868 -r 624fc24cfae5 dbutil.c --- a/dbutil.c Tue Jun 23 21:49:04 2015 +0800 +++ b/dbutil.c Fri Aug 07 21:26:03 2015 +0800 @@ -613,15 +613,16 @@ } } -/* Returns malloced path. Only expands ~ in first character */ -char * expand_tilde(const char *inpath) { +/* Returns malloced path. inpath beginning with '/' is returned as-is, +otherwise home directory is prepended */ +char * expand_homedir_path(const char *inpath) { struct passwd *pw = NULL; - if (inpath[0] == '~') { + if (inpath[0] != '/') { pw = getpwuid(getuid()); if (pw && pw->pw_dir) { - int len = strlen(inpath) + strlen(pw->pw_dir) + 1; + int len = strlen(inpath) + strlen(pw->pw_dir) + 2; char *buf = m_malloc(len); - snprintf(buf, len, "%s/%s", pw->pw_dir, &inpath[1]); + snprintf(buf, len, "%s/%s", pw->pw_dir, inpath); return buf; } } diff -r d41c7b967868 -r 624fc24cfae5 dbutil.h --- a/dbutil.h Tue Jun 23 21:49:04 2015 +0800 +++ b/dbutil.h Fri Aug 07 21:26:03 2015 +0800 @@ -78,7 +78,7 @@ void * m_malloc(size_t size); void * m_strdup(const char * str); void * m_realloc(void* ptr, size_t size); -#define m_free(X) do {free(X); (X) = NULL;} while (0); +#define m_free(X) do {free(X); (X) = NULL;} while (0) void m_burn(void* data, unsigned int len); void setnonblocking(int fd); void disallow_core(); @@ -97,6 +97,6 @@ a real-world clock */ time_t monotonic_now(); -char * expand_tilde(const char *inpath); +char * expand_homedir_path(const char *inpath); #endif /* DROPBEAR_DBUTIL_H_ */ diff -r d41c7b967868 -r 624fc24cfae5 netio.c --- a/netio.c Tue Jun 23 21:49:04 2015 +0800 +++ b/netio.c Fri Aug 07 21:26:03 2015 +0800 @@ -21,23 +21,6 @@ char* errstring; }; -#if defined(__linux__) && defined(TCP_DEFER_ACCEPT) -static void set_piggyback_ack(int sock) { - /* Undocumented Linux feature - set TCP_DEFER_ACCEPT and data will be piggybacked - on the 3rd packet (ack) of the TCP handshake. Saves a IP packet. - http://thread.gmane.org/gmane.linux.network/224627/focus=224727 - "Piggyback the final ACK of the three way TCP connection establishment with the data" */ - int val = 1; - /* No error checking, this is opportunistic */ - int err = setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, (void*)&val, sizeof(val)); - if (err) - { - TRACE(("Failed setsockopt TCP_DEFER_ACCEPT: %s", strerror(errno))) - } -} -#endif - - /* Deallocate a progress connection. Removes from the pending list if iter!=NULL. Does not close sockets */ static void remove_connect(struct dropbear_progress_connection *c, m_list_elem *iter) { @@ -87,10 +70,6 @@ set_sock_nodelay(c->sock); setnonblocking(c->sock); -#if defined(__linux__) && defined(TCP_DEFER_ACCEPT) - set_piggyback_ack(c->sock); -#endif - #ifdef DROPBEAR_CLIENT_TCP_FAST_OPEN fastopen = (c->writequeue != NULL); diff -r d41c7b967868 -r 624fc24cfae5 options.h --- a/options.h Tue Jun 23 21:49:04 2015 +0800 +++ b/options.h Fri Aug 07 21:26:03 2015 +0800 @@ -222,8 +222,8 @@ #define ENABLE_CLI_INTERACT_AUTH /* A default argument for dbclient -i . - leading "~" is expanded */ -#define DROPBEAR_DEFAULT_CLI_AUTHKEY "~/.ssh/id_dropbear" +Homedir is prepended unless path begins with / */ +#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 diff -r d41c7b967868 -r 624fc24cfae5 release.sh --- a/release.sh Tue Jun 23 21:49:04 2015 +0800 +++ b/release.sh Fri Aug 07 21:26:03 2015 +0800 @@ -33,7 +33,9 @@ rm -r "$RELDIR/autom4te.cache" || exit 2 -(cd $RELDIR/.. && tar cjf $ARCHIVE `basename "$RELDIR"`) || exit 2 +rm "$RELDIR/.hgtags" + +(cd "$RELDIR/.." && tar cjf $ARCHIVE `basename "$RELDIR"`) || exit 2 ls -l $ARCHIVE openssl sha -sha256 $ARCHIVE diff -r d41c7b967868 -r 624fc24cfae5 session.h --- a/session.h Tue Jun 23 21:49:04 2015 +0800 +++ b/session.h Fri Aug 07 21:26:03 2015 +0800 @@ -109,6 +109,11 @@ /* Is it a client or server? */ unsigned char isserver; + time_t connect_time; /* time the connection was established + (cleared after auth once we're not + respecting AUTH_TIMEOUT any more). + A monotonic time, not realworld */ + int sock_in; int sock_out; @@ -231,11 +236,6 @@ /* The resolved remote address, used for lastlog etc */ char *remotehost; - time_t connect_time; /* time the connection was established - (cleared after auth once we're not - respecting AUTH_TIMEOUT any more). - A monotonic time, not realworld */ - #ifdef USE_VFORK pid_t server_pid; #endif diff -r d41c7b967868 -r 624fc24cfae5 svr-auth.c --- a/svr-auth.c Tue Jun 23 21:49:04 2015 +0800 +++ b/svr-auth.c Fri Aug 07 21:26:03 2015 +0800 @@ -392,7 +392,8 @@ /* authdone must be set after encrypt_packet() for * delayed-zlib mode */ ses.authstate.authdone = 1; - svr_ses.connect_time = 0; + ses.connect_time = 0; + if (ses.authstate.pw_uid == 0) { ses.allowprivport = 1; diff -r d41c7b967868 -r 624fc24cfae5 svr-session.c --- a/svr-session.c Tue Jun 23 21:49:04 2015 +0800 +++ b/svr-session.c Fri Aug 07 21:26:03 2015 +0800 @@ -88,22 +88,12 @@ svr_ses.childpidsize = 0; } -static void -svr_sessionloop() { - if (svr_ses.connect_time != 0 - && monotonic_now() - svr_ses.connect_time >= AUTH_TIMEOUT) { - dropbear_close("Timeout before auth"); - } -} - void svr_session(int sock, int childpipe) { char *host, *port; size_t len; common_session_init(sock, sock); - svr_ses.connect_time = monotonic_now();; - /* Initialise server specific parts of the session */ svr_ses.childpipe = childpipe; #ifdef USE_VFORK @@ -146,7 +136,7 @@ /* Run the main for loop. NULL is for the dispatcher - only the client * code makes use of it */ - session_loop(svr_sessionloop); + session_loop(NULL); /* Not reached */ diff -r d41c7b967868 -r 624fc24cfae5 sysoptions.h --- a/sysoptions.h Tue Jun 23 21:49:04 2015 +0800 +++ b/sysoptions.h Fri Aug 07 21:26:03 2015 +0800 @@ -47,7 +47,7 @@ * the clearenv() function */ #define ENV_SIZE 100 -#define MAX_CMD_LEN 1024 /* max length of a command */ +#define MAX_CMD_LEN 9000 /* max length of a command */ #define MAX_TERM_LEN 200 /* max length of TERM name */ #define MAX_HOST_LEN 254 /* max hostname len for tcp fwding */ @@ -153,7 +153,8 @@ #define MAX_CHANNELS 100 /* simple mem restriction, includes each tcp/x11 connection, so can't be _too_ small */ -#define MAX_STRING_LEN 2400 /* Sun SSH needs this long for algos */ +#define MAX_STRING_LEN (MAX(MAX_CMD_LEN, 2400)) /* Sun SSH needs 2400 for algos, + MAX_CMD_LEN is usually longer */ /* For a 4096 bit DSS key, empirically determined */ #define MAX_PUBKEY_SIZE 1700