⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssh.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
			puts( "  (Insufficiently secure protocol parameters, "
				  "continuing...)\n" );
			return( TRUE );
			}
		return( FALSE );
		}
	if( testType == SSH_TEST_FINGERPRINT )
		{
		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 */
	if( !printSecurityInfo( cryptSession, isServer, TRUE ) )
		return( FALSE );
	status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_SSH_CHANNEL,
								&channel );
	if( cryptStatusError( status ) )
		{
		printf( "cryptGetAttributeString() failed with error code "
				"%d, line %d.\n", status, __LINE__ );
		return( FALSE );
		}
	printf( "%sCurrent channel is #%d.\n", isServer ? "SVR: " : "", 
			channel );

	/* Report additional channel-specific information */
	if( isServer )
		{
		/* Display info on any channels that the client has opened */
		status = printChannelInfo( cryptSession, testType, TRUE );
		if( cryptStatusError( status ) )
			return( FALSE );

		/* Process any additional information that the client may throw
		   at us after the user-auth has completed */
		status = cryptPopData( cryptSession, buffer, BUFFER_SIZE,
							   &bytesCopied );
		if( cryptStatusOK( status ) && bytesCopied > 0 )
			printf( "SVR: Client sent additional %d bytes post-"
					"handshake data.\n", bytesCopied );
		else
			if( status == CRYPT_ENVELOPE_RESOURCE )
				{
				/* The client performed additional control actions that were
				   handled inline as part of the data-pop, report the
				   details */
				status = printChannelInfo( cryptSession, testType, TRUE );
				if( cryptStatusError( status ) )
					return( FALSE );
				}
		}

	/* If we're using the SFTP subsystem as a server, use the special-case
	   routines for this */
#ifdef WINDOWS_THREADS
	if( testType == SSH_TEST_SUBSYSTEM )
		{
		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 */

	/* If we're performing a multi-channel test, open a second channel (the
	   server handles this as part of its general connect-handling) */
	if( testType == SSH_TEST_MULTICHANNEL && !isServer )
		{
		status = createChannel( cryptSession, TEXT( "direct-tcpip" ),
								TEXT( "localhost:5678" ) );
		if( cryptStatusOK( status ) )
			status = cryptGetAttribute( cryptSession,
										CRYPT_SESSINFO_SSH_CHANNEL,
										&channel );
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptSession,
										CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE,
										TRUE );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't open second SSH chanel, status %d, line "
					"%d.\n", status, __LINE__ );
			return( FALSE );
			}
		printf( "Opened additional channel #%d to server.\n", channel );
		}

	/* Send data over the SSH link */
	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 = printDataInfo( cryptSession, buffer, &bytesCopied, isServer );
	if( cryptStatusError( status ) )
		return( FALSE );

	/* If we're the server, echo the command to the client */
	if( isServer )
		{
		const int clientBytesCopied = bytesCopied;
		int dummy, i;

		/* If it's a multi-channel test, send the response back on a
		   different channel.  The currently-selected channel will be the
		   last one that the client opened (#2), so we can hardcode in
		   #1 for testing purposes */
		if( testType == SSH_TEST_MULTICHANNEL )
			{
			status = cryptSetAttribute( cryptSession,
										CRYPT_SESSINFO_SSH_CHANNEL, 1 );
			if( cryptStatusError( status ) )
				{
				printf( "SVR: Couldn't select channel #1 to return data to "
						"client, status %d, line %d.\n", status, __LINE__ );
				return( FALSE );
				}
			}
		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 );
				}
			puts( "Sent 'ls -l | head -25'" );
			delayThread( 3 );
			status = printDataInfo( cryptSession, buffer, &bytesCopied,
									isServer );
			if( cryptStatusError( status ) )
				return( FALSE );
			}
		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 that we stay around long enough to get the
			   server's response */
			delayThread( 1 );

			/* Print the server's response */
			status = printDataInfo( cryptSession, buffer, &bytesCopied,
									isServer );
			if( cryptStatusError( status ) )
				return( FALSE );
			}
		}

	/* If we're performing a multi-channel test, close the second channel */
	if( testType == SSH_TEST_MULTICHANNEL )
		{
		if( isServer )
			{
			/* Perform a dummy pop to process the channel close */
			cryptPopData( cryptSession, buffer, BUFFER_SIZE, &bytesCopied );
			}
		else
			{
			/* Close the current channel */
			status = cryptSetAttribute( cryptSession,
										CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE, 
										FALSE );
			if( cryptStatusError( status ) )
				{
				printf( "Couldn't close second SSH chanel, status %d, line "
						"%d.\n", status, __LINE__ );
				return( FALSE );
				}
			printf( "Closed second channel to server.\n" );
			}
		}

	/* 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, SSH_TEST_SSH1, FALSE ) );
	}
int testSessionSSH( void )
	{
	return( connectSSH( CRYPT_SESSION_SSH, SSH_TEST_NORMAL, FALSE ) );
	}
int testSessionSSHClientCert( void )
	{
	return( connectSSH( CRYPT_SESSION_SSH, SSH_TEST_CLIENTCERT, FALSE ) );
	}
int testSessionSSHPortforward( void )
	{
	return( connectSSH( CRYPT_SESSION_SSH, SSH_TEST_PORTFORWARDING, FALSE ) );
	}
int testSessionSSH_SFTP( void )
	{
	return( connectSSH( CRYPT_SESSION_SSH, SSH_TEST_SUBSYSTEM, FALSE ) );
	}
int testSessionSSHv1Server( void )
	{
	return( connectSSH( CRYPT_SESSION_SSH_SERVER, SSH_TEST_SSH1, FALSE ) );
	}
int testSessionSSHServer( void )
	{
	return( connectSSH( CRYPT_SESSION_SSH_SERVER, SSH_TEST_CONFIRMAUTH, FALSE ) );
	}
int testSessionSSH_SFTPServer( void )
	{
	return( connectSSH( CRYPT_SESSION_SSH_SERVER, SSH_TEST_SUBSYSTEM, FALSE ) );
	}

/* Perform a client/server loopback test */

#ifdef WINDOWS_THREADS

unsigned __stdcall ssh1ServerThread( void *dummy )
	{
	connectSSH( CRYPT_SESSION_SSH_SERVER, SSH_TEST_SSH1, TRUE );
	_endthreadex( 0 );
	return( 0 );
	}
unsigned __stdcall ssh2ServerThread( void *dummy )
	{
	connectSSH( CRYPT_SESSION_SSH_SERVER, SSH_TEST_NORMAL, TRUE );
	_endthreadex( 0 );
	return( 0 );
	}
unsigned __stdcall ssh2ServerFingerprintThread( void *dummy )
	{
	connectSSH( CRYPT_SESSION_SSH_SERVER, SSH_TEST_FINGERPRINT, TRUE );
	_endthreadex( 0 );
	return( 0 );
	}
unsigned __stdcall ssh2ServerMultichannelThread( void *dummy )
	{
	connectSSH( CRYPT_SESSION_SSH_SERVER, SSH_TEST_MULTICHANNEL, TRUE );
	_endthreadex( 0 );
	return( 0 );
	}
unsigned __stdcall sftpServerThread( void *dummy )
	{
	connectSSH( CRYPT_SESSION_SSH_SERVER, SSH_TEST_SUBSYSTEM, TRUE );
	_endthreadex( 0 );
	return( 0 );
	}

static int sshClientServer( const SSH_TEST_TYPE testType )
	{
	HANDLE hThread;
	unsigned threadID;
	int status;

	/* Start the server and wait for it to initialise */
	hThread = ( HANDLE ) _beginthreadex( NULL, 0,
							( testType == SSH_TEST_SUBSYSTEM ) ? \
								sftpServerThread : \
							( testType == SSH_TEST_SSH1 ) ? \
								ssh1ServerThread : \
							( testType == SSH_TEST_FINGERPRINT ) ? \
								ssh2ServerFingerprintThread : \
							( testType == SSH_TEST_MULTICHANNEL ) ? \
								ssh2ServerMultichannelThread : \
								ssh2ServerThread,
							NULL, 0, &threadID );
	Sleep( 1000 );

	/* Connect to the local server */
	status = connectSSH( CRYPT_SESSION_SSH, testType, TRUE );
	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( SSH_TEST_SSH1 ) );
	}
int testSessionSSHClientServer( void )
	{
	return( sshClientServer( SSH_TEST_NORMAL ) );
	}
int testSessionSSHClientServerFingerprint( void )
	{
	/* Note that this test tests the correct functioning of a refused
	   connection when an incorrect key fingerprint is used, so it's
	   supposed to fail */
	return( sshClientServer( SSH_TEST_FINGERPRINT ) );
	}
int testSessionSSHClientServerSFTP( void )
	{
	return( sshClientServer( SSH_TEST_SUBSYSTEM ) );
	}
int testSessionSSHClientServerPortForward( void )
	{
	return( sshClientServer( SSH_TEST_PORTFORWARDING ) );
	}
int testSessionSSHClientServerMultichannel( void )
	{
	return( sshClientServer( SSH_TEST_MULTICHANNEL ) );
	}
#endif /* WINDOWS_THREADS */

/****************************************************************************
*																			*
*							SFTP Routines for SSH							*
*																			*
****************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -