/*
 * mainloop.c -- The TPM Emulator's main processing loop
 *
 * (c) Copyright IBM Corporation 2014, 2015, 2016
 *
 * Author: Stefan Berger <stefanb@us.ibm.com>
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * Neither the names of the IBM Corporation nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* mainLoop() is the main server loop.

   It reads a TPM request, processes the ordinal, and writes the response
*/

#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <poll.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>

#include <libtpms/tpm_error.h>
#include <libtpms/tpm_library.h>
#include <libtpms/tpm_memory.h>

#include "swtpm_debug.h"
#include "swtpm_io.h"
#include "tpmlib.h"
#include "locality.h"
#include "logging.h"
#include "ctrlchannel.h"
#include "mainloop.h"
#include "utils.h"
#include "sys_dependencies.h"
#include "compiler_dependencies.h"
#include "swtpm_utils.h"

/* local variables */
static TPM_MODIFIER_INDICATOR locality;
bool tpm_running = false;

bool mainloop_terminate;

TPM_RESULT
mainloop_cb_get_locality(TPM_MODIFIER_INDICATOR *loc,
                         uint32_t tpmnum SWTPM_ATTR_UNUSED)
{
    *loc = locality;

    return TPM_SUCCESS;
}

int mainLoop(struct mainLoopParams *mlp,
             int notify_fd)
{
    TPM_RESULT          rc = 0;
    TPM_CONNECTION_FD   connection_fd;             /* file descriptor for read/write */
    unsigned char       *command = NULL;           /* command buffer */
    uint32_t            command_length;            /* actual length of command bytes */
    uint32_t            max_command_length;        /* command buffer size */
    off_t               cmd_offset;
    /* The response buffer is reused for each command. Thus it can grow but never shrink */
    unsigned char       *rbuffer = NULL;           /* actual response bytes */
    uint32_t            rlength = 0;               /* bytes in response buffer */
    uint32_t            rTotal = 0;                /* total allocated bytes */
    int                 ctrlfd;
    int                 ctrlclntfd;
    int                 sockfd;
    int                 ready;
    struct iovec        iov[3];
    uint32_t            ack = htobe32(0);
    struct tpm2_resp_prefix respprefix;
    uint32_t            lastCommand;

    /* poolfd[] indexes */
    enum {
        DATA_CLIENT_FD = 0,
        NOTIFY_FD,
        CTRL_SERVER_FD,
        CTRL_CLIENT_FD,
        DATA_SERVER_FD
    };

    TPM_DEBUG("mainLoop:\n");

    max_command_length = tpmlib_get_tpm_property(TPMPROP_TPM_BUFFER_MAX) +
                         sizeof(struct tpm2_send_command_prefix);

    command = malloc(max_command_length);
    if (!command) {
        logprintf(STDERR_FILENO, "Could not allocate %u bytes for buffer.\n",
                  max_command_length);
        return TPM_FAIL;
    }

    /* header and trailer that we may send by setting iov_len */
    iov[0].iov_base = &respprefix;
    iov[0].iov_len = 0;
    iov[2].iov_base = &ack;
    iov[2].iov_len = 0;

    connection_fd.fd = -1;
    ctrlfd = ctrlchannel_get_fd(mlp->cc);
    ctrlclntfd = ctrlchannel_get_client_fd(mlp->cc);

    sockfd = SWTPM_IO_GetSocketFD();

    if (mlp->startupType != _TPM_ST_NONE) {
        command_length = tpmlib_create_startup_cmd(
                                  mlp->startupType,
                                  mlp->tpmversion,
                                  command, max_command_length);
        if (command_length > 0) {
            mlp->lastCommand = tpmlib_get_cmd_ordinal(command, command_length);
            rc = TPMLIB_Process(&rbuffer, &rlength, &rTotal,
                                command, command_length);
        }

        if (rc || command_length == 0) {
            mainloop_terminate = true;
            if (rc)
                logprintf(STDERR_FILENO, "Could not send Startup: 0x%x\n", rc);
        }
    }

    while (!mainloop_terminate) {

        while (rc == 0) {
            if (mlp->flags & MAIN_LOOP_FLAG_USE_FD)
                connection_fd.fd = mlp->fd;

            struct pollfd pollfds[] = {
                [DATA_CLIENT_FD] = {
                    .fd = connection_fd.fd,
                    .events = POLLIN | POLLHUP,
                    .revents = 0,
                },
                [NOTIFY_FD] = {
                    .fd = notify_fd,
                    .events = POLLIN,
                    .revents = 0,
                },
                [CTRL_SERVER_FD] = {
                    .fd = -1,
                    .events = POLLIN,
                    .revents = 0,
                },
                [CTRL_CLIENT_FD] = {
                    .fd = ctrlclntfd,
                    .events = POLLIN | POLLHUP,
                    .revents = 0,
                },
                [DATA_SERVER_FD] = {
                    /* listen socket for accepting clients */
                    .fd = -1,
                    .events = POLLIN,
                    .revents = 0,
                }
            };

            /* only listend for clients if we don't have one */
            if (connection_fd.fd < 0)
                pollfds[DATA_SERVER_FD].fd = sockfd;
            if (ctrlclntfd < 0)
                pollfds[CTRL_SERVER_FD].fd = ctrlfd;

            ready = poll(pollfds, 5, -1);
            if (ready < 0 && errno == EINTR)
                continue;

            if (ready < 0 ||
                (pollfds[NOTIFY_FD].revents & POLLIN) != 0) {
                SWTPM_IO_Disconnect(&connection_fd);
                break;
            }

            if (pollfds[DATA_CLIENT_FD].revents & (POLLHUP | POLLERR)) {
                logprintf(STDERR_FILENO, "Data client disconnected\n");
                mlp->fd = -1;
                /* chardev and unixio get this signal, not tcp */
                if (mlp->flags & MAIN_LOOP_FLAG_END_ON_HUP) {
                    /* only the chardev terminates here */
                    mainloop_terminate = true;
                    break;
                }
            }

            if (pollfds[DATA_SERVER_FD].revents & POLLIN)
                connection_fd.fd = accept(pollfds[DATA_SERVER_FD].fd, NULL, 0);

            if (pollfds[CTRL_SERVER_FD].revents & POLLIN)
                ctrlclntfd = accept(ctrlfd, NULL, 0);

            if (pollfds[CTRL_CLIENT_FD].revents & POLLIN) {
                ctrlclntfd = ctrlchannel_process_fd(ctrlclntfd,
                                                    &mainloop_terminate,
                                                    &locality, &tpm_running,
                                                    mlp);
                if (mainloop_terminate)
                    break;
            }

            if (pollfds[CTRL_CLIENT_FD].revents & POLLHUP) {
                if (ctrlclntfd >= 0)
                    close(ctrlclntfd);
                ctrlclntfd = -1;
            }

            if (!(pollfds[DATA_CLIENT_FD].revents & POLLIN))
                continue;

            /* Read the command.  The number of bytes is determined by 'paramSize' in the stream */
            if (rc == 0) {
                rc = SWTPM_IO_Read(&connection_fd, command, &command_length,
                                   max_command_length);
                if (rc != 0) {
                    /* connection broke */
                    SWTPM_IO_Disconnect(&connection_fd);
                }
            }

            cmd_offset = 0;
            /* Handle optional TCG Header in front of TPM 2 Command */
            if (rc == 0 && mlp->tpmversion == TPMLIB_TPM_VERSION_2) {
                cmd_offset = tpmlib_handle_tcg_tpm2_cmd_header(command,
                                                               command_length,
                                                               &locality);
                if (cmd_offset > 0) {
                    /* send header and trailer */
                    iov[0].iov_len = sizeof(respprefix);
                    iov[2].iov_len = sizeof(ack);
                } else {
                    iov[0].iov_len = 0;
                    iov[2].iov_len = 0;
                }
            }

            if (rc == 0) {
                if (!tpm_running) {
                    tpmlib_write_fatal_error_response(&rbuffer, &rlength,
                                                      &rTotal,
                                                      mlp->tpmversion);
                    goto skip_process;
                }
            }

            if (rc == 0) {
                lastCommand =
                    tpmlib_get_cmd_ordinal(&command[cmd_offset],
                                           command_length - cmd_offset);
                if (lastCommand != TPM_ORDINAL_NONE)
                    mlp->lastCommand = lastCommand;
            }

            if (rc == 0) {
                rlength = 0;                                /* clear the response buffer */
                rc = tpmlib_process(&rbuffer,
                                    &rlength,
                                    &rTotal,
                                    &command[cmd_offset],
                                    command_length - cmd_offset,
                                    mlp->locality_flags,
                                    &locality,
                                    mlp->tpmversion);
                if (rlength)
                    goto skip_process;
            }

            if (rc == 0) {
                rlength = 0;                                /* clear the response buffer */
                rc = TPMLIB_Process(&rbuffer,
                                    &rlength,
                                    &rTotal,
                                    &command[cmd_offset],
                                    command_length - cmd_offset);
            }

skip_process:
            /* write the results */
            if (rc == 0) {
                respprefix.size = htobe32(rlength);
                iov[1].iov_base = rbuffer;
                iov[1].iov_len  = rlength;

                SWTPM_IO_Write(&connection_fd, iov, ARRAY_LEN(iov));
            }

            if (!(mlp->flags & MAIN_LOOP_FLAG_KEEP_CONNECTION)) {
                SWTPM_IO_Disconnect(&connection_fd);
                break;
            }
        }

        rc = 0; /* A fatal TPM_Process() error should cause the TPM to enter shutdown.  IO errors
                   are outside the TPM, so the TPM does not shut down.  The main loop should
                   continue to function.*/
        if (connection_fd.fd < 0 && mlp->flags & MAIN_LOOP_FLAG_TERMINATE)
            break;
    }

    free(rbuffer);
    free(command);

    if (ctrlclntfd >= 0)
        close(ctrlclntfd);
    ctrlchannel_set_client_fd(mlp->cc, -1);

    if (mlp->fd >= 0) {
        close(mlp->fd);
        mlp->fd = -1;
    }

    return rc;
}
