Beispiel #1
0
static void Help(void)
{
    PR_fprintf(err, "Usage: [-S] [-K <n>] [-h] <filename>\n");
    PR_fprintf(err, "\t-c   Nuber of iterations     (default: 10)\n");
    PR_fprintf(err, "\t-S   Sync the file           (default: FALSE)\n");
    PR_fprintf(err, "\t-K   Size of file (K bytes)  (default: 10)\n");
    PR_fprintf(err, "\t     Name of file to write   (default: /usr/tmp/sync.dat)\n");
    PR_fprintf(err, "\t-h   This message and nothing else\n");
}  /* Help */
Beispiel #2
0
/**************************************************************************
 *
 * G e n e r a t e S e l f S i g n e d O b j e c t S i g n i n g C e r t
 *														   		  *phew*^
 *
 */
static CERTCertificate*
GenerateSelfSignedObjectSigningCert(char *nickname, CERTCertDBHandle *db,
 	char *subject, unsigned long serial, int keysize, char *token)
{
    CERTCertificate * cert, *temp_cert;
    SECItem * derCert;
    CERTCertificateRequest * req;

    PK11SlotInfo * slot = NULL;
    SECKEYPrivateKey * privk = NULL;
    SECKEYPublicKey * pubk = NULL;

    if ( token ) {
	slot = PK11_FindSlotByName(token);
    } else {
	slot = PK11_GetInternalKeySlot();
    }

    if (slot == NULL) {
	PR_fprintf(errorFD, "Can't find PKCS11 slot %s\n",
	    token ? token : "");
	errorCount++;
	exit (ERRX);
    }

    if ( GenerateKeyPair(slot, &pubk, &privk, keysize) != SECSuccess) {
	FatalError("Error generating keypair.");
    }
    req = make_cert_request (subject, pubk);
    temp_cert = make_cert (req, serial, &req->subject);
    if (set_cert_type(temp_cert,
        NS_CERT_TYPE_OBJECT_SIGNING | NS_CERT_TYPE_OBJECT_SIGNING_CA)
         != SECSuccess) {
	FatalError("Unable to set cert type");
    }

    derCert = sign_cert (temp_cert, privk);
    cert = install_cert(db, derCert, nickname);
    if (ChangeTrustAttributes(db, cert, ",,uC") != SECSuccess) {
	FatalError("Unable to change trust on generated certificate");
    }

    /* !!! Free memory ? !!! */
    PK11_FreeSlot(slot);
    SECKEY_DestroyPrivateKey(privk);
    SECKEY_DestroyPublicKey(pubk);

    return cert;
}
Beispiel #3
0
PRStatus TimelineInit(void)
{
    char *timeStr;
    char *fileName;
    PRInt32 secs, msecs;
    PRFileDesc *fd;
    PRInt64 tmp1, tmp2;

    PRStatus status = PR_NewThreadPrivateIndex( &gTLSIndex, ThreadDestruct );
    NS_WARN_IF_FALSE(status==0, "TimelineService could not allocate TLS storage.");

    timeStr = PR_GetEnv("NS_TIMELINE_INIT_TIME");
#ifdef XP_MAC    
    initInterval = PR_IntervalNow();
#endif
    // NS_TIMELINE_INIT_TIME only makes sense for the main thread, so if it
    // exists, set it there.  If not, let normal thread management code take
    // care of setting the init time.
    if (timeStr != NULL && 2 == PR_sscanf(timeStr, "%d.%d", &secs, &msecs)) {
        PRTime &initTime = GetThisThreadData()->initTime;
        LL_MUL(tmp1, (PRInt64)secs, 1000000);
        LL_MUL(tmp2, (PRInt64)msecs, 1000);
        LL_ADD(initTime, tmp1, tmp2);
#ifdef XP_MAC
        initInterval -= PR_MicrosecondsToInterval(
            (PRUint32)(PR_Now() - initTime));
#endif
    }
    // Get the log file.
#ifdef XP_MAC
    fileName = "timeline.txt";
#else
    fileName = PR_GetEnv("NS_TIMELINE_LOG_FILE");
#endif
    if (fileName != NULL
        && (fd = PR_Open(fileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
                         0666)) != NULL) {
        timelineFD = fd;
        PR_fprintf(fd,
                   "NOTE: due to asynchrony, the indentation that you see does"
                   " not necessarily correspond to nesting in the code.\n\n");
    }

    // Runtime disable of timeline
    if (PR_GetEnv("NS_TIMELINE_ENABLE"))
        gTimelineDisabled = PR_FALSE;
    return PR_SUCCESS;
}
Beispiel #4
0
static void PR_CALLBACK Notified(void *arg)
{
    Shared *shared = (Shared*)arg;
    PRStatus status = PR_SUCCESS;
    while (PR_SUCCESS == status)
    {
        PR_Lock(shared->ml);
        while (shared->twiddle && (PR_SUCCESS == status))
            status = PR_WaitCondVar(shared->cv, PR_INTERVAL_NO_TIMEOUT);
		if (verbosity) PR_fprintf(debug_out, "+");
        shared->twiddle = PR_TRUE;
        shared->next->twiddle = PR_FALSE;
        PR_NotifyCondVar(shared->next->cv);
        PR_Unlock(shared->ml);
    }
}  /* Notified */
static void PrintProgress(PRIntn line)
{
    failed = failed || (should && !did);
    failed = failed || (!should && did);
    if (debug > 0)
    {
#if defined(WIN16)
        printf(
            "@ line %d destructor should%s have been called and was%s\n",
            line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT"));
#else    
        PR_fprintf(
            fout, "@ line %d destructor should%s have been called and was%s\n",
            line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT"));
#endif
    }
}  /* PrintProgress */
Beispiel #6
0
static void Help(void)
{
    debug_out = PR_STDOUT;

    PR_fprintf(
		debug_out, "Usage: >./switch [-c n] [-t n] [-d] [-v] [-G] [-C n]\n");
    PR_fprintf(
		debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS);
    PR_fprintf(
		debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS);
    PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n");
    PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n");
    PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n");
    PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n");
}  /* Help */
Beispiel #7
0
int Usage(void)
{
    PRFileDesc *pr_stderr = PR_STDERR;
    PR_fprintf (pr_stderr, "ocspresp runs an internal selftest for OCSP response creation");
    PR_fprintf (pr_stderr, "Usage:");
    PR_fprintf (pr_stderr,
                "\tocspresp <dbdir> <CA-nick> <EE-nick> [-p <pass>] [-f <file>]\n");
    PR_fprintf (pr_stderr,
                "\tdbdir:   Find security databases in \"dbdir\"\n");
    PR_fprintf (pr_stderr,
                "\tCA-nick: nickname of a trusted CA certificate with private key\n");
    PR_fprintf (pr_stderr,
                "\tEE-nick: nickname of a entity cert issued by CA\n");
    PR_fprintf (pr_stderr,
                "\t-p:      a password for db\n");
    PR_fprintf (pr_stderr,
                "\t-f:      a filename containing the password for db\n");
    return -1;
}
Beispiel #8
0
/************************************************************************
 *
 * g e t F l a g s F r o m S t r i n g
 *
 * Parses a mechanism list passed on the command line and converts it
 * to an unsigned long bitmask.
 * string is a colon-separated string of constants
 * array is an array of MaskStrings.
 * elements is the number of elements in array.
 */
static unsigned long
getFlagsFromString(char *string, const MaskString array[], int elements)
{
    unsigned long ret = 0;
    short i = 0;
    char *cp;
    char *buf;
    char *end;

    if (!string || !string[0]) {
        return ret;
    }

    /* Make a temporary copy of the string */
    buf = PR_Malloc(strlen(string) + 1);
    if (!buf) {
        out_of_memory();
    }
    strcpy(buf, string);

    /* Look at each element of the list passed in */
    for (cp = buf; cp && *cp; cp = (end ? end + 1 : NULL)) {
        /* Look at the string up to the next colon */
        end = strchr(cp, ':');
        if (end) {
            *end = '\0';
        }

        /* Find which element this is */
        for (i = 0; i < elements; i++) {
            if (!PORT_Strcasecmp(cp, array[i].name)) {
                break;
            }
        }
        if (i == elements) {
            /* Skip a bogus string, but print a warning message */
            PR_fprintf(PR_STDERR, errStrings[INVALID_CONSTANT_ERR], cp);
            continue;
        }
        ret |= array[i].mask;
    }

    PR_Free(buf);
    return ret;
}
Beispiel #9
0
static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv)
{
    Overlay_i si;
    Overlay_u ui;
    PLOptStatus os;
    PRBool bsi = PR_FALSE, bui = PR_FALSE;
    PLOptState *opt = PL_CreateOptState(argc, argv, "hi:u:");
    err = PR_GetSpecialFD(PR_StandardError);

    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
        if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 'i':  /* signed integer */
            si.i = (PRInt32)atoi(opt->value);
            bsi = PR_TRUE;
            break;
        case 'u':  /* unsigned */
            ui.i = (PRUint32)atoi(opt->value);
            bui = PR_TRUE;
            break;
        case 'h':  /* user wants some guidance */
         default:
            Help();  /* so give him an earful */
            return 2;  /* but not a lot else */
        }
    }
    PL_DestroyOptState(opt);

#if defined(HAVE_LONG_LONG)
    PR_fprintf(err, "We have long long\n");
#else
    PR_fprintf(err, "We don't have long long\n");
#endif

    if (bsi)
    {
        PR_fprintf(err, "Converting %ld: ", si.i);
        LL_I2L(si.l, si.i);
        PR_fprintf(err, "%lld\n", si.l);
    }

    if (bui)
    {
        PR_fprintf(err, "Converting %lu: ", ui.i);
        LL_I2L(ui.l, ui.i);
        PR_fprintf(err, "%llu\n", ui.l);
    }
    return 0;

}  /* main */
Beispiel #10
0
/*
 *  j a r _ f i n d _ k e y _ t y p e
 * 
 *  Determine the key type for a given cert, which 
 * should be rsaKey or dsaKey. Any error return 0.
 *
 */
static int	
jar_find_key_type (CERTCertificate *cert)
{
    SECKEYPrivateKey * privk = NULL;
    KeyType keyType;

    /* determine its type */
    privk = PK11_FindKeyByAnyCert (cert, &pwdata);
    if (privk == NULL) {
	PR_fprintf(errorFD, "warning - can't find private key for this cert\n");
	warningCount++;
	return 0;
    }

    keyType = privk->keyType;
    SECKEY_DestroyPrivateKey (privk);
    return keyType;
}
Beispiel #11
0
/*
 * Prints the contents of a PRHostEnt structure
 */
void PrintHostent(const PRHostEnt *he)
{
    int i;
    int j;

    PR_fprintf(outFile, "h_name: %s\n", he->h_name);
    for (i = 0; he->h_aliases[i]; i++) {
        PR_fprintf(outFile, "h_aliases[%d]: %s\n", i, he->h_aliases[i]);
    }
    PR_fprintf(outFile, "h_addrtype: %d\n", he->h_addrtype);
    PR_fprintf(outFile, "h_length: %d\n", he->h_length);
    for (i = 0; he->h_addr_list[i]; i++) {
        PR_fprintf(outFile, "h_addr_list[%d]: ", i);
        for (j = 0; j < he->h_length; j++) {
            if (j != 0) PR_fprintf(outFile, ".");
            PR_fprintf(outFile, "%u", (unsigned char)he->h_addr_list[i][j]);
        }
        PR_fprintf(outFile, "\n");
    }
}
static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
{
	PLOptStatus os;
  	PLOptState *opt = PL_CreateOptState(argc, argv, "dhlmc");
	PRBool locks = PR_FALSE, monitors = PR_FALSE, cmonitors = PR_FALSE;

    err = PR_GetSpecialFD(PR_StandardError);

	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
		if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 'd':  /* debug mode (noop) */
            break;
        case 'l':  /* locks */
			locks = PR_TRUE;
            break;
        case 'm':  /* monitors */
			monitors = PR_TRUE;
            break;
        case 'c':  /* cached monitors */
			cmonitors = PR_TRUE;
            break;
        case 'h':  /* needs guidance */
         default:
            Help();
            return 2;
        }
    }
	PL_DestroyOptState(opt);

    ml = PR_NewLock();
    if (locks) T1Lock();
    if (monitors) T1Mon();
    if (cmonitors) T1CMon();

    PR_DestroyLock(ml);

    PR_fprintf(err, "Done!\n");    
    return 0;
}  /* main */
Beispiel #13
0
static PRUint32 ContentiousMonitor(PRUint32 loops)
{
    PRStatus status;
    PRThread *thread = NULL;
    MonitorContentious_t * contention;
    PRIntervalTime rv, overhead, timein = PR_IntervalNow();

    contention = PR_NEWZAP(MonitorContentious_t);
    contention->loops = loops;
    contention->overhead = 0;
    contention->ml = PR_NewMonitor();
    contention->interval = contention_interval;
    thread = PR_CreateThread(
        PR_USER_THREAD, MonitorContender, contention,
        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
    PR_ASSERT(thread != NULL);

    overhead = PR_IntervalNow() - timein;

    while (contention->loops-- > 0)
    {
        PR_EnterMonitor(contention->ml);
        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
        contention->contentious+= 1;
        contention->overhead += contention->interval;
        PR_Sleep(contention->interval);
        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml);
        PR_ExitMonitor(contention->ml);
    }

    timein = PR_IntervalNow();
    status = PR_JoinThread(thread);
    PR_DestroyMonitor(contention->ml);
    overhead += (PR_IntervalNow() - timein);
    rv = overhead + contention->overhead;
    if (verbosity)
        PR_fprintf(
            std_err, "Access ratio: %u to %u\n",
            contention->contentious, contention->contender);
    PR_Free(contention);
    return rv;
}  /* ContentiousMonitor */
static void TestNowOverhead(void)
{
    PRTime timeout, timein;
    PRInt32 overhead, loops = 1000000;
    PRInt64 elapsed, per_call, ten23rd, ten26th;

    LL_I2L(ten23rd, 1000);
    LL_I2L(ten26th, 1000000);

    timein = PR_Now();
    while (--loops > 0)
        timeout = PR_Now();

    LL_SUB(elapsed, timeout, timein);
    LL_MUL(elapsed, elapsed, ten23rd);
    LL_DIV(per_call, elapsed, ten26th);
    LL_L2I(overhead, per_call);
    PR_fprintf(
        output, "Overhead of 'PR_Now()' is %u nsecs\n\n", overhead);
}  /* TestNowOverhead */
Beispiel #15
0
static PRInt16 PR_CALLBACK MyPoll(
    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
{
    PRInt16 my_flags, new_flags;
    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
    if (0 != (PR_POLL_READ & in_flags))
    {
        /* client thinks he's reading */
        switch (mine->rcvstate)
        {
            case rcv_send_credit:
                my_flags = (in_flags & ~PR_POLL_READ) | PR_POLL_WRITE;
                break;
            case rcv_data:
            case rcv_get_debit:
                my_flags = in_flags;
            default: break;
        }
    }
    else if (0 != (PR_POLL_WRITE & in_flags))
    {
        /* client thinks he's writing */
        switch (mine->xmtstate)
        {
            case xmt_recv_credit:
                my_flags = (in_flags & ~PR_POLL_WRITE) | PR_POLL_READ;
                break;
            case xmt_send_debit:
            case xmt_data:
                my_flags = in_flags;
            default: break;
        }
    }
    else PR_NOT_REACHED("How'd I get here?");
    new_flags = (fd->lower->methods->poll)(fd->lower, my_flags, out_flags);
    if (verbosity > chatty)
        PR_fprintf(
            logFile, "Poll [i: 0x%x, m: 0x%x, o: 0x%x, n: 0x%x]\n",
            in_flags, my_flags, *out_flags, new_flags);
    return new_flags;
}  /* MyPoll */
static PRBool
MakeConfFile(const char *regfile, const nsCString &greHome,
             const GREProperty *aProperties, PRUint32 aPropertiesLen)
{
  // If the file exists, don't create it again!
  if (access(regfile, R_OK) == 0)
    return PR_FALSE;

  PRBool ok = PR_TRUE;

  { // scope "fd" so that we can delete the file if something goes wrong
    AutoFDClose fd = PR_Open(regfile, PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE,
                             0664);
    if (!fd)
      return PR_FALSE;

    static const char kHeader[] =
      "# Registration file generated by xulrunner. Do not edit.\n\n"
      "[" GRE_BUILD_ID "]\n"
      "GRE_PATH=";

    if (PR_Write(fd, kHeader, sizeof(kHeader) - 1) != sizeof(kHeader) - 1)
      ok = PR_FALSE;

    if (PR_Write(fd, greHome.get(), greHome.Length()) != greHome.Length())
      ok = PR_FALSE;

    for (PRUint32 i = 0; i < aPropertiesLen; ++i) {
      if (PR_fprintf(fd, "\n%s=%s",
                     aProperties[i].property, aProperties[i].value) <= 0)
        ok = PR_FALSE;
    }

    PR_Write(fd, "\n", 1);
  }

  if (!ok)
    PR_Delete(regfile);

  return ok;
}
xpti_InterfaceWriter(PLDHashTable *table, PLDHashEntryHdr *hdr,
                     PRUint32 number, void *arg)
{
    xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value;
    PRFileDesc* fd = (PRFileDesc*)  arg;

    char iidStr[NSID_LENGTH];
    entry->GetTheIID()->ToProvidedString(iidStr);

    const xptiTypelib& typelib = entry->GetTypelibRecord();

    PRBool success =  !!PR_fprintf(fd, "%d,%s,%s,%d,%d,%d\n",
                                   (int) number,
                                   entry->GetTheName(),
                                   iidStr,
                                   (int) typelib.GetFileIndex(),
                                   (int) (typelib.IsZip() ?
                                          typelib.GetZipItemIndex() : -1),
                                   (int) entry->GetScriptableFlag());

    return success ? PL_DHASH_NEXT : PL_DHASH_STOP;
}
Beispiel #18
0
/*
 *  m a n i f e s t o _ x p i _ f n
 *
 *  Called by pointer from SignArchive(), once for
 *  each file within the directory. This function
 *  is only used for adding to XPI compatible archive
 *
 */
static int	manifesto_xpi_fn 
(char *relpath, char *basedir, char *reldir, char *filename, void *arg)
{
    char	fullname [FNSIZE];

    if (verbosity >= 0) {
	PR_fprintf(outputFD, "--> %s\n", relpath);
    }

    /* extension matching */
    if (extensionsGiven) {
	char	*ext = PL_strrchr(relpath, '.');
	if (!ext) 
	    return 0;
	if (!PL_HashTableLookup(extensions, ext)) 
	    return 0;
    }
    sprintf (fullname, "%s/%s", basedir, relpath);
    JzipAdd(fullname, relpath, zipfile, compression_level);

    return 0;
}
Beispiel #19
0
static void
long_usage (char *program_name)
{
    PRFileDesc *pr_stderr;

    pr_stderr = PR_STDERR;
    synopsis (program_name);
    PR_fprintf (pr_stderr, "\nDecode encrypted passwords (and other data).\n");
    PR_fprintf (pr_stderr,
                "This program reads in standard configuration files looking\n"
                "for base 64 encoded data. Data that looks like it's base 64 encode\n"
                "is decoded an passed to the NSS SDR code. If the decode and decrypt\n"
                "is successful, then decrypted data is outputted in place of the\n"
                "original base 64 data. If the decode or decrypt fails, the original\n"
                "data is written and the reason for failure is logged to the \n"
                "optional logfile.\n");
    PR_fprintf (pr_stderr,
                "  %-13s Read stream including encrypted data from "
                "\"read_file\"\n",
                "-i read_file");
    PR_fprintf (pr_stderr,
                "  %-13s Write results to \"write_file\"\n",
                "-o write_file");
    PR_fprintf (pr_stderr,
                "  %-13s Find security databases in \"dbdir\"\n",
                "-d dbdir");
    PR_fprintf (pr_stderr,
                "  %-13s Log failed decrypt/decode attempts to \"log_file\"\n",
                "-l log_file");
    PR_fprintf (pr_stderr,
                "  %-13s Token password\n",
                "-p pwd");
    PR_fprintf (pr_stderr,
                "  %-13s Password file\n",
                "-f pwfile");
}
Beispiel #20
0
/******************************************************************
 *
 * m a k e _ c e r t _ r e q u e s t
 */
static CERTCertificateRequest*
make_cert_request(char *subject, SECKEYPublicKey *pubk)
{
    CERTName * subj;
    CERTSubjectPublicKeyInfo * spki;

    CERTCertificateRequest * req;

    /* Create info about public key */
    spki = SECKEY_CreateSubjectPublicKeyInfo(pubk);
    if (!spki) {
	SECU_PrintError(progName, "unable to create subject public key");
	exit (ERRX);
    }

    subj = CERT_AsciiToName (subject);
    if (subj == NULL) {
	FatalError("Invalid data in certificate description");
    }

    /* Generate certificate request */
    req = CERT_CreateCertificateRequest(subj, spki, 0);
    if (!req) {
	SECU_PrintError(progName, "unable to make certificate request");
	exit (ERRX);
    }

    SECKEY_DestroySubjectPublicKeyInfo(spki);
    CERT_DestroyName(subj);

    if (verbosity >= 0) {
	PR_fprintf(outputFD, "certificate request generated\n");
    }

    return req;
}
Beispiel #21
0
Error
RawAddModule(char *dbmodulespec, char *modulespec)
{
    SECMODModule *module;
    SECMODModule *dbmodule;

    dbmodule = SECMOD_LoadModule(dbmodulespec, NULL, PR_TRUE);
    if (dbmodule == NULL) {
        /* handle error */
        return NO_SUCH_MODULE_ERR;
    }

    module = SECMOD_LoadModule(modulespec, dbmodule, PR_FALSE);
    if (module == NULL) {
        /* handle error */
        return NO_SUCH_MODULE_ERR;
    }

    if (SECMOD_UpdateModule(module) != SECSuccess) {
        PR_fprintf(PR_STDERR, errStrings[UPDATE_MOD_FAILED_ERR], modulespec);
        return UPDATE_MOD_FAILED_ERR;
    }
    return SUCCESS;
}
Beispiel #22
0
static void
long_usage (char *program_name)
{
    synopsis (program_name);
    PR_fprintf (pr_stderr, "\nSecret Decoder Test:\n");
    PR_fprintf (pr_stderr,
		"  %-13s Read encrypted data from \"file\"\n",
		"-i file");
    PR_fprintf (pr_stderr,
		"  %-13s Write newly generated encrypted data to \"file\"\n",
		"-o file");
    PR_fprintf (pr_stderr,
		"  %-13s Use \"text\" as the plaintext for encryption and verification\n",
		"-t text");
    PR_fprintf (pr_stderr,
		"  %-13s Find security databases in \"dbdir\"\n",
		"-d dbdir");
    PR_fprintf (pr_stderr,
		"  %-13s read the password from \"pwfile\"\n",
		"-f pwfile");
    PR_fprintf (pr_stderr,
		"  %-13s supply \"password\" on the command line\n",
		"-p password");
}
Beispiel #23
0
int main(int argc, char **argv)
{
    CERTCertDBHandle *certHandle;
    PRFileDesc *inFile;
    PRFileDesc *inCrlInitFile = NULL;
    int generateCRL;
    int modifyCRL;
    int listCRL;
    int importCRL;
    int showFileCRL;
    int deleteCRL;
    int rv;
    char *nickName;
    char *url;
    char *dbPrefix = "";
    char *alg = NULL;
    char *outFile = NULL;
    char *slotName = NULL;
    int ascii = 0;
    int crlType;
    PLOptState *optstate;
    PLOptStatus status;
    SECStatus secstatus;
    PRInt32 decodeOptions = CRL_DECODE_DEFAULT_OPTIONS;
    PRInt32 importOptions = CRL_IMPORT_DEFAULT_OPTIONS;
    PRBool quiet = PR_FALSE;
    PRBool test = PR_FALSE;
    PRBool erase = PR_FALSE;
    PRInt32 i = 0;
    PRInt32 iterations = 1;
    PRBool readonly = PR_FALSE;

    secuPWData  pwdata          = { PW_NONE, 0 };

    progName = strrchr(argv[0], '/');
    progName = progName ? progName+1 : argv[0];

    rv = 0;
    deleteCRL = importCRL = listCRL = generateCRL = modifyCRL = showFileCRL = 0;
    inFile = NULL;
    nickName = url = NULL;
    certHandle = NULL;
    crlType = SEC_CRL_TYPE;
    /*
     * Parse command line arguments
     */
    optstate = PL_CreateOptState(argc, argv, "sqBCDGILMSTEP:f:d:i:h:n:p:t:u:r:aZ:o:c:");
    while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
	switch (optstate->option) {
	  case '?':
	    Usage(progName);
	    break;

          case 'T':
            test = PR_TRUE;
            break;

          case 'E':
            erase = PR_TRUE;
            break;

	  case 'B':
            importOptions |= CRL_IMPORT_BYPASS_CHECKS;
            break;

	  case 'G':
	    generateCRL = 1;
	    break;

          case 'M':
            modifyCRL = 1;
            break;

	  case 'D':
	      deleteCRL = 1;
	      break;

	  case 'I':
	      importCRL = 1;
	      break;
	      
	  case 'S':
	      showFileCRL = 1;
	      break;
	           
	  case 'C':
	  case 'L':
	      listCRL = 1;
	      break;

	  case 'P':
 	    dbPrefix = strdup(optstate->value);
 	    break;
              
	  case 'Z':
              alg = strdup(optstate->value);
              break;
              
	  case 'a':
	      ascii = 1;
	      break;

	  case 'c':
              inCrlInitFile = PR_Open(optstate->value, PR_RDONLY, 0);
              if (!inCrlInitFile) {
                  PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for reading\n",
                             progName, optstate->value);
                  PL_DestroyOptState(optstate);
                  return -1;
              }
              break;
	    
	  case 'd':
              SECU_ConfigDirectory(optstate->value);
              break;

	  case 'f':
	      pwdata.source = PW_FROMFILE;
	      pwdata.data = strdup(optstate->value);
	      break;

	  case 'h':
              slotName = strdup(optstate->value);
              break;

	  case 'i':
	    inFile = PR_Open(optstate->value, PR_RDONLY, 0);
	    if (!inFile) {
		PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for reading\n",
			progName, optstate->value);
		PL_DestroyOptState(optstate);
		return -1;
	    }
	    break;
	    
	  case 'n':
	    nickName = strdup(optstate->value);
	    break;

	  case 'o':
	    outFile = strdup(optstate->value);
	    break;
	    
	  case 'p':
	    decodeOptions |= CRL_DECODE_SKIP_ENTRIES;
	    break;

	  case 'r': {
	    const char* str = optstate->value;
	    if (str && atoi(str)>0)
		iterations = atoi(str);
	    }
	    break;
	    
	  case 't': {
	    crlType = atoi(optstate->value);
	    if (crlType != SEC_CRL_TYPE && crlType != SEC_KRL_TYPE) {
		PR_fprintf(PR_STDERR, "%s: invalid crl type\n", progName);
		PL_DestroyOptState(optstate);
		return -1;
	    }
	    break;

	  case 'q':
            quiet = PR_TRUE;
	    break;

	  case 'w':
	      pwdata.source = PW_PLAINTEXT;
	      pwdata.data = strdup(optstate->value);
	      break;

	  case 'u':
	    url = strdup(optstate->value);
	    break;

          }
	}
    }
    PL_DestroyOptState(optstate);

    if (deleteCRL && !nickName) Usage (progName);
    if (importCRL && !inFile) Usage (progName);
    if (showFileCRL && !inFile) Usage (progName);
    if ((generateCRL && !nickName) ||
        (modifyCRL && !inFile && !nickName)) Usage (progName);
    if (!(listCRL || deleteCRL || importCRL || showFileCRL || generateCRL ||
	  modifyCRL || test || erase)) Usage (progName);

    if (listCRL || showFileCRL) {
        readonly = PR_TRUE;
    }
    
    PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);

    PK11_SetPasswordFunc(SECU_GetModulePassword);

    if (showFileCRL) {
	NSS_NoDB_Init(NULL);
    }
    else {
	secstatus = NSS_Initialize(SECU_ConfigDirectory(NULL), dbPrefix, dbPrefix,
				"secmod.db", readonly ? NSS_INIT_READONLY : 0);
	if (secstatus != SECSuccess) {
	    SECU_PrintPRandOSError(progName);
	    return -1;
	}
    }
    
    SECU_RegisterDynamicOids();

    certHandle = CERT_GetDefaultCertDB();
    if (certHandle == NULL) {
	SECU_PrintError(progName, "unable to open the cert db");	    	
	/*ignoring return value of NSS_Shutdown() as code returns -1*/
	(void) NSS_Shutdown();
	return (-1);
    }

    CRLGEN_InitCrlGenParserLock();

    for (i=0; i<iterations; i++) {
	/* Read in the private key info */
	if (deleteCRL) 
	    DeleteCRL (certHandle, nickName, crlType);
	else if (listCRL) {
	    rv = ListCRL (certHandle, nickName, crlType);
	}
	else if (importCRL) {
	    rv = ImportCRL (certHandle, url, crlType, inFile, importOptions,
			    decodeOptions, &pwdata);
	}
	else if (showFileCRL) {
	    rv = DumpCRL (inFile);
	} else if (generateCRL || modifyCRL) {
	    if (!inCrlInitFile)
		inCrlInitFile = PR_STDIN;
	    rv = GenerateCRL (certHandle, nickName, inCrlInitFile,
			      inFile, outFile, ascii,  slotName,
			      importOptions, alg, quiet,
			      decodeOptions, url, &pwdata,
			      modifyCRL);
	}
	else if (erase) {
	    /* list and delete all CRLs */
	    ListCRLNames (certHandle, crlType, PR_TRUE);
	}
#ifdef DEBUG
	else if (test) {
	    /* list and delete all CRLs */
	    ListCRLNames (certHandle, crlType, PR_TRUE);
	    /* list CRLs */
	    ListCRLNames (certHandle, crlType, PR_FALSE);
	    /* import CRL as a blob */
	    rv = ImportCRL (certHandle, url, crlType, inFile, importOptions,
			    decodeOptions, &pwdata);
	    /* list CRLs */
	    ListCRLNames (certHandle, crlType, PR_FALSE);
	}
#endif    
    }

    CRLGEN_DestroyCrlGenParserLock();

    if (NSS_Shutdown() != SECSuccess) {
        rv = SECFailure;
    }

    return (rv != SECSuccess);
}
Beispiel #24
0
int
main (int argc, char **argv)
{
    int		 retval;
    PRFileDesc	*in_file;
    FILE	*out_file;	/* not PRFileDesc until SECU accepts it */
    int		 crequest, dresponse;
    int		 prequest, presponse;
    int		 ccert, vcert;
    const char	*db_dir, *date_str, *cert_usage_str, *name;
    const char	*responder_name, *responder_url, *signer_name;
    PRBool	 add_acceptable_responses, add_service_locator;
    SECItem	*data = NULL;
    PLOptState	*optstate;
    SECStatus	 rv;
    CERTCertDBHandle *handle = NULL;
    SECCertUsage cert_usage;
    PRTime	 verify_time;
    CERTCertificate *cert = NULL;
    PRBool ascii = PR_FALSE;

    retval = -1;		/* what we return/exit with on error */

    program_name = PL_strrchr(argv[0], '/');
    program_name = program_name ? (program_name + 1) : argv[0];

    in_file = PR_STDIN;
    out_file = stdout;

    crequest = 0;
    dresponse = 0;
    prequest = 0;
    presponse = 0;
    ccert = 0;
    vcert = 0;

    db_dir = NULL;
    date_str = NULL;
    cert_usage_str = NULL;
    name = NULL;
    responder_name = NULL;
    responder_url = NULL;
    signer_name = NULL;

    add_acceptable_responses = PR_FALSE;
    add_service_locator = PR_FALSE;

    optstate = PL_CreateOptState (argc, argv, "AHLPR:S:V:d:l:pr:s:t:u:w:");
    if (optstate == NULL) {
	SECU_PrintError (program_name, "PL_CreateOptState failed");
	return retval;
    }

    while (PL_GetNextOpt (optstate) == PL_OPT_OK) {
	switch (optstate->option) {
	  case '?':
	    short_usage (program_name);
	    return retval;

	  case 'A':
	    add_acceptable_responses = PR_TRUE;
	    break;

	  case 'H':
	    long_usage (program_name);
	    return retval;

	  case 'L':
	    add_service_locator = PR_TRUE;
	    break;

	  case 'P':
	    presponse = 1;
	    break;

	  case 'R':
	    dresponse = 1;
	    name = optstate->value;
	    break;

	  case 'S':
	    ccert = 1;
	    name = optstate->value;
	    break;

	  case 'V':
	    vcert = 1;
	    name = optstate->value;
	    break;

	  case 'a':
	    ascii = PR_TRUE;
	    break;

	  case 'd':
	    db_dir = optstate->value;
	    break;

	  case 'l':
	    responder_url = optstate->value;
	    break;

	  case 'p':
	    prequest = 1;
	    break;

	  case 'r':
	    crequest = 1;
	    name = optstate->value;
	    break;

	  case 's':
	    signer_name = optstate->value;
	    break;

	  case 't':
	    responder_name = optstate->value;
	    break;

	  case 'u':
	    cert_usage_str = optstate->value;
	    break;

	  case 'w':
	    date_str = optstate->value;
	    break;
	}
    }

    PL_DestroyOptState(optstate);

    if ((crequest + dresponse + prequest + presponse + ccert + vcert) != 1) {
	PR_fprintf (PR_STDERR, "%s: must specify exactly one command\n\n",
		    program_name);
	short_usage (program_name);
	return retval;
    }

    if (vcert) {
	if (cert_usage_str == NULL) {
	    PR_fprintf (PR_STDERR, "%s: verification requires cert usage\n\n",
			program_name);
	    short_usage (program_name);
	    return retval;
	}

	rv = cert_usage_from_char (cert_usage_str, &cert_usage);
	if (rv != SECSuccess) {
	    PR_fprintf (PR_STDERR, "%s: invalid cert usage (\"%s\")\n\n",
			program_name, cert_usage_str);
	    long_usage (program_name);
	    return retval;
	}
    }

    if (ccert + vcert) {
	if (responder_url != NULL || responder_name != NULL) {
	    /*
	     * To do a full status check, both the URL and the cert name
	     * of the responder must be specified if either one is.
	     */
	    if (responder_url == NULL || responder_name == NULL) {
		if (responder_url == NULL)
		    PR_fprintf (PR_STDERR,
				"%s: must also specify responder location\n\n",
				program_name);
		else
		    PR_fprintf (PR_STDERR,
				"%s: must also specify responder name\n\n",
				program_name);
		short_usage (program_name);
		return retval;
	    }
	}

	if (date_str != NULL) {
	    rv = DER_AsciiToTime (&verify_time, (char *) date_str);
	    if (rv != SECSuccess) {
		SECU_PrintError (program_name, "error converting time string");
		PR_fprintf (PR_STDERR, "\n");
		long_usage (program_name);
		return retval;
	    }
	} else {
	    verify_time = PR_Now();
	}
    }

    retval = -2;		/* errors change from usage to runtime */

    /*
     * Initialize the NSPR and Security libraries.
     */
    PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
    db_dir = SECU_ConfigDirectory (db_dir);
    rv = NSS_Init (db_dir);
    if (rv != SECSuccess) {
	SECU_PrintError (program_name, "NSS_Init failed");
	goto prdone;
    }
    SECU_RegisterDynamicOids();

    if (prequest + presponse) {
	MAKE_FILE_BINARY(stdin);
	data = read_file_into_item (in_file, siBuffer);
	if (data == NULL) {
	    SECU_PrintError (program_name, "problem reading input");
	    goto nssdone;
	}
    }

    if (crequest + dresponse + presponse + ccert + vcert) {
	handle = CERT_GetDefaultCertDB();
	if (handle == NULL) {
	    SECU_PrintError (program_name, "problem getting certdb handle");
	    goto nssdone;
	}

	/*
	 * It would be fine to do the enable for all of these commands,
	 * but this way we check that everything but an overall verify
	 * can be done without it.  That is, that the individual pieces
	 * work on their own.
	 */
	if (vcert) {
	    rv = CERT_EnableOCSPChecking (handle);
	    if (rv != SECSuccess) {
		SECU_PrintError (program_name, "error enabling OCSP checking");
		goto nssdone;
	    }
	}

	if ((ccert + vcert) && (responder_name != NULL)) {
	    rv = CERT_SetOCSPDefaultResponder (handle, responder_url,
					       responder_name);
	    if (rv != SECSuccess) {
		SECU_PrintError (program_name,
				 "error setting default responder");
		goto nssdone;
	    }

	    rv = CERT_EnableOCSPDefaultResponder (handle);
	    if (rv != SECSuccess) {
		SECU_PrintError (program_name,
				 "error enabling default responder");
		goto nssdone;
	    }
	}
    }

#define NOTYET(opt)							\
	{								\
	    PR_fprintf (PR_STDERR, "%s not yet working\n", opt);	\
	    exit (-1);							\
	}

    if (name) {
        cert = find_certificate(handle, name, ascii);
    }

    if (crequest) {
	if (signer_name != NULL) {
	    NOTYET("-s");
	}
	rv = create_request (out_file, handle, cert, add_service_locator,
			     add_acceptable_responses);
    } else if (dresponse) {
	if (signer_name != NULL) {
	    NOTYET("-s");
	}
	rv = dump_response (out_file, handle, cert, responder_url);
    } else if (prequest) {
	rv = print_request (out_file, data);
    } else if (presponse) {
	rv = print_response (out_file, data, handle);
    } else if (ccert) {
	if (signer_name != NULL) {
	    NOTYET("-s");
	}
	rv = get_cert_status (out_file, handle, cert, name, verify_time);
    } else if (vcert) {
	if (signer_name != NULL) {
	    NOTYET("-s");
	}
	rv = verify_cert (out_file, handle, cert, name, cert_usage, verify_time);
    }

    if (rv != SECSuccess)
	SECU_PrintError (program_name, "error performing requested operation");
    else
	retval = 0;

nssdone:
    if (cert) {
        CERT_DestroyCertificate(cert);
    }

    if (data != NULL) {
	SECITEM_FreeItem (data, PR_TRUE);
    }

    if (handle != NULL) {
 	CERT_DisableOCSPDefaultResponder(handle);        
 	CERT_DisableOCSPChecking (handle);
    }

    if (NSS_Shutdown () != SECSuccess) {
	retval = 1;
    }

prdone:
    PR_Cleanup ();
    return retval;
}
Beispiel #25
0
static void
long_usage (char *program_name)
{
    PRFileDesc *pr_stderr;

    pr_stderr = PR_STDERR;
    synopsis (program_name);
    PR_fprintf (pr_stderr, "\nCommands (must specify exactly one):\n");
    PR_fprintf (pr_stderr,
		"  %-13s Pretty-print a binary request read from stdin\n",
		"-p");
    PR_fprintf (pr_stderr,
		"  %-13s Pretty-print a binary response read from stdin\n",
		"-P");
    PR_fprintf (pr_stderr,
		"  %-13s Create a request for cert \"nickname\" on stdout\n",
		"-r nickname");
    PR_fprintf (pr_stderr,
		"  %-13s Get response for cert \"nickname\", dump to stdout\n",
		"-R nickname");
    PR_fprintf (pr_stderr,
		"  %-13s Get status for cert \"nickname\"\n",
		"-S nickname");
    PR_fprintf (pr_stderr,
		"  %-13s Fully verify cert \"nickname\", w/ status check\n",
		"-V nickname");
    PR_fprintf (pr_stderr,
		"\n     %-10s also can be the name of the file with DER or\n"
                "  %-13s PEM(use -a option) cert encoding\n", "nickname", "");
    PR_fprintf (pr_stderr, "Options:\n");
    PR_fprintf (pr_stderr,
		"  %-13s Decode input cert from PEM format. DER is default\n",
		"-a");
    PR_fprintf (pr_stderr,
		"  %-13s Add the service locator extension to the request\n",
		"-L");
    PR_fprintf (pr_stderr,
		"  %-13s Find security databases in \"dbdir\" (default %s)\n",
		"-d dbdir", DEFAULT_DB_DIR);
    PR_fprintf (pr_stderr,
		"  %-13s Use \"location\" as URL of responder\n",
		"-l location");
    PR_fprintf (pr_stderr,
		"  %-13s Trust cert \"nickname\" as response signer\n",
		"-t nickname");
    PR_fprintf (pr_stderr,
		"  %-13s Sign requests with cert \"nickname\"\n",
		"-s nickname");
    PR_fprintf (pr_stderr,
		"  %-13s Type of certificate usage for verification:\n",
		"-u usage");
    PR_fprintf (pr_stderr,
		"%-17s c   SSL Client\n", "");
    PR_fprintf (pr_stderr,
		"%-17s s   SSL Server\n", "");
    PR_fprintf (pr_stderr,
		"%-17s e   Email Recipient\n", "");
    PR_fprintf (pr_stderr,
		"%-17s E   Email Signer\n", "");
    PR_fprintf (pr_stderr,
		"%-17s S   Object Signer\n", "");
    PR_fprintf (pr_stderr,
		"%-17s C   CA\n", "");
    PR_fprintf (pr_stderr,
		"  %-13s Validity time (default current time), one of:\n",
		"-w time");
    PR_fprintf (pr_stderr,
		"%-17s %-25s (GMT)\n", "", "YYMMDDhhmm[ss]Z");
    PR_fprintf (pr_stderr,
		"%-17s %-25s (later than GMT)\n", "", "YYMMDDhhmm[ss]+hhmm");
    PR_fprintf (pr_stderr,
		"%-17s %-25s (earlier than GMT)\n", "", "YYMMDDhhmm[ss]-hhmm");
}
Beispiel #26
0
/*********************************************************************
 *
 * m a i n
 */
int
main(int argc, char *argv[])
{
    PRBool readOnly;
    int retval = 0;

    outputFD = PR_STDOUT;
    errorFD = PR_STDERR;

    progName = argv[0];

    if (argc < 2) {
        Usage();
    }

    excludeDirs = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
                                  PL_CompareStrings, NULL, NULL);
    extensions = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
                                 PL_CompareStrings, NULL, NULL);

    if (parse_args(argc, argv)) {
        retval = -1;
        goto cleanup;
    }

    /* Parse the command file if one was given */
    if (cmdFile) {
        if (ProcessCommandFile()) {
            retval = -1;
            goto cleanup;
        }
    }

    /* Set up output redirection */
    if (outfile) {
        if (PR_Access(outfile, PR_ACCESS_EXISTS) == PR_SUCCESS) {
            /* delete the file if it is already present */
            PR_fprintf(errorFD,
                       "warning: %s already exists and will be overwritten.\n",
                       outfile);
            warningCount++;
            if (PR_Delete(outfile) != PR_SUCCESS) {
                PR_fprintf(errorFD, "ERROR: unable to delete %s.\n", outfile);
                errorCount++;
                exit(ERRX);
            }
        }
        outputFD = PR_Open(outfile,
                           PR_WRONLY |
                               PR_CREATE_FILE | PR_TRUNCATE,
                           0777);
        if (!outputFD) {
            PR_fprintf(errorFD, "ERROR: Unable to create %s.\n",
                       outfile);
            errorCount++;
            exit(ERRX);
        }
        errorFD = outputFD;
    }

    /* This seems to be a fairly common user error */

    if (verify && list_certs > 0) {
        PR_fprintf(errorFD, "%s: Can't use -l and -v at the same time\n",
                   PROGRAM_NAME);
        errorCount++;
        retval = -1;
        goto cleanup;
    }

    /* -J assumes -Z now */

    if (javascript && zipfile) {
        PR_fprintf(errorFD, "%s: Can't use -J and -Z at the same time\n",
                   PROGRAM_NAME);
        PR_fprintf(errorFD, "%s: -J option will create the jar files for you\n",
                   PROGRAM_NAME);
        errorCount++;
        retval = -1;
        goto cleanup;
    }

    /* -X needs -Z */

    if (xpi_arc && !zipfile) {
        PR_fprintf(errorFD, "%s: option XPI (-X) requires option jarfile (-Z)\n",
                   PROGRAM_NAME);
        errorCount++;
        retval = -1;
        goto cleanup;
    }

    /* Less common mixing of -L with various options */

    if (list_certs > 0 &&
        (tell_who || zipfile || javascript ||
         scriptdir || extensionsGiven || exclusionsGiven || install_script)) {
        PR_fprintf(errorFD, "%s: Can't use -l or -L with that option\n",
                   PROGRAM_NAME);
        errorCount++;
        retval = -1;
        goto cleanup;
    }

    if (!cert_dir)
        cert_dir = get_default_cert_dir();

    VerifyCertDir(cert_dir, keyName);

    if (compression_level < MIN_COMPRESSION_LEVEL ||
        compression_level > MAX_COMPRESSION_LEVEL) {
        PR_fprintf(errorFD, "Compression level must be between %d and %d.\n",
                   MIN_COMPRESSION_LEVEL, MAX_COMPRESSION_LEVEL);
        errorCount++;
        retval = -1;
        goto cleanup;
    }

    if (jartree && !keyName) {
        PR_fprintf(errorFD, "You must specify a key with which to sign.\n");
        errorCount++;
        retval = -1;
        goto cleanup;
    }

    readOnly = (genkey == NULL); /* only key generation requires write */
    if (InitCrypto(cert_dir, readOnly)) {
        PR_fprintf(errorFD, "ERROR: Cryptographic initialization failed.\n");
        errorCount++;
        retval = -1;
        goto cleanup;
    }

    if (enableOCSP) {
        SECStatus rv = CERT_EnableOCSPChecking(CERT_GetDefaultCertDB());
        if (rv != SECSuccess) {
            PR_fprintf(errorFD, "ERROR: Attempt to enable OCSP Checking failed.\n");
            errorCount++;
            retval = -1;
        }
    }

    if (verify) {
        if (VerifyJar(verify)) {
            errorCount++;
            retval = -1;
            goto cleanup;
        }
    } else if (list_certs) {
        if (ListCerts(keyName, list_certs)) {
            errorCount++;
            retval = -1;
            goto cleanup;
        }
    } else if (list_modules) {
        JarListModules();
    } else if (genkey) {
        if (GenerateCert(genkey, keySize, token)) {
            errorCount++;
            retval = -1;
            goto cleanup;
        }
    } else if (tell_who) {
        if (JarWho(tell_who)) {
            errorCount++;
            retval = -1;
            goto cleanup;
        }
    } else if (javascript && jartree) {
        /* make sure directory exists */
        PRDir *dir;
        dir = PR_OpenDir(jartree);
        if (!dir) {
            PR_fprintf(errorFD, "ERROR: unable to open directory %s.\n",
                       jartree);
            errorCount++;
            retval = -1;
            goto cleanup;
        } else {
            PR_CloseDir(dir);
        }

        /* undo junk from prior runs of signtool*/
        if (RemoveAllArc(jartree)) {
            PR_fprintf(errorFD, "Error removing archive directories under %s\n",
                       jartree);
            errorCount++;
            retval = -1;
            goto cleanup;
        }

        /* traverse all the htm|html files in the directory */
        if (InlineJavaScript(jartree, !noRecurse)) {
            retval = -1;
            goto cleanup;
        }

        /* sign any resultant .arc directories created in above step */
        if (SignAllArc(jartree, keyName, javascript, metafile, install_script,
                       optimize, !noRecurse)) {
            retval = -1;
            goto cleanup;
        }

        if (!leaveArc) {
            RemoveAllArc(jartree);
        }

        if (errorCount > 0 || warningCount > 0) {
            PR_fprintf(outputFD, "%d error%s, %d warning%s.\n",
                       errorCount,
                       errorCount == 1 ? "" : "s", warningCount, warningCount == 1 ? "" : "s");
        } else {
            PR_fprintf(outputFD, "Directory %s signed successfully.\n",
                       jartree);
        }
    } else if (jartree) {
        SignArchive(jartree, keyName, zipfile, javascript, metafile,
                    install_script, optimize, !noRecurse);
    } else
        Usage();

cleanup:
    if (extensions) {
        PL_HashTableDestroy(extensions);
        extensions = NULL;
    }
    if (excludeDirs) {
        PL_HashTableDestroy(excludeDirs);
        excludeDirs = NULL;
    }
    if (outputFD != PR_STDOUT) {
        PR_Close(outputFD);
    }
    rm_dash_r(TMP_OUTPUT);
    if (retval == 0) {
        if (NSS_Shutdown() != SECSuccess) {
            exit(1);
        }
    }
    return retval;
}
Beispiel #27
0
/*********************************************************************
 *
 * P r o c e s s O n e O p t
 *
 * Since options can come from different places (command file, word options,
 * char options), this is a central function that is called to deal with
 * them no matter where they come from.
 *
 * type is the type of option.
 * arg is the argument to the option, possibly NULL.
 * Returns 1 if the argument was eaten, 0 if it wasn't, and -1 for error.
 */
static int
ProcessOneOpt(OPT_TYPE type, char *arg)
{
    int ate = 0;

    switch (type) {
        case HELP_OPT:
            Usage();
            break;
        case LONG_HELP_OPT:
            LongUsage();
            break;
        case BASE_OPT:
            if (base) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-b");
                warningCount++;
                PR_Free(base);
                base = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "-b");
                errorCount++;
                goto loser;
            }
            base = PL_strdup(arg);
            ate = 1;
            break;
        case COMPRESSION_OPT:
            if (compression_level_specified) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-c");
                warningCount++;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "-c");
                errorCount++;
                goto loser;
            }
            compression_level = atoi(arg);
            compression_level_specified = PR_TRUE;
            ate = 1;
            break;
        case CERT_DIR_OPT:
            if (cert_dir) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-d");
                warningCount++;
                PR_Free(cert_dir);
                cert_dir = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "-d");
                errorCount++;
                goto loser;
            }
            cert_dir = PL_strdup(arg);
            ate = 1;
            break;
        case EXTENSION_OPT:
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "extension (-e)");
                errorCount++;
                goto loser;
            }
            PL_HashTableAdd(extensions, arg, arg);
            extensionsGiven = PR_TRUE;
            ate = 1;
            break;
        case INSTALL_SCRIPT_OPT:
            if (install_script) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR],
                           "installScript (-i)");
                warningCount++;
                PR_Free(install_script);
                install_script = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "installScript (-i)");
                errorCount++;
                goto loser;
            }
            install_script = PL_strdup(arg);
            ate = 1;
            break;
        case SCRIPTDIR_OPT:
            if (scriptdir) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR],
                           "javascriptdir (-j)");
                warningCount++;
                PR_Free(scriptdir);
                scriptdir = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "javascriptdir (-j)");
                errorCount++;
                goto loser;
            }
            scriptdir = PL_strdup(arg);
            ate = 1;
            break;
        case CERTNAME_OPT:
            if (keyName) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR],
                           "keyName (-k)");
                warningCount++;
                PR_Free(keyName);
                keyName = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "keyName (-k)");
                errorCount++;
                goto loser;
            }
            keyName = PL_strdup(arg);
            ate = 1;
            break;
        case LIST_OBJSIGN_CERTS_OPT:
        case LIST_ALL_CERTS_OPT:
            if (list_certs != 0) {
                PR_fprintf(errorFD,
                           "warning: only one of -l and -L may be specified.\n");
                warningCount++;
            }
            list_certs = (type == LIST_OBJSIGN_CERTS_OPT ? 1 : 2);
            break;
        case METAFILE_OPT:
            if (metafile) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR],
                           "metafile (-m)");
                warningCount++;
                PR_Free(metafile);
                metafile = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "metafile (-m)");
                errorCount++;
                goto loser;
            }
            metafile = PL_strdup(arg);
            ate = 1;
            break;
        case OPTIMIZE_OPT:
            optimize = 1;
            break;
        case ENABLE_OCSP_OPT:
            enableOCSP = 1;
            break;
        case PASSWORD_OPT:
            if (pwdata.data) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR],
                           "password (-p)");
                warningCount++;
                PR_Free(pwdata.data);
                pwdata.data = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "password (-p)");
                errorCount++;
                goto loser;
            }
            pwdata.source = PW_PLAINTEXT;
            pwdata.data = PL_strdup(arg);
            ate = 1;
            break;
        case VERIFY_OPT:
            if (verify) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR],
                           "verify (-v)");
                warningCount++;
                PR_Free(verify);
                verify = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "verify (-v)");
                errorCount++;
                goto loser;
            }
            verify = PL_strdup(arg);
            ate = 1;
            break;
        case WHO_OPT:
            if (tell_who) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR],
                           "who (-v)");
                warningCount++;
                PR_Free(tell_who);
                tell_who = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "who (-w)");
                errorCount++;
                goto loser;
            }
            tell_who = PL_strdup(arg);
            ate = 1;
            break;
        case EXCLUDE_OPT:
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "exclude (-x)");
                errorCount++;
                goto loser;
            }
            PL_HashTableAdd(excludeDirs, arg, arg);
            exclusionsGiven = PR_TRUE;
            ate = 1;
            break;
        case NO_TIME_OPT:
            no_time = 1;
            break;
        case JAVASCRIPT_OPT:
            javascript++;
            break;
        case ZIPFILE_OPT:
            if (zipfile) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR],
                           "jarfile (-Z)");
                warningCount++;
                PR_Free(zipfile);
                zipfile = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "jarfile (-Z)");
                errorCount++;
                goto loser;
            }
            zipfile = PL_strdup(arg);
            ate = 1;
            break;
        case GENKEY_OPT:
            if (genkey) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR],
                           "generate (-G)");
                warningCount++;
                PR_Free(genkey);
                genkey = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "generate (-G)");
                errorCount++;
                goto loser;
            }
            genkey = PL_strdup(arg);
            ate = 1;
            break;
        case MODULES_OPT:
            list_modules++;
            break;
        case SIGNDIR_OPT:
            if (jartree) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR],
                           "signdir");
                warningCount++;
                PR_Free(jartree);
                jartree = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "signdir");
                errorCount++;
                goto loser;
            }
            jartree = PL_strdup(arg);
            ate = 1;
            break;
        case OUTFILE_OPT:
            if (outfile) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR],
                           "outfile");
                warningCount++;
                PR_Free(outfile);
                outfile = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "outfile");
                errorCount++;
                goto loser;
            }
            outfile = PL_strdup(arg);
            ate = 1;
            break;
        case COMMAND_FILE_OPT:
            if (cmdFile) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR],
                           "-f");
                warningCount++;
                PR_Free(cmdFile);
                cmdFile = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "-f");
                errorCount++;
                goto loser;
            }
            cmdFile = PL_strdup(arg);
            ate = 1;
            break;
        case NORECURSE_OPT:
            noRecurse = PR_TRUE;
            break;
        case LEAVE_ARC_OPT:
            leaveArc = PR_TRUE;
            break;
        case VERBOSITY_OPT:
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR],
                           "--verbosity");
                errorCount++;
                goto loser;
            }
            verbosity = atoi(arg);
            ate = 1;
            break;
        case KEYSIZE_OPT:
            if (keySize != -1) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-s");
                warningCount++;
            }
            keySize = atoi(arg);
            ate = 1;
            if (keySize < 1 || keySize > MAX_RSA_KEY_SIZE) {
                PR_fprintf(errorFD, "Invalid key size: %d.\n", keySize);
                errorCount++;
                goto loser;
            }
            break;
        case TOKEN_OPT:
            if (token) {
                PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-t");
                PR_Free(token);
                token = NULL;
            }
            if (!arg) {
                PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "-t");
                errorCount++;
                goto loser;
            }
            token = PL_strdup(arg);
            ate = 1;
            break;
        case XPI_ARC_OPT:
            xpi_arc = 1;
            break;
        default:
            PR_fprintf(errorFD, "warning: unknown option\n");
            warningCount++;
            break;
    }

    return ate;
loser:
    return -1;
}
Beispiel #28
0
/*********************************************************************
 *
 * p a r s e _ a r g s
 */
static int
parse_args(int argc, char *argv[])
{
    char *opt;
    char *arg;
    int needsInc = 0;
    int i;
    OPT_TYPE type;

    /* Loop over all arguments */
    for (i = 1; i < argc; i++) {
        opt = argv[i];
        arg = NULL;

        if (opt[0] == '-') {
            if (opt[1] == '-') {
                /* word option */
                if (i < argc - 1) {
                    needsInc = 1;
                    arg = argv[i + 1];
                } else {
                    arg = NULL;
                }

                if (!PL_strcasecmp(opt + 2, "norecurse")) {
                    type = NORECURSE_OPT;
                } else if (!PL_strcasecmp(opt + 2, "leavearc")) {
                    type = LEAVE_ARC_OPT;
                } else if (!PL_strcasecmp(opt + 2, "verbosity")) {
                    type = VERBOSITY_OPT;
                } else if (!PL_strcasecmp(opt + 2, "outfile")) {
                    type = OUTFILE_OPT;
                } else if (!PL_strcasecmp(opt + 2, "keysize")) {
                    type = KEYSIZE_OPT;
                } else if (!PL_strcasecmp(opt + 2, "token")) {
                    type = TOKEN_OPT;
                } else {
                    PR_fprintf(errorFD, "warning: unknown option: %s\n",
                               opt);
                    warningCount++;
                    type = UNKNOWN_OPT;
                }
            } else {
                /* char option */
                if (opt[2] != '\0') {
                    arg = opt + 2;
                } else if (i < argc - 1) {
                    needsInc = 1;
                    arg = argv[i + 1];
                } else {
                    arg = NULL;
                }

                switch (opt[1]) {
                    case 'b':
                        type = BASE_OPT;
                        break;
                    case 'c':
                        type = COMPRESSION_OPT;
                        break;
                    case 'd':
                        type = CERT_DIR_OPT;
                        break;
                    case 'e':
                        type = EXTENSION_OPT;
                        break;
                    case 'f':
                        type = COMMAND_FILE_OPT;
                        break;
                    case 'h':
                        type = HELP_OPT;
                        break;
                    case 'H':
                        type = LONG_HELP_OPT;
                        break;
                    case 'i':
                        type = INSTALL_SCRIPT_OPT;
                        break;
                    case 'j':
                        type = SCRIPTDIR_OPT;
                        break;
                    case 'k':
                        type = CERTNAME_OPT;
                        break;
                    case 'l':
                        type = LIST_OBJSIGN_CERTS_OPT;
                        break;
                    case 'L':
                        type = LIST_ALL_CERTS_OPT;
                        break;
                    case 'm':
                        type = METAFILE_OPT;
                        break;
                    case 'o':
                        type = OPTIMIZE_OPT;
                        break;
                    case 'O':
                        type = ENABLE_OCSP_OPT;
                        break;
                    case 'p':
                        type = PASSWORD_OPT;
                        break;
                    case 'v':
                        type = VERIFY_OPT;
                        break;
                    case 'w':
                        type = WHO_OPT;
                        break;
                    case 'x':
                        type = EXCLUDE_OPT;
                        break;
                    case 'X':
                        type = XPI_ARC_OPT;
                        break;
                    case 'z':
                        type = NO_TIME_OPT;
                        break;
                    case 'J':
                        type = JAVASCRIPT_OPT;
                        break;
                    case 'Z':
                        type = ZIPFILE_OPT;
                        break;
                    case 'G':
                        type = GENKEY_OPT;
                        break;
                    case 'M':
                        type = MODULES_OPT;
                        break;
                    case 's':
                        type = KEYSIZE_OPT;
                        break;
                    case 't':
                        type = TOKEN_OPT;
                        break;
                    default:
                        type = UNKNOWN_OPT;
                        PR_fprintf(errorFD, "warning: unrecognized option: -%c.\n",
                                   opt[1]);
                        warningCount++;
                        break;
                }
            }
        } else {
            type = UNKNOWN_OPT;
            if (i == argc - 1) {
                if (jartree) {
                    PR_fprintf(errorFD,
                               "warning: directory to be signed specified more than once.\n"
                               " Only last specification will be used.\n");
                    warningCount++;
                    PR_Free(jartree);
                    jartree = NULL;
                }
                jartree = PL_strdup(opt);
            } else {
                PR_fprintf(errorFD, "warning: unrecognized option: %s\n", opt);
                warningCount++;
            }
        }

        if (type != UNKNOWN_OPT) {
            short ateArg = ProcessOneOpt(type, arg);
            if (ateArg == -1) {
                /* error */
                return -1;
            }
            if (ateArg && needsInc) {
                i++;
            }
        }
    }

    return 0;
}
Beispiel #29
0
/*********************************************************************
 *
 * P r o c e s s C o m m a n d F i l e
 */
int
ProcessCommandFile()
{
    PRFileDesc *fd;
#define CMD_FILE_BUFSIZE 1024
    char buf[CMD_FILE_BUFSIZE];
    char *equals;
    int linenum = 0;
    int retval = -1;
    OPT_TYPE type;

    fd = PR_Open(cmdFile, PR_RDONLY, 0777);
    if (!fd) {
        PR_fprintf(errorFD, "ERROR: Unable to open command file %s.\n");
        errorCount++;
        return -1;
    }

    while (pr_fgets(buf, CMD_FILE_BUFSIZE, fd)) {
        char *eol;
        linenum++;

        /* Chop off final newline */
        eol = PL_strchr(buf, '\r');
        if (!eol) {
            eol = PL_strchr(buf, '\n');
        }
        if (eol)
            *eol = '\0';

        equals = PL_strchr(buf, '=');
        if (!equals) {
            continue;
        }

        *equals = '\0';
        equals++;

        /* Now buf points to the attribute, and equals points to the value. */

        /* This is pretty straightforward, just deal with whatever attribute
         * this is */
        if (!PL_strcasecmp(buf, "basename")) {
            type = BASE_OPT;
        } else if (!PL_strcasecmp(buf, "compression")) {
            type = COMPRESSION_OPT;
        } else if (!PL_strcasecmp(buf, "certdir")) {
            type = CERT_DIR_OPT;
        } else if (!PL_strcasecmp(buf, "extension")) {
            type = EXTENSION_OPT;
        } else if (!PL_strcasecmp(buf, "generate")) {
            type = GENKEY_OPT;
        } else if (!PL_strcasecmp(buf, "installScript")) {
            type = INSTALL_SCRIPT_OPT;
        } else if (!PL_strcasecmp(buf, "javascriptdir")) {
            type = SCRIPTDIR_OPT;
        } else if (!PL_strcasecmp(buf, "htmldir")) {
            type = JAVASCRIPT_OPT;
            if (jartree) {
                PR_fprintf(errorFD,
                           "warning: directory to be signed specified more than once."
                           " Only last specification will be used.\n");
                warningCount++;
                PR_Free(jartree);
                jartree = NULL;
            }
            jartree = PL_strdup(equals);
        } else if (!PL_strcasecmp(buf, "certname")) {
            type = CERTNAME_OPT;
        } else if (!PL_strcasecmp(buf, "signdir")) {
            type = SIGNDIR_OPT;
        } else if (!PL_strcasecmp(buf, "list")) {
            type = LIST_OBJSIGN_CERTS_OPT;
        } else if (!PL_strcasecmp(buf, "listall")) {
            type = LIST_ALL_CERTS_OPT;
        } else if (!PL_strcasecmp(buf, "metafile")) {
            type = METAFILE_OPT;
        } else if (!PL_strcasecmp(buf, "modules")) {
            type = MODULES_OPT;
        } else if (!PL_strcasecmp(buf, "optimize")) {
            type = OPTIMIZE_OPT;
        } else if (!PL_strcasecmp(buf, "ocsp")) {
            type = ENABLE_OCSP_OPT;
        } else if (!PL_strcasecmp(buf, "password")) {
            type = PASSWORD_OPT;
        } else if (!PL_strcasecmp(buf, "verify")) {
            type = VERIFY_OPT;
        } else if (!PL_strcasecmp(buf, "who")) {
            type = WHO_OPT;
        } else if (!PL_strcasecmp(buf, "exclude")) {
            type = EXCLUDE_OPT;
        } else if (!PL_strcasecmp(buf, "notime")) {
            type = NO_TIME_OPT;
        } else if (!PL_strcasecmp(buf, "jarfile")) {
            type = ZIPFILE_OPT;
        } else if (!PL_strcasecmp(buf, "outfile")) {
            type = OUTFILE_OPT;
        } else if (!PL_strcasecmp(buf, "leavearc")) {
            type = LEAVE_ARC_OPT;
        } else if (!PL_strcasecmp(buf, "verbosity")) {
            type = VERBOSITY_OPT;
        } else if (!PL_strcasecmp(buf, "keysize")) {
            type = KEYSIZE_OPT;
        } else if (!PL_strcasecmp(buf, "token")) {
            type = TOKEN_OPT;
        } else if (!PL_strcasecmp(buf, "xpi")) {
            type = XPI_ARC_OPT;
        } else {
            PR_fprintf(errorFD,
                       "warning: unknown attribute \"%s\" in command file, line %d.\n",
                       buf, linenum);
            warningCount++;
            type = UNKNOWN_OPT;
        }

        /* Process the option, whatever it is */
        if (type != UNKNOWN_OPT) {
            if (ProcessOneOpt(type, equals) == -1) {
                goto finish;
            }
        }
    }

    retval = 0;

finish:
    PR_Close(fd);
    return retval;
}
int write_stats_dump(PRFileDesc *fd, StatsHeaderNode *hdr)
{
    int i = 0;
    StatsManager::lockStatsData();
    const StatsHeader *hdrStats = &hdr->hdrStats;

    // Version
    PR_fprintf(fd, "\n%s\n", hdrStats->versionServer);

    // Uptime
    char buffer[25];
    PRExplodedTime tm;
    PR_ExplodeTime(hdrStats->timeStarted, PR_LocalTimeParameters, &tm);
    PR_FormatTimeUSEnglish(buffer, sizeof(buffer), "%c", &tm);
    PR_fprintf(fd, "\nServer started %s\n", buffer);
    {
        StatsProcessNode *process = hdr->process;
        while (process) {
            const StatsProcessSlot *procStats = &process->procStats;
            PR_ExplodeTime(procStats->timeStarted, PR_LocalTimeParameters, &tm);
            PR_FormatTimeUSEnglish(buffer, sizeof(buffer), "%c", &tm);
            PR_fprintf(fd, "Process %d started %s\n", procStats->pid, buffer);
            process = process->next;
        }
    }

    // ConnectionQueue
    {
        StatsConnectionQueueSlot connqueues;
        memset(&connqueues, 0, sizeof(connqueues));

        // Accumulate connection queue buckets for every process
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsConnectionQueueNode *connQueueNode = process->connQueue;
            while (connQueueNode) {
                const StatsConnectionQueueSlot *connqueue = &connQueueNode->connQueueStats;
                connqueues.countQueued += connqueue->countQueued;
                connqueues.peakQueued += connqueue->peakQueued;
                connqueues.maxQueued += connqueue->maxQueued;
                connqueues.countOverflows += connqueue->countOverflows;
                connqueues.countTotalQueued += connqueue->countTotalQueued;
                connqueues.ticksTotalQueued += connqueue->ticksTotalQueued;
                connqueues.countTotalConnections += connqueue->countTotalConnections;
                connqueues.countQueued1MinuteAverage += connqueue->countQueued1MinuteAverage;
                connqueues.countQueued5MinuteAverage += connqueue->countQueued5MinuteAverage;
                connqueues.countQueued15MinuteAverage += connqueue->countQueued15MinuteAverage;
                connQueueNode = connQueueNode->next;
            }
            process = process->next;
        }

        PRFloat64 count = (PRInt64)connqueues.countTotalQueued;
        PRFloat64 ticks = (PRInt64)connqueues.ticksTotalQueued;
        if (count < 1.0)
            count = 1.0;

        PR_fprintf(fd,
                   "\nConnectionQueue:\n"
                   "-----------------------------------------\n"
                   "Current/Peak/Limit Queue Length            %d/%d/%d\n"
                   "Total Connections Queued                   %llu\n"
                   "Average Queue Length (1, 5, 15 minutes)    %4.2f, %4.2f, %4.2f\n"
                   "Average Queueing Delay                     %.2f milliseconds\n",
                   connqueues.countQueued, connqueues.peakQueued, connqueues.maxQueued,
                   connqueues.countTotalQueued,
                   connqueues.countQueued1MinuteAverage,
                   connqueues.countQueued5MinuteAverage,
                   connqueues.countQueued15MinuteAverage,
                   ticks / count / hdrStats->ticksPerSecond * 1000.0);
    }

    // Listen sockets
    {
        StatsProcessNode *process = hdr->process;
        StatsListenNode *lsNode = (process) ? process->ls : 0;
        while (lsNode) {
            StatsListenSlot *ls = &lsNode->lsStats;
            PRNetAddr addr;
            memcpy(&addr, &ls->address, sizeof(ls->address));
            char szAddress[512];
            memset(szAddress, 0, sizeof(szAddress));
            net_addr_to_string(&addr, szAddress, sizeof(szAddress)-1);
            PR_fprintf(fd, 
                       "\nListenSocket %s:\n"
                       "------------------------\n"
                       "Address                   %s://%s:%hu\n"
                       "Acceptor Threads          %d\n"
                       "Default Virtual Server    %s\n",
                       ls->id,
                       ls->flagSecure ? "https" : "http",
                       szAddress,
                       PR_ntohs(ls->address.inet.port),
                       ls->countAcceptors,
                       ls->defaultVsId
                    );
            lsNode = lsNode->next;
        }
    }

    // Keepalive Info
    {
        StatsKeepaliveBucket keepalives;
        memset(&keepalives, 0, sizeof(keepalives));

        // Accumulate keepalive buckets for every process
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsKeepaliveBucket *procKeepAlive = NULL;
            procKeepAlive = &process->procStats.keepAliveBucket;
            StatsManagerUtil::accumulateKeepAlive(&keepalives, procKeepAlive);
            process = process->next;
        }

        PR_fprintf(fd,
                   "\nKeepAliveInfo:\n"
                   "--------------------\n"
                   "KeepAliveCount        %lu/%lu\n"
                   "KeepAliveHits         %llu\n"
                   "KeepAliveFlushes      %llu\n"
                   "KeepAliveRefusals     %llu\n"
                   "KeepAliveTimeouts     %llu\n"
                   "KeepAliveTimeout      %lu seconds\n",
                   keepalives.countConnections,
                   keepalives.maxConnections,
                   keepalives.countHits,
                   keepalives.countFlushes,
                   keepalives.countRefusals,
                   keepalives.countTimeouts,
                   keepalives.secondsTimeout);
    }

    // Session Creation Info
    {
        PRUint32 countThreads = 0;
        PRUint32 countBusy = 0;
        PRUint32 countKeepAlive = 0;
        PRUint32 countKeepAliveThreads = 0;

        // Count the number of active threads
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsProcessSlot *procStats = &process->procStats;
            if (procStats->mode != STATS_PROCESS_EMPTY) {
                StatsThreadNode *thread = process->thread;
                while (thread) {
                    const StatsThreadSlot *threadStats = &thread->threadStats;
                    if (threadStats->mode != STATS_THREAD_EMPTY) {
                        countThreads++;
                        if (threadStats->mode == STATS_THREAD_KEEPALIVE) {
                            countKeepAlive++;
                        } else if (threadStats->mode != STATS_THREAD_IDLE) {
                            countBusy++;
                        }
                    }
                    thread = thread->next;
                }
            }
            // Get number of keepalive threads
            StatsKeepaliveBucket *procKeepAlive = NULL;
            procKeepAlive = &process->procStats.keepAliveBucket;
            countKeepAliveThreads += procKeepAlive->numThreads;

            process = process->next;
        }

        PR_fprintf(fd, 
                   "\nSessionCreationInfo:\n"
                   "------------------------\n"
                   "Active Sessions           %lu\n"
                   "Keep-Alive Sessions       %lu\n"
                   "Total Sessions Created    %lu/%lu\n",
                   countBusy,
                   countKeepAlive,
                   countThreads, (hdrStats->maxThreads * hdrStats->maxProcs + countKeepAliveThreads));
    }

    // Cache Info
    {
        StatsCacheBucket caches;
        memset(&caches, 0, sizeof(caches));

        // Accumulate cache buckets for every process
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsCacheBucket *procCache = NULL;
            procCache = &process->procStats.cacheBucket;
            StatsManagerUtil::accumulateCache(&caches, procCache);
            process = process->next;
        }

        if (caches.flagEnabled) {
            PR_fprintf(fd,
                       "\nCacheInfo:\n"
                       "-----------------------\n");

            PRInt64 fileLookups = caches.countHits + caches.countMisses;

            PR_fprintf(fd,
                       "File Cache Enabled       yes\n"
                       "File Cache Entries       %lu/%lu\n"
                       "File Cache Hit Ratio     %llu/%lld (%6.2f%%)\n"
                       "Maximum Age              %d\n",
                       caches.countEntries,
                       caches.maxEntries,
                       caches.countHits,
                       fileLookups,
                       percent(caches.countHits, fileLookups),
                       caches.secondsMaxAge);

            PRInt64 accelRequests = caches.countAcceleratableRequests + caches.countUnacceleratableRequests;
            PRInt64 accelResponses = caches.countAcceleratableResponses + caches.countUnacceleratableResponses;
            PRInt64 accelLookups = caches.countAcceleratorHits + caches.countAcceleratorMisses;

            PR_fprintf(fd,
                       "Accelerator Entries      %lu/%lu\n"
                       "Acceleratable Requests   %llu/%lld (%6.2f%%)\n"
                       "Acceleratable Responses  %llu/%lld (%6.2f%%)\n"
                       "Accelerator Hit Ratio    %llu/%lld (%6.2f%%)\n",
                       caches.countAcceleratorEntries,
                       caches.maxEntries,
                       caches.countAcceleratableRequests,
                       accelRequests,
                       percent(caches.countAcceleratableRequests, accelRequests),
                       caches.countAcceleratableResponses,
                       accelResponses,
                       percent(caches.countAcceleratableResponses, accelResponses),
                       caches.countAcceleratorHits,
                       accelLookups,
                       percent(caches.countAcceleratorHits, accelLookups));
        } else {
            PR_fprintf(fd, "\nServer cache disabled\n");
        }
    }

    // Thread pool info
    {
        StatsThreadPoolBucket pools[FUNC_MAXPOOLS];
        const char *names[FUNC_MAXPOOLS];
        memset(pools, 0, sizeof(pools));
        memset(names, 0, sizeof(names));

        // Accumulate thread pool buckets for every process
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsThreadPoolNode *pool = process->threadPool;
            for (i = 0; pool && (i < FUNC_MAXPOOLS); i++) {
                StatsManagerUtil::accumulateThreadPool(&pools[i],
                                                       &pool->threadPoolStats);
                names[i] = STATS_GET_NAME(&pool->threadPoolStats);
                pool = pool->next;
            }
            process = process->next;
        }

        int poolFlag = 0;

        for (i = 0; i < FUNC_MAXPOOLS; i++)
        {
            if (names[i]) {
                if (!poolFlag)
                {
                    poolFlag = 1;
                    PR_fprintf(fd,
                               "\nNative pools:\n"
                               "----------------------------\n");
                }

                PR_fprintf(fd,
                           "%s:\n"
                           "Idle/Peak/Limit               %lu/%lu/%lu\n"
                           "Work Queue Length/Peak/Limit  %lu/%lu/%lu\n",
                           names[i],
                           pools[i].countThreadsIdle, 
                           pools[i].countThreads, 
                           pools[i].maxThreads,
                           pools[i].countQueued, 
                           pools[i].peakQueued, 
                           pools[i].maxQueued);
            }
        }
    }

    // DNS info
    {
        StatsDnsBucket dnss;
        memset(&dnss, 0, sizeof(dnss));

        // Accumulate DNS buckets for every process
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsManagerUtil::accumulateDNS(&dnss,
                                            &process->procStats.dnsBucket);
            process = process->next;
        }

        if (dnss.flagCacheEnabled) {
            PRUint32 totalhits = dnss.countCacheMisses + dnss.countCacheHits;
            float hitratio;

            if (totalhits > 0.0)
                hitratio = (float)dnss.countCacheHits / (float)totalhits;
            else
                hitratio = 0.0;
            
            PR_fprintf(fd, 
                       "\nDNSCacheInfo:\n"
                       "------------------\n"
                       "enabled             yes\n"
                       "CacheEntries        %lu/%lu\n"
                       "HitRatio            %lu/%lu (%6.2f%%)\n",
                       dnss.countCacheEntries,
                       dnss.maxCacheEntries,
                       dnss.countCacheHits,
                       totalhits,
                       hitratio * 100.0);
        } else {
            PR_fprintf(fd, "\nServer DNS cache disabled\n");
        }

        if (dnss.flagAsyncEnabled) {
            PR_fprintf(fd, 
                       "\nAsyncDNS Data:\n"
                       "------------------\n"
                       "enabled             yes\n"
                       "NameLookups         %lu\n"
                       "AddrLookups         %lu\n"
                       "LookupsInProgress   %lu\n",
                       dnss.countAsyncNameLookups,
                       dnss.countAsyncAddrLookups,
                       dnss.countAsyncLookupsInProgress);
        } else {
            PR_fprintf(fd, "\nAsync DNS disabled\n");
        }
    }

    // NSAPI Profile Info
    if (hdrStats->maxProfileBuckets) {
        int i;

        StatsProfileBucket *profiles = new StatsProfileBucket[hdrStats->maxProfileBuckets];
        const char **names = new const char*[hdrStats->maxProfileBuckets];
        const char **descs = new const char*[hdrStats->maxProfileBuckets];
        memset(profiles, 0, sizeof(profiles[0]) * hdrStats->maxProfileBuckets);
        memset(names, 0, sizeof(names[0]) * hdrStats->maxProfileBuckets);
        memset(descs, 0, sizeof(descs[0]) * hdrStats->maxProfileBuckets);

        // Accumulate profiles for every thread
        StatsProcessNode *process = hdr->process;
        while (process) {
            StatsThreadNode *thread = process->thread;
            while (thread) {
                StatsProfileNode *profile = thread->profile;
                for (i = 0; i < hdrStats->maxProfileBuckets; i++) {
                    StatsManagerUtil::accumulateProfile(&profiles[i],
                                                        &profile->profileStats);
                    names[i] = STATS_GET_NAME(&profile->profileStats);
                    descs[i] = STATS_GET_DESCRIPTION(&profile->profileStats);
                    profile = profile->next;
                }
                thread = thread->next;
            }
            process = process->next;
        }

        PRInt64 tr = profiles[STATS_PROFILE_ALL].countRequests;
        PRInt64 tc = profiles[STATS_PROFILE_ALL].countCalls;
        float td = (float)(PRInt64)profiles[STATS_PROFILE_ALL].ticksDispatch;
        float tf = (float)(PRInt64)profiles[STATS_PROFILE_ALL].ticksFunction;
        td /= hdrStats->ticksPerSecond;
        tf /= hdrStats->ticksPerSecond;
        float tt = td + tf;

        PR_fprintf(fd, 
                   "\nPerformance Counters:\n"
                   "------------------------------------------------\n"
                   "                           Average         Total      Percent\n\n"
                   "Total number of requests:             %10llu\n"
                   "Request processing time:   %7.4f  %12.4f\n",
                   tr,
                   (tr > 0) ? (tt / (float)tr) : 0, tt);

        for (i = hdrStats->maxProfileBuckets-1; i >= STATS_PROFILE_DEFAULT; i--) {
            PRInt64 r = profiles[i].countRequests;
            PRInt64 c = profiles[i].countCalls;
            const char *name = names[i];

            // Don't display cache-bucket if it's empty.  This is a predefined
            // bucket that stored NSAPI accelerator cache statistics in
            // previous versions of the server.
            if (!c && i == STATS_PROFILE_CACHE && !strcmp(name, "cache-bucket")) {
                continue;
            }

            float d = (float)(PRInt64)profiles[i].ticksDispatch;
            float f = (float)(PRInt64)profiles[i].ticksFunction;
            d /= hdrStats->ticksPerSecond;
            f /= hdrStats->ticksPerSecond;
            float t = d + f;

            PR_fprintf(fd, 
                       "\n%s (%s)\n"
                       "Number of Requests:                 %12llu    (%6.2f%%)\n"
                       "Number of Invocations:              %12llu    (%6.2f%%)\n"
                       "Latency:                   %7.4f  %12.4f    (%6.2f%%)\n"
                       "Function Processing Time:  %7.4f  %12.4f    (%6.2f%%)\n"
                       "Total Response Time:       %7.4f  %12.4f    (%6.2f%%)\n",
                       name, SAFESTRING(descs[i]),
                       r, (tr > 0) ? (100.0 * r / (PRFloat64) tr) : 0,
                       c, (tc > 0) ? (100.0 * c / (PRFloat64) tc) : 0,
                       (r > 0)? (d / r): 0, d, (tt > 0)? (100 * d / tt): 0,
                       (r > 0)? (f / r): 0, f, (tt > 0)? (100 * f / tt): 0,
                       (r > 0)? (t / r): 0, t, (tt > 0)? (100 * t / tt): 0);
        }

        delete[] profiles;
        delete[] names;
        delete[] descs;

    } else {
        PR_fprintf(fd, "\nPerformance Statistics disabled\n");
    }

    // Session info
    {
        StatsProcessNode *process;
        int x;
        int y;

        // Count the number of rows in our session table
        int nr = 0;
        for (process = hdr->process; process; process = process->next) {
            StatsThreadNode *thread;
            for (thread = process->thread; thread; thread = thread->next)
                nr++;
        }

        SessionRow *rows = new SessionRow[nr];

        PRTime now = PR_Now();

        // Collect stats from each session
        y = 0;
        for (process = hdr->process; process; process = process->next) {
            StatsThreadNode *thread;
            for (thread = process->thread; thread; thread = thread->next) {
                thread->lock();

                PRUint32 mode = thread->threadStats.mode;
                if (mode != STATS_THREAD_EMPTY && mode != STATS_THREAD_IDLE &&
                    mode != STATS_THREAD_KEEPALIVE) {
                    rows[y].columns[SESSION_COLUMN_PROCESS].printf("%u", process->procStats.pid);
                    rows[y].columns[SESSION_COLUMN_STATUS] = StatsManager::getMode(&thread->threadStats);

                    char addr[NET_ADDR_STRING_SIZE];
                    net_addr_to_string(&thread->threadStats.addressClient, addr, sizeof(addr));
                    rows[y].columns[SESSION_COLUMN_CLIENT] = addr;

                    rows[y].timeRequestStarted = thread->threadStats.timeRequestStarted;
                    if (rows[y].timeRequestStarted != 0) {
                        PRTime microseconds = now - rows[y].timeRequestStarted;
                        int seconds = (microseconds + PR_USEC_PER_SEC/2) / PR_USEC_PER_SEC;
                        rows[y].columns[SESSION_COLUMN_AGE].printf("%d", seconds);
                    }

                    rows[y].columns[SESSION_COLUMN_VS] = thread->threadStats.vsId;
                    rows[y].columns[SESSION_COLUMN_METHOD] = thread->threadStats.requestBucket.method;
                    rows[y].columns[SESSION_COLUMN_URI] = thread->threadStats.requestBucket.uri;
                    rows[y].columns[SESSION_COLUMN_FUNCTION] = STATS_GET_FUNCTION_NAME(&thread->threadStats);

                    y++;
                }

                thread->unlock();
            }
        }

        // We'll only display stats for active sessions
        PR_ASSERT(y <= nr);
        nr = y;

        // Each column is at least as wide as its label
        int widths[SESSION_COLUMN_COUNT];
        for (x = 0; x < SESSION_COLUMN_COUNT; x++)
            widths[x] = session_column_labels[x].length();

        // Ensure each column is wide enough to fit its largest value
        for (y = 0; y < nr; y++) {
            for (x = 0; x < SESSION_COLUMN_COUNT; x++) {
                if (widths[x] < rows[y].columns[x].length())
                    widths[x] = rows[y].columns[x].length();
            }
        }

        // Leave at least 2 spaces between columns
        for (x = 0; x < SESSION_COLUMN_COUNT - 1; x++)
            widths[x] += 2;

        // Calculate total line width and individual column offsets
        int width = 0;
        int offsets[SESSION_COLUMN_COUNT];
        for (x = 0 ; x < SESSION_COLUMN_COUNT; x++) {
            offsets[x] = width;
            width += widths[x];
        }

        char *line = (char *) malloc(width + sizeof('\n'));

        // Output table heading and column labels
        PR_fprintf(fd, "\nSessions:\n");
        memset(line, '-', width);
        line[width] = '\n';
        PR_Write(fd, line, width + sizeof('\n'));
        PR_Write(fd, line, format_session(line, offsets, session_column_labels));
        PR_Write(fd, "\n", 1);

        // Sort rows by age
        const SessionRow **sorted = new const SessionRow *[nr];
        for (y = 0; y < nr; y++)
            sorted[y] = &rows[y];
        qsort(sorted, nr, sizeof(sorted[0]), &session_cmp);

        // Output individual rows
        for (y = 0; y < nr; y++)
            PR_Write(fd, line, format_session(line, offsets, sorted[y]->columns));

        delete [] sorted;

        free(line);

        delete [] rows;
    }

    StatsManager::unlockStatsData();
    return REQ_PROCEED;
}