diff common-session.c @ 1144:624fc24cfae5 coverity

merge
author Matt Johnston <matt@ucc.asn.au>
date Fri, 07 Aug 2015 21:26:03 +0800
parents 924ff1b959a2
children a550e1e2e2a9
line wrap: on
line diff
--- 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() {