Back to index

lightning-sunbird  0.9+nobinonly
Functions | Variables
vfyutil.c File Reference
#include "vfyserv.h"
#include "secerr.h"
#include "sslerr.h"
#include "nspr.h"
#include "secutil.h"

Go to the source code of this file.

Functions

char * myPasswd (PK11SlotInfo *info, PRBool retry, void *arg)
SECStatus myAuthCertificate (void *arg, PRFileDesc *socket, PRBool checksig, PRBool isServer)
SECStatus myBadCertHandler (void *arg, PRFileDesc *socket)
SECStatus myGetClientAuthData (void *arg, PRFileDesc *socket, struct CERTDistNamesStr *caNames, struct CERTCertificateStr **pRetCert, struct SECKEYPrivateKeyStr **pRetKey)
SECStatus myHandshakeCallback (PRFileDesc *socket, void *arg)
void disableAllSSLCiphers (void)
void errWarn (char *function)
void exitErr (char *function)
void printSecurityInfo (FILE *outfile, PRFileDesc *fd)
void thread_wrapper (void *arg)
SECStatus launch_thread (GlobalThreadMgr *threadMGR, startFn *startFunc, void *a, int b)
SECStatus reap_threads (GlobalThreadMgr *threadMGR)
void destroy_thread_data (GlobalThreadMgr *threadMGR)
void lockedVars_Init (lockedVars *lv)
void lockedVars_Destroy (lockedVars *lv)
void lockedVars_WaitForDone (lockedVars *lv)
int lockedVars_AddToCount (lockedVars *lv, int addend)

Variables

int ssl2CipherSuites []
int ssl3CipherSuites []

Function Documentation

Definition at line 554 of file vfyutil.c.

{
    PORT_Memset(threadMGR->threads, 0, sizeof(threadMGR->threads));

    if (threadMGR->threadEndQ) {
       PR_DestroyCondVar(threadMGR->threadEndQ);
       threadMGR->threadEndQ = NULL;
    }
    if (threadMGR->threadStartQ) {
       PR_DestroyCondVar(threadMGR->threadStartQ);
       threadMGR->threadStartQ = NULL;
    }
    if (threadMGR->threadLock) {
       PR_DestroyLock(threadMGR->threadLock);
       threadMGR->threadLock = NULL;
    }
}

Here is the call graph for this function:

Definition at line 347 of file vfyutil.c.

{
    const PRUint16 *cipherSuites = SSL_ImplementedCiphers;
    int             i            = SSL_NumImplementedCiphers;
    SECStatus       rv;

    /* disable all the SSL3 cipher suites */
    while (--i >= 0) {
       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);
       }
    }
}

Here is the call graph for this function:

void errWarn ( char *  function)

Definition at line 374 of file vfyutil.c.

{
    PRErrorCode  errorNumber = PR_GetError();
    const char * errorString = SECU_Strerror(errorNumber);

    fprintf(stderr, "Error in function %s: %d\n - %s\n",
                  function, errorNumber, errorString);
}

Here is the call graph for this function:

void exitErr ( char *  function)

Definition at line 384 of file vfyutil.c.

{
    errWarn(function);
    /* Exit gracefully. */
    /* ignoring return value of NSS_Shutdown as code exits with 1 anyway*/
    (void) NSS_Shutdown();
    PR_Cleanup();
    exit(1);
}

Here is the call graph for this function:

SECStatus launch_thread ( GlobalThreadMgr threadMGR,
startFn startFunc,
void a,
int  b 
)

Definition at line 455 of file vfyutil.c.

{
    perThread *slot;
    int        i;

    if (!threadMGR->threadStartQ) {
       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);
    }
    for (i = 0; i < threadMGR->numUsed; ++i) {
       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];
    }

    slot->a = a;
    slot->b = b;
    slot->startFunc = startFunc;

    threadMGR->index = i;

    slot->prThread = PR_CreateThread(PR_USER_THREAD,
                                 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;
    } 

    slot->inUse   = 1;
    slot->running = 1;
    ++(threadMGR->numRunning);
    PR_Unlock(threadMGR->threadLock);

    return SECSuccess;
}

Here is the call graph for this function:

int lockedVars_AddToCount ( lockedVars *  lv,
int  addend 
)

Definition at line 606 of file vfyutil.c.

{
    int rv;

    PR_Lock(lv->lock);
    rv = lv->count += addend;
    if (rv <= 0) {
       PR_NotifyCondVar(lv->condVar);
    }
    PR_Unlock(lv->lock);
    return rv;
}

Here is the call graph for this function:

void lockedVars_Destroy ( lockedVars *  lv)

Definition at line 586 of file vfyutil.c.

{
    PR_DestroyCondVar(lv->condVar);
    lv->condVar = NULL;

    PR_DestroyLock(lv->lock);
    lv->lock = NULL;
}

Here is the call graph for this function:

void lockedVars_Init ( lockedVars *  lv)

Definition at line 577 of file vfyutil.c.

{
    lv->count = 0;
    lv->waiters = 0;
    lv->lock  = PR_NewLock();
    lv->condVar = PR_NewCondVar(lv->lock);
}

Here is the call graph for this function:

void lockedVars_WaitForDone ( lockedVars *  lv)

Definition at line 596 of file vfyutil.c.

{
    PR_Lock(lv->lock);
    while (lv->count > 0) {
       PR_WaitCondVar(lv->condVar, PR_INTERVAL_NO_TIMEOUT);
    }
    PR_Unlock(lv->lock);
}

Here is the call graph for this function:

SECStatus myAuthCertificate ( void arg,
PRFileDesc socket,
PRBool  checksig,
PRBool  isServer 
)

Definition at line 117 of file vfyutil.c.

{

    SECCertificateUsage certUsage;
    CERTCertificate *   cert;
    void *              pinArg;
    char *              hostName;
    SECStatus           secStatus;

    if (!arg || !socket) {
       errWarn("myAuthCertificate");
       return SECFailure;
    }

    /* Define how the cert is being used based upon the isServer flag. */

    certUsage = isServer ? certificateUsageSSLClient : certificateUsageSSLServer;

    cert = SSL_PeerCertificate(socket);
       
    pinArg = SSL_RevealPinArg(socket);

    secStatus = CERT_VerifyCertificateNow((CERTCertDBHandle *)arg,
                               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;
    }

    /* Certificate is OK.  Since this is the client side of an SSL
     * connection, we need to verify that the name field in the cert
     * matches the desired hostname.  This is our defense against
     * man-in-the-middle attacks.
     */

    /* SSL_RevealURL returns a hostName, not an URL. */
    hostName = SSL_RevealURL(socket);

    if (hostName && hostName[0]) {
       secStatus = CERT_VerifyCertName(cert, hostName);
    } else {
       PR_SetError(SSL_ERROR_BAD_CERT_DOMAIN, 0);
       secStatus = SECFailure;
    }

    if (hostName)
       PR_Free(hostName);

    CERT_DestroyCertificate(cert);
    return secStatus;
}

Here is the call graph for this function:

SECStatus myBadCertHandler ( void arg,
PRFileDesc socket 
)

Definition at line 188 of file vfyutil.c.

{

    SECStatus secStatus = SECFailure;
    PRErrorCode      err;

    /* log invalid cert here */

    if (!arg) {
       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 */  
    /* 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;
    }

    fprintf(stderr, "Bad certificate: %d, %s\n", err, SECU_Strerror(err));

    return secStatus;
}

Here is the call graph for this function:

SECStatus myGetClientAuthData ( void arg,
PRFileDesc socket,
struct CERTDistNamesStr caNames,
struct CERTCertificateStr **  pRetCert,
struct SECKEYPrivateKeyStr **  pRetKey 
)

Definition at line 239 of file vfyutil.c.

{

    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);
           }
       }
    } 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);
       }
    }

    if (secStatus == SECSuccess) {
       *pRetCert = cert;
       *pRetKey  = privKey;
    }

    return secStatus;
}

Here is the call graph for this function:

SECStatus myHandshakeCallback ( PRFileDesc socket,
void arg 
)

Definition at line 333 of file vfyutil.c.

{
    fprintf(stderr,"Handshake Complete: SERVER CONFIGURED CORRECTLY\n");
    return SECSuccess;
}

Here is the call graph for this function:

char* myPasswd ( PK11SlotInfo *  info,
PRBool  retry,
void arg 
)

Definition at line 99 of file vfyutil.c.

{
    char * passwd = NULL;

    if ( (!retry) && arg ) {
       passwd = PORT_Strdup((char *)arg);
    }
    return passwd;
}

Here is the call graph for this function:

void printSecurityInfo ( FILE outfile,
PRFileDesc fd 
)

Definition at line 395 of file vfyutil.c.

{
    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;
    }

    result = SSL_SecurityStatus(fd, &op, &cp, &kp0, &kp1, &ip, &sp);
    if (result != SECSuccess)
       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);
    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);

}

Here is the call graph for this function:

Definition at line 515 of file vfyutil.c.

{
    perThread * slot;
    int                     i;

    if (!threadMGR->threadLock)
       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);
           }
       }
    }

    /* 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);
       }
    }
    PR_Unlock(threadMGR->threadLock);
    return SECSuccess;
}

Here is the call graph for this function:

void thread_wrapper ( void arg)

Definition at line 434 of file vfyutil.c.

{
    GlobalThreadMgr *threadMGR = (GlobalThreadMgr *)arg;
    perThread *slot = &threadMGR->threads[threadMGR->index];

    /* wait for parent to finish launching us before proceeding. */
    PR_Lock(threadMGR->threadLock);
    PR_Unlock(threadMGR->threadLock);

    slot->rv = (* slot->startFunc)(slot->a, slot->b);

    PR_Lock(threadMGR->threadLock);
    slot->running = rs_zombie;

    /* notify the thread exit handler. */
    PR_NotifyCondVar(threadMGR->threadEndQ);

    PR_Unlock(threadMGR->threadLock);
}

Here is the call graph for this function:


Variable Documentation