📄 testsess.c
字号:
printf( "SVR: Client requested '%s' subsystem.\n", subsystem );
}
else
if( useSubsystem )
{
printf( "SVR: Client requested subsystem but server didn't "
"report it, line %d.\n", __LINE__ );
return( FALSE );
}
}
if( cryptStatusError( status ) )
{
if( useFingerprint )
{
/* We've forced the connect to fail by using a dummy fingerprint,
everything is OK */
cryptDestroySession( cryptSession );
puts( "SVR: SSH client session succeeded.\n" );
return( TRUE );
}
printExtError( cryptSession, isServer ? \
"SVR: Attempt to activate SSH server session" : \
"Attempt to activate SSH client session", status,
__LINE__ );
cryptDestroySession( cryptSession );
if( status == CRYPT_ERROR_OPEN )
{
/* These servers are constantly appearing and disappearing so if
we get a straight connect error we don't treat it as a serious
failure */
puts( " (Server could be down, faking it and continuing...)\n" );
return( CRYPT_ERROR_FAILED );
}
if( status == CRYPT_ERROR_WRONGKEY )
{
/* This is another possible soft error condition, the default
username and password shouldn't be able to get into many
machines */
puts( " (Incorrect username/password, continuing...)\n" );
return( TRUE );
}
if( status == CRYPT_ERROR_NOSECURE )
{
/* Another soft error condition, the server can't handle the
security level we want (usually occurs when trying to perform
an SSHv2 connect to an SSHv1 server) */
puts( " (Insufficiently secure protocol parameters, continuing...)\n" );
return( TRUE );
}
return( FALSE );
}
if( useFingerprint )
{
printf( "Attempt to connect with invalid key fingerprint succeeded "
"when it should\nhave failed, line %d.\n", __LINE__ );
return( FALSE );
}
/* Report the session security info details */
status = cryptGetAttribute( cryptSession, CRYPT_CTXINFO_ALGO,
&cryptAlgo );
if( cryptStatusOK( status ) )
status = cryptGetAttribute( cryptSession, CRYPT_CTXINFO_KEYSIZE,
&keySize );
if( cryptStatusOK( status ) )
status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_VERSION,
&version );
if( cryptStatusError( status ) )
{
printf( "Couldn't query encryption algorithm and keysize used for "
"session, status %d, line %d.\n", status, __LINE__ );
return( FALSE );
}
printf( "%sSSHv%d session is protected using algorithm %d with a %d "
"bit key.\n", isServer ? "SVR: " : "", version, cryptAlgo,
keySize * 8 );
if( !isServer )
{
BYTE fingerPrint[ CRYPT_MAX_HASHSIZE ];
int length, i;
status = cryptGetAttributeString( cryptSession,
CRYPT_SESSINFO_SERVER_FINGERPRINT,
fingerPrint, &length );
if( cryptStatusError( status ) )
{
printf( "cryptGetAttributeString() failed with error code "
"%d, line %d.\n", status, __LINE__ );
return( FALSE );
}
printf( "Server key fingerprint =" );
for( i = 0; i < length; i++ )
printf( " %02X", fingerPrint[ i ] );
puts( "." );
}
/* If we're using the SFTP subsystem as a server, use the special-case
routines for this */
#ifdef WINDOWS_THREADS
if( useSubsystem )
{
if( isServer )
{
int sftpServer( const CRYPT_SESSION cryptSession );
status = sftpServer( cryptSession );
if( cryptStatusError( status ) )
{
printf( "SVR: Couldn't receive SFTP data from client, status %d, "
"line %d.\n", status, __LINE__ );
return( FALSE );
}
cryptDestroySession( cryptSession );
puts( "SVR: SFTP server session succeeded.\n" );
return( TRUE );
}
else
{
int sftpClient( const CRYPT_SESSION cryptSession );
status = sftpClient( cryptSession );
if( cryptStatusError( status ) )
{
printf( "Couldn't send SFTP data to server, status %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
cryptDestroySession( cryptSession );
puts( "SFTP client session succeeded.\n" );
return( TRUE );
}
}
#endif /* WINDOWS_THREADS */
/* Send data over the SSH link */
cryptSetAttribute( cryptSession, CRYPT_OPTION_NET_TIMEOUT, 5 );
if( isServer )
{
/* Send a status message to the client */
status = cryptPushData( cryptSession, "Welcome to cryptlib, now go "
"away.\r\n", 35, &bytesCopied );
if( cryptStatusOK( status ) )
status = cryptFlushData( cryptSession );
if( cryptStatusError( status ) || bytesCopied != 35 )
{
printf( "SVR: Couldn't send data to client, status %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
}
/* Wait a bit while data arrives */
delayThread( 2 );
/* Print the first lot of output from the other side */
status = cryptPopData( cryptSession, buffer, BUFFER_SIZE, &bytesCopied );
if( cryptStatusError( status ) )
{
printf( "%sCouldn't read data from %s, status %d, line %d.\n",
isServer ? "SVR: " : "", isServer ? "client" : "server",
status, __LINE__ );
return( FALSE );
}
buffer[ bytesCopied ] = '\0';
printf( "%s---- %s returned %d bytes ----\n", isServer ? "SVR: " : "",
isServer ? "Client" : "Server", bytesCopied );
puts( buffer );
printf( "%s---- End of output ----\n", isServer ? "SVR: " : "" );
/* See if the client requested port forwarding. We have to do this now
rather than right after the connect because this is generally a
post-handshake function (unless the client already has a forwarded
connection waiting), so we won't see it until after we try reading
some data */
if( isServer && \
cryptStatusOK( \
cryptGetAttributeString( cryptSession,
CRYPT_SESSINFO_SSH_PORTFORWARD,
NULL, &status ) ) )
{
int length;
status = cryptGetAttributeString( cryptSession,
CRYPT_SESSINFO_SSH_PORTFORWARD,
buffer, &length );
if( cryptStatusError( status ) )
{
printf( "cryptGetAttributeString() failed with error code "
"%d, line %d.\n", status, __LINE__ );
return( FALSE );
}
buffer[ length ] = '\0';
printf( "Client requested port forwarding to '%s'.\n", buffer );
}
/* If we're the server, echo the command to the client */
if( isServer )
{
const int clientBytesCopied = bytesCopied;
int dummy, i;
for( i = 0; i < clientBytesCopied; i++ )
if( buffer[ i ] < ' ' || buffer[ i ] >= 0x7F )
buffer[ i ] = '.';
status = cryptPushData( cryptSession, "Input was [", 11, &dummy );
if( cryptStatusOK( status ) && clientBytesCopied > 0 )
status = cryptPushData( cryptSession, buffer, clientBytesCopied,
&bytesCopied );
if( cryptStatusOK( status ) )
status = cryptPushData( cryptSession, "]\r\n", 3, &dummy );
if( cryptStatusOK( status ) )
status = cryptFlushData( cryptSession );
if( cryptStatusError( status ) || bytesCopied != clientBytesCopied )
{
printf( "SVR: Couldn't send data to client, status %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
}
else
{
/* We're the client, if it's a session to a Unix ssh server, send a
sample command and display the output */
if( !localSession )
{
/* Send a command to the server and get the results */
status = cryptPushData( cryptSession, "ls -l | head -25\n", 18,
&bytesCopied );
if( cryptStatusOK( status ) )
status = cryptFlushData( cryptSession );
if( cryptStatusError( status ) || bytesCopied != 18 )
{
printf( "Couldn't send data to server, status %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
delayThread( 3 );
status = cryptPopData( cryptSession, buffer, BUFFER_SIZE,
&bytesCopied );
if( cryptStatusError( status ) )
{
printf( "Couldn't read data from server, status %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
buffer[ bytesCopied ] = '\0';
printf( "---- Sent 'ls -l | head -25', server returned %d bytes "
"----\n", bytesCopied );
puts( buffer );
puts( "---- End of output ----" );
}
else
{
/* It's a local session, just send a simple text string for
testing */
status = cryptPushData( cryptSession, "Some test data", 14,
&bytesCopied );
if( cryptStatusOK( status ) )
status = cryptFlushData( cryptSession );
if( cryptStatusError( status ) || bytesCopied != 14 )
{
printf( "Couldn't send data to server, status %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
/* Make sure we stay around long enough to get the server's
response */
delayThread( 1 );
}
}
/* Clean up */
status = cryptDestroySession( cryptSession );
if( cryptStatusError( status ) )
{
printf( "cryptDestroySession() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( isServer ? "SVR: SSH server session succeeded.\n" : \
"SSH client session succeeded.\n" );
return( TRUE );
}
int testSessionSSHv1( void )
{
return( connectSSH( CRYPT_SESSION_SSH, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) );
}
int testSessionSSHv2( void )
{
return( connectSSH( CRYPT_SESSION_SSH, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE ) );
}
int testSessionSSHClientCert( void )
{
return( connectSSH( CRYPT_SESSION_SSH, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE ) );
}
int testSessionSSH_SFTP( void )
{
return( connectSSH( CRYPT_SESSION_SSH, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE ) );
}
int testSessionSSHv1Server( void )
{
return( connectSSH( CRYPT_SESSION_SSH_SERVER, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) );
}
int testSessionSSHv2Server( void )
{
return( connectSSH( CRYPT_SESSION_SSH_SERVER, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE ) );
}
int testSessionSSH_SFTPServer( void )
{
return( connectSSH( CRYPT_SESSION_SSH_SERVER, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE ) );
}
/* Perform a client/server loopback test */
#ifdef WINDOWS_THREADS
unsigned __stdcall ssh1ServerThread( void *dummy )
{
connectSSH( CRYPT_SESSION_SSH_SERVER, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE );
_endthreadex( 0 );
return( 0 );
}
unsigned __stdcall ssh2ServerThread( void *dummy )
{
connectSSH( CRYPT_SESSION_SSH_SERVER, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE );
_endthreadex( 0 );
return( 0 );
}
unsigned __stdcall sftpServerThread( void *dummy )
{
connectSSH( CRYPT_SESSION_SSH_SERVER, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE );
_endthreadex( 0 );
return( 0 );
}
static int sshClientServer( const BOOLEAN useFingerprint,
const BOOLEAN useSSHv2,
const BOOLEAN useSFTP,
const BOOLEAN usePortForwarding )
{
HANDLE hThread;
unsigned threadID;
int status;
/* Start the server and wait for it to initialise */
hThread = ( HANDLE ) _beginthreadex( NULL, 0, useSFTP ? \
sftpServerThread : \
useSSHv2 ? \
ssh2ServerThread : \
&ssh1ServerThread,
NULL, 0, &threadID );
Sleep( 1000 );
/* Connect to the local server */
status = connectSSH( CRYPT_SESSION_SSH, FALSE, useSFTP,
usePortForwarding, TRUE, useSSHv2, useFingerprint );
if( WaitForSingleObject( hThread, 15000 ) == WAIT_TIMEOUT )
{
puts( "Warning: Server thread is still active due to session "
"negotiation failure,\n this will cause an error "
"condition when cryptEnd() is called due\n to "
"resources remaining allocated. Press a key to continue." );
getchar();
}
CloseHandle( hThread );
return( status );
}
int testSessionSSHv1ClientServer( void )
{
return( sshClientServer( FALSE, FALSE, FALSE, FALSE ) );
}
int testSessionSSHv2ClientServer( void )
{
return( sshClientServer( FALSE, TRUE, FALSE, FALSE ) );
}
int testSessionSSHClientServerFingerprint( void )
{
return( sshClientServer( TRUE, FALSE, FALSE, FALSE ) );
}
int testSessionSSHClientServerSFTP( void )
{
return( sshClientServer( FALSE, TRUE, TRUE, FALSE ) );
}
int testSessionSSHClientServerPortForward( void )
{
return( sshClientServer( FALSE, TRUE, FALSE, TRUE ) );
}
#endif /* WINDOWS_THREADS */
/****************************************************************************
* *
* SSL/TLS Routines Test *
* *
****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -