📄 ssh2_chn.c
字号:
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 );
}
if( iterationCount >= FAILSAFE_ITERATIONS_MAX )
retIntError_Null();
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 */
int getChannelAttribute( const SESSION_INFO *sessionInfoPtr,
const CRYPT_ATTRIBUTE_TYPE attribute,
int *value )
{
const SSH_CHANNEL_INFO *channelInfoPtr = \
getCurrentChannelInfo( sessionInfoPtr, CHANNEL_READ );
assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
assert( isWritePtr( value, sizeof( int ) ) );
/* Clear return values */
*value = 0;
if( isNullChannel( channelInfoPtr ) )
return( CRYPT_ERROR_NOTFOUND );
switch( attribute )
{
case CRYPT_SESSINFO_SSH_CHANNEL:
*value = channelInfoPtr->channelID;
return( CRYPT_OK );
case CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE:
*value = isActiveChannel( channelInfoPtr ) ? TRUE : FALSE;
return( CRYPT_OK );
}
retIntError();
}
int getChannelAttributeString( const SESSION_INFO *sessionInfoPtr,
const CRYPT_ATTRIBUTE_TYPE attribute,
void *data, const int dataMaxLength,
int *dataLength )
{
const SSH_CHANNEL_INFO *channelInfoPtr = \
getCurrentChannelInfo( sessionInfoPtr, CHANNEL_READ );
assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
assert( ( data == NULL && dataMaxLength == 0 ) || \
isWritePtr( data, dataMaxLength ) );
assert( isWritePtr( dataLength, sizeof( int ) ) );
/* Clear return values */
if( data != NULL )
memset( data, 0, min( 8, dataMaxLength ) );
*dataLength = 0;
if( isNullChannel( channelInfoPtr ) )
return( CRYPT_ERROR_NOTFOUND );
switch( attribute )
{
case CRYPT_SESSINFO_SSH_CHANNEL_TYPE:
return( attributeCopyParams( data, dataMaxLength, dataLength,
channelInfoPtr->type,
channelInfoPtr->typeLen ) );
case CRYPT_SESSINFO_SSH_CHANNEL_ARG1:
return( attributeCopyParams( data, dataMaxLength, dataLength,
channelInfoPtr->arg1,
channelInfoPtr->arg1Len ) );
case CRYPT_SESSINFO_SSH_CHANNEL_ARG2:
return( attributeCopyParams( data, dataMaxLength, dataLength,
channelInfoPtr->arg2,
channelInfoPtr->arg2Len ) );
}
retIntError();
}
int getChannelExtAttribute( const SESSION_INFO *sessionInfoPtr,
const SSH_ATTRIBUTE_TYPE attribute,
void *data, const int dataMaxLength,
int *dataLength )
{
const SSH_CHANNEL_INFO *channelInfoPtr = \
getCurrentChannelInfo( sessionInfoPtr, CHANNEL_READ );
assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
assert( data == NULL && dataMaxLength == 0 );
assert( isWritePtr( dataLength, sizeof( int ) ) );
if( isNullChannel( channelInfoPtr ) )
return( CRYPT_ERROR_NOTFOUND );
switch( attribute )
{
case SSH_ATTRIBUTE_WINDOWCOUNT:
*dataLength = channelInfoPtr->windowCount;
return( CRYPT_OK );
}
retIntError();
}
int setChannelAttribute( SESSION_INFO *sessionInfoPtr,
const CRYPT_ATTRIBUTE_TYPE attribute,
const int value )
{
SSH_CHANNEL_INFO *channelInfoPtr;
assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
/* 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, value );
if( channelInfoPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
return( selectChannel( sessionInfoPtr, channelInfoPtr->writeChannelNo,
CHANNEL_WRITE ) );
}
retIntError();
}
int setChannelAttributeString( SESSION_INFO *sessionInfoPtr,
const CRYPT_ATTRIBUTE_TYPE attribute,
const void *data, const int dataLength )
{
SSH_CHANNEL_INFO *channelInfoPtr;
assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
assert( isReadPtr( data, dataLength ) && \
dataLength <= CRYPT_MAX_TEXTSIZE );
/* 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( attributeCopyParams( channelInfoPtr->type,
CRYPT_MAX_TEXTSIZE,
&channelInfoPtr->typeLen,
data, dataLength ) );
case CRYPT_SESSINFO_SSH_CHANNEL_ARG1:
return( attributeCopyParams( channelInfoPtr->arg1,
CRYPT_MAX_TEXTSIZE,
&channelInfoPtr->arg1Len,
data, dataLength ) );
case CRYPT_SESSINFO_SSH_CHANNEL_ARG2:
return( attributeCopyParams( channelInfoPtr->arg2,
CRYPT_MAX_TEXTSIZE,
&channelInfoPtr->arg2Len,
data, dataLength ) );
}
retIntError();
}
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 );
assert( isReadPtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
assert( data == NULL );
assert( ( attribute == SSH_ATTRIBUTE_ACTIVE && dataLength == TRUE ) || \
( attribute != SSH_ATTRIBUTE_ACTIVE && dataLength >= 0 ) );
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 );
}
retIntError();
}
/* 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:
retIntError();
}
sessionInfoPtr->maxPacketSize = channelInfoPtr->maxPacketSize;
return( CRYPT_OK );
}
/* Add/create/delete a channel */
int addChannel( SESSION_INFO *sessionInfoPtr, const long channelNo,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -