From d1e7fda1ff804cf06ed82d1f0c4c4222f10a3118 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net>
Date: Fri, 29 Dec 2023 20:03:27 -0500
Subject: [PATCH] Fix up patch...

Don't count read closed channels against "is this the last one?" checks
Fix checking of channel attributes are present.
Fully close readclose channel if it's the last one.
---
 3rdp/build/cl-fix-ssh-channel-close.patch | 49 ++++++++++++++++++-----
 1 file changed, 39 insertions(+), 10 deletions(-)

diff --git a/3rdp/build/cl-fix-ssh-channel-close.patch b/3rdp/build/cl-fix-ssh-channel-close.patch
index ed70e43eee..a16af75cd8 100644
--- a/3rdp/build/cl-fix-ssh-channel-close.patch
+++ b/3rdp/build/cl-fix-ssh-channel-close.patch
@@ -74,8 +74,8 @@
  		{
  		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
+--- ./session/ssh2_chn.c.orig	2023-12-29 19:50:00.990529000 -0500
++++ ./session/ssh2_chn.c	2023-12-29 19:51:32.502476000 -0500
 @@ -24,6 +24,7 @@
  #define CHANNEL_FLAG_NONE		0x00	/* No channel flag */
  #define CHANNEL_FLAG_ACTIVE		0x01	/* Channel is active */
@@ -84,7 +84,16 @@
  
  /* 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 @@
+@@ -126,6 +127,8 @@
+ 		   after */
+ 		ENSURES( attributeListPtr->valueLength == sizeof( SSH_CHANNEL_INFO ) );
+ 		channelInfoPtr = attributeListPtr->value;
++		if( channelInfoPtr->flags & CHANNEL_FLAG_READCLOSED)
++			continue;
+ 		if( isActiveChannel( channelInfoPtr ) && \
+ 			channelInfoPtr->channelID != excludedChannelID )
+ 			return( TRUE );
+@@ -149,7 +152,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,
@@ -95,7 +104,7 @@
  			CRYPT_ATTRIBUTE_NONE };
  	SSH_CHANNEL_INFO *channelInfoPtr = attributeListPtr->value;
  	CRYPT_ATTRIBUTE_TYPE attributeType = channelInfoPtr->cursorPos;
-@@ -229,6 +232,7 @@
+@@ -229,6 +234,7 @@
  			case CRYPT_SESSINFO_SSH_CHANNEL:
  			case CRYPT_SESSINFO_SSH_CHANNEL_TYPE:
  			case CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE:
@@ -103,7 +112,7 @@
  				doContinue = FALSE;	/* Always present */
  				break;
  
-@@ -474,6 +478,8 @@
+@@ -474,6 +480,8 @@
  	{
  	const SSH_CHANNEL_INFO *channelInfoPtr = \
  				getCurrentChannelInfo( sessionInfoPtr, CHANNEL_READ );
@@ -112,20 +121,38 @@
  
  	assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
  	assert( isWritePtr( value, sizeof( int ) ) );
-@@ -495,17 +501,21 @@
+@@ -485,27 +493,38 @@
+ 	/* Clear return values */
+ 	*value = 0;
+ 
+-	if( isNullChannel( channelInfoPtr ) )
+-		return( CRYPT_ERROR_NOTFOUND );
+-
+ 	switch( attribute )
+ 		{
+ 		case CRYPT_SESSINFO_SSH_CHANNEL:
++			if( isNullChannel( channelInfoPtr ) )
++				return( CRYPT_ERROR_NOTFOUND );
+ 			*value = channelInfoPtr->channelID;
  			return( CRYPT_OK );
  
  		case CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE:
 -			*value = isActiveChannel( channelInfoPtr ) ? TRUE : FALSE;
++			if( isNullChannel( writeChannelInfoPtr ) )
++				return( CRYPT_ERROR_NOTFOUND );
 +			*value = isActiveChannel( writeChannelInfoPtr ) ? TRUE : FALSE;
  			return( CRYPT_OK );
  
 +		case CRYPT_SESSINFO_SSH_CHANNEL_OPEN:
++			if( isNullChannel( writeChannelInfoPtr ) )
++				return( CRYPT_ERROR_NOTFOUND );
 +			*value = ( writeChannelInfoPtr->flags & CHANNEL_FLAG_READCLOSED ) ? FALSE : TRUE;
 +			return( CRYPT_OK );
 +
  		case CRYPT_SESSINFO_SSH_CHANNEL_WIDTH:
 -			if (channelInfoPtr->width == 0)
++			if( isNullChannel( writeChannelInfoPtr ) )
++				return( CRYPT_ERROR_NOTFOUND );
 +			if (writeChannelInfoPtr->width == 0)
  				return CRYPT_ERROR_NOTFOUND;
  			*value = channelInfoPtr->width;
@@ -133,11 +160,13 @@
  
  		case CRYPT_SESSINFO_SSH_CHANNEL_HEIGHT:
 -			if (channelInfoPtr->height == 0)
++			if( isNullChannel( writeChannelInfoPtr ) )
++				return( CRYPT_ERROR_NOTFOUND );
 +			if (writeChannelInfoPtr->height == 0)
  				return CRYPT_ERROR_NOTFOUND;
  			*value = channelInfoPtr->height;
  			return( CRYPT_OK );
-@@ -760,7 +770,7 @@
+@@ -760,7 +779,7 @@
  	channelInfoPtr = findChannelByChannelNo( sessionInfoPtr, channelNo );
  	return( ( channelInfoPtr == NULL ) ? CHANNEL_NONE : \
  			( channelInfoPtr->flags & CHANNEL_FLAG_WRITECLOSED ) ? \
@@ -146,7 +175,7 @@
  	}
  
  CHECK_RETVAL_ENUM( CHANNEL ) STDC_NONNULL_ARG( ( 1 ) ) \
-@@ -780,7 +790,7 @@
+@@ -780,7 +799,7 @@
  										addrInfoLen );
  	return( ( channelInfoPtr == NULL ) ? CHANNEL_NONE : \
  			( channelInfoPtr->flags & CHANNEL_FLAG_WRITECLOSED ) ? \
@@ -155,7 +184,7 @@
  	}
  
  /****************************************************************************
-@@ -1001,12 +1011,22 @@
+@@ -1001,12 +1020,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 */
@@ -170,7 +199,7 @@
 +								 channelInfoPtr->channelID ) ? \
 +				CRYPT_OK : OK_SPECIAL );
 +		}
-+	if( channelType == CHANNEL_READ && !(channelInfoPtr->flags & CHANNEL_FLAG_WRITECLOSED))
++	if( channelType == CHANNEL_READ && !(channelInfoPtr->flags & CHANNEL_FLAG_WRITECLOSED) && isChannelActive( sessionInfoPtr, channelID ) )
 +		{
 +		REQUIRES( !( channelInfoPtr->flags & CHANNEL_FLAG_READCLOSED ) );
 +		channelInfoPtr->flags |= CHANNEL_FLAG_READCLOSED;
-- 
GitLab