diff common-session.c @ 1049:01eea88963f3 fastopen

merge from default
author Matt Johnston <matt@ucc.asn.au>
date Sat, 28 Feb 2015 09:06:40 +0800
parents 0da8ba489c23 3fb883a6aa81
children c2a50c9f509e
line wrap: on
line diff
--- a/common-session.c	Fri Feb 27 00:02:48 2015 +0800
+++ b/common-session.c	Sat Feb 28 09:06:40 2015 +0800
@@ -246,6 +246,15 @@
 	/* Not reached */
 }
 
+static void cleanup_buf(buffer **buf) {
+	if (!*buf) {
+		return;
+	}
+	buf_burn(*buf);
+	buf_free(*buf);
+	*buf = NULL;
+}
+
 /* clean up a session on exit */
 void session_cleanup() {
 	
@@ -257,24 +266,45 @@
 		return;
 	}
 
+	/* Beware of changing order of functions here. */
+
+	/* Must be before extra_session_cleanup() */
+	chancleanup();
+
 	if (ses.extra_session_cleanup) {
 		ses.extra_session_cleanup();
 	}
 
-	chancleanup();
-	
-	/* Cleaning up keys must happen after other cleanup
-	functions which might queue packets */
-	if (ses.session_id) {
-		buf_burn(ses.session_id);
-		buf_free(ses.session_id);
-		ses.session_id = NULL;
+	/* After these are freed most functions will exit */
+#ifdef DROPBEAR_CLEANUP
+	/* listeners call cleanup functions, this should occur before
+	other session state is freed. */
+	remove_all_listeners();
+
+	while (!isempty(&ses.writequeue)) {
+		buf_free(dequeue(&ses.writequeue));
 	}
-	if (ses.hash) {
-		buf_burn(ses.hash);
-		buf_free(ses.hash);
-		ses.hash = NULL;
+
+	m_free(ses.remoteident);
+	m_free(ses.authstate.pw_dir);
+	m_free(ses.authstate.pw_name);
+	m_free(ses.authstate.pw_shell);
+	m_free(ses.authstate.pw_passwd);
+	m_free(ses.authstate.username);
+#endif
+
+	cleanup_buf(&ses.session_id);
+	cleanup_buf(&ses.hash);
+	cleanup_buf(&ses.payload);
+	cleanup_buf(&ses.readbuf);
+	cleanup_buf(&ses.writepayload);
+	cleanup_buf(&ses.kexhashbuf);
+	cleanup_buf(&ses.transkexinit);
+	if (ses.dh_K) {
+		mp_clear(ses.dh_K);
 	}
+	m_free(ses.dh_K);
+
 	m_burn(ses.keys, sizeof(struct key_context));
 	m_free(ses.keys);
 
@@ -405,15 +435,15 @@
 }
 
 void ignore_recv_response() {
-	// Do nothing
+	/* Do nothing */
 	TRACE(("Ignored msg_request_response"))
 }
 
 static void send_msg_keepalive() {
+	time_t old_time_idle = ses.last_packet_time_idle;
+	struct Channel *chan = get_any_ready_channel();
+
 	CHECKCLEARTOWRITE();
-	time_t old_time_idle = ses.last_packet_time_idle;
-
-	struct Channel *chan = get_any_ready_channel();
 
 	if (chan) {
 		/* Channel requests are preferable, more implementations