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

📄 testsess.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
*																			*
*					  cryptlib Secure Session Test Routines					*
*						Copyright Peter Gutmann 1998-2003					*
*																			*
****************************************************************************/

#ifdef _MSC_VER
  #include "../cryptlib.h"
  #include "../test/test.h"
#else
  #include "cryptlib.h"
  #include "test/test.h"
#endif /* Braindamaged MSC include handling */

#if defined( __MVS__ ) || defined( __VMCMS__ )
  /* Suspend conversion of literals to ASCII. */
  #pragma convlit( suspend )
#endif /* EBCDIC systems */

/* Uncomment the following to ask the user for a password rather than using
   a hardcoded password when testing against live accounts */

/* #define USER_SUPPLIED_PASSWORD	/**/
#ifdef USER_SUPPLIED_PASSWORD
  #undef SSH2_SERVER_NAME
  #undef SSH_USER_NAME
  #define SSH2_SERVER_NAME	"testserver"
  #define SSH_USER_NAME		"testname"
#endif /* USER_SUPPLIED_PASSWORD */

/****************************************************************************
*																			*
*								Utility Functions							*
*																			*
****************************************************************************/

/* Print information in the peer we're talking to */

static void printConnectInfo( const CRYPT_SESSION cryptSession )
	{
	time_t theTime;
	char serverName[ 128 ];
	int serverNameLength, serverPort, status;

	time( &theTime );
	status = cryptGetAttributeString( cryptSession, CRYPT_SESSINFO_CLIENT_NAME,
									  serverName, &serverNameLength );
	if( cryptStatusError( status ) )
		return;
	serverName[ serverNameLength ] = '\0';
	cryptGetAttribute( cryptSession, CRYPT_SESSINFO_CLIENT_PORT, &serverPort );
	printf( "SVR: Connect attempt from %s, port %d, on %s", serverName, 
			serverPort, ctime( &theTime ) );
	}

/* Set up a client/server to connect locally.  For the client his simply
   tells it where to connect, for the server this binds it to the local
   address so we don't inadvertently open up outside ports (admittedly
   they can't do much except run the hardcoded self-test, but it's better
   not to do this at all) */

static BOOLEAN setLocalConnect( const CRYPT_SESSION cryptSession,
								const int port )
	{
	int status;

	status = cryptSetAttributeString( cryptSession,
									  CRYPT_SESSINFO_SERVER_NAME,
									  "localhost", 9 );
#ifdef __UNIX__
	/* If we're running under Unix, set the port to a nonprivileged one so
	   we don't have to run as root.  For anything other than very low-
	   numbered ports (e.g. SSH), the way we determine the port is to repeat 
	   the first digit, so e.g. TSA on 318 becomes 3318, this seems to be 
	   the method most commonly used */
	if( cryptStatusOK( status ) && port < 1024 )
		{
		if( port < 100 )
			status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_SERVER_PORT,
										port + 4000 );
		else
			status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_SERVER_PORT,
										( ( port / 100 ) * 1000 ) + port );
		}
#endif /* __UNIX__ */
	if( cryptStatusError( status ) )
		{
		printf( "cryptSetAttribute/AttributeString() failed with error code "
				"%d, line %d.\n", status, __LINE__ );
		return( FALSE );
		}

	return( TRUE );
	}

/* Test the ability to parse URLs */

static const struct {
	const char *url;			/* Server URL */
	const char *name;			/* Parsed server name */
	const int port;				/* Parsed server port */
	const char *userInfo;		/* Parsed user info */
	} urlParseInfo[] = {
	/* IP address forms */
	{ "1.2.3.4", "1.2.3.4", 0, NULL },
	{ "1.2.3.4:80", "1.2.3.4", 80, NULL },
	{ "user@1.2.3.4", "1.2.3.4", 0, "user" },
	{ "[1:2:3:4]", "1:2:3:4", 0, NULL },
	{ "[1:2:3:4]:80", "1:2:3:4", 80, NULL },
	{ "user@[1:2:3:4]", "1:2:3:4", 0, "user" },

	/* General URI forms */
	{ "www.server.com", "www.server.com", 0, NULL },
	{ "www.server.com:80", "www.server.com", 80, NULL },
	{ "http://www.server.com:80", "www.server.com", 80, NULL },
	{ "http://user@www.server.com:80", "www.server.com", 80, "user" },

	/* Spurious whitespace */
	{ "  www.server.com  :   80 ", "www.server.com", 80, NULL },
	{ "http:// user  @ www.server.com  :   80 ", "www.server.com", 80, "user" },
	{ NULL, NULL, 0, NULL }
	};

int testSessionUrlParse( void )
	{
	CRYPT_SESSION cryptSession;
	int i, status;

	puts( "Testing session URL parsing..." );

	/* Create a session of the most generic type */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, CRYPT_SESSION_SSL );
	if( status == CRYPT_ERROR_PARAM3 )	/* SSL session access not available */
		return( CRYPT_ERROR_NOTAVAIL );
	if( cryptStatusError( status ) )
		{
		printf( "cryptCreateSession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Set various URLs as the server name and retrieve the parsed form */
	for( i = 0; urlParseInfo[ i ].url != NULL; i++ )
		{
		char nameBuffer[ 256 ], userInfoBuffer[ 256 ];
		int lengthLength, userInfoLength, port;

		/* Clear any leftover attributes from previous tests */
		cryptDeleteAttribute( cryptSession, CRYPT_SESSINFO_SERVER_NAME );
		cryptDeleteAttribute( cryptSession, CRYPT_SESSINFO_SERVER_PORT );
		cryptDeleteAttribute( cryptSession, CRYPT_SESSINFO_USERNAME );

		/* Set the URL */
		status = cryptSetAttributeString( cryptSession, 
										  CRYPT_SESSINFO_SERVER_NAME,
										  urlParseInfo[ i ].url,
										  strlen( urlParseInfo[ i ].url ) );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't set URL '%s', line %d.\n", 
					urlParseInfo[ i ].url, __LINE__ );
			return( FALSE );
			}
		
		/* Make sure the parsed form is OK */
		status = cryptGetAttributeString( cryptSession, 
										  CRYPT_SESSINFO_SERVER_NAME,
										  nameBuffer, &lengthLength );
		if( cryptStatusOK( status ) && urlParseInfo[ i ].port )
			status = cryptGetAttribute( cryptSession, 
										CRYPT_SESSINFO_SERVER_PORT, &port );
		if( cryptStatusOK( status ) && urlParseInfo[ i ].userInfo != NULL )
			status = cryptGetAttributeString( cryptSession, 
											  CRYPT_SESSINFO_USERNAME,
											  userInfoBuffer, 
											  &userInfoLength );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't get parsed URL info for '%s', line %d.\n", 
					urlParseInfo[ i ].url, __LINE__ );
			return( FALSE );
			}
		if( memcmp( nameBuffer, urlParseInfo[ i ].name, lengthLength ) || \
			( urlParseInfo[ i ].port && port != urlParseInfo[ i ].port ) || \
			( urlParseInfo[ i ].userInfo != NULL && \
			  memcmp( userInfoBuffer, urlParseInfo[ i ].userInfo, 
			  userInfoLength ) ) )
			{
			printf( "Parsed URL info for '%s' is incorrect, line %d.\n", 
					urlParseInfo[ i ].url, __LINE__ );
			return( FALSE );
			}
		}

	/* Clean up */
	status = cryptDestroySession( cryptSession );
	if( cryptStatusError( status ) )
		{
		printf( "cryptDestroySession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	puts( "Session URL parsing succeeded.\n" );
	return( TRUE );
	}

/****************************************************************************
*																			*
*								SSH Routines Test							*
*																			*
****************************************************************************/

/* There are various servers running that we can use for testing, the
   following remapping allows us to switch between them.  Notes:

	Server 1: Local loopback.
	Server 2: Sends extraneous lines of text before the SSH ID string 
			  (technically allowed by the RFC, but probably not in the way 
			  that it's being used here).
	Server 3: Reference ssh.com implementation.
	Server 4: Reference OpenSSH implementation 

   To test local -> remote/remote -> local forwarding: 

	ssh localhost -v -l test -pw test -L 110:pop3.test.com:110
	ssh localhost -v -l test -pw test -R 110:pop3.test.com:110

  For test purposes we connect to the OpenSSH server for the SSHv2 test 
  because this is the most frequently-used one around, so maintaining 
  compatibility with it whenever it changes is important.  Using it for test 
  connects is slightly antisocial but in practice few people seem to run the 
  self-test and we never get past the initial handshake phase so it shouldn't 
  be a big deal.  Testing SSHv1 is a bit tricky since there are few of these
  servers still around, in the absence of a convenient test server we just 
  try a local connect, which either times out or goes through an SSHv2 
  handshake if there's a server there */

static const char *ssh1Info[] = {
	NULL,
	"localhost",
	NULL
	};
static const char *ssh2Info[] = {
	NULL,
	"localhost",
	"sorrel.humboldt.edu:222",
	"www.ssh.com",
	"openssh.com",
	NULL
	};

#define SSH1_SERVER_NO	1
#define SSH2_SERVER_NO	4

/* Establish an SSH session.  The generic SSHv1 client test will always step 
   up to SSHv2 if the server is v2 (which almost all are), so v1 can't 
   easily be generically tested without hardcoding v1-only into 
   session/ssh.c.  However, the loopback test, which forces the use of a
   v1-only server, does test the client as a v1 client */

static int connectSSH( const CRYPT_SESSION_TYPE sessionType,
					   const BOOLEAN useClientCert, const BOOLEAN useSubsystem,
					   const BOOLEAN usePortForwarding, 
					   const BOOLEAN localSession, const BOOLEAN useSSHv2,
					   const BOOLEAN useFingerprint )
	{
	CRYPT_SESSION cryptSession;
	const char *serverName = localSession ? "localhost" : \
							 useSSHv2 ? ssh2Info[ SSH2_SERVER_NO ] : \
										ssh1Info[ SSH1_SERVER_NO ];
	const BOOLEAN isServer = ( sessionType == CRYPT_SESSION_SSH_SERVER ) ? \
							   TRUE : FALSE;
	char buffer[ BUFFER_SIZE ];
	int cryptAlgo, keySize, version, bytesCopied, status;

	printf( "%sTesting %sSSH%s%s session...\n", isServer ? "SVR: " : "",
			localSession ? "local " : "", useSSHv2 ? "v2" : "v1",
			useSubsystem ? " SFTP" : \
				usePortForwarding ? " port-forwarding" : "" );
	if( !isServer && !localSession )
		printf( "  Remote host: %s.\n", serverName );

	/* Create the session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType );
	if( status == CRYPT_ERROR_PARAM3 )	/* SSH session access not available */
		return( CRYPT_ERROR_NOTAVAIL );
	if( cryptStatusError( status ) )
		{
		printf( "cryptCreateSession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Set up the server and user information and activate the session */
	if( isServer )
		{
		CRYPT_CONTEXT privateKey;

		if( !setLocalConnect( cryptSession, 22 ) )
			return( FALSE );
		status = getPrivateKey( &privateKey, SSH_PRIVKEY_FILE,
								SSH_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
		if( cryptStatusOK( status ) )
			{
			status = cryptSetAttribute( cryptSession,
										CRYPT_SESSINFO_PRIVATEKEY, privateKey );
			cryptDestroyContext( privateKey );
			}
		}
	else
		{
		if( localSession )
			{
			if( !setLocalConnect( cryptSession, 22 ) )
				return( FALSE );
			}
		else
			{
			status = cryptSetAttributeString( cryptSession,
									CRYPT_SESSINFO_SERVER_NAME,
									serverName, strlen( serverName ) );
			}
		if( cryptStatusOK( status ) )
			status = cryptSetAttributeString( cryptSession,
									CRYPT_SESSINFO_USERNAME,
									SSH_USER_NAME, strlen( SSH_USER_NAME ) );
		if( cryptStatusOK( status ) )
			{
			if( useClientCert )
				{
				CRYPT_CONTEXT privateKey;

				status = getPrivateKey( &privateKey, USER_PRIVKEY_FILE,
									USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
				if( cryptStatusOK( status ) )
					{
					status = cryptSetAttribute( cryptSession,
									CRYPT_SESSINFO_PRIVATEKEY, privateKey );
					cryptDestroyContext( privateKey );
					}
				}
			else
				{
#ifdef USER_SUPPLIED_PASSWORD
				char password[ 256 ];

				printf( "Enter SSHv2 server password: " );
				fgets( password, 255, stdin );
				password[ strlen( password ) - 1 ] = '\0';
				status = cryptSetAttributeString( cryptSession,
									CRYPT_SESSINFO_PASSWORD,
									password, strlen( password ) );
#else
				status = cryptSetAttributeString( cryptSession,
									CRYPT_SESSINFO_PASSWORD,
									SSH_PASSWORD, strlen( SSH_PASSWORD ) );
#endif /* User-supplied password */
				}
			}
		if( cryptStatusOK( status ) && useSubsystem )
			status = cryptSetAttributeString( cryptSession,
									CRYPT_SESSINFO_SSH_SUBSYSTEM, "sftp", 4 );
		if( cryptStatusOK( status ) && usePortForwarding )
			status = cryptSetAttributeString( cryptSession,
									CRYPT_SESSINFO_SSH_PORTFORWARD, 
									"localhost:1234", 14 );
		if( cryptStatusOK( status ) && useFingerprint )
			{
			BYTE fingerPrint[ CRYPT_MAX_HASHSIZE ];

			/* Set a dummy (all-zero) fingerprint to force the connect to 
			   fail */
			memset( fingerPrint, 0, CRYPT_MAX_HASHSIZE );
			status = cryptSetAttributeString( cryptSession, 
											  CRYPT_SESSINFO_SERVER_FINGERPRINT, 
											  fingerPrint, 16 );
			}
		}
	if( cryptStatusOK( status ) )
		status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_VERSION,
									useSSHv2 ? 2 : 1 );
	if( cryptStatusError( status ) )
		{
		printf( "cryptSetAttribute/AttributeString() failed with error code "
				"%d, line %d.\n", status, __LINE__ );
		return( FALSE );
		}
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( isServer )
		{
		char subsystem[ CRYPT_MAX_TEXTSIZE + 1 ];
		int length;

		printConnectInfo( cryptSession );
		if( cryptStatusOK( \
			cryptGetAttributeString( cryptSession, CRYPT_SESSINFO_SSH_SUBSYSTEM,
									 subsystem, &length ) ) )
			{
			subsystem[ length ] = '\0';

⌨️ 快捷键说明

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