/********************************************************************************/
/*                                                                              */
/*                            CUSE TPM                                          */
/*                     IBM Thomas J. Watson Research Center                     */
/*                                                                              */
/* (c) Copyright IBM Corporation 2014-2015.					*/
/*										*/
/* 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.		*/
/********************************************************************************/

/*
 * Authors:
 *     Eric Richter, erichte@us.ibm.com
 *     Stefan Berger, stefanb@us.ibm.com
 *     David Safford, safford@us.ibm.com
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <getopt.h>
#include <pwd.h>
#include <grp.h>
#include <limits.h>
#include <errno.h>
#include <arpa/inet.h>
#include <dirent.h>

#include <fuse/cuse_lowlevel.h>

#include <glib.h>

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

#include "swtpm.h"
#include "common.h"
#include "tpmstate.h"
#include "pidfile.h"
#include "locality.h"
#include "logging.h"
#include "tpm_ioctl.h"
#include "swtpm_nvstore.h"
#include "tpmlib.h"
#include "main.h"
#include "utils.h"
#include "threadpool.h"
#include "seccomp_profile.h"
#include "options.h"
#include "capabilities.h"
#include "swtpm_utils.h"

/* maximum size of request buffer */
#define TPM_REQ_MAX 4096

/* version of the TPM (1.2 or 2) */
static TPMLIB_TPMVersion tpmversion;

/* buffer containing the TPM request */
static unsigned char *ptm_request;

/* buffer containing the TPM response */
static unsigned char *ptm_response;

/* offset from where to read from; reset when ptm_response is set */
static size_t ptm_read_offset;

/* the sizes of the data in the buffers */
static uint32_t ptm_req_len, ptm_res_len, ptm_res_tot;

/* locality applied to TPM commands */
static TPM_MODIFIER_INDICATOR locality;

/* whether the TPM is running (TPM_Init was received) */
static bool tpm_running;

/* flags on how to handle locality */
static uint32_t locality_flags;

/* the fuse_session that we will signal an exit to to exit the prg. */
static struct fuse_session *ptm_fuse_session;

/* last command sent to the TPM */
static uint32_t g_lastCommand = TPM_ORDINAL_NONE;

/* TPM2_Shutdown() will NOT be sent by swtpm */
static bool g_disable_auto_shutdown = false;

/* whether to defer locking NVRAM storage due to incoming migration */
static bool g_incoming_migration;

/* whether NVRAM storage is currently locked */
static bool g_storage_locked;

/* whether to relase the lock on outgoing migration */
static bool g_release_lock_outgoing;

/* how many times to retry locking; use for fallback after releasing
   the lock on outgoing migration. */
static unsigned int g_locking_retries;
#define DEFAULT_LOCKING_RETRIES  300 /* 300 * 10ms */

#if GLIB_MAJOR_VERSION >= 2
# if GLIB_MINOR_VERSION >= 32

static GMutex file_ops_lock;
#  define FILE_OPS_LOCK &file_ops_lock

# else

static GMutex *file_ops_lock;
#  define FILE_OPS_LOCK file_ops_lock

# endif
#else

#error Unsupport glib version

#endif

struct cuse_param {
    char *runas;
    char *chroot;
    char *logging;
    char *keydata;
    char *migkeydata;
    char *piddata;
    char *tpmstatedata;
    char *localitydata;
    char *seccompdata;
    char *migrationdata;
    unsigned int seccomp_action;
    char *flagsdata;
    uint16_t startupType;
};

/* single message to send to the worker thread */
static struct thread_message msg;

struct stateblob {
    uint8_t type;
    uint8_t *data;
    uint32_t length;
    TPM_BOOL is_encrypted;
};

typedef struct stateblob_desc {
    uint32_t blobtype;
    TPM_BOOL decrypt;
    TPM_BOOL is_encrypted;
    unsigned char *data;
    uint32_t data_length;
} stateblob_desc;

typedef enum tx_state_type {
    TX_STATE_CLOSED = 0,
    TX_STATE_RW_COMMAND = 1,
    TX_STATE_SET_STATE_BLOB = 2,
    TX_STATE_GET_STATE_BLOB = 3,
} tx_state_type;

typedef struct transfer_state {
    tx_state_type state;
    /* while in TX_STATE_GET/SET_STATEBLOB */
    uint32_t blobtype;
    TPM_BOOL blob_is_encrypted;
    /* while in TX_STATE_GET */
    uint32_t offset;
} transfer_state;

typedef struct TPM_Response_Header {
    uint16_t tag;
    uint32_t paramSize;
    uint32_t returnCode;
} __attribute__ ((packed)) TPM_Response_Header;

/*********************************** data *************************************/

static const char *usage =
"usage: %s %s [options]\n"
"\n"
"The following options are supported:\n"
"\n"
"-n NAME|--name=NAME :  device name (mandatory)\n"
"-M MAJ|--maj=MAJ    :  device major number\n"
"-m MIN|--min=MIN    :  device minor number\n"
"--key file=<path>|fd=<fd>[,mode=aes-cbc|aes-256-cbc][,format=hex|binary][,remove=[true|false]]\n"
"                    :  use an AES key for the encryption of the TPM's state\n"
"                       files; use the given mode for the block encryption;\n"
"                       the key is to be provided as a hex string or in binary\n"
"                       format; the keyfile can be automatically removed using\n"
"                       the remove parameter\n"
"--key pwdfile=<path>|pwdfd=<fd>[,mode=aes-cbc|aes-256-cbc][,remove=[true|false]][,kdf=sha512|pbkdf2]\n"
"                    :  provide a passphrase in a file; the AES key will be\n"
"                       derived from this passphrase; default kdf is PBKDF2\n"
"--locality [reject-locality-4][,allow-set-locality]\n"
"                    :  reject-locality-4: reject any command in locality 4\n"
"                       allow-set-locality: accept SetLocality command\n"
"--migration-key file=<path>|fd=<fd>[,mode=aes-cbc|aes-256-cbc][,format=hex|binary][,remove=[true|false]]\n"
"                    :  use an AES key for the encryption of the TPM's state\n"
"                       when it is retrieved from the TPM via ioctls;\n"
"                       Setting this key ensures that the TPM's state will always\n"
"                       be encrypted when migrated\n"
"--migration-key pwdfile=<path>|pwdfd=<fd>[,mode=aes-cbc|aes-256-cbc][,remove=[true|false]][,kdf=sha512|pbkdf2]\n"
"                    :  provide a passphrase in a file; the AES key will be\n"
"                       derived from this passphrase; default kdf is PBKDF2\n"
"--log file=<path>|fd=<filedescriptor>[,level=n][,prefix=<prefix>][,truncate]\n"
"                    :  write the TPM's log into the given file rather than\n"
"                       to the console; provide '-' for path to avoid logging\n"
"                       log level 5 and higher will enable libtpms logging;\n"
"                       all logged output will be prefixed with prefix;\n"
"                       the log file can be reset (truncate)\n"
"--pid file=<path>|fd=<filedescriptor>\n"
"                    :  write the process ID into the given file\n"
"--tpmstate dir=<dir>[,mode=0...]|backend-uri=<uri>\n"
"                    :  set the directory or uri where the TPM's state will be written\n"
"                       into; the TPM_PATH environment variable can be used\n"
"                       instead of dir option;\n"
"                       mode allows a user to set the file mode bits of the state\n"
"                       files; the default mode is 0640;\n"
"--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none][,disable-auto-shutdown]\n"
"                    :  not-need-init: commands can be sent without needing to\n"
"                       send an INIT via control channel;\n"
"                       startup-...: send Startup command with this type;\n"
"                       disable-auto-shutdown disables automatic sending of\n"
"                       TPM2_Shutdown before TPM 2 reset or swtpm termination;\n"
"-r|--runas <user>   :  after creating the CUSE device, change to the given\n"
"                       user\n"
"-R|--chroot <path>  :  chroot to the given directory at startup\n"
"--tpm2              :  choose TPM2 functionality\n"
#ifdef WITH_SECCOMP
# ifndef SCMP_ACT_LOG
"--seccomp action=none|kill\n"
# else
"--seccomp action=none|kill|log\n"
# endif
"                    :  Choose the action of the seccomp profile when a\n"
"                       blacklisted syscall is executed; default is kill\n"
#endif
"--migration [incoming][,release-lock-outgoing]\n"
"                    : Incoming migration defers locking of storage backend\n"
"                      until the TPM state is received; release-lock-outgoing\n"
"                      releases the storage lock on outgoing migration\n"
"--print-capabilites : print capabilities and terminate\n"
"--print-states      : print existing TPM states and terminate\n"
"-h|--help           :  display this help screen and terminate\n"
"\n";

static TPM_RESULT
ptm_io_getlocality(TPM_MODIFIER_INDICATOR *loc,
                   uint32_t tpmnum SWTPM_ATTR_UNUSED)
{
    *loc = locality;
    return TPM_SUCCESS;
}

static struct libtpms_callbacks cbs = {
    .sizeOfStruct           = sizeof(struct libtpms_callbacks),
    .tpm_nvram_init         = SWTPM_NVRAM_Init,
    .tpm_nvram_loaddata     = SWTPM_NVRAM_LoadData,
    .tpm_nvram_storedata    = SWTPM_NVRAM_StoreData,
    .tpm_nvram_deletename   = SWTPM_NVRAM_DeleteName,
    .tpm_io_getlocality     = ptm_io_getlocality,
};

/* the current state the transfer interface is in */
static transfer_state tx_state;

/* function prototypes */
static void ptm_cleanup(void);

/************************* NVRAM locking ************************************/

/* ensure that the NVRAM is locked; returns false in case of failure */
static bool ensure_locked_storage(void)
{
    TPM_RESULT res;

    if (g_storage_locked)
        return true;

    /* if NVRAM hasn't been initialized yet locking may need to be retried */
    res = SWTPM_NVRAM_Lock_Storage(g_locking_retries);
    if (res == TPM_RETRY)
        return true;
    if (res != TPM_SUCCESS)
        return false;

    g_storage_locked = true;
    g_incoming_migration = false;
    g_locking_retries = 0;

    return true;
}

static void unlock_nvram(unsigned int locking_retries)
{
    SWTPM_NVRAM_Unlock();

    g_storage_locked = false;
    g_locking_retries = locking_retries;
}

/************************* cached stateblob *********************************/

static stateblob_desc cached_stateblob;

/*
 * cached_stateblob_is_loaded: is the stateblob with the given properties
 *                             the one in the cache?
 */
static bool cached_stateblob_is_loaded(uint32_t blobtype,
                                       TPM_BOOL decrypt)
{
    return (cached_stateblob.data != NULL) &&
           (cached_stateblob.blobtype == blobtype) &&
           (cached_stateblob.decrypt == decrypt);
}

/*
 * cached_stateblob_free: Free any previously loaded state blob
 */
static void cached_stateblob_free(void)
{
    free(cached_stateblob.data);
    cached_stateblob.data = NULL;
    cached_stateblob.data_length = 0;
}

/*
 * cached_stateblob_get_bloblength: get the total length of the cached blob
 */
static uint32_t cached_stateblob_get_bloblength(void)
{
    return cached_stateblob.data_length;
}

/*
 * cached_statblob_get: get stateblob data without copying them
 *
 * @offset: at which offset to get the data
 * @bufptr: pointer to a buffer pointer used to return buffer start
 * @length: pointer used to return number of available bytes in returned buffer
 */
static int cached_stateblob_get(uint32_t offset,
                                unsigned char **bufptr, size_t *length)
{
    if (cached_stateblob.data == NULL ||
        offset > cached_stateblob.data_length)
        return -1;

    *bufptr = &cached_stateblob.data[offset];
    *length = cached_stateblob.data_length - offset;

    return 0;
}

/*
 * cached_stateblob_load: load a state blob into the cache
 *
 * blobtype: the type of blob
 * decrypt: whether the blob is to be decrypted
 */
static TPM_RESULT cached_stateblob_load(uint32_t blobtype, TPM_BOOL decrypt)
{
    TPM_RESULT res = 0;
    const char *blobname = tpmlib_get_blobname(blobtype);
    uint32_t tpm_number = 0;

    if (!blobname)
        return TPM_BAD_PARAMETER;

    cached_stateblob_free();

    if (blobtype == PTM_BLOB_TYPE_VOLATILE)
        res = SWTPM_NVRAM_Store_Volatile();

    if (res == 0)
        res = SWTPM_NVRAM_GetStateBlob(&cached_stateblob.data,
                                       &cached_stateblob.data_length,
                                       tpm_number, blobname, decrypt,
                                       &cached_stateblob.is_encrypted);

    /* make sure the volatile state file is gone */
    if (blobtype == PTM_BLOB_TYPE_VOLATILE)
        SWTPM_NVRAM_DeleteName(tpm_number, blobname, FALSE);

    if (res == 0) {
        cached_stateblob.blobtype = blobtype;
        cached_stateblob.decrypt = decrypt;
    }

    if (blobtype == PTM_BLOB_TYPE_SAVESTATE)
        unlock_nvram(DEFAULT_LOCKING_RETRIES);

    return res;
}

/*
 * cached_state_blob_copy: copy the cached state blob to a destination buffer
 *
 * dest: destination buffer
 * destlen: size of the buffer
 * srcoffset: offset to copy from
 * copied: variable to return the number of copied bytes
 * is_encrypted: variable to return whether the blob is encrypted
 */
static int cached_stateblob_copy(void *dest, size_t destlen,
                                 uint32_t srcoffset, uint32_t *copied,
                                 TPM_BOOL *is_encrypted)
{
    int ret = -1;

    *copied = 0;

    if (cached_stateblob.data != NULL && cached_stateblob.data_length > 0) {

        if (srcoffset < cached_stateblob.data_length) {
            *copied = min(cached_stateblob.data_length - srcoffset, destlen);

            memcpy(dest, &cached_stateblob.data[srcoffset], *copied);

            *is_encrypted = cached_stateblob.is_encrypted;
        }

        ret = 0;
    }

    return ret;
}

/************************* worker thread ************************************/

/*
 * worker_thread: the worker thread
 */
static void worker_thread(gpointer data, gpointer user_data SWTPM_ATTR_UNUSED)
{
    struct thread_message *msg = (struct thread_message *)data;

    switch (msg->type) {
    case MESSAGE_TPM_CMD:
        TPMLIB_Process(&ptm_response, &ptm_res_len, &ptm_res_tot,
                       ptm_request, ptm_req_len);
        ptm_read_offset = 0;
        break;
    case MESSAGE_IOCTL:
        break;
    }

    /* results are ready */
    worker_thread_mark_done();
}

/***************************** utility functions ****************************/

/*
 * tpm_start: Start the TPM
 *
 * Check whether the TPM's state directory exists and if it does
 * not exists, try to creat it. Start the thread pool, initilize
 * libtpms and allocate a global TPM request buffer.
 *
 * @flags: libtpms init flags
 * @l_tpmversion: the version of the TPM
 * @res: the result from starting the TPM
 */
static int tpm_start(uint32_t flags, TPMLIB_TPMVersion l_tpmversion,
                     TPM_RESULT *res)
{
    DIR *dir;
    const char *uri = tpmstate_get_backend_uri();
    const char *tpmdir = uri + strlen("dir://");

    *res = TPM_FAIL;

    dir = opendir(tpmdir);
    if (dir) {
        closedir(dir);
    } else {
        if (mkdir(tpmdir, 0775)) {
            logprintf(STDERR_FILENO,
                      "Error: Could not open tpmstate dir %s\n",
                      tpmdir);
            return -1;
        }
    }

    pool = g_thread_pool_new(worker_thread,
                             NULL,
                             1,
                             FALSE,
                             NULL);
    if (!pool) {
        logprintf(STDERR_FILENO,
                  "Error: Could not create the thread pool.\n");
        return -1;
    }

    if(!ptm_request)
        ptm_request = malloc(4096);
    if(!ptm_request) {
        logprintf(STDERR_FILENO,
                  "Error: Could not allocate memory for request buffer.\n");
        goto error_del_pool;
    }

    g_storage_locked = !g_incoming_migration;

    *res = tpmlib_start(flags, l_tpmversion, g_storage_locked);
    if (*res != TPM_SUCCESS)
        goto error_del_pool;

    logprintf(STDOUT_FILENO,
              "CUSE TPM successfully initialized.\n");

    return 0;

error_del_pool:
    g_thread_pool_free(pool, TRUE, TRUE);
    pool = NULL;

    return -1;
}

/*
 * ptm_write_fatal_error_response: Write fatal error response
 *
 * Write a fatal error response into the global ptm_response buffer.
 */
static void ptm_write_fatal_error_response(TPMLIB_TPMVersion l_tpmversion)
{
    tpmlib_write_fatal_error_response(&ptm_response,
                                      &ptm_res_len,
                                      &ptm_res_tot,
                                      l_tpmversion);
    ptm_read_offset = 0;
}

/*
 * ptm_send_startup: Send a TPM/TPM2_Startup
 */
static int ptm_send_startup(uint16_t startupType,
                            TPMLIB_TPMVersion l_tpmversion SWTPM_ATTR_UNUSED)
{
    uint32_t command_length;
    unsigned char command[sizeof(struct tpm_startup)];
    uint32_t max_command_length = sizeof(command);
    int ret = 0;
    TPM_RESULT rc = TPM_SUCCESS;

    command_length = tpmlib_create_startup_cmd(
                               startupType,
                               tpmversion,
                               command, max_command_length);
    if (command_length > 0) {
        g_lastCommand = tpmlib_get_cmd_ordinal(command, command_length);

        rc = TPMLIB_Process(&ptm_response, &ptm_res_len, &ptm_res_tot,
                           (unsigned char *)command, command_length);
        ptm_read_offset = 0;
    }

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

    return ret;
}

/************************************ read() support ***************************/

/*
 * ptm_read_result: Return the TPM response packet
 *
 * @req: the fuse_req_t
 * @size: the max. number of bytes to return to the requester
 */
static void ptm_read_result(fuse_req_t req, size_t size)
{
    size_t len = 0;

    /* prevent other threads from reading or writing cmds or doing ioctls */
    g_mutex_lock(FILE_OPS_LOCK);

    if (tpm_running) {
        /* wait until results are ready */
        worker_thread_wait_done();
    }

    if (ptm_read_offset < ptm_res_len) {
        len = ptm_res_len - ptm_read_offset;
        if (size < len)
            len = size;
    }

    fuse_reply_buf(req, (const char *)&ptm_response[ptm_read_offset], len);

    ptm_read_offset += len;

    g_mutex_unlock(FILE_OPS_LOCK);
}

/*
 * ptm_read_stateblob: get a TPM stateblob via the read() interface
 *
 * @req: the fuse_req_t
 * @size: the number of bytes to read
 *
 * The internal offset into the buffer is advanced by the number
 * of bytes that were copied. We switch back to command read/write
 * mode if an error occurred or once all bytes were read.
 */
static void ptm_read_stateblob(fuse_req_t req, size_t size)
{
    unsigned char *bufptr = NULL;
    size_t numbytes;
    size_t tocopy;

    if (cached_stateblob_get(tx_state.offset, &bufptr, &numbytes) < 0) {
        fuse_reply_err(req, EIO);
        tx_state.state = TX_STATE_RW_COMMAND;
    } else {
        tocopy = MIN(size, numbytes);
        tx_state.offset += tocopy;

        fuse_reply_buf(req, (char *)bufptr, tocopy);
        /* last transfer indicated by less bytes available than requested */
        if (numbytes < size) {
            tx_state.state = TX_STATE_RW_COMMAND;
        }
    }
}

/*
 * ptm_read: interface to POSIX read()
 *
 * @req: fuse_req_t
 * @size: number of bytes to read
 * @off: offset (not used)
 * @fi: fuse_file_info (not used)
 *
 * Depending on the current state of the transfer interface (read/write)
 * return either the results of TPM commands or a data of a TPM state blob.
 */
static void ptm_read(fuse_req_t req, size_t size, off_t off SWTPM_ATTR_UNUSED,
                     struct fuse_file_info *fi SWTPM_ATTR_UNUSED)
{
    switch (tx_state.state) {
    case TX_STATE_RW_COMMAND:
        ptm_read_result(req, size);
        break;
    case TX_STATE_SET_STATE_BLOB:
        fuse_reply_err(req, EIO);
        tx_state.state = TX_STATE_RW_COMMAND;
        break;
    case TX_STATE_GET_STATE_BLOB:
        ptm_read_stateblob(req, size);
        break;
    case TX_STATE_CLOSED:
        /* not possible */
        break;
    }
}

/*************************read/write stateblob support ***********************/

/*
 * ptm_set_stateblob_append: Append a piece of TPM state blob and transfer to TPM
 *
 * blobtype: the type of blob
 * data: the data to append
 * length: length of the data
 * is_encrypted: whether the blob is encrypted
 * is_last: whether this is the last part of the TPM state blob; if it is, the TPM
 *          state blob will then be transferred to the TPM
 */
static TPM_RESULT
ptm_set_stateblob_append(uint32_t blobtype,
                         const unsigned char *data, uint32_t length,
                         bool is_encrypted, bool is_last)
{
    TPM_RESULT res = 0;
    static struct stateblob stateblob;
    unsigned char *tmp;

    if (stateblob.type != blobtype) {
        /* new blob; clear old data */
        free(stateblob.data);
        stateblob.data = NULL;
        stateblob.length = 0;
        stateblob.type = blobtype;
        stateblob.is_encrypted = is_encrypted;

        /*
         * on the first call for a new state blob we allow 0 bytes to be written
         * this allows the user to transfer via write()
         */
        if (length == 0)
            return 0;
    }

    /* append */
    tmp = realloc(stateblob.data, stateblob.length + length);
    if (!tmp) {
        logprintf(STDERR_FILENO,
                  "Could not allocate %u bytes.\n", stateblob.length + length);
        /* error */
        free(stateblob.data);
        stateblob.data = NULL;
        stateblob.length = 0;
        stateblob.type = 0;

        return TPM_FAIL;
    } else
        stateblob.data = tmp;

    memcpy(&stateblob.data[stateblob.length], data, length);
    stateblob.length += length;

    if (!is_last) {
        /* full packet -- expecting more data */
        return res;
    }

    res = SWTPM_NVRAM_SetStateBlob(stateblob.data,
                                   stateblob.length,
                                   stateblob.is_encrypted,
                                   0 /* tpm_number */,
                                   blobtype);

    logprintf(STDERR_FILENO,
              "Deserialized state type %d (%s), length=%d, res=%d\n",
              blobtype, tpmlib_get_blobname(blobtype),
              stateblob.length, res);

    free(stateblob.data);
    stateblob.data = NULL;
    stateblob.length = 0;
    stateblob.type = 0;

    /* transfer of blob is complete */
    tx_state.state = TX_STATE_RW_COMMAND;

    return res;
}

/*
 * ptm_set_stateblob: set part of a TPM state blob
 *
 * @req: fuse_req_t
 * pss: ptm_setstate provided via ioctl()
 */
static void
ptm_set_stateblob(fuse_req_t req, ptm_setstate *pss)
{
    TPM_RESULT res = 0;
    TPM_BOOL is_encrypted =
        ((pss->u.req.state_flags & PTM_STATE_FLAG_ENCRYPTED) != 0);
    bool is_last = (sizeof(pss->u.req.data) != pss->u.req.length);

    if (pss->u.req.length > sizeof(pss->u.req.data)) {
        res = TPM_BAD_PARAMETER;
        goto send_response;
    }

    /* transfer of blob initiated */
    tx_state.state = TX_STATE_SET_STATE_BLOB;
    tx_state.blobtype = pss->u.req.type;
    tx_state.blob_is_encrypted = is_encrypted;
    tx_state.offset = 0;

    res = ptm_set_stateblob_append(pss->u.req.type,
                                   pss->u.req.data,
                                   pss->u.req.length,
                                   is_encrypted,
                                   is_last);

    if (res)
        tx_state.state = TX_STATE_RW_COMMAND;

 send_response:
    pss->u.resp.tpm_result = res;

    fuse_reply_ioctl(req, 0, pss, sizeof(*pss));
}

/*
 * ptm_get_stateblob_part: get part of a state blob
 *
 * @blobtype: the type of blob to get
 * @buffer: the buffer this function will write the blob into
 * @buffer_size: the size of the buffer
 * @offset: the offset into the state blob
 * @copied: pointer to int to indicate the number of bytes that were copied
 * @is_encryped: returns whether the state blob is encrypted
 */
static TPM_RESULT
ptm_get_stateblob_part(uint32_t blobtype,
                       unsigned char *buffer, size_t buffer_size,
                       uint32_t offset, uint32_t *copied,
                       TPM_BOOL decrypt, TPM_BOOL *is_encrypted)
{
    TPM_RESULT res = 0;

    if (!cached_stateblob_is_loaded(blobtype, decrypt)) {
        res = cached_stateblob_load(blobtype, decrypt);
    }

    if (res == 0) {
        cached_stateblob_copy(buffer, buffer_size,
                              offset, copied, is_encrypted);
    }

    return res;
}

/*
 * ptm_get_stateblob: Get the state blob from the TPM using ioctl()
 */
static void
ptm_get_stateblob(fuse_req_t req, ptm_getstate *pgs)
{
    TPM_RESULT res = 0;
    uint32_t blobtype = pgs->u.req.type;
    TPM_BOOL decrypt =
        ((pgs->u.req.state_flags & PTM_STATE_FLAG_DECRYPTED) != 0);
    TPM_BOOL is_encrypted = FALSE;
    uint32_t copied = 0;
    uint32_t offset = pgs->u.req.offset;
    uint32_t totlength;

    res = ptm_get_stateblob_part(blobtype,
                                 pgs->u.resp.data, sizeof(pgs->u.resp.data),
                                 pgs->u.req.offset, &copied,
                                 decrypt, &is_encrypted);

    totlength = cached_stateblob_get_bloblength();

    pgs->u.resp.state_flags = 0;
    if (is_encrypted)
        pgs->u.resp.state_flags |= PTM_STATE_FLAG_ENCRYPTED;

    pgs->u.resp.length = copied;
    pgs->u.resp.totlength = totlength;
    pgs->u.resp.tpm_result = res;
    logprintf(STDERR_FILENO,
              "Serialized state type %d, length=%d, totlength=%d, res=%d\n",
              blobtype, copied, totlength, res);

    if (res == 0) {
        if (offset + copied < totlength) {
            /* last byte was not copied */
            tx_state.state = TX_STATE_GET_STATE_BLOB;
            tx_state.blobtype = pgs->u.req.type;
            tx_state.blob_is_encrypted = is_encrypted;
            tx_state.offset = copied;
        } else {
            /* last byte was copied */
            tx_state.state = TX_STATE_RW_COMMAND;
        }
    } else {
        /* error occurred */
        tx_state.state = TX_STATE_RW_COMMAND;
    }

    fuse_reply_ioctl(req, 0, pgs, sizeof(pgs->u.resp));
}

/*********************************** write() support *************************/

/*
 * ptm_write_stateblob: Write the state blob using the write() interface
 *
 * @req: the fuse_req_t
 * @buf: the buffer with the data
 * @size: the number of bytes in the buffer
 *
 * The data are appended to an existing buffer that was created with the
 * initial ioctl().
 */
static void ptm_write_stateblob(fuse_req_t req, const char *buf, size_t size)
{
    TPM_RESULT res;

    res = ptm_set_stateblob_append(tx_state.blobtype,
                                   (unsigned char *)buf, size,
                                   tx_state.blob_is_encrypted,
                                   (size == 0));
    if (res) {
        tx_state.state = TX_STATE_RW_COMMAND;
        fuse_reply_err(req, EIO);
    } else {
        fuse_reply_write(req, size);
    }
}

/*
 * ptm_write_cmd: User writing a TPM command
 *
 * req: fuse_req_t
 * buf: the buffer containing the TPM command
 * size: the size of the buffer
 * tpmversion: the version of the TPM
 */
static void ptm_write_cmd(fuse_req_t req, const char *buf, size_t size,
                          TPMLIB_TPMVersion l_tpmversion)
{
    uint32_t lastCommand;

    ptm_req_len = size;
    ptm_res_len = 0;

    /* prevent other threads from reading or writing cmds or doing ioctls */
    g_mutex_lock(FILE_OPS_LOCK);

    if (tpm_running) {
        /* before processing a command ensure that the NVRAM is locked */
        if (!ensure_locked_storage()) {
            fuse_reply_err(req, EIO);
            goto cleanup;
        }

        /* ensure that we only ever work on one TPM command */
        if (worker_thread_is_busy()) {
            fuse_reply_err(req, EBUSY);
            goto cleanup;
        }

        if (ptm_req_len > TPM_REQ_MAX)
            ptm_req_len = TPM_REQ_MAX;

        /* process SetLocality command, if */
        tpmlib_process(&ptm_response, &ptm_res_len, &ptm_res_tot,
                       (unsigned char *)buf, ptm_req_len,
                       locality_flags, &locality, tpmversion);
        if (ptm_res_len) {
            ptm_read_offset = 0;
            goto skip_process;
        }

        lastCommand = tpmlib_get_cmd_ordinal((unsigned char *)buf, ptm_req_len);
        if (lastCommand != TPM_ORDINAL_NONE)
            g_lastCommand = lastCommand;

        if (tpmlib_is_request_cancelable(l_tpmversion,
                                         (const unsigned char*)buf,
                                         ptm_req_len)) {
            /* have command processed by thread pool */
            memcpy(ptm_request, buf, ptm_req_len);

            msg.type = MESSAGE_TPM_CMD;

            worker_thread_mark_busy();

            g_thread_pool_push(pool, &msg, NULL);
        } else {
            /* direct processing */
            TPMLIB_Process(&ptm_response, &ptm_res_len, &ptm_res_tot,
                           (unsigned char *)buf, ptm_req_len);
            ptm_read_offset = 0;
        }
    } else {
        /* TPM not initialized; return error */
        ptm_write_fatal_error_response(l_tpmversion);
    }

skip_process:
    fuse_reply_write(req, ptm_req_len);

cleanup:
    g_mutex_unlock(FILE_OPS_LOCK);

    return;
}

/*
 * ptm_write: low-level write() interface; calls approriate function depending
 *            on what is being transferred using the write()
 */
static void ptm_write(fuse_req_t req, const char *buf, size_t size,
                      off_t off SWTPM_ATTR_UNUSED,
                      struct fuse_file_info *fi SWTPM_ATTR_UNUSED)
{
    switch (tx_state.state) {
    case TX_STATE_RW_COMMAND:
        ptm_write_cmd(req, buf, size, tpmversion);
        break;
    case TX_STATE_GET_STATE_BLOB:
        fuse_reply_err(req, EIO);
        tx_state.state = TX_STATE_RW_COMMAND;
        break;
    case TX_STATE_SET_STATE_BLOB:
        ptm_write_stateblob(req, buf, size);
        break;
    case TX_STATE_CLOSED:
        /* not possible */
        break;
    }
}

/*
 * ptm_open: interface to POSIX open()
 */
static void ptm_open(fuse_req_t req, struct fuse_file_info *fi)
{
    if (tx_state.state != TX_STATE_CLOSED) {
        fuse_reply_err(req, EBUSY);
        return;
    }

    tx_state.state = TX_STATE_RW_COMMAND;

    fuse_reply_open(req, fi);
}

/*
 * ptm_release:
 */
static void ptm_release(fuse_req_t req, struct fuse_file_info *fi)
{
    tx_state.state = TX_STATE_CLOSED;

    fuse_reply_err(req, 0);
}

/*
 * ptm_ioctl : ioctl execution
 *
 * req: the fuse_req_t used to send response with
 * cmd: the ioctl request code
 * arg: the pointer the application used for calling the ioctl (3rd param)
 * fi:
 * flags: some flags provided by fuse
 * in_buf: the copy of the input buffer
 * in_bufsz: size of the input buffer; provided by fuse and has size of
 *           needed buffer
 * out_bufsz: size of the output buffer; provided by fuse and has size of
 *            needed buffer
 */
static void ptm_ioctl(fuse_req_t req, int cmd, void *arg,
                      struct fuse_file_info *fi SWTPM_ATTR_UNUSED,
                      unsigned flags SWTPM_ATTR_UNUSED,
                      const void *in_buf, size_t in_bufsz, size_t out_bufsz)
{
    TPM_RESULT res = TPM_FAIL;
    bool exit_prg = FALSE;
    ptm_init *init_p;
    TPM_MODIFIER_INDICATOR orig_locality;

    /* some commands have to wait until the worker thread is done */
    switch(cmd) {
    case PTM_GET_CAPABILITY:
    case PTM_SET_LOCALITY:
    case PTM_CANCEL_TPM_CMD:
    case PTM_GET_CONFIG:
    case PTM_SET_BUFFERSIZE:
    case PTM_LOCK_STORAGE:
        /* no need to wait */
        break;
    case PTM_INIT:
    case PTM_SHUTDOWN:
    case PTM_GET_TPMESTABLISHED:
    case PTM_RESET_TPMESTABLISHED:
    case PTM_HASH_START:
    case PTM_HASH_DATA:
    case PTM_HASH_END:
    case PTM_STORE_VOLATILE:
    case PTM_GET_STATEBLOB:
    case PTM_SET_STATEBLOB:
        if (tpm_running)
            worker_thread_wait_done();
        break;
    }

    /* prevent other threads from writing or doing ioctls */
    g_mutex_lock(FILE_OPS_LOCK);

    switch (cmd) {
    case PTM_GET_CAPABILITY:
        if (out_bufsz != sizeof(ptm_cap)) {
            struct iovec iov = { arg, sizeof(uint8_t) };
            fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
        } else {
            ptm_cap ptm_caps;
            switch (tpmversion) {
            case TPMLIB_TPM_VERSION_2:
                ptm_caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN
                    | PTM_CAP_GET_TPMESTABLISHED
                    | PTM_CAP_SET_LOCALITY
                    | PTM_CAP_HASHING
                    | PTM_CAP_CANCEL_TPM_CMD
                    | PTM_CAP_STORE_VOLATILE
                    | PTM_CAP_RESET_TPMESTABLISHED
                    | PTM_CAP_GET_STATEBLOB
                    | PTM_CAP_SET_STATEBLOB
                    | PTM_CAP_STOP
                    | PTM_CAP_GET_CONFIG
                    | PTM_CAP_SET_BUFFERSIZE
                    | PTM_CAP_GET_INFO
                    | PTM_CAP_LOCK_STORAGE;
                break;
            case TPMLIB_TPM_VERSION_1_2:
                ptm_caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN
                    | PTM_CAP_GET_TPMESTABLISHED
                    | PTM_CAP_SET_LOCALITY
                    | PTM_CAP_HASHING
                    | PTM_CAP_CANCEL_TPM_CMD
                    | PTM_CAP_STORE_VOLATILE
                    | PTM_CAP_RESET_TPMESTABLISHED
                    | PTM_CAP_GET_STATEBLOB
                    | PTM_CAP_SET_STATEBLOB
                    | PTM_CAP_STOP
                    | PTM_CAP_GET_CONFIG
                    | PTM_CAP_SET_BUFFERSIZE
                    | PTM_CAP_GET_INFO
                    | PTM_CAP_LOCK_STORAGE;
                break;
            }
            fuse_reply_ioctl(req, 0, &ptm_caps, sizeof(ptm_caps));
        }
        break;

    case PTM_INIT:
        if (in_bufsz != sizeof(ptm_init)) {
            struct iovec iov = { arg, sizeof(uint8_t) };
            fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
        } else {
            init_p = (ptm_init *)in_buf;

            worker_thread_end();

            if (tpm_running && !g_disable_auto_shutdown)
                tpmlib_maybe_send_tpm2_shutdown(tpmversion,
                                                &g_lastCommand);

            TPMLIB_Terminate();

            tpm_running = false;
            if (tpm_start(init_p->u.req.init_flags, tpmversion, &res) < 0) {
                logprintf(STDERR_FILENO,
                          "Error: Could not initialize the TPM.\n");
            } else {
                tpm_running = true;
            }
            init_p->u.resp.tpm_result = res;
            fuse_reply_ioctl(req, 0, init_p, sizeof(*init_p));
        }
        break;

    case PTM_STOP:
        worker_thread_end();

        if (tpm_running && !g_disable_auto_shutdown)
            tpmlib_maybe_send_tpm2_shutdown(tpmversion, &g_lastCommand);

        res = TPM_SUCCESS;
        TPMLIB_Terminate();

        tpm_running = false;

        free(ptm_response);
        ptm_response = NULL;

        fuse_reply_ioctl(req, 0, &res, sizeof(res));

        break;

    case PTM_SHUTDOWN:
        worker_thread_end();

        if (tpm_running && !g_disable_auto_shutdown)
            tpmlib_maybe_send_tpm2_shutdown(tpmversion, &g_lastCommand);

        res = TPM_SUCCESS;
        TPMLIB_Terminate();

        free(ptm_response);
        ptm_response = NULL;

        fuse_reply_ioctl(req, 0, &res, sizeof(res));
        exit_prg = TRUE;

        break;

    case PTM_GET_TPMESTABLISHED:
        if (!tpm_running)
            goto error_not_running;

        if (out_bufsz != sizeof(ptm_est)) {
            struct iovec iov = { arg, sizeof(uint8_t) };
            fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
        } else {
            ptm_est te;
            memset(&te, 0, sizeof(te));
            te.u.resp.tpm_result = TPM_IO_TpmEstablished_Get(&te.u.resp.bit);
            fuse_reply_ioctl(req, 0, &te, sizeof(te));
        }
        break;

    case PTM_RESET_TPMESTABLISHED:
        if (!tpm_running)
            goto error_not_running;

        if (in_bufsz != sizeof(ptm_reset_est)) {
            struct iovec iov = { arg, sizeof(uint32_t) };
            fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
        } else {
            ptm_reset_est *re = (ptm_reset_est *)in_buf;
            if (re->u.req.loc > 4) {
                res = TPM_BAD_LOCALITY;
            } else {
                /* set locality and reset flag in one command */
                orig_locality = locality;
                locality = re->u.req.loc;

                res = TPM_IO_TpmEstablished_Reset();

                locality = orig_locality;
                fuse_reply_ioctl(req, 0, &res, sizeof(res));
            }
        }
        break;

    case PTM_SET_LOCALITY:
        if (in_bufsz != sizeof(ptm_loc)) {
            struct iovec iov = { arg, sizeof(uint32_t) };
            fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
        } else {
            ptm_loc *l = (ptm_loc *)in_buf;
            if (l->u.req.loc > 4 ||
                (l->u.req.loc == 4 &&
                 locality_flags & LOCALITY_FLAG_REJECT_LOCALITY_4)) {
                res = TPM_BAD_LOCALITY;
            } else {
                res = TPM_SUCCESS;
                locality = l->u.req.loc;
            }
            l->u.resp.tpm_result = res;
            fuse_reply_ioctl(req, 0, l, sizeof(*l));
        }
        break;

    case PTM_HASH_START:
        if (!tpm_running)
            goto error_not_running;

        res = TPM_IO_Hash_Start();
        fuse_reply_ioctl(req, 0, &res, sizeof(res));
        break;

    case PTM_HASH_DATA:
        if (!tpm_running)
            goto error_not_running;

        if (in_bufsz != sizeof(ptm_hdata)) {
            struct iovec iov = { arg, sizeof(uint32_t) };
            fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
        } else {
            ptm_hdata *data = (ptm_hdata *)in_buf;
            if (data->u.req.length <= sizeof(data->u.req.data)) {
                res = TPM_IO_Hash_Data(data->u.req.data,
                                       data->u.req.length);
            } else {
                res = TPM_FAIL;
            }
            data->u.resp.tpm_result = res;
            fuse_reply_ioctl(req, 0, data, sizeof(*data));
        }
        break;

    case PTM_HASH_END:
        if (!tpm_running)
            goto error_not_running;

        res = TPM_IO_Hash_End();
        fuse_reply_ioctl(req, 0, &res, sizeof(res));
        break;

    case PTM_CANCEL_TPM_CMD:
        if (!tpm_running)
            goto error_not_running;

        /* for cancellation to work, the TPM would have to
         * execute in another thread that polls on a cancel
         * flag
         */
        res = TPMLIB_CancelCommand();
        fuse_reply_ioctl(req, 0, &res, sizeof(res));
        break;

    case PTM_STORE_VOLATILE:
        if (!tpm_running)
            goto error_not_running;

        res = SWTPM_NVRAM_Store_Volatile();
        fuse_reply_ioctl(req, 0, &res, sizeof(res));

        cached_stateblob_free();
        break;

    case PTM_GET_STATEBLOB:
        if (!tpm_running)
            goto error_not_running;

        if (in_bufsz != sizeof(ptm_getstate)) {
            struct iovec iov = { arg, sizeof(uint32_t) };
            fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
        } else {
            ptm_get_stateblob(req, (ptm_getstate *)in_buf);
        }
        break;

    case PTM_SET_STATEBLOB:
        if (tpm_running)
            goto error_running;

        /* tpm state dir must be set */
        SWTPM_NVRAM_Init();
        if ((exit_prg = !ensure_locked_storage())) {
            fuse_reply_err(req, EIO);
        } else if (in_bufsz != sizeof(ptm_setstate)) {
            struct iovec iov = { arg, sizeof(uint32_t) };
            fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
        } else {
            ptm_set_stateblob(req, (ptm_setstate *)in_buf);
        }
        break;

    case PTM_GET_CONFIG:
        if (out_bufsz != sizeof(ptm_getconfig)) {
            struct iovec iov = { arg, sizeof(uint32_t) };
            fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
        } else {
            ptm_getconfig pgs;
            pgs.u.resp.tpm_result = 0;
            pgs.u.resp.flags = 0;
            if (SWTPM_NVRAM_Has_FileKey())
                pgs.u.resp.flags |= PTM_CONFIG_FLAG_FILE_KEY;
            if (SWTPM_NVRAM_Has_MigrationKey())
                pgs.u.resp.flags |= PTM_CONFIG_FLAG_MIGRATION_KEY;
            fuse_reply_ioctl(req, 0, &pgs, sizeof(pgs));
        }
        break;

    case PTM_SET_BUFFERSIZE:
        if (out_bufsz != sizeof(ptm_setbuffersize)) {
            struct iovec iov = { arg, sizeof(uint32_t) };
            fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
        } else {
            ptm_setbuffersize *in_psbs = (ptm_setbuffersize *)in_buf;
            ptm_setbuffersize out_psbs;
            uint32_t buffersize, minsize, maxsize;

            buffersize = in_psbs->u.req.buffersize;

            if (buffersize > 0 && tpm_running)
                goto error_running;

            buffersize = TPMLIB_SetBufferSize(buffersize,
                                              &minsize,
                                              &maxsize);

            out_psbs.u.resp.tpm_result = TPM_SUCCESS;
            out_psbs.u.resp.buffersize = buffersize;
            out_psbs.u.resp.minsize = minsize;
            out_psbs.u.resp.maxsize = maxsize;
            fuse_reply_ioctl(req, 0, &out_psbs, sizeof(out_psbs));
        }
        break;

    case PTM_GET_INFO:
        if (out_bufsz != sizeof(ptm_getinfo)) {
            struct iovec iov = { arg, sizeof(uint32_t) };
            fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
        } else {
            ptm_getinfo *in_pgi = (ptm_getinfo *)in_buf;
            ptm_getinfo out_pgi;
            char *info_data;
            uint32_t length, offset;

            info_data = TPMLIB_GetInfo(in_pgi->u.req.flags);
            if (!info_data)
                goto error_memory;

            offset = in_pgi->u.req.offset;
            if (offset >= strlen(info_data)) {
                free(info_data);
                goto error_bad_input;
            }

            length = min(strlen(info_data) + 1 - offset,
                         sizeof(out_pgi.u.resp.buffer));

            out_pgi.u.resp.tpm_result = 0;
            out_pgi.u.resp.totlength = strlen(info_data) + 1;
            out_pgi.u.resp.length = length;
            /* client has to collect whole string in case buffer is too small */
            memcpy(out_pgi.u.resp.buffer, &info_data[offset], length);
            free(info_data);

            fuse_reply_ioctl(req, 0, &out_pgi, sizeof(out_pgi));
        }
        break;

    case PTM_LOCK_STORAGE:
        if (out_bufsz != sizeof(ptm_lockstorage)) {
            struct iovec iov = { arg, sizeof(uint32_t) };
            fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
        } else {
            ptm_lockstorage *in_pls = (ptm_lockstorage *)in_buf;
            ptm_lockstorage out_pls;

            g_locking_retries = in_pls->u.req.retries;

            if (!ensure_locked_storage())
                out_pls.u.resp.tpm_result = TPM_FAIL;
            else
                out_pls.u.resp.tpm_result = TPM_SUCCESS;
            fuse_reply_ioctl(req, 0, &out_pls, sizeof(out_pls));
        }

        break;

    default:
        fuse_reply_err(req, EINVAL);
    }

cleanup:
    g_mutex_unlock(FILE_OPS_LOCK);

    if (exit_prg) {
        logprintf(STDOUT_FILENO, "CUSE TPM is shutting down.\n");
        ptm_cleanup();
        fuse_session_exit(ptm_fuse_session);
    }

    return;

error_bad_input:
    res = TPM_BAD_PARAMETER;
    fuse_reply_ioctl(req, 0, &res, sizeof(res));

    goto cleanup;

error_running:
error_not_running:
    res = TPM_BAD_ORDINAL;
    fuse_reply_ioctl(req, 0, &res, sizeof(res));

    goto cleanup;

error_memory:
    res = TPM_SIZE;
    fuse_reply_ioctl(req, 0, &res, sizeof(res));

    goto cleanup;
}

static void ptm_init_done(void *userdata)
{
    struct cuse_param *param = userdata;
    int ret;

    /* at this point the entry in /dev/ is available */
    if (pidfile_write(getpid()) < 0) {
        ret = -13;
        goto error_exit;
    }

    if (param->runas) {
        ret = change_process_owner(param->runas);
        if (ret)
            goto error_exit;
    }

    if (create_seccomp_profile(true, param->seccomp_action) < 0) {
        ret = -14;
        goto error_exit;
    }

    return;

error_exit:
    ptm_cleanup();

    exit(ret);
}

static void ptm_cleanup(void)
{
    pidfile_remove();
    log_global_free();
    tpmstate_global_free();
    SWTPM_NVRAM_Shutdown();
}

static const struct cuse_lowlevel_ops clops = {
    .open = ptm_open,
    .read = ptm_read,
    .write = ptm_write,
    .release = ptm_release,
    .ioctl = ptm_ioctl,
    .init_done = ptm_init_done,
};

/* ptm_cuse_lowlevel_main is like cuse_lowlevel_main with the difference that
 * it uses a global ptm_fuse_session so we can call fuse_session_exit() on it
 * for a graceful exit with cleanups.
 */
static int
ptm_cuse_lowlevel_main(int argc, char *argv[], const struct cuse_info *ci,
                       const struct cuse_lowlevel_ops *clop, void *userdata)
{
    int mt;
    int ret;
    struct cuse_param *param = userdata;

    ptm_fuse_session = cuse_lowlevel_setup(argc, argv, ci, clop, &mt,
                                           userdata);
    if (ptm_fuse_session == NULL)
        return 1;

    if (param->seccomp_action == SWTPM_SECCOMP_ACTION_NONE && mt)
        ret = fuse_session_loop_mt(ptm_fuse_session);
    else
        ret = fuse_session_loop(ptm_fuse_session);

    cuse_lowlevel_teardown(ptm_fuse_session);
    if (ret < 0)
        ret = 1;

    return ret;
}

#ifndef HAVE_SWTPM_CUSE_MAIN
int main(int argc, char **argv)
{
    const char *prgname = argv[0];
    const char *iface = "";
#else
int swtpm_cuse_main(int argc, char **argv, const char *prgname, const char *iface)
{
#endif
    int opt, longindex = 0;
    static struct option longopts[] = {
        {"maj"           , required_argument, 0, 'M'},
        {"min"           , required_argument, 0, 'm'},
        {"name"          , required_argument, 0, 'n'},
        {"runas"         , required_argument, 0, 'r'},
        {"chroot"        , required_argument, 0, 'R'},
        {"log"           , required_argument, 0, 'l'},
        {"locality"      , required_argument, 0, 'L'},
        {"key"           , required_argument, 0, 'k'},
        {"migration-key" , required_argument, 0, 'K'},
        {"pid"           , required_argument, 0, 'p'},
        {"tpmstate"      , required_argument, 0, 's'},
        {"flags"         , required_argument, 0, 'F'},
        {"tpm2"          ,       no_argument, 0, '2'},
        {"help"          ,       no_argument, 0, 'h'},
        {"version"       ,       no_argument, 0, 'v'},
#ifdef WITH_SECCOMP
        {"seccomp"       , required_argument, 0, 'S'},
#endif
        {"migration"     , required_argument, 0, 'i'},
        {"print-capabilities"
                         ,       no_argument, 0, 'a'},
        {"print-states"  ,       no_argument, 0, 'e'},
        {NULL            , 0                , 0, 0  },
    };
    struct cuse_info cinfo;
    struct cuse_param param = {
        .startupType = _TPM_ST_NONE,
    };
    const char *devname = NULL;
    char *cinfo_argv[1] = { 0 };
    unsigned int num;
    struct passwd *passwd;
    const char *uri = NULL;
    int n, tpmfd;
    char path[PATH_MAX];
    int ret = 0;
    bool printcapabilities = false;
    bool printstates = false;
    bool need_init_cmd = true;
    TPM_RESULT res;

    memset(&cinfo, 0, sizeof(cinfo));
    memset(&param, 0, sizeof(param));

    log_set_prefix("swtpm: ");

    tpmversion = TPMLIB_TPM_VERSION_1_2;

    while (true) {
        opt = getopt_long(argc, argv, "M:m:n:r:R:hv", longopts, &longindex);

        if (opt == -1)
            break;

        switch (opt) {
        case 'M': /* major */
            if (sscanf(optarg, "%u", &num) != 1) {
                logprintf(STDERR_FILENO, "Could not parse major number\n");
                ret = -1;
                goto exit;
            }
            if (num > 65535) {
                logprintf(STDERR_FILENO,
                          "Major number outside valid range [0 - 65535]\n");
                ret = -1;
                goto exit;
            }
            cinfo.dev_major = num;
            break;
        case 'm': /* minor */
            if (sscanf(optarg, "%u", &num) != 1) {
                logprintf(STDERR_FILENO, "Could not parse major number\n");
                ret = -1;
                goto exit;
            }
            if (num > 65535) {
                logprintf(STDERR_FILENO,
                          "Major number outside valid range [0 - 65535]\n");
                ret = -1;
                goto exit;
            }
            cinfo.dev_minor = num;
            break;
        case 'n': /* name */
            if (!cinfo.dev_info_argc) {
                cinfo_argv[0] = calloc(1, strlen("DEVNAME=") + strlen(optarg) + 1);
                if (!cinfo_argv[0]) {
                    logprintf(STDERR_FILENO, "Out of memory\n");
                    ret = -1;
                    goto exit;
                }
                devname = optarg;

                strcpy(cinfo_argv[0], "DEVNAME=");
                strcat(cinfo_argv[0], optarg);

                cinfo.dev_info_argc = 1;
                cinfo.dev_info_argv = (const char **)cinfo_argv;
            }
            break;
        case 'r': /* runas */
            param.runas = optarg;
            break;
        case 'R':
            param.chroot = optarg;
            break;
        case 'l': /* log */
            param.logging = optarg;
            break;
        case 'k': /* key */
            param.keydata = optarg;
            break;
        case 'K': /* migration-key */
            param.migkeydata = optarg;
            break;
        case 'p': /* pid */
            param.piddata = optarg;
            break;
        case 's': /* tpmstate */
            param.tpmstatedata = optarg;
            break;
        case 'L':
            param.localitydata = optarg;
            break;
        case 'F':
            param.flagsdata = optarg;
            break;
        case '2':
            tpmversion = TPMLIB_TPM_VERSION_2;
            break;
        case 'S':
            param.seccompdata = optarg;
            break;
        case 'i': /* --migration */
            param.migrationdata = optarg;
            break;
        case 'h': /* help */
            fprintf(stdout, usage, prgname, iface);
            goto exit;
        case 'a':
            printcapabilities = true;
            break;
        case 'e':
            printstates = true;
            break;
        case 'v': /* version */
            fprintf(stdout, "TPM emulator CUSE interface version %d.%d.%d, "
                    "Copyright (c) 2014-2015 IBM Corp.\n",
                    SWTPM_VER_MAJOR,
                    SWTPM_VER_MINOR,
                    SWTPM_VER_MICRO);
            goto exit;
        }
    }

    if (optind < argc) {
        logprintf(STDERR_FILENO,
                  "Unknown parameter '%s'\n", argv[optind]);
        ret = EXIT_FAILURE;
        goto exit;
    }

    if (setuid(0)) {
        logprintf(STDERR_FILENO, "Error: Unable to setuid root. uid = %d, "
                  "euid = %d, gid = %d\n", getuid(), geteuid(), getgid());
        ret = -4;
        goto exit;
    }

    if (param.chroot) {
        if (do_chroot(param.chroot) < 0) {
            ret = EXIT_FAILURE;
            goto exit;
        }
    }

    if (param.runas) {
        if (!(passwd = getpwnam(param.runas))) {
            logprintf(STDERR_FILENO, "User '%s' does not exist\n",
                      param.runas);
            ret = -5;
            goto exit;
        }
    }

    if (handle_log_options(param.logging) < 0) {
        ret = EXIT_FAILURE;
        goto exit;
    }

    if (printcapabilities) {
        /*
         * Choose the TPM version so that getting/setting buffer size works.
         * Ignore failure, for backward compatibility when TPM 1.2 is disabled.
         */
        ret = capabilities_print_json(true, tpmversion) ? EXIT_FAILURE : EXIT_SUCCESS;
        goto exit;
    }

    if (tpmlib_choose_tpm_version(tpmversion) != TPM_SUCCESS) {
        ret = EXIT_FAILURE;
        goto exit;
    }

    tpmstate_set_version(tpmversion);

    if (printstates) {
        if (handle_tpmstate_options(param.tpmstatedata) < 0) {
            ret = EXIT_FAILURE;
            goto exit;
        }
        if (param.tpmstatedata == NULL) {
            logprintf(STDERR_FILENO,
                      "Error: --tpmstate option is required for --print-states\n");
            ret = EXIT_FAILURE;
            goto exit;
        }
        ret = SWTPM_NVRAM_PrintJson();
        ret = ret ? EXIT_FAILURE : EXIT_SUCCESS;
        goto exit;
    }

    if (!cinfo.dev_info_argv) {
        logprintf(STDERR_FILENO, "Error: device name missing\n");
        ret = -2;
        goto exit;
    }

    if (handle_key_options(param.keydata) < 0 ||
        handle_migration_key_options(param.migkeydata) < 0 ||
        handle_pid_options(param.piddata) < 0 ||
        handle_tpmstate_options(param.tpmstatedata) < 0 ||
        handle_seccomp_options(param.seccompdata, &param.seccomp_action) < 0 ||
        handle_locality_options(param.localitydata, &locality_flags) < 0 ||
        handle_flags_options(param.flagsdata, &need_init_cmd,
                             &param.startupType, &g_disable_auto_shutdown) < 0 ||
        handle_migration_options(param.migrationdata, &g_incoming_migration,
                                 &g_release_lock_outgoing) < 0) {
        ret = -3;
        goto exit;
    }

    uri = tpmstate_get_backend_uri();
    if (uri == NULL) {
        logprintf(STDERR_FILENO,
                  "Error: No TPM state directory is defined; "
                  "TPM_PATH is not set\n");
        ret = -1;
        goto exit;
    }

    n = snprintf(path, sizeof(path), "/dev/%s", devname);
    if (n < 0) {
        logprintf(STDERR_FILENO,
                  "Error: Could not create device file name\n");
        ret = -1;
        goto exit;
    }
    if (n >= (int)sizeof(path)) {
        logprintf(STDERR_FILENO,
                  "Error: Buffer too small to create device file name\n");
        ret = -1;
        goto exit;
    }

    tpmfd = open(path, O_RDWR);
    if (tpmfd >= 0) {
        close(tpmfd);
        logprintf(STDERR_FILENO,
                  "Error: A device '%s' already exists.\n",
                  path);
        ret = -1;
        goto exit;
    }

    if (tpmlib_register_callbacks(&cbs) != TPM_SUCCESS) {
        ret = -1;
        goto exit;
    }

    worker_thread_init();

    if (!need_init_cmd) {
        if (tpm_start(0, tpmversion, &res) < 0) {
            ret = -1;
            goto exit;
        }
        tpm_running = true;
    }

    if (param.startupType != _TPM_ST_NONE) {
        if (ptm_send_startup(param.startupType, tpmversion) < 0) {
            ret = -1;
            goto exit;
        }
    }

#if GLIB_MINOR_VERSION >= 32
    g_mutex_init(FILE_OPS_LOCK);
#else
    FILE_OPS_LOCK = g_mutex_new();
#endif

    ret = ptm_cuse_lowlevel_main(1, argv, &cinfo, &clops, &param);

exit:
    ptm_cleanup();
    free(cinfo_argv[0]);

    return ret;
}
