/*
 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/* Very basic HTTP server */

#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
/*
 * On VMS, you need to define this to get the declaration of fileno().  The
 * value 2 is to make sure no function defined in POSIX-2 is left undefined.
 */
# define _POSIX_C_SOURCE 2
#endif

#include <string.h>
#include <ctype.h>
#include "http_server.h"
#include "internal/sockets.h"
#include <openssl/err.h>
#include <openssl/rand.h>
#include "s_apps.h"

#if defined(__TANDEM)
# if defined(OPENSSL_TANDEM_FLOSS)
#  include <floss.h(floss_fork)>
# endif
#endif

static int verbosity = LOG_INFO;

#define HTTP_PREFIX "HTTP/"
#define HTTP_VERSION_PATT "1." /* allow 1.x */
#define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT
#define HTTP_1_0 HTTP_PREFIX_VERSION"0" /* "HTTP/1.0" */

#ifdef HTTP_DAEMON

int multi = 0; /* run multiple responder processes */
int acfd = (int) INVALID_SOCKET;

static int print_syslog(const char *str, size_t len, void *levPtr)
{
    int level = *(int *)levPtr;
    int ilen = len > MAXERRLEN ? MAXERRLEN : len;

    syslog(level, "%.*s", ilen, str);

    return ilen;
}
#endif

void log_message(const char *prog, int level, const char *fmt, ...)
{
    va_list ap;

    if (verbosity < level)
        return;

    va_start(ap, fmt);
#ifdef HTTP_DAEMON
    if (multi) {
        char buf[1024];

        if (vsnprintf(buf, sizeof(buf), fmt, ap) > 0)
            syslog(level, "%s", buf);
        if (level <= LOG_ERR)
            ERR_print_errors_cb(print_syslog, &level);
    } else
#endif
    {
        BIO_printf(bio_err, "%s: ", prog);
        BIO_vprintf(bio_err, fmt, ap);
        BIO_printf(bio_err, "\n");
        (void)BIO_flush(bio_err);
    }
    va_end(ap);
}

#ifdef HTTP_DAEMON
void socket_timeout(int signum)
{
    if (acfd != (int)INVALID_SOCKET)
        (void)shutdown(acfd, SHUT_RD);
}

static void killall(int ret, pid_t *kidpids)
{
    int i;

    for (i = 0; i < multi; ++i)
        if (kidpids[i] != 0)
            (void)kill(kidpids[i], SIGTERM);
    OPENSSL_free(kidpids);
    ossl_sleep(1000);
    exit(ret);
}

static int termsig = 0;

static void noteterm(int sig)
{
    termsig = sig;
}

/*
 * Loop spawning up to `multi` child processes, only child processes return
 * from this function.  The parent process loops until receiving a termination
 * signal, kills extant children and exits without returning.
 */
void spawn_loop(const char *prog)
{
    pid_t *kidpids = NULL;
    int status;
    int procs = 0;
    int i;

    openlog(prog, LOG_PID, LOG_DAEMON);

    if (setpgid(0, 0)) {
        syslog(LOG_ERR, "fatal: error detaching from parent process group: %s",
               strerror(errno));
        exit(1);
    }
    kidpids = app_malloc(multi * sizeof(*kidpids), "child PID array");
    for (i = 0; i < multi; ++i)
        kidpids[i] = 0;

    signal(SIGINT, noteterm);
    signal(SIGTERM, noteterm);

    while (termsig == 0) {
        pid_t fpid;

        /*
         * Wait for a child to replace when we're at the limit.
         * Slow down if a child exited abnormally or waitpid() < 0
         */
        while (termsig == 0 && procs >= multi) {
            if ((fpid = waitpid(-1, &status, 0)) > 0) {
                for (i = 0; i < procs; ++i) {
                    if (kidpids[i] == fpid) {
                        kidpids[i] = 0;
                        --procs;
                        break;
                    }
                }
                if (i >= multi) {
                    syslog(LOG_ERR, "fatal: internal error: "
                           "no matching child slot for pid: %ld",
                           (long) fpid);
                    killall(1, kidpids);
                }
                if (status != 0) {
                    if (WIFEXITED(status))
                        syslog(LOG_WARNING, "child process: %ld, exit status: %d",
                               (long)fpid, WEXITSTATUS(status));
                    else if (WIFSIGNALED(status))
                        syslog(LOG_WARNING, "child process: %ld, term signal %d%s",
                               (long)fpid, WTERMSIG(status),
# ifdef WCOREDUMP
                               WCOREDUMP(status) ? " (core dumped)" :
# endif
                               "");
                    ossl_sleep(1000);
                }
                break;
            } else if (errno != EINTR) {
                syslog(LOG_ERR, "fatal: waitpid(): %s", strerror(errno));
                killall(1, kidpids);
            }
        }
        if (termsig)
            break;

        switch (fpid = fork()) {
        case -1: /* error */
            /* System critically low on memory, pause and try again later */
            ossl_sleep(30000);
            break;
        case 0: /* child */
            OPENSSL_free(kidpids);
            signal(SIGINT, SIG_DFL);
            signal(SIGTERM, SIG_DFL);
            if (termsig)
                _exit(0);
            if (RAND_poll() <= 0) {
                syslog(LOG_ERR, "fatal: RAND_poll() failed");
                _exit(1);
            }
            return;
        default:            /* parent */
            for (i = 0; i < multi; ++i) {
                if (kidpids[i] == 0) {
                    kidpids[i] = fpid;
                    procs++;
                    break;
                }
            }
            if (i >= multi) {
                syslog(LOG_ERR, "fatal: internal error: no free child slots");
                killall(1, kidpids);
            }
            break;
        }
    }

    /* The loop above can only break on termsig */
    syslog(LOG_INFO, "terminating on signal: %d", termsig);
    killall(0, kidpids);
}
#endif

#ifndef OPENSSL_NO_SOCK
BIO *http_server_init_bio(const char *prog, const char *port)
{
    BIO *acbio = NULL, *bufbio;
    int asock;

    bufbio = BIO_new(BIO_f_buffer());
    if (bufbio == NULL)
        goto err;
    acbio = BIO_new(BIO_s_accept());
    if (acbio == NULL
        || BIO_set_bind_mode(acbio, BIO_BIND_REUSEADDR) < 0
        || BIO_set_accept_port(acbio, port) < 0) {
        log_message(prog, LOG_ERR, "Error setting up accept BIO");
        goto err;
    }

    BIO_set_accept_bios(acbio, bufbio);
    bufbio = NULL;
    if (BIO_do_accept(acbio) <= 0) {
        log_message(prog, LOG_ERR, "Error starting accept");
        goto err;
    }

    /* Report back what address and port are used */
    BIO_get_fd(acbio, &asock);
    if (!report_server_accept(bio_out, asock, 1, 1)) {
        log_message(prog, LOG_ERR, "Error printing ACCEPT string");
        goto err;
    }

    return acbio;

 err:
    BIO_free_all(acbio);
    BIO_free(bufbio);
    return NULL;
}

/*
 * Decode %xx URL-decoding in-place. Ignores malformed sequences.
 */
static int urldecode(char *p)
{
    unsigned char *out = (unsigned char *)p;
    unsigned char *save = out;

    for (; *p; p++) {
        if (*p != '%') {
            *out++ = *p;
        } else if (isxdigit(_UC(p[1])) && isxdigit(_UC(p[2]))) {
            /* Don't check, can't fail because of ixdigit() call. */
            *out++ = (OPENSSL_hexchar2int(p[1]) << 4)
                | OPENSSL_hexchar2int(p[2]);
            p += 2;
        } else {
            return -1;
        }
    }
    *out = '\0';
    return (int)(out - save);
}

/* if *pcbio != NULL, continue given connected session, else accept new */
/* if found_keep_alive != NULL, return this way connection persistence state */
int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
                             char **ppath, BIO **pcbio, BIO *acbio,
                             int *found_keep_alive,
                             const char *prog, const char *port,
                             int accept_get, int timeout)
{
    BIO *cbio = *pcbio, *getbio = NULL, *b64 = NULL;
    int len;
    char reqbuf[2048], inbuf[2048];
    char *meth, *url, *end;
    ASN1_VALUE *req;
    int ret = 0;

    *preq = NULL;
    if (ppath != NULL)
        *ppath = NULL;

    if (cbio == NULL) {
        log_message(prog, LOG_DEBUG,
                    "Awaiting new connection on port %s...", port);
        if (BIO_do_accept(acbio) <= 0)
            /* Connection loss before accept() is routine, ignore silently */
            return ret;

        *pcbio = cbio = BIO_pop(acbio);
    } else {
        log_message(prog, LOG_DEBUG, "Awaiting next request...");
    }
    if (cbio == NULL) {
        /* Cannot call http_server_send_status(cbio, ...) */
        ret = -1;
        goto out;
    }

# ifdef HTTP_DAEMON
    if (timeout > 0) {
        (void)BIO_get_fd(cbio, &acfd);
        alarm(timeout);
    }
# endif

    /* Read the request line. */
    len = BIO_gets(cbio, reqbuf, sizeof(reqbuf));
    if (len == 0)
        return ret;
    ret = 1;
    if (len < 0) {
        log_message(prog, LOG_WARNING, "Request line read error");
        (void)http_server_send_status(cbio, 400, "Bad Request");
        goto out;
    }
    if ((end = strchr(reqbuf, '\r')) != NULL
            || (end = strchr(reqbuf, '\n')) != NULL)
        *end = '\0';
    log_message(prog, LOG_INFO, "Received request, 1st line: %s", reqbuf);

    meth = reqbuf;
    url = meth + 3;
    if ((accept_get && strncmp(meth, "GET ", 4) == 0)
            || (url++, strncmp(meth, "POST ", 5) == 0)) {
        static const char http_version_str[] = " "HTTP_PREFIX_VERSION;
        static const size_t http_version_str_len = sizeof(http_version_str) - 1;

        /* Expecting (GET|POST) {sp} /URL {sp} HTTP/1.x */
        *(url++) = '\0';
        while (*url == ' ')
            url++;
        if (*url != '/') {
            log_message(prog, LOG_WARNING,
                        "Invalid %s -- URL does not begin with '/': %s",
                        meth, url);
            (void)http_server_send_status(cbio, 400, "Bad Request");
            goto out;
        }
        url++;

        /* Splice off the HTTP version identifier. */
        for (end = url; *end != '\0'; end++)
            if (*end == ' ')
                break;
        if (strncmp(end, http_version_str, http_version_str_len) != 0) {
            log_message(prog, LOG_WARNING,
                        "Invalid %s -- bad HTTP/version string: %s",
                        meth, end + 1);
            (void)http_server_send_status(cbio, 400, "Bad Request");
            goto out;
        }
        *end = '\0';
        /* above HTTP 1.0, connection persistence is the default */
        if (found_keep_alive != NULL)
            *found_keep_alive = end[http_version_str_len] > '0';

        /*-
         * Skip "GET / HTTP..." requests often used by load-balancers.
         * 'url' was incremented above to point to the first byte *after*
         * the leading slash, so in case 'GET / ' it is now an empty string.
         */
        if (strlen(meth) == 3 && url[0] == '\0') {
            (void)http_server_send_status(cbio, 200, "OK");
            goto out;
        }

        len = urldecode(url);
        if (len < 0) {
            log_message(prog, LOG_WARNING,
                        "Invalid %s request -- bad URL encoding: %s",
                        meth, url);
            (void)http_server_send_status(cbio, 400, "Bad Request");
            goto out;
        }
        if (strlen(meth) == 3) { /* GET */
            if ((getbio = BIO_new_mem_buf(url, len)) == NULL
                || (b64 = BIO_new(BIO_f_base64())) == NULL) {
                log_message(prog, LOG_ERR,
                            "Could not allocate base64 bio with size = %d",
                            len);
                goto fatal;
            }
            BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
            getbio = BIO_push(b64, getbio);
        }
    } else {
        log_message(prog, LOG_WARNING,
                    "HTTP request does not begin with %sPOST: %s",
                    accept_get ? "GET or " : "", reqbuf);
        (void)http_server_send_status(cbio, 400, "Bad Request");
        goto out;
    }

    /* chop any further/duplicate leading or trailing '/' */
    while (*url == '/')
        url++;
    while (end >= url + 2 && end[-2] == '/' && end[-1] == '/')
        end--;
    *end = '\0';

    /* Read and skip past the headers. */
    for (;;) {
        char *key, *value, *line_end = NULL;

        len = BIO_gets(cbio, inbuf, sizeof(inbuf));
        if (len <= 0) {
            log_message(prog, LOG_WARNING, "Error reading HTTP header");
            (void)http_server_send_status(cbio, 400, "Bad Request");
            goto out;
        }

        if (inbuf[0] == '\r' || inbuf[0] == '\n')
            break;

        key = inbuf;
        value = strchr(key, ':');
        if (value == NULL) {
            log_message(prog, LOG_WARNING,
                        "Error parsing HTTP header: missing ':'");
            (void)http_server_send_status(cbio, 400, "Bad Request");
            goto out;
        }
        *(value++) = '\0';
        while (*value == ' ')
            value++;
        line_end = strchr(value, '\r');
        if (line_end == NULL) {
            line_end = strchr(value, '\n');
            if (line_end == NULL) {
                log_message(prog, LOG_WARNING,
                            "Error parsing HTTP header: missing end of line");
                (void)http_server_send_status(cbio, 400, "Bad Request");
                goto out;
            }
        }
        *line_end = '\0';
        /* https://tools.ietf.org/html/rfc7230#section-6.3 Persistence */
        if (found_keep_alive != NULL && strcasecmp(key, "Connection") == 0) {
            if (strcasecmp(value, "keep-alive") == 0)
                *found_keep_alive = 1;
            else if (strcasecmp(value, "close") == 0)
                *found_keep_alive = 0;
        }
    }

# ifdef HTTP_DAEMON
    /* Clear alarm before we close the client socket */
    alarm(0);
    timeout = 0;
# endif

    /* Try to read and parse request */
    req = ASN1_item_d2i_bio(it, getbio != NULL ? getbio : cbio, NULL);
    if (req == NULL) {
        log_message(prog, LOG_WARNING,
                    "Error parsing DER-encoded request content");
        (void)http_server_send_status(cbio, 400, "Bad Request");
    } else if (ppath != NULL && (*ppath = OPENSSL_strdup(url)) == NULL) {
        log_message(prog, LOG_ERR,
                    "Out of memory allocating %zu bytes", strlen(url) + 1);
        ASN1_item_free(req, it);
        goto fatal;
    }

    *preq = req;

 out:
    BIO_free_all(getbio);
# ifdef HTTP_DAEMON
    if (timeout > 0)
        alarm(0);
    acfd = (int)INVALID_SOCKET;
# endif
    return ret;

 fatal:
    (void)http_server_send_status(cbio, 500, "Internal Server Error");
    if (ppath != NULL) {
        OPENSSL_free(*ppath);
        *ppath = NULL;
    }
    BIO_free_all(cbio);
    *pcbio = NULL;
    ret = -1;
    goto out;
}

/* assumes that cbio does not do an encoding that changes the output length */
int http_server_send_asn1_resp(BIO *cbio, int keep_alive,
                               const char *content_type,
                               const ASN1_ITEM *it, const ASN1_VALUE *resp)
{
    int ret = BIO_printf(cbio, HTTP_1_0" 200 OK\r\n%s"
                         "Content-type: %s\r\n"
                         "Content-Length: %d\r\n\r\n",
                         keep_alive ? "Connection: keep-alive\r\n" : "",
                         content_type,
                         ASN1_item_i2d(resp, NULL, it)) > 0
            && ASN1_item_i2d_bio(it, cbio, resp) > 0;

    (void)BIO_flush(cbio);
    return ret;
}

int http_server_send_status(BIO *cbio, int status, const char *reason)
{
    int ret = BIO_printf(cbio, HTTP_1_0" %d %s\r\n\r\n",
                         /* This implicitly cancels keep-alive */
                         status, reason) > 0;

    (void)BIO_flush(cbio);
    return ret;
}
#endif
