changeset 1144:624fc24cfae5 coverity

merge
author Matt Johnston <matt@ucc.asn.au>
date Fri, 07 Aug 2015 21:26:03 +0800
parents d41c7b967868 (current diff) 924ff1b959a2 (diff)
children d734fe76b72f
files .travis.yml
diffstat 13 files changed, 71 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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
 
--- 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);
 	}
--- 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() {
--- 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;
 		}
 	}
--- 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_ */
--- 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);
 
--- 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 <privatekey>. 
-   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
--- 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
--- 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
--- 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;
--- 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 */
 
--- 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