/* 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;

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