📄 testssl.c
字号:
/* *********************************************************************
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 + -