#!/usr/bin/env bash
# setup the certificate manager

SPATH="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")"    # dir of the script
SNAME="$(basename ${BASH_SOURCE[0]})"                    # name of the script

ASCEDSCONF='local site certbot hostconf'
ASCEDSLIBS='utils hosts postfix openssl'

if [ ! -r "${SPATH}/asceds-head" ] ; then
   echo "No header ${SPATH}/asceds-head. Exiting"
   exit 9
fi

. ${SPATH}/asceds-head

asceds-standalone-setup-usage()
{
  cat << ENDUSAGE

Usage: asceds-standalone-setup [-h] [-d]
-h --> display usage and exit
-d --> disable the standalone mode

Enable standalone mode:
Checks/fixes network configuration including hosts, postfix, openssl.cnf.
Checks for certbot; if not found, offer self signed certbot (for test sites)
   or requests certbot install.
Checks for mailer; if not found, requests mailer install.
Collects certbot credentials and authorized domains in asceds-certbot.conf.
Creates asceds user ssh keys and the local authorized_keys.
Creates/updates the site config file asceds-site.conf.
Creates symlinks to certobot-related ASCEDS scripts.
Sets cron asceds-cert-propagate for driving asceds-propagate-certbot 
   to push renewed cert files to ~asceds/<client> and propagate
   them to managed clients through asceds-send-cert.

Disable standalone mode:
* disable certbot timer: systemctl disable snap.certbot.renew.timer
* move certbot-related crontabs to ${ASCEDSETCDIR}/disabled.cron/
* disable asceds timer: /etc/cron.d/asceds-cert-propagate


ENDUSAGE
exit 0
}

# direct standalone mode
STANDALONE='yes'

# force self signed site
SELFSIGNED=''

# disable
SADISABLE=''

# general validation and parse of the command line
for ARG in ${ARGS} ; do
   #echo "ARG=${ARG}"
   if [ "${ARG}" != "${ARG//[^-a-zA-Z0-9.]/}" ] ; then
      asceds-error "Malformed argument ${ARG}"
   elif [ "${ARG}" == "-h" ] ; then
      shift
      asceds-standalone-setup-usage
   elif [ "${ARG}" == "-d" ] ; then
      shift
      SADISABLE='yes'
      STANDALONE=''
   else
      shift
   fi
done

# run as root only
asceds-run-asroot

# set standalone mode
asceds-refresh-var "${ASCEDSETCDIR}/asceds-site.conf" \
                               "STANDALONE" "${STANDALONE}"

# find certbot cron.d triggers
CRONDTRIG="$( grep -IlZ -- 'certbot' /etc/cron.d/* | xargs -0 )"

# disable standalone mode
if [ -n "${SADISABLE}" ] ; then
   # disable certbot timer
   if [ -n "${CRONDTRIG}" ] ; then
      if [ ! -d "${ASCEDSETCDIR}/disabled.cron" ] ; then
         mkdir ${ASCEDSETCDIR}/disabled.cron
      fi
      ${MV} ${CRONDTRIG} ${ASCEDSETCDIR}/disabled.cron/
   else
      echo "No cron triggers found"
   fi

   # disable systemctl timers
   if systemctl list-unit-files --type=timer --no-legend | \
        awk '{print $1}' | grep -qx 'snap.certbot.renew.timer'; then
      systemctl disable --now snap.certbot.renew.timer
   else
      echo "No systemctl timers found"
   fi

   echo "Standalone mode successfully disabled"
   exit 0
fi 

# check/fix network configuration
asceds-check-netconf

# clean old asceds-local.conf for backwards compatibility
if [ -r "${ASCEDSETCDIR}/asceds-local.conf" ] ; then
   ${RM} -f ${ASCEDSETCDIR}/asceds-local.conf
fi

# check for mailer,
# the certificate manager cannot work without sending email
asceds-find-mail
asceds-source-etcconf "${ASCEDSETCDIR}" "${ASCEDSCONF}"
if [ -z "${ALARMSEND}" ] ; then
   echo "No mailer was found on this system !!!!!!!!!!!!!!!!!!!"
   echo "Please install mailutils and postfix, "
   echo "then run again asceds-standalone-setup"
   exit 1
fi

# Check for certbot; if not found, request certbot install
asceds-find-certbot

# config certbot to work with the ACME server
asceds-config-certbot
asceds-source-etcconf "${ASCEDSETCDIR}" "${ASCEDSCONF}"

# set the certificate manager name
ASCEDSCRTMGR='$( hostname -f )'

# create asceds user ssh keys and the local authorized_keys
if [ ! -d "${ASCEDSHOMEDIR}/.ssh" ] ; then 
   mkdir -p ${ASCEDSHOMEDIR}/.ssh
fi
if [ ! -r "${ASCEDSHOMEDIR}/.ssh/id_ed25519.pub" ] && 
   [ ! -r "${ASCEDSHOMEDIR}/.ssh/id_rsa.pub" ] ; then
   asceds-echo "Generating asceds user ssh keys."
   eval ${SSHKEYGEN} -f ${ASCEDSHOMEDIR}/.ssh/id_ed25519 -C "asceds@${ASCEDSCRTMGR}"
   ${CP} -f ${ASCEDSHOMEDIR}/.ssh/id_ed25519.pub ${ASCEDSHOMEDIR}/.ssh/authorized_keys
   chown -R asceds:asceds ${ASCEDSHOMEDIR}/.ssh
   chmod go-rwx ${ASCEDSHOMEDIR}/.ssh ${ASCEDSHOMEDIR}/.ssh/authorized_keys
fi

# Create symlinks to certobot-related scripts
ln -sf ${ASCEDSCBDIR}/asceds-certbot-gencert /usr/bin/asceds-certbot-gencert 
ln -sf ${ASCEDSCBDIR}/asceds-certbot-revoke /usr/bin/asceds-certbot-revoke
ln -sf ${ASCEDSCBDIR}/asceds-propagate-certbot /usr/bin/asceds-propagate-certbot

# Sets cron asceds-cert-propagate for driving asceds-propagate-certbot 
#    to copy renewal cert files to ~asceds/<domainname>
CRONF="/etc/cron.d/asceds-cert-propagate"
if [ ! -r "${CRONF}" ] ; then
   if [ ! -d "/etc/cron.d" ] ; then
      asceds-error "No cron dir /etc/cron.d"
   fi
   asceds-echo "Creating cron file asceds-propagate-certbot"
   cat <<< "# detects cretificate changes/renewals; propagates to clients" > ${CRONF}
   CRONEXEC="${ASCEDSHOME}/certbot/asceds-propagate-certbot"
   if [ -x "${CRONEXEC}" ] ; then 
      # run it every day at 22:16
      cat <<< "16 22 * * * root ${CRONEXEC} -q > /dev/null 2>&1"  >> ${CRONF}
   else
      asceds-error "The new cert detection script ${CRONEXEC} not found. Please fix and try again"
   fi
else
   asceds-echo "Cron file ${CRONF} exists, please tune it to your needs"
fi

# fix siteconfig
ASCEDSALTCRTMGR="${ASCEDSCRTMGR}" CALLFROMCRTMGRST='' STANDALONE="yes" SELFSIGNED="" \
   asceds-update-siteconfig -s || \
   asceds-error "The site config file could not be created successfuly"

# refresh the values
asceds-source-etcconf "${ASCEDSETCDIR}" "${ASCEDSCONF}"

# make sure that the certbot timer is active
if systemctl list-unit-files --type=timer --no-legend | \
       awk '{print $1}' | grep -qx 'snap.certbot.renew.timer'; then
   systemctl enable --now snap.certbot.renew.timer
elif [ -z "${CRONDTRIG}" ] || [ "${CRONDTRIG}" == "/etc/cron.d/asceds-cert-propagate" ] ; then
   echo "!!!!! No certbot renew trigger found. Set by hand !!!!!!"
fi

# further instructions: configure the client and get the initial cert
echo "To finish setup and get the initial cert:"
echo "      edit CERTBOTOPTS in /etc/asceds/asceds-certbot.conf"
echo "      then run asceds-init -d"
