#!/bin/bash
# configures/updates site config file ${ASCEDSETCDIR}/asceds-site.conf

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-update-siteconfig-usage()
{
  cat << ENDUSAGE

Configures/updates site config file ${ASCEDSETCDIR}/asceds-site.conf
Usage: asceds-update-siteconfig [-h] [-q] [-s] [-c]
-h --> display usage and exit
-q --> no question asked; sends output to the logs in ${ASCEDSLOGDIR}/
-s --> create/update the site config file on the certificate manager
-c --> reconfigure client (-s and -c are mutually exclusive)

On the certificate manager:
  Creates/updates the site config file ${ASCEDSETCDIR}/asceds-site.conf.
    Allows ASCEDSCRTMGR change only if ran from asceds-certmanager-setup.
    If certificate manager name is a CNAME (not fqdn of localhost): 
      checks if it resolves to the same IP address;
      adds it to hosts, postfix, openssl.cnf.
  Refreshes symlink to make site config file available by wget to clients.
  Copies the new site config file into ${ASCEDSHOMEDIR}/<managed_client>/ and
     adds .newsiteconf trigger to all managed clients except cert manager itself.
  On the cert manager, copies the new site config file into ${ASCEDSHOMEDIR}/.
On the client (no prompts in quiet mode):
  Certificate manager URL priority: ${ASCEDSALTCRTMGR}, ${ASCEDSCRTMGR}, input.
  Retrieves the site config file from the certificate manager URL
     to ${ASCEDSHOMEDIR}/asceds-site.conf.
  Parses and creates ${ASCEDSETCDIR}/asceds-site.conf.
  Uses the site ssh public key to create/update authorized_keys.

ENDUSAGE
exit 0
}

# output to terminal by default
QUIETRUN=''

# reconfigure server?
ASCEDSRECONFSRV=''

# reconfigure client?
ASCEDSRECONFCLIENT=''

# 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-update-siteconfig-usage
   elif [ "${ARG}" == "-q" ] ; then
      shift
      asceds-exec-noninteractive "$*"
      # bring other scripts in non-interactive mode
      QUIETRUN="y"
   elif [ "${ARG}" == "-s" ] ; then
      shift
      # create/update asceds-site.conf on the cert manager
      ASCEDSRECONFSRV='yes'
   elif [ "${ARG}" == "-c" ] ; then
      shift
      # pull asceds-site.conf from the certificate manager
      ASCEDSRECONFCLIENT='yes'
   else
      shift
   fi
done

# -s and -c are mutually exclusive
if [ -n "${ASCEDSRECONFSRV}" ] && [ -n "${ASCEDSRECONFCLIENT}" ] ; then
   asceds-error "Options -c and -s are mutually exclusive."
fi
# -q and -s are mutually exclusive
if [ -n "${ASCEDSRECONFSRV}" ] && [ -n "${QUIETRUN}" ] ; then
   asceds-error "Options -q and -s are mutually exclusive: \
      run as script only on client."
fi

# run as root only
asceds-run-asroot

# if on certificate manager
if [ -n "${ASCEDSRECONFSRV}" ] ; then

   # create site file ${ASCEDSETCDIR}/asceds-site.conf
   NEWSITEFILE=''
   if [ -f "${ASCEDSETCDIR}/asceds-site.conf" ] ; then
      asceds-echo "Site file ${ASCEDSETCDIR}/asceds-site.conf exists"
      cat ${ASCEDSETCDIR}/asceds-site.conf
      echo -n "Do you want to keep it? [Y/n] "
      read YE
      if [ "${YE}" == "n" ] || [ "${YE}" == "N" ] ; then
         NEWSITEFILE='yes'
      fi
   else
      NEWSITEFILE='yes'
   fi
   if [ -n "${NEWSITEFILE}" ] ; then
      asceds-echo "Creating a new site file"
      asceds-build-siteconf
   fi
fi

# if on client
TESTLOCAL='n'
if [ -r "${ASCEDSETCDIR}/asceds-site.conf" ] && \
   [ -r "${ASCEDSHOMEDIR}/asceds-site.conf" ] ; then
   # only on the cert manager asceds-site.conf is the same
   # in ${ASCEDSETCDIR} and ${ASCEDSHOMEDIR}
   TESTLOCAL="$( diff ${ASCEDSETCDIR}/asceds-site.conf \
      ${ASCEDSHOMEDIR}/asceds-site.conf )"
fi
if [ -n "${ASCEDSRECONFCLIENT}" ] && [ -n "${TESTLOCAL}" ] ; then 
   if [ -n "${ASCEDSALTCRTMGR}" ] ; then
      ASCEDSCRTMGR="${ASCEDSALTCRTMGR}"
   fi
   
   if [ -z "${ASCEDSCRTMGR}" ] && [ -n "${QUIETRUN}" ] ; then
      asceds-error "No certificate manager specified."
   fi 
   
   if [ -z "${QUIETRUN}" ] ; then
      if [ -n "${ASCEDSCRTMGR}" ] ; then
         YE=''
         echo -n "Is ${ASCEDSCRTMGR} the right site certificate manager? [Y/n] "
         read YE
         if [ "${YE}" == "n" ] ||  [ "${YE}" == "N" ] ; then
            ASCEDSCRTMGR=''
         fi
   
      fi
   
      # ask for the site certificate manager
      if [ -z "${ASCEDSCRTMGR}" ] ; then
         read -e -p "Name of the ASCEDS site certificate manager: " ASCEDSALTCRTMGR
         echo
         if [ "${ASCEDSALTCRTMGR}" != "${ASCEDSALTCRTMGR//[^-a-zA-Z0-9.]/}" ] ; then
            asceds-error "${ASCEDSALTCRTMGR} contains illegal characters"
         fi
         ASCEDSCRTMGR=$( cat <<< ${ASCEDSALTCRTMGR} | tr '[:upper:]' '[:lower:]' )
         asceds-validate-fqdn "${ASCEDSCRTMGR}" || \
            asceds-error "Provided cert manager name ${ASCEDSCRTMGR} not a FQDN."
         asceds-test-ping "${ASCEDSCRTMGR}" || \
            asceds-error "Provided cert manager ${ASCEDSCRTMGR} not accessible."
      fi
   fi

   # get the site config file from the certificate manager
   if [ -n "${ASCEDSCRTMGR}" ] ; then
      if [ -n "${SELFSIGNED}" ] ; then
         WGET="${WGET} --no-check-certificate"
      fi
      asceds-echo "Getting site config file from the site cert manager."
      cd ${ASCEDSHOMEDIR}/
      if [ -f "asceds-site.conf" ] ; then
         ${RM} -f asceds-site.conf
      fi
      ${WGET} --quiet https://${ASCEDSCRTMGR}/public/asceds-site.conf
      RET=$?
      if [ ${RET} != '0' ] ; then
         if [ -r "${ASCEDSWEBDIR}/html/public/asceds-site.conf" ] ; then
            # bypass for the cert manager if the website was not configured yet
            ${CP} -f ${ASCEDSWEBDIR}/html/public/asceds-site.conf .
         else
            asceds-error "Asceds site config file cannot be retrieved from the certificate manager ${ASCEDSCRTMGR}. Maybe use asceds-init -f "
         fi
      fi
      # ${ASCEDSHOMEDIR}/asceds-site.conf is there to stay as reference
      # it can be overwritten through a push from asceds@certmanager
      chown asceds:asceds ${ASCEDSHOMEDIR}/asceds-site.conf
      if [ -r "${ASCEDSHOMEDIR}/asceds-site.conf" ] ; then
         asceds-echo "Parsing the certificate manager site config file"
         asceds-parse-siteconf "${ASCEDSHOMEDIR}/asceds-site.conf"
         asceds-source-etcconf "${ASCEDSETCDIR}" "${ASCEDSCONF}"

         # use the site ssh public key to create authorized_keys
         asceds-echo "Creating authorized_keys for certificate manager access"
         if [ ! -d "${ASCEDSHOMEDIR}/.ssh" ] ; then
            mkdir ${ASCEDSHOMEDIR}/.ssh
            chown asceds:asceds ${ASCEDSHOMEDIR}/.ssh
            chmod 600 ${ASCEDSHOMEDIR}/.ssh
         fi
         cat <<< "${ASCEDSSSHPUBKEY}" > ${ASCEDSHOMEDIR}/.ssh/authorized_keys
                  
         TESTAUTHKEYS1=$( ${GREP} "^ssh-rsa" ${ASCEDSHOMEDIR}/.ssh/authorized_keys )
         TESTAUTHKEYS2=$( wc -l ${ASCEDSHOMEDIR}/.ssh/authorized_keys | cut -f1 -d" " )
         if [ -n "${TESTAUTHKEYS1}" ] && [ "${TESTAUTHKEYS2}" == "1" ] ; then
            asceds-echo "Asceds public ssh key successfully placed into \
                         authorized_keys"
            chown asceds:asceds ${ASCEDSHOMEDIR}/.ssh/authorized_keys
            chmod 600 ${ASCEDSHOMEDIR}/.ssh/authorized_keys
         else
            ${RM} -f authorized_keys
            asceds-warning "authorized_keys test results:"
            asceds-warning "${TESTAUTHKEYS1}"
            asceds-warning "${TESTAUTHKEYS2}" 
            asceds-error "Site public ssh key distributed by the web \
                          interface is improper."
         fi
      else
         asceds-error "No ASCEDS site config file downloaded. Mission impossible."
      fi
   else
      asceds-error "Cert manager undefined."
   fi
fi
