selfserv.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,329 行 · 第 1/3 页

C
1,329
字号
		if (rv < 0) {		    errWarn("SSL_ForceHandshake");		    break;		}	    }	}	rv = PR_Write(ssl_sock, outHeader, (sizeof(outHeader)) - 1);	if (rv < 0) {	    errWarn("PR_Write");	    break;	}	if (i <= 0) {	/* hit eof */	    PORT_Sprintf(msgBuf, "Get or Post incomplete after %d bytes.\r\n",			 bufDat);	    rv = PR_Write(ssl_sock, msgBuf, PORT_Strlen(msgBuf));	    if (rv < 0) {		errWarn("PR_Write");		break;	    }	} else {	    if (verbose > 1) fwrite(buf, 1, i, stdout);	/* display it */	    rv = PR_Write(ssl_sock, buf, i);	    if (rv < 0) {		errWarn("PR_Write");		break;	    }	    printSecurityInfo(ssl_sock);	    if (i < bufDat) {		PORT_Sprintf(buf, "Discarded %d characters.\r\n", rv - i);		rv = PR_Write(ssl_sock, buf, PORT_Strlen(buf));		if (rv < 0) {		    errWarn("PR_Write");		    break;		}	    }	}	rv = PR_Write(ssl_sock, "EOF\r\n\r\n\r\n", 9);	if (rv < 0) {	    errWarn("PR_Write");	    break;	}    } while (0);cleanup:    PR_Close(ssl_sock);    /* do a nice shutdown if asked. */    if (!strncmp(buf, stopCmd, strlen(stopCmd))) {	stopping = 1;/*	return SECFailure; */    }    return SECSuccess;	/* success */}intdo_accepts(    PRFileDesc *listen_sock,    PRFileDesc *model_sock,    int         requestCert    ){    PRNetAddr   addr;    while (!stopping) {	PRFileDesc *tcp_sock;	SECStatus   result;	FPRINTF(stderr, "\n\n\nselfserv: About to call accept.\n");	tcp_sock = PR_Accept(listen_sock, &addr, PR_INTERVAL_NO_TIMEOUT);	if (tcp_sock == NULL) {	    errWarn("PR_Accept");	    break;	}	if (bigBuf.data != NULL)	    result = launch_thread(handle_fdx_connection, tcp_sock, model_sock, requestCert);	else	    result = launch_thread(handle_connection, tcp_sock, model_sock, requestCert);	if (result != SECSuccess) {	    PR_Close(tcp_sock);	    break;        }    }    fprintf(stderr, "selfserv: Closing listen socket.\n");    PR_Close(listen_sock);    return SECSuccess;}voidserver_main(    unsigned short      port,     int                 requestCert,     SECKEYPrivateKey ** privKey,    CERTCertificate **  cert){    PRFileDesc *listen_sock;    PRFileDesc *model_sock	= NULL;    int         rv;    SSLKEAType  kea;    PRNetAddr   addr;    SECStatus	secStatus;    PRSocketOptionData opt;    networkStart();    addr.inet.family = PR_AF_INET;    addr.inet.ip     = PR_INADDR_ANY;    addr.inet.port   = PR_htons(port);    /* all suites except RSA_NULL_MD5 are enabled by default */    listen_sock = PR_NewTCPSocket();    if (listen_sock == NULL) {	errExit("PR_NewTCPSocket");    }    opt.option = PR_SockOpt_Nonblocking;    opt.value.non_blocking = PR_FALSE;    PR_SetSocketOption(listen_sock, &opt);    opt.option=PR_SockOpt_Reuseaddr;    opt.value.reuse_addr = PR_TRUE;    PR_SetSocketOption(listen_sock, &opt);    if (useModelSocket) {    	model_sock = PR_NewTCPSocket();	if (model_sock == NULL) {	    errExit("PR_NewTCPSocket on model socket");	}	model_sock = SSL_ImportFD(NULL, model_sock);	if (model_sock == NULL) {	    errExit("SSL_ImportFD");	}    } else {	model_sock = listen_sock = SSL_ImportFD(NULL, listen_sock);	if (listen_sock == NULL) {	    errExit("SSL_ImportFD");	}    }    /* do SSL configuration. */#if 0    /* This is supposed to be true by default.    ** Setting it explicitly should not be necessary.    ** Let's test and make sure that's true.    */    rv = SSL_Enable(model_sock, SSL_SECURITY, 1);    if (rv < 0) {	errExit("SSL_Enable SSL_SECURITY");    }#endif    rv = SSL_Enable(model_sock, SSL_ENABLE_SSL3, !disableSSL3);    if (rv != SECSuccess) {	errExit("error enabling SSLv3 ");    }    rv = SSL_Enable(model_sock, SSL_ENABLE_TLS, !disableTLS);    if (rv != SECSuccess) {	errExit("error enabling TLS ");    }    rv = SSL_Enable(model_sock, SSL_ROLLBACK_DETECTION, !disableRollBack);    if (rv != SECSuccess) {	errExit("error enabling RollBack detection ");    }    for (kea = kt_rsa; kea < kt_kea_size; kea++) {	if (cert[kea] != NULL) {	    secStatus = SSL_ConfigSecureServer(model_sock, 	    		cert[kea], privKey[kea], kea);	    if (secStatus != SECSuccess)		errExit("SSL_ConfigSecureServer");	}    }    if (bigBuf.data) { /* doing FDX */	rv = SSL_Enable(model_sock, SSL_ENABLE_FDX, 1);	if (rv < 0) {	    errExit("SSL_Enable SSL_ENABLE_FDX");	}    }    /* This cipher is not on by default. The Acceptance test     * would like it to be. Turn this cipher on.     */    secStatus = SSL_EnableCipher( SSL_RSA_WITH_NULL_MD5, PR_TRUE);    if ( secStatus != SECSuccess ) {	errExit("SSL_EnableCipher:SSL_RSA_WITH_NULL_MD5");    }    if (requestCert) {	SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate, 	                        (void *)CERT_GetDefaultCertDB());	if (requestCert <= 2) { 	    rv = SSL_Enable(model_sock, SSL_REQUEST_CERTIFICATE, 1);	    if (rv < 0) {		errExit("first SSL_Enable SSL_REQUEST_CERTIFICATE");	    }	    rv = SSL_Enable(model_sock, SSL_REQUIRE_CERTIFICATE, 	                    (requestCert == 2));	    if (rv < 0) {		errExit("first SSL_Enable SSL_REQUIRE_CERTIFICATE");	    }	}    }    /* end of ssl configuration. */    rv = PR_Bind(listen_sock, &addr);    if (rv < 0) {	errExit("PR_Bind");    }    rv = PR_Listen(listen_sock, 5);    if (rv < 0) {	errExit("PR_Listen");    }    rv = launch_thread(do_accepts, listen_sock, model_sock, requestCert);    if (rv != SECSuccess) {    	PR_Close(listen_sock);    } else {	reap_threads();	destroy_thread_data();    }    if (useModelSocket && model_sock) {    	PR_Close(model_sock);    }    networkEnd();}SECStatusreadBigFile(const char * fileName){    PRFileInfo  info;    PRStatus	status;    SECStatus	rv	= SECFailure;    int		count;    int		hdrLen;    PRFileDesc *local_file_fd = NULL;    status = PR_GetFileInfo(fileName, &info);    if (status == PR_SUCCESS &&	info.type == PR_FILE_FILE &&	info.size > 0 &&	NULL != (local_file_fd = PR_Open(fileName, PR_RDONLY, 0))) {	hdrLen      = PORT_Strlen(outHeader);	bigBuf.len  = hdrLen + info.size;	bigBuf.data = PORT_Malloc(bigBuf.len + 4095);	if (!bigBuf.data) {	    errWarn("PORT_Malloc");	    goto done;	}	PORT_Memcpy(bigBuf.data, outHeader, hdrLen);	count = PR_Read(local_file_fd, bigBuf.data + hdrLen, info.size);	if (count != info.size) {	    errWarn("PR_Read local file");	    goto done;	}	rv = SECSuccess;done:	PR_Close(local_file_fd);    }    return rv;}intmain(int argc, char **argv){    char *               progName    = NULL;    char *               nickName    = NULL;    char *               fNickName   = NULL;    char *               fileName    = NULL;    char *               cipherString= NULL;    char *               dir         = ".";    char *               passwd      = NULL;    char *		 pidFile    = NULL;    char *               tmp;    CERTCertificate *    cert   [kt_kea_size] = { NULL };    SECKEYPrivateKey *   privKey[kt_kea_size] = { NULL };    unsigned short       port        = 0;    SECStatus            rv;    PRBool               useExportPolicy = PR_FALSE;    PLOptState *optstate;    tmp = strrchr(argv[0], '/');    tmp = tmp ? tmp + 1 : argv[0];    progName = strrchr(tmp, '\\');    progName = progName ? progName + 1 : tmp;    optstate = PL_CreateOptState(argc, argv, "RT2:3c:d:p:mn:i:f:rvw:x");    while (PL_GetNextOpt(optstate) == PL_OPT_OK) {	switch(optstate->option) {	default:	case '?': Usage(progName); 		break;	case '2': fileName = optstate->value; 	break;	case '3': disableSSL3 = PR_TRUE;	break;	case 'R': disableRollBack = PR_TRUE;	break;	case 'T': disableTLS  = PR_TRUE;	break;        case 'c': cipherString = strdup(optstate->value); break;	case 'd': dir = optstate->value; 	break;	case 'f': fNickName = optstate->value; 	break;        case 'm': useModelSocket = PR_TRUE; 	break;        case 'n': nickName = optstate->value; 	break;        case 'i': pidFile = optstate->value; 	break;	case 'p': port = PORT_Atoi(optstate->value); break;	case 'r': ++requestCert; 		break;        case 'v': verbose++; 			break;	case 'w': passwd = optstate->value;	break;        case 'x': useExportPolicy = PR_TRUE; 	break;	}    }    if ((nickName == NULL) && (fNickName == NULL))	Usage(progName);    if (port == 0)	Usage(progName);    if (pidFile) {	FILE *tmpfile=fopen(pidFile,"w+");	if (tmpfile) {	    fprintf(tmpfile,"%d",getpid());	    fclose(tmpfile);        }    }	    /* Call the NSPR initialization routines */    PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);    if (fileName)    	readBigFile(fileName);    /* set our password function */    PK11_SetPasswordFunc( passwd ? ownPasswd : SECU_GetModulePassword);    /* Call the libsec initialization routines */    rv = NSS_Init(dir);    if (rv != SECSuccess) {    	fputs("NSS_Init failed.\n", stderr);	exit(1);    }    /* set the policy bits true for all the cipher suites. */    if (useExportPolicy)	NSS_SetExportPolicy();    else	NSS_SetDomesticPolicy();    /* all the SSL2 and SSL3 cipher suites are enabled by default. */    if (cipherString) {    	int ndx;	/* disable all the ciphers, then enable the ones we want. */	disableSSL2Ciphers();	disableSSL3Ciphers();	while (0 != (ndx = *cipherString++)) {	    int *cptr;	    int  cipher;	    if (! isalpha(ndx))	     	Usage(progName);	    cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;	    for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; ) 	    	/* do nothing */;	    if (cipher) {		SECStatus status;		status = SSL_CipherPrefSetDefault(cipher, SSL_ALLOWED);		if (status != SECSuccess) 		    SECU_PrintError(progName, "SSL_CipherPrefSet()");	    }	}    }    if (nickName) {	cert[kt_rsa] = PK11_FindCertFromNickname(nickName, passwd);	if (cert[kt_rsa] == NULL) {	    fprintf(stderr, "selfserv: Can't find certificate %s\n", nickName);	    exit(1);	}	privKey[kt_rsa] = PK11_FindKeyByAnyCert(cert[kt_rsa], passwd);	if (privKey[kt_rsa] == NULL) {	    fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n", nickName);	    exit(1);	}    }    if (fNickName) {	cert[kt_fortezza] = PK11_FindCertFromNickname(fNickName, NULL);	if (cert[kt_fortezza] == NULL) {	    fprintf(stderr, "selfserv: Can't find certificate %s\n", fNickName);	    exit(1);	}	privKey[kt_fortezza] = PK11_FindKeyByAnyCert(cert[kt_fortezza], NULL);    }    rv = SSL_ConfigMPServerSIDCache(256, 0, 0, NULL);    if (rv != SECSuccess) {        errExit("SSL_ConfigMPServerSIDCache");    }    server_main(port, requestCert, privKey, cert);    NSS_Shutdown();    PR_Cleanup();    return 0;}

⌨️ 快捷键说明

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