/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <stdio.h>
#include <string.h>

#include "secutil.h"

#if defined(XP_UNIX)
#include <unistd.h>
#endif

#if defined(_WINDOWS)
#include <process.h> /* for getpid() */
#endif

#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>

#include "nspr.h"
#include "prio.h"
#include "prerror.h"
#include "prnetdb.h"
#include "prclist.h"
#include "plgetopt.h"
#include "pk11func.h"
#include "nss.h"
#include "nssb64.h"
#include "sechash.h"
#include "cert.h"
#include "certdb.h"
#include "ocsp.h"
#include "ocspti.h"
#include "ocspi.h"

#ifndef PORT_Sprintf
#define PORT_Sprintf sprintf
#endif

#ifndef PORT_Strstr
#define PORT_Strstr strstr
#endif

#ifndef PORT_Malloc
#define PORT_Malloc PR_Malloc
#endif

static int handle_connection(PRFileDesc *, PRFileDesc *, int);

/* data and structures for shutdown */
static int stopping;

static PRBool noDelay;
static int verbose;

static PRThread *acceptorThread;

static PRLogModuleInfo *lm;

#define PRINTF   \
    if (verbose) \
    printf
#define FPRINTF  \
    if (verbose) \
    fprintf
#define FLUSH           \
    if (verbose) {      \
        fflush(stdout); \
        fflush(stderr); \
    }
#define VLOG(arg) PR_LOG(lm, PR_LOG_DEBUG, arg)

static void
Usage(const char *progName)
{
    fprintf(stderr,

            "Usage: %s -p port [-Dbv]\n"
            "         [-t threads] [-i pid_file]\n"
            "         [-A nickname -C crl-filename]... [-O method]\n"
            "         [-d dbdir] [-f password_file] [-w password] [-P dbprefix]\n"
            "-D means disable Nagle delays in TCP\n"
            "-b means try binding to the port and exit\n"
            "-v means verbose output\n"
            "-t threads -- specify the number of threads to use for connections.\n"
            "-i pid_file file to write the process id of httpserv\n"
            "Parameters -A, -C and -O are used to provide an OCSP server at /ocsp?\n"
            "-A a nickname of a CA certificate\n"
            "-C a CRL filename corresponding to the preceding CA nickname\n"
            "-O allowed HTTP methods for OCSP requests: get, post, all, random, get-unknown\n"
            "   random means: randomly fail if request method is GET, POST always works\n"
            "   get-unknown means: status unknown for GET, correct status for POST\n"
            "Multiple pairs of parameters -A and -C are allowed.\n"
            "If status for a cert from an unknown CA is requested, the cert from the\n"
            "first -A parameter will be used to sign the unknown status response.\n"
            "NSS database parameters are used only if OCSP parameters are used.\n",
            progName);
}

static const char *
errWarn(char *funcString)
{
    PRErrorCode perr = PR_GetError();
    const char *errString = SECU_Strerror(perr);

    fprintf(stderr, "httpserv: %s returned error %d:\n%s\n",
            funcString, perr, errString);
    return errString;
}

static void
errExit(char *funcString)
{
    errWarn(funcString);
    exit(3);
}

#define MAX_VIRT_SERVER_NAME_ARRAY_INDEX 10

/**************************************************************************
** Begin thread management routines and data.
**************************************************************************/
#define MIN_THREADS 3
#define DEFAULT_THREADS 8
#define MAX_THREADS 4096
#define MAX_PROCS 25
static int maxThreads = DEFAULT_THREADS;

typedef struct jobStr {
    PRCList link;
    PRFileDesc *tcp_sock;
    PRFileDesc *model_sock;
    int requestCert;
} JOB;

static PZLock *qLock;             /* this lock protects all data immediately below */
static PRLock *lastLoadedCrlLock; /* this lock protects lastLoadedCrl variable */
static PZCondVar *jobQNotEmptyCv;
static PZCondVar *freeListNotEmptyCv;
static PZCondVar *threadCountChangeCv;
static int threadCount;
static PRCList jobQ;
static PRCList freeJobs;
static JOB *jobTable;

SECStatus
setupJobs(int maxJobs)
{
    int i;

    jobTable = (JOB *)PR_Calloc(maxJobs, sizeof(JOB));
    if (!jobTable)
        return SECFailure;

    PR_INIT_CLIST(&jobQ);
    PR_INIT_CLIST(&freeJobs);

    for (i = 0; i < maxJobs; ++i) {
        JOB *pJob = jobTable + i;
        PR_APPEND_LINK(&pJob->link, &freeJobs);
    }
    return SECSuccess;
}

typedef int startFn(PRFileDesc *a, PRFileDesc *b, int c);

typedef enum { rs_idle = 0,
               rs_running = 1,
               rs_zombie = 2 } runState;

typedef struct perThreadStr {
    PRFileDesc *a;
    PRFileDesc *b;
    int c;
    int rv;
    startFn *startFunc;
    PRThread *prThread;
    runState state;
} perThread;

static perThread *threads;

void
thread_wrapper(void *arg)
{
    perThread *slot = (perThread *)arg;

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

    /* notify the thread exit handler. */
    PZ_Lock(qLock);
    slot->state = rs_zombie;
    --threadCount;
    PZ_NotifyAllCondVar(threadCountChangeCv);
    PZ_Unlock(qLock);
}

int
jobLoop(PRFileDesc *a, PRFileDesc *b, int c)
{
    PRCList *myLink = 0;
    JOB *myJob;

    PZ_Lock(qLock);
    do {
        myLink = 0;
        while (PR_CLIST_IS_EMPTY(&jobQ) && !stopping) {
            PZ_WaitCondVar(jobQNotEmptyCv, PR_INTERVAL_NO_TIMEOUT);
        }
        if (!PR_CLIST_IS_EMPTY(&jobQ)) {
            myLink = PR_LIST_HEAD(&jobQ);
            PR_REMOVE_AND_INIT_LINK(myLink);
        }
        PZ_Unlock(qLock);
        myJob = (JOB *)myLink;
        /* myJob will be null when stopping is true and jobQ is empty */
        if (!myJob)
            break;
        handle_connection(myJob->tcp_sock, myJob->model_sock,
                          myJob->requestCert);
        PZ_Lock(qLock);
        PR_APPEND_LINK(myLink, &freeJobs);
        PZ_NotifyCondVar(freeListNotEmptyCv);
    } while (PR_TRUE);
    return 0;
}

SECStatus
launch_threads(
    startFn *startFunc,
    PRFileDesc *a,
    PRFileDesc *b,
    int c,
    PRBool local)
{
    int i;
    SECStatus rv = SECSuccess;

    /* create the thread management serialization structs */
    qLock = PZ_NewLock(nssILockSelfServ);
    jobQNotEmptyCv = PZ_NewCondVar(qLock);
    freeListNotEmptyCv = PZ_NewCondVar(qLock);
    threadCountChangeCv = PZ_NewCondVar(qLock);

    /* create monitor for crl reload procedure */
    lastLoadedCrlLock = PR_NewLock();

    /* allocate the array of thread slots */
    threads = PR_Calloc(maxThreads, sizeof(perThread));
    if (NULL == threads) {
        fprintf(stderr, "Oh Drat! Can't allocate the perThread array\n");
        return SECFailure;
    }
    /* 5 is a little extra, intended to keep the jobQ from underflowing.
    ** That is, from going empty while not stopping and clients are still
    ** trying to contact us.
    */
    rv = setupJobs(maxThreads + 5);
    if (rv != SECSuccess)
        return rv;

    PZ_Lock(qLock);
    for (i = 0; i < maxThreads; ++i) {
        perThread *slot = threads + i;

        slot->state = rs_running;
        slot->a = a;
        slot->b = b;
        slot->c = c;
        slot->startFunc = startFunc;
        slot->prThread = PR_CreateThread(PR_USER_THREAD,
                                         thread_wrapper, slot, PR_PRIORITY_NORMAL,
                                         (PR_TRUE ==
                                          local)
                                             ? PR_LOCAL_THREAD
                                             : PR_GLOBAL_THREAD,
                                         PR_JOINABLE_THREAD, 0);
        if (slot->prThread == NULL) {
            printf("httpserv: Failed to launch thread!\n");
            slot->state = rs_idle;
            rv = SECFailure;
            break;
        }

        ++threadCount;
    }
    PZ_Unlock(qLock);

    return rv;
}

#define DESTROY_CONDVAR(name)    \
    if (name) {                  \
        PZ_DestroyCondVar(name); \
        name = NULL;             \
    }
#define DESTROY_LOCK(name)    \
    if (name) {               \
        PZ_DestroyLock(name); \
        name = NULL;          \
    }

void
terminateWorkerThreads(void)
{
    int i;

    VLOG(("httpserv: server_thread: waiting on stopping"));
    PZ_Lock(qLock);
    PZ_NotifyAllCondVar(jobQNotEmptyCv);
    PZ_Unlock(qLock);

    /* Wait for worker threads to terminate. */
    for (i = 0; i < maxThreads; ++i) {
        perThread *slot = threads + i;
        if (slot->prThread) {
            PR_JoinThread(slot->prThread);
        }
    }

    /* The worker threads empty the jobQ before they terminate. */
    PZ_Lock(qLock);
    PORT_Assert(threadCount == 0);
    PORT_Assert(PR_CLIST_IS_EMPTY(&jobQ));
    PZ_Unlock(qLock);

    DESTROY_CONDVAR(jobQNotEmptyCv);
    DESTROY_CONDVAR(freeListNotEmptyCv);
    DESTROY_CONDVAR(threadCountChangeCv);

    PR_DestroyLock(lastLoadedCrlLock);
    DESTROY_LOCK(qLock);
    PR_Free(jobTable);
    PR_Free(threads);
}

/**************************************************************************
** End   thread management routines.
**************************************************************************/

PRBool NoReuse = PR_FALSE;
PRBool disableLocking = PR_FALSE;
static secuPWData pwdata = { PW_NONE, 0 };

struct caRevoInfoStr {
    PRCList link;
    char *nickname;
    char *crlFilename;
    CERTCertificate *cert;
    CERTOCSPCertID *id;
    CERTSignedCrl *crl;
};
typedef struct caRevoInfoStr caRevoInfo;
/* Created during app init. No locks necessary,
 * because later on, only read access will occur. */
static caRevoInfo *caRevoInfos = NULL;

static enum {
    ocspGetOnly,
    ocspPostOnly,
    ocspGetAndPost,
    ocspRandomGetFailure,
    ocspGetUnknown
} ocspMethodsAllowed = ocspGetAndPost;

static const char stopCmd[] = { "GET /stop " };
static const char getCmd[] = { "GET " };
static const char outHeader[] = {
    "HTTP/1.0 200 OK\r\n"
    "Server: Generic Web Server\r\n"
    "Date: Tue, 26 Aug 1997 22:10:05 GMT\r\n"
    "Content-type: text/plain\r\n"
    "\r\n"
};
static const char outOcspHeader[] = {
    "HTTP/1.0 200 OK\r\n"
    "Server: Generic OCSP Server\r\n"
    "Content-type: application/ocsp-response\r\n"
    "\r\n"
};
static const char outBadRequestHeader[] = {
    "HTTP/1.0 400 Bad Request\r\n"
    "Server: Generic OCSP Server\r\n"
    "\r\n"
};

void
stop_server()
{
    stopping = 1;
    PR_Interrupt(acceptorThread);
    PZ_TraceFlush();
}

/* Will only work if the original input to url encoding was
 * a base64 encoded buffer. Will only decode the sequences used
 * for encoding the special base64 characters, and fail if any
 * other encoded chars are found.
 * Will return SECSuccess if input could be processed.
 * Coversion is done in place.
 */
static SECStatus
urldecode_base64chars_inplace(char *buf)
{
    char *walk;
    size_t remaining_bytes;

    if (!buf || !*buf)
        return SECFailure;

    walk = buf;
    remaining_bytes = strlen(buf) + 1; /* include terminator */

    while (*walk) {
        if (*walk == '%') {
            if (!PL_strncasecmp(walk, "%2B", 3)) {
                *walk = '+';
            } else if (!PL_strncasecmp(walk, "%2F", 3)) {
                *walk = '/';
            } else if (!PL_strncasecmp(walk, "%3D", 3)) {
                *walk = '=';
            } else {
                return SECFailure;
            }
            remaining_bytes -= 3;
            ++walk;
            memmove(walk, walk + 2, remaining_bytes);
        } else {
            ++walk;
            --remaining_bytes;
        }
    }
    return SECSuccess;
}

int
handle_connection(
    PRFileDesc *tcp_sock,
    PRFileDesc *model_sock,
    int requestCert)
{
    PRFileDesc *ssl_sock = NULL;
    PRFileDesc *local_file_fd = NULL;
    char *pBuf; /* unused space at end of buf */
    const char *errString;
    PRStatus status;
    int bufRem;    /* unused bytes at end of buf */
    int bufDat;    /* characters received in buf */
    int newln = 0; /* # of consecutive newlns */
    int firstTime = 1;
    int reqLen;
    int rv;
    int numIOVs;
    PRSocketOptionData opt;
    PRIOVec iovs[16];
    char msgBuf[160];
    char buf[10240];
    char fileName[513];
    char *getData = NULL; /* inplace conversion */
    SECItem postData;
    PRBool isOcspRequest = PR_FALSE;
    PRBool isPost = PR_FALSE;

    postData.data = NULL;
    postData.len = 0;

    pBuf = buf;
    bufRem = sizeof buf;

    VLOG(("httpserv: handle_connection: starting"));
    opt.option = PR_SockOpt_Nonblocking;
    opt.value.non_blocking = PR_FALSE;
    PR_SetSocketOption(tcp_sock, &opt);

    VLOG(("httpserv: handle_connection: starting\n"));
    ssl_sock = tcp_sock;

    if (noDelay) {
        opt.option = PR_SockOpt_NoDelay;
        opt.value.no_delay = PR_TRUE;
        status = PR_SetSocketOption(ssl_sock, &opt);
        if (status != PR_SUCCESS) {
            errWarn("PR_SetSocketOption(PR_SockOpt_NoDelay, PR_TRUE)");
            if (ssl_sock) {
                PR_Close(ssl_sock);
            }
            return SECFailure;
        }
    }

    while (1) {
        const char *post;
        const char *foundStr = NULL;
        const char *tmp = NULL;

        newln = 0;
        reqLen = 0;

        rv = PR_Read(ssl_sock, pBuf, bufRem - 1);
        if (rv == 0 ||
            (rv < 0 && PR_END_OF_FILE_ERROR == PR_GetError())) {
            if (verbose)
                errWarn("HDX PR_Read hit EOF");
            break;
        }
        if (rv < 0) {
            errWarn("HDX PR_Read");
            goto cleanup;
        }
        /* NULL termination */
        pBuf[rv] = 0;
        if (firstTime) {
            firstTime = 0;
        }

        pBuf += rv;
        bufRem -= rv;
        bufDat = pBuf - buf;
        /* Parse the input, starting at the beginning of the buffer.
         * Stop when we detect two consecutive \n's (or \r\n's)
         * as this signifies the end of the GET or POST portion.
         * The posted data follows.
         */
        while (reqLen < bufDat && newln < 2) {
            int octet = buf[reqLen++];
            if (octet == '\n') {
                newln++;
            } else if (octet != '\r') {
                newln = 0;
            }
        }

        /* came to the end of the buffer, or second newln
         * If we didn't get an empty line (CRLFCRLF) then keep on reading.
         */
        if (newln < 2)
            continue;

        /* we're at the end of the HTTP request.
         * If the request is a POST, then there will be one more
         * line of data.
         * This parsing is a hack, but ok for SSL test purposes.
         */
        post = PORT_Strstr(buf, "POST ");
        if (!post || *post != 'P')
            break;

        postData.data = (void *)(buf + reqLen);

        tmp = "content-length: ";
        foundStr = PL_strcasestr(buf, tmp);
        if (foundStr) {
            int expectedPostLen;
            int havePostLen;

            expectedPostLen = atoi(foundStr + strlen(tmp));
            havePostLen = bufDat - reqLen;
            if (havePostLen >= expectedPostLen) {
                postData.len = expectedPostLen;
                break;
            }
        } else {
            /* use legacy hack */
            /* It's a post, so look for the next and final CR/LF. */
            while (reqLen < bufDat && newln < 3) {
                int octet = buf[reqLen++];
                if (octet == '\n') {
                    newln++;
                }
            }
            if (newln == 3)
                break;
        }
    } /* read loop */

    bufDat = pBuf - buf;
    if (bufDat)
        do { /* just close if no data */
            /* Have either (a) a complete get, (b) a complete post, (c) EOF */
            if (reqLen > 0) {
                PRBool isGetOrPost = PR_FALSE;
                unsigned skipChars = 0;
                isPost = PR_FALSE;

                if (!strncmp(buf, getCmd, sizeof getCmd - 1)) {
                    isGetOrPost = PR_TRUE;
                    skipChars = 4;
                } else if (!strncmp(buf, "POST ", 5)) {
                    isGetOrPost = PR_TRUE;
                    isPost = PR_TRUE;
                    skipChars = 5;
                }

                if (isGetOrPost) {
                    char *fnBegin = buf;
                    char *fnEnd;
                    char *fnstart = NULL;
                    PRFileInfo info;

                    fnBegin += skipChars;

                    fnEnd = strpbrk(fnBegin, " \r\n");
                    if (fnEnd) {
                        int fnLen = fnEnd - fnBegin;
                        if (fnLen < sizeof fileName) {
                            strncpy(fileName, fnBegin, fnLen);
                            fileName[fnLen] = 0; /* null terminate */
                            fnstart = fileName;
                            /* strip initial / because our root is the current directory*/
                            while (*fnstart && *fnstart == '/')
                                ++fnstart;
                        }
                    }
                    if (fnstart) {
                        if (!strncmp(fnstart, "ocsp", 4)) {
                            if (isPost) {
                                if (postData.data) {
                                    isOcspRequest = PR_TRUE;
                                }
                            } else {
                                if (!strncmp(fnstart, "ocsp/", 5)) {
                                    isOcspRequest = PR_TRUE;
                                    getData = fnstart + 5;
                                }
                            }
                        } else {
                            /* try to open the file named.
                             * If successful, then write it to the client.
                             */
                            status = PR_GetFileInfo(fnstart, &info);
                            if (status == PR_SUCCESS &&
                                info.type == PR_FILE_FILE &&
                                info.size >= 0) {
                                local_file_fd = PR_Open(fnstart, PR_RDONLY, 0);
                            }
                        }
                    }
                }
            }

            numIOVs = 0;

            iovs[numIOVs].iov_base = (char *)outHeader;
            iovs[numIOVs].iov_len = (sizeof(outHeader)) - 1;
            numIOVs++;

            if (isOcspRequest && caRevoInfos) {
                CERTOCSPRequest *request = NULL;
                PRBool failThisRequest = PR_FALSE;
                PLArenaPool *arena = NULL;

                if (ocspMethodsAllowed == ocspGetOnly && postData.len) {
                    failThisRequest = PR_TRUE;
                } else if (ocspMethodsAllowed == ocspPostOnly && getData) {
                    failThisRequest = PR_TRUE;
                } else if (ocspMethodsAllowed == ocspRandomGetFailure && getData) {
                    if (!(rand() % 2)) {
                        failThisRequest = PR_TRUE;
                    }
                }

                if (failThisRequest) {
                    PR_Write(ssl_sock, outBadRequestHeader, strlen(outBadRequestHeader));
                    break;
                }
                /* get is base64, post is binary.
                 * If we have base64, convert into the (empty) postData array.
                 */
                if (getData) {
                    if (urldecode_base64chars_inplace(getData) == SECSuccess) {
                        /* The code below can handle a NULL arena */
                        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
                        NSSBase64_DecodeBuffer(arena, &postData, getData, strlen(getData));
                    }
                }
                if (postData.len) {
                    request = CERT_DecodeOCSPRequest(&postData);
                }
                if (arena) {
                    PORT_FreeArena(arena, PR_FALSE);
                    arena = NULL;
                }
                if (!request || !request->tbsRequest ||
                    !request->tbsRequest->requestList ||
                    !request->tbsRequest->requestList[0]) {
                    PORT_Sprintf(msgBuf, "Cannot decode OCSP request.\r\n");

                    iovs[numIOVs].iov_base = msgBuf;
                    iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
                    numIOVs++;
                } else {
                    /* TODO: support more than one request entry */
                    CERTOCSPCertID *reqid = request->tbsRequest->requestList[0]->reqCert;
                    const caRevoInfo *revoInfo = NULL;
                    PRBool unknown = PR_FALSE;
                    PRBool revoked = PR_FALSE;
                    PRTime nextUpdate = 0;
                    PRTime revoDate = 0;
                    PRCList *caRevoIter;

                    caRevoIter = &caRevoInfos->link;
                    do {
                        CERTOCSPCertID *caid;

                        revoInfo = (caRevoInfo *)caRevoIter;
                        caid = revoInfo->id;

                        if (SECOID_CompareAlgorithmID(&reqid->hashAlgorithm,
                                                      &caid->hashAlgorithm) == SECEqual &&
                            SECITEM_CompareItem(&reqid->issuerNameHash,
                                                &caid->issuerNameHash) == SECEqual &&
                            SECITEM_CompareItem(&reqid->issuerKeyHash,
                                                &caid->issuerKeyHash) == SECEqual) {
                            break;
                        }
                        revoInfo = NULL;
                        caRevoIter = PR_NEXT_LINK(caRevoIter);
                    } while (caRevoIter != &caRevoInfos->link);

                    if (!revoInfo) {
                        unknown = PR_TRUE;
                        revoInfo = caRevoInfos;
                    } else {
                        CERTCrl *crl = &revoInfo->crl->crl;
                        CERTCrlEntry *entry = NULL;
                        DER_DecodeTimeChoice(&nextUpdate, &crl->nextUpdate);
                        if (crl->entries) {
                            int iv = 0;
                            /* assign, not compare */
                            while ((entry = crl->entries[iv++])) {
                                if (SECITEM_CompareItem(&reqid->serialNumber,
                                                        &entry->serialNumber) == SECEqual) {
                                    break;
                                }
                            }
                        }
                        if (entry) {
                            /* revoked status response */
                            revoked = PR_TRUE;
                            DER_DecodeTimeChoice(&revoDate, &entry->revocationDate);
                        } else {
                            /* else good status response */
                            if (!isPost && ocspMethodsAllowed == ocspGetUnknown) {
                                unknown = PR_TRUE;
                                nextUpdate = PR_Now() + (PRTime)60 * 60 * 24 * PR_USEC_PER_SEC; /*tomorrow*/
                                revoDate = PR_Now() - (PRTime)60 * 60 * 24 * PR_USEC_PER_SEC;   /*yesterday*/
                            }
                        }
                    }

                    {
                        PRTime now = PR_Now();
                        CERTOCSPSingleResponse *sr;
                        CERTOCSPSingleResponse **singleResponses;
                        SECItem *ocspResponse;

                        PORT_Assert(!arena);
                        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

                        if (unknown) {
                            sr = CERT_CreateOCSPSingleResponseUnknown(arena, reqid, now,
                                                                      &nextUpdate);
                        } else if (revoked) {
                            sr = CERT_CreateOCSPSingleResponseRevoked(arena, reqid, now,
                                                                      &nextUpdate, revoDate, NULL);
                        } else {
                            sr = CERT_CreateOCSPSingleResponseGood(arena, reqid, now,
                                                                   &nextUpdate);
                        }

                        /* meaning of value 2: one entry + one end marker */
                        singleResponses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse *, 2);
                        singleResponses[0] = sr;
                        singleResponses[1] = NULL;
                        ocspResponse = CERT_CreateEncodedOCSPSuccessResponse(arena,
                                                                             revoInfo->cert, ocspResponderID_byName, now,
                                                                             singleResponses, &pwdata);

                        if (!ocspResponse) {
                            PORT_Sprintf(msgBuf, "Failed to encode response\r\n");
                            iovs[numIOVs].iov_base = msgBuf;
                            iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
                            numIOVs++;
                        } else {
                            PR_Write(ssl_sock, outOcspHeader, strlen(outOcspHeader));
                            PR_Write(ssl_sock, ocspResponse->data, ocspResponse->len);
                        }
                        PORT_FreeArena(arena, PR_FALSE);
                    }
                    CERT_DestroyOCSPRequest(request);
                    break;
                }
            } else if (local_file_fd) {
                PRInt32 bytes;
                int errLen;
                bytes = PR_TransmitFile(ssl_sock, local_file_fd, outHeader,
                                        sizeof outHeader - 1,
                                        PR_TRANSMITFILE_KEEP_OPEN,
                                        PR_INTERVAL_NO_TIMEOUT);
                if (bytes >= 0) {
                    bytes -= sizeof outHeader - 1;
                    FPRINTF(stderr,
                            "httpserv: PR_TransmitFile wrote %d bytes from %s\n",
                            bytes, fileName);
                    break;
                }
                errString = errWarn("PR_TransmitFile");
                errLen = PORT_Strlen(errString);
                errLen = PR_MIN(errLen, sizeof msgBuf - 1);
                PORT_Memcpy(msgBuf, errString, errLen);
                msgBuf[errLen] = 0;

                iovs[numIOVs].iov_base = msgBuf;
                iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
                numIOVs++;
            } else if (reqLen <= 0) { /* hit eof */
                PORT_Sprintf(msgBuf, "Get or Post incomplete after %d bytes.\r\n",
                             bufDat);

                iovs[numIOVs].iov_base = msgBuf;
                iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
                numIOVs++;
            } else if (reqLen < bufDat) {
                PORT_Sprintf(msgBuf, "Discarded %d characters.\r\n",
                             bufDat - reqLen);

                iovs[numIOVs].iov_base = msgBuf;
                iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
                numIOVs++;
            }

            if (reqLen > 0) {
                if (verbose > 1)
                    fwrite(buf, 1, reqLen, stdout); /* display it */

                iovs[numIOVs].iov_base = buf;
                iovs[numIOVs].iov_len = reqLen;
                numIOVs++;
            }

            rv = PR_Writev(ssl_sock, iovs, numIOVs, PR_INTERVAL_NO_TIMEOUT);
            if (rv < 0) {
                errWarn("PR_Writev");
                break;
            }

        } while (0);

cleanup:
    if (ssl_sock) {
        PR_Close(ssl_sock);
    } else if (tcp_sock) {
        PR_Close(tcp_sock);
    }
    if (local_file_fd)
        PR_Close(local_file_fd);
    VLOG(("httpserv: handle_connection: exiting\n"));

    /* do a nice shutdown if asked. */
    if (!strncmp(buf, stopCmd, sizeof stopCmd - 1)) {
        VLOG(("httpserv: handle_connection: stop command"));
        stop_server();
    }
    VLOG(("httpserv: handle_connection: exiting"));
    return SECSuccess; /* success */
}

#ifdef XP_UNIX

void
sigusr1_handler(int sig)
{
    VLOG(("httpserv: sigusr1_handler: stop server"));
    stop_server();
}

#endif

SECStatus
do_accepts(
    PRFileDesc *listen_sock,
    PRFileDesc *model_sock,
    int requestCert)
{
    PRNetAddr addr;
    PRErrorCode perr;
#ifdef XP_UNIX
    struct sigaction act;
#endif

    VLOG(("httpserv: do_accepts: starting"));
    PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_HIGH);

    acceptorThread = PR_GetCurrentThread();
#ifdef XP_UNIX
    /* set up the signal handler */
    act.sa_handler = sigusr1_handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    if (sigaction(SIGUSR1, &act, NULL)) {
        fprintf(stderr, "Error installing signal handler.\n");
        exit(1);
    }
#endif
    while (!stopping) {
        PRFileDesc *tcp_sock;
        PRCList *myLink;

        FPRINTF(stderr, "\n\n\nhttpserv: About to call accept.\n");
        tcp_sock = PR_Accept(listen_sock, &addr, PR_INTERVAL_NO_TIMEOUT);
        if (tcp_sock == NULL) {
            perr = PR_GetError();
            if ((perr != PR_CONNECT_RESET_ERROR &&
                 perr != PR_PENDING_INTERRUPT_ERROR) ||
                verbose) {
                errWarn("PR_Accept");
            }
            if (perr == PR_CONNECT_RESET_ERROR) {
                FPRINTF(stderr,
                        "Ignoring PR_CONNECT_RESET_ERROR error - continue\n");
                continue;
            }
            stopping = 1;
            break;
        }

        VLOG(("httpserv: do_accept: Got connection\n"));

        PZ_Lock(qLock);
        while (PR_CLIST_IS_EMPTY(&freeJobs) && !stopping) {
            PZ_WaitCondVar(freeListNotEmptyCv, PR_INTERVAL_NO_TIMEOUT);
        }
        if (stopping) {
            PZ_Unlock(qLock);
            if (tcp_sock) {
                PR_Close(tcp_sock);
            }
            break;
        }
        myLink = PR_LIST_HEAD(&freeJobs);
        PR_REMOVE_AND_INIT_LINK(myLink);
        /* could release qLock here and reaquire it 7 lines below, but
        ** why bother for 4 assignment statements?
        */
        {
            JOB *myJob = (JOB *)myLink;
            myJob->tcp_sock = tcp_sock;
            myJob->model_sock = model_sock;
            myJob->requestCert = requestCert;
        }

        PR_APPEND_LINK(myLink, &jobQ);
        PZ_NotifyCondVar(jobQNotEmptyCv);
        PZ_Unlock(qLock);
    }

    FPRINTF(stderr, "httpserv: Closing listen socket.\n");
    VLOG(("httpserv: do_accepts: exiting"));
    if (listen_sock) {
        PR_Close(listen_sock);
    }
    return SECSuccess;
}

PRFileDesc *
getBoundListenSocket(unsigned short port)
{
    PRFileDesc *listen_sock;
    int listenQueueDepth = 5 + (2 * maxThreads);
    PRStatus prStatus;
    PRNetAddr addr;
    PRSocketOptionData opt;

    addr.inet.family = PR_AF_INET;
    addr.inet.ip = PR_INADDR_ANY;
    addr.inet.port = PR_htons(port);

    listen_sock = PR_NewTCPSocket();
    if (listen_sock == NULL) {
        errExit("PR_NewTCPSocket");
    }

    opt.option = PR_SockOpt_Nonblocking;
    opt.value.non_blocking = PR_FALSE;
    prStatus = PR_SetSocketOption(listen_sock, &opt);
    if (prStatus < 0) {
        PR_Close(listen_sock);
        errExit("PR_SetSocketOption(PR_SockOpt_Nonblocking)");
    }

    opt.option = PR_SockOpt_Reuseaddr;
    opt.value.reuse_addr = PR_TRUE;
    prStatus = PR_SetSocketOption(listen_sock, &opt);
    if (prStatus < 0) {
        PR_Close(listen_sock);
        errExit("PR_SetSocketOption(PR_SockOpt_Reuseaddr)");
    }

#ifndef WIN95
    /* Set PR_SockOpt_Linger because it helps prevent a server bind issue
     * after clean shutdown . See bug 331413 .
     * Don't do it in the WIN95 build configuration because clean shutdown is
     * not implemented, and PR_SockOpt_Linger causes a hang in ssl.sh .
     * See bug 332348 */
    opt.option = PR_SockOpt_Linger;
    opt.value.linger.polarity = PR_TRUE;
    opt.value.linger.linger = PR_SecondsToInterval(1);
    prStatus = PR_SetSocketOption(listen_sock, &opt);
    if (prStatus < 0) {
        PR_Close(listen_sock);
        errExit("PR_SetSocketOption(PR_SockOpt_Linger)");
    }
#endif

    prStatus = PR_Bind(listen_sock, &addr);
    if (prStatus < 0) {
        PR_Close(listen_sock);
        errExit("PR_Bind");
    }

    prStatus = PR_Listen(listen_sock, listenQueueDepth);
    if (prStatus < 0) {
        PR_Close(listen_sock);
        errExit("PR_Listen");
    }
    return listen_sock;
}

void
server_main(
    PRFileDesc *listen_sock,
    int requestCert,
    SECKEYPrivateKey **privKey,
    CERTCertificate **cert,
    const char *expectedHostNameVal)
{
    PRFileDesc *model_sock = NULL;

    /* Now, do the accepting, here in the main thread. */
    do_accepts(listen_sock, model_sock, requestCert);

    terminateWorkerThreads();

    if (model_sock) {
        PR_Close(model_sock);
    }
}

int numChildren;
PRProcess *child[MAX_PROCS];

PRProcess *
haveAChild(int argc, char **argv, PRProcessAttr *attr)
{
    PRProcess *newProcess;

    newProcess = PR_CreateProcess(argv[0], argv, NULL, attr);
    if (!newProcess) {
        errWarn("Can't create new process.");
    } else {
        child[numChildren++] = newProcess;
    }
    return newProcess;
}

/* slightly adjusted version of ocsp_CreateCertID (not using issuer) */
static CERTOCSPCertID *
ocsp_CreateSelfCAID(PLArenaPool *arena, CERTCertificate *cert, PRTime time)
{
    CERTOCSPCertID *certID;
    void *mark = PORT_ArenaMark(arena);
    SECStatus rv;

    PORT_Assert(arena != NULL);

    certID = PORT_ArenaZNew(arena, CERTOCSPCertID);
    if (certID == NULL) {
        goto loser;
    }

    rv = SECOID_SetAlgorithmID(arena, &certID->hashAlgorithm, SEC_OID_SHA1,
                               NULL);
    if (rv != SECSuccess) {
        goto loser;
    }

    if (CERT_GetSubjectNameDigest(arena, cert, SEC_OID_SHA1,
                                  &(certID->issuerNameHash)) == NULL) {
        goto loser;
    }
    certID->issuerSHA1NameHash.data = certID->issuerNameHash.data;
    certID->issuerSHA1NameHash.len = certID->issuerNameHash.len;

    if (CERT_GetSubjectNameDigest(arena, cert, SEC_OID_MD5,
                                  &(certID->issuerMD5NameHash)) == NULL) {
        goto loser;
    }

    if (CERT_GetSubjectNameDigest(arena, cert, SEC_OID_MD2,
                                  &(certID->issuerMD2NameHash)) == NULL) {
        goto loser;
    }

    if (CERT_GetSubjectPublicKeyDigest(arena, cert, SEC_OID_SHA1,
                                       &certID->issuerKeyHash) == NULL) {
        goto loser;
    }
    certID->issuerSHA1KeyHash.data = certID->issuerKeyHash.data;
    certID->issuerSHA1KeyHash.len = certID->issuerKeyHash.len;
    /* cache the other two hash algorithms as well */
    if (CERT_GetSubjectPublicKeyDigest(arena, cert, SEC_OID_MD5,
                                       &certID->issuerMD5KeyHash) == NULL) {
        goto loser;
    }
    if (CERT_GetSubjectPublicKeyDigest(arena, cert, SEC_OID_MD2,
                                       &certID->issuerMD2KeyHash) == NULL) {
        goto loser;
    }

    PORT_ArenaUnmark(arena, mark);
    return certID;

loser:
    PORT_ArenaRelease(arena, mark);
    return NULL;
}

/* slightly adjusted version of CERT_CreateOCSPCertID */
CERTOCSPCertID *
cert_CreateSelfCAID(CERTCertificate *cert, PRTime time)
{
    PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    CERTOCSPCertID *certID;
    PORT_Assert(arena != NULL);
    if (!arena)
        return NULL;

    certID = ocsp_CreateSelfCAID(arena, cert, time);
    if (!certID) {
        PORT_FreeArena(arena, PR_FALSE);
        return NULL;
    }
    certID->poolp = arena;
    return certID;
}

int
main(int argc, char **argv)
{
    char *progName = NULL;
    const char *dir = ".";
    char *passwd = NULL;
    char *pwfile = NULL;
    const char *pidFile = NULL;
    char *tmp;
    PRFileDesc *listen_sock;
    int optionsFound = 0;
    unsigned short port = 0;
    SECStatus rv;
    PRStatus prStatus;
    PRBool bindOnly = PR_FALSE;
    PRBool useLocalThreads = PR_FALSE;
    PLOptState *optstate;
    PLOptStatus status;
    char emptyString[] = { "" };
    char *certPrefix = emptyString;
    caRevoInfo *revoInfo = NULL;
    PRCList *caRevoIter = NULL;
    PRBool provideOcsp = PR_FALSE;

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

    PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);

    /* please keep this list of options in ASCII collating sequence.
    ** numbers, then capital letters, then lower case, alphabetical.
    */
    optstate = PL_CreateOptState(argc, argv,
                                 "A:C:DO:P:bd:f:hi:p:t:vw:");
    while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
        ++optionsFound;
        switch (optstate->option) {
            /* A first, must be followed by C. Any other order is an error.
             * A creates the object. C completes and moves into list.
             */
            case 'A':
                provideOcsp = PR_TRUE;
                if (revoInfo) {
                    Usage(progName);
                    exit(0);
                }
                revoInfo = PORT_New(caRevoInfo);
                revoInfo->nickname = PORT_Strdup(optstate->value);
                break;
            case 'C':
                if (!revoInfo) {
                    Usage(progName);
                    exit(0);
                }
                revoInfo->crlFilename = PORT_Strdup(optstate->value);
                if (!caRevoInfos) {
                    PR_INIT_CLIST(&revoInfo->link);
                    caRevoInfos = revoInfo;
                } else {
                    PR_APPEND_LINK(&revoInfo->link, &caRevoInfos->link);
                }
                revoInfo = NULL;
                break;

            case 'O':
                if (!PL_strcasecmp(optstate->value, "all")) {
                    ocspMethodsAllowed = ocspGetAndPost;
                } else if (!PL_strcasecmp(optstate->value, "get")) {
                    ocspMethodsAllowed = ocspGetOnly;
                } else if (!PL_strcasecmp(optstate->value, "post")) {
                    ocspMethodsAllowed = ocspPostOnly;
                } else if (!PL_strcasecmp(optstate->value, "random")) {
                    ocspMethodsAllowed = ocspRandomGetFailure;
                } else if (!PL_strcasecmp(optstate->value, "get-unknown")) {
                    ocspMethodsAllowed = ocspGetUnknown;
                } else {
                    Usage(progName);
                    exit(0);
                }
                break;

            case 'D':
                noDelay = PR_TRUE;
                break;

            case 'P':
                certPrefix = PORT_Strdup(optstate->value);
                break;

            case 'b':
                bindOnly = PR_TRUE;
                break;

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

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

            case 'h':
                Usage(progName);
                exit(0);
                break;

            case 'i':
                pidFile = optstate->value;
                break;

            case 'p':
                port = PORT_Atoi(optstate->value);
                break;

            case 't':
                maxThreads = PORT_Atoi(optstate->value);
                if (maxThreads > MAX_THREADS)
                    maxThreads = MAX_THREADS;
                if (maxThreads < MIN_THREADS)
                    maxThreads = MIN_THREADS;
                break;

            case 'v':
                verbose++;
                break;

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

            default:
            case '?':
                fprintf(stderr, "Unrecognized or bad option specified.\n");
                fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
                exit(4);
                break;
        }
    }
    PL_DestroyOptState(optstate);
    if (status == PL_OPT_BAD) {
        fprintf(stderr, "Unrecognized or bad option specified.\n");
        fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
        exit(5);
    }
    if (!optionsFound) {
        Usage(progName);
        exit(51);
    }

    /* The -b (bindOnly) option is only used by the ssl.sh test
     * script on Linux to determine whether a previous httpserv
     * process has fully died and freed the port.  (Bug 129701)
     */
    if (bindOnly) {
        listen_sock = getBoundListenSocket(port);
        if (!listen_sock) {
            exit(1);
        }
        if (listen_sock) {
            PR_Close(listen_sock);
        }
        exit(0);
    }

    if (port == 0) {
        fprintf(stderr, "Required argument 'port' must be non-zero value\n");
        exit(7);
    }

    if (pidFile) {
        FILE *tmpfile = fopen(pidFile, "w+");

        if (tmpfile) {
            fprintf(tmpfile, "%d", getpid());
            fclose(tmpfile);
        }
    }

    tmp = PR_GetEnvSecure("TMP");
    if (!tmp)
        tmp = PR_GetEnvSecure("TMPDIR");
    if (!tmp)
        tmp = PR_GetEnvSecure("TEMP");
    /* we're an ordinary single process server. */
    listen_sock = getBoundListenSocket(port);
    prStatus = PR_SetFDInheritable(listen_sock, PR_FALSE);
    if (prStatus != PR_SUCCESS)
        errExit("PR_SetFDInheritable");

    lm = PR_NewLogModule("TestCase");

    /* set our password function */
    PK11_SetPasswordFunc(SECU_GetModulePassword);

    if (provideOcsp) {
        /* Call the NSS initialization routines */
        rv = NSS_Initialize(dir, certPrefix, certPrefix, SECMOD_DB, NSS_INIT_READONLY);
        if (rv != SECSuccess) {
            fputs("NSS_Init failed.\n", stderr);
            exit(8);
        }

        if (caRevoInfos) {
            caRevoIter = &caRevoInfos->link;
            do {
                PRFileDesc *inFile;
                SECItem crlDER;
                crlDER.data = NULL;

                revoInfo = (caRevoInfo *)caRevoIter;
                revoInfo->cert = CERT_FindCertByNickname(
                    CERT_GetDefaultCertDB(), revoInfo->nickname);
                if (!revoInfo->cert) {
                    fprintf(stderr, "cannot find cert with nickname %s\n",
                            revoInfo->nickname);
                    exit(1);
                }
                inFile = PR_Open(revoInfo->crlFilename, PR_RDONLY, 0);
                if (inFile) {
                    rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE, PR_FALSE);
                    PR_Close(inFile);
                    inFile = NULL;
                }
                if (rv != SECSuccess) {
                    fprintf(stderr, "unable to read crl file %s\n",
                            revoInfo->crlFilename);
                    exit(1);
                }
                revoInfo->crl =
                    CERT_DecodeDERCrlWithFlags(NULL, &crlDER, SEC_CRL_TYPE,
                                               CRL_DECODE_DEFAULT_OPTIONS);
                SECITEM_FreeItem(&crlDER, PR_FALSE);
                if (!revoInfo->crl) {
                    fprintf(stderr, "unable to decode crl file %s\n",
                            revoInfo->crlFilename);
                    exit(1);
                }
                if (CERT_CompareName(&revoInfo->crl->crl.name,
                                     &revoInfo->cert->subject) != SECEqual) {
                    fprintf(stderr, "CRL %s doesn't match cert identified by preceding nickname %s\n",
                            revoInfo->crlFilename, revoInfo->nickname);
                    exit(1);
                }
                revoInfo->id = cert_CreateSelfCAID(revoInfo->cert, PR_Now());
                caRevoIter = PR_NEXT_LINK(caRevoIter);
            } while (caRevoIter != &caRevoInfos->link);
        }
    }

    /* allocate the array of thread slots, and launch the worker threads. */
    rv = launch_threads(&jobLoop, 0, 0, 0, useLocalThreads);

    if (rv == SECSuccess) {
        server_main(listen_sock, 0, 0, 0,
                    0);
    }

    VLOG(("httpserv: server_thread: exiting"));

    if (provideOcsp) {
        if (caRevoInfos) {
            caRevoIter = &caRevoInfos->link;
            do {
                revoInfo = (caRevoInfo *)caRevoIter;
                if (revoInfo->nickname)
                    PORT_Free(revoInfo->nickname);
                if (revoInfo->crlFilename)
                    PORT_Free(revoInfo->crlFilename);
                if (revoInfo->cert)
                    CERT_DestroyCertificate(revoInfo->cert);
                if (revoInfo->id)
                    CERT_DestroyOCSPCertID(revoInfo->id);
                if (revoInfo->crl)
                    SEC_DestroyCrl(revoInfo->crl);

                caRevoIter = PR_NEXT_LINK(caRevoIter);
            } while (caRevoIter != &caRevoInfos->link);
        }
        if (NSS_Shutdown() != SECSuccess) {
            SECU_PrintError(progName, "NSS_Shutdown");
            PR_Cleanup();
            exit(1);
        }
    }
    if (passwd) {
        PORT_Free(passwd);
    }
    if (pwfile) {
        PORT_Free(pwfile);
    }
    if (certPrefix && certPrefix != emptyString) {
        PORT_Free(certPrefix);
    }
    PR_Cleanup();
    printf("httpserv: normal termination\n");
    return 0;
}
