22 #define CHANNEL_FLAG_NONE 0x00
23 #define CHANNEL_FLAG_ACTIVE 0x01
24 #define CHANNEL_FLAG_WRITECLOSED 0x02
69 #define isNullChannel( channelInfoPtr ) \
70 ( ( channelInfoPtr )->readChannelNo == UNUSED_CHANNEL_NO )
71 #define isActiveChannel( channelInfoPtr ) \
72 ( channelInfoPtr->flags & CHANNEL_FLAG_ACTIVE )
76 #ifdef USE_SSH_EXTENDED
77 #define SSH_MAX_CHANNELS 4
79 #define SSH_MAX_CHANNELS 1
109 ( excludedChannelID > 0 && \
114 attributeListPtr != NULL && \
116 attributeListPtr = attributeListPtr->
next, iterationCount++ )
127 channelInfoPtr = attributeListPtr->value;
129 channelInfoPtr->
channelID != excludedChannelID )
152 CRYPT_ATTRIBUTE_NONE };
170 attributeType = channelInfoPtr->
cursorPos = \
171 CRYPT_SESSINFO_SSH_CHANNEL;
183 for( doContinue =
TRUE, iterationCount = 0;
193 attributeOrderList[ orderIndex ] != attributeType && \
211 attributeType = ( orderIndex <= 0 ) ? \
213 attributeOrderList[ orderIndex - 1 ];
216 attributeType = attributeOrderList[ orderIndex + 1 ];
227 switch( attributeType )
236 if( channelInfoPtr->arg1Len > 0 )
241 if( channelInfoPtr->arg2Len > 0 )
249 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
274 ( channelNo >= 0 && channelNo <= LONG_MAX ) );
278 attributeListPtr != NULL && \
280 attributeListPtr = attributeListPtr->
next, iterationCount++ )
291 channelInfoPtr = attributeListPtr->value;
298 return( attributeListPtr );
302 return( attributeListPtr );
314 IN const long channelNo )
317 findChannelAttr( sessionInfoPtr, channelNo );
322 ( channelNo >= 0 && channelNo <= LONG_MAX ) );
324 return( ( attributeListPtr == NULL ) ? NULL : attributeListPtr->value );
340 attributeListPtr != NULL && \
342 attributeListPtr = attributeListPtr->
next, iterationCount++ )
353 channelInfoPtr = attributeListPtr->value;
354 if( channelInfoPtr->
channelID == channelID )
365 const char *addrInfo,
373 assert(
isReadPtr( addrInfo, addrInfoLen ) );
379 attributeListPtr != NULL && \
381 attributeListPtr = attributeListPtr->
next, iterationCount++ )
392 channelInfoPtr = attributeListPtr->value;
393 if( channelInfoPtr->arg1Len == addrInfoLen && \
394 !memcmp( channelInfoPtr->arg1, addrInfo, addrInfoLen ) )
412 const int channelID = ( channelType ==
CHANNEL_READ ) ? \
425 channelInfoPtr = findChannelByID( sessionInfoPtr,
429 return( ( channelInfoPtr == NULL ) ? \
446 getCurrentChannelInfo( sessionInfoPtr, channelType );
461 int getChannelAttribute(
const SESSION_INFO *sessionInfoPtr,
495 int getChannelAttributeS(
const SESSION_INFO *sessionInfoPtr,
506 assert( ( data == NULL && dataMaxLength == 0 ) || \
508 assert(
isWritePtr( dataLength,
sizeof(
int ) ) );
511 REQUIRES( ( data == NULL && dataMaxLength == 0 ) || \
513 dataMaxLength > 0 && \
519 memset( data, 0,
min( 16, dataMaxLength ) );
528 return( attributeCopyParams( data, dataMaxLength, dataLength,
529 channelInfoPtr->type,
530 channelInfoPtr->typeLen ) );
533 return( attributeCopyParams( data, dataMaxLength, dataLength,
534 channelInfoPtr->arg1,
535 channelInfoPtr->arg1Len ) );
538 return( attributeCopyParams( data, dataMaxLength, dataLength,
539 channelInfoPtr->arg2,
540 channelInfoPtr->arg2Len ) );
547 int getChannelExtAttribute(
const SESSION_INFO *sessionInfoPtr,
597 channelInfoPtr = findChannelByID( sessionInfoPtr, value );
598 if( channelInfoPtr == NULL )
600 return( selectChannel( sessionInfoPtr, channelInfoPtr->
writeChannelNo,
610 IN_BUFFER( dataLength )
const void *data,
630 return( attributeCopyParams( channelInfoPtr->type,
632 &channelInfoPtr->typeLen,
633 data, dataLength ) );
636 return( attributeCopyParams( channelInfoPtr->arg1,
638 &channelInfoPtr->arg1Len,
639 data, dataLength ) );
642 return( attributeCopyParams( channelInfoPtr->arg2,
644 &channelInfoPtr->arg2Len,
645 data, dataLength ) );
652 int setChannelExtAttribute(
const SESSION_INFO *sessionInfoPtr,
663 value >= 0 && value < INT_MAX ) );
702 REQUIRES_EXT( ( channelNo >= 0 && channelNo <= LONG_MAX ), \
705 channelInfoPtr = findChannelByChannelNo( sessionInfoPtr, channelNo );
719 assert(
isReadPtr( addrInfo, addrInfoLen ) );
724 channelInfoPtr = findChannelByAddr( sessionInfoPtr, addrInfo,
741 IN const long channelNo,
744 SSH_INFO *sshInfo = sessionInfoPtr->sessionSSH;
750 ( channelNo >= 0 && channelNo <= LONG_MAX ) );
763 channelInfoPtr = findChannelByChannelNo( sessionInfoPtr, channelNo );
764 if( channelInfoPtr == NULL )
768 switch( channelType )
781 sshInfo->currWriteChannel = channelInfoPtr->
channelID;
787 sessionInfoPtr->maxPacketSize = channelInfoPtr->
maxPacketSize;
796 IN const long channelNo,
804 SSH_INFO *sshInfo = sessionInfoPtr->sessionSSH;
806 int channelCount, iterationCount,
status;
810 assert( ( arg1 == NULL && arg1Len == 0 ) ||
813 REQUIRES( channelNo >= 0 && channelNo <= LONG_MAX );
816 REQUIRES( ( arg1 == NULL && arg1Len == 0 ) || \
821 if( findChannelByChannelNo( sessionInfoPtr, channelNo ) != NULL )
825 "Attempt to add duplicate channel %lX", channelNo ) );
837 for( channelCount = 0, \
838 attributeListPtr = sessionInfoPtr->attributeList, \
840 attributeListPtr != NULL && \
842 attributeListPtr = attributeListPtr->
next, iterationCount++ )
852 "Maximum number (%d) of SSH channels reached",
862 &channelInfo.typeLen, type, typeLen );
865 &channelInfo.arg1Len, arg1, arg1Len );
868 status = addSessionInfoComposite( &sessionInfoPtr->attributeList,
881 return( selectChannel( sessionInfoPtr, channelNo,
CHANNEL_NONE ) );
887 SSH_INFO *sshInfo = sessionInfoPtr->sessionSSH;
896 for( iterationCount = 0;
897 findChannelByChannelNo( sessionInfoPtr, \
905 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
908 return( addChannel( sessionInfoPtr, sshInfo->
nextChannelNo++,
910 "session", 7, NULL, 0 ) );
915 IN const long channelNo,
919 SSH_INFO *sshInfo = sessionInfoPtr->sessionSSH;
926 REQUIRES( channelNo >= 0 && channelNo <= LONG_MAX );
930 attributeListPtr = findChannelAttr( sessionInfoPtr, channelNo );
931 if( attributeListPtr == NULL )
934 channelInfoPtr = attributeListPtr->value;
940 if( !deleteLastChannel && \
941 !isChannelActive( sessionInfoPtr, channelID ) )
953 return( isChannelActive( sessionInfoPtr, \
957 deleteSessionInfo( &sessionInfoPtr->attributeList,
958 &sessionInfoPtr->attributeListCurrent,
978 IN_BUFFER( addrInfoLen )
const char *addrInfo,
984 assert(
isReadPtr( addrInfo, addrInfoLen ) );
988 channelInfoPtr = findChannelByAddr( sessionInfoPtr, addrInfo,
990 if( channelInfoPtr == NULL )
997 channelInfoPtr->arg1Len = 0;
1017 IN_RANGE( 0, 4 )
const int noParams,
1018 IN const long channelNo,
1027 REQUIRES( type > 0 && type <= 0xFF );
1028 REQUIRES( noParams >= 0 && noParams <= 4 );
1030 REQUIRES( channelNo >= 0 && channelNo <= LONG_MAX );
1039 status = writeUint32( &stream, channelNo );
1041 status = writeUint32( &stream, param1 );
1043 status = writeUint32( &stream, param2 );
1045 status = writeUint32( &stream, param3 );
1047 respPtr->
dataLen = stell( &stream );
1048 sMemDisconnect( &stream );
1076 int sendBufOffset = assembleOnly ? offset : sessionInfoPtr->sendBufPos;
1080 assert( responseSize == NULL || \
1084 ( offset >= 0 && offset < sessionInfoPtr->sendBufSize && \
1085 responseSize != NULL ) );
1086 REQUIRES( sendBufOffset >= 0 && offset < sessionInfoPtr->sendBufSize );
1097 "Buffer packet size" );
1100 if( responseSize != NULL )
1107 if( assembleOnly && !sessionInfoPtr->partialWrite && \
1108 ( sendBufOffset > sessionInfoPtr->sendBufStartOfs ) )
1115 sessionInfoPtr->sendBufSize );
1117 ENSURES( ( sendBufOffset <= sessionInfoPtr->sendBufStartOfs ) || \
1118 ( sessionInfoPtr->partialWrite && \
1121 sessionInfoPtr->sendBufSize ) );
1129 sendBufOffset == sessionInfoPtr->sendBufStartOfs )
1132 adjustedStartOffset =
TRUE;
1138 sessionInfoPtr->sendBufSize - sendBufOffset,
1139 sessionInfoPtr->sendBufSize ) );
1140 sMemOpen( &stream, sessionInfoPtr->sendBuffer + sendBufOffset,
1141 sessionInfoPtr->sendBufSize - sendBufOffset );
1143 status = sputc( &stream, respPtr->
type );
1147 status = swrite( &stream, respPtr->data, respPtr->
dataLen );
1150 status = wrapPacketSSH2( sessionInfoPtr, &stream, 0,
FALSE,
TRUE );
1152 encodedResponseSize = stell( &stream );
1155 sMemDisconnect( &stream );
1167 sMemDisconnect( &stream );
1168 *responseSize = encodedResponseSize;
1178 status = sendPacketSSH2( sessionInfoPtr, &stream,
TRUE );
1179 sMemDisconnect( &stream );
1187 sMemDisconnect( &stream );
1188 if( adjustedStartOffset )
1197 sessionInfoPtr->sendBufPos = encodedResponseSize;
1202 sessionInfoPtr->sendBufPos += encodedResponseSize;
1204 sessionInfoPtr->partialWrite =
TRUE;
1205 return( putSessionData( sessionInfoPtr, NULL, 0, &dummy ) );
1213 return( encodeSendResponse( sessionInfoPtr,
CRYPT_UNUSED, NULL ) );
1226 IN const long channelNo,
1233 REQUIRES( type > 0 && type <= 0xFF );
1234 REQUIRES( channelNo >= 0 && channelNo <= LONG_MAX );
1236 status = enqueueResponse( sessionInfoPtr, type, 2, channelNo, param,
1240 return( encodeSendResponse( sessionInfoPtr,
CRYPT_UNUSED, NULL ) );
1258 int channelDataSize,
status;
1262 REQUIRES( offset >= 0 && offset < sessionInfoPtr->sendBufSize );
1264 status = encodeSendResponse( sessionInfoPtr, offset, &channelDataSize );