#!/bin/bash

#
# AIM: Ask SSL certificates to an ACME Server
#

. /usr/lib/eole/ihm.sh

MODE=$1
[ -z "$MODE" ] && MODE=test

function openPorts()
{
    local SOURCE=${1}
    shift
    local PORTS=${@}

    for prt in ${PORTS}
    do
        iptables -I INPUT -p tcp -m tcp --dport ${prt} --tcp-flags FIN,SYN,RST,ACK SYN -j ACCEPT
    done
}

function startWWW()
{
    PIDFILE=$(mktemp)
    WWWSRV=nginx
    OPT="-c /etc/eole/ssl/nginx-minimal.conf"
    CMD="${WWWSRV} ${OPT}"
    [[ ! -d "/tmp/www" ]] && mkdir -p /tmp/www

    ${CMD}
    PID=$(pidof ${CMD})
	if [[ -n ${PID} ]]
    then
        echo ${PID} > ${PIDFILE}
        echo ${PIDFILE}
        return 0
    else
        return 1
    fi
}

function getRevProxDomains()
{
    local names=($(CreoleGet revprox_domainname))
    local wildcards=($(CreoleGet revprox_domain_wildcard))
    local cert=($(CreoleGet revprox_le_cert 2> /dev/null))
    local toRet=""
    local i=0
    local i_cert=0

    for name in ${names[@]}
    do
        wildcard="${wildcards[${i}]}"
        if [[ ${wildcard} == "non" ]]
        then
            rep="${cert[${i_cert}]}"
            if [[ ${rep} == 'oui' ]]
            then
                toRet="${toRet} ${name}"
            fi
            ((i_cert+=1))
        fi
        ((i+=1))
    done

    echo ${toRet}
    return 0
}

function startHttp()
{
	# Test if apache is running and stop it !
    PIDAPACHE=$(pidof apache2)
    [[ -n ${PIDAPACHE} ]] && CreoleService apache2 stop

    #arrêt de nginx pour laisser la place à nginx
    PIDNGINX=$(pidof nginx)
    [[ -n ${PIDNGINX} ]] && systemctl stop nginx.service

    if [[ ${LEMODE} = 'standalone' ]]
    then
        openPorts "${SERVER}" "${HTTP01PORT}" "${TLSNSIPORT}"
        MODE_OPT="--standalone"
    else
        openPorts "${SERVER}" "80"
        PIDFILE=$(startWWW)
        if [[ ${?} -ne 0 ]]
        then
            EchoRouge "Erreur lors du lancement du serveur web temporaire"
            killHttp
            exit 22
        fi
        MODE_OPT="--webroot --webroot-path /tmp/www"
    fi
}
function killHttp()
{
    # Stop http server
    if [[ -e ${PIDFILE} ]]
    then
        kill $(cat ${PIDFILE})
        if [[ ${?} -ne 0 ]]
        then
            EchoRouge "Erreur lors de l'arrêt du processus $(cat ${PIDFILE}) (serveur web temporaire)"
            exit 45
        else
            rm -f ${PIDFILE}
        fi
    fi
}

if [[ $(CreoleGet cert_type non) == 'letsencrypt'  ]]
then
    PROTOC="https"
    SERVER=$(CreoleGet le_server_addr)
    PORT=$(CreoleGet le_server_port)
    HTTP01PORT=$(CreoleGet le_http_01_port)
    TLSNSIPORT=$(CreoleGet le_tls_sni_port)
    CONFDIR=$(CreoleGet le_config_dir)
    WOKRDIR=$(CreoleGet le_work_dir)
    LOGSDIR=$(CreoleGet le_logs_dir)
    LEMODE=$(CreoleGet le_client_mode)
    PIDFILE=""

    LECLIENT='letsencrypt'
    LEOPT='certonly'

    if [[ -n ${SERVER} ]]
    then
        SERVER="--server ${PROTOC}://${SERVER}"
        [[ -n ${PORT} ]] && SERVER="${SERVER}:${PORT}"
        SERVER="${SERVER}/directory"
    fi

    NOMDOMAINEMACHINE="$(CreoleGet nom_domaine_machine)"
    WEBURL=$(CreoleGet web_url "")

    DOMAINS=""
    for domain in $(CreoleGet le_extra_names)
    do
        DOMAINS="${DOMAINS} ${domain}"
    done

    if [[ "$(CreoleGet activer_revprox non )" == "oui" ]] && [[ "$(CreoleGet revprox_activate_http)" == "oui" ]]
    then
        DOMAINS="${DOMAINS} $(getRevProxDomains)"
    fi

    # Removing duplicate entries in domain list
    DOMAINS=$(awk '{ while(++i<=NF) printf (!a[$i]++) ? $i FS : ""; i=split("",a); print ""  }'  <<< ${DOMAINS})


    if [ "$MODE" = "test" ]; then
        MODE_OPT="$MODE_OPT --staging"
    fi

    GETNEWCERTIF=1
    res=0
    if [ ! -d "${CONFDIR}/live/${NOMDOMAINEMACHINE}" ]; then
        # Creating ACME client command line options for main domain
        DOM_OPT="-d ${NOMDOMAINEMACHINE}"
        if [[ -n ${WEBURL} ]]
        then
            if [[ ${NOMDOMAINEMACHINE} != ${WEBURL} ]]
            then
                DOM_OPT="${DOM_OPT} -d ${WEBURL}"
                echo -n "  - Demande de certificat pour ${NOMDOMAINEMACHINE} ${WEBURL}"
            else
                echo -n "  - Demande de certificat pour ${NOMDOMAINEMACHINE}"
            fi
        else
            echo -n "  - Demande de certificat pour ${NOMDOMAINEMACHINE}"
        fi
        startHttp
        ${LECLIENT} ${LEOPT}                  \
            ${MODE_OPT}                          \
            --expand                          \
            ${SERVER}                         \
            --http-01-port ${HTTP01PORT}      \
            --tls-sni-01-port ${TLSNSIPORT}   \
            ${DOM_OPT}                           \
            --no-verify-ssl                   \
            --non-interactive                 \
            --no-redirect                     \
            --agree-tos                       \
            --register-unsafely-without-email \
            --manual-public-ip-logging-ok     \
            --config-dir ${CONFDIR}           \
            --work-dir ${WOKRDIR}             \
            --logs-dir ${LOGSDIR} > /var/log/eole-letsencrypt.log 2>&1
        cres=${?}
        if [[ ${cres} -ne 0 ]]; then
            EchoRouge " [KO]"
            EchoRouge "Code retour ${cres}"
            EchoRouge "Erreur à la demande du certificat, des logs sont disponibles dans le fichier /var/log/eole-letsencrypt.log"
            killHttp
            exit 1
        else
            EchoVert " [OK]"
        fi
        ((res+=${cres}))
        GETNEWCERTIF=0
    fi

    # Creating ACME client command line options for extra domains
    for dom in ${DOMAINS}
    do
        if [ ! -d "${CONFDIR}/live/${dom}" ]; then
            echo -n "  - Demande de certificat pour ${dom}"
            if [ "$GETNEWCERTIF" = "1" ]; then
                startHttp
            fi
            ${LECLIENT} ${LEOPT}                  \
                ${MODE_OPT}                          \
                --expand                          \
                ${SERVER}                         \
                --http-01-port ${HTTP01PORT}      \
                --tls-sni-01-port ${TLSNSIPORT}   \
                -d ${dom}                         \
                --no-verify-ssl                   \
                --non-interactive                 \
                --no-redirect                     \
                --agree-tos                       \
                --register-unsafely-without-email \
                --manual-public-ip-logging-ok     \
                --config-dir ${CONFDIR}           \
                --work-dir ${WOKRDIR}             \
                --logs-dir ${LOGSDIR} > /var/log/eole-letsencrypt.log 2>&1
            cres=${?}
            if [[ ${cres} -ne 0 ]]; then
                EchoRouge " [KO]"
                EchoRouge "Code retour ${cres}"
                EchoRouge "Erreur à la demande du certificat, des logs sont disponibles dans le fichier /var/log/eole-letsencrypt.log"
                killHttp
                exit 1
            else
                EchoVert " [OK]"
            fi
            ((res+=${cres}))
            GETNEWCERTIF=0
        fi
    done

    killHttp
    if [[ ${res} -ne 0 ]]; then
        EchoRouge "Erreur lors de la requête ACME veuillez consulter les journaux dans le répertoire ${LOGSDIR}"
        exit 1
    fi
    if [ "$GETNEWCERTIF" = "0" ]; then
        /usr/share/eole/letsencrypt/post.sh
        EchoVert "Certificat généré et pris en compte"
    fi

    exit ${res}
else
    exit 0
fi
