diff --git a/src/syncterm/ssh.c b/src/syncterm/ssh.c
index 0241283b96003edeaca6ec46019a87f5c1503cb3..b647695f6a270b6ce9cd0b9fc329baa63cdabf8e 100644
--- a/src/syncterm/ssh.c
+++ b/src/syncterm/ssh.c
@@ -3,6 +3,7 @@
 /* $Id: ssh.c,v 1.31 2020/05/28 22:58:26 deuce Exp $ */
 
 #include <assert.h>
+#include <stdatomic.h>
 #include <stdlib.h>
 
 #include "base64.h"
@@ -30,11 +31,11 @@
 SOCKET          ssh_sock = INVALID_SOCKET;
 CRYPT_SESSION   ssh_session;
 int             ssh_channel = -1;
-bool            ssh_active;
+atomic_bool     ssh_active;
+atomic_bool     ssh_complete;
 pthread_mutex_t ssh_mutex;
 pthread_mutex_t ssh_tx_mutex;
 int             sftp_channel = -1;
-bool            sftp_active;
 sftpc_state_t   sftp_state;
 bool            pubkey_thread_running;
 
@@ -168,10 +169,11 @@ ssh_input_thread(void *args)
 
 	SetThreadName("SSH Input");
 	conn_api.input_thread_running = 1;
-	while (ssh_active && !conn_api.terminate) {
+	while (ssh_active && !conn_api.terminate && !ssh_complete) {
 		sftp_do_finish = false;
 		pthread_mutex_lock(&ssh_mutex);
 		if (FlushData(ssh_session) == CRYPT_ERROR_COMPLETE) {
+			ssh_complete = true;
 			pthread_mutex_unlock(&ssh_mutex);
 			break;
 		}
@@ -185,11 +187,14 @@ ssh_input_thread(void *args)
 				sftp_channel = -1;
 			}
 		}
-		if (ssh_channel == -1 && sftp_channel == -1) 
+		if (ssh_channel == -1 && sftp_channel == -1) {
 			both_gone = true;
+			ssh_complete = true;
+		}
 		pthread_mutex_unlock(&ssh_mutex);
-		if (both_gone)
+		if (both_gone) {
 			break;
+		}
 		if (sftp_do_finish) {
 			sftpc_finish(sftp_state);
 			sftp_do_finish = false;
@@ -199,11 +204,12 @@ ssh_input_thread(void *args)
 
 		pthread_mutex_lock(&ssh_mutex);
 		if (FlushData(ssh_session) == CRYPT_ERROR_COMPLETE) {
+			ssh_complete = true;
 			pthread_mutex_unlock(&ssh_mutex);
 			break;
 		}
 
-		// Check channels are active...
+		// Check channels are active (again)...
 		if (ssh_channel != -1) {
 			if (!check_channel_open(&ssh_channel))
 				ssh_channel = -1;
@@ -213,9 +219,11 @@ ssh_input_thread(void *args)
 				pthread_mutex_unlock(&ssh_mutex);
 				sftpc_finish(sftp_state);
 				pthread_mutex_lock(&ssh_mutex);
+				sftp_channel = -1;
 			}
 		}
 		if (ssh_channel == -1 && sftp_channel == -1) {
+			ssh_complete = true;
 			pthread_mutex_unlock(&ssh_mutex);
 			break;
 		}
@@ -285,7 +293,7 @@ ssh_input_thread(void *args)
 				pthread_mutex_unlock(&ssh_mutex);
 				if (rd > 0) {
 					buffered = 0;
-					while (buffered < rd) {
+					while (buffered < rd && ssh_active && !ssh_complete && !conn_api.terminate) {
 						pthread_mutex_lock(&(conn_inbuf.mutex));
 						buffer = conn_buf_wait_free(&conn_inbuf, rd - buffered, 100);
 						buffered += conn_buf_put(&conn_inbuf, conn_api.rd_buf + buffered, buffer);
@@ -312,7 +320,7 @@ ssh_output_thread(void *args)
 
 	SetThreadName("SSH Output");
 	conn_api.output_thread_running = 1;
-	while (ssh_active && !conn_api.terminate && !channel_gone) {
+	while (ssh_active && !conn_api.terminate && !channel_gone && !ssh_complete) {
 		pthread_mutex_lock(&(conn_outbuf.mutex));
 		wr = conn_buf_wait_bytes(&conn_outbuf, 1, 100);
 		if (wr) {
@@ -320,10 +328,11 @@ ssh_output_thread(void *args)
 			pthread_mutex_unlock(&(conn_outbuf.mutex));
 			sent = 0;
 			pthread_mutex_lock(&ssh_tx_mutex);
-			while (ssh_active && sent < wr) {
+			while (sent < wr && ssh_active && !conn_api.terminate && !channel_gone && !ssh_complete) {
 				ret = 0;
 				pthread_mutex_lock(&ssh_mutex);
 				if (ssh_channel == -1) {
+					ssh_complete = true;
 					pthread_mutex_unlock(&ssh_mutex);
 					channel_gone = true;
 					break;
@@ -335,14 +344,18 @@ ssh_output_thread(void *args)
 					if (cryptStatusOK(status))
 						FlushData(ssh_session);
 				}
-				pthread_mutex_unlock(&ssh_mutex);
 				if (cryptStatusError(status)) {
+					ssh_complete = true;
+					pthread_mutex_unlock(&ssh_mutex);
 					if ((status == CRYPT_ERROR_COMPLETE) || (status == CRYPT_ERROR_NOTFOUND)) { /* connection closed */
+						channel_gone = true;
 						break;
 					}
 					cryptlib_error_message(status, "sending data");
+					channel_gone = true;
 					break;
 				}
+				pthread_mutex_unlock(&ssh_mutex);
 				sent += ret;
 			}
 			pthread_mutex_unlock(&ssh_tx_mutex);
@@ -363,7 +376,7 @@ sftp_send(uint8_t *buf, size_t sz, void *cb_data)
 	if (sz == 0)
 		return true;
 	pthread_mutex_lock(&ssh_tx_mutex);
-	while (ssh_active && sent < sz) {
+	while (ssh_active && sent < sz && !ssh_complete) {
 		int status;
 		int ret = 0;
 		pthread_mutex_lock(&ssh_mutex);
@@ -436,7 +449,7 @@ key_not_present(sftp_filehandle_t f, const char *priv)
 	sftp_str_t r = NULL;
 	bool skipread = false;
 
-	while (ssh_active) {
+	while (ssh_active && !ssh_complete) {
 		if (skipread) {
 			old_bufpos = 0;
 			skipread = false;
@@ -508,7 +521,7 @@ add_public_key(void *vpriv)
 			}
 		}
 		pthread_mutex_unlock(&ssh_mutex);
-		if (!ssh_active)
+		if (ssh_complete || !ssh_active)
 			break;
 		SLEEP(10);
 	};
@@ -596,7 +609,7 @@ add_public_key(void *vpriv)
 		 * To avoid that, we'll sleep for a second to allow
 		 * the remote to close the channel if it wants to.
 		 */
-		for (unsigned sleep_count = 0; sleep_count < 100 && conn_api.terminate == 0 && ssh_active; sleep_count++) {
+		for (unsigned sleep_count = 0; sleep_count < 100 && conn_api.terminate == 0 && ssh_active && !ssh_complete; sleep_count++) {
 			SLEEP(10);
 		}
 		pthread_mutex_lock(&ssh_tx_mutex);
@@ -747,7 +760,7 @@ ssh_connect(struct bbslist *bbs)
 		return -1;
 	}
 	ssh_active = true;
-
+	ssh_complete = false;
 
 	/* we need to disable Nagle on the socket. */
 	if (setsockopt(ssh_sock, IPPROTO_TCP, TCP_NODELAY, (char *)&off, sizeof(off)))
@@ -1002,6 +1015,7 @@ ssh_close(void)
 	char garbage[1024];
 
 	conn_api.terminate = 1;
+	ssh_complete = true;
 	if (ssh_active) {
 		cryptSetAttribute(ssh_session, CRYPT_OPTION_NET_READTIMEOUT, 1);
 		cryptSetAttribute(ssh_session, CRYPT_OPTION_NET_WRITETIMEOUT, 1);
diff --git a/src/syncterm/ssh.h b/src/syncterm/ssh.h
index bf268129d3dc5ea5b6978382ff970b43c8a0a6ea..a0dd23f3028747ab8002f389d5156114594e59cd 100644
--- a/src/syncterm/ssh.h
+++ b/src/syncterm/ssh.h
@@ -16,7 +16,6 @@ void ssh_output_thread(void *args);
 extern SOCKET          ssh_sock;
 extern CRYPT_SESSION   ssh_session;
 extern int             ssh_channel;
-extern bool            ssh_active;
 extern pthread_mutex_t ssh_mutex;
 extern int             sftp_channel;
 extern bool            sftp_active;