#!/bin/bash
# send cert files back to the clients

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

ASCEDSCONF='local site certbot'
ASCEDSLIBS='utils'

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

. ${SPATH}/asceds-head

asceds-send-cert-usage()
{
  cat << ENDUSAGE

Usage: asceds-send-cert [-h] [-q] -c <client_name>

Copies new site config and certificate files to the client;
it does not check for the type of client, attempts transfer anyway.
-h --> display usage and exit
-q --> no question asked; sends output to the logs in ${ASCEDSLOGDIR}/
-c <client_name> --> transfer the certificate files to client_name; 
                     print usage if missing

Checks for a new site config file (flagged by <client_name>:.newsiteconf).
SCP the new site config file to asceds@<client_name>:.
Removes the trigger for uploading the site config file.
Sets the trigger for site config file update <client_name>:.site-reconf.
Checks if new certificate files exist (flagged by <client_name>:.newcerts).
SCP the new certificate files to asceds@<client_name>:certs/.
Removes the trigger for uploading new certificate files.
Sets the trigger for service reconfiguration <client_name>:.asceds-reconf.
If the client is unreachable, sets a flag ~asceds/down/<client_name> and
   emails to ALARM; if client is reachable and the flag exists, removes it. 

ENDUSAGE
exit 0
}

# output to terminal by default
QUIETRUN=""

# initialize CLIENT_NAME
CLIENT_NAME=''

# general validation and parse of the command line
if  [ -z "${ARGS}" ] ; then
   asceds-send-cert-usage
else
   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
         asceds-send-cert-usage
      elif [ "${ARG}" == "-q" ] ; then
         shift
         asceds-exec-noninteractive "$*"
         # bring other scripts in non-interactive mode
         QUIETRUN="y"
      elif [ "${ARG}" == "-c" ] ; then
         shift
         if [[ "$1" != -* ]] && [ -n "$1" ] ; then
            CLIENT_NAME=$( cat <<< $1 | tr '[:upper:]' '[:lower:]' )
            asceds-expand-hostname "${CLIENT_NAME}" && \
               CLIENT_NAME="${ASCEDS_FQDN}"
            asceds-validate-fqdn "${CLIENT_NAME}" || \
               asceds-error "Invalid client FQDN ${CLIENT_NAME}"
         fi
      else
         shift
      fi
   done
fi
if [ -z "${CLIENT_NAME}" ] ; then
   asceds-send-cert-usage 
fi
# run as asceds only
asceds-run-asasceds

# checks on client name
if [ -z "${CLIENT_NAME}" ] || [[ "${CLIENT_NAME}" = "-"* ]] ; then
   asceds-error "No client name passwed as argument"
else
   asceds-echo "Sending certificate files to ${CLIENT_NAME}"
fi

if [ -d "${ASCEDSHOMEDIR}/${CLIENT_NAME}" ] ; then
   CLIENTDOWN=''
   if [ -r "${ASCEDSHOMEDIR}/${CLIENT_NAME}/.newsiteconf" ] && \
      [ -r "${ASCEDSHOMEDIR}/${CLIENT_NAME}/asceds-site.conf" ] ; then
      # new site config file flagged
      # scp site config file to ${CLIENT_NAME}
      eval ${SCP} ${ASCEDSHOMEDIR}/${CLIENT_NAME}/asceds-site.conf \
           asceds@${CLIENT_NAME}: || CLIENTDOWN='yes'

      # if client can be accessed
      if [ -z "${CLIENTDOWN}" ] ; then
         CLIENTDOWN='up'
         # delete .newcerts flag if transfer was successful 
         ${RM} -f ${ASCEDSHOMEDIR}/${CLIENT_NAME}/.newsiteconf
         # trigger reconfiguration on the client
         eval ${SSH} asceds@${CLIENT_NAME} "touch ~asceds/.site-reconf"
      fi
   fi 

   if [ -r "${ASCEDSHOMEDIR}/${CLIENT_NAME}/.newcerts" ] ; then
      # are there any certificate files to be sent?
      if [ ! -r "${ASCEDSHOMEDIR}/${CLIENT_NAME}/privkey.pem" ] || \
         [ ! -r "${ASCEDSHOMEDIR}/${CLIENT_NAME}/fullchain.pem" ] || \
         [ ! -r "${ASCEDSHOMEDIR}/${CLIENT_NAME}/cert.pem" ] ; then
         asceds-error "Certificate files not found in ${ASCEDSHOMEDIR}/${CLIENT_NAME}/"
      fi
   
      # switch filesystem to rw state for pikvm systems
      ${SSH} asceds@${CLIENT_NAME} \
         'if [ -x /usr/bin/rw ] ; then sudo /usr/bin/rw ; fi' || CLIENTDOWN='yes'

      # if client can be accessed
      if [ -z "${CLIENTDOWN}" ] || [ "${CLIENTDOWN}" == 'up' ] ; then
         CLIENTDOWN='up'

         # scp certificate files to ${CLIENT_NAME}
         eval ${SCP} ${ASCEDSHOMEDIR}/${CLIENT_NAME}/*.pem \
              asceds@${CLIENT_NAME}:certs/ || CLIENTDOWN='yes'

         # if transfer was succesful
         if [ "${CLIENTDOWN}" == 'up' ] ; then
            # delete .newcerts flag if transfer was successful 
            ${RM} -f ${ASCEDSHOMEDIR}/${CLIENT_NAME}/.newcerts
            # trigger reconfiguration on the client
            eval ${SSH} asceds@${CLIENT_NAME} "touch ~asceds/.asceds-reconf"
            ## copy cert.conf used by the certificate manager back to the client
            #eval ${SCP} ${ASCEDSHOMEDIR}/${CLIENT_NAME}_cert.conf \
            #     asceds@${CLIENT_NAME}:cert.conf
         fi

         # switch filesystem to rw state for pikvm systems
         ${SSH} asceds@${CLIENT_NAME} \
            'if [ -x /usr/bin/ro ] ; then sudo /usr/bin/ro ; fi' 
      fi  
   fi

   if [ "${CLIENTDOWN}" == 'yes' ] ; then
      if [ ! -d "${ASCEDSHOMEDIR}/down" ] ; then
         mkdir ${ASCEDSHOMEDIR}/down
      fi
      asceds-warning "Client ${CLIENT_NAME} cannot be accessed for writing"
      # send email to ALARM
      if [ ! -r "${ASCEDSHOMEDIR}/down/${CLIENT_NAME}" ] ; then
         touch ${ASCEDSHOMEDIR}/down/${CLIENT_NAME}
         asceds-mailto-alarm "Fully managed client ${CLIENT_NAME} disfunctional" \
                          "${ASCEDSLOGF}"
      fi
   elif [ "${CLIENTDOWN}" == 'up' ] && \
        [ -r "${ASCEDSHOMEDIR}/down/${CLIENT_NAME}" ] ; then
      ${RM} -f ${ASCEDSHOMEDIR}/down/${CLIENT_NAME}
   fi
else
   asceds-error "No client dir ${ASCEDSHOMEDIR}/${CLIENT_NAME}"
fi
