#!/usr/bin/sh -e
#
# Copyright Red Hat, Inc.
#
# SPDX-License-Identifier: GPL-2.0-or-later
#

. /usr/share/pki/scripts/config

PKI_CA_SIGNING_NICKNAME="${PKI_CA_SIGNING_NICKNAME:-ca_signing}"
PKI_SSLSERVER_NICKNAME="${PKI_SSLSERVER_NICKNAME:-sslserver}"

# Allow the owner of the container (who might not be in the root group)
# to manage the config and log files.
umask 000

echo "################################################################################"

if [ -z "$(ls -A /conf 2> /dev/null)" ]
then
    echo "INFO: Installing default config files"
    cp -r /var/lib/pki/pki-tomcat/conf.default/* /conf
fi

if [ -z "$(ls -A /conf/alias 2> /dev/null)" ]
then
    echo "INFO: Creating default NSS database"
    mkdir -p /conf/alias
    pki-server nss-create --no-password
fi

mkdir -p /conf/certs

if [ "$UID" = "0" ]
then
    chown -Rf pkiuser:root /conf
    chown -Rf pkiuser:root /logs
fi

find /conf -type f -exec chmod +rw -- {} +
find /conf -type d -exec chmod +rwx -- {} +
find /logs -type f -exec chmod +rw -- {} +
find /logs -type d -exec chmod +rwx -- {} +

echo "################################################################################"

if [ -f /certs/ca_signing.csr ]
then
    echo "INFO: Importing CA signing CSR"
    cp /certs/ca_signing.csr /conf/certs/ca_signing.csr
fi

if [ -f /certs/sslserver.csr ]
then
    echo "INFO: Importing SSL server CSR"
    cp /certs/sslserver.csr /conf/certs/sslserver.csr
fi

echo "################################################################################"

# import ca_signing.cert and ca_signing.key if available
if [ -f /certs/ca_signing.crt ] && [ -f /certs/ca_signing.key ]
then
    echo "INFO: Importing CA Signing Certificate and Key"

    # generate random password
    openssl rand -hex 8 > /tmp/password

    # import PEM cert and key into PKCS #12 file
    openssl pkcs12 -export \
        -in /certs/ca_signing.crt \
        -inkey /certs/ca_signing.key \
        -out /tmp/certs.p12 \
        -name "$PKI_CA_SIGNING_NICKNAME" \
        -passout file:/tmp/password

    # trust CA signing cert in PKCS #12 file
    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        pkcs12-cert-mod \
        --pkcs12 /tmp/certs.p12 \
        --password-file /tmp/password \
        --trust-flags CT,C,C \
        "$PKI_CA_SIGNING_NICKNAME"

    # import PKCS #12 file into NSS database
    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        pkcs12-import \
        --pkcs12 /tmp/certs.p12 \
        --password-file /tmp/password

    rm /tmp/certs.p12
    rm /tmp/password
fi

# import certs.p12 if available
if [ -f /certs/certs.p12 ]
then
    echo "INFO: Importing Certificates and Keys from PKCS #12 File"

    # import PKCS #12 file into NSS database
    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        pkcs12-import \
        --pkcs12 /certs/certs.p12 \
        --password-file /certs/password
fi

# check whether CA signing certificate is available
rc=0
pki \
    -d /conf/alias \
    -f /conf/password.conf \
    nss-cert-export \
    --output-file /tmp/ca_signing.crt \
    "$PKI_CA_SIGNING_NICKNAME" \
    2> /dev/null || rc=$?

# generate a CA signing certificate if not available
if [ $rc -ne 0 ]
then
    echo "INFO: Creating CA signing cert"

    # generate CA signing CSR
    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        nss-cert-request \
        --subject "CN=CA Signing Certificate" \
        --ext /usr/share/pki/server/certs/ca_signing.conf \
        --csr /conf/certs/ca_signing.csr

    # issue self-signed CA signing cert
    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        nss-cert-issue \
        --csr /conf/certs/ca_signing.csr \
        --ext /usr/share/pki/server/certs/ca_signing.conf \
        --validity-length 1 \
        --validity-unit year \
        --cert /tmp/ca_signing.crt

    # import and trust CA signing cert into NSS database
    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        nss-cert-import \
        --cert /tmp/ca_signing.crt \
        --trust CT,C,C \
        "$PKI_CA_SIGNING_NICKNAME"
fi

echo "INFO: CA signing cert:"
pki \
    -d /conf/alias \
    -f /conf/password.conf \
    nss-cert-show \
    "$PKI_CA_SIGNING_NICKNAME"

echo "################################################################################"

# check whether SSL server certificate is available
rc=0
pki \
    -d /conf/alias \
    -f /conf/password.conf \
    nss-cert-export \
    --output-file /tmp/sslserver.crt \
    "$PKI_SSLSERVER_NICKNAME" \
    2> /dev/null || rc=$?

# generate a SSL server certificate if not available
if [ $rc -ne 0 ]
then
    echo "INFO: Creating SSL server cert"

    # generate SSL server CSR
    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        nss-cert-request \
        --subject "CN=$HOSTNAME" \
        --ext /usr/share/pki/server/certs/sslserver.conf \
        --csr /conf/certs/sslserver.csr

    # issue SSL server cert
    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        nss-cert-issue \
        --issuer "$PKI_CA_SIGNING_NICKNAME" \
        --csr /conf/certs/sslserver.csr \
        --ext /usr/share/pki/server/certs/sslserver.conf \
        --cert /tmp/sslserver.crt

    # import SSL server cert into NSS database
    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        nss-cert-import \
        --cert /tmp/sslserver.crt \
        "$PKI_SSLSERVER_NICKNAME"
fi

echo "INFO: SSL server cert:"
pki \
    -d /conf/alias \
    -f /conf/password.conf \
    nss-cert-show \
    "$PKI_SSLSERVER_NICKNAME"

echo "################################################################################"
echo "INFO: Updating owners and permissions"

if [ "$UID" = "0" ]
then
    chown -Rf pkiuser:root /conf
    chown -Rf pkiuser:root /logs
fi

find /conf -type f -exec chmod +rw -- {} +
find /conf -type d -exec chmod +rwx -- {} +
find /logs -type f -exec chmod +rw -- {} +
find /logs -type d -exec chmod +rwx -- {} +

echo "################################################################################"
echo "INFO: Removing temporary files"

rm /tmp/ca_signing.crt
rm /tmp/sslserver.crt

echo "################################################################################"
echo "INFO: Starting PKI server"

trap "kill -- -$(ps -o pgid= $PID | grep -o '[0-9]*')" TERM

if [ "$UID" = "0" ]; then
    # In Docker the server runs as root user but it will switch
    # into pkiuser (UID=17) that belongs to the root group (GID=0).
    pki-server run --skip-upgrade --skip-migration &
    PID=$!
    wait $PID

else
    # In OpenShift/Podman the server runs as a non-root user
    # (with a random UID) that belongs to the root group (GID=0).
    #
    # https://www.redhat.com/en/blog/jupyter-on-openshift-part-6-running-as-an-assigned-user-id
    pki-server run --as-current-user --skip-upgrade --skip-migration &
    PID=$!
    wait $PID
fi
