diff options
Diffstat (limited to 'nss/cmd/vfyserv/vfyutil.c')
-rw-r--r-- | nss/cmd/vfyserv/vfyutil.c | 507 |
1 files changed, 247 insertions, 260 deletions
diff --git a/nss/cmd/vfyserv/vfyutil.c b/nss/cmd/vfyserv/vfyutil.c index 686c7b1..2f1b532 100644 --- a/nss/cmd/vfyserv/vfyutil.c +++ b/nss/cmd/vfyserv/vfyutil.c @@ -8,60 +8,50 @@ #include "nspr.h" #include "secutil.h" - extern PRBool dumpChain; extern void dumpCertChain(CERTCertificate *, SECCertUsage); /* Declare SSL cipher suites. */ -int ssl2CipherSuites[] = { - SSL_EN_RC4_128_WITH_MD5, /* A */ - SSL_EN_RC4_128_EXPORT40_WITH_MD5, /* B */ - SSL_EN_RC2_128_CBC_WITH_MD5, /* C */ - SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */ - SSL_EN_DES_64_CBC_WITH_MD5, /* E */ - SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */ - 0 -}; - 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 */ + -1, /* TLS_RSA_EXPORT_WITH_RC4_40_MD5 * f */ + -1, /* TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 * g */ + -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA * h */ + TLS_RSA_WITH_NULL_MD5, /* i */ + -1, /* SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA * j */ + -1, /* SSL_RSA_FIPS_WITH_DES_CBC_SHA * k */ + -1, /* TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA * l */ + -1, /* 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 }; +int numSSL3CipherSuites = PR_ARRAY_SIZE(ssl3CipherSuites); /************************************************************************** -** +** ** SSL callback routines. ** **************************************************************************/ /* Function: char * myPasswd() - * + * * Purpose: This function is our custom password handler that is called by * SSL when retreiving private certs and keys from the database. Returns a * pointer to a string that with a password for the database. Password pointer @@ -70,10 +60,10 @@ int ssl3CipherSuites[] = { char * myPasswd(PK11SlotInfo *info, PRBool retry, void *arg) { - char * passwd = NULL; + char *passwd = NULL; - if ( (!retry) && arg ) { - passwd = PORT_Strdup((char *)arg); + if ((!retry) && arg) { + passwd = PORT_Strdup((char *)arg); } return passwd; } @@ -81,24 +71,24 @@ myPasswd(PK11SlotInfo *info, PRBool retry, void *arg) /* Function: SECStatus myAuthCertificate() * * Purpose: This function is our custom certificate authentication handler. - * - * Note: This implementation is essentially the same as the default + * + * Note: This implementation is essentially the same as the default * SSL_AuthCertificate(). */ -SECStatus -myAuthCertificate(void *arg, PRFileDesc *socket, - PRBool checksig, PRBool isServer) +SECStatus +myAuthCertificate(void *arg, PRFileDesc *socket, + PRBool checksig, PRBool isServer) { SECCertificateUsage certUsage; - CERTCertificate * cert; - void * pinArg; - char * hostName; - SECStatus secStatus; + CERTCertificate *cert; + void *pinArg; + char *hostName; + SECStatus secStatus; if (!arg || !socket) { - errWarn("myAuthCertificate"); - return SECFailure; + errWarn("myAuthCertificate"); + return SECFailure; } /* Define how the cert is being used based upon the isServer flag. */ @@ -106,26 +96,26 @@ myAuthCertificate(void *arg, PRFileDesc *socket, certUsage = isServer ? certificateUsageSSLClient : certificateUsageSSLServer; cert = SSL_PeerCertificate(socket); - + pinArg = SSL_RevealPinArg(socket); - + if (dumpChain == PR_TRUE) { dumpCertChain(cert, certUsage); } secStatus = CERT_VerifyCertificateNow((CERTCertDBHandle *)arg, - cert, - checksig, - certUsage, - pinArg, - NULL); + cert, + checksig, + certUsage, + pinArg, + NULL); /* If this is a server, we're finished. */ if (isServer || secStatus != SECSuccess) { - SECU_printCertProblems(stderr, (CERTCertDBHandle *)arg, cert, - checksig, certUsage, pinArg, PR_FALSE); - CERT_DestroyCertificate(cert); - return secStatus; + SECU_printCertProblems(stderr, (CERTCertDBHandle *)arg, cert, + checksig, certUsage, pinArg, PR_FALSE); + CERT_DestroyCertificate(cert); + return secStatus; } /* Certificate is OK. Since this is the client side of an SSL @@ -138,14 +128,14 @@ myAuthCertificate(void *arg, PRFileDesc *socket, hostName = SSL_RevealURL(socket); if (hostName && hostName[0]) { - secStatus = CERT_VerifyCertName(cert, hostName); + secStatus = CERT_VerifyCertName(cert, hostName); } else { - PR_SetError(SSL_ERROR_BAD_CERT_DOMAIN, 0); - secStatus = SECFailure; + PR_SetError(SSL_ERROR_BAD_CERT_DOMAIN, 0); + secStatus = SECFailure; } if (hostName) - PR_Free(hostName); + PR_Free(hostName); CERT_DestroyCertificate(cert); return secStatus; @@ -157,48 +147,48 @@ myAuthCertificate(void *arg, PRFileDesc *socket, * valid. We define a certain set of parameters that still cause the * certificate to be "valid" for this session, and return SECSuccess to cause * the server to continue processing the request when any of these conditions - * are met. Otherwise, SECFailure is return and the server rejects the + * are met. Otherwise, SECFailure is return and the server rejects the * request. */ -SECStatus -myBadCertHandler(void *arg, PRFileDesc *socket) +SECStatus +myBadCertHandler(void *arg, PRFileDesc *socket) { - SECStatus secStatus = SECFailure; - PRErrorCode err; + SECStatus secStatus = SECFailure; + PRErrorCode err; /* log invalid cert here */ if (!arg) { - return secStatus; + return secStatus; } *(PRErrorCode *)arg = err = PORT_GetError(); /* If any of the cases in the switch are met, then we will proceed */ - /* with the processing of the request anyway. Otherwise, the default */ + /* with the processing of the request anyway. Otherwise, the default */ /* case will be reached and we will reject the request. */ switch (err) { - case SEC_ERROR_INVALID_AVA: - case SEC_ERROR_INVALID_TIME: - case SEC_ERROR_BAD_SIGNATURE: - case SEC_ERROR_EXPIRED_CERTIFICATE: - case SEC_ERROR_UNKNOWN_ISSUER: - case SEC_ERROR_UNTRUSTED_CERT: - case SEC_ERROR_CERT_VALID: - case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: - case SEC_ERROR_CRL_EXPIRED: - case SEC_ERROR_CRL_BAD_SIGNATURE: - case SEC_ERROR_EXTENSION_VALUE_INVALID: - case SEC_ERROR_CA_CERT_INVALID: - case SEC_ERROR_CERT_USAGES_INVALID: - case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION: - secStatus = SECSuccess; - break; - default: - secStatus = SECFailure; - break; + case SEC_ERROR_INVALID_AVA: + case SEC_ERROR_INVALID_TIME: + case SEC_ERROR_BAD_SIGNATURE: + case SEC_ERROR_EXPIRED_CERTIFICATE: + case SEC_ERROR_UNKNOWN_ISSUER: + case SEC_ERROR_UNTRUSTED_CERT: + case SEC_ERROR_CERT_VALID: + case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: + case SEC_ERROR_CRL_EXPIRED: + case SEC_ERROR_CRL_BAD_SIGNATURE: + case SEC_ERROR_EXTENSION_VALUE_INVALID: + case SEC_ERROR_CA_CERT_INVALID: + case SEC_ERROR_CERT_USAGES_INVALID: + case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION: + secStatus = SECSuccess; + break; + default: + secStatus = SECFailure; + break; } fprintf(stderr, "Bad certificate: %d, %s\n", err, SECU_Strerror(err)); @@ -208,75 +198,75 @@ myBadCertHandler(void *arg, PRFileDesc *socket) /* Function: SECStatus ownGetClientAuthData() * - * Purpose: This callback is used by SSL to pull client certificate + * Purpose: This callback is used by SSL to pull client certificate * information upon server request. */ -SECStatus +SECStatus myGetClientAuthData(void *arg, PRFileDesc *socket, struct CERTDistNamesStr *caNames, struct CERTCertificateStr **pRetCert, - struct SECKEYPrivateKeyStr **pRetKey) + struct SECKEYPrivateKeyStr **pRetKey) { - CERTCertificate * cert; - SECKEYPrivateKey * privKey; - char * chosenNickName = (char *)arg; - void * proto_win = NULL; - SECStatus secStatus = SECFailure; + CERTCertificate *cert; + SECKEYPrivateKey *privKey; + char *chosenNickName = (char *)arg; + void *proto_win = NULL; + SECStatus secStatus = SECFailure; proto_win = SSL_RevealPinArg(socket); if (chosenNickName) { - cert = PK11_FindCertFromNickname(chosenNickName, proto_win); - if (cert) { - privKey = PK11_FindKeyByAnyCert(cert, proto_win); - if (privKey) { - secStatus = SECSuccess; - } else { - CERT_DestroyCertificate(cert); - } - } + cert = PK11_FindCertFromNickname(chosenNickName, proto_win); + if (cert) { + privKey = PK11_FindKeyByAnyCert(cert, proto_win); + if (privKey) { + secStatus = SECSuccess; + } else { + CERT_DestroyCertificate(cert); + } + } } else { /* no nickname given, automatically find the right cert */ - CERTCertNicknames *names; - int i; - - names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(), - SEC_CERT_NICKNAMES_USER, proto_win); - - if (names != NULL) { - for(i = 0; i < names->numnicknames; i++ ) { - - cert = PK11_FindCertFromNickname(names->nicknames[i], - proto_win); - if (!cert) { - continue; - } - - /* Only check unexpired certs */ - if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE) - != secCertTimeValid ) { - CERT_DestroyCertificate(cert); - continue; - } - - secStatus = NSS_CmpCertChainWCANames(cert, caNames); - if (secStatus == SECSuccess) { - privKey = PK11_FindKeyByAnyCert(cert, proto_win); - if (privKey) { - break; - } - secStatus = SECFailure; - } - CERT_DestroyCertificate(cert); - } /* for loop */ - CERT_FreeNicknames(names); - } + CERTCertNicknames *names; + int i; + + names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(), + SEC_CERT_NICKNAMES_USER, proto_win); + + if (names != NULL) { + for (i = 0; i < names->numnicknames; i++) { + + cert = PK11_FindCertFromNickname(names->nicknames[i], + proto_win); + if (!cert) { + continue; + } + + /* Only check unexpired certs */ + if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE) != + secCertTimeValid) { + CERT_DestroyCertificate(cert); + continue; + } + + secStatus = NSS_CmpCertChainWCANames(cert, caNames); + if (secStatus == SECSuccess) { + privKey = PK11_FindKeyByAnyCert(cert, proto_win); + if (privKey) { + break; + } + secStatus = SECFailure; + } + CERT_DestroyCertificate(cert); + } /* for loop */ + CERT_FreeNicknames(names); + } } if (secStatus == SECSuccess) { - *pRetCert = cert; - *pRetKey = privKey; + *pRetCert = cert; + *pRetKey = privKey; } return secStatus; @@ -287,7 +277,7 @@ myGetClientAuthData(void *arg, * Purpose: Called by SSL to inform application that the handshake is * complete. This function is mostly used on the server side of an SSL * connection, although it is provided for a client as well. - * Useful when a non-blocking SSL_ReHandshake or SSL_ResetHandshake + * Useful when a non-blocking SSL_ReHandshake or SSL_ResetHandshake * is used to initiate a handshake. * * A typical scenario would be: @@ -306,14 +296,13 @@ myGetClientAuthData(void *arg, * blocking sockets. */ void -myHandshakeCallback(PRFileDesc *socket, void *arg) +myHandshakeCallback(PRFileDesc *socket, void *arg) { - fprintf(stderr,"Handshake Complete: SERVER CONFIGURED CORRECTLY\n"); + fprintf(stderr, "Handshake Complete: SERVER CONFIGURED CORRECTLY\n"); } - /************************************************************************** -** +** ** Routines for disabling SSL ciphers. ** **************************************************************************/ @@ -322,25 +311,25 @@ void disableAllSSLCiphers(void) { const PRUint16 *cipherSuites = SSL_ImplementedCiphers; - int i = SSL_NumImplementedCiphers; - SECStatus rv; + int i = SSL_NumImplementedCiphers; + SECStatus rv; /* disable all the SSL3 cipher suites */ while (--i >= 0) { - PRUint16 suite = cipherSuites[i]; + PRUint16 suite = cipherSuites[i]; rv = SSL_CipherPrefSetDefault(suite, PR_FALSE); - if (rv != SECSuccess) { - fprintf(stderr, - "SSL_CipherPrefSetDefault didn't like value 0x%04x (i = %d)\n", - suite, i); - errWarn("SSL_CipherPrefSetDefault"); - exit(2); - } + if (rv != SECSuccess) { + fprintf(stderr, + "SSL_CipherPrefSetDefault didn't like value 0x%04x (i = %d)\n", + suite, i); + errWarn("SSL_CipherPrefSetDefault"); + exit(2); + } } } /************************************************************************** -** +** ** Error and information routines. ** **************************************************************************/ @@ -348,11 +337,11 @@ disableAllSSLCiphers(void) void errWarn(char *function) { - PRErrorCode errorNumber = PR_GetError(); - const char * errorString = SECU_Strerror(errorNumber); + PRErrorCode errorNumber = PR_GetError(); + const char *errorString = SECU_Strerror(errorNumber); fprintf(stderr, "Error in function %s: %d\n - %s\n", - function, errorNumber, errorString); + function, errorNumber, errorString); } void @@ -361,52 +350,51 @@ exitErr(char *function) errWarn(function); /* Exit gracefully. */ /* ignoring return value of NSS_Shutdown as code exits with 1 anyway*/ - (void) NSS_Shutdown(); + (void)NSS_Shutdown(); PR_Cleanup(); exit(1); } -void +void printSecurityInfo(FILE *outfile, PRFileDesc *fd) { - char * cp; /* bulk cipher name */ - char * ip; /* cert issuer DN */ - char * sp; /* cert subject DN */ - int op; /* High, Low, Off */ - int kp0; /* total key bits */ - int kp1; /* secret key bits */ - int result; - SSL3Statistics * ssl3stats = SSL_GetStatistics(); + char *cp; /* bulk cipher name */ + char *ip; /* cert issuer DN */ + char *sp; /* cert subject DN */ + int op; /* High, Low, Off */ + int kp0; /* total key bits */ + int kp1; /* secret key bits */ + int result; + SSL3Statistics *ssl3stats = SSL_GetStatistics(); if (!outfile) { - outfile = stdout; + outfile = stdout; } result = SSL_SecurityStatus(fd, &op, &cp, &kp0, &kp1, &ip, &sp); if (result != SECSuccess) - return; + return; fprintf(outfile, - " bulk cipher %s, %d secret key bits, %d key bits, status: %d\n" - " subject DN:\n %s\n" - " issuer DN:\n %s\n", cp, kp1, kp0, op, sp, ip); + " bulk cipher %s, %d secret key bits, %d key bits, status: %d\n" + " subject DN:\n %s\n" + " issuer DN:\n %s\n", + cp, kp1, kp0, op, sp, ip); PR_Free(cp); PR_Free(ip); PR_Free(sp); fprintf(outfile, - " %ld cache hits; %ld cache misses, %ld cache not reusable\n", - ssl3stats->hch_sid_cache_hits, ssl3stats->hch_sid_cache_misses, - ssl3stats->hch_sid_cache_not_ok); - + " %ld cache hits; %ld cache misses, %ld cache not reusable\n", + ssl3stats->hch_sid_cache_hits, ssl3stats->hch_sid_cache_misses, + ssl3stats->hch_sid_cache_not_ok); } - /************************************************************************** ** Begin thread management routines and data. **************************************************************************/ void -thread_wrapper(void * arg) +thread_wrapper(void *arg) { GlobalThreadMgr *threadMGR = (GlobalThreadMgr *)arg; perThread *slot = &threadMGR->threads[threadMGR->index]; @@ -415,7 +403,7 @@ thread_wrapper(void * arg) PR_Lock(threadMGR->threadLock); PR_Unlock(threadMGR->threadLock); - slot->rv = (* slot->startFunc)(slot->a, slot->b); + slot->rv = (*slot->startFunc)(slot->a, slot->b); PR_Lock(threadMGR->threadLock); slot->running = rs_zombie; @@ -428,37 +416,37 @@ thread_wrapper(void * arg) SECStatus launch_thread(GlobalThreadMgr *threadMGR, - startFn *startFunc, - void *a, - int b) + startFn *startFunc, + void *a, + int b) { perThread *slot; - int i; + int i; if (!threadMGR->threadStartQ) { - threadMGR->threadLock = PR_NewLock(); - threadMGR->threadStartQ = PR_NewCondVar(threadMGR->threadLock); - threadMGR->threadEndQ = PR_NewCondVar(threadMGR->threadLock); + threadMGR->threadLock = PR_NewLock(); + threadMGR->threadStartQ = PR_NewCondVar(threadMGR->threadLock); + threadMGR->threadEndQ = PR_NewCondVar(threadMGR->threadLock); } PR_Lock(threadMGR->threadLock); while (threadMGR->numRunning >= MAX_THREADS) { - PR_WaitCondVar(threadMGR->threadStartQ, PR_INTERVAL_NO_TIMEOUT); + PR_WaitCondVar(threadMGR->threadStartQ, PR_INTERVAL_NO_TIMEOUT); } for (i = 0; i < threadMGR->numUsed; ++i) { - slot = &threadMGR->threads[i]; - if (slot->running == rs_idle) - break; + slot = &threadMGR->threads[i]; + if (slot->running == rs_idle) + break; } if (i >= threadMGR->numUsed) { - if (i >= MAX_THREADS) { - /* something's really wrong here. */ - PORT_Assert(i < MAX_THREADS); - PR_Unlock(threadMGR->threadLock); - return SECFailure; - } - ++(threadMGR->numUsed); - PORT_Assert(threadMGR->numUsed == i + 1); - slot = &threadMGR->threads[i]; + if (i >= MAX_THREADS) { + /* something's really wrong here. */ + PORT_Assert(i < MAX_THREADS); + PR_Unlock(threadMGR->threadLock); + return SECFailure; + } + ++(threadMGR->numUsed); + PORT_Assert(threadMGR->numUsed == i + 1); + slot = &threadMGR->threads[i]; } slot->a = a; @@ -468,17 +456,17 @@ launch_thread(GlobalThreadMgr *threadMGR, threadMGR->index = i; slot->prThread = PR_CreateThread(PR_USER_THREAD, - thread_wrapper, threadMGR, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, 0); + thread_wrapper, threadMGR, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, 0); if (slot->prThread == NULL) { - PR_Unlock(threadMGR->threadLock); - printf("Failed to launch thread!\n"); - return SECFailure; - } + PR_Unlock(threadMGR->threadLock); + printf("Failed to launch thread!\n"); + return SECFailure; + } - slot->inUse = 1; + slot->inUse = 1; slot->running = 1; ++(threadMGR->numRunning); PR_Unlock(threadMGR->threadLock); @@ -486,40 +474,40 @@ launch_thread(GlobalThreadMgr *threadMGR, return SECSuccess; } -SECStatus +SECStatus reap_threads(GlobalThreadMgr *threadMGR) { - perThread * slot; - int i; + perThread *slot; + int i; if (!threadMGR->threadLock) - return SECSuccess; + return SECSuccess; PR_Lock(threadMGR->threadLock); while (threadMGR->numRunning > 0) { - PR_WaitCondVar(threadMGR->threadEndQ, PR_INTERVAL_NO_TIMEOUT); - for (i = 0; i < threadMGR->numUsed; ++i) { - slot = &threadMGR->threads[i]; - if (slot->running == rs_zombie) { - /* Handle cleanup of thread here. */ - - /* Now make sure the thread has ended OK. */ - PR_JoinThread(slot->prThread); - slot->running = rs_idle; - --threadMGR->numRunning; - - /* notify the thread launcher. */ - PR_NotifyCondVar(threadMGR->threadStartQ); - } - } + PR_WaitCondVar(threadMGR->threadEndQ, PR_INTERVAL_NO_TIMEOUT); + for (i = 0; i < threadMGR->numUsed; ++i) { + slot = &threadMGR->threads[i]; + if (slot->running == rs_zombie) { + /* Handle cleanup of thread here. */ + + /* Now make sure the thread has ended OK. */ + PR_JoinThread(slot->prThread); + slot->running = rs_idle; + --threadMGR->numRunning; + + /* notify the thread launcher. */ + PR_NotifyCondVar(threadMGR->threadStartQ); + } + } } /* Safety Sam sez: make sure count is right. */ for (i = 0; i < threadMGR->numUsed; ++i) { - slot = &threadMGR->threads[i]; - if (slot->running != rs_idle) { - fprintf(stderr, "Thread in slot %d is in state %d!\n", - i, slot->running); - } + slot = &threadMGR->threads[i]; + if (slot->running != rs_idle) { + fprintf(stderr, "Thread in slot %d is in state %d!\n", + i, slot->running); + } } PR_Unlock(threadMGR->threadLock); return SECSuccess; @@ -531,16 +519,16 @@ destroy_thread_data(GlobalThreadMgr *threadMGR) PORT_Memset(threadMGR->threads, 0, sizeof(threadMGR->threads)); if (threadMGR->threadEndQ) { - PR_DestroyCondVar(threadMGR->threadEndQ); - threadMGR->threadEndQ = NULL; + PR_DestroyCondVar(threadMGR->threadEndQ); + threadMGR->threadEndQ = NULL; } if (threadMGR->threadStartQ) { - PR_DestroyCondVar(threadMGR->threadStartQ); - threadMGR->threadStartQ = NULL; + PR_DestroyCondVar(threadMGR->threadStartQ); + threadMGR->threadStartQ = NULL; } if (threadMGR->threadLock) { - PR_DestroyLock(threadMGR->threadLock); - threadMGR->threadLock = NULL; + PR_DestroyLock(threadMGR->threadLock); + threadMGR->threadLock = NULL; } } @@ -548,17 +536,17 @@ destroy_thread_data(GlobalThreadMgr *threadMGR) ** End thread management routines. **************************************************************************/ -void -lockedVars_Init( lockedVars * lv) +void +lockedVars_Init(lockedVars *lv) { - lv->count = 0; + lv->count = 0; lv->waiters = 0; - lv->lock = PR_NewLock(); + lv->lock = PR_NewLock(); lv->condVar = PR_NewCondVar(lv->lock); } void -lockedVars_Destroy( lockedVars * lv) +lockedVars_Destroy(lockedVars *lv) { PR_DestroyCondVar(lv->condVar); lv->condVar = NULL; @@ -568,30 +556,29 @@ lockedVars_Destroy( lockedVars * lv) } void -lockedVars_WaitForDone(lockedVars * lv) +lockedVars_WaitForDone(lockedVars *lv) { PR_Lock(lv->lock); while (lv->count > 0) { - PR_WaitCondVar(lv->condVar, PR_INTERVAL_NO_TIMEOUT); + PR_WaitCondVar(lv->condVar, PR_INTERVAL_NO_TIMEOUT); } PR_Unlock(lv->lock); } -int /* returns count */ -lockedVars_AddToCount(lockedVars * lv, int addend) +int /* returns count */ + lockedVars_AddToCount(lockedVars *lv, int addend) { int rv; PR_Lock(lv->lock); rv = lv->count += addend; if (rv <= 0) { - PR_NotifyCondVar(lv->condVar); + PR_NotifyCondVar(lv->condVar); } PR_Unlock(lv->lock); return rv; } - /* * Dump cert chain in to cert.* files. This function is will * create collisions while dumping cert chains if called from @@ -611,20 +598,20 @@ dumpCertChain(CERTCertificate *cert, SECCertUsage usage) return; } - for(count = 0; count < (unsigned int)certList->len; count++) { + for (count = 0; count < (unsigned int)certList->len; count++) { char certFileName[16]; PRFileDesc *cfd; PR_snprintf(certFileName, sizeof certFileName, "cert.%03d", count); - cfd = PR_Open(certFileName, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, + cfd = PR_Open(certFileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0664); if (!cfd) { PR_fprintf(PR_STDOUT, "Error: couldn't save cert der in file '%s'\n", certFileName); } else { - PR_Write(cfd, certList->certs[count].data, certList->certs[count].len); + PR_Write(cfd, certList->certs[count].data, certList->certs[count].len); PR_Close(cfd); PR_fprintf(PR_STDOUT, "Cert file %s was created.\n", certFileName); } |