#!/bin/sh
#VERSION=1.1.39
# 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

DEFAULT_KEY_SIZE=""

# 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

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
	DEFAULT_KEY_SIZE=4096
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
if ${DA_BIN} c | grep -m1 -q "^ipv6=1$"; then
        DA_IPV6=true
        DNS_SERVER=${DNS6_SERVER}
        NEW_IP=${NEW6_IP}
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}"

ACCOUNT_URL=""

CHALLENGETYPE="http-01"
LICENSE_KEY_MIN_DATE=1470383674

DIG_SECONDS=15
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

run_dataskq() {
	DATASKQ_OPT=$1
	/usr/local/directadmin/dataskq ${DATASKQ_OPT} --custombuild
}

#Encode data using base64 with URL-safe chars
base64_encode() {
	${OPENSSL} base64 -e | tr -d '\n\r' | tr "+/" "-_" | tr -d '= '
}

#Send signed request
send_signed_request() {
	URL="${1}"
	PAYLOAD="${2}"

	#Use base64 for the payload
	PAYLOAD64="`echo -n \"${PAYLOAD}\" | base64_encode`"

	#Get nonce from acme-server
	FULL_NONCE="`${CURL} ${CURL_OPTIONS} -I ${API}/acme/new-nonce`"
	NONCE="`echo \"${FULL_NONCE}\" | grep -m1 -i '^Replay-Nonce:' | cut -d' ' -f2 | cut -d: -f2 | tr -d '\n\r'`"
	if [ "${NONCE}" = "" ]; then
		echo "Nonce is empty. Exiting. dig output of ${API_URI}: "
		${DIG} @${DNS_SERVER} ${API_URI} +short
		echo "Full nonce request output:"
		echo "${FULL_NONCE}"
		exit 1
	fi

	#Create header with nonce encode as base64
	if [ "${ACCOUNT_URL}" = "" ]; then
		PROTECTED="{\"nonce\": \"${NONCE}\", \"alg\": \"RS256\", \"jwk\": ${FOR_THUMBPRINT}, \"url\": \"${URL}\"}"
	else
		PROTECTED="{\"nonce\": \"${NONCE}\", \"alg\": \"RS256\", \"kid\": \"${ACCOUNT_URL}\", \"url\": \"${URL}\"}"
	fi

	PROTECTED64="`echo -n ${PROTECTED} | base64_encode`"

	SIGN64="`echo -n \"${PROTECTED64}.${PAYLOAD64}\" | ${OPENSSL} dgst -sha256 -sign \"${LETSENCRYPT_ACCOUNT_KEY}\" | base64_encode`"
	
	#Form the BODY to send
	BODY="{\"protected\": \"${PROTECTED64}\", \"payload\": \"${PAYLOAD64}\", \"signature\": \"${SIGN64}\"}"

	#Send the BODY, save the response
	RESPONSE="`${CURL} ${CURL_OPTIONS} -i -X POST -H 'Content-Type: application/jose+json' --data \"${BODY}\" \"${URL}\"`"
	
	if [ "${RESPONSE}" = "" ]; then
		echo "Response is empty. Command:"
		echo "${CURL} ${CURL_OPTIONS} -i -X POST -H 'Content-Type: application/jose+json' --data \"${BODY}\" \"${URL}\""
		echo "Exiting..."
		exit 1
	fi
	#HTTP status code
	HTTP_STATUS=`echo "${RESPONSE}" | grep -v 'HTTP.*100 Continue' | grep -m1 'HTTP.*' | awk '{print $2}'`
}

#Check if private key matches certificate

checkPrivPubMatch() {
	PRIV="${1}"
	PUB="${2}"
	if [ -f "${PRIV}" ] && [ -f "${PUB}" ]; then
		MD5SUMPRIVMOD=`openssl rsa -noout -modulus -in ${PRIV}| openssl md5`
		MD5SUMPUBMOD=`openssl x509 -noout -modulus -in ${PUB} | openssl md5`
		if [ "${MD5SUMPRIVMOD}" = "${MD5SUMPUBMOD}" ]; then
			echo 0
		else
			echo 1
		fi
	else
		echo 2
	fi
}

ACTION=$1
IS_SINGLE=false
if [ "$1" = "request_single" ]; then
	IS_SINGLE=true
	ACTION=request
fi

DOMAIN=$2
if [ "${DEFAULT_KEY_SIZE}" = "" ]; then
	KEY_SIZE=$3
else
	KEY_SIZE=${DEFAULT_KEY_SIZE}
fi
CSR_CF_FILE=$4
DOCUMENT_ROOT=$5
#We need the domain to match in /etc/virtual/domainowners, if we use grep -F, we cannot use any regex'es including ^

DOMAINARR_IN_USE=false
if echo "${DOMAIN}" | grep -m1 -q ","; then
	DOMAINARR_IN_USE=true
fi
DOMAINARR=`echo "${DOMAIN}" | perl -p0 -e "s/,/ /g"`

FOUNDDOMAIN=0
for TDOMAIN in ${DOMAINARR}
do
	DOMAIN=${TDOMAIN}

	DOMAIN_ESCAPED="`echo ${DOMAIN} | 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
	elif grep -m1 -q "^${DOMAIN_ESCAPED}$" /etc/virtual/domains; then
		USER="root"
		if ${DA_BIN} c | grep -m1 -q "^servername=${DOMAIN_ESCAPED}\$"; then
			echo "Setting up certificate for a hostname: ${DOMAIN}"
			HOSTNAME=1
			FOUNDDOMAIN=1
			break
		else
			echo "Domain exists in /etc/virtual/domains, but is not set as a hostname in DirectAdmin. Unable to find 'servername=${DOMAIN}' in the output of '/usr/local/directadmin/directadmin c'. Exiting..."
			#exit 1
		fi
	else
		echo "Domain does not exist on the system. Unable to find ${DOMAIN} in /etc/virtual/domainowners. Exiting..."
		#exit 1
	fi
done

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

IS_FULL=false
if [ "$1" = "request_full" ]; then
        IS_FULL=true
        ACTION=request
fi


if [ ${KEY_SIZE} -ne 2048 ] && [ ${KEY_SIZE} -ne 4096 ]; then
	echo "Wrong key size. It must be 2048 or 4096. Exiting..."
	exit 1
fi

if [ "${CSR_CF_FILE}" != "" ] && [ ! -s ${CSR_CF_FILE} ]; then
	echo "CSR config file ${CSR_CF_FILE} passed but does not exist or is empty."
	ls -la ${CSR_CF_FILE}
	exit 1
fi

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

# Account registration is rate-limited, so, it's better to always use a single key on the system
if echo "${API_URI}" | grep -m1 -q staging; then
	LETSENCRYPT_ACCOUNT_KEY="${DA_CONFDIR}/letsencrypt.staging.key"
else
	LETSENCRYPT_ACCOUNT_KEY="${DA_CONFDIR}/letsencrypt.key"
fi

if [ "${HOSTNAME}" -eq 0 ]; then
	KEY="${DA_USERDIR}/domains/${DOMAIN}.key"
	CERT="${DA_USERDIR}/domains/${DOMAIN}.cert"
	CACERT="${DA_USERDIR}/domains/${DOMAIN}.cacert"
	CSR="${DA_USERDIR}/domains/${DOMAIN}.csr"
	SAN_CONFIG="${DA_USERDIR}/domains/${DOMAIN}.san_config"
	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}/public_html"
	else
		DOMAIN_DIR="${HOSTNAME_DIR}"
	fi
	WELLKNOWN_PATH="${DOMAIN_DIR}/.well-known/acme-challenge"
else
	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`
	if [ "${CACERT}" = "" ]; then
		CACERT="${DA_CONFDIR}/carootcert.pem"
	fi
	CSR="${DA_CONFDIR}/ca.csr"
	SAN_CONFIG="${DA_CONFDIR}/ca.san_config"
	DOMAIN_DIR="${HOSTNAME_DIR}"
	WELLKNOWN_PATH="${DOMAIN_DIR}/.well-known/acme-challenge"
fi

challenge_check() {
	if [ "${CHALLENGETYPE}" = "dns-01" ]; then
		if [ "${2}" = "dns-precheck" ]; then
                        # Get NS entries from the domain
                        if ! ${DIG} TXT _acme-challenge-test.${1} @${DNS_SERVER} +short | grep -m1 -q -F -- "pre-check"; then
                                echo 1
                        else
                                echo 0
                        fi
		else
			# Get NS entries from the domain
			if ! ${DIG} TXT _acme-challenge.${1} @${DNS_SERVER} +short | grep -m1 -q -F -- "${DNSENTRY}"; then
				echo 1
			else
				echo 0
			fi
		fi
	else
		if [ ! -d ${WELLKNOWN_PATH} ]; then
				mkdir -p ${WELLKNOWN_PATH}
		fi
		touch ${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}" ] && [ "${IP_TO_RESOLV}" != "${CURRENT_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
			echo 1
		else
			echo 0
		fi
		rm -f ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP}
	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

#ensure the letsencrypt.key is new enough
if [ -s "${LETSENCRYPT_ACCOUNT_KEY}" ]; then
	if [ "${OS}" = "FreeBSD" ]; then
		STAT_CMD="/usr/bin/stat -f %m ${LETSENCRYPT_ACCOUNT_KEY}"
	else
		STAT_CMD="/usr/bin/stat --printf %Y ${LETSENCRYPT_ACCOUNT_KEY}"
	fi

	LAST_CHANGED=`${STAT_CMD} 2>/dev/null`
	if [ "${LAST_CHANGED}" = "" ]; then
		echo "Unable to get last modification time from key using:";
		echo "${STAT_CMD}";
		${STAT_CMD}
	else
		#got a number, hopfully.
		if [ "${LAST_CHANGED}" -lt "${LICENSE_KEY_MIN_DATE}" ]; then
			echo "${LETSENCRYPT_ACCOUNT_KEY} was older than recent license agreement.  Deleting it, and creating a new one";
			rm -f ${LETSENCRYPT_ACCOUNT_KEY} ${LETSENCRYPT_ACCOUNT_KEY}.json
		fi
	fi
fi

#Create account KEY if it does not exist
OLD_KEY=1

if [ ! -s "${LETSENCRYPT_ACCOUNT_KEY}.json" ]; then
	echo "Generating ${KEY_SIZE} bit RSA key for let's encrypt account..."
	echo "openssl genrsa ${KEY_SIZE} > \"${LETSENCRYPT_ACCOUNT_KEY}\""
	${OPENSSL} genrsa ${KEY_SIZE} > "${LETSENCRYPT_ACCOUNT_KEY}"
	chown diradmin:diradmin ${LETSENCRYPT_ACCOUNT_KEY}
	chmod 600 ${LETSENCRYPT_ACCOUNT_KEY}
	OLD_KEY=0
fi

#We use perl here to convert HEX to BIN
PUBLIC_EXPONENT64=`${OPENSSL} rsa -in "${LETSENCRYPT_ACCOUNT_KEY}" -noout -text | grep "^publicExponent:" | awk '{print $3}' | cut -d'(' -f2 | cut -d')' -f1 | tr -d '\r\n' | tr -d 'x' | perl -n0 -e 's/([0-9a-f]{2})/print chr hex $1/gie' | base64_encode`
PUBLIC_MODULUS64=`${OPENSSL} rsa -in "${LETSENCRYPT_ACCOUNT_KEY}" -noout -modulus | cut -d'=' -f2 | perl -n0 -e 's/([0-9a-f]{2})/print chr hex $1/gie' | base64_encode`

FOR_THUMBPRINT="{\"e\": \"${PUBLIC_EXPONENT64}\", \"kty\": \"RSA\", \"n\": \"${PUBLIC_MODULUS64}\"}"

HAS_SHA_256=`${OPENSSL} help 2>&1 | grep -c sha256`
if [ "${HAS_SHA_256}" -gt 0 ]; then
	THUMBPRINT=`echo -n "${FOR_THUMBPRINT}" | tr -d ' ' | ${OPENSSL} sha256 -binary | base64_encode`
else
	THUMBPRINT=`echo -n "${FOR_THUMBPRINT}" | tr -d ' ' | ${OPENSSL} sha -sha256 -binary | base64_encode`
fi

#Register the new key with the acme-server
if [ ${OLD_KEY} -eq 0 ]; then
	send_signed_request "${API}/acme/new-acct" '{"termsOfServiceAgreed": true}'

	echo "${RESPONSE}" > ${LETSENCRYPT_ACCOUNT_KEY}.json
	if [ "${HTTP_STATUS}" = "" ] || [ "${HTTP_STATUS}" -eq 201 ] ; then
		echo "Account has been registered."
	elif [ "${HTTP_STATUS}" -eq 409 ] ; then
		echo "Account is already registered."
	else
		echo "Account registration error. Response: ${RESPONSE}."
		rm -f ${LETSENCRYPT_ACCOUNT_KEY} ${LETSENCRYPT_ACCOUNT_KEY}.json
		exit 1
	fi
fi

if [ -s "${LETSENCRYPT_ACCOUNT_KEY}.json" ]; then
	ACCOUNT_ID="`grep -m1 '\"id\":' \"${LETSENCRYPT_ACCOUNT_KEY}.json\" | awk '{print $2}' | cut -d, -f1`"
	if [ "${ACCOUNT_ID}" = "" ]; then
		ACCOUNT_ID="`grep -m1 -i 'Location:.*/acct/' \"${LETSENCRYPT_ACCOUNT_KEY}.json\" | cut -d'/' -f6 | grep -o '[0-9]*'`"
	fi
	if [ "${ACCOUNT_ID}" = "" ]; then
		echo "Unable to find account ID in \"${LETSENCRYPT_ACCOUNT_KEY}.json\". Exiting..."
		exit 1
	fi

	ACCOUNT_URL="${API}/acme/acct/${ACCOUNT_ID}"
else
	echo "Requesting CA for missing information about the account..."
	send_signed_request "${API}/acme/new-acct" '{\"onlyReturnExisting\": true}' "${API}/acme/acct"
	ACCOUNT_URL="`echo \"${RESPONSE}\" | grep ^Location: | awk '{print $2}' | tr -d '\r\n'`"
	send_signed_request "${ACCOUNT_URL}" '{}'
	ACCOUNT_ID="`echo \"${RESPONSE}\" | grep -oE '/[0-9]+' | cut -d/ -f2`"
	echo "${RESPONSE}" > "${LETSENCRYPT_ACCOUNT_KEY}.json"
fi

if [ "${ACTION}" = "revoke" ]; then
	if [ ! -e ${CERT} ]; then
		echo "Certificate ${CERT} does not exist, there is nothing to revoke."
		exit 1
	fi
	DER64="`${OPENSSL} x509 -in ${CERT} -inform PEM -outform DER | base64_encode`"
	send_signed_request "${API}/acme/revoke-cert" '{"certificate": "'"${DER64}"'"}' 
	if [ "${HTTP_STATUS}" = "" ] || [ "${HTTP_STATUS}" -eq 200 ] ; then
		echo "Certificate has been successfully revoked."
	else
		echo "Certificate revocation error. Response: ${RESPONSE}."
		exit 1
	fi
	exit 0
fi

#Overwrite san_config file if csr_cf_file path is different
if [ "${CSR_CF_FILE}" != "" ] && [ "${CSR_CF_FILE}" != "${SAN_CONFIG}" ]; then
	cp -f ${CSR_CF_FILE} ${SAN_CONFIG}
fi

#For multi-domains (www and non-www one)
SAN=""

OVERWRITE_SAN=true
if [ -s ${SAN_CONFIG} ] && ! ${DOMAINARR_IN_USE} && ! ${IS_SINGLE} && ! ${IS_FULL}; then
	SAN="`cat \"${SAN_CONFIG}\" | grep '^subjectAltName=' | cut -d= -f2`"
	if [ -z "${SAN}" ]; then
		OVERWRITE_SAN=true
	else
		OVERWRITE_SAN=false
	fi
fi

if [ "${HOSTNAME}" -eq 0 ] && ${OVERWRITE_SAN}; then
	if ${DOMAINARR_IN_USE} || ${IS_SINGLE}; then
		SAN=""
		for TDOMAIN in ${DOMAINARR}
		do
			CHALLENGE_TEST=`challenge_check ${TDOMAIN}`
			if [ ${CHALLENGE_TEST} -ne 1 ]; then
				SAN="${SAN}, DNS:${TDOMAIN}"
			else
				echo "skipping ${TDOMAIN} challenge test failed"
			fi
		done
		SAN=`echo ${SAN} | grep -o -E "DNS:(.*)"`
	elif ! echo "${DOMAIN}" | grep -q "^www\."; then
		#We have a domain without www., add www domain to to SAN too
		SAN="DNS:${DOMAIN}, DNS: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.##'`
		SAN="DNS:${DOMAIN2}, DNS:www.${DOMAIN2}"
	fi

	if ${IS_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} mail ftp smtp pop"
		for s in `echo ${SUB_LIST}`; do
		{
			H=${s}.${DOMAIN}
			CHALLENGE_TEST=`challenge_check ${H}`
			if [ ${CHALLENGE_TEST} -eq 1 ]; then
				if [ "${CHALLENGETYPE}" = "http-01" ]; then
					echo "${H} was skipped due to unreachable http://${H}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} file. Not adding to san_config"
				else
					echo "${H} was skipped due to missing DNS TXT entry at _acme-challenge.${H}. Not adding to san_config"
				fi
			else
					SAN="${SAN}, DNS:${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
			{
				SAN="${SAN}, DNS:${p}, DNS:www.${p}"
			};
			done;
		fi
	fi
elif ${OVERWRITE_SAN}; then
	#For hostname, we add www, mail, ftp, pop, smtp to the SAN
	if ${DOMAINARR_IN_USE} || ${IS_SINGLE}; then
		SAN=""
		for TDOMAIN in ${DOMAINARR}
		do
			SAN="${SAN}, DNS:${TDOMAIN}"
		done
		SAN=`echo ${SAN} | egrep -o "DNS:(.*)"`
	else

		if ! echo "${DOMAIN}" | grep -q "^www\."; then
			#We have a domain without www., add www domain to to SAN too
			MAIN_HOST=${DOMAIN}
		else
			#We have a domain with www., drop www and add it to SAN too
			DOMAIN2=`echo ${DOMAIN} | perl -p0 -e 's#^www.##'`
			MAIN_HOST=${DOMAIN2}
		fi
		SAN="DNS:${MAIN_HOST}"
		for A in www mail ftp pop smtp; do
		{
			H=${A}.${MAIN_HOST}
			CHALLENGE_TEST=`challenge_check ${H}`
			if [ ${CHALLENGE_TEST} -eq 1 ]; then
				if [ "${CHALLENGETYPE}" = "http-01" ]; then
					echo "${H} was skipped due to unreachable http://${H}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} file. Not adding to san_config"
				else
					echo "${H} was skipped due to missing DNS TXT entry at _acme-challenge.${H}. Not adding to san_config"
				fi
			else
				SAN="${SAN}, DNS:${H}"
			fi
		};
		done;
	fi
fi

DOMAINS="`echo ${SAN} | tr -d '\",' | perl -p0 -e 's#DNS:##g'`"

if [ -z "${DOMAINS}" ]; then
	echo "No domains to generate certificates for, as provided domains failed Let's Encrypt validation."
	exit 1
fi

if echo ${DOMAINS} | grep -m1 -q '*\.'; then
	if [ "${CHALLENGETYPE}" = "http-01" ]; then
		echo "Found wildcard domain name and http-01 challenge type, switching to dns-01 validation."
		CHALLENGETYPE="dns-01"
	fi
fi

CN_DOMAIN=${DOMAIN}
if ! echo "${DOMAINS}" | grep -m1 -q "DNS:${DOMAIN},"; then
        CN_DOMAIN="`echo ${SAN} | cut -d':' -f2 | cut -d',' -f1`"
fi
if [ "${CN_DOMAIN}" = "" ]; then
	CN_DOMAIN=${DOMAIN}
fi

#Create san_config
if [ ! -s ${SAN_CONFIG} ] || ${DOMAINARR_IN_USE} || ${IS_SINGLE} || ${IS_FULL} || ${OVERWRITE_SAN}; then
	echo "[ req_distinguished_name ]" > ${SAN_CONFIG}
	echo "CN = ${CN_DOMAIN}" >> ${SAN_CONFIG}
	echo "[ req ]" >> ${SAN_CONFIG}
	echo "distinguished_name = req_distinguished_name" >> ${SAN_CONFIG}
	echo "[SAN]" >> ${SAN_CONFIG}
	echo "subjectAltName=${SAN}" >> ${SAN_CONFIG}
fi

for single_domain in `echo "${DOMAINS}" | tr ' ' '\n' | perl -p0 -e 's|\*\.||g' | sort | uniq`; do {
	if [ "${CHALLENGETYPE}" = "http-01" ]; then
		CHALLENGE_TEST=`challenge_check ${single_domain}`
	else
		CHALLENGE_TEST=`challenge_check ${single_domain} dns-precheck`
	fi
	if [ ${CHALLENGE_TEST} -eq 1 ] && [ "${CHALLENGETYPE}" = "http-01" ]; then
		echo "Error: http://${single_domain}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} is not reachable. Aborting the script."
		echo "dig output for ${single_domain}:"
		IPV6=`${DIG} @${DNS_SERVER} AAAA ${single_domain} +short`
		if [ -z "${IPV6}" ]; then
			${DIG} @${DNS_SERVER} ${single_domain} +short
		else
			echo "${IPV6}"
		fi
		if [ ${LETSENCRYPT_OPTION} -eq 1 ]; then
			echo "Please make sure /.well-known alias is setup in WWW server."
		else
			echo "Please make sure .htaccess or WWW server is not preventing access to /.well-known folder."
		fi
        	exit 1
	elif [ ${CHALLENGE_TEST} -eq 1 ]; then
		MAXTRIES=20
		TRIES=0

		echo "action=dns&do=add&domain=${single_domain}&type=TXT&name=_acme-challenge-test&value=\"pre-check\"&ttl=5&named_reload=yes" >> ${TASK_QUEUE}
                run_dataskq

		# Get NS entries from the domain
		echo "DNS challenge test fail for _acme-challenge-test.${single_domain} IN TXT \"pre-check\", retrying..."

		#if 8.8.8.8 is not accessible, dig returns code 9.  The dig|grep method returns code 1, so have to redo.
		${DIG} TXT _acme-challenge-test.${single_domain} @${DNS_SERVER} +short > /dev/null 2>&1
		if [ "$?" -eq 9 ] && [ "${DNS_SERVER}" != "${NEW_IP}" ]; then
			if [ "${NEW_IP}" != "" ]; then
				echo "Unable to connect to ${DNS_SERVER}. Trying ${NEW_IP} instead";
				DNS_SERVER=${NEW_IP}
			fi
		fi

		while [ ${CHALLENGE_TEST} -eq 1 ]; do
			CHALLENGE_TEST=`challenge_check ${single_domain} dns-precheck`
			sleep ${DIG_SECONDS}
			TRIES=`expr ${TRIES} + 1`
			if [ "${TRIES}" = "${MAXTRIES}" ]; then
				echo "DNS validation failed. Exiting..."
				echo "action=dns&do=delete&domain=${single_domain}&type=TXT&name=_acme-challenge-test&value=\"pre-check\"" >> ${TASK_QUEUE}
				run_dataskq
				exit 1
			fi
			echo "Retry failed, trying again in ${DIG_SECONDS}s..."
		done
	fi
}
done

#If config has no CN - add it
if ! grep -m1 -q '^CN[^A-Za-z0-9]*=' ${SAN_CONFIG}; then
       perl -pi -e "s|^\[ req_distinguished_name \]$|[ req_distinguished_name ]\nCN = ${CN_DOMAIN}|g" ${SAN_CONFIG}
fi

chown diradmin:diradmin ${SAN_CONFIG}
chmod 600 ${SAN_CONFIG}

#Form identifiers
IDENTIFIERS_PART=""
for single_domain in ${DOMAINS}; do {
	IDENTIFIERS_PART="${IDENTIFIERS_PART}, {\"type\": \"dns\", \"value\": \"${single_domain}\"}";
}
done
IDENTIFIERS_PART="`echo \"${IDENTIFIERS_PART}\" | perl -p0 -e 's|^, ||g'`"
IDENTIFIERS="{\"identifiers\": [${IDENTIFIERS_PART}]}"

echo "Requesting new certificate order..."
send_signed_request "${API}/acme/new-order" "${IDENTIFIERS}"

#Account has a key for let's encrypt, but it's not registered
if [ "${HTTP_STATUS}" -eq 403 ] ; then
	echo "User let's encrypt key has been found, but not registered. Registering..."
	send_signed_request "${API}/acme/new-acct" '{"termsOfServiceAgreed": true}' > ${LETSENCRYPT_ACCOUNT_KEY}.json
	if [ "${HTTP_STATUS}" = "" ] || [ "${HTTP_STATUS}" -eq 201 ] ; then
		echo "Account has been registered."
	elif [ "${HTTP_STATUS}" -eq 409 ] ; then
		echo "Account is already registered."
	else
		echo "Account registration error. Response: ${RESPONSE}."
		rm -f ${LETSENCRYPT_ACCOUNT_KEY}.json ${LETSENCRYPT_ACCOUNT_KEY}
		exit 1
	fi

	echo "Requesting new certificate order..."
	send_signed_request "${API}/acme/new-order" "${IDENTIFIERS}"
fi

if [ "${HTTP_STATUS}" -ne 201 ] ; then
	echo "new-order error: ${RESPONSE}. Exiting..."
	exit 1
fi

AUTHORIZATIONS="`echo \"${RESPONSE}\" | tr -d '\n' | grep -o '"authorizations": \[[^]]*' | cut -d'[' -f2 | cut -d ']' -f1 | tr -d '",'`"
FINALIZE="`echo \"${RESPONSE}\" | grep -o '"finalize": ".*"' | awk '{print $2}' | tr -d '"'`"

if [ "${AUTHORIZATIONS}" = "" ]; then
	echo "Authorizations list empty, cannot continue. Exiting..."
	exit 1
fi

if [ "${FINALIZE}" = "" ]; then
	echo "Finalize URL empty, cannot continue. Exiting..."
	exit 1
fi

clear_pending_auth() {
        while [ "${CHALLENGE_STATUS}" = "pending" ]; do
                sleep 1
		send_signed_request "${CHALLENGE_URI}" "{\"keyAuthorization\": \"${KEYAUTH}\"}"
                CHALLENGE_STATUS="`echo ${RESPONSE} | tr ',' '\n' | grep -m1 '\"status\":' | cut -d'\"' -f4`"
                CHALLENGE_DETAIL="`echo ${RESPONSE} | tr ',' '\n' | grep -m1 '\"detail\":' | cut -d'\"' -f4`"
        done
}
#For each of the domains, we need to verify them
for authorization in ${AUTHORIZATIONS}; do {
	echo "Processing ${authorization}..."
	send_signed_request "${authorization}" ""
	if [ "${HTTP_STATUS}" = "400" ]; then
		echo "Authorization is pending..."
		return
	fi
	single_domain="`echo \"${RESPONSE}\" | tr -d '\n' | grep -o -m1 '\"identifier\":[^}]*' | grep -o '\"value\": \"[^\"]*' | awk '{print $2}' | tr -d '\"'`"
	if [ "${single_domain}" = "" ]; then
		echo "Unable to determine domain name for authorization. Exiting..."
		exit 1
	else
		echo "Processing authorization for ${single_domain}..."
	fi
	
	if echo "${RESPONSE}" | grep -m1 -q '"status": "valid"'; then
		echo "Challenge is valid."
		continue
	fi

	CHALLENGE="`echo \"${RESPONSE}\" | tr -d '\n' | grep -o "\\"type\\": \\"${CHALLENGETYPE}\\",[^}]*"`"

	CHALLENGE_TOKEN="`echo \"${CHALLENGE}\" | tr ',' '\n' | grep -m1 '\"token\":' | cut -d'\"' -f4`"
	CHALLENGE_URI="`echo \"${CHALLENGE}\" | tr ',' '\n' | grep -m1 '\"url\":' | cut -d'\"' -f4`"
	CHALLENGE_STATUS="`echo \"${CHALLENGE}\" | tr ',' '\n' | grep -m1 '\"status\":' | cut -d'\"' -f4`"

	if [ "${CHALLENGE_TOKEN}" = "" ]; then
		if [ "${CHALLENGE_STATUS}" = "pending" ]; then
			clear_pending_auth
		fi
		echo "Challenge token is empty. Something went wrong. Exiting..."
		exit 1
	fi

	KEYAUTH="${CHALLENGE_TOKEN}.${THUMBPRINT}"

	if [ "${CHALLENGETYPE}" = "dns-01" ]; then
		DNSENTRY="`echo -n \"${KEYAUTH}\" | \"${OPENSSL}\" dgst -sha256 -binary | base64_encode`"
		# We must create _acme-challenge IN TXT for ${DOMAIN} here with DNSENTRY value
		# something like the following with very low TTL of 5sec or so: _acme-challenge 1 IN TXT "${DNSENTRY}"
		#
		# We cannot have SAN like: *.testing.martynas.it,abc.testing.martynas.it,testing.martynas.it, because it throws:
		# detail": "Error creating new order :: Domain name \"abc.testing.martynas.it\" is redundant with a wildcard domain in the same request. Remove one or the other from the certificate request.",
		echo "action=dns&do=delete&domain=${single_domain}&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=${single_domain}&type=TXT&name=_acme-challenge&value=\"${DNSENTRY}\"&ttl=5&named_reload=yes" >> ${TASK_QUEUE}
		run_dataskq
	else
		if [ "${DOMAIN_DIR}" = "/var/www/html" ]; then
			mkdir -p ${WELLKNOWN_PATH}
			chown webapps:webapps ${HOSTNAME_DIR}/.well-known
			chown webapps:webapps ${WELLKNOWN_PATH}
		fi

		if [ ! -d "${WELLKNOWN_PATH}" ]; then
                	if [ "${CHALLENGE_STATUS}" = "pending" ]; then
        	                clear_pending_auth
	                fi
			echo "Cannot find ${WELLKNOWN_PATH}. Create this path, ensure it's chowned to the User.";
			exit 1;
		fi
		echo "${KEYAUTH}" > "${WELLKNOWN_PATH}/${CHALLENGE_TOKEN}"
		chown webapps:webapps "${WELLKNOWN_PATH}/${CHALLENGE_TOKEN}"

		trap "rm -f \"${WELLKNOWN_PATH}/${CHALLENGE_TOKEN}\"; exit" INT TERM EXIT
	fi

	#Checking if challenge will be reachable
	CHALLENGE_TEST=`challenge_check ${single_domain}`
	if [ ${CHALLENGE_TEST} -eq 1 ] && [ "${CHALLENGETYPE}" = "http-01" ]; then
		echo "Error: http://${single_domain}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} is not reachable. Aborting the script."
		echo "dig output for ${single_domain}:"
		IPV6=`${DIG} @${DNS_SERVER} AAAA ${single_domain} +short`
		if [ -z "${IPV6}" ]; then
			${DIG} @${DNS_SERVER} ${single_domain} +short
		else
			echo "${IPV6}"
		fi
		if [ ${LETSENCRYPT_OPTION} -eq 1 ]; then
			echo "Please make sure /.well-known alias is setup in WWW server."
		else
			echo "Please make sure .htaccess or WWW server is not preventing access to /.well-known folder."
		fi
		if [ "${CHALLENGE_STATUS}" = "pending" ]; then
                        clear_pending_auth
                fi
        	exit 1
	elif [ ${CHALLENGE_TEST} -eq 1 ]; then
		MAXTRIES=20
		TRIES=0
		# Get NS entries from the domain
		echo "DNS challenge test fail for _acme-challenge.${single_domain} IN TXT \"${DNSENTRY}\", retrying..."

		#if 8.8.8.8 is not accessible, dig returns code 9.  The dig|grep method returns code 1, so have to redo.
		${DIG} TXT _acme-challenge.${single_domain} @${DNS_SERVER} +short > /dev/null 2>&1
		if [ "$?" -eq 9 ] && [ "${DNS_SERVER}" != "${NEW_IP}" ]; then
			if [ "${NEW_IP}" != "" ]; then
				echo "Unable to connect to ${DNS_SERVER}. Trying ${NEW_IP} instead";
				DNS_SERVER=${NEW_IP}
			fi
		fi

		while [ ${CHALLENGE_TEST} -eq 1 ]; do
			CHALLENGE_TEST=`challenge_check ${single_domain}`
			sleep ${DIG_SECONDS}
			TRIES=`expr ${TRIES} + 1`
			if [ "${TRIES}" = "${MAXTRIES}" ]; then
				echo "DNS validation failed. Exiting..."
				echo "action=dns&do=delete&domain=${single_domain}&type=TXT&name=_acme-challenge&value=\"${DNSENTRY}\"" >> ${TASK_QUEUE}
				run_dataskq
		                if [ "${CHALLENGE_STATUS}" = "pending" ]; then
		                        clear_pending_auth
                		fi
				exit 1
			fi
			echo "Retry failed, trying again in ${DIG_SECONDS}s..."
		done
	fi

	sleep 1

	echo "Waiting for domain verification..."
	while [ "${CHALLENGE_STATUS}" = "pending" ]; do
		sleep 1
		send_signed_request "${CHALLENGE_URI}" "{\"keyAuthorization\": \"${KEYAUTH}\"}"
		CHALLENGE_STATUS="`echo ${RESPONSE} | tr ',' '\n' | grep -m1 '\"status\":' | cut -d'\"' -f4`"
		CHALLENGE_DETAIL="`echo ${RESPONSE} | tr ',' '\n' | grep -m1 '\"detail\":' | cut -d'\"' -f4`"
		if echo "${CHALLENGE_DETAIL}" | grep -m1 -q 'authorization must be pending'; then
			echo "Let's Encrypt was unable to verify the challenge. ${CHALLENGE_DETAIL}. Exiting..."
			exit 1
		fi
	done

	CHALLENGE_STATUS_VALID=false

	if echo "${RESPONSE}" | grep -m1 -q '"status": "valid"'; then
		echo "Challenge is valid."
		CHALLENGE_STATUS_VALID=true
	fi

	if [ "${CHALLENGE_STATUS}" != "valid" ] && [ "${CHALLENGE_STATUS}" != "invalid" ] && [ "${CHALLENGE_STATUS}" != "" ]; then
		echo "Trying again..."
		for n in `seq 1 5`; do
		sleep 1;
		echo -n "${n}..";
		done;
		echo "";
		send_signed_request "${CHALLENGE_URI}" "{\"keyAuthorization\": \"${KEYAUTH}\"}"
		sleep 1;
	elif [ "${CHALLENGE_STATUS}" != "invalid" ]; then
		CHALLENGE_STATUS_VALID=true
	fi

	if ! ${CHALLENGE_STATUS_VALID}; then
		if [ "${CHALLENGE_STATUS}" != "valid" ]; then
	                if [ "${CHALLENGE_STATUS}" = "pending" ]; then
        	                clear_pending_auth
                	fi
			echo "Challenge status: ${CHALLENGE_STATUS}. Challenge error: ${RESPONSE}. Exiting..."
			exit 1
		fi
	fi

	if [ "${CHALLENGETYPE}" = "http-01" ]; then
		rm -f "${WELLKNOWN_PATH}/${CHALLENGE_TOKEN}"
	fi
	
	if [ "${CHALLENGE_STATUS}" = "valid" ]; then
		echo "Challenge is valid."
	else
		if [ "${CHALLENGETYPE}" = "dns-01" ]; then
			echo "action=dns&do=delete&domain=${single_domain}&type=TXT&name=_acme-challenge&value=\"${DNSENTRY}\"" >> ${TASK_QUEUE}
			run_dataskq
		fi
                if [ "${CHALLENGE_STATUS}" = "pending" ]; then
                        clear_pending_auth
                fi
		echo "Challenge is ${CHALLENGE_STATUS}. Details: ${CHALLENGE_DETAIL}. Exiting..."
		exit 1
	fi
}
done

#Create domain key, also generate CSR for the domain
echo "Generating ${KEY_SIZE} bit RSA key for ${DOMAIN}..."
echo "openssl genrsa ${KEY_SIZE} > \"${KEY}.new\""
${OPENSSL} genrsa ${KEY_SIZE} > "${KEY}.new"

${OPENSSL} req -new -sha256 -key "${KEY}.new" -subj "/CN=${CN_DOMAIN}" -reqexts SAN -config "${SAN_CONFIG}" -out "${CSR}"

#Request certificate from let's encrypt
DER64="`${OPENSSL} req -in ${CSR} -outform DER | base64_encode`"

send_signed_request "${FINALIZE}" "{\"resource\": \"new-cert\", \"csr\": \"${DER64}\"}"
CERTIFICATE_URL="`echo ${RESPONSE} | grep -m1 -o '\"certificate\": \"[^\"]*' | cut -d'\"' -f4`"

if [ "${CERTIFICATE_URL}" = "" ]; then
	echo "Unable to find certificate. Something went wrong. Printing response..."
	echo "${RESPONSE}" | grep -o '"detail": ".*"'
	echo ""
	exit 1
fi

send_signed_request "${CERTIFICATE_URL}" ""

echo "${RESPONSE}" > ${CERT}.new.tmp

${OPENSSL} x509 -text < ${CERT}.new.tmp > /dev/null 2>&1
if [ $? -ne 0 ]; then
	echo "Certificate error in ${CERT}. Exiting..."
	/bin/rm -f ${KEY}.new ${CERT}.new.tmp
	exit 1
fi

openssl x509 -in ${CERT}.new.tmp -out ${CERT}.new
sed '1,/^$/d' ${CERT}.new.tmp > ${CACERT}.new

if [ "${CHALLENGETYPE}" = "dns-01" ]; then
        echo "action=dns&do=delete&domain=${single_domain}&type=TXT&name=_acme-challenge&value=\"${DNSENTRY}\"" >> ${TASK_QUEUE}
        run_dataskq
fi

echo -n "Checking Certificate Private key match... "
CHECKPRIVPUBRES=`checkPrivPubMatch ${KEY}.new ${CERT}.new`
if [ $CHECKPRIVPUBRES -eq 0 ]; then
	echo "Match!"
else
	echo "Certificate mismatch!!!"
	rm -f ${KEY}.new ${CERT}.new.tmp ${CACERT}.new
	exit 1
fi

if [ ! -s ${KEY}.new ] || [ ! -s ${CERT}.new ]; then
	echo "New key/certificate is empty. Exiting..."
	exit 1
fi

#everything went well, move the new files.
/bin/mv -f ${KEY}.new ${KEY}
/bin/mv -f ${CERT}.new ${CERT}
if [ -s ${CACERT}.new ]; then
	/bin/mv -f ${CACERT}.new ${CACERT}
fi
if [ ! -s ${CACERT} ]; then
echo "-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
-----END CERTIFICATE-----" > ${CACERT}
fi
date +%s > ${CERT}.creation_time

cat ${CERT} ${CACERT} > ${CERT}.combined

chown ${FILE_CHOWN} ${KEY} ${CERT} ${CERT}.combined ${CACERT} ${CSR} ${CERT}.creation_time
chmod ${FILE_CHMOD} ${KEY} ${CERT} ${CERT}.combined ${CACERT} ${CSR} ${CERT}.creation_time

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

	#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

echo "Certificate for ${DOMAIN} has been created successfully!"
