diff options
author | Franziskus Kiefer <franziskuskiefer@gmail.com> | 2016-04-21 21:50:20 +0200 |
---|---|---|
committer | Franziskus Kiefer <franziskuskiefer@gmail.com> | 2016-04-21 21:50:20 +0200 |
commit | efe5b290c741ac43f20cfef1d138360f79bdcdc1 (patch) | |
tree | d95945989095c453fcea223a7ec4a496efb7a396 /cmd/selfserv | |
parent | 8189af23f9ee951b4f5ca31d4e79693bc34d4ae5 (diff) | |
download | nss-hg-efe5b290c741ac43f20cfef1d138360f79bdcdc1.tar.gz |
Bug 1254918 - clang-format NSS: cmd, r=kaie
Diffstat (limited to 'cmd/selfserv')
-rw-r--r-- | cmd/selfserv/selfserv.c | 3043 |
1 files changed, 1576 insertions, 1467 deletions
diff --git a/cmd/selfserv/selfserv.c b/cmd/selfserv/selfserv.c index ca6d0eb10..bf85d1637 100644 --- a/cmd/selfserv/selfserv.c +++ b/cmd/selfserv/selfserv.c @@ -3,10 +3,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* -r flag is interepreted as follows: - * 1 -r means request, not require, on initial handshake. - * 2 -r's mean request and require, on initial handshake. - * 3 -r's mean request, not require, on second handshake. - * 4 -r's mean request and require, on second handshake. + * 1 -r means request, not require, on initial handshake. + * 2 -r's mean request and require, on initial handshake. + * 3 -r's mean request, not require, on second handshake. + * 4 -r's mean request and require, on second handshake. */ #include <stdio.h> #include <string.h> @@ -18,7 +18,7 @@ #endif #if defined(_WINDOWS) -#include <process.h> /* for getpid() */ +#include <process.h> /* for getpid() */ #endif #include <signal.h> @@ -56,17 +56,17 @@ int NumSidCacheEntries = 1024; -static int handle_connection( PRFileDesc *, PRFileDesc *, int ); +static int handle_connection(PRFileDesc *, PRFileDesc *, int); static const char envVarName[] = { SSL_ENV_VAR_NAME }; static const char inheritableSockName[] = { "SELFSERV_LISTEN_SOCKET" }; #define DEFAULT_BULK_TEST 16384 -#define MAX_BULK_TEST 1048576 /* 1 MB */ +#define MAX_BULK_TEST 1048576 /* 1 MB */ static PRBool testBulk; -static PRUint32 testBulkSize = DEFAULT_BULK_TEST; +static PRUint32 testBulkSize = DEFAULT_BULK_TEST; static PRInt32 testBulkTotal; -static char* testBulkBuf; +static char *testBulkBuf; static PRDescIdentity log_layer_id = PR_INVALID_IO_LAYER; static PRFileDesc *loggingFD; static PRIOMethods loggingMethods; @@ -88,135 +88,143 @@ static enum ocspStaplingModeEnum { osm_corrupted, /* supply a corrupted data block as the status */ osm_random, /* use a random response for each connection */ osm_ocsp /* retrieve ocsp status from external ocsp server, - use empty status if server is unavailable */ + use empty status if server is unavailable */ } ocspStaplingMode = osm_disabled; typedef enum ocspStaplingModeEnum ocspStaplingModeType; static char *ocspStaplingCA = NULL; static SECItemArray *certStatus[kt_kea_size] = { NULL }; const int ssl3CipherSuites[] = { - -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */ - -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA * b */ - TLS_RSA_WITH_RC4_128_MD5, /* c */ - TLS_RSA_WITH_3DES_EDE_CBC_SHA, /* d */ - TLS_RSA_WITH_DES_CBC_SHA, /* e */ - TLS_RSA_EXPORT_WITH_RC4_40_MD5, /* f */ - TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */ - -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA, * h */ - TLS_RSA_WITH_NULL_MD5, /* i */ - SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */ - SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */ - TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, /* l */ - TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, /* m */ - TLS_RSA_WITH_RC4_128_SHA, /* n */ - TLS_DHE_DSS_WITH_RC4_128_SHA, /* o */ - TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, /* p */ - TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, /* q */ - TLS_DHE_RSA_WITH_DES_CBC_SHA, /* r */ - TLS_DHE_DSS_WITH_DES_CBC_SHA, /* s */ - TLS_DHE_DSS_WITH_AES_128_CBC_SHA, /* t */ - TLS_DHE_RSA_WITH_AES_128_CBC_SHA, /* u */ - TLS_RSA_WITH_AES_128_CBC_SHA, /* v */ - TLS_DHE_DSS_WITH_AES_256_CBC_SHA, /* w */ - TLS_DHE_RSA_WITH_AES_256_CBC_SHA, /* x */ - TLS_RSA_WITH_AES_256_CBC_SHA, /* y */ - TLS_RSA_WITH_NULL_SHA, /* z */ + -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */ + -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA * b */ + TLS_RSA_WITH_RC4_128_MD5, /* c */ + TLS_RSA_WITH_3DES_EDE_CBC_SHA, /* d */ + TLS_RSA_WITH_DES_CBC_SHA, /* e */ + TLS_RSA_EXPORT_WITH_RC4_40_MD5, /* f */ + TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */ + -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA, * h */ + TLS_RSA_WITH_NULL_MD5, /* i */ + SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */ + SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */ + TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, /* l */ + TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, /* m */ + TLS_RSA_WITH_RC4_128_SHA, /* n */ + TLS_DHE_DSS_WITH_RC4_128_SHA, /* o */ + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, /* p */ + TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, /* q */ + TLS_DHE_RSA_WITH_DES_CBC_SHA, /* r */ + TLS_DHE_DSS_WITH_DES_CBC_SHA, /* s */ + TLS_DHE_DSS_WITH_AES_128_CBC_SHA, /* t */ + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, /* u */ + TLS_RSA_WITH_AES_128_CBC_SHA, /* v */ + TLS_DHE_DSS_WITH_AES_256_CBC_SHA, /* w */ + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, /* x */ + TLS_RSA_WITH_AES_256_CBC_SHA, /* y */ + TLS_RSA_WITH_NULL_SHA, /* z */ 0 }; /* data and structures for shutdown */ -static int stopping; +static int stopping; -static PRBool noDelay; -static int requestCert; -static int verbose; -static SECItem bigBuf; -static int configureDHE = -1; /* -1: don't configure, 0 disable, >=1 enable*/ +static PRBool noDelay; +static int requestCert; +static int verbose; +static SECItem bigBuf; +static int configureDHE = -1; /* -1: don't configure, 0 disable, >=1 enable*/ static int configureReuseECDHE = -1; /* -1: don't configure, 0 refresh, >=1 reuse*/ -static int configureWeakDHE = -1; /* -1: don't configure, 0 disable, >=1 enable*/ +static int configureWeakDHE = -1; /* -1: don't configure, 0 disable, >=1 enable*/ -static PRThread * acceptorThread; +static PRThread *acceptorThread; static PRLogModuleInfo *lm; -#define PRINTF if (verbose) printf -#define FPRINTF if (verbose) fprintf -#define FLUSH if (verbose) { fflush(stdout); fflush(stderr); } -#define VLOG(arg) PR_LOG(lm,PR_LOG_DEBUG,arg) +#define PRINTF \ + if (verbose) \ + printf +#define FPRINTF \ + if (verbose) \ + fprintf +#define FLUSH \ + if (verbose) { \ + fflush(stdout); \ + fflush(stderr); \ + } +#define VLOG(arg) PR_LOG(lm, PR_LOG_DEBUG, arg) static void PrintUsageHeader(const char *progName) { - fprintf(stderr, -"Usage: %s -n rsa_nickname -p port [-BDENRbjlmrsuvx] [-w password]\n" -" [-t threads] [-i pid_file] [-c ciphers] [-Y] [-d dbdir] [-g numblocks]\n" -" [-f password_file] [-L [seconds]] [-M maxProcs] [-P dbprefix]\n" -" [-V [min-version]:[max-version]] [-a sni_name]\n" -" [ T <good|revoked|unknown|badsig|corrupted|none|ocsp>] [-A ca]\n" -" [-C SSLCacheEntries] [-S dsa_nickname]" + fprintf(stderr, + "Usage: %s -n rsa_nickname -p port [-BDENRbjlmrsuvx] [-w password]\n" + " [-t threads] [-i pid_file] [-c ciphers] [-Y] [-d dbdir] [-g numblocks]\n" + " [-f password_file] [-L [seconds]] [-M maxProcs] [-P dbprefix]\n" + " [-V [min-version]:[max-version]] [-a sni_name]\n" + " [ T <good|revoked|unknown|badsig|corrupted|none|ocsp>] [-A ca]\n" + " [-C SSLCacheEntries] [-S dsa_nickname]" #ifndef NSS_DISABLE_ECC - " [-e ec_nickname]" + " [-e ec_nickname]" #endif /* NSS_DISABLE_ECC */ -"\n" -" -U [0|1] -H [0|1] -W [0|1]\n" - ,progName); + "\n" + " -U [0|1] -H [0|1] -W [0|1]\n", + progName); } static void PrintParameterUsage() { fputs( -"-V [min]:[max] restricts the set of enabled SSL/TLS protocol versions.\n" -" All versions are enabled by default.\n" -" Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2\n" -" Example: \"-V ssl3:\" enables SSL 3 and newer.\n" -"-B bypasses the PKCS11 layer for SSL encryption and MACing\n" -"-q checks for bypassability\n" -"-D means disable Nagle delays in TCP\n" -"-E means disable export ciphersuites and SSL step down key gen\n" -"-R means disable detection of rollback from TLS to SSL3\n" -"-a configure server for SNI.\n" -"-k expected name negotiated on server sockets\n" -"-b means try binding to the port and exit\n" -"-m means test the model-socket feature of SSL_ImportFD.\n" -"-r flag is interepreted as follows:\n" -" 1 -r means request, not require, cert on initial handshake.\n" -" 2 -r's mean request and require, cert on initial handshake.\n" -" 3 -r's mean request, not require, cert on second handshake.\n" -" 4 -r's mean request and require, cert on second handshake.\n" -"-s means disable SSL socket locking for performance\n" -"-u means enable Session Ticket extension for TLS.\n" -"-v means verbose output\n" -"-x means use export policy.\n" -"-z means enable compression.\n" -"-L seconds means log statistics every 'seconds' seconds (default=30).\n" -"-M maxProcs tells how many processes to run in a multi-process server\n" -"-N means do NOT use the server session cache. Incompatible with -M.\n" -"-t threads -- specify the number of threads to use for connections.\n" -"-i pid_file file to write the process id of selfserve\n" -"-l means use local threads instead of global threads\n" -"-g numblocks means test throughput by sending total numblocks chunks\n" -" of size 16kb to the client, 0 means unlimited (default=0)\n" -"-j means measure TCP throughput (for use with -g option)\n" -"-C SSLCacheEntries sets the maximum number of entries in the SSL\n" -" session cache\n" -"-T <mode> enable OCSP stapling. Possible modes:\n" -" none: don't send cert status (default)\n" -" good, revoked, unknown: Include locally signed response. Requires: -A\n" -" failure: return a failure response (try later, unsigned)\n" -" badsig: use a good status but with an invalid signature\n" -" corrupted: stapled cert status is an invalid block of data\n" -" random: each connection uses a random status from this list:\n" -" good, revoked, unknown, failure, badsig, corrupted\n" -" ocsp: fetch from external OCSP server using AIA, or none\n" -"-A <ca> Nickname of a CA used to sign a stapled cert status\n" -"-U override default ECDHE ephemeral key reuse, 0: refresh, 1: reuse\n" -"-H override default DHE server support, 0: disable, 1: enable\n" -"-W override default DHE server weak parameters support, 0: disable, 1: enable\n" -"-c Restrict ciphers\n" -"-Y prints cipher values allowed for parameter -c and exits\n" -"-G enables the extended master secret extension [RFC7627]\n" - , stderr); + "-V [min]:[max] restricts the set of enabled SSL/TLS protocol versions.\n" + " All versions are enabled by default.\n" + " Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2\n" + " Example: \"-V ssl3:\" enables SSL 3 and newer.\n" + "-B bypasses the PKCS11 layer for SSL encryption and MACing\n" + "-q checks for bypassability\n" + "-D means disable Nagle delays in TCP\n" + "-E means disable export ciphersuites and SSL step down key gen\n" + "-R means disable detection of rollback from TLS to SSL3\n" + "-a configure server for SNI.\n" + "-k expected name negotiated on server sockets\n" + "-b means try binding to the port and exit\n" + "-m means test the model-socket feature of SSL_ImportFD.\n" + "-r flag is interepreted as follows:\n" + " 1 -r means request, not require, cert on initial handshake.\n" + " 2 -r's mean request and require, cert on initial handshake.\n" + " 3 -r's mean request, not require, cert on second handshake.\n" + " 4 -r's mean request and require, cert on second handshake.\n" + "-s means disable SSL socket locking for performance\n" + "-u means enable Session Ticket extension for TLS.\n" + "-v means verbose output\n" + "-x means use export policy.\n" + "-z means enable compression.\n" + "-L seconds means log statistics every 'seconds' seconds (default=30).\n" + "-M maxProcs tells how many processes to run in a multi-process server\n" + "-N means do NOT use the server session cache. Incompatible with -M.\n" + "-t threads -- specify the number of threads to use for connections.\n" + "-i pid_file file to write the process id of selfserve\n" + "-l means use local threads instead of global threads\n" + "-g numblocks means test throughput by sending total numblocks chunks\n" + " of size 16kb to the client, 0 means unlimited (default=0)\n" + "-j means measure TCP throughput (for use with -g option)\n" + "-C SSLCacheEntries sets the maximum number of entries in the SSL\n" + " session cache\n" + "-T <mode> enable OCSP stapling. Possible modes:\n" + " none: don't send cert status (default)\n" + " good, revoked, unknown: Include locally signed response. Requires: -A\n" + " failure: return a failure response (try later, unsigned)\n" + " badsig: use a good status but with an invalid signature\n" + " corrupted: stapled cert status is an invalid block of data\n" + " random: each connection uses a random status from this list:\n" + " good, revoked, unknown, failure, badsig, corrupted\n" + " ocsp: fetch from external OCSP server using AIA, or none\n" + "-A <ca> Nickname of a CA used to sign a stapled cert status\n" + "-U override default ECDHE ephemeral key reuse, 0: refresh, 1: reuse\n" + "-H override default DHE server support, 0: disable, 1: enable\n" + "-W override default DHE server weak parameters support, 0: disable, 1: enable\n" + "-c Restrict ciphers\n" + "-Y prints cipher values allowed for parameter -c and exits\n" + "-G enables the extended master secret extension [RFC7627]\n", + stderr); } static void @@ -231,40 +239,40 @@ PrintCipherUsage(const char *progName) { PrintUsageHeader(progName); fputs( -"-c ciphers Letter(s) chosen from the following list\n" -"c SSL3 RSA WITH RC4 128 MD5\n" -"d SSL3 RSA WITH 3DES EDE CBC SHA\n" -"e SSL3 RSA WITH DES CBC SHA\n" -"f SSL3 RSA EXPORT WITH RC4 40 MD5\n" -"g SSL3 RSA EXPORT WITH RC2 CBC 40 MD5\n" -"i SSL3 RSA WITH NULL MD5\n" -"j SSL3 RSA FIPS WITH 3DES EDE CBC SHA\n" -"k SSL3 RSA FIPS WITH DES CBC SHA\n" -"l SSL3 RSA EXPORT WITH DES CBC SHA\t(new)\n" -"m SSL3 RSA EXPORT WITH RC4 56 SHA\t(new)\n" -"n SSL3 RSA WITH RC4 128 SHA\n" -"o TLS_DHE_DSS_WITH_RC4_128_SHA\n" -"p TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA\n" -"q TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA\n" -"r TLS_DHE_RSA_WITH_DES_CBC_SHA\n" -"s TLS_DHE_DSS_WITH_DES_CBC_SHA\n" -"t TLS_DHE_DSS_WITH_AES_128_CBC_SHA\n" -"u TLS_DHE_RSA_WITH_AES_128_CBC_SHA\n" -"v SSL3 RSA WITH AES 128 CBC SHA\n" -"w TLS_DHE_DSS_WITH_AES_256_CBC_SHA\n" -"x TLS_DHE_RSA_WITH_AES_256_CBC_SHA\n" -"y SSL3 RSA WITH AES 256 CBC SHA\n" -"z SSL3 RSA WITH NULL SHA\n" -"\n" -":WXYZ Use cipher with hex code { 0xWX , 0xYZ } in TLS\n" - , stderr); + "-c ciphers Letter(s) chosen from the following list\n" + "c SSL3 RSA WITH RC4 128 MD5\n" + "d SSL3 RSA WITH 3DES EDE CBC SHA\n" + "e SSL3 RSA WITH DES CBC SHA\n" + "f SSL3 RSA EXPORT WITH RC4 40 MD5\n" + "g SSL3 RSA EXPORT WITH RC2 CBC 40 MD5\n" + "i SSL3 RSA WITH NULL MD5\n" + "j SSL3 RSA FIPS WITH 3DES EDE CBC SHA\n" + "k SSL3 RSA FIPS WITH DES CBC SHA\n" + "l SSL3 RSA EXPORT WITH DES CBC SHA\t(new)\n" + "m SSL3 RSA EXPORT WITH RC4 56 SHA\t(new)\n" + "n SSL3 RSA WITH RC4 128 SHA\n" + "o TLS_DHE_DSS_WITH_RC4_128_SHA\n" + "p TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA\n" + "q TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA\n" + "r TLS_DHE_RSA_WITH_DES_CBC_SHA\n" + "s TLS_DHE_DSS_WITH_DES_CBC_SHA\n" + "t TLS_DHE_DSS_WITH_AES_128_CBC_SHA\n" + "u TLS_DHE_RSA_WITH_AES_128_CBC_SHA\n" + "v SSL3 RSA WITH AES 128 CBC SHA\n" + "w TLS_DHE_DSS_WITH_AES_256_CBC_SHA\n" + "x TLS_DHE_RSA_WITH_AES_256_CBC_SHA\n" + "y SSL3 RSA WITH AES 256 CBC SHA\n" + "z SSL3 RSA WITH NULL SHA\n" + "\n" + ":WXYZ Use cipher with hex code { 0xWX , 0xYZ } in TLS\n", + stderr); } static const char * -errWarn(char * funcString) +errWarn(char *funcString) { - PRErrorCode perr = PR_GetError(); - const char * errString = SECU_Strerror(perr); + PRErrorCode perr = PR_GetError(); + const char *errString = SECU_Strerror(perr); fprintf(stderr, "selfserv: %s returned error %d:\n%s\n", funcString, perr, errString); @@ -272,15 +280,14 @@ errWarn(char * funcString) } static void -errExit(char * funcString) +errExit(char *funcString) { errWarn(funcString); exit(3); } - /************************************************************************** -** +** ** Routines for disabling SSL ciphers. ** **************************************************************************/ @@ -290,17 +297,17 @@ void disableAllSSLCiphers(void) { const PRUint16 *cipherSuites = SSL_ImplementedCiphers; - int i = SSL_NumImplementedCiphers; - SECStatus rv; + int i = SSL_NumImplementedCiphers; + SECStatus rv; while (--i >= 0) { - PRUint16 suite = cipherSuites[i]; + PRUint16 suite = cipherSuites[i]; rv = SSL_CipherPrefSetDefault(suite, PR_FALSE); - if (rv != SECSuccess) { - printf("SSL_CipherPrefSetDefault rejected suite 0x%04x (i = %d)\n", - suite, i); - errWarn("SSL_CipherPrefSetDefault"); - } + if (rv != SECSuccess) { + printf("SSL_CipherPrefSetDefault rejected suite 0x%04x (i = %d)\n", + suite, i); + errWarn("SSL_CipherPrefSetDefault"); + } } } @@ -309,52 +316,52 @@ SECStatus disableExportSSLCiphers(void) { const PRUint16 *cipherSuites = SSL_ImplementedCiphers; - int i = SSL_NumImplementedCiphers; - SECStatus rv = SECSuccess; + int i = SSL_NumImplementedCiphers; + SECStatus rv = SECSuccess; SSLCipherSuiteInfo info; while (--i >= 0) { - PRUint16 suite = cipherSuites[i]; - SECStatus status; - status = SSL_GetCipherSuiteInfo(suite, &info, sizeof info); - if (status != SECSuccess) { - printf("SSL_GetCipherSuiteInfo rejected suite 0x%04x (i = %d)\n", - suite, i); - errWarn("SSL_GetCipherSuiteInfo"); - rv = SECFailure; - continue; - } - if (info.cipherSuite != suite) { - printf( -"SSL_GetCipherSuiteInfo returned wrong suite! Wanted 0x%04x, Got 0x%04x\n", - suite, i); - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - rv = SECFailure; - continue; - } - /* should check here that info.length >= offsetof isExportable */ - if (info.isExportable) { - status = SSL_CipherPolicySet(suite, SSL_NOT_ALLOWED); - if (status != SECSuccess) { - printf("SSL_CipherPolicySet rejected suite 0x%04x (i = %d)\n", - suite, i); - errWarn("SSL_CipherPolicySet"); - rv = SECFailure; - } - } + PRUint16 suite = cipherSuites[i]; + SECStatus status; + status = SSL_GetCipherSuiteInfo(suite, &info, sizeof info); + if (status != SECSuccess) { + printf("SSL_GetCipherSuiteInfo rejected suite 0x%04x (i = %d)\n", + suite, i); + errWarn("SSL_GetCipherSuiteInfo"); + rv = SECFailure; + continue; + } + if (info.cipherSuite != suite) { + printf( + "SSL_GetCipherSuiteInfo returned wrong suite! Wanted 0x%04x, Got 0x%04x\n", + suite, i); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + rv = SECFailure; + continue; + } + /* should check here that info.length >= offsetof isExportable */ + if (info.isExportable) { + status = SSL_CipherPolicySet(suite, SSL_NOT_ALLOWED); + if (status != SECSuccess) { + printf("SSL_CipherPolicySet rejected suite 0x%04x (i = %d)\n", + suite, i); + errWarn("SSL_CipherPolicySet"); + rv = SECFailure; + } + } } return rv; } static SECStatus mySSLAuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, - PRBool isServer) + PRBool isServer) { SECStatus rv; - CERTCertificate * peerCert; + CERTCertificate *peerCert; peerCert = SSL_PeerCertificate(fd); - + if (peerCert) { PRINTF("selfserv: Subject: %s\nselfserv: Issuer : %s\n", peerCert->subjectName, peerCert->issuerName); @@ -364,63 +371,63 @@ mySSLAuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, rv = SSL_AuthCertificate(arg, fd, checkSig, isServer); if (rv == SECSuccess) { - PRINTF("selfserv: -- SSL3: Certificate Validated.\n"); + PRINTF("selfserv: -- SSL3: Certificate Validated.\n"); } else { - int err = PR_GetError(); - FPRINTF(stderr, "selfserv: -- SSL3: Certificate Invalid, err %d.\n%s\n", + int err = PR_GetError(); + FPRINTF(stderr, "selfserv: -- SSL3: Certificate Invalid, err %d.\n%s\n", err, SECU_Strerror(err)); } FLUSH; - return rv; + return rv; } void printSSLStatistics() { - SSL3Statistics * ssl3stats = SSL_GetStatistics(); + SSL3Statistics *ssl3stats = SSL_GetStatistics(); printf( - "selfserv: %ld cache hits; %ld cache misses, %ld cache not reusable\n" - " %ld stateless resumes, %ld ticket parse failures\n", - ssl3stats->hch_sid_cache_hits, ssl3stats->hch_sid_cache_misses, - ssl3stats->hch_sid_cache_not_ok, ssl3stats->hch_sid_stateless_resumes, - ssl3stats->hch_sid_ticket_parse_failures); + "selfserv: %ld cache hits; %ld cache misses, %ld cache not reusable\n" + " %ld stateless resumes, %ld ticket parse failures\n", + ssl3stats->hch_sid_cache_hits, ssl3stats->hch_sid_cache_misses, + ssl3stats->hch_sid_cache_not_ok, ssl3stats->hch_sid_stateless_resumes, + ssl3stats->hch_sid_ticket_parse_failures); } -void +void printSecurityInfo(PRFileDesc *fd) { - CERTCertificate * cert = NULL; - SECStatus result; - SSLChannelInfo channel; + CERTCertificate *cert = NULL; + SECStatus result; + SSLChannelInfo channel; SSLCipherSuiteInfo suite; if (verbose) - printSSLStatistics(); + printSSLStatistics(); result = SSL_GetChannelInfo(fd, &channel, sizeof channel); - if (result == SECSuccess && - channel.length == sizeof channel && - channel.cipherSuite) { - result = SSL_GetCipherSuiteInfo(channel.cipherSuite, - &suite, sizeof suite); - if (result == SECSuccess) { - FPRINTF(stderr, - "selfserv: SSL version %d.%d using %d-bit %s with %d-bit %s MAC\n", - channel.protocolVersion >> 8, channel.protocolVersion & 0xff, - suite.effectiveKeyBits, suite.symCipherName, - suite.macBits, suite.macAlgorithmName); - FPRINTF(stderr, - "selfserv: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n" - " Compression: %s, Extended Master Secret: %s\n", - channel.authKeyBits, suite.authAlgorithmName, - channel.keaKeyBits, suite.keaTypeName, - channel.compressionMethodName, - channel.extendedMasterSecretUsed ? "Yes": "No"); - } + if (result == SECSuccess && + channel.length == sizeof channel && + channel.cipherSuite) { + result = SSL_GetCipherSuiteInfo(channel.cipherSuite, + &suite, sizeof suite); + if (result == SECSuccess) { + FPRINTF(stderr, + "selfserv: SSL version %d.%d using %d-bit %s with %d-bit %s MAC\n", + channel.protocolVersion >> 8, channel.protocolVersion & 0xff, + suite.effectiveKeyBits, suite.symCipherName, + suite.macBits, suite.macAlgorithmName); + FPRINTF(stderr, + "selfserv: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n" + " Compression: %s, Extended Master Secret: %s\n", + channel.authKeyBits, suite.authAlgorithmName, + channel.keaKeyBits, suite.keaTypeName, + channel.compressionMethodName, + channel.extendedMasterSecretUsed ? "Yes" : "No"); + } } if (verbose) { - SECItem *hostInfo = SSL_GetNegotiatedHostInfo(fd); + SECItem *hostInfo = SSL_GetNegotiatedHostInfo(fd); if (hostInfo) { char namePref[] = "selfserv: Negotiated server name: "; @@ -432,22 +439,22 @@ printSecurityInfo(PRFileDesc *fd) } } if (requestCert) - cert = SSL_PeerCertificate(fd); + cert = SSL_PeerCertificate(fd); else - cert = SSL_LocalCertificate(fd); + cert = SSL_LocalCertificate(fd); if (cert) { - char * ip = CERT_NameToAscii(&cert->issuer); - char * sp = CERT_NameToAscii(&cert->subject); + char *ip = CERT_NameToAscii(&cert->issuer); + char *sp = CERT_NameToAscii(&cert->subject); if (sp) { - FPRINTF(stderr, "selfserv: subject DN: %s\n", sp); - PORT_Free(sp); - } + FPRINTF(stderr, "selfserv: subject DN: %s\n", sp); + PORT_Free(sp); + } if (ip) { - FPRINTF(stderr, "selfserv: issuer DN: %s\n", ip); - PORT_Free(ip); - } - CERT_DestroyCertificate(cert); - cert = NULL; + FPRINTF(stderr, "selfserv: issuer DN: %s\n", ip); + PORT_Free(ip); + } + CERT_DestroyCertificate(cert); + cert = NULL; } FLUSH; } @@ -455,41 +462,41 @@ printSecurityInfo(PRFileDesc *fd) static int MakeCertOK; static SECStatus -myBadCertHandler( void *arg, PRFileDesc *fd) +myBadCertHandler(void *arg, PRFileDesc *fd) { int err = PR_GetError(); if (!MakeCertOK) - fprintf(stderr, - "selfserv: -- SSL: Client Certificate Invalid, err %d.\n%s\n", - err, SECU_Strerror(err)); + fprintf(stderr, + "selfserv: -- SSL: Client Certificate Invalid, err %d.\n%s\n", + err, SECU_Strerror(err)); return (MakeCertOK ? SECSuccess : SECFailure); } -#define MAX_VIRT_SERVER_NAME_ARRAY_INDEX 10 +#define MAX_VIRT_SERVER_NAME_ARRAY_INDEX 10 /* Simple SNI socket config function that does not use SSL_ReconfigFD. * Only uses one server name but verifies that the names match. */ -PRInt32 +PRInt32 mySSLSNISocketConfig(PRFileDesc *fd, const SECItem *sniNameArr, PRUint32 sniNameArrSize, void *arg) { - PRInt32 i = 0; + PRInt32 i = 0; const SECItem *current = sniNameArr; - const char **nameArr = (const char**)arg; + const char **nameArr = (const char **)arg; secuPWData *pwdata; - CERTCertificate * cert = NULL; - SECKEYPrivateKey * privKey = NULL; + CERTCertificate *cert = NULL; + SECKEYPrivateKey *privKey = NULL; PORT_Assert(fd && sniNameArr); if (!fd || !sniNameArr) { - return SSL_SNI_SEND_ALERT; + return SSL_SNI_SEND_ALERT; } pwdata = SSL_RevealPinArg(fd); - for (;current && (PRUint32)i < sniNameArrSize;i++) { + for (; current && (PRUint32)i < sniNameArrSize; i++) { unsigned int j = 0; - for (;j < MAX_VIRT_SERVER_NAME_ARRAY_INDEX && nameArr[j];j++) { + for (; j < MAX_VIRT_SERVER_NAME_ARRAY_INDEX && nameArr[j]; j++) { if (!PORT_Strncmp(nameArr[j], (const char *)current[i].data, current[i].len) && @@ -529,7 +536,6 @@ loser: return SSL_SNI_SEND_ALERT; } - /************************************************************************** ** Begin thread management routines and data. **************************************************************************/ @@ -537,24 +543,23 @@ loser: #define DEFAULT_THREADS 8 #define MAX_THREADS 4096 #define MAX_PROCS 25 -static int maxThreads = DEFAULT_THREADS; - +static int maxThreads = DEFAULT_THREADS; typedef struct jobStr { - PRCList link; + PRCList link; PRFileDesc *tcp_sock; PRFileDesc *model_sock; - int requestCert; + int requestCert; } JOB; -static PZLock * qLock; /* this lock protects all data immediately below */ -static PRLock * lastLoadedCrlLock; /* this lock protects lastLoadedCrl variable */ -static PZCondVar * jobQNotEmptyCv; -static PZCondVar * freeListNotEmptyCv; -static PZCondVar * threadCountChangeCv; -static int threadCount; -static PRCList jobQ; -static PRCList freeJobs; +static PZLock *qLock; /* this lock protects all data immediately below */ +static PRLock *lastLoadedCrlLock; /* this lock protects lastLoadedCrl variable */ +static PZCondVar *jobQNotEmptyCv; +static PZCondVar *freeListNotEmptyCv; +static PZCondVar *threadCountChangeCv; +static int threadCount; +static PRCList jobQ; +static PRCList freeJobs; static JOB *jobTable; SECStatus @@ -564,40 +569,42 @@ setupJobs(int maxJobs) jobTable = (JOB *)PR_Calloc(maxJobs, sizeof(JOB)); if (!jobTable) - return SECFailure; + return SECFailure; PR_INIT_CLIST(&jobQ); PR_INIT_CLIST(&freeJobs); for (i = 0; i < maxJobs; ++i) { - JOB * pJob = jobTable + i; - PR_APPEND_LINK(&pJob->link, &freeJobs); + JOB *pJob = jobTable + i; + PR_APPEND_LINK(&pJob->link, &freeJobs); } return SECSuccess; } typedef int startFn(PRFileDesc *a, PRFileDesc *b, int c); -typedef enum { rs_idle = 0, rs_running = 1, rs_zombie = 2 } runState; +typedef enum { rs_idle = 0, + rs_running = 1, + rs_zombie = 2 } runState; typedef struct perThreadStr { PRFileDesc *a; PRFileDesc *b; - int c; - int rv; - startFn * startFunc; - PRThread * prThread; - runState state; + int c; + int rv; + startFn *startFunc; + PRThread *prThread; + runState state; } perThread; static perThread *threads; void -thread_wrapper(void * arg) +thread_wrapper(void *arg) { - perThread * slot = (perThread *)arg; + perThread *slot = (perThread *)arg; - slot->rv = (* slot->startFunc)(slot->a, slot->b, slot->c); + slot->rv = (*slot->startFunc)(slot->a, slot->b, slot->c); /* notify the thread exit handler. */ PZ_Lock(qLock); @@ -607,103 +614,110 @@ thread_wrapper(void * arg) PZ_Unlock(qLock); } -int +int jobLoop(PRFileDesc *a, PRFileDesc *b, int c) { - PRCList * myLink = 0; - JOB * myJob; + PRCList *myLink = 0; + JOB *myJob; PZ_Lock(qLock); do { - myLink = 0; - while (PR_CLIST_IS_EMPTY(&jobQ) && !stopping) { + myLink = 0; + while (PR_CLIST_IS_EMPTY(&jobQ) && !stopping) { PZ_WaitCondVar(jobQNotEmptyCv, PR_INTERVAL_NO_TIMEOUT); - } - if (!PR_CLIST_IS_EMPTY(&jobQ)) { - myLink = PR_LIST_HEAD(&jobQ); - PR_REMOVE_AND_INIT_LINK(myLink); - } - PZ_Unlock(qLock); - myJob = (JOB *)myLink; - /* myJob will be null when stopping is true and jobQ is empty */ - if (!myJob) - break; - handle_connection( myJob->tcp_sock, myJob->model_sock, - myJob->requestCert); - PZ_Lock(qLock); - PR_APPEND_LINK(myLink, &freeJobs); - PZ_NotifyCondVar(freeListNotEmptyCv); + } + if (!PR_CLIST_IS_EMPTY(&jobQ)) { + myLink = PR_LIST_HEAD(&jobQ); + PR_REMOVE_AND_INIT_LINK(myLink); + } + PZ_Unlock(qLock); + myJob = (JOB *)myLink; + /* myJob will be null when stopping is true and jobQ is empty */ + if (!myJob) + break; + handle_connection(myJob->tcp_sock, myJob->model_sock, + myJob->requestCert); + PZ_Lock(qLock); + PR_APPEND_LINK(myLink, &freeJobs); + PZ_NotifyCondVar(freeListNotEmptyCv); } while (PR_TRUE); return 0; } - SECStatus launch_threads( - startFn *startFunc, + startFn *startFunc, PRFileDesc *a, PRFileDesc *b, - int c, - PRBool local) + int c, + PRBool local) { int i; SECStatus rv = SECSuccess; /* create the thread management serialization structs */ - qLock = PZ_NewLock(nssILockSelfServ); - jobQNotEmptyCv = PZ_NewCondVar(qLock); - freeListNotEmptyCv = PZ_NewCondVar(qLock); + qLock = PZ_NewLock(nssILockSelfServ); + jobQNotEmptyCv = PZ_NewCondVar(qLock); + freeListNotEmptyCv = PZ_NewCondVar(qLock); threadCountChangeCv = PZ_NewCondVar(qLock); /* create monitor for crl reload procedure */ - lastLoadedCrlLock = PR_NewLock(); + lastLoadedCrlLock = PR_NewLock(); /* allocate the array of thread slots */ threads = PR_Calloc(maxThreads, sizeof(perThread)); - if ( NULL == threads ) { + if (NULL == threads) { fprintf(stderr, "Oh Drat! Can't allocate the perThread array\n"); return SECFailure; } - /* 5 is a little extra, intended to keep the jobQ from underflowing. + /* 5 is a little extra, intended to keep the jobQ from underflowing. ** That is, from going empty while not stopping and clients are still ** trying to contact us. */ rv = setupJobs(maxThreads + 5); if (rv != SECSuccess) - return rv; + return rv; PZ_Lock(qLock); for (i = 0; i < maxThreads; ++i) { - perThread * slot = threads + i; - - slot->state = rs_running; - slot->a = a; - slot->b = b; - slot->c = c; - slot->startFunc = startFunc; - slot->prThread = PR_CreateThread(PR_USER_THREAD, - thread_wrapper, slot, PR_PRIORITY_NORMAL, - (PR_TRUE==local)?PR_LOCAL_THREAD:PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, 0); - if (slot->prThread == NULL) { - printf("selfserv: Failed to launch thread!\n"); - slot->state = rs_idle; - rv = SECFailure; - break; - } - - ++threadCount; - } - PZ_Unlock(qLock); + perThread *slot = threads + i; + + slot->state = rs_running; + slot->a = a; + slot->b = b; + slot->c = c; + slot->startFunc = startFunc; + slot->prThread = PR_CreateThread(PR_USER_THREAD, + thread_wrapper, slot, PR_PRIORITY_NORMAL, + (PR_TRUE == + local) + ? PR_LOCAL_THREAD + : PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (slot->prThread == NULL) { + printf("selfserv: Failed to launch thread!\n"); + slot->state = rs_idle; + rv = SECFailure; + break; + } + + ++threadCount; + } + PZ_Unlock(qLock); return rv; } -#define DESTROY_CONDVAR(name) if (name) { \ - PZ_DestroyCondVar(name); name = NULL; } -#define DESTROY_LOCK(name) if (name) { \ - PZ_DestroyLock(name); name = NULL; } - +#define DESTROY_CONDVAR(name) \ + if (name) { \ + PZ_DestroyCondVar(name); \ + name = NULL; \ + } +#define DESTROY_LOCK(name) \ + if (name) { \ + PZ_DestroyLock(name); \ + name = NULL; \ + } void terminateWorkerThreads(void) @@ -712,11 +726,11 @@ terminateWorkerThreads(void) PZ_Lock(qLock); PZ_NotifyAllCondVar(jobQNotEmptyCv); while (threadCount > 0) { - PZ_WaitCondVar(threadCountChangeCv, PR_INTERVAL_NO_TIMEOUT); + PZ_WaitCondVar(threadCountChangeCv, PR_INTERVAL_NO_TIMEOUT); } /* The worker threads empty the jobQ before they terminate. */ PORT_Assert(PR_CLIST_IS_EMPTY(&jobQ)); - PZ_Unlock(qLock); + PZ_Unlock(qLock); DESTROY_CONDVAR(jobQNotEmptyCv); DESTROY_CONDVAR(freeListNotEmptyCv); @@ -728,7 +742,7 @@ terminateWorkerThreads(void) PR_Free(threads); } -static void +static void logger(void *arg) { PRFloat64 seconds; @@ -747,12 +761,12 @@ logger(void *arg) previousOps = loggerOps; previousTime = PR_IntervalNow(); - + for (;;) { - /* OK, implementing a new sleep algorithm here... always sleep + /* OK, implementing a new sleep algorithm here... always sleep * for 1 second but print out info at the user-specified interval. - * This way, we don't overflow all of our PR_Atomic* functions and - * we don't have to use locks. + * This way, we don't overflow all of our PR_Atomic* functions and + * we don't have to use locks. */ PR_Sleep(logPeriodTicks); secondsElapsed++; @@ -762,13 +776,13 @@ logger(void *arg) continue; } /* when we reach the user-specified logging interval, print out all - * data + * data */ secondsElapsed = 0; latestTime = PR_IntervalNow(); ops = loggerOps; period = latestTime - previousTime; - seconds = (PRFloat64) period*secondsPerTick; + seconds = (PRFloat64)period * secondsPerTick; opsPerSec = (ops - previousOps) / seconds; if (testBulk) { @@ -780,17 +794,17 @@ logger(void *arg) } } if (loggingLayer == PR_TRUE) { - printf("%4.d %5.3f MB/s %5.3f MB/s\n", ops, - totalPeriodBytes / (seconds * 1048576.0), - totalPeriodBytesTCP / (seconds * 1048576.0)); + printf("%4.d %5.3f MB/s %5.3f MB/s\n", ops, + totalPeriodBytes / (seconds * 1048576.0), + totalPeriodBytesTCP / (seconds * 1048576.0)); } else { - printf("%4.d %5.3f MB/s\n", ops, - totalPeriodBytes / (seconds * 1048576.0)); + printf("%4.d %5.3f MB/s\n", ops, + totalPeriodBytes / (seconds * 1048576.0)); } totalPeriodBytes = 0; totalPeriodBytesTCP = 0; /* Print the "legend" every 20 iterations */ - iterations = (iterations + 1) % 20; + iterations = (iterations + 1) % 20; } else { printf("%.2f ops/second, %d threads\n", opsPerSec, threadCount); } @@ -804,32 +818,30 @@ logger(void *arg) } } - /************************************************************************** ** End thread management routines. **************************************************************************/ -PRBool useModelSocket = PR_FALSE; +PRBool useModelSocket = PR_FALSE; static SSLVersionRange enabledVersions; PRBool disableRollBack = PR_FALSE; -PRBool NoReuse = PR_FALSE; -PRBool hasSidCache = PR_FALSE; +PRBool NoReuse = PR_FALSE; +PRBool hasSidCache = PR_FALSE; PRBool disableStepDown = PR_FALSE; -PRBool bypassPKCS11 = PR_FALSE; -PRBool disableLocking = PR_FALSE; -PRBool testbypass = PR_FALSE; +PRBool bypassPKCS11 = PR_FALSE; +PRBool disableLocking = PR_FALSE; +PRBool testbypass = PR_FALSE; PRBool enableSessionTickets = PR_FALSE; -PRBool enableCompression = PR_FALSE; -PRBool failedToNegotiateName = PR_FALSE; +PRBool enableCompression = PR_FALSE; +PRBool failedToNegotiateName = PR_FALSE; PRBool enableExtendedMasterSecret = PR_FALSE; -static char *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX]; -static int virtServerNameIndex = 1; - +static char *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX]; +static int virtServerNameIndex = 1; static const char stopCmd[] = { "GET /stop " }; -static const char getCmd[] = { "GET " }; -static const char EOFmsg[] = { "EOF\r\n\r\n\r\n" }; +static const char getCmd[] = { "GET " }; +static const char EOFmsg[] = { "EOF\r\n\r\n\r\n" }; static const char outHeader[] = { "HTTP/1.0 200 OK\r\n" "Server: Generic Web Server\r\n" @@ -837,7 +849,7 @@ static const char outHeader[] = { "Content-type: text/plain\r\n" "\r\n" }; -static const char crlCacheErr[] = { "CRL ReCache Error: " }; +static const char crlCacheErr[] = { "CRL ReCache Error: " }; PRUint16 cipherlist[100]; int nciphers; @@ -845,33 +857,32 @@ int nciphers; void savecipher(int c) { - if (nciphers < sizeof cipherlist / sizeof (cipherlist[0])) - cipherlist[nciphers++] = (PRUint16)c; + if (nciphers < sizeof cipherlist / sizeof(cipherlist[0])) + cipherlist[nciphers++] = (PRUint16)c; } - #ifdef FULL_DUPLEX_CAPABLE struct lockedVarsStr { - PZLock * lock; - int count; - int waiters; - PZCondVar * condVar; + PZLock *lock; + int count; + int waiters; + PZCondVar *condVar; }; typedef struct lockedVarsStr lockedVars; -void -lockedVars_Init( lockedVars * lv) +void +lockedVars_Init(lockedVars *lv) { - lv->count = 0; + lv->count = 0; lv->waiters = 0; - lv->lock = PZ_NewLock(nssILockSelfServ); + lv->lock = PZ_NewLock(nssILockSelfServ); lv->condVar = PZ_NewCondVar(lv->lock); } void -lockedVars_Destroy( lockedVars * lv) +lockedVars_Destroy(lockedVars *lv) { PZ_DestroyCondVar(lv->condVar); lv->condVar = NULL; @@ -881,24 +892,24 @@ lockedVars_Destroy( lockedVars * lv) } void -lockedVars_WaitForDone(lockedVars * lv) +lockedVars_WaitForDone(lockedVars *lv) { PZ_Lock(lv->lock); while (lv->count > 0) { - PZ_WaitCondVar(lv->condVar, PR_INTERVAL_NO_TIMEOUT); + PZ_WaitCondVar(lv->condVar, PR_INTERVAL_NO_TIMEOUT); } PZ_Unlock(lv->lock); } -int /* returns count */ -lockedVars_AddToCount(lockedVars * lv, int addend) +int /* returns count */ + lockedVars_AddToCount(lockedVars *lv, int addend) { int rv; PZ_Lock(lv->lock); rv = lv->count += addend; if (rv <= 0) { - PZ_NotifyCondVar(lv->condVar); + PZ_NotifyCondVar(lv->condVar); } PZ_Unlock(lv->lock); return rv; @@ -906,28 +917,27 @@ lockedVars_AddToCount(lockedVars * lv, int addend) int do_writes( - PRFileDesc * ssl_sock, - PRFileDesc * model_sock, - int requestCert - ) + PRFileDesc *ssl_sock, + PRFileDesc *model_sock, + int requestCert) { - int sent = 0; - int count = 0; - lockedVars * lv = (lockedVars *)model_sock; + int sent = 0; + int count = 0; + lockedVars *lv = (lockedVars *)model_sock; VLOG(("selfserv: do_writes: starting")); while (sent < bigBuf.len) { - count = PR_Write(ssl_sock, bigBuf.data + sent, bigBuf.len - sent); - if (count < 0) { - errWarn("PR_Write bigBuf"); - break; - } - FPRINTF(stderr, "selfserv: PR_Write wrote %d bytes from bigBuf\n", count ); - sent += count; + count = PR_Write(ssl_sock, bigBuf.data + sent, bigBuf.len - sent); + if (count < 0) { + errWarn("PR_Write bigBuf"); + break; + } + FPRINTF(stderr, "selfserv: PR_Write wrote %d bytes from bigBuf\n", count); + sent += count; } - if (count >= 0) { /* last write didn't fail. */ - PR_Shutdown(ssl_sock, PR_SHUTDOWN_SEND); + if (count >= 0) { /* last write didn't fail. */ + PR_Shutdown(ssl_sock, PR_SHUTDOWN_SEND); } /* notify the reader that we're done. */ @@ -937,64 +947,62 @@ do_writes( return (sent < bigBuf.len) ? SECFailure : SECSuccess; } -static int +static int handle_fdx_connection( - PRFileDesc * tcp_sock, - PRFileDesc * model_sock, - int requestCert - ) + PRFileDesc *tcp_sock, + PRFileDesc *model_sock, + int requestCert) { - PRFileDesc * ssl_sock = NULL; - SECStatus result; - int firstTime = 1; - lockedVars lv; + PRFileDesc *ssl_sock = NULL; + SECStatus result; + int firstTime = 1; + lockedVars lv; PRSocketOptionData opt; - char buf[10240]; - + char buf[10240]; VLOG(("selfserv: handle_fdx_connection: starting")); - opt.option = PR_SockOpt_Nonblocking; + opt.option = PR_SockOpt_Nonblocking; opt.value.non_blocking = PR_FALSE; PR_SetSocketOption(tcp_sock, &opt); if (useModelSocket && model_sock) { - SECStatus rv; - ssl_sock = SSL_ImportFD(model_sock, tcp_sock); - if (!ssl_sock) { - errWarn("SSL_ImportFD with model"); - goto cleanup; - } - rv = SSL_ResetHandshake(ssl_sock, /* asServer */ 1); - if (rv != SECSuccess) { - errWarn("SSL_ResetHandshake"); - goto cleanup; - } + SECStatus rv; + ssl_sock = SSL_ImportFD(model_sock, tcp_sock); + if (!ssl_sock) { + errWarn("SSL_ImportFD with model"); + goto cleanup; + } + rv = SSL_ResetHandshake(ssl_sock, /* asServer */ 1); + if (rv != SECSuccess) { + errWarn("SSL_ResetHandshake"); + goto cleanup; + } } else { - ssl_sock = tcp_sock; + ssl_sock = tcp_sock; } lockedVars_Init(&lv); lockedVars_AddToCount(&lv, 1); /* Attempt to launch the writer thread. */ - result = launch_thread(do_writes, ssl_sock, (PRFileDesc *)&lv, + result = launch_thread(do_writes, ssl_sock, (PRFileDesc *)&lv, requestCert); - if (result == SECSuccess) - do { - /* do reads here. */ - int count; - count = PR_Read(ssl_sock, buf, sizeof buf); - if (count < 0) { - errWarn("FDX PR_Read"); - break; - } - FPRINTF(stderr, "selfserv: FDX PR_Read read %d bytes.\n", count ); - if (firstTime) { - firstTime = 0; - printSecurityInfo(ssl_sock); - } - } while (lockedVars_AddToCount(&lv, 0) > 0); + if (result == SECSuccess) + do { + /* do reads here. */ + int count; + count = PR_Read(ssl_sock, buf, sizeof buf); + if (count < 0) { + errWarn("FDX PR_Read"); + break; + } + FPRINTF(stderr, "selfserv: FDX PR_Read read %d bytes.\n", count); + if (firstTime) { + firstTime = 0; + printSecurityInfo(ssl_sock); + } + } while (lockedVars_AddToCount(&lv, 0) > 0); /* Wait for writer to finish */ lockedVars_WaitForDone(&lv); @@ -1003,9 +1011,9 @@ handle_fdx_connection( cleanup: if (ssl_sock) { - PR_Close(ssl_sock); + PR_Close(ssl_sock); } else if (tcp_sock) { - PR_Close(tcp_sock); + PR_Close(tcp_sock); } VLOG(("selfserv: handle_fdx_connection: exiting")); @@ -1054,13 +1062,14 @@ reload_crl(PRFileDesc *crlFile) lastLoadedCrl = tempItem; } - loser: +loser: PR_Unlock(lastLoadedCrlLock); SECITEM_FreeItem(crlDer, PR_TRUE); return rv; } -void stop_server() +void +stop_server() { stopping = 1; PR_Interrupt(acceptorThread); @@ -1074,13 +1083,13 @@ makeTryLaterOCSPResponse(PLArenaPool *arena) SECItem *ocspResponse = NULL; ocspResponse = CERT_CreateEncodedOCSPErrorResponse(arena, - SEC_ERROR_OCSP_TRY_SERVER_LATER); + SEC_ERROR_OCSP_TRY_SERVER_LATER); if (!ocspResponse) - errExit("cannot created ocspResponse"); + errExit("cannot created ocspResponse"); result = SECITEM_AllocArray(arena, NULL, 1); if (!result) - errExit("cannot allocate multiOcspResponses"); + errExit("cannot allocate multiOcspResponses"); result->items[0].data = ocspResponse->data; result->items[0].len = ocspResponse->len; @@ -1096,11 +1105,11 @@ makeCorruptedOCSPResponse(PLArenaPool *arena) ocspResponse = SECITEM_AllocItem(arena, NULL, 1); if (!ocspResponse) - errExit("cannot created ocspResponse"); + errExit("cannot created ocspResponse"); result = SECITEM_AllocArray(arena, NULL, 1); if (!result) - errExit("cannot allocate multiOcspResponses"); + errExit("cannot allocate multiOcspResponses"); result->items[0].data = ocspResponse->data; result->items[0].len = ocspResponse->len; @@ -1110,7 +1119,7 @@ makeCorruptedOCSPResponse(PLArenaPool *arena) SECItemArray * makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm, - CERTCertificate *cert, secuPWData *pwdata) + CERTCertificate *cert, secuPWData *pwdata) { SECItemArray *result = NULL; SECItem *ocspResponse = NULL; @@ -1125,59 +1134,61 @@ makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm, ca = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), ocspStaplingCA); if (!ca) - errExit("cannot find CA"); + errExit("cannot find CA"); cid = CERT_CreateOCSPCertID(cert, now); if (!cid) - errExit("cannot created cid"); + errExit("cannot created cid"); - nextUpdate = now + (PRTime)60*60*24 * PR_USEC_PER_SEC; /* plus 1 day */ + nextUpdate = now + (PRTime)60 * 60 * 24 * PR_USEC_PER_SEC; /* plus 1 day */ switch (osm) { - case osm_good: - case osm_badsig: - sr = CERT_CreateOCSPSingleResponseGood(arena, cid, now, - &nextUpdate); - break; - case osm_unknown: - sr = CERT_CreateOCSPSingleResponseUnknown(arena, cid, now, - &nextUpdate); - break; - case osm_revoked: - sr = CERT_CreateOCSPSingleResponseRevoked(arena, cid, now, - &nextUpdate, - now - (PRTime)60*60*24 * PR_USEC_PER_SEC, /* minus 1 day */ - NULL); - break; - default: - PORT_Assert(0); - break; + case osm_good: + case osm_badsig: + sr = CERT_CreateOCSPSingleResponseGood(arena, cid, now, + &nextUpdate); + break; + case osm_unknown: + sr = CERT_CreateOCSPSingleResponseUnknown(arena, cid, now, + &nextUpdate); + break; + case osm_revoked: + sr = CERT_CreateOCSPSingleResponseRevoked(arena, cid, now, + &nextUpdate, + now - (PRTime)60 * 60 * 24 * PR_USEC_PER_SEC, /* minus 1 day */ + NULL); + break; + default: + PORT_Assert(0); + break; } if (!sr) - errExit("cannot create sr"); + errExit("cannot create sr"); /* meaning of value 2: one entry + one end marker */ - singleResponses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse*, 2); + singleResponses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse *, 2); if (singleResponses == NULL) - errExit("cannot allocate singleResponses"); + errExit("cannot allocate singleResponses"); singleResponses[0] = sr; singleResponses[1] = NULL; ocspResponse = CERT_CreateEncodedOCSPSuccessResponse(arena, - (osm == osm_badsig) ? NULL : ca, - ocspResponderID_byName, now, singleResponses, - &pwdata); + (osm == osm_badsig) + ? NULL + : ca, + ocspResponderID_byName, now, singleResponses, + &pwdata); if (!ocspResponse) - errExit("cannot created ocspResponse"); + errExit("cannot created ocspResponse"); CERT_DestroyCertificate(ca); ca = NULL; result = SECITEM_AllocArray(arena, NULL, 1); if (!result) - errExit("cannot allocate multiOcspResponses"); + errExit("cannot allocate multiOcspResponses"); result->items[0].data = ocspResponse->data; result->items[0].len = ocspResponse->len; @@ -1190,109 +1201,122 @@ makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm, void setupCertStatus(PLArenaPool *arena, enum ocspStaplingModeEnum ocspStaplingMode, - CERTCertificate *cert, SSLKEAType kea, secuPWData *pwdata) + CERTCertificate *cert, SSLKEAType kea, secuPWData *pwdata) { if (ocspStaplingMode == osm_random) { - /* 6 different responses */ - int r = rand() % 6; - switch (r) { - case 0: ocspStaplingMode = osm_good; break; - case 1: ocspStaplingMode = osm_revoked; break; - case 2: ocspStaplingMode = osm_unknown; break; - case 3: ocspStaplingMode = osm_badsig; break; - case 4: ocspStaplingMode = osm_corrupted; break; - case 5: ocspStaplingMode = osm_failure; break; - default: PORT_Assert(0); break; - } + /* 6 different responses */ + int r = rand() % 6; + switch (r) { + case 0: + ocspStaplingMode = osm_good; + break; + case 1: + ocspStaplingMode = osm_revoked; + break; + case 2: + ocspStaplingMode = osm_unknown; + break; + case 3: + ocspStaplingMode = osm_badsig; + break; + case 4: + ocspStaplingMode = osm_corrupted; + break; + case 5: + ocspStaplingMode = osm_failure; + break; + default: + PORT_Assert(0); + break; + } } if (ocspStaplingMode != osm_disabled) { - SECItemArray *multiOcspResponses = NULL; - switch (ocspStaplingMode) { - case osm_good: - case osm_revoked: - case osm_unknown: - case osm_badsig: - multiOcspResponses = - makeSignedOCSPResponse(arena, ocspStaplingMode, cert, - pwdata); - break; - case osm_corrupted: - multiOcspResponses = makeCorruptedOCSPResponse(arena); - break; - case osm_failure: - multiOcspResponses = makeTryLaterOCSPResponse(arena); - break; - case osm_ocsp: - errExit("stapling mode \"ocsp\" not implemented"); - break; - break; - default: - break; - } - if (multiOcspResponses) { - certStatus[kea] = multiOcspResponses; - } - } + SECItemArray *multiOcspResponses = NULL; + switch (ocspStaplingMode) { + case osm_good: + case osm_revoked: + case osm_unknown: + case osm_badsig: + multiOcspResponses = + makeSignedOCSPResponse(arena, ocspStaplingMode, cert, + pwdata); + break; + case osm_corrupted: + multiOcspResponses = makeCorruptedOCSPResponse(arena); + break; + case osm_failure: + multiOcspResponses = makeTryLaterOCSPResponse(arena); + break; + case osm_ocsp: + errExit("stapling mode \"ocsp\" not implemented"); + break; + break; + default: + break; + } + if (multiOcspResponses) { + certStatus[kea] = multiOcspResponses; + } + } } int -handle_connection( +handle_connection( PRFileDesc *tcp_sock, PRFileDesc *model_sock, - int requestCert - ) + int requestCert) { - PRFileDesc * ssl_sock = NULL; - PRFileDesc * local_file_fd = NULL; - char * post; - char * pBuf; /* unused space at end of buf */ - const char * errString; - PRStatus status; - int bufRem; /* unused bytes at end of buf */ - int bufDat; /* characters received in buf */ - int newln = 0; /* # of consecutive newlns */ - int firstTime = 1; - int reqLen; - int rv; - int numIOVs; + PRFileDesc *ssl_sock = NULL; + PRFileDesc *local_file_fd = NULL; + char *post; + char *pBuf; /* unused space at end of buf */ + const char *errString; + PRStatus status; + int bufRem; /* unused bytes at end of buf */ + int bufDat; /* characters received in buf */ + int newln = 0; /* # of consecutive newlns */ + int firstTime = 1; + int reqLen; + int rv; + int numIOVs; PRSocketOptionData opt; - PRIOVec iovs[16]; - char msgBuf[160]; - char buf[10240]; - char fileName[513]; - char proto[128]; - PRDescIdentity aboveLayer = PR_INVALID_IO_LAYER; - SSLKEAType kea; - - pBuf = buf; + PRIOVec iovs[16]; + char msgBuf[160]; + char buf[10240]; + char fileName[513]; + char proto[128]; + PRDescIdentity aboveLayer = PR_INVALID_IO_LAYER; + SSLKEAType kea; + + pBuf = buf; bufRem = sizeof buf; VLOG(("selfserv: handle_connection: starting")); - opt.option = PR_SockOpt_Nonblocking; + opt.option = PR_SockOpt_Nonblocking; opt.value.non_blocking = PR_FALSE; PR_SetSocketOption(tcp_sock, &opt); VLOG(("selfserv: handle_connection: starting\n")); if (useModelSocket && model_sock) { - SECStatus rv; - ssl_sock = SSL_ImportFD(model_sock, tcp_sock); - if (!ssl_sock) { - errWarn("SSL_ImportFD with model"); - goto cleanup; - } - rv = SSL_ResetHandshake(ssl_sock, /* asServer */ 1); - if (rv != SECSuccess) { - errWarn("SSL_ResetHandshake"); - goto cleanup; - } + SECStatus rv; + ssl_sock = SSL_ImportFD(model_sock, tcp_sock); + if (!ssl_sock) { + errWarn("SSL_ImportFD with model"); + goto cleanup; + } + rv = SSL_ResetHandshake(ssl_sock, /* asServer */ 1); + if (rv != SECSuccess) { + errWarn("SSL_ResetHandshake"); + goto cleanup; + } } else { - ssl_sock = tcp_sock; + ssl_sock = tcp_sock; } for (kea = kt_rsa; kea < kt_kea_size; kea++) { - if (certStatus[kea] != NULL) { - SSL_SetStapledOCSPResponses(ssl_sock, certStatus[kea], kea); - } + if (certStatus[kea] != NULL) { + SSL_SetStapledOCSPResponses(ssl_sock, certStatus[kea], kea); + } } if (loggingLayer) { @@ -1313,254 +1337,255 @@ handle_connection( } if (noDelay) { - opt.option = PR_SockOpt_NoDelay; - opt.value.no_delay = PR_TRUE; - status = PR_SetSocketOption(ssl_sock, &opt); - if (status != PR_SUCCESS) { - errWarn("PR_SetSocketOption(PR_SockOpt_NoDelay, PR_TRUE)"); + opt.option = PR_SockOpt_NoDelay; + opt.value.no_delay = PR_TRUE; + status = PR_SetSocketOption(ssl_sock, &opt); + if (status != PR_SUCCESS) { + errWarn("PR_SetSocketOption(PR_SockOpt_NoDelay, PR_TRUE)"); if (ssl_sock) { - PR_Close(ssl_sock); + PR_Close(ssl_sock); } - return SECFailure; - } + return SECFailure; + } } while (1) { - newln = 0; - reqLen = 0; - rv = PR_Read(ssl_sock, pBuf, bufRem - 1); - if (rv == 0 || - (rv < 0 && PR_END_OF_FILE_ERROR == PR_GetError())) { - if (verbose) - errWarn("HDX PR_Read hit EOF"); - break; - } - if (rv < 0) { - errWarn("HDX PR_Read"); - goto cleanup; - } - /* NULL termination */ - pBuf[rv] = 0; - if (firstTime) { - firstTime = 0; - printSecurityInfo(ssl_sock); - } - - pBuf += rv; - bufRem -= rv; - bufDat = pBuf - buf; - /* Parse the input, starting at the beginning of the buffer. - * Stop when we detect two consecutive \n's (or \r\n's) - * as this signifies the end of the GET or POST portion. - * The posted data follows. - */ - while (reqLen < bufDat && newln < 2) { - int octet = buf[reqLen++]; - if (octet == '\n') { - newln++; - } else if (octet != '\r') { - newln = 0; - } - } - - /* came to the end of the buffer, or second newln - * If we didn't get an empty line (CRLFCRLF) then keep on reading. - */ - if (newln < 2) - continue; - - /* we're at the end of the HTTP request. - * If the request is a POST, then there will be one more - * line of data. - * This parsing is a hack, but ok for SSL test purposes. - */ - post = PORT_Strstr(buf, "POST "); - if (!post || *post != 'P') - break; - - /* It's a post, so look for the next and final CR/LF. */ - /* We should parse content length here, but ... */ - while (reqLen < bufDat && newln < 3) { - int octet = buf[reqLen++]; - if (octet == '\n') { - newln++; - } - } - if (newln == 3) - break; + newln = 0; + reqLen = 0; + rv = PR_Read(ssl_sock, pBuf, bufRem - 1); + if (rv == 0 || + (rv < 0 && PR_END_OF_FILE_ERROR == PR_GetError())) { + if (verbose) + errWarn("HDX PR_Read hit EOF"); + break; + } + if (rv < 0) { + errWarn("HDX PR_Read"); + goto cleanup; + } + /* NULL termination */ + pBuf[rv] = 0; + if (firstTime) { + firstTime = 0; + printSecurityInfo(ssl_sock); + } + + pBuf += rv; + bufRem -= rv; + bufDat = pBuf - buf; + /* Parse the input, starting at the beginning of the buffer. + * Stop when we detect two consecutive \n's (or \r\n's) + * as this signifies the end of the GET or POST portion. + * The posted data follows. + */ + while (reqLen < bufDat && newln < 2) { + int octet = buf[reqLen++]; + if (octet == '\n') { + newln++; + } else if (octet != '\r') { + newln = 0; + } + } + + /* came to the end of the buffer, or second newln + * If we didn't get an empty line (CRLFCRLF) then keep on reading. + */ + if (newln < 2) + continue; + + /* we're at the end of the HTTP request. + * If the request is a POST, then there will be one more + * line of data. + * This parsing is a hack, but ok for SSL test purposes. + */ + post = PORT_Strstr(buf, "POST "); + if (!post || *post != 'P') + break; + + /* It's a post, so look for the next and final CR/LF. */ + /* We should parse content length here, but ... */ + while (reqLen < bufDat && newln < 3) { + int octet = buf[reqLen++]; + if (octet == '\n') { + newln++; + } + } + if (newln == 3) + break; } /* read loop */ bufDat = pBuf - buf; - if (bufDat) do { /* just close if no data */ - /* Have either (a) a complete get, (b) a complete post, (c) EOF */ - if (reqLen > 0 && !strncmp(buf, getCmd, sizeof getCmd - 1)) { - char * fnBegin = buf + 4; - char * fnEnd; - PRFileInfo info; - /* try to open the file named. - * If successful, then write it to the client. - */ - fnEnd = strpbrk(fnBegin, " \r\n"); - if (fnEnd) { - int fnLen = fnEnd - fnBegin; - if (fnLen < sizeof fileName) { - char *real_fileName = fileName; - char *protoEnd = NULL; - strncpy(fileName, fnBegin, fnLen); - fileName[fnLen] = 0; /* null terminate */ - if ((protoEnd = strstr(fileName, "://")) != NULL) { - int protoLen = PR_MIN(protoEnd - fileName, sizeof(proto) - 1); - PL_strncpy(proto, fileName, protoLen); - proto[protoLen] = 0; - real_fileName= protoEnd + 3; - } else { - proto[0] = 0; + if (bufDat) + do { /* just close if no data */ + /* Have either (a) a complete get, (b) a complete post, (c) EOF */ + if (reqLen > 0 && !strncmp(buf, getCmd, sizeof getCmd - 1)) { + char *fnBegin = buf + 4; + char *fnEnd; + PRFileInfo info; + /* try to open the file named. + * If successful, then write it to the client. + */ + fnEnd = strpbrk(fnBegin, " \r\n"); + if (fnEnd) { + int fnLen = fnEnd - fnBegin; + if (fnLen < sizeof fileName) { + char *real_fileName = fileName; + char *protoEnd = NULL; + strncpy(fileName, fnBegin, fnLen); + fileName[fnLen] = 0; /* null terminate */ + if ((protoEnd = strstr(fileName, "://")) != NULL) { + int protoLen = PR_MIN(protoEnd - fileName, sizeof(proto) - 1); + PL_strncpy(proto, fileName, protoLen); + proto[protoLen] = 0; + real_fileName = protoEnd + 3; + } else { + proto[0] = 0; + } + status = PR_GetFileInfo(real_fileName, &info); + if (status == PR_SUCCESS && + info.type == PR_FILE_FILE && + info.size >= 0) { + local_file_fd = PR_Open(real_fileName, PR_RDONLY, 0); + } } - status = PR_GetFileInfo(real_fileName, &info); - if (status == PR_SUCCESS && - info.type == PR_FILE_FILE && - info.size >= 0 ) { - local_file_fd = PR_Open(real_fileName, PR_RDONLY, 0); - } - } - } - } - /* if user has requested client auth in a subsequent handshake, - * do it here. - */ - if (requestCert > 2) { /* request cert was 3 or 4 */ - CERTCertificate * cert = SSL_PeerCertificate(ssl_sock); - if (cert) { - CERT_DestroyCertificate(cert); - } else { - rv = SSL_OptionSet(ssl_sock, SSL_REQUEST_CERTIFICATE, 1); - if (rv < 0) { - errWarn("second SSL_OptionSet SSL_REQUEST_CERTIFICATE"); - break; - } - rv = SSL_OptionSet(ssl_sock, SSL_REQUIRE_CERTIFICATE, - (requestCert == 4)); - if (rv < 0) { - errWarn("second SSL_OptionSet SSL_REQUIRE_CERTIFICATE"); - break; - } - rv = SSL_ReHandshake(ssl_sock, PR_TRUE); - if (rv != 0) { - errWarn("SSL_ReHandshake"); - break; - } - rv = SSL_ForceHandshake(ssl_sock); - if (rv < 0) { - errWarn("SSL_ForceHandshake"); - break; - } - } - } - - numIOVs = 0; - - iovs[numIOVs].iov_base = (char *)outHeader; - iovs[numIOVs].iov_len = (sizeof(outHeader)) - 1; - numIOVs++; - - if (local_file_fd) { - PRInt32 bytes; - int errLen; - if (!PL_strlen(proto) || !PL_strcmp(proto, "file")) { - bytes = PR_TransmitFile(ssl_sock, local_file_fd, outHeader, - sizeof outHeader - 1, - PR_TRANSMITFILE_KEEP_OPEN, - PR_INTERVAL_NO_TIMEOUT); - if (bytes >= 0) { - bytes -= sizeof outHeader - 1; - FPRINTF(stderr, - "selfserv: PR_TransmitFile wrote %d bytes from %s\n", - bytes, fileName); - break; } - errString = errWarn("PR_TransmitFile"); - errLen = PORT_Strlen(errString); - errLen = PR_MIN(errLen, sizeof msgBuf - 1); - PORT_Memcpy(msgBuf, errString, errLen); - msgBuf[errLen] = 0; - - iovs[numIOVs].iov_base = msgBuf; - iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); - numIOVs++; } - if (!PL_strcmp(proto, "crl")) { - if (reload_crl(local_file_fd) == SECFailure) { - errString = errWarn("CERT_CacheCRL"); - if (!errString) - errString = "Unknow error"; - PR_snprintf(msgBuf, sizeof(msgBuf), "%s%s ", - crlCacheErr, errString); - - iovs[numIOVs].iov_base = msgBuf; - iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); - numIOVs++; + /* if user has requested client auth in a subsequent handshake, + * do it here. + */ + if (requestCert > 2) { /* request cert was 3 or 4 */ + CERTCertificate *cert = SSL_PeerCertificate(ssl_sock); + if (cert) { + CERT_DestroyCertificate(cert); } else { - FPRINTF(stderr, - "selfserv: CRL %s reloaded.\n", - fileName); - break; + rv = SSL_OptionSet(ssl_sock, SSL_REQUEST_CERTIFICATE, 1); + if (rv < 0) { + errWarn("second SSL_OptionSet SSL_REQUEST_CERTIFICATE"); + break; + } + rv = SSL_OptionSet(ssl_sock, SSL_REQUIRE_CERTIFICATE, + (requestCert == 4)); + if (rv < 0) { + errWarn("second SSL_OptionSet SSL_REQUIRE_CERTIFICATE"); + break; + } + rv = SSL_ReHandshake(ssl_sock, PR_TRUE); + if (rv != 0) { + errWarn("SSL_ReHandshake"); + break; + } + rv = SSL_ForceHandshake(ssl_sock); + if (rv < 0) { + errWarn("SSL_ForceHandshake"); + break; + } } } - } else if (reqLen <= 0) { /* hit eof */ - PORT_Sprintf(msgBuf, "Get or Post incomplete after %d bytes.\r\n", - bufDat); - - iovs[numIOVs].iov_base = msgBuf; - iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); - numIOVs++; - } else if (reqLen < bufDat) { - PORT_Sprintf(msgBuf, "Discarded %d characters.\r\n", - bufDat - reqLen); - - iovs[numIOVs].iov_base = msgBuf; - iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); - numIOVs++; - } - - if (reqLen > 0) { - if (verbose > 1) - fwrite(buf, 1, reqLen, stdout); /* display it */ - - iovs[numIOVs].iov_base = buf; - iovs[numIOVs].iov_len = reqLen; - numIOVs++; - } - - /* Don't add the EOF if we want to test bulk encryption */ - if (!testBulk) { - iovs[numIOVs].iov_base = (char *)EOFmsg; - iovs[numIOVs].iov_len = sizeof EOFmsg - 1; + + numIOVs = 0; + + iovs[numIOVs].iov_base = (char *)outHeader; + iovs[numIOVs].iov_len = (sizeof(outHeader)) - 1; numIOVs++; - } - rv = PR_Writev(ssl_sock, iovs, numIOVs, PR_INTERVAL_NO_TIMEOUT); - if (rv < 0) { - errWarn("PR_Writev"); - break; - } + if (local_file_fd) { + PRInt32 bytes; + int errLen; + if (!PL_strlen(proto) || !PL_strcmp(proto, "file")) { + bytes = PR_TransmitFile(ssl_sock, local_file_fd, outHeader, + sizeof outHeader - 1, + PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + if (bytes >= 0) { + bytes -= sizeof outHeader - 1; + FPRINTF(stderr, + "selfserv: PR_TransmitFile wrote %d bytes from %s\n", + bytes, fileName); + break; + } + errString = errWarn("PR_TransmitFile"); + errLen = PORT_Strlen(errString); + errLen = PR_MIN(errLen, sizeof msgBuf - 1); + PORT_Memcpy(msgBuf, errString, errLen); + msgBuf[errLen] = 0; - /* Send testBulkTotal chunks to the client. Unlimited if 0. */ - if (testBulk) { - while (0 < (rv = PR_Write(ssl_sock, testBulkBuf, testBulkSize))) { - PR_ATOMIC_ADD(&loggerBytes, rv); - PR_ATOMIC_INCREMENT(&bulkSentChunks); - if ((bulkSentChunks > testBulkTotal) && (testBulkTotal != 0)) - break; + iovs[numIOVs].iov_base = msgBuf; + iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); + numIOVs++; + } + if (!PL_strcmp(proto, "crl")) { + if (reload_crl(local_file_fd) == SECFailure) { + errString = errWarn("CERT_CacheCRL"); + if (!errString) + errString = "Unknow error"; + PR_snprintf(msgBuf, sizeof(msgBuf), "%s%s ", + crlCacheErr, errString); + + iovs[numIOVs].iov_base = msgBuf; + iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); + numIOVs++; + } else { + FPRINTF(stderr, + "selfserv: CRL %s reloaded.\n", + fileName); + break; + } + } + } else if (reqLen <= 0) { /* hit eof */ + PORT_Sprintf(msgBuf, "Get or Post incomplete after %d bytes.\r\n", + bufDat); + + iovs[numIOVs].iov_base = msgBuf; + iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); + numIOVs++; + } else if (reqLen < bufDat) { + PORT_Sprintf(msgBuf, "Discarded %d characters.\r\n", + bufDat - reqLen); + + iovs[numIOVs].iov_base = msgBuf; + iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); + numIOVs++; } - /* There was a write error, so close this connection. */ - if (bulkSentChunks <= testBulkTotal) { - errWarn("PR_Write"); + if (reqLen > 0) { + if (verbose > 1) + fwrite(buf, 1, reqLen, stdout); /* display it */ + + iovs[numIOVs].iov_base = buf; + iovs[numIOVs].iov_len = reqLen; + numIOVs++; + } + + /* Don't add the EOF if we want to test bulk encryption */ + if (!testBulk) { + iovs[numIOVs].iov_base = (char *)EOFmsg; + iovs[numIOVs].iov_len = sizeof EOFmsg - 1; + numIOVs++; } - PR_ATOMIC_DECREMENT(&loggerOps); - break; - } - } while (0); + + rv = PR_Writev(ssl_sock, iovs, numIOVs, PR_INTERVAL_NO_TIMEOUT); + if (rv < 0) { + errWarn("PR_Writev"); + break; + } + + /* Send testBulkTotal chunks to the client. Unlimited if 0. */ + if (testBulk) { + while (0 < (rv = PR_Write(ssl_sock, testBulkBuf, testBulkSize))) { + PR_ATOMIC_ADD(&loggerBytes, rv); + PR_ATOMIC_INCREMENT(&bulkSentChunks); + if ((bulkSentChunks > testBulkTotal) && (testBulkTotal != 0)) + break; + } + + /* There was a write error, so close this connection. */ + if (bulkSentChunks <= testBulkTotal) { + errWarn("PR_Write"); + } + PR_ATOMIC_DECREMENT(&loggerOps); + break; + } + } while (0); cleanup: if (ssl_sock) { @@ -1569,7 +1594,7 @@ cleanup: PR_Close(tcp_sock); } if (local_file_fd) - PR_Close(local_file_fd); + PR_Close(local_file_fd); VLOG(("selfserv: handle_connection: exiting\n")); /* do a nice shutdown if asked. */ @@ -1578,12 +1603,13 @@ cleanup: stop_server(); } VLOG(("selfserv: handle_connection: exiting")); - return SECSuccess; /* success */ + return SECSuccess; /* success */ } #ifdef XP_UNIX -void sigusr1_handler(int sig) +void +sigusr1_handler(int sig) { VLOG(("selfserv: sigusr1_handler: stop server")); stop_server(); @@ -1595,17 +1621,16 @@ SECStatus do_accepts( PRFileDesc *listen_sock, PRFileDesc *model_sock, - int requestCert - ) + int requestCert) { - PRNetAddr addr; - PRErrorCode perr; + PRNetAddr addr; + PRErrorCode perr; #ifdef XP_UNIX struct sigaction act; #endif VLOG(("selfserv: do_accepts: starting")); - PR_SetThreadPriority( PR_GetCurrentThread(), PR_PRIORITY_HIGH); + PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_HIGH); acceptorThread = PR_GetCurrentThread(); #ifdef XP_UNIX @@ -1619,25 +1644,26 @@ do_accepts( } #endif while (!stopping) { - PRFileDesc *tcp_sock; - PRCList *myLink; - - 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) { - perr = PR_GetError(); - if ((perr != PR_CONNECT_RESET_ERROR && - perr != PR_PENDING_INTERRUPT_ERROR) || verbose) { - errWarn("PR_Accept"); - } - if (perr == PR_CONNECT_RESET_ERROR) { - FPRINTF(stderr, - "Ignoring PR_CONNECT_RESET_ERROR error - continue\n"); - continue; - } - stopping = 1; - break; - } + PRFileDesc *tcp_sock; + PRCList *myLink; + + 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) { + perr = PR_GetError(); + if ((perr != PR_CONNECT_RESET_ERROR && + perr != PR_PENDING_INTERRUPT_ERROR) || + verbose) { + errWarn("PR_Accept"); + } + if (perr == PR_CONNECT_RESET_ERROR) { + FPRINTF(stderr, + "Ignoring PR_CONNECT_RESET_ERROR error - continue\n"); + continue; + } + stopping = 1; + break; + } VLOG(("selfserv: do_accept: Got connection\n")); @@ -1645,32 +1671,32 @@ do_accepts( PR_ATOMIC_INCREMENT(&loggerOps); } - PZ_Lock(qLock); - while (PR_CLIST_IS_EMPTY(&freeJobs) && !stopping) { + PZ_Lock(qLock); + while (PR_CLIST_IS_EMPTY(&freeJobs) && !stopping) { PZ_WaitCondVar(freeListNotEmptyCv, PR_INTERVAL_NO_TIMEOUT); - } - if (stopping) { - PZ_Unlock(qLock); + } + if (stopping) { + PZ_Unlock(qLock); if (tcp_sock) { - PR_Close(tcp_sock); + PR_Close(tcp_sock); } - break; - } - myLink = PR_LIST_HEAD(&freeJobs); - PR_REMOVE_AND_INIT_LINK(myLink); - /* could release qLock here and reaquire it 7 lines below, but - ** why bother for 4 assignment statements? - */ - { - JOB * myJob = (JOB *)myLink; - myJob->tcp_sock = tcp_sock; - myJob->model_sock = model_sock; - myJob->requestCert = requestCert; - } - - PR_APPEND_LINK(myLink, &jobQ); - PZ_NotifyCondVar(jobQNotEmptyCv); - PZ_Unlock(qLock); + break; + } + myLink = PR_LIST_HEAD(&freeJobs); + PR_REMOVE_AND_INIT_LINK(myLink); + /* could release qLock here and reaquire it 7 lines below, but + ** why bother for 4 assignment statements? + */ + { + JOB *myJob = (JOB *)myLink; + myJob->tcp_sock = tcp_sock; + myJob->model_sock = model_sock; + myJob->requestCert = requestCert; + } + + PR_APPEND_LINK(myLink, &jobQ); + PZ_NotifyCondVar(jobQNotEmptyCv); + PZ_Unlock(qLock); } FPRINTF(stderr, "selfserv: Closing listen socket.\n"); @@ -1684,19 +1710,19 @@ do_accepts( PRFileDesc * getBoundListenSocket(unsigned short port) { - PRFileDesc * listen_sock; - int listenQueueDepth = 5 + (2 * maxThreads); - PRStatus prStatus; - PRNetAddr addr; + PRFileDesc *listen_sock; + int listenQueueDepth = 5 + (2 * maxThreads); + PRStatus prStatus; + PRNetAddr addr; PRSocketOptionData opt; addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_INADDR_ANY; - addr.inet.port = PR_htons(port); + addr.inet.ip = PR_INADDR_ANY; + addr.inet.port = PR_htons(port); listen_sock = PR_NewTCPSocket(); if (listen_sock == NULL) { - errExit("PR_NewTCPSocket"); + errExit("PR_NewTCPSocket"); } opt.option = PR_SockOpt_Nonblocking; @@ -1704,15 +1730,15 @@ getBoundListenSocket(unsigned short port) prStatus = PR_SetSocketOption(listen_sock, &opt); if (prStatus < 0) { PR_Close(listen_sock); - errExit("PR_SetSocketOption(PR_SockOpt_Nonblocking)"); + errExit("PR_SetSocketOption(PR_SockOpt_Nonblocking)"); } - opt.option=PR_SockOpt_Reuseaddr; + opt.option = PR_SockOpt_Reuseaddr; opt.value.reuse_addr = PR_TRUE; prStatus = PR_SetSocketOption(listen_sock, &opt); if (prStatus < 0) { PR_Close(listen_sock); - errExit("PR_SetSocketOption(PR_SockOpt_Reuseaddr)"); + errExit("PR_SetSocketOption(PR_SockOpt_Reuseaddr)"); } #ifndef WIN95 @@ -1721,7 +1747,7 @@ getBoundListenSocket(unsigned short port) * Don't do it in the WIN95 build configuration because clean shutdown is * not implemented, and PR_SockOpt_Linger causes a hang in ssl.sh . * See bug 332348 */ - opt.option=PR_SockOpt_Linger; + opt.option = PR_SockOpt_Linger; opt.value.linger.polarity = PR_TRUE; opt.value.linger.linger = PR_SecondsToInterval(1); prStatus = PR_SetSocketOption(listen_sock, &opt); @@ -1734,74 +1760,75 @@ getBoundListenSocket(unsigned short port) prStatus = PR_Bind(listen_sock, &addr); if (prStatus < 0) { PR_Close(listen_sock); - errExit("PR_Bind"); + errExit("PR_Bind"); } prStatus = PR_Listen(listen_sock, listenQueueDepth); if (prStatus < 0) { PR_Close(listen_sock); - errExit("PR_Listen"); + errExit("PR_Listen"); } return listen_sock; } -PRInt32 PR_CALLBACK -logWritev ( - PRFileDesc *fd, - const PRIOVec *iov, - PRInt32 size, - PRIntervalTime timeout ) +PRInt32 PR_CALLBACK +logWritev( + PRFileDesc *fd, + const PRIOVec *iov, + PRInt32 size, + PRIntervalTime timeout) { - PRInt32 rv = (fd->lower->methods->writev)(fd->lower, iov, size, - timeout); + PRInt32 rv = (fd->lower->methods->writev)(fd->lower, iov, size, + timeout); /* Add the amount written, but not if there's an error */ - if (rv > 0) + if (rv > 0) PR_ATOMIC_ADD(&loggerBytesTCP, rv); return rv; } - -PRInt32 PR_CALLBACK -logWrite ( - PRFileDesc *fd, - const void *buf, - PRInt32 amount) -{ + +PRInt32 PR_CALLBACK +logWrite( + PRFileDesc *fd, + const void *buf, + PRInt32 amount) +{ PRInt32 rv = (fd->lower->methods->write)(fd->lower, buf, amount); /* Add the amount written, but not if there's an error */ - if (rv > 0) + if (rv > 0) PR_ATOMIC_ADD(&loggerBytesTCP, rv); - + return rv; } -PRInt32 PR_CALLBACK -logSend ( - PRFileDesc *fd, - const void *buf, - PRInt32 amount, - PRIntn flags, - PRIntervalTime timeout) +PRInt32 PR_CALLBACK +logSend( + PRFileDesc *fd, + const void *buf, + PRInt32 amount, + PRIntn flags, + PRIntervalTime timeout) { - PRInt32 rv = (fd->lower->methods->send)(fd->lower, buf, amount, - flags, timeout); + PRInt32 rv = (fd->lower->methods->send)(fd->lower, buf, amount, + flags, timeout); /* Add the amount written, but not if there's an error */ - if (rv > 0) + if (rv > 0) PR_ATOMIC_ADD(&loggerBytesTCP, rv); return rv; } - -void initLoggingLayer(void) -{ + +void +initLoggingLayer(void) +{ /* get a new layer ID */ log_layer_id = PR_GetUniqueIdentity("Selfserv Logging"); if (log_layer_id == PR_INVALID_IO_LAYER) errExit("PR_GetUniqueIdentity"); - + /* setup the default IO methods with my custom write methods */ memcpy(&loggingMethods, PR_GetDefaultIOMethods(), sizeof(PRIOMethods)); loggingMethods.writev = logWritev; - loggingMethods.write = logWrite; - loggingMethods.send = logSend; + loggingMethods.write = logWrite; + loggingMethods.send = logSend; } void @@ -1809,8 +1836,8 @@ handshakeCallback(PRFileDesc *fd, void *client_data) { const char *handshakeName = (const char *)client_data; if (handshakeName && !failedToNegotiateName) { - SECItem *hostInfo = SSL_GetNegotiatedHostInfo(fd); - if (!hostInfo || PORT_Strncmp(handshakeName, (char*)hostInfo->data, + SECItem *hostInfo = SSL_GetNegotiatedHostInfo(fd); + if (!hostInfo || PORT_Strncmp(handshakeName, (char *)hostInfo->data, hostInfo->len)) { failedToNegotiateName = PR_TRUE; } @@ -1819,130 +1846,130 @@ handshakeCallback(PRFileDesc *fd, void *client_data) void server_main( - PRFileDesc * listen_sock, - int requestCert, - SECKEYPrivateKey ** privKey, - CERTCertificate ** cert, + PRFileDesc *listen_sock, + int requestCert, + SECKEYPrivateKey **privKey, + CERTCertificate **cert, const char *expectedHostNameVal) { - PRFileDesc *model_sock = NULL; - int rv; - SSLKEAType kea; - SECStatus secStatus; + PRFileDesc *model_sock = NULL; + int rv; + SSLKEAType kea; + SECStatus secStatus; 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"); - } + 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"); - } + model_sock = listen_sock = SSL_ImportFD(NULL, listen_sock); + if (listen_sock == NULL) { + errExit("SSL_ImportFD"); + } } /* do SSL configuration. */ rv = SSL_OptionSet(model_sock, SSL_SECURITY, enabledVersions.min != 0); if (rv < 0) { - errExit("SSL_OptionSet SSL_SECURITY"); + errExit("SSL_OptionSet SSL_SECURITY"); } rv = SSL_VersionRangeSet(model_sock, &enabledVersions); if (rv != SECSuccess) { - errExit("error setting SSL/TLS version range "); + errExit("error setting SSL/TLS version range "); } rv = SSL_OptionSet(model_sock, SSL_ROLLBACK_DETECTION, !disableRollBack); if (rv != SECSuccess) { - errExit("error enabling RollBack detection "); + errExit("error enabling RollBack detection "); } if (disableStepDown) { - rv = SSL_OptionSet(model_sock, SSL_NO_STEP_DOWN, PR_TRUE); - if (rv != SECSuccess) { - errExit("error disabling SSL StepDown "); - } + rv = SSL_OptionSet(model_sock, SSL_NO_STEP_DOWN, PR_TRUE); + if (rv != SECSuccess) { + errExit("error disabling SSL StepDown "); + } } if (bypassPKCS11) { - rv = SSL_OptionSet(model_sock, SSL_BYPASS_PKCS11, PR_TRUE); - if (rv != SECSuccess) { - errExit("error enabling PKCS11 bypass "); - } + rv = SSL_OptionSet(model_sock, SSL_BYPASS_PKCS11, PR_TRUE); + if (rv != SECSuccess) { + errExit("error enabling PKCS11 bypass "); + } } if (disableLocking) { - rv = SSL_OptionSet(model_sock, SSL_NO_LOCKS, PR_TRUE); - if (rv != SECSuccess) { - errExit("error disabling SSL socket locking "); - } - } + rv = SSL_OptionSet(model_sock, SSL_NO_LOCKS, PR_TRUE); + if (rv != SECSuccess) { + errExit("error disabling SSL socket locking "); + } + } if (enableSessionTickets) { - rv = SSL_OptionSet(model_sock, SSL_ENABLE_SESSION_TICKETS, PR_TRUE); - if (rv != SECSuccess) { - errExit("error enabling Session Ticket extension "); - } + rv = SSL_OptionSet(model_sock, SSL_ENABLE_SESSION_TICKETS, PR_TRUE); + if (rv != SECSuccess) { + errExit("error enabling Session Ticket extension "); + } } if (enableCompression) { - rv = SSL_OptionSet(model_sock, SSL_ENABLE_DEFLATE, PR_TRUE); - if (rv != SECSuccess) { - errExit("error enabling compression "); - } + rv = SSL_OptionSet(model_sock, SSL_ENABLE_DEFLATE, PR_TRUE); + if (rv != SECSuccess) { + errExit("error enabling compression "); + } } - if (virtServerNameIndex >1) { + if (virtServerNameIndex > 1) { rv = SSL_SNISocketConfigHook(model_sock, mySSLSNISocketConfig, - (void*)&virtServerNameArray); + (void *)&virtServerNameArray); if (rv != SECSuccess) { errExit("error enabling SNI extension "); } } if (configureDHE > -1) { - rv = SSL_OptionSet(model_sock, SSL_ENABLE_SERVER_DHE, (configureDHE > 0)); + rv = SSL_OptionSet(model_sock, SSL_ENABLE_SERVER_DHE, (configureDHE > 0)); if (rv != SECSuccess) { errExit("error configuring server side DHE support"); } } if (configureReuseECDHE > -1) { - rv = SSL_OptionSet(model_sock, SSL_REUSE_SERVER_ECDHE_KEY, (configureReuseECDHE > 0)); + rv = SSL_OptionSet(model_sock, SSL_REUSE_SERVER_ECDHE_KEY, (configureReuseECDHE > 0)); if (rv != SECSuccess) { errExit("error configuring server side reuse of ECDHE key"); } } if (configureWeakDHE > -1) { - rv = SSL_EnableWeakDHEPrimeGroup(model_sock, (configureWeakDHE > 0)); + rv = SSL_EnableWeakDHEPrimeGroup(model_sock, (configureWeakDHE > 0)); if (rv != SECSuccess) { errExit("error configuring weak DHE prime group"); } } - if (enableExtendedMasterSecret) { + if (enableExtendedMasterSecret) { rv = SSL_OptionSet(model_sock, SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE); - if (rv != SECSuccess) { - errExit("error enabling extended master secret "); - } + if (rv != SECSuccess) { + errExit("error enabling extended master secret "); + } } 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 (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_OptionSet(model_sock, SSL_ENABLE_FDX, 1); - if (rv < 0) { - errExit("SSL_OptionSet SSL_ENABLE_FDX"); - } + rv = SSL_OptionSet(model_sock, SSL_ENABLE_FDX, 1); + if (rv < 0) { + errExit("SSL_OptionSet SSL_ENABLE_FDX"); + } } if (NoReuse) { @@ -1956,38 +1983,37 @@ server_main( * would like it to be. Turn this cipher on. */ - secStatus = SSL_CipherPrefSetDefault( TLS_RSA_WITH_NULL_MD5, PR_TRUE); - if ( secStatus != SECSuccess ) { - errExit("SSL_CipherPrefSetDefault:TLS_RSA_WITH_NULL_MD5"); + secStatus = SSL_CipherPrefSetDefault(TLS_RSA_WITH_NULL_MD5, PR_TRUE); + if (secStatus != SECSuccess) { + errExit("SSL_CipherPrefSetDefault:TLS_RSA_WITH_NULL_MD5"); } if (expectedHostNameVal) { SSL_HandshakeCallback(model_sock, handshakeCallback, - (void*)expectedHostNameVal); + (void *)expectedHostNameVal); } if (requestCert) { - SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate, - (void *)CERT_GetDefaultCertDB()); - if (requestCert <= 2) { - rv = SSL_OptionSet(model_sock, SSL_REQUEST_CERTIFICATE, 1); - if (rv < 0) { - errExit("first SSL_OptionSet SSL_REQUEST_CERTIFICATE"); - } - rv = SSL_OptionSet(model_sock, SSL_REQUIRE_CERTIFICATE, - (requestCert == 2)); - if (rv < 0) { - errExit("first SSL_OptionSet SSL_REQUIRE_CERTIFICATE"); - } - } + SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate, + (void *)CERT_GetDefaultCertDB()); + if (requestCert <= 2) { + rv = SSL_OptionSet(model_sock, SSL_REQUEST_CERTIFICATE, 1); + if (rv < 0) { + errExit("first SSL_OptionSet SSL_REQUEST_CERTIFICATE"); + } + rv = SSL_OptionSet(model_sock, SSL_REQUIRE_CERTIFICATE, + (requestCert == 2)); + if (rv < 0) { + errExit("first SSL_OptionSet SSL_REQUIRE_CERTIFICATE"); + } + } } if (MakeCertOK) - SSL_BadCertHook(model_sock, myBadCertHandler, NULL); + SSL_BadCertHook(model_sock, myBadCertHandler, NULL); /* end of ssl configuration. */ - /* Now, do the accepting, here in the main thread. */ rv = do_accepts(listen_sock, model_sock, requestCert); @@ -1998,43 +2024,42 @@ server_main( PR_Close(model_sock); } } - } SECStatus -readBigFile(const char * fileName) +readBigFile(const char *fileName) { - PRFileInfo info; - PRStatus status; - SECStatus rv = SECFailure; - int count; - int hdrLen; + 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: + 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: if (local_file_fd) { PR_Close(local_file_fd); } @@ -2042,112 +2067,113 @@ done: return rv; } -int numChildren; -PRProcess * child[MAX_PROCS]; +int numChildren; +PRProcess *child[MAX_PROCS]; PRProcess * -haveAChild(int argc, char **argv, PRProcessAttr * attr) +haveAChild(int argc, char **argv, PRProcessAttr *attr) { - PRProcess * newProcess; + PRProcess *newProcess; newProcess = PR_CreateProcess(argv[0], argv, NULL, attr); if (!newProcess) { - errWarn("Can't create new process."); + errWarn("Can't create new process."); } else { - child[numChildren++] = newProcess; + child[numChildren++] = newProcess; } return newProcess; } void -beAGoodParent(int argc, char **argv, int maxProcs, PRFileDesc * listen_sock) +beAGoodParent(int argc, char **argv, int maxProcs, PRFileDesc *listen_sock) { - PRProcess * newProcess; - PRProcessAttr * attr; - int i; - PRInt32 exitCode; - PRStatus rv; + PRProcess *newProcess; + PRProcessAttr *attr; + int i; + PRInt32 exitCode; + PRStatus rv; rv = PR_SetFDInheritable(listen_sock, PR_TRUE); if (rv != PR_SUCCESS) - errExit("PR_SetFDInheritable"); + errExit("PR_SetFDInheritable"); attr = PR_NewProcessAttr(); if (!attr) - errExit("PR_NewProcessAttr"); + errExit("PR_NewProcessAttr"); rv = PR_ProcessAttrSetInheritableFD(attr, listen_sock, inheritableSockName); if (rv != PR_SUCCESS) - errExit("PR_ProcessAttrSetInheritableFD"); + errExit("PR_ProcessAttrSetInheritableFD"); for (i = 0; i < maxProcs; ++i) { - newProcess = haveAChild(argc, argv, attr); - if (!newProcess) - break; + newProcess = haveAChild(argc, argv, attr); + if (!newProcess) + break; } rv = PR_SetFDInheritable(listen_sock, PR_FALSE); if (rv != PR_SUCCESS) - errExit("PR_SetFDInheritable"); + errExit("PR_SetFDInheritable"); while (numChildren > 0) { - newProcess = child[numChildren - 1]; - PR_WaitProcess(newProcess, &exitCode); - fprintf(stderr, "Child %d exited with exit code %x\n", - numChildren, exitCode); - numChildren--; + newProcess = child[numChildren - 1]; + PR_WaitProcess(newProcess, &exitCode); + fprintf(stderr, "Child %d exited with exit code %x\n", + numChildren, exitCode); + numChildren--; } exit(0); } -#define HEXCHAR_TO_INT(c, i) \ - if (((c) >= '0') && ((c) <= '9')) { \ - i = (c) - '0'; \ - } else if (((c) >= 'a') && ((c) <= 'f')) { \ - i = (c) - 'a' + 10; \ - } else if (((c) >= 'A') && ((c) <= 'F')) { \ - i = (c) - 'A' + 10; \ - } else if ((c) == '\0') { \ - fprintf(stderr, "Invalid length of cipher string (-c :WXYZ).\n"); \ - exit(9); \ - } else { \ - fprintf(stderr, "Non-hex char in cipher string (-c :WXYZ).\n"); \ - exit(9); \ - } - -SECStatus enableOCSPStapling(const char* mode) +#define HEXCHAR_TO_INT(c, i) \ + if (((c) >= '0') && ((c) <= '9')) { \ + i = (c) - '0'; \ + } else if (((c) >= 'a') && ((c) <= 'f')) { \ + i = (c) - 'a' + 10; \ + } else if (((c) >= 'A') && ((c) <= 'F')) { \ + i = (c) - 'A' + 10; \ + } else if ((c) == '\0') { \ + fprintf(stderr, "Invalid length of cipher string (-c :WXYZ).\n"); \ + exit(9); \ + } else { \ + fprintf(stderr, "Non-hex char in cipher string (-c :WXYZ).\n"); \ + exit(9); \ + } + +SECStatus +enableOCSPStapling(const char *mode) { if (!strcmp(mode, "good")) { - ocspStaplingMode = osm_good; - return SECSuccess; + ocspStaplingMode = osm_good; + return SECSuccess; } if (!strcmp(mode, "unknown")) { - ocspStaplingMode = osm_unknown; - return SECSuccess; + ocspStaplingMode = osm_unknown; + return SECSuccess; } if (!strcmp(mode, "revoked")) { - ocspStaplingMode = osm_revoked; - return SECSuccess; + ocspStaplingMode = osm_revoked; + return SECSuccess; } if (!strcmp(mode, "badsig")) { - ocspStaplingMode = osm_badsig; - return SECSuccess; + ocspStaplingMode = osm_badsig; + return SECSuccess; } if (!strcmp(mode, "corrupted")) { - ocspStaplingMode = osm_corrupted; - return SECSuccess; + ocspStaplingMode = osm_corrupted; + return SECSuccess; } if (!strcmp(mode, "failure")) { - ocspStaplingMode = osm_failure; - return SECSuccess; + ocspStaplingMode = osm_failure; + return SECSuccess; } if (!strcmp(mode, "random")) { - ocspStaplingMode = osm_random; - return SECSuccess; + ocspStaplingMode = osm_random; + return SECSuccess; } if (!strcmp(mode, "ocsp")) { - ocspStaplingMode = osm_ocsp; - return SECSuccess; + ocspStaplingMode = osm_ocsp; + return SECSuccess; } return SECFailure; } @@ -2155,228 +2181,310 @@ SECStatus enableOCSPStapling(const char* mode) int main(int argc, char **argv) { - char * progName = NULL; - char * nickName = NULL; + char *progName = NULL; + char *nickName = NULL; #ifndef NSS_DISABLE_ECC - char * ecNickName = NULL; + char *ecNickName = NULL; #endif - char * dsaNickName = NULL; - const char * fileName = NULL; - char * cipherString= NULL; - const char * dir = "."; - char * passwd = NULL; - char * pwfile = NULL; - const char * pidFile = NULL; - char * tmp; - char * envString; - PRFileDesc * listen_sock; - CERTCertificate * cert [kt_kea_size] = { NULL }; - SECKEYPrivateKey * privKey[kt_kea_size] = { NULL }; - int optionsFound = 0; - int maxProcs = 1; - unsigned short port = 0; - SECStatus rv; - PRStatus prStatus; - PRBool bindOnly = PR_FALSE; - PRBool useExportPolicy = PR_FALSE; - PRBool useLocalThreads = PR_FALSE; - PLOptState *optstate; - PLOptStatus status; - PRThread *loggerThread = NULL; - PRBool debugCache = PR_FALSE; /* bug 90518 */ - char emptyString[] = { "" }; - char* certPrefix = emptyString; - PRUint32 protos = 0; - SSL3Statistics *ssl3stats; - PRUint32 i; - secuPWData pwdata = { PW_NONE, 0 }; - char *expectedHostNameVal = NULL; - PLArenaPool *certStatusArena = NULL; + char *dsaNickName = NULL; + const char *fileName = NULL; + char *cipherString = NULL; + const char *dir = "."; + char *passwd = NULL; + char *pwfile = NULL; + const char *pidFile = NULL; + char *tmp; + char *envString; + PRFileDesc *listen_sock; + CERTCertificate *cert[kt_kea_size] = { NULL }; + SECKEYPrivateKey *privKey[kt_kea_size] = { NULL }; + int optionsFound = 0; + int maxProcs = 1; + unsigned short port = 0; + SECStatus rv; + PRStatus prStatus; + PRBool bindOnly = PR_FALSE; + PRBool useExportPolicy = PR_FALSE; + PRBool useLocalThreads = PR_FALSE; + PLOptState *optstate; + PLOptStatus status; + PRThread *loggerThread = NULL; + PRBool debugCache = PR_FALSE; /* bug 90518 */ + char emptyString[] = { "" }; + char *certPrefix = emptyString; + PRUint32 protos = 0; + SSL3Statistics *ssl3stats; + PRUint32 i; + secuPWData pwdata = { PW_NONE, 0 }; + char *expectedHostNameVal = NULL; + PLArenaPool *certStatusArena = NULL; tmp = strrchr(argv[0], '/'); tmp = tmp ? tmp + 1 : argv[0]; progName = strrchr(tmp, '\\'); progName = progName ? progName + 1 : tmp; - PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); + PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions); /* please keep this list of options in ASCII collating sequence. - ** numbers, then capital letters, then lower case, alphabetical. + ** numbers, then capital letters, then lower case, alphabetical. */ - optstate = PL_CreateOptState(argc, argv, - "2:A:BC:DEGH:L:M:NP:RS:T:U:V:W:Ya:bc:d:e:f:g:hi:jk:lmn:op:qrst:uvw:xyz"); + optstate = PL_CreateOptState(argc, argv, + "2:A:BC:DEGH:L:M:NP:RS:T:U:V:W:Ya:bc:d:e:f:g:hi:jk:lmn:op:qrst:uvw:xyz"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { - ++optionsFound; - switch(optstate->option) { - case '2': fileName = optstate->value; break; - - case 'A': ocspStaplingCA = PORT_Strdup(optstate->value); break; - - case 'B': bypassPKCS11 = PR_TRUE; break; - - case 'C': if (optstate->value) NumSidCacheEntries = PORT_Atoi(optstate->value); break; - - case 'D': noDelay = PR_TRUE; break; - case 'E': disableStepDown = PR_TRUE; break; - case 'H': configureDHE = (PORT_Atoi(optstate->value) != 0); break; - - case 'G': enableExtendedMasterSecret = PR_TRUE; break; - - case 'I': /* reserved for OCSP multi-stapling */ break; - - case 'L': - logStats = PR_TRUE; - if (optstate->value == NULL) { - logPeriod = 30; - } else { - logPeriod = PORT_Atoi(optstate->value); - if (logPeriod <= 0) logPeriod = 30; - } - break; - - case 'M': - maxProcs = PORT_Atoi(optstate->value); - if (maxProcs < 1) maxProcs = 1; - if (maxProcs > MAX_PROCS) maxProcs = MAX_PROCS; - break; - - case 'N': NoReuse = PR_TRUE; break; - - case 'R': disableRollBack = PR_TRUE; break; - - case 'S': dsaNickName = PORT_Strdup(optstate->value); break; + ++optionsFound; + switch (optstate->option) { + case '2': + fileName = optstate->value; + break; + + case 'A': + ocspStaplingCA = PORT_Strdup(optstate->value); + break; + + case 'B': + bypassPKCS11 = PR_TRUE; + break; + + case 'C': + if (optstate->value) + NumSidCacheEntries = PORT_Atoi(optstate->value); + break; + + case 'D': + noDelay = PR_TRUE; + break; + case 'E': + disableStepDown = PR_TRUE; + break; + case 'H': + configureDHE = (PORT_Atoi(optstate->value) != 0); + break; + + case 'G': + enableExtendedMasterSecret = PR_TRUE; + break; + + case 'I': /* reserved for OCSP multi-stapling */ + break; + + case 'L': + logStats = PR_TRUE; + if (optstate->value == NULL) { + logPeriod = 30; + } else { + logPeriod = PORT_Atoi(optstate->value); + if (logPeriod <= 0) + logPeriod = 30; + } + break; + + case 'M': + maxProcs = PORT_Atoi(optstate->value); + if (maxProcs < 1) + maxProcs = 1; + if (maxProcs > MAX_PROCS) + maxProcs = MAX_PROCS; + break; + + case 'N': + NoReuse = PR_TRUE; + break; + + case 'R': + disableRollBack = PR_TRUE; + break; + + case 'S': + dsaNickName = PORT_Strdup(optstate->value); + break; + + case 'T': + if (enableOCSPStapling(optstate->value) != SECSuccess) { + fprintf(stderr, "Invalid OCSP stapling mode.\n"); + fprintf(stderr, "Run '%s -h' for usage information.\n", progName); + exit(53); + } + break; - case 'T': - if (enableOCSPStapling(optstate->value) != SECSuccess) { - fprintf(stderr, "Invalid OCSP stapling mode.\n"); - fprintf(stderr, "Run '%s -h' for usage information.\n", progName); - exit(53); - } - break; + case 'U': + configureReuseECDHE = (PORT_Atoi(optstate->value) != 0); + break; - case 'U': configureReuseECDHE = (PORT_Atoi(optstate->value) != 0); break; + case 'V': + if (SECU_ParseSSLVersionRangeString(optstate->value, + enabledVersions, &enabledVersions) != + SECSuccess) { + Usage(progName); + } + break; - case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value, - enabledVersions, &enabledVersions) != SECSuccess) { - Usage(progName); - } - break; + case 'W': + configureWeakDHE = (PORT_Atoi(optstate->value) != 0); + break; - case 'W': configureWeakDHE = (PORT_Atoi(optstate->value) != 0); break; + case 'Y': + PrintCipherUsage(progName); + exit(0); + break; - case 'Y': PrintCipherUsage(progName); exit(0); break; - - case 'a': if (virtServerNameIndex >= MAX_VIRT_SERVER_NAME_ARRAY_INDEX) { - Usage(progName); break; - } - virtServerNameArray[virtServerNameIndex++] = - PORT_Strdup(optstate->value); break; + case 'a': + if (virtServerNameIndex >= MAX_VIRT_SERVER_NAME_ARRAY_INDEX) { + Usage(progName); + break; + } + virtServerNameArray[virtServerNameIndex++] = + PORT_Strdup(optstate->value); + break; - case 'b': bindOnly = PR_TRUE; break; + case 'b': + bindOnly = PR_TRUE; + break; - case 'c': cipherString = PORT_Strdup(optstate->value); break; + case 'c': + cipherString = PORT_Strdup(optstate->value); + break; - case 'd': dir = optstate->value; break; + case 'd': + dir = optstate->value; + break; #ifndef NSS_DISABLE_ECC - case 'e': ecNickName = PORT_Strdup(optstate->value); break; + case 'e': + ecNickName = PORT_Strdup(optstate->value); + break; #endif /* NSS_DISABLE_ECC */ - case 'f': - pwdata.source = PW_FROMFILE; - pwdata.data = pwfile = PORT_Strdup(optstate->value); - break; - - case 'g': - testBulk = PR_TRUE; - testBulkTotal = PORT_Atoi(optstate->value); - break; - - case 'h': Usage(progName); exit(0); break; - - case 'i': pidFile = optstate->value; break; - - case 'j': - initLoggingLayer(); - loggingLayer = PR_TRUE; - break; - - case 'k': expectedHostNameVal = PORT_Strdup(optstate->value); - break; - - case 'l': useLocalThreads = PR_TRUE; break; - - case 'm': useModelSocket = PR_TRUE; break; - - case 'n': nickName = PORT_Strdup(optstate->value); - virtServerNameArray[0] = PORT_Strdup(optstate->value); - break; - - case 'P': certPrefix = PORT_Strdup(optstate->value); break; - - case 'o': MakeCertOK = 1; break; - - case 'p': port = PORT_Atoi(optstate->value); break; - - case 'q': testbypass = PR_TRUE; break; - - case 'r': ++requestCert; break; - - case 's': disableLocking = PR_TRUE; break; - - case 't': - maxThreads = PORT_Atoi(optstate->value); - if ( maxThreads > MAX_THREADS ) maxThreads = MAX_THREADS; - if ( maxThreads < MIN_THREADS ) maxThreads = MIN_THREADS; - break; - - case 'u': enableSessionTickets = PR_TRUE; break; - - case 'v': verbose++; break; - - case 'w': - pwdata.source = PW_PLAINTEXT; - pwdata.data = passwd = PORT_Strdup(optstate->value); - break; - - case 'x': useExportPolicy = PR_TRUE; break; - - case 'y': debugCache = PR_TRUE; break; - - case 'z': enableCompression = PR_TRUE; break; - - default: - case '?': - fprintf(stderr, "Unrecognized or bad option specified.\n"); - fprintf(stderr, "Run '%s -h' for usage information.\n", progName); - exit(4); - break; - } + case 'f': + pwdata.source = PW_FROMFILE; + pwdata.data = pwfile = PORT_Strdup(optstate->value); + break; + + case 'g': + testBulk = PR_TRUE; + testBulkTotal = PORT_Atoi(optstate->value); + break; + + case 'h': + Usage(progName); + exit(0); + break; + + case 'i': + pidFile = optstate->value; + break; + + case 'j': + initLoggingLayer(); + loggingLayer = PR_TRUE; + break; + + case 'k': + expectedHostNameVal = PORT_Strdup(optstate->value); + break; + + case 'l': + useLocalThreads = PR_TRUE; + break; + + case 'm': + useModelSocket = PR_TRUE; + break; + + case 'n': + nickName = PORT_Strdup(optstate->value); + virtServerNameArray[0] = PORT_Strdup(optstate->value); + break; + + case 'P': + certPrefix = PORT_Strdup(optstate->value); + break; + + case 'o': + MakeCertOK = 1; + break; + + case 'p': + port = PORT_Atoi(optstate->value); + break; + + case 'q': + testbypass = PR_TRUE; + break; + + case 'r': + ++requestCert; + break; + + case 's': + disableLocking = PR_TRUE; + break; + + case 't': + maxThreads = PORT_Atoi(optstate->value); + if (maxThreads > MAX_THREADS) + maxThreads = MAX_THREADS; + if (maxThreads < MIN_THREADS) + maxThreads = MIN_THREADS; + break; + + case 'u': + enableSessionTickets = PR_TRUE; + break; + + case 'v': + verbose++; + break; + + case 'w': + pwdata.source = PW_PLAINTEXT; + pwdata.data = passwd = PORT_Strdup(optstate->value); + break; + + case 'x': + useExportPolicy = PR_TRUE; + break; + + case 'y': + debugCache = PR_TRUE; + break; + + case 'z': + enableCompression = PR_TRUE; + break; + + default: + case '?': + fprintf(stderr, "Unrecognized or bad option specified.\n"); + fprintf(stderr, "Run '%s -h' for usage information.\n", progName); + exit(4); + break; + } } PL_DestroyOptState(optstate); if (status == PL_OPT_BAD) { - fprintf(stderr, "Unrecognized or bad option specified.\n"); - fprintf(stderr, "Run '%s -h' for usage information.\n", progName); - exit(5); + fprintf(stderr, "Unrecognized or bad option specified.\n"); + fprintf(stderr, "Run '%s -h' for usage information.\n", progName); + exit(5); } if (!optionsFound) { - Usage(progName); - exit(51); + Usage(progName); + exit(51); } switch (ocspStaplingMode) { - case osm_good: - case osm_revoked: - case osm_unknown: - case osm_random: - if (!ocspStaplingCA) { - fprintf(stderr, "Selected stapling response requires the -A parameter.\n"); - fprintf(stderr, "Run '%s -h' for usage information.\n", progName); - exit(52); - } - break; - default: - break; + case osm_good: + case osm_revoked: + case osm_unknown: + case osm_random: + if (!ocspStaplingCA) { + fprintf(stderr, "Selected stapling response requires the -A parameter.\n"); + fprintf(stderr, "Run '%s -h' for usage information.\n", progName); + exit(52); + } + break; + default: + break; } /* The -b (bindOnly) option is only used by the ssl.sh test @@ -2384,45 +2492,45 @@ main(int argc, char **argv) * process has fully died and freed the port. (Bug 129701) */ if (bindOnly) { - listen_sock = getBoundListenSocket(port); - if (!listen_sock) { - exit(1); - } + listen_sock = getBoundListenSocket(port); + if (!listen_sock) { + exit(1); + } if (listen_sock) { PR_Close(listen_sock); } - exit(0); + exit(0); } - if ((nickName == NULL) - && (dsaNickName == NULL) - #ifndef NSS_DISABLE_ECC - && (ecNickName == NULL) - #endif - ) { + if ((nickName == NULL) && + (dsaNickName == NULL) +#ifndef NSS_DISABLE_ECC + && (ecNickName == NULL) +#endif + ) { - fprintf(stderr, "Required arg '-n' (rsa nickname) not supplied.\n"); - fprintf(stderr, "Run '%s -h' for usage information.\n", progName); + fprintf(stderr, "Required arg '-n' (rsa nickname) not supplied.\n"); + fprintf(stderr, "Run '%s -h' for usage information.\n", progName); exit(6); } if (port == 0) { - fprintf(stderr, "Required argument 'port' must be non-zero value\n"); - exit(7); + fprintf(stderr, "Required argument 'port' must be non-zero value\n"); + exit(7); } if (NoReuse && maxProcs > 1) { - fprintf(stderr, "-M and -N options are mutually exclusive.\n"); - exit(14); + fprintf(stderr, "-M and -N options are mutually exclusive.\n"); + exit(14); } if (pidFile) { - FILE *tmpfile=fopen(pidFile,"w+"); + FILE *tmpfile = fopen(pidFile, "w+"); - if (tmpfile) { - fprintf(tmpfile,"%d",getpid()); - fclose(tmpfile); - } + if (tmpfile) { + fprintf(tmpfile, "%d", getpid()); + fclose(tmpfile); + } } /* allocate and initialize app data for bulk encryption testing */ @@ -2437,59 +2545,59 @@ main(int argc, char **argv) envString = PR_GetEnvSecure(envVarName); tmp = PR_GetEnvSecure("TMP"); if (!tmp) - tmp = PR_GetEnvSecure("TMPDIR"); + tmp = PR_GetEnvSecure("TMPDIR"); if (!tmp) - tmp = PR_GetEnvSecure("TEMP"); + tmp = PR_GetEnvSecure("TEMP"); if (envString) { - /* we're one of the children in a multi-process server. */ - listen_sock = PR_GetInheritedFD(inheritableSockName); - if (!listen_sock) - errExit("PR_GetInheritedFD"); + /* we're one of the children in a multi-process server. */ + listen_sock = PR_GetInheritedFD(inheritableSockName); + if (!listen_sock) + errExit("PR_GetInheritedFD"); #ifndef WINNT - /* we can't do this on NT because it breaks NSPR and - PR_Accept will fail on the socket in the child process if - the socket state is change to non inheritable - It is however a security issue to leave it accessible, - but it is OK for a test server such as selfserv. - NSPR should fix it eventually . see bugzilla 101617 - and 102077 - */ - prStatus = PR_SetFDInheritable(listen_sock, PR_FALSE); - if (prStatus != PR_SUCCESS) - errExit("PR_SetFDInheritable"); + /* we can't do this on NT because it breaks NSPR and + PR_Accept will fail on the socket in the child process if + the socket state is change to non inheritable + It is however a security issue to leave it accessible, + but it is OK for a test server such as selfserv. + NSPR should fix it eventually . see bugzilla 101617 + and 102077 + */ + prStatus = PR_SetFDInheritable(listen_sock, PR_FALSE); + if (prStatus != PR_SUCCESS) + errExit("PR_SetFDInheritable"); #endif - rv = SSL_InheritMPServerSIDCache(envString); - if (rv != SECSuccess) - errExit("SSL_InheritMPServerSIDCache"); - hasSidCache = PR_TRUE; + rv = SSL_InheritMPServerSIDCache(envString); + if (rv != SECSuccess) + errExit("SSL_InheritMPServerSIDCache"); + hasSidCache = PR_TRUE; } else if (maxProcs > 1) { - /* we're going to be the parent in a multi-process server. */ - listen_sock = getBoundListenSocket(port); - rv = SSL_ConfigMPServerSIDCache(NumSidCacheEntries, 0, 0, tmp); - if (rv != SECSuccess) - errExit("SSL_ConfigMPServerSIDCache"); - hasSidCache = PR_TRUE; - beAGoodParent(argc, argv, maxProcs, listen_sock); - exit(99); /* should never get here */ + /* we're going to be the parent in a multi-process server. */ + listen_sock = getBoundListenSocket(port); + rv = SSL_ConfigMPServerSIDCache(NumSidCacheEntries, 0, 0, tmp); + if (rv != SECSuccess) + errExit("SSL_ConfigMPServerSIDCache"); + hasSidCache = PR_TRUE; + beAGoodParent(argc, argv, maxProcs, listen_sock); + exit(99); /* should never get here */ } else { - /* we're an ordinary single process server. */ - listen_sock = getBoundListenSocket(port); - prStatus = PR_SetFDInheritable(listen_sock, PR_FALSE); - if (prStatus != PR_SUCCESS) - errExit("PR_SetFDInheritable"); - if (!NoReuse) { - rv = SSL_ConfigServerSessionIDCache(NumSidCacheEntries, - 0, 0, tmp); - if (rv != SECSuccess) - errExit("SSL_ConfigServerSessionIDCache"); - hasSidCache = PR_TRUE; - } + /* we're an ordinary single process server. */ + listen_sock = getBoundListenSocket(port); + prStatus = PR_SetFDInheritable(listen_sock, PR_FALSE); + if (prStatus != PR_SUCCESS) + errExit("PR_SetFDInheritable"); + if (!NoReuse) { + rv = SSL_ConfigServerSessionIDCache(NumSidCacheEntries, + 0, 0, tmp); + if (rv != SECSuccess) + errExit("SSL_ConfigServerSessionIDCache"); + hasSidCache = PR_TRUE; + } } lm = PR_NewLogModule("TestCase"); if (fileName) - readBigFile(fileName); + readBigFile(fileName); /* set our password function */ PK11_SetPasswordFunc(SECU_GetModulePassword); @@ -2497,89 +2605,89 @@ main(int argc, char **argv) /* Call the NSS initialization routines */ rv = NSS_Initialize(dir, certPrefix, certPrefix, SECMOD_DB, NSS_INIT_READONLY); if (rv != SECSuccess) { - fputs("NSS_Init failed.\n", stderr); - exit(8); + fputs("NSS_Init failed.\n", stderr); + exit(8); } /* set the policy bits true for all the cipher suites. */ if (useExportPolicy) { - NSS_SetExportPolicy(); - if (disableStepDown) { - fputs("selfserv: -x and -E options may not be used together\n", - stderr); - exit(98); - } + NSS_SetExportPolicy(); + if (disableStepDown) { + fputs("selfserv: -x and -E options may not be used together\n", + stderr); + exit(98); + } } else { - NSS_SetDomesticPolicy(); - if (disableStepDown) { - rv = disableExportSSLCiphers(); - if (rv != SECSuccess) { - errExit("error disabling export ciphersuites "); - } - } + NSS_SetDomesticPolicy(); + if (disableStepDown) { + rv = disableExportSSLCiphers(); + if (rv != SECSuccess) { + errExit("error disabling export ciphersuites "); + } + } } /* all SSL3 cipher suites are enabled by default. */ if (cipherString) { - char *cstringSaved = cipherString; - int ndx; + char *cstringSaved = cipherString; + int ndx; - /* disable all the ciphers, then enable the ones we want. */ - disableAllSSLCiphers(); + /* disable all the ciphers, then enable the ones we want. */ + disableAllSSLCiphers(); - while (0 != (ndx = *cipherString++)) { + while (0 != (ndx = *cipherString++)) { int cipher = 0; - if (ndx == ':') { - int ctmp; - - HEXCHAR_TO_INT(*cipherString, ctmp) - cipher |= (ctmp << 12); - cipherString++; - HEXCHAR_TO_INT(*cipherString, ctmp) - cipher |= (ctmp << 8); - cipherString++; - HEXCHAR_TO_INT(*cipherString, ctmp) - cipher |= (ctmp << 4); - cipherString++; - HEXCHAR_TO_INT(*cipherString, ctmp) - cipher |= ctmp; - cipherString++; - } else { - if (! isalpha(ndx)) { - fprintf(stderr, - "Non-alphabetic char in cipher string (-c arg).\n"); - exit(9); - } + if (ndx == ':') { + int ctmp; + + HEXCHAR_TO_INT(*cipherString, ctmp) + cipher |= (ctmp << 12); + cipherString++; + HEXCHAR_TO_INT(*cipherString, ctmp) + cipher |= (ctmp << 8); + cipherString++; + HEXCHAR_TO_INT(*cipherString, ctmp) + cipher |= (ctmp << 4); + cipherString++; + HEXCHAR_TO_INT(*cipherString, ctmp) + cipher |= ctmp; + cipherString++; + } else { + if (!isalpha(ndx)) { + fprintf(stderr, + "Non-alphabetic char in cipher string (-c arg).\n"); + exit(9); + } ndx = tolower(ndx) - 'a'; if (ndx < PR_ARRAY_SIZE(ssl3CipherSuites)) { cipher = ssl3CipherSuites[ndx]; } - } - if (cipher > 0) { - SECStatus status; - status = SSL_CipherPrefSetDefault(cipher, SSL_ALLOWED); - if (status != SECSuccess) - SECU_PrintError(progName, "SSL_CipherPrefSet()"); - } else { - fprintf(stderr, - "Invalid cipher specification (-c arg).\n"); - exit(9); - } - } - PORT_Free(cstringSaved); + } + if (cipher > 0) { + SECStatus status; + status = SSL_CipherPrefSetDefault(cipher, SSL_ALLOWED); + if (status != SECSuccess) + SECU_PrintError(progName, "SSL_CipherPrefSet()"); + } else { + fprintf(stderr, + "Invalid cipher specification (-c arg).\n"); + exit(9); + } + } + PORT_Free(cstringSaved); } if (testbypass) { - const PRUint16 *cipherSuites = SSL_ImplementedCiphers; - int i = SSL_NumImplementedCiphers; - PRBool enabled; - - for (i=0; i < SSL_NumImplementedCiphers; i++, cipherSuites++) { - if (SSL_CipherPrefGetDefault(*cipherSuites, &enabled) == SECSuccess - && enabled) - savecipher(*cipherSuites); - } + const PRUint16 *cipherSuites = SSL_ImplementedCiphers; + int i = SSL_NumImplementedCiphers; + PRBool enabled; + + for (i = 0; i < SSL_NumImplementedCiphers; i++, cipherSuites++) { + if (SSL_CipherPrefGetDefault(*cipherSuites, &enabled) == SECSuccess && + enabled) + savecipher(*cipherSuites); + } protos = 0; if (enabledVersions.min <= SSL_LIBRARY_VERSION_3_0 && enabledVersions.max >= SSL_LIBRARY_VERSION_3_0) { @@ -2598,115 +2706,116 @@ main(int argc, char **argv) certStatusArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!certStatusArena) - errExit("cannot allocate certStatusArena"); + errExit("cannot allocate certStatusArena"); if (nickName) { - cert[kt_rsa] = PK11_FindCertFromNickname(nickName, &pwdata); - if (cert[kt_rsa] == NULL) { - fprintf(stderr, "selfserv: Can't find certificate %s\n", nickName); - exit(10); - } - privKey[kt_rsa] = PK11_FindKeyByAnyCert(cert[kt_rsa], &pwdata); - if (privKey[kt_rsa] == NULL) { - fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n", - nickName); - exit(11); - } - if (testbypass) { - PRBool bypassOK; - if (SSL_CanBypass(cert[kt_rsa], privKey[kt_rsa], protos, cipherlist, - nciphers, &bypassOK, &pwdata) != SECSuccess) { - SECU_PrintError(progName, "Bypass test failed %s\n", nickName); - exit(14); - } - fprintf(stderr, "selfserv: %s can%s bypass\n", nickName, - bypassOK ? "" : "not"); - } - setupCertStatus(certStatusArena, ocspStaplingMode, cert[kt_rsa], kt_rsa, - &pwdata); + cert[kt_rsa] = PK11_FindCertFromNickname(nickName, &pwdata); + if (cert[kt_rsa] == NULL) { + fprintf(stderr, "selfserv: Can't find certificate %s\n", nickName); + exit(10); + } + privKey[kt_rsa] = PK11_FindKeyByAnyCert(cert[kt_rsa], &pwdata); + if (privKey[kt_rsa] == NULL) { + fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n", + nickName); + exit(11); + } + if (testbypass) { + PRBool bypassOK; + if (SSL_CanBypass(cert[kt_rsa], privKey[kt_rsa], protos, cipherlist, + nciphers, &bypassOK, &pwdata) != SECSuccess) { + SECU_PrintError(progName, "Bypass test failed %s\n", nickName); + exit(14); + } + fprintf(stderr, "selfserv: %s can%s bypass\n", nickName, + bypassOK ? "" : "not"); + } + setupCertStatus(certStatusArena, ocspStaplingMode, cert[kt_rsa], kt_rsa, + &pwdata); } if (dsaNickName) { - /* Investigate if ssl_kea_dh should be changed to ssl_auth_dsa. - * See bug 102794.*/ - cert[ssl_kea_dh] = PK11_FindCertFromNickname(dsaNickName, &pwdata); - if (cert[ssl_kea_dh] == NULL) { - fprintf(stderr, "selfserv: Can't find certificate %s\n", dsaNickName); - exit(12); - } - privKey[ssl_kea_dh] = PK11_FindKeyByAnyCert(cert[ssl_kea_dh], &pwdata); - if (privKey[ssl_kea_dh] == NULL) { - fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n", - dsaNickName); - exit(11); - } - if (testbypass) { - PRBool bypassOK; - if (SSL_CanBypass(cert[ssl_kea_dh], privKey[ssl_kea_dh], protos, cipherlist, - nciphers, &bypassOK, &pwdata) != SECSuccess) { - SECU_PrintError(progName, "Bypass test failed %s\n", nickName); - exit(14); - } - fprintf(stderr, "selfserv: %s can%s bypass\n", nickName, - bypassOK ? "" : "not"); - } - setupCertStatus(certStatusArena, ocspStaplingMode, cert[ssl_kea_dh], ssl_kea_dh, - &pwdata); + /* Investigate if ssl_kea_dh should be changed to ssl_auth_dsa. + * See bug 102794.*/ + cert[ssl_kea_dh] = PK11_FindCertFromNickname(dsaNickName, &pwdata); + if (cert[ssl_kea_dh] == NULL) { + fprintf(stderr, "selfserv: Can't find certificate %s\n", dsaNickName); + exit(12); + } + privKey[ssl_kea_dh] = PK11_FindKeyByAnyCert(cert[ssl_kea_dh], &pwdata); + if (privKey[ssl_kea_dh] == NULL) { + fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n", + dsaNickName); + exit(11); + } + if (testbypass) { + PRBool bypassOK; + if (SSL_CanBypass(cert[ssl_kea_dh], privKey[ssl_kea_dh], protos, cipherlist, + nciphers, &bypassOK, &pwdata) != SECSuccess) { + SECU_PrintError(progName, "Bypass test failed %s\n", nickName); + exit(14); + } + fprintf(stderr, "selfserv: %s can%s bypass\n", nickName, + bypassOK ? "" : "not"); + } + setupCertStatus(certStatusArena, ocspStaplingMode, cert[ssl_kea_dh], ssl_kea_dh, + &pwdata); } #ifndef NSS_DISABLE_ECC if (ecNickName) { - cert[kt_ecdh] = PK11_FindCertFromNickname(ecNickName, &pwdata); - if (cert[kt_ecdh] == NULL) { - fprintf(stderr, "selfserv: Can't find certificate %s\n", - ecNickName); - exit(13); - } - privKey[kt_ecdh] = PK11_FindKeyByAnyCert(cert[kt_ecdh], &pwdata); - if (privKey[kt_ecdh] == NULL) { - fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n", - ecNickName); - exit(11); - } - if (testbypass) { - PRBool bypassOK; - if (SSL_CanBypass(cert[kt_ecdh], privKey[kt_ecdh], protos, cipherlist, - nciphers, &bypassOK, &pwdata) != SECSuccess) { - SECU_PrintError(progName, "Bypass test failed %s\n", ecNickName); - exit(15); - } - fprintf(stderr, "selfserv: %s can%s bypass\n", ecNickName, - bypassOK ? "" : "not"); - } - setupCertStatus(certStatusArena, ocspStaplingMode, cert[kt_ecdh], kt_ecdh, - &pwdata); + cert[kt_ecdh] = PK11_FindCertFromNickname(ecNickName, &pwdata); + if (cert[kt_ecdh] == NULL) { + fprintf(stderr, "selfserv: Can't find certificate %s\n", + ecNickName); + exit(13); + } + privKey[kt_ecdh] = PK11_FindKeyByAnyCert(cert[kt_ecdh], &pwdata); + if (privKey[kt_ecdh] == NULL) { + fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n", + ecNickName); + exit(11); + } + if (testbypass) { + PRBool bypassOK; + if (SSL_CanBypass(cert[kt_ecdh], privKey[kt_ecdh], protos, cipherlist, + nciphers, &bypassOK, &pwdata) != SECSuccess) { + SECU_PrintError(progName, "Bypass test failed %s\n", ecNickName); + exit(15); + } + fprintf(stderr, "selfserv: %s can%s bypass\n", ecNickName, + bypassOK ? "" : "not"); + } + setupCertStatus(certStatusArena, ocspStaplingMode, cert[kt_ecdh], kt_ecdh, + &pwdata); } #endif /* NSS_DISABLE_ECC */ if (testbypass) - goto cleanup; + goto cleanup; if (configureWeakDHE > 0) { - fprintf(stderr, "selfserv: Creating dynamic weak DH parameters\n"); - rv = SSL_EnableWeakDHEPrimeGroup(NULL, PR_TRUE); - fprintf(stderr, "selfserv: Done creating dynamic weak DH parameters\n"); + fprintf(stderr, "selfserv: Creating dynamic weak DH parameters\n"); + rv = SSL_EnableWeakDHEPrimeGroup(NULL, PR_TRUE); + fprintf(stderr, "selfserv: Done creating dynamic weak DH parameters\n"); } - -/* allocate the array of thread slots, and launch the worker threads. */ + /* allocate the array of thread slots, and launch the worker threads. */ rv = launch_threads(&jobLoop, 0, 0, requestCert, useLocalThreads); if (rv == SECSuccess && logStats) { - loggerThread = PR_CreateThread(PR_SYSTEM_THREAD, - logger, NULL, PR_PRIORITY_NORMAL, - useLocalThreads ? PR_LOCAL_THREAD:PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, 0); - if (loggerThread == NULL) { - fprintf(stderr, "selfserv: Failed to launch logger thread!\n"); - rv = SECFailure; - } + loggerThread = PR_CreateThread(PR_SYSTEM_THREAD, + logger, NULL, PR_PRIORITY_NORMAL, + useLocalThreads ? + PR_LOCAL_THREAD + : PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, 0); + if (loggerThread == NULL) { + fprintf(stderr, "selfserv: Failed to launch logger thread!\n"); + rv = SECFailure; + } } if (rv == SECSuccess) { - server_main(listen_sock, requestCert, privKey, cert, + server_main(listen_sock, requestCert, privKey, cert, expectedHostNameVal); } @@ -2716,8 +2825,8 @@ cleanup: printSSLStatistics(); ssl3stats = SSL_GetStatistics(); if (ssl3stats->hch_sid_ticket_parse_failures != 0) { - fprintf(stderr, "selfserv: Experienced ticket parse failure(s)\n"); - exit(1); + fprintf(stderr, "selfserv: Experienced ticket parse failure(s)\n"); + exit(1); } if (failedToNegotiateName) { fprintf(stderr, "selfserv: Failed properly negotiate server name\n"); @@ -2725,22 +2834,22 @@ cleanup: } { - int i; - for (i=0; i<kt_kea_size; i++) { - if (cert[i]) { - CERT_DestroyCertificate(cert[i]); - } - if (privKey[i]) { - SECKEY_DestroyPrivateKey(privKey[i]); - } - } - for (i = 0;virtServerNameArray[i];i++) { + int i; + for (i = 0; i < kt_kea_size; i++) { + if (cert[i]) { + CERT_DestroyCertificate(cert[i]); + } + if (privKey[i]) { + SECKEY_DestroyPrivateKey(privKey[i]); + } + } + for (i = 0; virtServerNameArray[i]; i++) { PORT_Free(virtServerNameArray[i]); } } if (debugCache) { - nss_DumpCertificateCacheInfo(); + nss_DumpCertificateCacheInfo(); } if (nickName) { PORT_Free(nickName); @@ -2754,28 +2863,28 @@ cleanup: if (pwfile) { PORT_Free(pwfile); } - if (certPrefix && certPrefix != emptyString) { + if (certPrefix && certPrefix != emptyString) { PORT_Free(certPrefix); } - #ifndef NSS_DISABLE_ECC +#ifndef NSS_DISABLE_ECC if (ecNickName) { PORT_Free(ecNickName); } - #endif +#endif if (hasSidCache) { - SSL_ShutdownServerSessionIDCache(); + SSL_ShutdownServerSessionIDCache(); } if (certStatusArena) { - PORT_FreeArena(certStatusArena, PR_FALSE); + PORT_FreeArena(certStatusArena, PR_FALSE); } if (NSS_Shutdown() != SECSuccess) { - SECU_PrintError(progName, "NSS_Shutdown"); + SECU_PrintError(progName, "NSS_Shutdown"); if (loggerThread) { PR_JoinThread(loggerThread); } - PR_Cleanup(); - exit(1); + PR_Cleanup(); + exit(1); } PR_Cleanup(); printf("selfserv: normal termination\n"); |