diff --git a/3rdp/build/GNUmakefile b/3rdp/build/GNUmakefile
index f78f77eeaea6b9a5835421928e544deda144cb22..5987bff65fc8398b560fe837a616fce391568b2e 100644
--- a/3rdp/build/GNUmakefile
+++ b/3rdp/build/GNUmakefile
@@ -88,7 +88,7 @@ $(CRYPT_SRC): | $(3RDPSRCDIR)
 $(CRYPT_IDIR): | $(3RDPODIR)
 	$(QUIET)$(IFNOTEXIST) mkdir $(CRYPT_IDIR)
 
-$(CRYPTLIB_BUILD): $(3RDP_ROOT)/dist/cryptlib.zip $(3RDP_ROOT)/build/terminal-params.patch $(3RDP_ROOT)/build/cl-mingw32-static.patch $(3RDP_ROOT)/build/cl-ranlib.patch $(3RDP_ROOT)/build/cl-win32-noasm.patch $(3RDP_ROOT)/build/cl-zz-country.patch $(3RDP_ROOT)/build/cl-algorithms.patch $(3RDP_ROOT)/build/cl-allow-duplicate-ext.patch $(3RDP_ROOT)/build/cl-macosx-minver.patch $(3RDP_ROOT)/build/cl-endian.patch $(3RDP_ROOT)/build/cl-cryptodev.patch $(3RDP_ROOT)/build/cl-posix-me-gently.patch $(3RDP_ROOT)/build/cl-tpm-linux.patch $(3RDP_ROOT)/build/cl-PAM-noprompts.patch $(3RDP_ROOT)/build/cl-zlib.patch $(3RDP_ROOT)/build/Dynamic-linked-static-lib.patch $(3RDP_ROOT)/build/SSL-fix.patch $(3RDP_ROOT)/build/cl-bigger-maxattribute.patch $(3RDP_ROOT)/build/cl-vcxproj.patch $(3RDP_ROOT)/build/cl-mingw-vcver.patch $(3RDP_ROOT)/build/cl-win32-build-fix.patch $(3RDP_ROOT)/build/cl-gcc-non-const-time-val.patch $(3RDP_ROOT)/build/cl-no-odbc.patch $(3RDP_ROOT)/build/cl-noasm-defines.patch $(3RDP_ROOT)/build/cl-bn-noasm64-fix.patch $(3RDP_ROOT)/build/cl-no-RSA-suites.patch $(3RDP_ROOT)/build/cl-fix-ECC-RSA.patch $(3RDP_ROOT)/build/cl-prefer-ECC.patch $(3RDP_ROOT)/build/cl-prefer-ECC-harder.patch $(3RDP_ROOT)/build/cl-more-RSA-ECC-fixes.patch $(3RDP_ROOT)/build/cl-DH-key-init.patch $(3RDP_ROOT)/build/cl-clear-GCM-flag.patch $(3RDP_ROOT)/build/cl-use-ssh-ctr.patch $(3RDP_ROOT)/build/cl-ssh-list-ctr-modes.patch $(3RDP_ROOT)/build/cl-ssh-incCtr.patch $(3RDP_ROOT)/build/cl-ssl-suite-blocksizes.patch $(3RDP_ROOT)/build/cl-no-tpm.patch $(3RDP_ROOT)/build/cl-no-via-aes.patch $(3RDP_ROOT)/build/cl-fix-ssh-ecc-ephemeral.patch $(3RDP_ROOT)/build/cl-just-use-cc.patch $(3RDP_ROOT)/build/cl-learn-numbers.patch $(3RDP_ROOT)/build/cl-no-safe-stack.patch $(3RDP_ROOT)/build/cl-allow-pkcs12.patch $(3RDP_ROOT)/build/cl-uint64_t-redefine.patch $(3RDP_ROOT)/build/cl-random-openbsd.patch $(3RDP_ROOT)/build/cl-openbsd-threads.patch $(3RDP_ROOT)/build/cl-allow-none-auth.patch $(3RDP_ROOT)/build/cl-mingw-add-m32.patch $(3RDP_ROOT)/build/cl-poll-not-select.patch $(3RDP_ROOT)/build/cl-check-before-use.patch $(3RDP_ROOT)/build/cl-linux-yield.patch $(3RDP_ROOT)/build/cl-good-sockets.patch $(3RDP_ROOT)/build/cl-moar-objects.patch $(3RDP_ROOT)/build/cl-pthread_yield.patch $(3RDP_ROOT)/build/cl-check-cert-dont-modify.patch $(3RDP_ROOT)/build/cl-server-term-support.patch $(3RDP_ROOT)/build/cl-add-pubkey-attribute.patch $(3RDP_ROOT)/build/cl-allow-ssh-auth-retries.patch | $(CRYPT_SRC) $(CRYPT_IDIR) $(3RDP_ROOT)/build/cl-remove-march.patch
+$(CRYPTLIB_BUILD): $(3RDP_ROOT)/dist/cryptlib.zip $(3RDP_ROOT)/build/terminal-params.patch $(3RDP_ROOT)/build/cl-mingw32-static.patch $(3RDP_ROOT)/build/cl-ranlib.patch $(3RDP_ROOT)/build/cl-win32-noasm.patch $(3RDP_ROOT)/build/cl-zz-country.patch $(3RDP_ROOT)/build/cl-algorithms.patch $(3RDP_ROOT)/build/cl-allow-duplicate-ext.patch $(3RDP_ROOT)/build/cl-macosx-minver.patch $(3RDP_ROOT)/build/cl-endian.patch $(3RDP_ROOT)/build/cl-cryptodev.patch $(3RDP_ROOT)/build/cl-posix-me-gently.patch $(3RDP_ROOT)/build/cl-tpm-linux.patch $(3RDP_ROOT)/build/cl-PAM-noprompts.patch $(3RDP_ROOT)/build/cl-zlib.patch $(3RDP_ROOT)/build/Dynamic-linked-static-lib.patch $(3RDP_ROOT)/build/SSL-fix.patch $(3RDP_ROOT)/build/cl-bigger-maxattribute.patch $(3RDP_ROOT)/build/cl-vcxproj.patch $(3RDP_ROOT)/build/cl-mingw-vcver.patch $(3RDP_ROOT)/build/cl-win32-build-fix.patch $(3RDP_ROOT)/build/cl-gcc-non-const-time-val.patch $(3RDP_ROOT)/build/cl-no-odbc.patch $(3RDP_ROOT)/build/cl-noasm-defines.patch $(3RDP_ROOT)/build/cl-bn-noasm64-fix.patch $(3RDP_ROOT)/build/cl-no-RSA-suites.patch $(3RDP_ROOT)/build/cl-fix-ECC-RSA.patch $(3RDP_ROOT)/build/cl-prefer-ECC.patch $(3RDP_ROOT)/build/cl-prefer-ECC-harder.patch $(3RDP_ROOT)/build/cl-more-RSA-ECC-fixes.patch $(3RDP_ROOT)/build/cl-DH-key-init.patch $(3RDP_ROOT)/build/cl-clear-GCM-flag.patch $(3RDP_ROOT)/build/cl-use-ssh-ctr.patch $(3RDP_ROOT)/build/cl-ssh-list-ctr-modes.patch $(3RDP_ROOT)/build/cl-ssh-incCtr.patch $(3RDP_ROOT)/build/cl-ssl-suite-blocksizes.patch $(3RDP_ROOT)/build/cl-no-tpm.patch $(3RDP_ROOT)/build/cl-no-via-aes.patch $(3RDP_ROOT)/build/cl-fix-ssh-ecc-ephemeral.patch $(3RDP_ROOT)/build/cl-just-use-cc.patch $(3RDP_ROOT)/build/cl-learn-numbers.patch $(3RDP_ROOT)/build/cl-no-safe-stack.patch $(3RDP_ROOT)/build/cl-allow-pkcs12.patch $(3RDP_ROOT)/build/cl-uint64_t-redefine.patch $(3RDP_ROOT)/build/cl-random-openbsd.patch $(3RDP_ROOT)/build/cl-openbsd-threads.patch $(3RDP_ROOT)/build/cl-allow-none-auth.patch $(3RDP_ROOT)/build/cl-mingw-add-m32.patch $(3RDP_ROOT)/build/cl-poll-not-select.patch $(3RDP_ROOT)/build/cl-check-before-use.patch $(3RDP_ROOT)/build/cl-linux-yield.patch $(3RDP_ROOT)/build/cl-good-sockets.patch $(3RDP_ROOT)/build/cl-moar-objects.patch $(3RDP_ROOT)/build/cl-pthread_yield.patch $(3RDP_ROOT)/build/cl-check-cert-dont-modify.patch $(3RDP_ROOT)/build/cl-server-term-support.patch $(3RDP_ROOT)/build/cl-add-pubkey-attribute.patch $(3RDP_ROOT)/build/cl-allow-ssh-auth-retries.patch $(3RDP_ROOT)/build/cl-fix-ssh-channel-close.patch | $(CRYPT_SRC) $(CRYPT_IDIR) $(3RDP_ROOT)/build/cl-remove-march.patch
 	@echo Creating $@ ...
 	$(QUIET)-rm -rf $(CRYPT_SRC)/*
 	$(QUIET)unzip -oa $(3RDPDISTDIR)/cryptlib.zip -d $(CRYPT_SRC)
@@ -150,6 +150,7 @@ $(CRYPTLIB_BUILD): $(3RDP_ROOT)/dist/cryptlib.zip $(3RDP_ROOT)/build/terminal-pa
 	$(QUIET)patch -b -p0 -d $(CRYPT_SRC) < cl-server-term-support.patch
 	$(QUIET)patch -b -p0 -d $(CRYPT_SRC) < cl-add-pubkey-attribute.patch
 	$(QUIET)patch -b -p0 -d $(CRYPT_SRC) < cl-allow-ssh-auth-retries.patch
+	$(QUIET)patch -b -p0 -d $(CRYPT_SRC) < cl-fix-ssh-channel-close.patch
 ifeq ($(os),win32)
 	$(QUIET)cd $(CRYPT_SRC) && env - PATH="$(PATH)" CC="$(CC)" AR="$(AR)" RANLIB="$(RANLIB)" make directories
 	$(QUIET)cd $(CRYPT_SRC) && env - PATH="$(PATH)" CC="$(CC)" AR="$(AR)" RANLIB="$(RANLIB)" make toolscripts
diff --git a/3rdp/build/cl-fix-ssh-channel-close.patch b/3rdp/build/cl-fix-ssh-channel-close.patch
new file mode 100644
index 0000000000000000000000000000000000000000..ed70e43eee7f67a87b35de8dd9235cf5c5b5af33
--- /dev/null
+++ b/3rdp/build/cl-fix-ssh-channel-close.patch
@@ -0,0 +1,181 @@
+--- session/ssh2_msg.c.orig	2023-12-29 14:59:17.512549000 -0500
++++ session/ssh2_msg.c	2023-12-29 15:00:11.110220000 -0500
+@@ -457,7 +457,7 @@
+ 											 channelNo ) == CHANNEL_BOTH )
+ 				{
+ 				status = sendChannelClose( sessionInfoPtr, channelNo,
+-										   CHANNEL_BOTH, TRUE );
++										   CHANNEL_READ, TRUE );
+ 				}
+ 			else
+ 				{
+--- cryptlib.h.orig	2023-12-29 15:55:17.717475000 -0500
++++ cryptlib.h	2023-12-29 15:56:34.124863000 -0500
+@@ -1228,6 +1228,7 @@
+ 	CRYPT_SESSINFO_SSH_CHANNEL_TERMINAL,	/* TERM string sent to remote */
+ 	CRYPT_SESSINFO_SSH_CHANNEL_WIDTH,	/* Terminal width */
+ 	CRYPT_SESSINFO_SSH_CHANNEL_HEIGHT,	/* Terminal height */
++	CRYPT_SESSINFO_SSH_CHANNEL_OPEN,	/* True if write channel is open for read */
+ 
+ 	/* Used internally */
+ 	CRYPT_SESSINFO_LAST, CRYPT_USERINFO_FIRST = 7000,
+@@ -1374,7 +1375,7 @@
+ 	CRYPT_CERTINFO_FIRST_CMS = CRYPT_CERTINFO_CMS_CONTENTTYPE,
+ 	CRYPT_CERTINFO_LAST_CMS = CRYPT_CERTINFO_LAST - 1,
+ 	CRYPT_SESSINFO_FIRST_SPECIFIC = CRYPT_SESSINFO_REQUEST,
+-	CRYPT_SESSINFO_LAST_SPECIFIC = CRYPT_SESSINFO_SSH_CHANNEL_HEIGHT
++	CRYPT_SESSINFO_LAST_SPECIFIC = CRYPT_SESSINFO_SSH_CHANNEL_OPEN
+ 
+ 	/* Point at which private-use values start.  Attribute values sometimes
+ 	   need to be extended with additional pseudo-values in object-specific
+--- ./kernel/attr_acl.c	2023-12-29 15:57:31.965603000 -0500
++++ ./kernel/attr_acl.c.orig	2023-12-29 15:57:21.751654000 -0500
+@@ -3840,6 +3840,12 @@
+ 		MKPERM_SSH_EXT( RWx_RWx ),
+ 		ROUTE( OBJECT_TYPE_SESSION ),
+ 		subACL_SessinfoSSHChannelHeight ),
++	MKACL_N(
++		CRYPT_SESSINFO_SSH_CHANNEL_OPEN,
++		ST_NONE, ST_NONE, ST_SESS_SSH | ST_SESS_SSH_SVR, 
++		MKPERM_SSL( Rxx_Rxx ),
++		ROUTE( OBJECT_TYPE_SESSION ),
++		RANGE( FALSE, TRUE ) ),
+ 
+ 	MKACL_END(), MKACL_END()
+ 	};
+@@ -4707,7 +4713,7 @@
+ 	static_assert( CRYPT_CERTINFO_FIRST_EXTENSION == 2200, "Attribute value" );
+ 	static_assert( CRYPT_CERTINFO_FIRST_CMS == 2500, "Attribute value" );
+ 	static_assert( CRYPT_SESSINFO_FIRST_SPECIFIC == 6016, "Attribute value" );
+-	static_assert( CRYPT_SESSINFO_LAST_SPECIFIC == 6035, "Attribute value" );
++	static_assert( CRYPT_SESSINFO_LAST_SPECIFIC == 6036, "Attribute value" );
+ 	static_assert( CRYPT_CERTFORMAT_LAST == 12, "Attribute value" );
+ 
+ 	/* Perform a consistency check on the attribute ACLs.  The ACLs are
+--- session/ssh.c.orig	2023-12-29 16:07:09.485094000 -0500
++++ session/ssh.c	2023-12-29 16:07:52.102633000 -0500
+@@ -993,7 +993,8 @@
+ 			  type == CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE || \
+ 			  type == CRYPT_SESSINFO_SSH_CHANNEL_WIDTH || \
+ 			  type == CRYPT_SESSINFO_SSH_CHANNEL_HEIGHT || \
+-			  type == CRYPT_SESSINFO_SSH_CHANNEL_TERMINAL);
++			  type == CRYPT_SESSINFO_SSH_CHANNEL_TERMINAL || \
++			  type == CRYPT_SESSINFO_SSH_CHANNEL_OPEN);
+ 
+ 	if( type == CRYPT_SESSINFO_SSH_OPTIONS )
+ 		{
+@@ -1010,7 +1011,8 @@
+ 	if( type == CRYPT_SESSINFO_SSH_CHANNEL || \
+ 		type == CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE || \
+ 		type == CRYPT_SESSINFO_SSH_CHANNEL_WIDTH || \
+-		type == CRYPT_SESSINFO_SSH_CHANNEL_HEIGHT)
++		type == CRYPT_SESSINFO_SSH_CHANNEL_HEIGHT || \
++		type == CRYPT_SESSINFO_SSH_CHANNEL_OPEN)
+ 		{
+ 		status = getChannelAttribute( sessionInfoPtr, type, data );
+ 		}
+--- ./session/ssh2_chn.c.orig	2023-12-29 16:24:38.424547000 -0500
++++ ./session/ssh2_chn.c	2023-12-29 16:25:43.443138000 -0500
+@@ -24,6 +24,7 @@
+ #define CHANNEL_FLAG_NONE		0x00	/* No channel flag */
+ #define CHANNEL_FLAG_ACTIVE		0x01	/* Channel is active */
+ #define CHANNEL_FLAG_WRITECLOSED 0x02	/* Write-side of ch.closed */
++#define CHANNEL_FLAG_READCLOSED 0x04	/* Read-side of ch.closed */
+ 
+ /* Per-channel information.  SSH channel IDs are 32-bit/4 byte data values
+    and can be reused during sessions so we provide our own guaranteed-unique
+@@ -149,7 +150,9 @@
+ 	static const CRYPT_ATTRIBUTE_TYPE attributeOrderList[] = {
+ 			CRYPT_SESSINFO_SSH_CHANNEL, CRYPT_SESSINFO_SSH_CHANNEL_TYPE,
+ 			CRYPT_SESSINFO_SSH_CHANNEL_ARG1, CRYPT_SESSINFO_SSH_CHANNEL_ARG2,
+-			CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE, CRYPT_ATTRIBUTE_NONE,
++			CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE, CRYPT_SESSINFO_SSH_CHANNEL_TERMINAL,
++			CRYPT_SESSINFO_SSH_CHANNEL_WIDTH, CRYPT_SESSINFO_SSH_CHANNEL_HEIGHT,
++			CRYPT_SESSINFO_SSH_CHANNEL_OPEN, CRYPT_ATTRIBUTE_NONE,
+ 			CRYPT_ATTRIBUTE_NONE };
+ 	SSH_CHANNEL_INFO *channelInfoPtr = attributeListPtr->value;
+ 	CRYPT_ATTRIBUTE_TYPE attributeType = channelInfoPtr->cursorPos;
+@@ -229,6 +232,7 @@
+ 			case CRYPT_SESSINFO_SSH_CHANNEL:
+ 			case CRYPT_SESSINFO_SSH_CHANNEL_TYPE:
+ 			case CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE:
++			case CRYPT_SESSINFO_SSH_CHANNEL_OPEN:
+ 				doContinue = FALSE;	/* Always present */
+ 				break;
+ 
+@@ -474,6 +478,8 @@
+ 	{
+ 	const SSH_CHANNEL_INFO *channelInfoPtr = \
+ 				getCurrentChannelInfo( sessionInfoPtr, CHANNEL_READ );
++	const SSH_CHANNEL_INFO *writeChannelInfoPtr = \
++				getCurrentChannelInfo( sessionInfoPtr, CHANNEL_WRITE );
+ 
+ 	assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
+ 	assert( isWritePtr( value, sizeof( int ) ) );
+@@ -495,17 +501,21 @@
+ 			return( CRYPT_OK );
+ 
+ 		case CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE:
+-			*value = isActiveChannel( channelInfoPtr ) ? TRUE : FALSE;
++			*value = isActiveChannel( writeChannelInfoPtr ) ? TRUE : FALSE;
+ 			return( CRYPT_OK );
+ 
++		case CRYPT_SESSINFO_SSH_CHANNEL_OPEN:
++			*value = ( writeChannelInfoPtr->flags & CHANNEL_FLAG_READCLOSED ) ? FALSE : TRUE;
++			return( CRYPT_OK );
++
+ 		case CRYPT_SESSINFO_SSH_CHANNEL_WIDTH:
+-			if (channelInfoPtr->width == 0)
++			if (writeChannelInfoPtr->width == 0)
+ 				return CRYPT_ERROR_NOTFOUND;
+ 			*value = channelInfoPtr->width;
+ 			return( CRYPT_OK );
+ 
+ 		case CRYPT_SESSINFO_SSH_CHANNEL_HEIGHT:
+-			if (channelInfoPtr->height == 0)
++			if (writeChannelInfoPtr->height == 0)
+ 				return CRYPT_ERROR_NOTFOUND;
+ 			*value = channelInfoPtr->height;
+ 			return( CRYPT_OK );
+@@ -760,7 +770,7 @@
+ 	channelInfoPtr = findChannelByChannelNo( sessionInfoPtr, channelNo );
+ 	return( ( channelInfoPtr == NULL ) ? CHANNEL_NONE : \
+ 			( channelInfoPtr->flags & CHANNEL_FLAG_WRITECLOSED ) ? \
+-				CHANNEL_READ : CHANNEL_BOTH );
++				CHANNEL_READ : ( channelInfoPtr->flags & CHANNEL_FLAG_READCLOSED ) ? CHANNEL_WRITE : CHANNEL_BOTH );
+ 	}
+ 
+ CHECK_RETVAL_ENUM( CHANNEL ) STDC_NONNULL_ARG( ( 1 ) ) \
+@@ -780,7 +790,7 @@
+ 										addrInfoLen );
+ 	return( ( channelInfoPtr == NULL ) ? CHANNEL_NONE : \
+ 			( channelInfoPtr->flags & CHANNEL_FLAG_WRITECLOSED ) ? \
+-				CHANNEL_READ : CHANNEL_BOTH );
++				CHANNEL_READ : ( channelInfoPtr->flags & CHANNEL_FLAG_READCLOSED ) ? CHANNEL_WRITE : CHANNEL_BOTH );
+ 	}
+ 
+ /****************************************************************************
+@@ -1001,12 +1011,22 @@
+ 	/* Delete the channel entry.  If we're only closing the write side we
+ 	   mark the channel as closed for write but leave the overall channel
+ 	   open */
+-	if( channelType == CHANNEL_WRITE )
++	if( channelType == CHANNEL_WRITE  && !(channelInfoPtr->flags & CHANNEL_FLAG_READCLOSED))
+ 		{
+ 		REQUIRES( !( channelInfoPtr->flags & CHANNEL_FLAG_WRITECLOSED ) );
+ 		channelInfoPtr->flags |= CHANNEL_FLAG_WRITECLOSED;
+ 		if( channelID == sshInfo->currWriteChannel )
+ 			sshInfo->currWriteChannel = UNUSED_CHANNEL_ID;
++		return( isChannelActive( sessionInfoPtr, \
++								 channelInfoPtr->channelID ) ? \
++				CRYPT_OK : OK_SPECIAL );
++		}
++	if( channelType == CHANNEL_READ && !(channelInfoPtr->flags & CHANNEL_FLAG_WRITECLOSED))
++		{
++		REQUIRES( !( channelInfoPtr->flags & CHANNEL_FLAG_READCLOSED ) );
++		channelInfoPtr->flags |= CHANNEL_FLAG_READCLOSED;
++		if( channelID == sshInfo->currReadChannel )
++			sshInfo->currReadChannel = UNUSED_CHANNEL_ID;
+ 		return( isChannelActive( sessionInfoPtr, \
+ 								 channelInfoPtr->channelID ) ? \
+ 				CRYPT_OK : OK_SPECIAL );