📄 ssh2_chn.c
字号:
/* If it's not an SSH channel. continue */
if( attributeListPtr->attribute != CRYPT_SESSINFO_SSH_CHANNEL )
continue;
/* It's an SSH channel, check whether it's the one that we're
after */
assert( attributeListPtr->valueLength == sizeof( SSH_CHANNEL_INFO ) );
channelInfoPtr = attributeListPtr->value;
if( channelInfoPtr->arg1Len == addrInfoLen && \
!memcmp( channelInfoPtr->arg1, addrInfo, addrInfoLen ) )
return( ( SSH_CHANNEL_INFO * ) channelInfoPtr );
}
return( NULL );
}
static const SSH_CHANNEL_INFO *getCurrentChannelInfo( const SESSION_INFO *sessionInfoPtr,
const CHANNEL_TYPE channelType )
{
static const SSH_CHANNEL_INFO nullChannel = \
{ UNUSED_CHANNEL_ID, UNUSED_CHANNEL_NO, CHANNEL_FLAG_NONE, \
0, 0 /*...*/ };
SSH_INFO *sshInfo = sessionInfoPtr->sessionSSH;
const SSH_CHANNEL_INFO *channelInfoPtr;
const int channelID = ( channelType == CHANNEL_READ ) ? \
sshInfo->currReadChannel : \
sshInfo->currWriteChannel;
/* If there's no channel open yet, return the null channel */
if( channelID == UNUSED_CHANNEL_ID )
return( ( SSH_CHANNEL_INFO * ) &nullChannel );
channelInfoPtr = findChannelInfoID( sessionInfoPtr,
( channelType == CHANNEL_READ ) ? \
sshInfo->currReadChannel : \
sshInfo->currWriteChannel );
return( ( channelInfoPtr == NULL ) ? \
( SSH_CHANNEL_INFO * ) &nullChannel : channelInfoPtr );
}
/****************************************************************************
* *
* Get/Set Channel Info *
* *
****************************************************************************/
/* Get the currently active channel */
int getCurrentChannelNo( const SESSION_INFO *sessionInfoPtr,
const CHANNEL_TYPE channelType )
{
const SSH_CHANNEL_INFO *channelInfoPtr = \
getCurrentChannelInfo( sessionInfoPtr, channelType );
assert( channelType == CHANNEL_READ || channelType == CHANNEL_WRITE );
return( ( channelType == CHANNEL_READ ) ? \
channelInfoPtr->readChannelNo : channelInfoPtr->writeChannelNo );
}
/* Get/set an attribute or SSH-specific internal attribute from the current
channel */
static int copyAttributeData( void *dest, int *destLen, const void *src,
const int srcLen, const BOOLEAN copyIn )
{
if( !copyIn && srcLen <= 0 )
return( CRYPT_ERROR_NOTFOUND );
if( srcLen <= 0 || srcLen > CRYPT_MAX_TEXTSIZE )
return( CRYPT_ERROR_BADDATA );
*destLen = srcLen;
if( dest != NULL )
memcpy( dest, src, srcLen );
return( CRYPT_OK );
}
int getChannelAttribute( const SESSION_INFO *sessionInfoPtr,
const CRYPT_ATTRIBUTE_TYPE attribute,
void *data, int *dataLength )
{
const SSH_CHANNEL_INFO *channelInfoPtr = \
getCurrentChannelInfo( sessionInfoPtr, CHANNEL_READ );
/* Clear return values */
if( data != NULL )
memset( data, 0, 8 );
*dataLength = 0;
if( isNullChannel( channelInfoPtr ) )
return( CRYPT_ERROR_NOTFOUND );
switch( attribute )
{
case CRYPT_SESSINFO_SSH_CHANNEL:
*dataLength = channelInfoPtr->channelID;
return( CRYPT_OK );
case CRYPT_SESSINFO_SSH_CHANNEL_TYPE:
return( copyAttributeData( data, dataLength,
channelInfoPtr->type,
channelInfoPtr->typeLen, FALSE ) );
case CRYPT_SESSINFO_SSH_CHANNEL_ARG1:
return( copyAttributeData( data, dataLength,
channelInfoPtr->arg1,
channelInfoPtr->arg1Len, FALSE ) );
case CRYPT_SESSINFO_SSH_CHANNEL_ARG2:
return( copyAttributeData( data, dataLength,
channelInfoPtr->arg2,
channelInfoPtr->arg2Len, FALSE ) );
case CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE:
*dataLength = isActiveChannel( channelInfoPtr ) ? TRUE : FALSE;
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
int setChannelAttribute( SESSION_INFO *sessionInfoPtr,
const CRYPT_ATTRIBUTE_TYPE attribute,
const void *data, const int dataLength )
{
SSH_CHANNEL_INFO *channelInfoPtr;
/* If we're setting the channel ID this doesn't change any channel
attribute but selects the one with the given ID */
if( attribute == CRYPT_SESSINFO_SSH_CHANNEL )
{
channelInfoPtr = findChannelInfoID( sessionInfoPtr, dataLength );
if( channelInfoPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
return( selectChannel( sessionInfoPtr, channelInfoPtr->writeChannelNo,
CHANNEL_WRITE ) );
}
/* Set the attribute for the currently-active channel */
channelInfoPtr = ( SSH_CHANNEL_INFO * ) \
getCurrentChannelInfo( sessionInfoPtr, CHANNEL_READ );
if( isNullChannel( channelInfoPtr ) )
return( CRYPT_ERROR_NOTFOUND );
switch( attribute )
{
case CRYPT_SESSINFO_SSH_CHANNEL_TYPE:
return( copyAttributeData( channelInfoPtr->type,
&channelInfoPtr->typeLen,
data, dataLength, TRUE ) );
case CRYPT_SESSINFO_SSH_CHANNEL_ARG1:
return( copyAttributeData( channelInfoPtr->arg1,
&channelInfoPtr->arg1Len,
data, dataLength, TRUE ) );
case CRYPT_SESSINFO_SSH_CHANNEL_ARG2:
return( copyAttributeData( channelInfoPtr->arg2,
&channelInfoPtr->arg2Len,
data, dataLength, TRUE ) );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
int getChannelExtAttribute( const SESSION_INFO *sessionInfoPtr,
const SSH_ATTRIBUTE_TYPE attribute,
void *data, int *dataLength )
{
const SSH_CHANNEL_INFO *channelInfoPtr = \
getCurrentChannelInfo( sessionInfoPtr, CHANNEL_READ );
if( isNullChannel( channelInfoPtr ) )
return( CRYPT_ERROR_NOTFOUND );
switch( attribute )
{
case SSH_ATTRIBUTE_WINDOWCOUNT:
*dataLength = channelInfoPtr->windowCount;
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
int setChannelExtAttribute( const SESSION_INFO *sessionInfoPtr,
const SSH_ATTRIBUTE_TYPE attribute,
const void *data, const int dataLength )
{
SSH_CHANNEL_INFO *channelInfoPtr = ( SSH_CHANNEL_INFO * ) \
getCurrentChannelInfo( sessionInfoPtr, CHANNEL_READ );
if( isNullChannel( channelInfoPtr ) )
return( CRYPT_ERROR_NOTFOUND );
switch( attribute )
{
case SSH_ATTRIBUTE_ACTIVE:
channelInfoPtr->flags |= CHANNEL_FLAG_ACTIVE;
return( CRYPT_OK );
case SSH_ATTRIBUTE_WINDOWCOUNT:
channelInfoPtr->windowCount = dataLength;
return( CRYPT_OK );
case SSH_ATTRIBUTE_ALTCHANNELNO:
channelInfoPtr->writeChannelNo = dataLength;
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
/* Get the status of a channel: Not open, write-side closed, open */
CHANNEL_TYPE getChannelStatus( const SESSION_INFO *sessionInfoPtr,
const long channelNo )
{
SSH_CHANNEL_INFO *channelInfoPtr;
channelInfoPtr = findChannelInfo( sessionInfoPtr, channelNo );
return( ( channelInfoPtr == NULL ) ? CHANNEL_NONE : \
( channelInfoPtr->flags & CHANNEL_FLAG_WRITECLOSED ) ? \
CHANNEL_READ : CHANNEL_BOTH );
}
CHANNEL_TYPE getChannelStatusAddr( const SESSION_INFO *sessionInfoPtr,
const char *addrInfo,
const int addrInfoLen )
{
const SSH_CHANNEL_INFO *channelInfoPtr;
channelInfoPtr = findChannelInfoAddr( sessionInfoPtr, addrInfo,
addrInfoLen );
return( ( channelInfoPtr == NULL ) ? CHANNEL_NONE : \
( channelInfoPtr->flags & CHANNEL_FLAG_WRITECLOSED ) ? \
CHANNEL_READ : CHANNEL_BOTH );
}
/****************************************************************************
* *
* Channel Management Functions *
* *
****************************************************************************/
/* Select a channel */
int selectChannel( SESSION_INFO *sessionInfoPtr, const long channelNo,
const CHANNEL_TYPE channelType )
{
SSH_INFO *sshInfo = sessionInfoPtr->sessionSSH;
SSH_CHANNEL_INFO *channelInfoPtr;
/* Locate the channel and update the current channel info. We allow a
special channel-type indicator of CHANNEL_NONE to allow the selection
of not-yet-activated channels. Since it's possible to have per-
channel packet sizes, we also update the overall packet size value */
channelInfoPtr = findChannelInfo( sessionInfoPtr, channelNo );
if( channelInfoPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
if( !isActiveChannel( channelInfoPtr ) && channelType != CHANNEL_NONE )
return( CRYPT_ERROR_NOTINITED );
switch( channelType )
{
case CHANNEL_READ:
sshInfo->currReadChannel = channelInfoPtr->channelID;
break;
case CHANNEL_WRITE:
sshInfo->currWriteChannel = channelInfoPtr->channelID;
break;
case CHANNEL_BOTH:
case CHANNEL_NONE:
sshInfo->currReadChannel = \
sshInfo->currWriteChannel = channelInfoPtr->channelID;
break;
default:
assert( NOTREACHED );
return( CRYPT_ERROR_NOTINITED );
}
sessionInfoPtr->maxPacketSize = channelInfoPtr->maxPacketSize;
return( CRYPT_OK );
}
/* Add/create/delete a channel */
int addChannel( SESSION_INFO *sessionInfoPtr, const long channelNo,
const int maxPacketSize, const void *type,
const int typeLen, const void *arg1, const int arg1Len )
{
ATTRIBUTE_LIST *attributeListPtr;
SSH_INFO *sshInfo = sessionInfoPtr->sessionSSH;
SSH_CHANNEL_INFO channelInfo;
int channelCount = 0, status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -