#!/bin/sh
# Script for provisioning and running the swtpm emulator. This script can only be run by a user with
# sudo privileges.
set -e

# The name of the virtual TPM device. This will determine the name of the device under /dev.
TPM_NAME=vtpm0
# The path to the directory where the TPM's state will be stored.
TPM_PATH=/tmp/$TPM_NAME
# The file where swtpm's pid will be stored.
TPM_PID=$TPM_PATH/swtpm.pid
# The file where tpm2-abrmd's pid will be stored.
TPM_ABRMD_PID=$TPM_PATH/tpm2-abrmd.pid
TPM_ADDR=127.0.0.1
TPM_PORT=2321

setup() {
    mkdir -p $TPM_PATH
    swtpm_setup --config swtpm_setup.conf --tpm-state dir://$TPM_PATH \
        --tpm2 --ecc --createek --display
}

start() {
    if [ ! -d $TPM_PATH ]; then
        setup
    fi
    if [ -f $TPM_PID ]; then
        echo "swtpm is already running with PID $(cat $TPM_PID)."
        exit 1
    fi
    swtpm socket --server type=tcp,port=$TPM_PORT,bindaddr=$TPM_ADDR \
        --ctrl type=tcp,port=$(($TPM_PORT + 1)),bindaddr=$TPM_ADDR \
        --tpm2 --log file=$TPM_PATH/log.txt,level=5 \
        --flags not-need-init,startup-clear --pid file=$TPM_PID \
        --tpmstate dir=$TPM_PATH --daemon
    if [ "$UID" = 0 ]; then
        # If this script was run as root, then connect to the system bus.
        tpm2-abrmd --tcti="swtpm:host=$TPM_ADDR" --allow-root &
    else
        tpm2-abrmd --tcti="swtpm:host=$TPM_ADDR" --session &
    fi
    echo -n $! > $TPM_ABRMD_PID
}

kill_from_file() {
    pid=$(cat $1)
    kill -s TERM $pid
}

stop() {
    if [ ! -f $TPM_PID ]; then
        echo "swtpm is not running."
        exit 1
    fi
    kill_from_file $TPM_ABRMD_PID
    rm $TPM_ABRMD_PID
    kill_from_file $TPM_PID
}

restart() {
    stop
    sleep 0.2
    start
}

purge() {
    if [ -f $TPM_PID ]; then
        stop
    fi
    rm -rf $TPM_PATH
}

usage() {
    echo "${0} <start|stop|restart>"
}

case "${1}" in
    start)
        start
        ;;
    stop) 
        stop
        ;;
    restart)
        restart
        ;;
    purge)
        purge
        ;;
    *)
        usage
        ;;
esac