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

📄 testssl.c

📁 Netscape公司提供的安全套接字层
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	*********************************************************************
	File: testssl.c

	SSLRef 3.0 Final -- 11/19/96

	Copyright (c)1996 by Netscape Communications Corp.

	By retrieving this software you are bound by the licensing terms
	disclosed in the file "LICENSE.txt". Please read it, and if you don't
	accept the terms, delete this software.

	SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
	View, California <http://home.netscape.com/> and Consensus Development
	Corporation of Berkeley, California <http://www.consensus.com/>.

	*********************************************************************

	File: testssl.c    Main function for the sample client


	****************************************************************** */

#include "ssl.h"
#include "testssl.h"

#if MAC
#undef BIG_ENDIAN /* conflict with BSAFE */
#include <GUSI.h>
int gethostname(char *, int);
#elif WIN32
#include <winsock.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#ifdef WIN32
static SSLErr AcceptClientConnection(int port, SOCKET *socketNo, PeerSpec *peer);
static SSLErr MakeServerConnection(char *hostName, int port, SOCKET *socketNo, PeerSpec *peer);
#else
static SSLErr AcceptClientConnection(int port, int *socketNo, PeerSpec *peer);
static SSLErr MakeServerConnection(char *hostName, int port, int *socketNo, PeerSpec *peer);
#endif

#define SERVER_MESSAGE	"<HTML><HEAD><TITLE>SSLRef 3 Test Server</TITLE></HEAD><BODY><H2>You have sucessfully made a secure connection!</H2>Message from the 'testssl' sample application, a part of <A HREF=\"http://home.netscape.com/newsref/std/SSL.html\">SSLRef 3.0</A>.</BODY></HTML>\015\012"
#define CLIENT_REQUEST	"GET /\015\012"

void *gRandomRef;

int
main(int argc, char *argv[])
{	int 				i;
#ifdef WIN32
	SOCKET				sock;
	WORD				wVersionRequested;
	WSADATA 			wsaData;
#else
	int 				sock;
#endif
	SSLErr				err;
	SSLContext			*ctx;
	uint32				length;
	int 				isServer = DEFAULTSERVER, port = DEFAULTPORT;
	int 				clientAuth = DEFAULTAUTH, useCache = DEFAULTCACHE;
	char				*hostName = DEFAULTHOST;
	SSLProtocolVersion	version = DEFAULTVERSION;
	uint8				buffer[4096];
	void				*databaseRef;
	PeerSpec			peer;
	SSLBuffer			peerID;
	SSLRSAPrivateKey	privKey;

#if MAC
	GUSISetup(GUSIwithSIOUXSockets);
	GUSISetup(GUSIwithInternetSockets);
	printf("*** Initialize ***\n");
#endif

	for (i = 1; i < argc; i++)
	{	if ((argv[i][0] == '-') || (argv[i][0] == '/'))
		{	switch (argv[i][1])
			{	case 'c':
					isServer = 0;
					break;
				case 's':
					isServer = 1;
					break;
				case '2':
					version = SSL_Version_2_0;
					break;
				case '3':
					version = SSL_Version_3_0_Only;
					break;
				case 'h':
					version = SSL_Version_3_0_With_2_0_Hello;
					break;
				case 'n':
					version = SSL_Version_Undetermined;
					break;
				case 'A':
					clientAuth = 1;
					break;
				case 'a':
					clientAuth = 0;
					break;
				case 'R':
					useCache = 1;
					break;
				case 'r':
					useCache = 0;
					break;
				case 'p':
					if (argv[i][2] >= '0' && argv[i][2] <= '9')
						sscanf(argv[i]+2,"%d", &port);
					else if (argc > (i+1))
						sscanf(argv[++i],"%d", &port);
					else
						goto usage;
					break;
				default:
					printf("Bad argument %s\n", argv[i]);
					goto usage;
				case 'H':
				case '?':
					goto usage;
			}
		}
		else
			hostName = argv[i];
	}

//-c localhost -p 4430 -r
	printf("isServer =%d, port=%d\n", isServer, port);

	ctx = (SSLContext *)malloc(SSLContextSize());
	ConfigureGenericSSLSession(ctx);

	#ifdef WIN32
	wVersionRequested = 0x0101;

	if (err = WSAStartup(wVersionRequested, &wsaData))
		{
			printf("Could not start winsocks\n");
			exit(-1);
		}
	if ((LOBYTE(wsaData.wVersion) != 1) || (HIBYTE(wsaData.wVersion) != 1))
		{
			printf("Wrong version of winsock loaded.  We only work with 1.1\n");
			WSACleanup();
			exit(-1);
		}
	#endif

	if (isServer || clientAuth)
	{	ERR(ReadPrivateKey(&privKey, ctx));
		ERR(SSLSetPrivateKey(ctx, &privKey));
		ERR(AddCertificates(ctx));
	}
	if (isServer)
		ERR(SSLSetExportPrivateKey(ctx, &privKey));
	if (isServer && clientAuth)
		ERR(AddDistinguishedNames(ctx));

	ERR(AddDHParams(ctx));

	ERR(SSLSetProtocolVersion(ctx, version));

	if (useCache)
	{	InitDatabase("SessionDB", &databaseRef);
		ERR(SSLSetSessionRef(ctx, databaseRef));
	}
	else
		ERR(SSLSetSessionRef(ctx, (void*)0));

	memset(&peer, 0, sizeof(PeerSpec));
	if (isServer)
	{	ERR(SSLSetProtocolSide(ctx, SSL_ServerSide));
		ERR(SSLSetRequestClientCert(ctx, clientAuth));
		ERR(AcceptClientConnection(port, &sock, &peer));
	}
	else
	{	ERR(SSLSetProtocolSide(ctx, SSL_ClientSide));
		ERR(MakeServerConnection(hostName, port, &sock, &peer));
	}

	if (useCache)
	{	peerID.data = (uint8*)&peer;
		peerID.length = sizeof(peer);
		ERR(SSLSetPeerID(ctx, peerID));
	}

	ERR(SSLSetIORef(ctx, (void*)&sock));

	do
	{	err = SSLHandshake(ctx);
	} while (err == SSLWouldBlockErr);

	ERR(err);

	if (err == SSLNoErr)
	{	if (isServer)
		{	buffer[0] = 0;
			while (err == 0 && buffer[0] != '\012')
			{	length = 1;
				ERR(err = SSLRead(buffer, &length, ctx));
				fwrite(buffer, 1, length, stdout);
				if (err == SSLWouldBlockErr)
					err = SSLNoErr;
			}
		
			if (err == SSLNoErr)
			{	length = sizeof(SERVER_MESSAGE) - 1;
				ERR(err = SSLWrite(SERVER_MESSAGE, &length, ctx));
			}
		
			if (err == SSLNoErr)
				ERR(SSLClose(ctx));
		}
		else
		{	
			length = sizeof(CLIENT_REQUEST) - 1;
		
			ERR(err = SSLWrite(CLIENT_REQUEST, &length, ctx));
			while (err == 0)
			{	length = sizeof(buffer);
				ERR(err = SSLRead(buffer, &length, ctx));
				fwrite(buffer, 1, length, stdout);
				if (err == SSLWouldBlockErr)
					err = SSLNoErr;
			}
			if (err == SSLNoErr)
				ERR(SSLClose(ctx));
		}
	}

#ifdef WIN32
	closesocket(sock);
	WSACleanup();
#else
	close(sock);
#endif
	if (useCache)
		ERR(DisposeDatabase());

	SSLDeleteContext(ctx);
	free((char*)ctx);
	
#if BSAFE
	B_DestroyAlgorithmObject(gRandomRef);
#endif
		
	printf("*** done [%d] ***\n", err);
	return 0;

usage:
	fprintf(stderr, "Usage: %s [-c | -s] [-2 | -3 | -h | -n] [host] [-p port]\n", argv[0]);
	fprintf(stderr, "   -c: Act as client\n   -s: Act as server\n");
	fprintf(stderr, "   -2: SSL 2.0 only\n   -3: SSL 3.0 only\n");
	fprintf(stderr, "   -h: Support SSL 3.0, but allow SSL 2.0 hello messages\n");
	fprintf(stderr, "   -n: Support both 2.0 and 3.0\n");
	fprintf(stderr, "   -A: Request or support client authentication\n");
	fprintf(stderr, "   -a: Do not request or support client authentication\n");
	fprintf(stderr, "   -R: Use a cache to resume sessions\n");
	fprintf(stderr, "   -r: Disable session resumption\n");
	fprintf(stderr, "   host: Host to connect to\n   -p port: Use port number port\n");
	fprintf(stderr, "   Defaults are:\n    side: %s\n", DEFAULTSERVER ? "server" : "client");
	fprintf(stderr, "    host: %s\n    port: %d\n", DEFAULTHOST, DEFAULTPORT);
	{	char	*protocolName;
#define NAMECASE(version)	case version: protocolName = #version; break;
		switch(DEFAULTVERSION)
		{	NAMECASE(SSL_Version_2_0)
			NAMECASE(SSL_Version_3_0)
			NAMECASE(SSL_Version_3_0_Only)
			NAMECASE(SSL_Version_3_0_With_2_0_Hello)
			NAMECASE(SSL_Version_Undetermined)
		}
		fprintf(stderr, "    protocol: %s\n", protocolName);
	}
	fprintf(stderr, "    request authentication: %s\n", DEFAULTAUTH ? "yes" : "no");
	fprintf(stderr, "    use session caching: %s\n", DEFAULTCACHE ? "yes" : "no");
	exit(1);
	return 1;
}

static SSLErr
#ifdef WIN32
MakeServerConnection(char *hostName, int port, SOCKET *socketNo, PeerSpec *peer)
#else
MakeServerConnection(char *hostName, int port, int *socketNo, PeerSpec *peer)
#endif
{	struct sockaddr_in	addr;
	struct hostent		*ent;
	struct in_addr		host;

	if (hostName[0] >= '0' && hostName[0] <= '9')
	{
#if MAC
		host.s_addr = inet_addr(hostName).s_addr;
#else
		host.s_addr = inet_addr(hostName);
#endif
	}
	else
	{	ent = gethostbyname(hostName);
		if (!ent)
		{	printf("gethostbyname failed\n");
			exit(1);
		}
		memcpy(&host, ent->h_addr, sizeof(struct in_addr));
	}
	*socketNo = socket(AF_INET, SOCK_STREAM, 0);
	addr.sin_addr = host;
	addr.sin_port = htons((u_short)port);

	addr.sin_family = AF_INET;
	if (connect(*socketNo, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) != 0)
	{	printf("connect returned error\n");
		exit(1);
	}

	peer->ipAddr = addr.sin_addr.s_addr;
	peer->port = htons((u_short)port);

	return SSLNoErr;
}	

static SSLErr
#ifdef WIN32
AcceptClientConnection(int port, SOCKET *socketNo, PeerSpec *peer)
#else
AcceptClientConnection(int port, int *socketNo, PeerSpec *peer)
#endif
{	struct sockaddr_in	addr;
	struct hostent		*ent;
	char				buffer[100];
	int 				len;

	*socketNo = socket(AF_INET, SOCK_STREAM, 0);

	gethostname(buffer, 100);
	ent = gethostbyname(buffer);
	if (!ent)
	{	printf("gethostbyname failed\n");
		exit(1);
	}
	memcpy(&addr.sin_addr, ent->h_addr, sizeof(struct in_addr));

	addr.sin_port = htons((u_short)port);
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_family = AF_INET;
	len = sizeof(struct sockaddr_in);
	if (bind(*socketNo, (struct sockaddr *) &addr, len))
	{	printf("bind failed\n");
		exit(1);
	}
	if (listen(*socketNo, 1))
	{	printf("listen failed\n");
		exit(1);
	}

⌨️ 快捷键说明

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