📄 ssh.h
字号:
SSH_ATTRIBUTE_ACTIVE, /* Channel is active */
SSH_ATTRIBUTE_WINDOWCOUNT, /* Data window count */
SSH_ATTRIBUTE_ALTCHANNELNO, /* Secondary channel no. */
SSH_ATRIBUTE_LAST /* Last channel attribute */
} SSH_ATTRIBUTE_TYPE;
/* Check whether an algorithm ID is one of the above pseudo-algorithm
types */
#define isPseudoAlgo( algorithm ) \
( algorithm >= CRYPT_PSEUDOALGO_DHE && \
algorithm <= CRYPT_PSEUDOALGO_PAM )
/* Check whether a DH value is valid for a given server key size */
#define isValidDHsize( value, serverKeySize, extraLength ) \
( ( value ) > ( ( serverKeySize ) - 8 ) + ( extraLength ) && \
( value ) < ( ( serverKeySize ) + 2 ) + ( extraLength ) )
/****************************************************************************
* *
* SSH Structures *
* *
****************************************************************************/
/* Mapping of SSHv2 algorithm names to cryptlib algorithm IDs, in preferred
algorithm order */
typedef struct {
const char *name; /* Algorithm name */
const CRYPT_ALGO_TYPE algo; /* Algorithm ID */
} ALGO_STRING_INFO;
/* SSH handshake state information. This is passed around various
subfunctions that handle individual parts of the handshake */
typedef struct SH {
/* SSHv1 session state information/SSHv2 exchange hash */
BYTE cookie[ SSH2_COOKIE_SIZE ]; /* Anti-spoofing cookie */
BYTE sessionID[ CRYPT_MAX_HASHSIZE ]; /* Session ID/exchange hash */
int sessionIDlength;
CRYPT_CONTEXT iExchangeHashcontext; /* Hash of exchanged info */
/* Information needed to compute the session ID. SSHv1 requires the
host and server key modulus, SSHv2 requires the client and server DH
values (along with various other things, but these are hashed
inline). The SSHv2 values are in MPI-encoded form, so we need to
reserve a little extra room for the length and leading zero-padding.
Since the data fields are rather large and also disjoint, we alias
one to the other to save space */
BYTE clientKeyexValue[ CRYPT_MAX_PKCSIZE + 16 ];
BYTE serverKeyexValue[ CRYPT_MAX_PKCSIZE + 16 ];
int clientKeyexValueLength, serverKeyexValueLength;
#define hostModulus clientKeyexValue
#define serverModulus serverKeyexValue
#define hostModulusLength clientKeyexValueLength
#define serverModulusLength serverKeyexValueLength
/* Encryption algorithm and key information */
CRYPT_ALGO_TYPE pubkeyAlgo; /* Host signature algo */
BYTE secretValue[ CRYPT_MAX_PKCSIZE ]; /* Shared secret value */
int secretValueLength;
/* Short-term server key (SSHv1) or DH key agreement context (SSHv2),
and the client requested DH key size for the SSHv2 key exchange.
Alongside the actual key size, we also store the original encoded
form, which has to be hashed as part of the exchange hash. The
long-term host key is stored as the session info iKeyexCryptContext
for the client and privateKey for the server */
CRYPT_CONTEXT iServerCryptContext;
int serverKeySize, requestedServerKeySize;
BYTE encodedReqKeySizes[ UINT_SIZE * 3 ];
int encodedReqKeySizesLength;
/* Tables mapping SSHv2 algorithm names to cryptlib algorithm IDs.
These are declared once in ssh2.c and referred to here via pointers
to allow them to be static const, which is necessary in some
environments to get them into the read-only segment */
const FAR_BSS ALGO_STRING_INFO *algoStringPubkeyTbl;
/* Function pointers to handshaking functions. These are set up as
required depending on whether the protocol being used is v1 or v2,
and the session is client or server */
int ( *beginHandshake )( SESSION_INFO *sessionInfoPtr,
struct SH *handshakeInfo );
int ( *exchangeKeys )( SESSION_INFO *sessionInfoPtr,
struct SH *handshakeInfo );
int ( *completeHandshake )( SESSION_INFO *sessionInfoPtr,
struct SH *handshakeInfo );
} SSH_HANDSHAKE_INFO;
/* Channel number and ID used to mark an unused channel */
#define UNUSED_CHANNEL_NO CRYPT_ERROR
#define UNUSED_CHANNEL_ID 0
/****************************************************************************
* *
* SSH Functions *
* *
****************************************************************************/
/* Unlike SSL, SSH only hashes portions of the handshake, and even then not
complete packets but arbitrary bits and pieces. In order to perform the
hashing, we have to be able to bookmark positions in a stream to allow
the data at that point to be hashed once it's been encoded. The following
macros set and complete a bookmark.
When we create or continue a packet stream, the packet type is written
before we can set the bookmark. To handle this, we also provide a macro
that sets the bookmark for a full packet by adjusting for the packet type
that's already been written */
#define streamBookmarkSet( stream, pointer, offset ) \
pointer = sMemBufPtr( stream ); \
offset = stell( stream )
#define streamBookmarkSetFullPacket( stream, pointer, offset ) \
pointer = sMemBufPtr( stream ) - ID_SIZE; \
offset = stell( stream ) - ID_SIZE
#define streamBookmarkComplete( stream, offset ) \
offset = stell( stream ) - offset
/* Prototypes for functions in ssh2.c */
int readAlgoString( STREAM *stream, const ALGO_STRING_INFO *algoInfo,
CRYPT_ALGO_TYPE *algo, const BOOLEAN useFirstMatch,
void *errorInfo );
int writeAlgoString( STREAM *stream, const CRYPT_ALGO_TYPE algo );
int completeKeyex( SESSION_INFO *sessionInfoPtr,
SSH_HANDSHAKE_INFO *handshakeInfo,
const BOOLEAN isServer );
void openPacketStreamSSH( STREAM *stream, const SESSION_INFO *sessionInfoPtr,
const int bufferSize, const int packetType );
int continuePacketStreamSSH( STREAM *stream, const int packetType );
int processHelloSSH( SESSION_INFO *sessionInfoPtr,
SSH_HANDSHAKE_INFO *handshakeInfo, int *keyexLength,
const BOOLEAN isServer );
/* Prototypes for functions in ssh2_chn.c */
typedef enum { CHANNEL_NONE, CHANNEL_READ, CHANNEL_WRITE,
CHANNEL_BOTH, CHANNEL_LAST } CHANNEL_TYPE;
int createChannel( SESSION_INFO *sessionInfoPtr );
int addChannel( SESSION_INFO *sessionInfoPtr, const long channelNo,
const int maxPacketSize, const void *type,
const int typeLen, const void *arg1, const int arg1Len );
int deleteChannel( SESSION_INFO *sessionInfoPtr, const long channelNo,
const CHANNEL_TYPE channelType,
const BOOLEAN closeLastChannel );
int deleteChannelAddr( SESSION_INFO *sessionInfoPtr, const char *addrInfo,
const int addrInfoLen );
int selectChannel( SESSION_INFO *sessionInfoPtr, const long channelNo,
const CHANNEL_TYPE channelType );
int getCurrentChannelNo( const SESSION_INFO *sessionInfoPtr,
const CHANNEL_TYPE channelType );
CHANNEL_TYPE getChannelStatus( const SESSION_INFO *sessionInfoPtr,
const long channelNo );
CHANNEL_TYPE getChannelStatusAddr( const SESSION_INFO *sessionInfoPtr,
const char *addrInfo,
const int addrInfoLen );
int getChannelAttribute( const SESSION_INFO *sessionInfoPtr,
const CRYPT_ATTRIBUTE_TYPE attribute,
void *data, int *dataLength );
int setChannelAttribute( SESSION_INFO *sessionInfoPtr,
const CRYPT_ATTRIBUTE_TYPE attribute,
const void *data, const int dataLength );
int getChannelExtAttribute( const SESSION_INFO *sessionInfoPtr,
const SSH_ATTRIBUTE_TYPE attribute,
void *data, int *dataLength );
int setChannelExtAttribute( const SESSION_INFO *sessionInfoPtr,
const SSH_ATTRIBUTE_TYPE attribute,
const void *data, const int dataLength );
int enqueueResponse( SESSION_INFO *sessionInfoPtr, const int type,
const int noParams, const long channelNo,
const int param1, const int param2, const int param3 );
int sendEnqueuedResponse( SESSION_INFO *sessionInfoPtr, const int offset );
int enqueueChannelData( SESSION_INFO *sessionInfoPtr, const int type,
const long channelNo, const int param );
int appendChannelData( SESSION_INFO *sessionInfoPtr, const int offset );
/* Prototypes for functions in ssh2_msg.c */
int sendChannelOpen( SESSION_INFO *sessionInfoPtr );
int processChannelOpen( SESSION_INFO *sessionInfoPtr, STREAM *stream );
int processChannelControlMessage( SESSION_INFO *sessionInfoPtr,
STREAM *stream );
int closeChannel( SESSION_INFO *sessionInfoPtr,
const BOOLEAN closeLastChannel );
/* Prototypes for functions in ssh2_cry.c */
typedef enum { MAC_START, MAC_END, MAC_ALL, MAC_LAST } MAC_TYPE;
int initDHcontextSSH( CRYPT_CONTEXT *iCryptContext, int *keySize,
const void *keyData, const int keyDataLength,
const int requestedKeySize );
int initSecurityInfo( SESSION_INFO *sessionInfoPtr,
SSH_HANDSHAKE_INFO *handshakeInfo );
int initSecurityContextsSSH( SESSION_INFO *sessionInfoPtr );
void destroySecurityContextsSSH( SESSION_INFO *sessionInfoPtr );
int hashAsString( const CRYPT_CONTEXT iHashContext,
const BYTE *data, const int dataLength );
int hashAsMPI( const CRYPT_CONTEXT iHashContext, const BYTE *data,
const int dataLength );
int macPayload( const CRYPT_CONTEXT iMacContext, const long seqNo,
const BYTE *data, const int dataLength,
const int packetDataLength, const MAC_TYPE macType,
const int macLength, const BOOLEAN isRead );
/* Prototypes for functions in ssh2_rw.c */
int wrapPacketSSH2( SESSION_INFO *sessionInfoPtr, STREAM *stream,
const int offset );
int sendPacketSSH2( SESSION_INFO *sessionInfoPtr, STREAM *stream,
const BOOLEAN sendOnly );
int readPacketHeaderSSH2( SESSION_INFO *sessionInfoPtr,
const int expectedType, long *packetLength,
int *packetExtraLength,
READSTATE_INFO *readInfo );
int readPacketSSH2( SESSION_INFO *sessionInfoPtr, int expectedType,
const int minPacketSize );
int getDisconnectInfo( SESSION_INFO *sessionInfoPtr, STREAM *stream );
/* Prototypes for session mapping functions */
void initSSH1processing( SESSION_INFO *sessionInfoPtr,
SSH_HANDSHAKE_INFO *handshakeInfo,
const BOOLEAN isServer );
void initSSH2processing( SESSION_INFO *sessionInfoPtr,
SSH_HANDSHAKE_INFO *handshakeInfo,
const BOOLEAN isServer );
void initSSH2clientProcessing( SESSION_INFO *sessionInfoPtr,
SSH_HANDSHAKE_INFO *handshakeInfo );
void initSSH2serverProcessing( SESSION_INFO *sessionInfoPtr,
SSH_HANDSHAKE_INFO *handshakeInfo );
#ifndef USE_SSH1
#define initSSH1processing initSSH2processing
#endif /* USE_SSH1 */
#ifndef USE_SSH2
#define initSSH2processing initSSH1processing
#endif /* USE_SSH2 */
#endif /* _SSH_DEFINED */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -