From eb811e9fc502c7dfd6093909e7efc28eef1dd110 Mon Sep 17 00:00:00 2001
From: deuce <>
Date: Tue, 19 Jun 2012 08:18:02 +0000
Subject: [PATCH] What's good for the client is good for the server - serialize
 access to the ssh session.

---
 src/sbbs3/answer.cpp |  2 ++
 src/sbbs3/main.cpp   | 16 ++++++++++++++--
 src/sbbs3/sbbs.h     |  1 +
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/sbbs3/answer.cpp b/src/sbbs3/answer.cpp
index 9bfd2221fc..6fa8f8f2fd 100644
--- a/src/sbbs3/answer.cpp
+++ b/src/sbbs3/answer.cpp
@@ -189,9 +189,11 @@ bool sbbs_t::answer()
 	}
 #ifdef USE_CRYPTLIB
 	if(sys_status&SS_SSH) {
+		pthread_mutex_lock(&ssh_mutex);
 		cryptGetAttributeString(ssh_session, CRYPT_SESSINFO_USERNAME, rlogin_name, &i);
 		rlogin_name[i]=0;
 		cryptGetAttributeString(ssh_session, CRYPT_SESSINFO_PASSWORD, rlogin_pass, &i);
+		pthread_mutex_unlock(&ssh_mutex);
 		rlogin_pass[i]=0;
 		lprintf(LOG_DEBUG,"Node %d SSH login: '%s'"
 			,cfg.node_num, rlogin_name);
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 153d8ac7b8..fa33900f15 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -71,7 +71,7 @@
 #endif // _WIN32
 
 #ifdef USE_CRYPTLIB
-	#define SSH_END()	if(ssh)	cryptDestroySession(sbbs->ssh_session);
+	#define SSH_END()	if(ssh) { pthread_mutex_lock(&sbbs->ssh_mutex); cryptDestroySession(sbbs->ssh_session); pthread_mutex_unlock(&sbbs->ssh_mutex); }
 #else
 	#define	SSH_END()
 #endif
@@ -1521,6 +1521,7 @@ void input_thread(void *arg)
 #endif
 
 	pthread_mutex_init(&sbbs->input_thread_mutex,NULL);
+	pthread_mutex_init(&sbbs->ssh_mutex,NULL);
     sbbs->input_thread_running = true;
 	sbbs->console|=CON_R_INPUT;
 
@@ -1641,7 +1642,9 @@ void input_thread(void *arg)
 #ifdef USE_CRYPTLIB
 		if(sbbs->ssh_mode && sock==sbbs->client_socket) {
 			int err;
+			pthread_mutex_lock(&sbbs->ssh_mutex);
 			if(!cryptStatusOK((err=cryptPopData(sbbs->ssh_session, (char*)inbuf, rd, &i)))) {
+				pthread_mutex_unlock(&sbbs->ssh_mutex);
 				if(pthread_mutex_unlock(&sbbs->input_thread_mutex)!=0)
 					sbbs->errormsg(WHERE,ERR_UNLOCK,"input_thread_mutex",0);
 				if(err==CRYPT_ERROR_TIMEOUT)
@@ -1651,6 +1654,7 @@ void input_thread(void *arg)
 				break;
 			}
 			else {
+				pthread_mutex_unlock(&sbbs->ssh_mutex);
 				if(!i) {
 					if(pthread_mutex_unlock(&sbbs->input_thread_mutex)!=0)
 						sbbs->errormsg(WHERE,ERR_UNLOCK,"input_thread_mutex",0);
@@ -1756,6 +1760,8 @@ void input_thread(void *arg)
 	if(node_socket[sbbs->cfg.node_num-1]==INVALID_SOCKET)	// Shutdown locally
 		sbbs->terminated = true;	// Signal JS to stop execution
 
+	while(pthread_mutex_destroy(&sbbs->ssh_mutex)==EBUSY)
+		mswait(1);
 	while(pthread_mutex_destroy(&sbbs->input_thread_mutex)==EBUSY)
 		mswait(1);
 
@@ -1834,13 +1840,17 @@ void passthru_output_thread(void* arg)
 
 #ifdef USE_CRYPTLIB
 		if(sbbs->ssh_mode) {
+			pthread_mutex_lock(&sbbs->ssh_mutex);
 			if(!cryptStatusOK(cryptPopData(sbbs->ssh_session, (char*)inbuf, rd, &i)))
 				rd=0;
 			else {
-				if(!i)
+				if(!i) {
+					pthread_mutex_unlock(&sbbs->ssh_mutex);
 					continue;
+				}
 				rd=i;
 			}
+			pthread_mutex_unlock(&sbbs->ssh_mutex);
 		}
 		else
 #endif
@@ -2106,6 +2116,7 @@ void output_thread(void* arg)
 #ifdef USE_CRYPTLIB
 		if(sbbs->ssh_mode) {
 			int err;
+			pthread_mutex_lock(&sbbs->ssh_mutex);
 			if(!cryptStatusOK((err=cryptPushData(sbbs->ssh_session, (char*)buf+bufbot, buftop-bufbot, &i)))) {
 				/* Handle the SSH error here... */
 				lprintf(LOG_WARNING,"%s !ERROR %d sending on Cryptlib session", node, err);
@@ -2114,6 +2125,7 @@ void output_thread(void* arg)
 			}
 			else
 				cryptFlushData(sbbs->ssh_session);
+			pthread_mutex_unlock(&sbbs->ssh_mutex);
 		}
 		else
 #endif
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index 1c6e28b6db..63799aea93 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -226,6 +226,7 @@ public:
 	HANDLE	input_thread;
 	pthread_mutex_t	input_thread_mutex;
 	bool	input_thread_mutex_locked;	// by someone other than the input_thread
+	pthread_mutex_t	ssh_mutex;
 
 	int 	outcom(uchar ch); 	   // send character
 	int 	incom(unsigned long timeout=0);		   // receive character
-- 
GitLab