# Extra packages required in this snippet:
#  * swtpm
#  * swtpm-tools
#  * tpm2-abrmd
#  * selinux-policy-devel

LOG_FILE=/root/postinstall-swtpm.log
[ -n "@NO_SAVE@" ] && LOG_FILE=/dev/null

exec < /dev/tty3 > /dev/tty3
chvt 3
echo "###############"
echo "# %post swtpm #"
echo "###############"
(
  REQ_PKGS='swtpm swtpm-tools tpm2-abrmd selinux-policy-devel'

  # Sanity check.
  skip=
  for _pkg in ${REQ_PKGS}; do
    rpm -q "${_pkg}" >/dev/null || skip=true
  done

  # el7 is not supported by this snippet.
  if [ -n "${EL_MAJOR}" ] && [ "${EL_MAJOR}" = '7' ]; then
    REQ_PKGS=
    skip=true
  fi

  if [ -z "${skip}" ]; then
    export TPM2TOOLS_TCTI="tabrmd:bus_name=com.intel.tss2.Tabrmd"

    cat > /etc/profile.d/swtpm.sh <<_EOF
export TPM2TOOLS_TCTI=${TPM2TOOLS_TCTI}
export TCTI=${TPM2TOOLS_TCTI}
_EOF

    cat > /etc/systemd/system/swtpm.service <<_EOF
[Unit]
Description=swtpm TPM Software emulator

[Service]
Type=fork
ExecStartPre=/usr/bin/mkdir -p /var/lib/tpm/swtpm
ExecStartPre=/usr/bin/swtpm_setup --tpm-state /var/lib/tpm/swtpm --createek --decryption --create-ek-cert --create-platform-cert --lock-nvram --overwrite --display --tpm2 --pcr-banks sha256
ExecStart=/usr/bin/swtpm socket --tpmstate dir=/var/lib/tpm/swtpm --log level=4 --ctrl type=tcp,port=2322 --server type=tcp,port=2321 --flags startup-clear --tpm2

[Install]
WantedBy=multi-user.target
_EOF

    cat > /etc/systemd/system/tpm2-abrmd.service <<_EOF
[Unit]
Description=TPM2 Access Broker and Resource Management Daemon
# These settings are needed when using the device TCTI. If the
# TCP mssim is used then the settings should be commented out.
#After=dev-tpm0.device
#Requires=dev-tpm0.device
ConditionPathExistsGlob=

[Service]
Type=dbus
BusName=com.intel.tss2.Tabrmd
ExecStart=/usr/sbin/tpm2-abrmd --tcti=swtpm
User=tss

[Install]
WantedBy=multi-user.target
_EOF

    mkdir -p /etc/systemd/system/keylime_agent.service.d
    cat > /etc/systemd/system/keylime_agent.service.d/10-tcti.conf <<_EOF
[Unit]
# we want to unset this since there is no /dev/tmp0
ConditionPathExistsGlob=
[Service]
Environment="TPM2TOOLS_TCTI=${TPM2TOOLS_TCTI}"
Environment="TCTI=${TPM2TOOLS_TCTI}"
_EOF

    mkdir -p /root/swtpm_permissive
    cat > /root/swtpm_permissive/swtpm_permissive.te <<_EOF
policy_module(swtpm_permissive, 1.0)
require {
type swtpm_t;
type swtpm_exec_t;
type tcsd_var_lib_t;
type unreserved_port_t;
type var_lib_t;
type init_t;
}
permissive swtpm_t;

init_daemon_domain(swtpm_t, swtpm_exec_t);

dontaudit swtpm_t self:tcp_socket { accept listen };
dontaudit swtpm_t tcsd_var_lib_t:dir { add_name remove_name write };
dontaudit swtpm_t tcsd_var_lib_t:file { create getattr lock open read rename setattr unlink write };
dontaudit swtpm_t unreserved_port_t:tcp_socket name_bind;
dontaudit swtpm_t var_lib_t:dir { add_name remove_name write };
dontaudit swtpm_t var_lib_t:file { create getattr lock open read rename setattr unlink write };
dontaudit init_t swtpm_exec_t:file { execute execute_no_trans open read };
dontaudit init_t swtpm_exec_t:file map;
_EOF

    pushd /root/swtpm_permissive
    make -f /usr/share/selinux/devel/Makefile swtpm_permissive.pp
    semodule -i swtpm_permissive.pp
    yum remove -y selinux-policy-devel
    popd

    # allow tpm2-abrmd to connect to swtpm port
    setsebool -P tabrmd_connect_all_unreserved on

    systemctl enable swtpm.service
    command -v tpm2_clear && tpm2_clear ||:
  else
    echo "##################################################################"
    echo "#    Kickstart snippet skipped. Please make sure the required    #"
    echo "# variables are defined and the required packages are installed. #"
    echo "#        Note also that this snippet does not support el7.       #"
    echo "##################################################################"
    echo
    echo "* Required variables:"
    echo "(none)"
    echo
    echo "* Required packages: ${REQ_PKGS}"
    echo
    echo "* Installed packages:"
    rpm -qa | sort
    echo
  fi
) 2>&1 | tee "${LOG_FILE}"
chvt 1

# vim:set ts=2 sw=2 et:

