20 #if defined( USE_SSH ) || defined( USE_SSH1 )
37 handshakeInfo->iExchangeHashContext = \
38 handshakeInfo->iExchangeHashAltContext = \
54 if( handshakeInfo->iExchangeHashContext !=
CRYPT_ERROR )
57 if( handshakeInfo->iExchangeHashAltContext !=
CRYPT_ERROR )
60 if( handshakeInfo->iServerCryptContext !=
CRYPT_ERROR )
67 ( void ) initHandshakeInfo( handshakeInfo );
81 status = sread( stream, &ch, 1 );
88 const BYTE *versionStringPtr;
89 const char *peerType =
isServer( sessionInfoPtr ) ?
"Client" :
"Server";
116 for( linesRead = 0; linesRead < 20; linesRead++ )
123 status = readTextLine( readCharFunction, &sessionInfoPtr->stream,
124 sessionInfoPtr->receiveBuffer,
128 const char *lcPeerType =
isServer( sessionInfoPtr ) ? \
132 sNetGetErrorInfo( &sessionInfoPtr->stream, &errorInfo );
135 "Error reading %s's SSH identifier string: ",
148 if( linesRead >= 20 )
152 "%s sent excessive amounts of text without sending an "
153 "SSH identifier string", peerType ) );
163 "%s sent truncated identifier string '%s'", peerType,
164 sanitiseString( sessionInfoPtr->receiveBuffer,
173 memset( sessionInfoPtr->receiveBuffer + length, 0, 16 );
176 switch( sessionInfoPtr->receiveBuffer[
SSH_ID_SIZE ] )
179 if( !memcmp( sessionInfoPtr->receiveBuffer +
SSH_ID_SIZE,
183 sessionInfoPtr->version = 2;
190 if( sessionInfoPtr->version >= 2 )
194 "Server can only do SSHv1 when SSHv2 was "
197 sessionInfoPtr->version = 1;
202 "Server can only do SSHv1" ) );
206 sessionInfoPtr->version = 2;
212 "Invalid SSH version '%s'",
213 sanitiseString( &sessionInfoPtr->receiveBuffer[
SSH_ID_SIZE ],
221 versionStringPtr = sessionInfoPtr->receiveBuffer +
SSH_ID_SIZE;
222 versionStringLength > 0 && *versionStringPtr !=
'-';
223 versionStringLength--, versionStringPtr++ );
224 if( versionStringLength < 4 )
230 "%s sent malformed identifier string '%s'", peerType,
231 sanitiseString( sessionInfoPtr->receiveBuffer,
234 versionStringPtr++, versionStringLength--;
235 ENSURES( versionStringLength >= 3 && \
236 versionStringLength < SSH_ID_MAX_SIZE );
239 if( versionStringLength >= 8 && \
240 !memcmp( versionStringPtr,
"cryptlib", 8 ) )
363 if( versionStringLength >= 8 + 3 && \
364 !memcmp( versionStringPtr,
"OpenSSH_", 8 ) )
366 const BYTE *subVersionStringPtr = versionStringPtr + 8;
368 if( !memcmp( subVersionStringPtr,
"2.0", 3 ) )
370 if( !memcmp( subVersionStringPtr,
"3.8", 3 ) || \
371 !memcmp( subVersionStringPtr,
"3.9", 3 ) || \
372 ( versionStringLength >= 8 + 4 && \
373 !memcmp( subVersionStringPtr,
"3.10", 4 ) ) || \
374 *subVersionStringPtr >=
'4' )
376 if( ( !memcmp( subVersionStringPtr,
"2.", 2 ) && \
377 subVersionStringPtr[ 2 ] >=
'5' ) || \
378 ( !memcmp( subVersionStringPtr,
"3.", 2 ) && \
379 subVersionStringPtr[ 2 ] <=
'2' ) )
384 if( versionStringLength >= 14 + 4 && \
385 !memcmp( versionStringPtr,
"PuTTY_Release_", 14 ) )
387 const BYTE *subVersionStringPtr = versionStringPtr + 14;
389 if( !memcmp( subVersionStringPtr,
"0.59", 4 ) )
394 if( versionStringLength >= 9 && \
395 !memcmp( versionStringPtr,
"WeOnlyDo ", 9 ) )
397 const BYTE *subVersionStringPtr = versionStringPtr + 9;
399 if( subVersionStringPtr[ 0 ] >=
'2' )
403 if(
isDigit( *versionStringPtr ) )
405 const BYTE *vendorIDString;
406 const int versionDigit =
byteToInt( *versionStringPtr );
407 int vendorIDStringLength;
412 for( vendorIDStringLength = versionStringLength, \
413 vendorIDString = versionStringPtr;
414 vendorIDStringLength > 0 && *vendorIDString !=
' ';
415 vendorIDStringLength--, vendorIDString++ );
416 if( vendorIDStringLength > 1 )
419 vendorIDString++, vendorIDStringLength--;
421 ENSURES( vendorIDStringLength >= 0 && \
422 vendorIDStringLength < SSH_ID_MAX_SIZE );
423 switch( versionDigit )
426 if( versionStringLength >= 12 && \
427 !memcmp( versionStringPtr,
"1.7 SecureFX", 12 ) )
429 if( versionStringLength == 3 && \
430 !memcmp( versionStringPtr,
"1.0", 3 ) )
432 if( ( vendorIDStringLength > 8 && \
433 !memcmp( vendorIDString,
"sshlib: ", 8 ) > 0 ) || \
434 ( vendorIDStringLength > 9 && \
435 !memcmp( vendorIDString,
"FlowSsh: ", 9 ) > 0 ) )
440 if( vendorIDStringLength >= 6 && \
441 !memcmp( vendorIDString,
"VShell", 6 ) )
446 if( ( versionStringLength >= 5 && \
447 !memcmp( versionStringPtr,
"2.0.0", 5 ) ) || \
448 ( versionStringLength >= 6 && \
449 !memcmp( versionStringPtr,
"2.0.10", 6 ) ) )
451 if( !memcmp( versionStringPtr,
"2.0", 3 ) || \
452 !memcmp( versionStringPtr,
"2.1", 3 ) )
454 if( !memcmp( versionStringPtr,
"2.0", 3 ) || \
455 !memcmp( versionStringPtr,
"2.1", 3 ) )
457 if( !memcmp( versionStringPtr,
"2.1", 3 ) || \
458 !memcmp( versionStringPtr,
"2.2", 3 ) )
460 if( !memcmp( versionStringPtr,
"2.0", 3 ) || \
461 !memcmp( versionStringPtr,
"2.1", 3 ) || \
462 !memcmp( versionStringPtr,
"2.2", 3 ) || \
463 ( versionStringLength >= 5 && \
464 !memcmp( versionStringPtr,
"2.3.0", 5 ) ) )
466 if( !memcmp( versionStringPtr,
"2.0", 3 ) )
468 if( !memcmp( versionStringPtr,
"2.", 2 ) )
477 if( versionStringLength >= 13 && \
478 !memcmp( versionStringPtr,
"3.0 SecureCRT", 13 ) )
483 if( versionStringLength >= 10 && \
484 !memcmp( vendorIDString,
"SSH Tectia", 10 ) )
511 status = readVersionString( sessionInfoPtr );
515 if( sessionInfoPtr->version == 1 )
519 sessionInfoPtr->sendBufStartOfs =
\
525 initSSH2processing( sessionInfoPtr, handshakeInfo,
538 handshakeInfo->iExchangeHashContext = createInfo.
cryptHandle;
551 handshakeInfo->iExchangeHashAltContext = createInfo.
cryptHandle;
566 status = handshakeInfo->completeHandshake( sessionInfoPtr,
568 destroyHandshakeInfo( handshakeInfo );
581 sessionInfoPtr->shutdownFunction( sessionInfoPtr );
582 destroySecurityContextsSSH( sessionInfoPtr );
602 status = initHandshakeInfo( &handshakeInfo );
604 status = initVersion( sessionInfoPtr, &handshakeInfo );
606 status = handshakeInfo.beginHandshake( sessionInfoPtr,
613 destroyHandshakeInfo( &handshakeInfo );
615 sessionInfoPtr->shutdownFunction( sessionInfoPtr );
620 status = handshakeInfo.exchangeKeys( sessionInfoPtr, &handshakeInfo );
623 destroySecurityContextsSSH( sessionInfoPtr );
624 destroyHandshakeInfo( &handshakeInfo );
626 sessionInfoPtr->shutdownFunction( sessionInfoPtr );
631 return( completeHandshake( sessionInfoPtr, &handshakeInfo ) );
639 const char *idString = ( sessionInfoPtr->version == 1 ) ? \
642 ( ( sessionInfoPtr->version == 1 ) ? 1 : 2 );
654 status = initHandshakeInfo( &handshakeInfo );
657 initSSH2processing( sessionInfoPtr, &handshakeInfo,
TRUE );
658 return( completeHandshake( sessionInfoPtr, &handshakeInfo ) );
670 status = swrite( &sessionInfoPtr->stream, idString, idStringLen );
675 return( completeStartup( sessionInfoPtr ) );
684 #ifdef USE_SSH_EXTENDED
704 status = getChannelAttribute( sessionInfoPtr, type, data );
710 status = getChannelAttributeS( sessionInfoPtr, type, msgData->data,
724 assert(
isReadPtr( data,
sizeof(
int ) ) );
735 value = *( (
int * ) data );
751 getCurrentChannelNo( sessionInfoPtr, \
755 return( createChannel( sessionInfoPtr ) );
764 return( sendChannelOpen( sessionInfoPtr ) );
765 return( closeChannel( sessionInfoPtr,
FALSE ) );
769 status = setChannelAttribute( sessionInfoPtr, type, value );
774 status = setChannelAttributeS( sessionInfoPtr, type, msgData->data,
782 static
int checkAttributeFunction(
SESSION_INFO *sessionInfoPtr,
848 &msgData, CRYPT_IATTRIBUTE_KEY_SSH );
852 readUint32( &stream );
853 status = readUniversal32( &stream );
855 status = sMemGetDataBlockRemaining( &stream, &blobData,
857 sMemDisconnect( &stream );
866 fingerPrint, hashSize ) );
881 #ifdef USE_SSH_EXTENDED
882 sessionInfoPtr->getAttributeFunction = getAttributeFunction;
883 sessionInfoPtr->setAttributeFunction = setAttributeFunction;
885 sessionInfoPtr->checkAttributeFunction = checkAttributeFunction;
888 sessionInfoPtr->transactFunction = serverStartup;
889 initSSH2processing( sessionInfoPtr, NULL,
TRUE );
893 sessionInfoPtr->transactFunction = completeStartup;
894 initSSH2processing( sessionInfoPtr, NULL,
FALSE );