From bf6f3f613d487299df5e2570984c22ad72908c28 Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Mon, 17 Feb 2014 21:41:06 +0800
Subject: [PATCH] Read (and enqueue) packets from interactive input even when
 we're waiting for a key exchange.

This should hopefully fix the situation where "~." doesn't work to terminate a
client session when a laptop wakes up. The client will be stuck waiting for a
key exchange on a dead connection, so won't have read the escape character
---
 common-channel.c |  9 +++++++--
 common-session.c | 11 ++++-------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/common-channel.c b/common-channel.c
index 20689046..4a6bdb46 100644
--- a/common-channel.c
+++ b/common-channel.c
@@ -474,8 +474,13 @@ void setchannelfds(fd_set *readfds, fd_set *writefds) {
 			continue;
 		}
 
-		/* Stuff to put over the wire */
-		if (channel->transwindow > 0) {
+		/* Stuff to put over the wire. 
+		Avoid queueing data to send if we're in the middle of a 
+		key re-exchange (!dataallowed), but still read from the 
+		FD if there's the possibility of "~."" to kill an 
+		interactive session (the read_mangler) */
+		if (channel->transwindow > 0
+		   && (ses.dataallowed || channel->read_mangler)) {
 
 			if (channel->readfd >= 0) {
 				FD_SET(channel->readfd, readfds);
diff --git a/common-session.c b/common-session.c
index 6882dced..02eeaaed 100644
--- a/common-session.c
+++ b/common-session.c
@@ -153,10 +153,9 @@ void session_loop(void(*loophandler)()) {
 		   SIGCHLD in svr-chansession is the only one currently. */
 		FD_SET(ses.signal_pipe[0], &readfd);
 
-		/* set up for channels which require reading/writing */
-		if (ses.dataallowed) {
-			setchannelfds(&readfd, &writefd);
-		}
+		/* set up for channels which can be read/written */
+		setchannelfds(&readfd, &writefd);
+
 		val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout);
 
 		if (exitflag) {
@@ -217,9 +216,7 @@ void session_loop(void(*loophandler)()) {
 
 		/* process pipes etc for the channels, ses.dataallowed == 0
 		 * during rekeying ) */
-		if (ses.dataallowed) {
-			channelio(&readfd, &writefd);
-		}
+		channelio(&readfd, &writefd);
 
 		if (loophandler) {
 			loophandler();
-- 
GitLab