#!/bin/bash

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

. /usr/lib/eole/ihm.sh
. /usr/lib/eole/letsencrypt.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 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}" "${HTTPSPORT}"
        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
}

rm -f /var/lib/eole/reports/letsencrypt.err

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)
    HTTPSPORT=$(CreoleGet le_https_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 [ -f /etc/eole/letsencrypt.conf ]; then
        OLD_SERVER=$(cat /etc/eole/letsencrypt.conf)
        if [ ! "${SERVER}" = "${OLD_SERVER}" ]; then
            rm -rf /etc/eole/letsencrypt.conf /etc/ssl/letsencrypt/conf/renewal/*.conf /etc/ssl/letsencrypt/conf/live/* /etc/ssl/letsencrypt/conf/archive/*
        fi
    fi
    if [ ! -f /etc/eole/letsencrypt.conf ]; then
        echo  ${SERVER} > /etc/eole/letsencrypt.conf
    fi

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

    SSLSERVERNAME="$(CreoleGet ssl_server_name)"

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

    GETNEWCERTIF=1
    res=0
    if [ ! -d "${CONFDIR}/live/${SSLSERVERNAME}" ]; then
        # Creating ACME client command line options for main domain
        MSG="  - Demande de certificat pour ${SSLSERVERNAME}"
        DOM_OPT="-d ${SSLSERVERNAME}"
        for dmn in $(CreoleGet ssl_subjectaltname)
        do
            MSG="$MSG, ${dmn}"
            DOM_OPT="${DOM_OPT} -d ${dmn}"
        done
        echo -n "$MSG"
        startHttp
        ${LECLIENT} ${LEOPT}                  \
            ${MODE_OPT}                       \
            --expand                          \
            ${SERVER}                         \
            --http-01-port ${HTTP01PORT}      \
            ${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
            touch /var/lib/eole/reports/letsencrypt.err
            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 $(getExtraDomains)
    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}      \
                -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
                touch /var/lib/eole/reports/letsencrypt.err
                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
