#!/bin/sh
#VERSION=2.0.8
# This script is written by Martynas Bendorius and DirectAdmin
# It is used to create/renew let's encrypt certificate for a domain
# Official DirectAdmin webpage: http://www.directadmin.com
# Usage:
# ./letsencrypt.sh <domain> <key-size>
MYUID=`/usr/bin/id -u`
if [ "${MYUID}" != 0 ]; then
	echo "You require Root Access to run this script";
	exit 0
fi

export EXEC_PROPAGATION_TIMEOUT=300
export EXEC_POLLING_INTERVAL=5

LEGO=/usr/local/bin/lego

# Use Google DNS for external lookups
DNS_SERVER="8.8.8.8"
DNS6_SERVER="2001:4860:4860::8888"
# Fallback DNS server
NEW_IP="1.1.1.1"
NEW6_IP="2606:4700:4700::1111"
#NEW_IP=`cat /etc/resolv.conf |grep ^nameserver | grep -v 127.0.0.1 | head -n1 | cut -d\  -f2`
DA_IPV6=false

TASK_QUEUE=/usr/local/directadmin/data/task.queue.cb
LEGO_DATA_PATH=/usr/local/directadmin/data/.lego

if [ $# -lt 2 ]; then
	echo "Usage:";
	echo "$0 request|request_single|request_full|renew|revoke <domain> <key-size> (<csr-config-file>)";
	echo "you gave #$#: $0 $1 $2 $3";
	echo "Multiple comma separated domains, owned by the same user, can be used for a certificate request"
	exit 0;
elif [ $# -lt 3 ]; then
	#No key size specified, assign default one
	KEY_SIZE=ec256
    ECC_USED=true
    ECC="secp384r1"
fi
KEY_SIZE=$3
#Set key size (flag)
if [ "${KEY_SIZE}" = "secp384r1" ]; then
    ECC="secp384r1"
    KEY_SIZE="ec384"
    ECC_USED=true
elif [ "${KEY_SIZE}" = "prime256v1" ]; then
    ECC="prime256v1"
    KEY_SIZE="ec256"
    ECC_USED=true
elif [ "${KEY_SIZE}" = "4096" ]; then
    KEY_SIZE="rsa4096"
    ECC_USED=false
elif [ "${KEY_SIZE}" = "2048" ]; then
    KEY_SIZE="rsa2048"
    ECC_USED=false
elif [ "${KEY_SIZE}" = "8192" ]; then
    KEY_SIZE="rsa8192"
    ECC_USED=false
else
    #set default to ec256
    ECC="prime256v1"
    KEY_SIZE="ec256"
    ECC_USED=true
fi
DA_BIN="/usr/local/directadmin/directadmin"
if [ ! -s ${DA_BIN} ]; then
	echo "Unable to find DirectAdmin binary /usr/local/directadmin/directadmin. Exiting..."
	exit 1
fi
run_dataskq() {
	DATASKQ_OPT=$1
	/usr/local/directadmin/dataskq ${DATASKQ_OPT} --custombuild
}

#we received present/cleanup as $1 from lego callback
# ./letsencrypt.sh "present" "_acme-challenge.foo.example.com." "MsijOYZxqyjGnFGwhjrhfg-Xgbl5r68WPda0J9EgqqI"
if [ "$1" = "present" ]; then
	#remove _acme-challenge from the beginning
	DOMAIN_TO_USE=`echo $2 | perl -p0 -e 's|^_acme-challenge\.||g' | perl -p0 -e 's|\.$||g'`
	# cleanup of the old record
	echo "action=dns&do=delete&domain=${DOMAIN_TO_USE}&type=TXT&name=_acme-challenge" >> ${TASK_QUEUE}
	# it's run in reverse because the list is sorted for duplicates.  Must run the dataskq immediately before calling the add.
	run_dataskq
	echo "action=dns&do=add&domain=${DOMAIN_TO_USE}&type=TXT&name=_acme-challenge&value=\"${3}\"&ttl=5&named_reload=yes" >> ${TASK_QUEUE}
	run_dataskq
	exit 0
elif [ "$1" = "cleanup" ]; then
	DOMAIN_TO_USE=`echo $2 | perl -p0 -e 's|^_acme-challenge\.||g' | perl -p0 -e 's|\.$||g'`
	echo "action=dns&do=delete&domain=${DOMAIN_TO_USE}&type=TXT&name=_acme-challenge" >> ${TASK_QUEUE}
	# it's run in reverse because the list is sorted for duplicates.  Must run the dataskq immediately before calling the add.
	run_dataskq
	exit 0
fi

if ${DA_BIN} c | grep -m1 -q "^ipv6=1$"; then
        if [ -x /sbin/ping6 ] || [ -x /usr/sbin/ping6 ]; then
            if ping6 -q -c 1 -W 1 ${DNS6_SERVER} >/dev/null 2>&1; then
		DA_IPV6=true
		DNS_SERVER=${DNS6_SERVER}
		NEW_IP=${NEW6_IP}
	    fi
	fi
fi

CURL=/usr/local/bin/curl
if [ ! -x ${CURL} ]; then
    CURL=/usr/bin/curl
fi

DIG=/usr/bin/dig
if [ ! -x ${DIG} ]; then
	if [ -x /usr/local/bin/dig ]; then
		DIG=/usr/local/bin/dig
	else
		echo "Cannot find $DIG nor /usr/local/bin/dig"
	fi
fi

#Staging/development
if [ "${staging}" = "yes" ]; then
	API_URI="acme-staging-v02.api.letsencrypt.org"
else
	API_URI="acme-v02.api.letsencrypt.org"
fi

API="https://${API_URI}"
CHALLENGETYPE="http"

GENERAL_TIMEOUT=40
CURL_OPTIONS="--connect-timeout ${GENERAL_TIMEOUT} -k --silent"

OS=`uname`

OPENSSL=/usr/bin/openssl
TIMESTAMP=`date +%s`

LETSENCRYPT_OPTION=`${DA_BIN} c | grep '^letsencrypt=' | cut -d= -f2`
ACCESS_GROUP_OPTION=`${DA_BIN} c | grep '^secure_access_group=' | cut -d= -f2`
FILE_CHOWN="diradmin:mail"
FILE_CHMOD="640"
if [ "${ACCESS_GROUP_OPTION}" != "" ]; then
	FILE_CHOWN="diradmin:${ACCESS_GROUP_OPTION}"
fi

if [ ! -x ${LEGO} ]; then
    echo "${LEGO} is required, exiting..."
    exit 1
fi
####### PRE_CHECK FUNCTIONS BEGIN #########
DOCUMENT_ROOT=$5
WELLKNOWN_PATH="/var/www/html/.well-known/acme-challenge"
if [ ! -z "${DOCUMENT_ROOT}" ] && [ -d "${DOCUMENT_ROOT}" ]; then
    WELLKNOWN_PATH=${DOCUMENT_ROOT}
fi
caa_check() {
    CAA_OK=true
    #if 8.8.8.8 is not accessible, dig returns code 9.  The dig|grep method returns code 1, so have to redo.
    IP_TO_RESOLV=`${DIG} @${DNS_SERVER} AAAA ${1} +short | grep -v '\.$' | tail -n1`
    if [ "$?" -eq 9 ] && [ "${DNS_SERVER}" != "${NEW_IP}" ]; then
        if [ "${NEW_IP}" != "" ]; then	
            DNS_SERVER=${NEW_IP}
            IP_TO_RESOLV=`${DIG} @${DNS_SERVER} AAAA ${1} +short | grep -v '\.$' | tail -n1`
        fi
    fi
    for i in `echo ${1} | awk -F'.' '{b=$NF;for(i=NF-1;i>0;i--){b=$i FS b;print b}}'`; do {
        if ${DIG} CAA ${i} @${DNS_SERVER} +short | grep -m1 -q -F -- "issue"; then
            CAA_OK=false
            if ${DIG} CAA ${i} @${DNS_SERVER} +short | grep -m1 -q -F -- "letsencrypt.org"; then
                CAA_OK=true
            else
                CAA_CURRENT=`${DIG} CAA ${i} @${DNS_SERVER} +short | grep -m1 issue | awk '{print $3}'`
            fi
        fi
        if ${DIG} CAA ${i} @${DNS_SERVER} | grep -m1 -q -F -- "SERVFAIL"; then
            CAA_OK=false
            CAA_CURRENT="SERVFAIL"
        fi
    }
    done

    if ! ${CAA_OK}; then
        echo "CAA record prevents issuing the certificate: ${CAA_CURRENT}"
        exit 1
    fi
}

challenge_check() {
    if [ ! -d ${WELLKNOWN_PATH} ]; then
        mkdir -p ${WELLKNOWN_PATH}
        chown webapps:webapps ${HOSTNAME_DIR}/.well-known
        chown webapps:webapps ${WELLKNOWN_PATH}
    fi
    touch ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP}
    chmod 644 ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP}
    chown webapps:webapps ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP}
    CURL_RESOLV_OPTIONS=""
    #if 8.8.8.8 is not accessible, dig returns code 9.  The dig|grep method returns code 1, so have to redo.
    IP_TO_RESOLV=`${DIG} @${DNS_SERVER} AAAA ${1} +short | grep -v '\.$' | tail -n1`
    if [ "$?" -eq 9 ] && [ "${DNS_SERVER}" != "${NEW_IP}" ]; then
        if [ "${NEW_IP}" != "" ]; then	
            DNS_SERVER=${NEW_IP}
            IP_TO_RESOLV=`${DIG} @${DNS_SERVER} AAAA ${1} +short | grep -v '\.$' | tail -n1`
        fi
    fi
    if ! echo "${IP_TO_RESOLV}" | grep -m1 -q ':'; then
        IP_TO_RESOLV=""
    fi
    if [ -z "${IP_TO_RESOLV}" ]; then
        IP_TO_RESOLV=`${DIG} @${DNS_SERVER} ${1} +short | tail -n1`
        CURRENT_RESOLV=`${DIG} ${1} +short | tail -n1`
    else
        CURRENT_RESOLV=`${DIG} AAAA ${1} +short | grep -v '\.$' | tail -n1`
    fi
    if [ -z "${IP_TO_RESOLV}" ]; then
        echo 1
        return
    fi
    if [ -x /sbin/ping6 ] || [ -x /usr/sbin/ping6 ]; then
        if ! ${DA_IPV6}; then
            if ! ping6 -q -c 1 -W 1 ${1} >/dev/null 2>&1; then
                IP_TO_RESOLV=`${DIG} @${DNS_SERVER} ${1} +short | tail -n1`
                CURRENT_RESOLV=`${DIG} ${1} +short | tail -n1`
            fi
        fi
    fi
    if [ ! -z "${IP_TO_RESOLV}" ]; then
        if ${CURL} --help | grep -m1 -q 'resolve'; then
            CURL_RESOLV_OPTIONS="--resolve ${1}:80:${IP_TO_RESOLV} --resolve ${1}:443:${IP_TO_RESOLV}"
        fi
    fi
    #Checking if http://www.domain.com/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} is available
    if ! ${CURL} ${CURL_OPTIONS} ${CURL_RESOLV_OPTIONS} -I -L -X GET http://${1}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} 2>/dev/null | grep -m1 -q 'HTTP.*200'; then
        if [ "$2" = "silent" ]; then
            echo 1
            rm -f ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP}
            return
        else
            echo "Challenge pre-checks for http://${1}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} failed... Command:"
            echo "${CURL} ${CURL_OPTIONS} ${CURL_RESOLV_OPTIONS} -I -L -X GET http://${1}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP}"
            echo "Exiting."
            rm -f ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP}
            exit 1
        fi
    elif [ "$2" = "silent" ]; then
        echo 0
	rm -f ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP}
        return
    fi
    if [ -s ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP} ]; then
        rm -f ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP}
    fi
}
####### PRE_CHECK FUNCITONS END #########

#Set staging server if testing
APPEND_SERVER="-s https://${API_URI}/directory"
SERVER_HOSTNAME="`hostname -f 2>/dev/null`"
if [ -z "${SERVER_HOSTNAME}" ] && [ "${OS}" != "FreeBSD" ] && [ -x /usr/bin/hostnamectl ]; then
    SERVER_HOSTNAME=`/usr/bin/hostnamectl --static | head -n1`
    if ! echo "${SERVER_HOSTNAME}" | grep  -m1 -q '\.'; then
        SERVER_HOSTNAME=`grep -m1 -o "${SERVER_HOSTNAME}\.[^ ]*" /etc/hosts`
    fi
fi
if [ ! -s /usr/local/directadmin/data/users/admin/user.conf ] ;then
    ADMIN_USERCONF="`grep -l -m1 '^creator=root$' /usr/local/directadmin/data/users/*/user.conf`"
    if [ -z "${ADMIN_USERCONF}" ]; then
	ADMIN_USERCONF="/usr/local/directadmin/data/users/`head -n1 /usr/local/directadmin/data/admin/admin.list`/user.conf"
    fi
else
    ADMIN_USERCONF=/usr/local/directadmin/data/users/admin/user.conf
fi
if [ ! -z "${ADMIN_USERCONF}" ] && [ -s ${ADMIN_USERCONF} ]; then
    EMAIL="`grep -m1 '^email=' ${ADMIN_USERCONF} 2>/dev/null | cut -d= -f2 | cut -d, -f1`"
fi
if [ -z "${EMAIL}" ]; then
    EMAIL="admin@${SERVER_HOSTNAME}"
fi
DOMAIN=$2
#Old-method
if [ "${SINGLE_CERT_STORE}" != "yes" ]; then
    #We need the domain to match in /etc/virtual/domainowners, if we use grep -F, we cannot use any regex'es including ^
    FOUNDDOMAIN=0
    for TDOMAIN in `echo "${DOMAIN}" | tr ',' ' '`; do {
        DOMAIN_NAME_FOUND=${TDOMAIN}

        DOMAIN_ESCAPED="`echo ${DOMAIN_NAME_FOUND} | perl -p0 -e 's#\.#\\\.#g'`"

        if grep -m1 -q "^${DOMAIN_ESCAPED}:" /etc/virtual/domainowners; then
            USER=`grep -m1 "^${DOMAIN_ESCAPED}:" /etc/virtual/domainowners | cut -d' ' -f2`
            HOSTNAME=0
            FOUNDDOMAIN=1
            break
        else
            USER="root"
            DA_SERVER_NAME=`${DA_BIN} c | grep -m1 "^servername=${DOMAIN_ESCAPED}\$"`
            if [ ! -z "${DA_SERVER_NAME}" ]; then
                echo "Setting up certificate for a hostname: ${DOMAIN_NAME_FOUND}"
                HOSTNAME=1
                FOUNDDOMAIN=1
                if ! grep -m1 -q "^${DOMAIN_ESCAPED}$" /etc/virtual/domains; then
                    echo "${DOMAIN_NAME_FOUND}" >> /etc/virtual/domains
                fi
                break
            else
                echo "Domain does not exist on the system. Unable to find ${DOMAIN_NAME_FOUND} in /etc/virtual/domainowners, and domain is not set as hostname (servername) in DirectAdmin configuration. Exiting..."
            fi
        fi
    }
    done

    if [ ${FOUNDDOMAIN} -eq 0 ]; then
        echo "no valid domain found - exiting"
        exit 1
    fi

    CSR_CF_FILE=$4

    DA_USERDIR="/usr/local/directadmin/data/users/${USER}"
    DA_CONFDIR="/usr/local/directadmin/conf"
    HOSTNAME_DIR="/var/www/html"

    if [ ! -d "${DA_USERDIR}" ] && [ "${HOSTNAME}" -eq 0 ]; then
        echo "${DA_USERDIR} not found, exiting..."
        exit 1
    elif [ ! -d "${DA_CONFDIR}" ] && [ "${HOSTNAME}" -eq 1 ]; then
        echo "${DA_CONFDIR} not found, exiting..."
        exit 1
    fi

    if [ "${HOSTNAME}" -eq 0 ]; then
        DNSPROVIDER_FALLBACK="${DA_USERDIR}/domains/${DOMAIN_NAME_FOUND}.dnsprovider"
	if [ -s "${DNSPROVIDER_FALLBACK}" ]; then
		if grep -m1 -q "^dnsprovider=inherit-creator$" "${DNSPROVIDER_FALLBACK}"; then
			CREATOR=`grep -m1 '^creator=' "${DA_USERDIR}/user.conf" | cut -d= -f2`
			CREATOR_DNSPROVIDER="/usr/local/directadmin/data/users/${CREATOR}/dnsprovider.conf"
			if [ -s "${CREATOR_DNSPROVIDER}" ]; then
		        	DNSPROVIDER_FALLBACK="${CREATOR_DNSPROVIDER}"
			fi
		elif grep -m1 -q "^dnsprovider=inherit-global$" "${DNSPROVIDER_FALLBACK}"; then
			if [ -s "/usr/local/directadmin/data/admin/dnsprovider.conf" ]; then
				DNSPROVIDER_FALLBACK="/usr/local/directadmin/data/admin/dnsprovider.conf"
			fi
		fi
	fi
        KEY="${DA_USERDIR}/domains/${DOMAIN_NAME_FOUND}.key"
        CERT="${DA_USERDIR}/domains/${DOMAIN_NAME_FOUND}.cert"
        CACERT="${DA_USERDIR}/domains/${DOMAIN_NAME_FOUND}.cacert"
        if [ "${DOCUMENT_ROOT}" != "" ]; then
            DOMAIN_DIR="${DOCUMENT_ROOT}"
        elif ${DA_BIN} c | grep -m1 -q '^letsencrypt=2$'; then
            USER_HOMEDIR="`grep -m1 \"^${USER}:\" /etc/passwd | cut -d: -f6`"
            DOMAIN_DIR="${USER_HOMEDIR}/domains/${DOMAIN_NAME_FOUND}/public_html"
        else
            DOMAIN_DIR="${HOSTNAME_DIR}"
        fi
        WELLKNOWN_PATH="${DOMAIN_DIR}/.well-known/acme-challenge"
    else
        DNSPROVIDER_FALLBACK="${DA_CONFDIR}/ca.dnsprovider"
        KEY=`${DA_BIN} c |grep ^cakey= | cut -d= -f2`
        CERT=`${DA_BIN} c |grep ^cacert= | cut -d= -f2`
        CACERT=`${DA_BIN} c |grep ^carootcert= | cut -d= -f2`
        SET_DA_CACERT=false
        if [ "${CACERT}" = "" ] || [ "${CERT}" = "${DA_CONFDIR}/carootcert.pem" ]; then
            CERT="${DA_CONFDIR}/cacert.pem"
            CACERT="${DA_CONFDIR}/carootcert.pem"
            SET_DA_CACERT=true
        fi
        DOMAIN_DIR="${HOSTNAME_DIR}"
        WELLKNOWN_PATH="${DOMAIN_DIR}/.well-known/acme-challenge"
    fi

    if [ -s "${CERT}" ] && [ "$1" = "renew" ]; then
        if [ -s "${CERT}" ]; then
            DOMAIN=`${OPENSSL} x509 -text -noout -in "${CERT}" | grep -m1 'Subject Alternative Name:' -A1 | grep 'DNS:' | perl -p0 -e 's|DNS:||g' | tr -d ' '`
        fi
    elif [ "$1" = "request" ] && ! echo "${DOMAIN}" | grep -m1 -q ","; then
        if [ -s "${CSR_CF_FILE}" ] && grep -m1 -q 'DNS:' "${CSR_CF_FILE}"; then
            DOMAIN="`cat \"${CSR_CF_FILE}\" | grep '^subjectAltName=' | cut -d= -f2 | grep 'DNS:' | perl -p0 -e 's|DNS:||g' | tr -d ' '`"
        elif [ -s "${CERT}" ] && ${OPENSSL} x509 -text -noout -in "${CERT}" | grep -m1 -q 'Subject Alternative Name:' >/dev/null 2>&1; then
            DOMAIN=`${OPENSSL} x509 -text -noout -in "${CERT}" | grep -m1 'Subject Alternative Name:' -A1 | grep 'DNS:' | perl -p0 -e 's|DNS:||g' | tr -d ' '`
        elif [ "${HOSTNAME}" -eq 0 ]; then
            if ! echo "${DOMAIN}" | grep -q "^www\."; then
                #We have a domain without www., add www domain to to SAN too
                DOMAIN="${DOMAIN},www.${DOMAIN}"
            else
                #We have a domain with www., drop www and add it to SAN too
                DOMAIN2=`echo ${DOMAIN} | perl -p0 -e 's#^www.##'`
                DOMAIN="${DOMAIN2},www.${DOMAIN2}"
            fi
        fi
    elif [ "$1" = "request_full" ]; then
        #find all subdomains and pointers, and include them in the list.
        SUB_LIST_FILE="${DA_USERDIR}/domains/${DOMAIN}.subdomains"
        SUB_LIST=""

        if [ -s ${SUB_LIST_FILE} ]; then
            SUB_LIST=`cat ${SUB_LIST_FILE}`
        fi

        SUB_LIST="${SUB_LIST} www mail ftp smtp pop"
        for s in `echo ${SUB_LIST}`; do
        {
            H=${s}.${DOMAIN}
            if [ "${CHALLENGETYPE}" = "http" ]; then
                CHALLENGE_TEST=`challenge_check ${H} silent`
            else
                CHALLENGE_TEST=0
            fi
            if [ ${CHALLENGE_TEST} -eq 1 ] && [ "${CHALLENGETYPE}" = "http" ]; then
                echo "${H} was skipped due to unreachable http://${H}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} file."
            else
                DOMAIN="${DOMAIN},${H}"
            fi
        };
        done;

        POINTER_LIST="${DA_USERDIR}/domains/${DOMAIN}.pointers"
        if [ -s ${POINTER_LIST} ]; then
            for p in `cat ${POINTER_LIST} | cut -d= -f1`; do
            {
                    DOMAIN="${DOMAIN},${p},www.${p}"
            };
            done;
        fi
    fi

    #It could be a symlink, so we use -e
    if [ ! -e "${DOMAIN_DIR}" ]; then
        echo "${DOMAIN_DIR} does not exist. Exiting..."
        exit 1
    fi
fi

if echo "${DOMAIN}" | grep -m1 -q ','; then
    DOMAINS=`echo "${DOMAIN}" | perl -p0 -e "s/,/ -d /g"`
    DOMAIN_FLAG="-d ${DOMAINS}"
    FIRST_DOMAIN=`echo "${DOMAIN}" | cut -d, -f1`
else
    DOMAINS="${DOMAIN}"
    DOMAIN_FLAG="-d ${DOMAIN}"
    FIRST_DOMAIN=${DOMAIN}
fi
#Set validation method
CHALLENGETYPE=http
#empty env for dnsprovider - but dnsprovider file in use
if [ -s "${DNSPROVIDER_FALLBACK}" ] && [ -z "${dnsprovider}" ]; then
    export `grep -o '^[a-zA-Z0-9_]*=[^;<>|\ ]*' "${DNSPROVIDER_FALLBACK}" | xargs`
fi
if [ ! -z "${dnsprovider}" ] && [ "${dnsprovider}" != "exec" ]; then
    DNSPROVIDER_NAME=${dnsprovider}
    echo "Found DNS provider configured: ${DNSPROVIDER_NAME}"
    CHALLENGETYPE="dns ${DNSPROVIDER_NAME}"
elif echo "${DOMAIN_FLAG}" | grep -m1 -q '*\.'; then
    echo "Found wildcard domain name and http challenge type, switching to dns-01 validation."
    CHALLENGETYPE="dns exec"
    export EXEC_PATH=/usr/local/directadmin/scripts/letsencrypt.sh
fi
#Run all domains through CAA and http pre-checks to save LE rate-limits
for domain_name in `echo ${DOMAIN} | perl -p0 -e "s/,/ /g" | perl -p0 -e "s/^\*.//g"`; do {
    caa_check ${domain_name}
    if [ "${CHALLENGETYPE}" = "http" ]; then
        challenge_check ${domain_name}
    fi
};
done

if [ "$1" = "request_full" ] && [ "${SINGLE_CERT_STORE}" = "yes" ]; then
    echo "request_full is not supported/recommended to use anymore"
    exit 1
fi
if [ "$1" = "request_single" ] || [ "$1" = "request" ] || [ "$1" = "renew" ] || [ "$1" = "request_full" ] ; then
    ${LEGO} --path ${LEGO_DATA_PATH} --dns.resolvers ${DNS_SERVER} --accept-tos ${APPEND_SERVER} -m ${EMAIL} --${CHALLENGETYPE} --http.webroot /var/www/html ${DOMAIN_FLAG} --key-type ${KEY_SIZE} run --no-bundle
    if [ $? -eq 0 ]; then
        if [ "${SINGLE_CERT_STORE}" != "yes" ]; then
            CERT_DOMAIN_FILE=`echo "${FIRST_DOMAIN}" | tr '*' '_'`
            LEGO_CERT_PATH="${LEGO_DATA_PATH}/certificates/${CERT_DOMAIN_FILE}.crt"
            LEGO_KEY_PATH="${LEGO_DATA_PATH}/certificates/${CERT_DOMAIN_FILE}.key"
            LEGO_ISSUER_CERT_PATH=`echo "${LEGO_CERT_PATH}" | perl -p0 -e 's|\.crt$|.issuer.crt|g'`


            if [ -s "${LEGO_CERT_PATH}" ] && [ -s "${LEGO_KEY_PATH}" ]; then
		if [ `grep -c "BEGIN CERTIFICATE" "${LEGO_CERT_PATH}"` -eq 1 ]; then
	                cp -pf "${LEGO_CERT_PATH}" ${CERT}
		else
			${OPENSSL} x509 -in "${LEGO_CERT_PATH}" -out ${CERT}
		fi
                cp -pf "${LEGO_KEY_PATH}" ${KEY}
                if [ -s "${LEGO_ISSUER_CERT_PATH}" ]; then
                    cp -pf "${LEGO_ISSUER_CERT_PATH}" ${CACERT}
                    cat ${CERT} ${CACERT} > ${CERT}.combined
		else
                    cp -pf "${LEGO_CERT_PATH}" ${CERT}.combined		
                fi
                date +%s > ${CERT}.creation_time
                chown ${FILE_CHOWN} ${KEY} ${CERT} ${CERT}.combined ${CACERT} ${CERT}.creation_time
                chmod ${FILE_CHMOD} ${KEY} ${CERT} ${CERT}.combined ${CACERT} ${CERT}.creation_time
                echo "Certificate for ${DOMAIN} has been created successfully!"
            else
                echo "New key/certificate is empty. Exiting..."
                exit 1
            fi
        else
            echo "Certificate for ${DOMAIN} has been created successfully!"
            #here we need to do something light to scan ${LEGO_DATA_PATH}/.lego/certificates/ certs, wildcard name is _.domain.com.crt / _.domain.com.key. If we need cacert to be in a separate file - there is also a flag for this. It should auto-move the certs from this dir and update .creation_time file if we still rely on it?
            #it has the hook to just do it for the domain we generate (for example _.domain.com), but DA needs to place it to all domains that may use it...
            # echo "action=certscan&do=update&path=${LEGO_DATA_PATH}/.lego/certificates" >> ${TASK_QUEUE}
        fi
    else
        echo "Certificate generation failed."
        exit 1
    fi

    #Change exim, apache/nginx certs
    if [ "${SINGLE_CERT_STORE}" != "yes" ]; then
        if [ "${HOSTNAME}" -eq 1 ]; then
            echo "DirectAdmin certificate has been setup."

            if grep -m1 -q "^cacert=${DA_CONFDIR}/carootcert.pem$" /usr/local/directadmin/conf/directadmin.conf; then
		${DA_BIN} set cacert ${DA_CONFDIR}/cacert.pem
            fi
            if ${SET_DA_CACERT}; then
		${DA_BIN} set carootcert ${CACERT}
            fi
            if ${DA_BIN} c | grep -m1 -q "^ssl=0$"; then
		${DA_BIN} set ssl 1
            fi

            #Exim
            echo "Setting up cert for Exim..."
            EXIMKEY="/etc/exim.key"
            EXIMCERT="/etc/exim.cert"
            cp -f ${KEY} ${EXIMKEY}
            cat ${CERT} ${CACERT} > ${EXIMCERT}
            chown mail:mail ${EXIMKEY} ${EXIMCERT}
            chmod 600 ${EXIMKEY} ${EXIMCERT}

            echo "action=exim&value=restart" >> ${TASK_QUEUE}
            echo "action=dovecot&value=restart" >> ${TASK_QUEUE}

            #Apache
            echo "Setting up cert for WWW server..."
            if [ -d /etc/httpd/conf/ssl.key ] && [ -d /etc/httpd/conf/ssl.crt ]; then
                APACHEKEY="/etc/httpd/conf/ssl.key/server.key"
                APACHECERT="/etc/httpd/conf/ssl.crt/server.crt"
                APACHECACERT="/etc/httpd/conf/ssl.crt/server.ca"
                APACHECERTCOMBINED="${APACHECERT}.combined"
                cp -f ${KEY} ${APACHEKEY}
                cp -f ${CERT} ${APACHECERT}
                cp -f ${CACERT} ${APACHECACERT}
                cat ${APACHECERT} ${APACHECACERT} > ${APACHECERTCOMBINED}
                chown root:root ${APACHEKEY} ${APACHECERT} ${APACHECACERT} ${APACHECERTCOMBINED}
                chmod 600 ${APACHEKEY} ${APACHECERT} ${APACHECACERT} ${APACHECERTCOMBINED}

                HTTPDACTION=restart
                GRACEFUL=`$DA_BIN c |grep ^graceful_restarts= | cut -d= -f2`
                if [ "$GRACEFUL" = "1" ]; then
                    SYSTEMD=`$DA_BIN c |grep ^systemd= | cut -d= -f2`
                    if [ "$SYSTEMD" = "1" ]; then
                        HTTPDACTION=reload
                    else
                        HTTPDACTION=graceful
                    fi
                fi

                echo "action=httpd&value=${HTTPDACTION}&affect_php_fpm=no" >> ${TASK_QUEUE}
            fi

            #Nginx
            if [ -d /etc/nginx/ssl.key ] && [ -d /etc/nginx/ssl.crt ]; then
                NGINXKEY="/etc/nginx/ssl.key/server.key"
                NGINXCERT="/etc/nginx/ssl.crt/server.crt"
                NGINXCACERT="/etc/nginx/ssl.crt/server.ca"
                NGINXCERTCOMBINED="${NGINXCERT}.combined"
                cp -f ${KEY} ${NGINXKEY}
                cp -f ${CERT} ${NGINXCERT}
                cp -f ${CACERT} ${NGINXCACERT}
                cat ${NGINXCERT} ${NGINXCACERT} > ${NGINXCERTCOMBINED}
                chown root:root ${NGINXKEY} ${NGINXCERT} ${NGINXCACERT} ${NGINXCERTCOMBINED}
                chmod 600 ${NGINXKEY} ${NGINXCERT} ${NGINXCACERT} ${NGINXCERTCOMBINED}

                echo "action=nginx&value=restart&affect_php_fpm=no" >> ${TASK_QUEUE}
            fi

            #OLS
            if [ -d /usr/local/lsws/ssl.key ] && [ -d /usr/local/lsws/ssl.crt ]; then
                OLSKEY="/usr/local/lsws/ssl.key/server.key"
                OLSCERT="/usr/local/lsws/ssl.crt/server.crt"
                OLSCACERT="/usr/local/lsws/ssl.crt/server.ca"
                OLSCERTCOMBINED="${OLSCERT}.combined"
                cp -f ${KEY} ${OLSKEY}
                cp -f ${CERT} ${OLSCERT}
                cp -f ${CACERT} ${OLSCACERT}
                cat ${OLSCERT} ${OLSCACERT} > ${OLSCERTCOMBINED}
                chown root:root ${OLSKEY} ${OLSCERT} ${OLSCACERT} ${OLSCERTCOMBINED}
                chmod 600 ${OLSKEY} ${OLSCERT} ${OLSCACERT} ${OLSCERTCOMBINED}

                echo "action=openlitespeed&value=restart&affect_php_fpm=no" >> ${TASK_QUEUE}
            fi

            #FTP
            echo "Setting up cert for FTP server..."
            cat ${KEY} ${CERT} ${CACERT} > /etc/pure-ftpd.pem
            chmod 600 /etc/pure-ftpd.pem
            chown root:root /etc/pure-ftpd.pem

            if /usr/local/directadmin/directadmin c | grep -m1 -q "^pureftp=1\$"; then
                echo "action=pure-ftpd&value=restart" >> ${TASK_QUEUE}
            else
                echo "action=proftpd&value=restart" >> ${TASK_QUEUE}
            fi

            echo "action=directadmin&value=restart" >> ${TASK_QUEUE}
            echo "The services will be restarted in about 1 minute via the dataskq."
            run_dataskq
        fi
    fi
elif [ "$1" = "revoke" ]; then
    ${LEGO} --path ${LEGO_DATA_PATH} ${APPEND_SERVER} -m ${EMAIL} ${DOMAIN_FLAG} revoke
fi
