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

PKI_CA_SIGNING_NICKNAME="${PKI_CA_SIGNING_NICKNAME:-ca_signing}"
PKI_OCSP_SIGNING_NICKNAME="${PKI_OCSP_SIGNING_NICKNAME:-ca_ocsp_signing}"
PKI_SUBSYSTEM_NICKNAME="${PKI_SUBSYSTEM_NICKNAME:-subsystem}"
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 [ "$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/server.p12 ]
then
    echo "INFO: Importing server certs and keys"

    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        pkcs12-import \
        --pkcs12 /certs/server.p12 \
        --password Secret.123
fi

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

# check whether CA signing cert exists
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=$?

if [ $rc -ne 0 ]
then
    echo "INFO: Creating CA signing cert"

    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

    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

    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 "################################################################################"

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

# check whether OCSP signing cert exists
rc=0
pki \
    -d /conf/alias \
    -f /conf/password.conf \
    nss-cert-export \
    --output-file /tmp/ca_ocsp_signing.crt \
    "$PKI_OCSP_SIGNING_NICKNAME" \
    2> /dev/null || rc=$?

if [ $rc -ne 0 ]
then
    echo "INFO: Creating OCSP signing cert"

    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        nss-cert-request \
        --subject "CN=OCSP Signing Certificate" \
        --ext /usr/share/pki/server/certs/ocsp_signing.conf \
        --csr /conf/certs/ca_ocsp_signing.csr

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

    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        nss-cert-import \
        --cert /tmp/ca_ocsp_signing.crt \
        "$PKI_OCSP_SIGNING_NICKNAME"
fi

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

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

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

echo "INFO: Audit signing cert:"
pki \
    -d /conf/alias \
    -f /conf/password.conf \
    nss-cert-show \
    "$PKI_AUDIT_SIGNING_NICKNAME" \
    2> /dev/null || true

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

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

# check whether subsystem cert exists
rc=0
pki \
    -d /conf/alias \
    -f /conf/password.conf \
    nss-cert-export \
    --output-file /tmp/subsystem.crt \
    "$PKI_SUBSYSTEM_NICKNAME" \
    2> /dev/null || rc=$?

if [ $rc -ne 0 ]
then
    echo "INFO: Creating subsystem cert"

    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        nss-cert-request \
        --subject "CN=Subsystem Certificate" \
        --csr /conf/certs/subsystem.csr

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

    pki \
        -d /conf/alias \
        -f /conf/password.conf \
        nss-cert-import \
        --cert /tmp/subsystem.crt \
        "$PKI_SUBSYSTEM_NICKNAME"
fi

echo "INFO: Subsystem cert:"
pki \
    -d /conf/alias \
    -f /conf/password.conf \
    nss-cert-show \
    "$PKI_SUBSYSTEM_NICKNAME"

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

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

# check whether SSL server cert exists
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=$?

if [ $rc -ne 0 ]
then
    echo "INFO: Creating SSL server cert"

    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

    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

    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: Creating CA server"

OPTIONS=()

OPTIONS+=(--conf /conf)
OPTIONS+=(--logs /logs)

OPTIONS+=(-f /usr/share/pki/server/examples/installation/ca.cfg)
OPTIONS+=(-s CA)

OPTIONS+=(-D pki_group=root)

OPTIONS+=(-D pki_ds_url=$PKI_DS_URL)
OPTIONS+=(-D pki_ds_password=$PKI_DS_PASSWORD)
OPTIONS+=(-D pki_ds_database=userroot)
OPTIONS+=(-D pki_ds_setup=False)
OPTIONS+=(-D pki_skip_ds_verify=True)
OPTIONS+=(-D pki_share_db=True)

OPTIONS+=(-D pki_import_system_certs=False)

OPTIONS+=(-D pki_ca_signing_nickname="$PKI_CA_SIGNING_NICKNAME")
OPTIONS+=(-D pki_ca_signing_csr_path=/conf/certs/ca_signing.csr)

OPTIONS+=(-D pki_ocsp_signing_nickname="$PKI_OCSP_SIGNING_NICKNAME")
OPTIONS+=(-D pki_ocsp_signing_csr_path=/conf/certs/ca_ocsp_signing.csr)

OPTIONS+=(-D pki_audit_signing_nickname="$PKI_AUDIT_SIGNING_NICKNAME")
if [ -f /conf/certs/ca_audit_signing.csr ]
then
    OPTIONS+=(-D pki_audit_signing_csr_path=/conf/certs/ca_audit_signing.csr)
fi

OPTIONS+=(-D pki_subsystem_nickname="$PKI_SUBSYSTEM_NICKNAME")
OPTIONS+=(-D pki_subsystem_csr_path=/conf/certs/subsystem.csr)

OPTIONS+=(-D pki_sslserver_nickname="$PKI_SSLSERVER_NICKNAME")
OPTIONS+=(-D pki_sslserver_csr_path=/conf/certs/sslserver.csr)

OPTIONS+=(-D pki_admin_setup=False)
OPTIONS+=(-D pki_security_domain_setup=False)
OPTIONS+=(-D pki_security_manager=False)
OPTIONS+=(-D pki_systemd_service_create=False)
OPTIONS+=(-D pki_registry_enable=False)

OPTIONS+=(-v)

pkispawn "${OPTIONS[@]}"

echo "################################################################################"
echo "INFO: Configuring CA server"

pki-server ca-config-set internaldb.minConns 0
pki-server ca-config-set ca.authorityMonitor.enable false

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/ca_ocsp_signing.crt
rm /tmp/subsystem.crt
rm /tmp/sslserver.crt

echo "################################################################################"
echo "INFO: Starting CA 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 &
    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 &
    PID=$!
    wait $PID
fi
