netscape-revival
security/cmd/selfserv.c
#include "secutil.h"
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include "pk11func.h"
#include "secitem.h"
static void
Usage(const char *progName)
{
fprintf(stderr, "Usage: %s -n nickname -p port [-d dbdir]\n", progName);
exit(-1);
}
void
server_main(int port)
{
int listen_sock;
int fd;
int rv;
struct sockaddr_in sin;
char buf[1000];
int len;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_family = AF_INET;
sin.sin_port = port;
listen_sock = SSL_Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listen_sock < 0) {
exit(-1);
}
rv = SSL_Bind(listen_sock, (struct sockaddr *) &sin, sizeof(sin));
if (rv < 0) {
exit(-1);
}
rv = SSL_Enable(listen_sock, SSL_SECURITY, 1);
if (rv < 0) {
exit(-1);
}
rv = SSL_Enable(listen_sock, SSL_REQUEST_CERTIFICATE, 1);
if (rv < 0) {
exit(-1);
}
rv = SSL_Listen(listen_sock, 5);
if (rv < 0) {
exit(-1);
}
len = sizeof(sin);
while((fd = SSL_Accept(listen_sock, (struct sockaddr *)&sin,
&len)) > 0) {
do {
rv = SSL_Read(fd, buf, sizeof(buf));
} while((rv == -1) && (PORT_GetError() == EWOULDBLOCK));
SSL_Write(fd, "foo\n", 5);
SSL_Close(fd);
}
}
char *
get_certdb_name(void *cbarg, int dbVersion)
{
return SECU_DatabaseFileName(xpCertDB);
}
int
main(int argc, char **argv)
{
int o, port = 0;
char *progName = NULL;
char *nickname = NULL;
CERTCertificate *cert;
SECItem *ssl2cert;
CERTCertificateList *ssl3chain;
SECKEYPrivateKey *privKey;
CERTCertDBHandle *cert_db_handle;
progName = strrchr(argv[0], '/');
progName = progName ? progName+1 : argv[0];
while ((o = getopt(argc, argv, "d:p:n:")) != -1) {
switch(o) {
default:
case '?':
Usage(progName);
break;
case 'd':
SECU_ConfigDirectory(optarg);
break;
case 'n':
nickname = optarg;
break;
case 'p':
port = PORT_Atoi(optarg);
}
}
if (nickname == NULL)
Usage(progName);
if (port == 0)
Usage(progName);
/* Call the libsec initialization routines */
PR_Init("selfserv", 1, 1, 0);
SECU_PKCS11Init();
RNG_SystemInfoForRNG();
/* Open the server cert database */
cert_db_handle = (CERTCertDBHandle *)PORT_ZAlloc(sizeof(CERTCertDBHandle));
if (!cert_db_handle) {
exit(-1);
}
/* Open default database, readonly false */
CERT_OpenCertDB(cert_db_handle, PR_TRUE, get_certdb_name, NULL);
/* XXX - this should not be required for SSL */
CERT_SetDefaultCertDB(cert_db_handle);
cert = PK11_FindCertFromNickname(nickname, NULL);
if (cert == NULL) {
fprintf(stderr, "Can't find certificate %s\n", nickname);
exit(-1);
}
ssl2cert = SECITEM_DupItem(&cert->derCert);
ssl3chain = CERT_CertChainFromCert(CERT_GetDefaultCertDB(), cert);
privKey = PK11_FindPrivateKeyFromCert(PK11_GetInternalKeySlot(),
cert, NULL);
SSL_ConfigSecureServer(ssl2cert, privKey, ssl3chain,
CERT_GetSSLCACerts(CERT_GetDefaultCertDB()));
SSL_ConfigServerSessionIDCache(10, 0, 0, ".");
server_main(port);
}