20 #error The SSHv1 protocol is insecure and obsolete, and this code is completely
21 #error unsupported. You should only enable this code if it's absolutely necessary,
22 #error and your warranty is void when you do so. Use this code at your own risk.
27 #define getPadLength( length ) \
28 ( 8 - ( ( ID_SIZE + ( length ) + SSH1_CRC_SIZE ) & 7 ) )
43 static void longReverse(
unsigned long *
buffer,
int count )
45 #if defined( SYSTEM_64BIT )
46 BYTE *bufPtr = (
BYTE * ) buffer, temp;
48 assert( ( count % 4 ) == 0 );
57 temp =
value = *buffer & 0xFFFFFFFFUL;
59 ( (
value & 0x00FF00FFUL ) << 8 );
62 buffer = (
unsigned long * ) ( (
BYTE * ) buffer + 4 );
71 bufPtr[ 3 ] = bufPtr[ 0 ];
74 bufPtr[ 2 ] = bufPtr[ 1 ];
78 #elif defined( __WIN32__ )
79 assert( ( count % 4 ) == 0 );
98 assert( ( count % 4 ) == 0 );
99 assert(
sizeof(
unsigned long ) == 4 );
101 count /=
sizeof(
unsigned long );
105 value = ( ( value & 0xFF00FF00UL ) >> 8 ) | \
106 ( ( value & 0x00FF00FFUL ) << 8 );
120 static const FAR_BSS unsigned long crc32table[] = {
121 0x00000000UL, 0x77073096UL, 0xEE0E612CUL, 0x990951BAUL,
122 0x076DC419UL, 0x706AF48FUL, 0xE963A535UL, 0x9E6495A3UL,
123 0x0EDB8832UL, 0x79DCB8A4UL, 0xE0D5E91EUL, 0x97D2D988UL,
124 0x09B64C2BUL, 0x7EB17CBDUL, 0xE7B82D07UL, 0x90BF1D91UL,
125 0x1DB71064UL, 0x6AB020F2UL, 0xF3B97148UL, 0x84BE41DEUL,
126 0x1ADAD47DUL, 0x6DDDE4EBUL, 0xF4D4B551UL, 0x83D385C7UL,
127 0x136C9856UL, 0x646BA8C0UL, 0xFD62F97AUL, 0x8A65C9ECUL,
128 0x14015C4FUL, 0x63066CD9UL, 0xFA0F3D63UL, 0x8D080DF5UL,
129 0x3B6E20C8UL, 0x4C69105EUL, 0xD56041E4UL, 0xA2677172UL,
130 0x3C03E4D1UL, 0x4B04D447UL, 0xD20D85FDUL, 0xA50AB56BUL,
131 0x35B5A8FAUL, 0x42B2986CUL, 0xDBBBC9D6UL, 0xACBCF940UL,
132 0x32D86CE3UL, 0x45DF5C75UL, 0xDCD60DCFUL, 0xABD13D59UL,
133 0x26D930ACUL, 0x51DE003AUL, 0xC8D75180UL, 0xBFD06116UL,
134 0x21B4F4B5UL, 0x56B3C423UL, 0xCFBA9599UL, 0xB8BDA50FUL,
135 0x2802B89EUL, 0x5F058808UL, 0xC60CD9B2UL, 0xB10BE924UL,
136 0x2F6F7C87UL, 0x58684C11UL, 0xC1611DABUL, 0xB6662D3DUL,
137 0x76DC4190UL, 0x01DB7106UL, 0x98D220BCUL, 0xEFD5102AUL,
138 0x71B18589UL, 0x06B6B51FUL, 0x9FBFE4A5UL, 0xE8B8D433UL,
139 0x7807C9A2UL, 0x0F00F934UL, 0x9609A88EUL, 0xE10E9818UL,
140 0x7F6A0DBBUL, 0x086D3D2DUL, 0x91646C97UL, 0xE6635C01UL,
141 0x6B6B51F4UL, 0x1C6C6162UL, 0x856530D8UL, 0xF262004EUL,
142 0x6C0695EDUL, 0x1B01A57BUL, 0x8208F4C1UL, 0xF50FC457UL,
143 0x65B0D9C6UL, 0x12B7E950UL, 0x8BBEB8EAUL, 0xFCB9887CUL,
144 0x62DD1DDFUL, 0x15DA2D49UL, 0x8CD37CF3UL, 0xFBD44C65UL,
145 0x4DB26158UL, 0x3AB551CEUL, 0xA3BC0074UL, 0xD4BB30E2UL,
146 0x4ADFA541UL, 0x3DD895D7UL, 0xA4D1C46DUL, 0xD3D6F4FBUL,
147 0x4369E96AUL, 0x346ED9FCUL, 0xAD678846UL, 0xDA60B8D0UL,
148 0x44042D73UL, 0x33031DE5UL, 0xAA0A4C5FUL, 0xDD0D7CC9UL,
149 0x5005713CUL, 0x270241AAUL, 0xBE0B1010UL, 0xC90C2086UL,
150 0x5768B525UL, 0x206F85B3UL, 0xB966D409UL, 0xCE61E49FUL,
151 0x5EDEF90EUL, 0x29D9C998UL, 0xB0D09822UL, 0xC7D7A8B4UL,
152 0x59B33D17UL, 0x2EB40D81UL, 0xB7BD5C3BUL, 0xC0BA6CADUL,
153 0xEDB88320UL, 0x9ABFB3B6UL, 0x03B6E20CUL, 0x74B1D29AUL,
154 0xEAD54739UL, 0x9DD277AFUL, 0x04DB2615UL, 0x73DC1683UL,
155 0xE3630B12UL, 0x94643B84UL, 0x0D6D6A3EUL, 0x7A6A5AA8UL,
156 0xE40ECF0BUL, 0x9309FF9DUL, 0x0A00AE27UL, 0x7D079EB1UL,
157 0xF00F9344UL, 0x8708A3D2UL, 0x1E01F268UL, 0x6906C2FEUL,
158 0xF762575DUL, 0x806567CBUL, 0x196C3671UL, 0x6E6B06E7UL,
159 0xFED41B76UL, 0x89D32BE0UL, 0x10DA7A5AUL, 0x67DD4ACCUL,
160 0xF9B9DF6FUL, 0x8EBEEFF9UL, 0x17B7BE43UL, 0x60B08ED5UL,
161 0xD6D6A3E8UL, 0xA1D1937EUL, 0x38D8C2C4UL, 0x4FDFF252UL,
162 0xD1BB67F1UL, 0xA6BC5767UL, 0x3FB506DDUL, 0x48B2364BUL,
163 0xD80D2BDAUL, 0xAF0A1B4CUL, 0x36034AF6UL, 0x41047A60UL,
164 0xDF60EFC3UL, 0xA867DF55UL, 0x316E8EEFUL, 0x4669BE79UL,
165 0xCB61B38CUL, 0xBC66831AUL, 0x256FD2A0UL, 0x5268E236UL,
166 0xCC0C7795UL, 0xBB0B4703UL, 0x220216B9UL, 0x5505262FUL,
167 0xC5BA3BBEUL, 0xB2BD0B28UL, 0x2BB45A92UL, 0x5CB36A04UL,
168 0xC2D7FFA7UL, 0xB5D0CF31UL, 0x2CD99E8BUL, 0x5BDEAE1DUL,
169 0x9B64C2B0UL, 0xEC63F226UL, 0x756AA39CUL, 0x026D930AUL,
170 0x9C0906A9UL, 0xEB0E363FUL, 0x72076785UL, 0x05005713UL,
171 0x95BF4A82UL, 0xE2B87A14UL, 0x7BB12BAEUL, 0x0CB61B38UL,
172 0x92D28E9BUL, 0xE5D5BE0DUL, 0x7CDCEFB7UL, 0x0BDBDF21UL,
173 0x86D3D2D4UL, 0xF1D4E242UL, 0x68DDB3F8UL, 0x1FDA836EUL,
174 0x81BE16CDUL, 0xF6B9265BUL, 0x6FB077E1UL, 0x18B74777UL,
175 0x88085AE6UL, 0xFF0F6A70UL, 0x66063BCAUL, 0x11010B5CUL,
176 0x8F659EFFUL, 0xF862AE69UL, 0x616BFFD3UL, 0x166CCF45UL,
177 0xA00AE278UL, 0xD70DD2EEUL, 0x4E048354UL, 0x3903B3C2UL,
178 0xA7672661UL, 0xD06016F7UL, 0x4969474DUL, 0x3E6E77DBUL,
179 0xAED16A4AUL, 0xD9D65ADCUL, 0x40DF0B66UL, 0x37D83BF0UL,
180 0xA9BCAE53UL, 0xDEBB9EC5UL, 0x47B2CF7FUL, 0x30B5FFE9UL,
181 0xBDBDF21CUL, 0xCABAC28AUL, 0x53B39330UL, 0x24B4A3A6UL,
182 0xBAD03605UL, 0xCDD70693UL, 0x54DE5729UL, 0x23D967BFUL,
183 0xB3667A2EUL, 0xC4614AB8UL, 0x5D681B02UL, 0x2A6F2B94UL,
184 0xB40BBE37UL, 0xC30C8EA1UL, 0x5A05DF1BUL, 0x2D02EF8DUL
189 unsigned long crc32 = 0;
193 crc32 = crc32table[ (
int ) ( crc32 ^ data[ i ] ) & 0xFF ] ^ ( crc32 >> 8 );
206 static unsigned long calculateTruncatedMAC(
const CRYPT_CONTEXT iMacContext,
208 const int dataLength )
212 unsigned long macValue;
283 static long getAlgorithmMask(
void )
301 static int encodeString(
BYTE *buffer,
const BYTE *
string,
305 const int length = ( stringLength > 0 ) ? stringLength : strlen(
string );
310 memcpy( bufPtr,
string, length );
329 hashFunction( hashInfo, NULL, handshakeInfo->hostModulus,
330 handshakeInfo->hostModulusLength, HASH_START );
331 hashFunction( hashInfo, NULL, handshakeInfo->serverModulus,
332 handshakeInfo->serverModulusLength, HASH_CONTINUE );
342 const void *
n,
const int nLength,
343 const void *e,
int eLength )
355 hashFunction( hashInfo, fingerPrint, e, eLength, HASH_END );
356 if( attributeListPtr == NULL )
360 fingerPrint, hashSize ) );
365 memcmp( attributeListPtr->value, fingerPrint, hashSize ) )
367 "Server key fingerprint doesn't match requested "
374 static void generateChallengeResponse(
BYTE *response,
376 const BYTE *challenge )
397 const void *data,
const int dataLength,
401 BYTE *dataPtr = (
BYTE * ) data, *ePtr;
402 int nominalLength, eLength, nLength;
404 nominalLength = ( int )
mgetLong( dataPtr );
406 if( nominalLength <
bitsToBytes( MIN_PKCSIZE_BITS ) || \
409 "Invalid public key size %d", nominalLength );
410 eLength = mgetWord( dataPtr );
415 "Invalid exponent size %d for key size %d", eLength,
419 nLength = mgetWord( dataPtr );
421 if( nLength != nominalLength )
423 "Public key size %d doesn't match modulus size %d",
424 nominalLength, nLength );
427 memcpy( handshakeInfo->serverModulus, dataPtr, nLength );
428 handshakeInfo->serverModulusLength = nLength;
432 memcpy( handshakeInfo->hostModulus, dataPtr, nLength );
433 handshakeInfo->hostModulusLength = nLength;
435 if( sessionInfoPtr != NULL )
439 status = processKeyFingerprint( sessionInfoPtr, dataPtr, nLength,
451 static int initSecurityInfoSSH1(
SESSION_INFO *sessionInfoPtr,
458 status = initSecurityContextsSSH( sessionInfoPtr );
482 handshakeInfo->secretValue + 16 : handshakeInfo->secretValue,
542 longReverse( (
unsigned long * ) buffer, length );
546 longReverse( (
unsigned long * ) buffer, length );
551 const BYTE *buffer,
const int length )
554 BYTE *bufPtr = (
BYTE * ) buffer + dataLength;
555 unsigned long crc32, storedCrc32;
562 buffer, dataLength );
564 crc32 = calculateCRC( buffer, dataLength );
566 return( ( crc32 == storedCrc32 ) ?
TRUE :
FALSE );
569 static int getDisconnectInfoSSH1(
SESSION_INFO *sessionInfoPtr,
BYTE *bufPtr )
577 "Invalid error information size %d", length );
579 "Received SSHv1 server message: " );
580 memcpy( sessionInfoPtr->errorMessage + 31, bufPtr, length );
581 sessionInfoPtr->errorMessage[ 31 +
length ] =
'\0';
586 static int readPacketSSH1(
SESSION_INFO *sessionInfoPtr,
int expectedType )
588 BYTE *bufPtr = sessionInfoPtr->receiveBuffer;
590 int padLength, packetType, iterationCount = 0;
599 const BYTE *lengthPtr = bufPtr;
614 status = readFixedHeader( sessionInfoPtr,
LENGTH_SIZE );
619 padLength = 8 - ( length & 7 );
623 "Invalid packet length %d", length );
624 status = sread( &sessionInfoPtr->
stream,
625 sessionInfoPtr->receiveBuffer, padLength + length );
628 sNetGetErrorInfo( &sessionInfoPtr->
stream,
632 if( status != padLength + length )
634 "Timeout during packet remainder read, only got %d of "
635 "%d bytes", status, padLength + length );
638 status = decryptPayload( sessionInfoPtr,
639 sessionInfoPtr->receiveBuffer,
640 padLength + length );
644 if( !checksumPayload( sessionInfoPtr, sessionInfoPtr->receiveBuffer,
645 padLength + length ) )
653 "Bad message checksum" );
654 packetType = sessionInfoPtr->receiveBuffer[ padLength ];
658 if( iterationCount >= 1000 )
660 "Peer sent excessive number of no-op packets" );
666 return( getDisconnectInfoSSH1( sessionInfoPtr,
667 sessionInfoPtr->receiveBuffer + padLength +
ID_SIZE ) );
687 "Server indicated incorrect password was used" );
698 "Server indicated incorrect RSA key was used" );
709 *bufPtr++ = packetType;
713 if( packetType != expectedType )
715 "Invalid packet type 0x%02X, expected 0x%02X",
716 packetType, expectedType );
721 memmove( bufPtr, sessionInfoPtr->receiveBuffer + padLength +
ID_SIZE,
735 static int sendPacketSsh1(
SESSION_INFO *sessionInfoPtr,
736 const int packetType,
const int dataLength,
740 BYTE *bufStartPtr = sessionInfoPtr->sendBuffer + \
742 BYTE *bufPtr = bufStartPtr;
745 const int padLength = getPadLength( dataLength );
755 mputLong( bufPtr, (
long ) length );
758 &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
759 bufPtr[ padLength ] = packetType;
764 padLength +
ID_SIZE + dataLength );
766 crc32 = calculateCRC( bufPtr, padLength +
ID_SIZE + dataLength );
774 longReverse( (
unsigned long * ) ( bufStartPtr +
LENGTH_SIZE ),
775 padLength + length );
779 padLength + length );
781 longReverse( (
unsigned long * ) ( bufStartPtr +
LENGTH_SIZE ),
782 padLength + length );
797 memmove( sessionInfoPtr->sendBuffer, bufStartPtr,
801 status = swrite( &sessionInfoPtr->
stream, bufStartPtr,
805 sNetGetErrorInfo( &sessionInfoPtr->
stream,
820 static int beginClientHandshake(
SESSION_INFO *sessionInfoPtr,
843 if( sessionInfoPtr->receiveBuffer[ 2 ] < \
847 status = swrite( &sessionInfoPtr->
stream, sessionInfoPtr->sendBuffer,
848 strlen( sessionInfoPtr->sendBuffer ) );
851 sNetGetErrorInfo( &sessionInfoPtr->
stream,
897 bufPtr = sessionInfoPtr->receiveBuffer;
901 keyDataLength = status = processPublickeyData( handshakeInfo, bufPtr,
902 length,
TRUE, NULL );
908 CRYPT_IATTRIBUTE_KEY_SSH1 );
911 serverKeyLength =
mgetLong( bufPtr );
914 keyDataLength = status = processPublickeyData( handshakeInfo, bufPtr,
922 CRYPT_IATTRIBUTE_KEY_SSH1 );
926 bufPtr += keyDataLength - LENGTH_SIZE +
UINT_SIZE;
928 if( length != UINT_SIZE + UINT_SIZE )
930 "Invalid length %d, should be %d", length,
931 UINT_SIZE + UINT_SIZE );
933 sessionInfoPtr->
cryptAlgo = maskToAlgoID( value );
936 "No crypto algorithm compatible with the remote system "
952 "Server requested password authentication but no "
953 "password was available" );
958 "Server requested public-key authentication but no "
959 "key was available" );
981 if( hostKeyLength < serverKeyLength )
988 handshakeInfo->iServerCryptContext;
990 temp = hostKeyLength;
991 hostKeyLength = serverKeyLength;
992 serverKeyLength = temp;
997 if( hostKeyLength < serverKeyLength + 128 )
999 "Invalid host vs.server key lengths %d:%d bytes",
1000 hostKeyLength, serverKeyLength );
1007 static int exchangeClientKeys(
SESSION_INFO *sessionInfoPtr,
1013 BYTE *bufPtr = sessionInfoPtr->sendBuffer;
1045 generateSessionID( handshakeInfo );
1048 &msgData, CRYPT_IATTRIBUTE_RANDOM );
1053 handshakeInfo->secretValue[ i ] ^= handshakeInfo->sessionID[ i ];
1075 mputWord( bufPtr, length );
1081 handshakeInfo->secretValue[ i ] ^= handshakeInfo->sessionID[ i ];
1088 dataLength = bufPtr - sessionInfoPtr->sendBuffer;
1089 memmove( sessionInfoPtr->sendBuffer + LENGTH_SIZE + \
1090 getPadLength( dataLength ) +
ID_SIZE,
1091 sessionInfoPtr->sendBuffer, dataLength );
1098 static int completeClientHandshake(
SESSION_INFO *sessionInfoPtr,
1111 status = initSecurityInfoSSH1( sessionInfoPtr, handshakeInfo );
1120 padLength = getPadLength( LENGTH_SIZE + userNamePtr->
valueLength );
1121 bufPtr = sessionInfoPtr->sendBuffer + LENGTH_SIZE + padLength +
ID_SIZE;
1122 encodeString( bufPtr, userNamePtr->value, userNamePtr->
valueLength );
1140 if( passwordPtr != NULL )
1142 int maxLen, packetType, i;
1159 for( maxLen = 16; maxLen <= passwordPtr->
valueLength;
1164 padLength = getPadLength( LENGTH_SIZE + i );
1165 bufPtr = sessionInfoPtr->sendBuffer + LENGTH_SIZE + \
1169 encodeString( bufPtr, passwordPtr->value,
1181 CRYPT_IATTRIBUTE_RANDOM_NONCE );
1182 encodeString( bufPtr, sessionInfoPtr->receiveBuffer, i );
1185 status = sendPacketSsh1( sessionInfoPtr, packetType,
1189 status = readPacketSSH1( sessionInfoPtr,
1200 CRYPT_MAX_PKCSIZE ) * 2 ) + 8 ];
1218 CRYPT_IATTRIBUTE_KEY_SSH1 );
1225 modulusPtr = modulusBuffer +
sizeof(
LENGTH_SIZE );
1226 length = mgetWord( modulusPtr );
1229 modulusLength = mgetWord( modulusPtr );
1235 padLength = getPadLength( length );
1236 bufPtr = sessionInfoPtr->sendBuffer + LENGTH_SIZE + \
1238 memcpy( bufPtr, modulusPtr, length );
1242 status = readPacketSSH1( sessionInfoPtr,
1252 bufPtr = sessionInfoPtr->receiveBuffer;
1253 length = mgetWord( bufPtr );
1255 if( length < modulusLength - 8 || length > modulusLength )
1257 "Invalid encrypted challenge length %d for modulus "
1258 "length %d", length, modulusLength );
1275 generateChallengeResponse( response, handshakeInfo, challenge );
1277 bufPtr = sessionInfoPtr->sendBuffer + LENGTH_SIZE +
1280 status = sendPacketSsh1( sessionInfoPtr,
1284 status = readPacketSSH1( sessionInfoPtr,
1299 padLength = getPadLength( LENGTH_SIZE );
1300 bufPtr = sessionInfoPtr->sendBuffer + LENGTH_SIZE + padLength +
ID_SIZE;
1318 padLength = getPadLength( ( LENGTH_SIZE + 5 ) + ( UINT_SIZE * 4 ) + 1 );
1319 bufPtr = sessionInfoPtr->sendBuffer + LENGTH_SIZE + padLength +
ID_SIZE;
1320 bufPtr += encodeString( bufPtr,
"vt100", 0 );
1327 ( LENGTH_SIZE + 5 ) + ( UINT_SIZE * 4 ) + 1,
1351 static int beginServerHandshake(
SESSION_INFO *sessionInfoPtr,
1356 BYTE *bufPtr = sessionInfoPtr->sendBuffer;
1405 &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
1414 CRYPT_IATTRIBUTE_KEY_SSH1 );
1417 length = processPublickeyData( handshakeInfo, bufPtr, msgData.
length,
1424 CRYPT_IATTRIBUTE_KEY_SSH1 );
1427 length = processPublickeyData( handshakeInfo, bufPtr, msgData.
length,
1431 value = getAlgorithmMask();
1440 length = bufPtr - sessionInfoPtr->sendBuffer;
1441 memmove( sessionInfoPtr->sendBuffer + LENGTH_SIZE + \
1442 getPadLength( length ) + ID_SIZE, sessionInfoPtr->sendBuffer,
1466 static int exchangeServerKeys(
SESSION_INFO *sessionInfoPtr,
1471 BYTE *bufPtr = sessionInfoPtr->receiveBuffer;
1483 sessionInfoPtr->
cryptAlgo = sshIDToAlgoID( bufPtr[ 0 ] );
1486 "No crypto algorithm compatible with the remote system "
1490 "Client cookie doesn't match server cookie" );
1493 keyLength = mgetWord( bufPtr );
1499 "Invalid encrypted session key packet length %d, key "
1500 "length %d", length, keyLength );
1527 generateSessionID( handshakeInfo );
1529 handshakeInfo->secretValue[ i ] ^= handshakeInfo->sessionID[ i ];
1536 static int completeServerHandshake(
SESSION_INFO *sessionInfoPtr,
1543 status = initSecurityInfoSSH1( sessionInfoPtr, handshakeInfo );
1553 length = status = readPacketSSH1( sessionInfoPtr,
SSH1_CMSG_USER );
1556 bufPtr = sessionInfoPtr->receiveBuffer;
1557 stringLength = ( int )
mgetLong( bufPtr );
1558 if( length != LENGTH_SIZE + stringLength || \
1561 "Invalid user name packet length %d, name length %d",
1562 length, stringLength );
1572 length = status = readPacketSSH1( sessionInfoPtr,
1576 bufPtr = sessionInfoPtr->receiveBuffer;
1577 stringLength = ( int )
mgetLong( bufPtr );
1578 if( length != LENGTH_SIZE + stringLength || \
1579 stringLength <= 0 || stringLength > CRYPT_MAX_TEXTSIZE )
1581 "Invalid password packet length %d, password length %d",
1582 length, stringLength );
1601 packetType = sessionInfoPtr->receiveBuffer[ 0 ];
1602 switch( packetType )
1628 if( iterationCount >= 50 )
1630 "Peer sent excessive number of session open packets" );
1643 static int readHeaderFunction(
SESSION_INFO *sessionInfoPtr,
1646 BYTE *bufPtr = sessionInfoPtr->receiveBuffer +
\
1656 status = readFixedHeader( sessionInfoPtr, LENGTH_SIZE );
1663 assert( status == LENGTH_SIZE );
1668 "Invalid packet length %d", length );
1683 static int processBodyFunction(
SESSION_INFO *sessionInfoPtr,
1686 BYTE *bufPtr = sessionInfoPtr->receiveBuffer +
\
1688 BYTE *bufStartPtr = bufPtr;
1697 assert( bufPtr == sessionInfoPtr->receiveBuffer + \
1700 status = decryptPayload( sessionInfoPtr, bufPtr,
1704 if( !checksumPayload( sessionInfoPtr, bufPtr,
1707 "Bad message checksum" );
1710 bufPtr += padLength;
1721 return( getDisconnectInfoSSH1( sessionInfoPtr,
1722 sessionInfoPtr->receiveBuffer + padLength + ID_SIZE ) );
1739 ( ID_SIZE + LENGTH_SIZE + SSH1_CRC_SIZE ) )
1741 "Invalid payload length %d", length );
1743 memmove( bufStartPtr, bufPtr, length );
1744 sessionInfoPtr->
receiveBufEnd -= padLength + ID_SIZE + LENGTH_SIZE + \
1760 static int preparePacketFunction(
SESSION_INFO *sessionInfoPtr )
1762 BYTE *bufPtr = sessionInfoPtr->sendBuffer + \
1766 ( LENGTH_SIZE + getPadLength( LENGTH_SIZE + dataLength ) + \
1776 return( sendPacketSsh1( sessionInfoPtr,
isServer( sessionInfoPtr ) ? \
1778 LENGTH_SIZE + dataLength, delta ) );
1783 static void shutdownFunction(
SESSION_INFO *sessionInfoPtr )
1785 sNetDisconnect( &sessionInfoPtr->
stream );
1805 SESSION_NEEDS_KEYORPASSWORD | \
1806 SESSION_NEEDS_PRIVKEYCRYPT,
1816 DEFAULT_PACKET_SIZE,
1826 sessionInfoPtr->readHeaderFunction = readHeaderFunction;
1827 sessionInfoPtr->processBodyFunction = processBodyFunction;
1828 sessionInfoPtr->preparePacketFunction = preparePacketFunction;
1829 if( handshakeInfo != NULL )
1833 handshakeInfo->beginHandshake = beginServerHandshake;
1834 handshakeInfo->exchangeKeys = exchangeServerKeys;
1835 handshakeInfo->completeHandshake = completeServerHandshake;
1839 handshakeInfo->beginHandshake = beginClientHandshake;
1840 handshakeInfo->exchangeKeys = exchangeClientKeys;
1841 handshakeInfo->completeHandshake = completeClientHandshake;
1848 sessionInfoPtr->shutdownFunction = shutdownFunction;