#!/bin/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-certmanager-setup-usage()
{
  cat << ENDUSAGE

Usage: asceds-certmanager-setup [-h] [-s <certmanager>]
-h --> display usage and exit
-s <certmanager> --> FQDN of the certificate manager (if different from hostname)

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.
Web interface setup:
   Gets info: organization name, website url, request execution methods;
   Customizes config.php and asceds.php;
   Copies and reconfigs asceds-site-apache2.conf;
   Initializes request log file;
   Builds directory structure for the website;
   Creates symlink to make site config file available by wget to clients;
   Creates ssh keys for root requests by ssh;
   Sets asceds-web-actions crontab for running the request queues generated by 
      the web interface.

ENDUSAGE
exit 0
}

# alternate ASCEDSCRTMGR
ASCEDSALTCRTMGR=''

# 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-certmanager-setup-usage
   elif [ "${ARG}" == "-s" ] ; then
      shift
      if [[ "$1" != -* ]] && [ -n "$1" ] ; then
         ASCEDSALTCRTMGR=$( cat <<< $1 | tr '[:upper:]' '[:lower:]' )
         asceds-validate-fqdn "${ASCEDSALTCRTMGR}" || \
            asceds-error "Invalid certificate manager FQDN ${ASCEDSALTCRTMGR}"
      fi
   else
      shift
   fi
done

# run as root only
asceds-run-asroot

# 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-certmanager-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
if [ -n "${ASCEDSALTCRTMGR}" ] ; then
   ASCEDSCRTMGR="${ASCEDSALTCRTMGR}"
elif [ -z "${ASCEDSCRTMGR}" ] ; then
   ASCEDSCRTMGR=$( hostname -f | tr '[:upper:]' '[:lower:]' )
   ASCEDSALTCRTMGR="${ASCEDSCRTMGR}"
fi

# refresh the website setup for consistency
asceds-refresh-webdomains

# configure authorized domains: asceds-authorized-domains
# echo 
# YE=''
# echo -n "Configure CA authorized domains? [Y/n] "
# read YE
# if [ "${YE}" != "n" ] && [ "${YE}" != "N" ] ; then
#    asceds-authorized-domains
# fi
# echo "CA authorized domains can be managed later using"
# echo "the asceds-authorized-domains command"
# echo

# 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_rsa.pub" ] ; then
   asceds-echo "Generating asceds user ssh keys."
   eval ${SSHKEYGEN} -f ${ASCEDSHOMEDIR}/.ssh/id_rsa -C "asceds@${ASCEDSCRTMGR}"
   ${CP} -f ${ASCEDSHOMEDIR}/.ssh/id_rsa.pub ${ASCEDSHOMEDIR}/.ssh/authorized_keys
   chown -R asceds:asceds ${ASCEDSHOMEDIR}/.ssh
   chmod go-rwx ${ASCEDSHOMEDIR}/.ssh ${ASCEDSHOMEDIR}/.ssh/authorized_keys
fi

# create site file ${ASCEDSETCDIR}/asceds-site.conf
ASCEDSALTCRTMGR="${ASCEDSALTCRTMGR}" CALLFROMCRTMGRST='yes' \
   asceds-update-siteconfig -s || \
   asceds-error "The site config file could not be created successfuly"
# refresh the values
asceds-source-etcconf "${ASCEDSETCDIR}" "${ASCEDSCONF}"

# 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

# web interface setup #########################################################   

# cofigure config.php
asceds-config-configphp

# copy and reconfig /usr/lib/asceds/website/asceds-site-apache2.conf
echo
APACHESITECONF="${ASCEDSWEBSRVCONFDIR}/sites-available/asceds.conf"
if [ ! -r "${APACHESITECONF}" ] ; then
   if [ -r "${ASCEDSHOME}/website/asceds-site-apache2.conf" ] ; then
      ${CP} ${ASCEDSHOME}/website/asceds-site-apache2.conf ${APACHESITECONF}
      sed -i -e "s/cert.example.com/${ASCEDSCRTMGR}/g" ${APACHESITECONF}
      sed -i -e "s/host.example.com/$( hostname -f | tr '[:upper:]' '[:lower:]' )/g" ${APACHESITECONF}
      sed -i -e "s+/etc/ssl+${ASCEDS_SSLDIR}+g" ${APACHESITECONF}
   else
      echo "Missing site template ${ASCEDSHOME}/website/asceds-site-apache2.conf"
      echo "Please create website comfiguration file ${APACHESITECONF}"
   fi
   echo "Please make adjustments to the website configuration file"
   echo "${APACHESITECONF}"
   echo "then run 'a2ensite asceds' to enable website,"
   echo "and 'systemctl restart ${ASCEDSWEBEXEC}' to load it into apache"    
else
   echo "Website comfiguration file ${APACHESITECONF} exists already."
   echo "Reconfiguring it... "
      sed -i -e "/ServerName/s/.*/        ServerName ${ASCEDSCRTMGR}/; \
         s%\s*Redirect\s.*%        Redirect / https://${ASCEDSCRTMGR}/%" \
         ${APACHESITECONF} || \
         asceds-warning "Website comfiguration file ${APACHESITECONF} must be reconfigured by hand."
   if [ -n "$( which systemctl )" ]  ; then
      systemctl restart ${ASCEDSWEBEXEC}
   else
      service ${ASCEDSWEBEXEC} restart
   fi
   echo "done"   
fi
echo

# initialize request log file
if [ ! -r "/var/log/asceds/cert.requests" ] ; then
   :>/var/log/asceds/cert.requests
   chown ${ASCEDSWEBUSER} /var/log/asceds/cert.requests 
fi

# build directory structure for the website
if [ ! -d "${ASCEDSWEBDIR}/html/cert/keys" ] ; then
   mkdir -p ${ASCEDSWEBDIR}/html/cert/keys
   chown ${ASCEDSWEBUSER} ${ASCEDSWEBDIR}/html/cert/keys
fi
if [ ! -d "${ASCEDSWEBDIR}/html/public" ] ; then
   mkdir -p ${ASCEDSWEBDIR}/html/public
fi

# if (by ssh), create ssh keys and add public key to /root/.ssh/authorized_keys
if [ "${WEBNEWCERTMODE}" == 'ssh' ] || [ "${WEBREVOKEMODE}" == 'ssh' ] || \
   [ "${WEBPROPAGATEMODE}" == 'ssh' ] ; then
   if [ ! -d "${ASCEDSWEBDIR}/.ssh" ] ; then
      mkdir -p ${ASCEDSWEBDIR}/.ssh
   fi
   if [ ! -d "/root/.ssh" ] ; then
      mkdir /root/.ssh
      chmod go-rwx /root/.ssh
   fi
   if [ ! -r "${ASCEDSWEBDIR}/.ssh/id_rsa.pub" ] ; then
      asceds-echo "Generating ssh keys for instant web requests" 
      eval ${SSHKEYGEN} -f ${ASCEDSWEBDIR}/.ssh/id_rsa -C "ascedsweb@${ASCEDSCRTMGR}"
      chown -R ${ASCEDSWEBUSER}:${ASCEDSWEBUSER} ${ASCEDSWEBDIR}/.ssh
      chmod go-rwx ${ASCEDSWEBDIR}/.ssh
      cat ${ASCEDSWEBDIR}/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
      chmod go-rwx /root/.ssh/authorized_keys
   fi
fi

# misc dirs and permissions
if [ ! -d "${ASCEDSWEBDIR}/cert_queue" ] ; then
   mkdir -p ${ASCEDSWEBDIR}/cert_queue
   chown ${ASCEDSWEBUSER}:${ASCEDSWEBUSER} ${ASCEDSWEBDIR}/cert_queue
fi

# set crontab for web interface actions
CRONF="/etc/cron.d/asceds-web-actions"
if [ ! -r "${CRONF}" ] ; then
   asceds-echo "Creating cron file asceds-web-actions"
   cat <<< "# runs actions requested through the web interface" > ${CRONF}
   CRONEXEC="${ASCEDSHOME}/website/asceds-web-unmanaged"
   if [ -x "${CRONEXEC}" ] ; then 
      # unmanaged requests
      cat <<< "17 * * * * root ${CRONEXEC} -q -n > /dev/null 2>&1" >> ${CRONF}
      cat <<< "47 22 * * * root ${CRONEXEC} -q -r > /dev/null 2>&1" >> ${CRONF}
   else
      asceds-error "The script for unmanaged web interface requests 
         ${CRONEXEC} was not found."
   fi
   CRONEXEC="${ASCEDSHOME}/website/asceds-web-propagate"
   if [ -x "${CRONEXEC}" ] ; then 
      # asceds propagate requests
      cat <<< "7 * * * * root ${CRONEXEC} -q > /dev/null 2>&1" >> ${CRONF}
   else
      asceds-error "The script for unmanaged web interface requests 
          ${CRONEXEC} was not found."
   fi
else
   asceds-echo "Cron file ${CRONF} exists, please tune it to your needs"
fi

# configure web users: asceds-web-user
# YE=''
# echo "Configure web users for simple authentication? [y/N] "
# read YE
# if [ "${YE}" == "y" ] || [ "${YE}" == "Y" ] ; then
#    asceds-web-user -p
# fi
echo
echo "Web users can be managed for simple or shibboleth authentication"
echo "using the asceds-web-user command."
echo

