#!/bin/bash

# cert-download: Obtain Let's Encrypt SSL certificates from the master store

set -o errexit
set -o nounset
set -o pipefail
#set -o xtrace

# The list of SOE4 services that may need a *reload* after updating a cert
SERVICE_LIST=( haproxy nginx apache2 lighttpd stunnel postfix courier-imap-ssl courier-pop-ssl )

if [[ $( whoami ) != 'root' ]]; then
    echo "ERROR: This script must run as root."
    exit 1
fi

STORE_HOST="cert.clearcable.net"
STORE_USER="certificates"
STORE_PASS="NRlGieBAKs1qC9Go30mowdajz54wxQ6N"
STORE_URL="https://${STORE_USER}:${STORE_PASS}@${STORE_HOST}"

# Get customer code from filename
_SELF="${0##*/}"
CUSTOMER_CODE="${_SELF#*_}"

if [ -z "${CUSTOMER_CODE}" ]; then
    echo "Customer code not set in filename. Ensure you use '_' instead of '.' in the code part for proper run-parts support."
    echo "   Eg: ${_SELF}<customer_code>"
    exit 1
fi

DOMAIN="${CUSTOMER_CODE}.clearcable.net"
DOMAIN_NICENAME="$( sed 's/\./_/g' <<<"${DOMAIN}" )"
CERT_NAME="star_${DOMAIN_NICENAME}"

# Attempt to download the checksum file; this is our test if we have a valid cert
CHECKSUM_FILENAME="${CERT_NAME}.sha256sum"
REMOTE_CHECKSUM_RAW="$( wget -q -O - ${STORE_URL}/${DOMAIN_NICENAME}/${CHECKSUM_FILENAME} )"
REMOTE_CHECKSUM_VALUE="$( awk '{ print $1 }' <<<"${REMOTE_CHECKSUM_RAW}" )"
ARCHIVE_FILENAME="$( awk '{ print $2 }' <<<"${REMOTE_CHECKSUM_RAW}" )"
echo "SSL Certificate Archive: ${ARCHIVE_FILENAME}"

do_download() {
    # Download the certificate archive and checksum (for later validation)
    wget -q -O /etc/ssl/${DOMAIN_NICENAME}/${ARCHIVE_FILENAME}  ${STORE_URL}/${DOMAIN_NICENAME}/${ARCHIVE_FILENAME}
    wget -q -O /etc/ssl/${DOMAIN_NICENAME}/${CHECKSUM_FILENAME} ${STORE_URL}/${DOMAIN_NICENAME}/${CHECKSUM_FILENAME}
    
    # Verify the checksum matches the value
    CALCULATED_CHECKSUM="$( sha256sum /etc/ssl/${DOMAIN_NICENAME}/${ARCHIVE_FILENAME} | awk '{ print $1 }' )"
    DOWNLOADED_CHECKSUM="$( cat /etc/ssl/${DOMAIN_NICENAME}/${CHECKSUM_FILENAME} | awk '{ print $1 }' )"
    if [[ ! ${CALCULATED_CHECKSUM} == ${DOWNLOADED_CHECKSUM} ]]; then
        echo "ERROR: Downloaded archive does not match its checksum."
        exit 1
    fi
    
    # Extract the certificate archive
    tar -xzf /etc/ssl/${DOMAIN_NICENAME}/${ARCHIVE_FILENAME} -C /etc/ssl/${DOMAIN_NICENAME}/

    # Correct permissions on extracted files
    chown -R root:ssl-cert /etc/ssl/${DOMAIN_NICENAME}/
    chmod 440 /etc/ssl/${DOMAIN_NICENAME}/${CERT_NAME}.{key,combined,combined_cacert}
    chmod 600 /etc/ssl/${DOMAIN_NICENAME}/${ARCHIVE_FILENAME}
}

do_svcrefresh() {
    for SERVICE in ${SERVICE_LIST[@]}; do
        if [[ -x /usr/sbin/service ]]; then
            if /usr/sbin/service ${SERVICE} status &>/dev/null; then
                /usr/sbin/service ${SERVICE} reload
            fi
        else
            if [[ -x /etc/init.d/${SERVICE} ]]; then
                /etc/init.d/${SERVICE} reload
            fi
        fi
    done
}

# Check if a cert archive already exists; if not, it's a fresh download; if so, it's a refresh
if [[ ! -f /etc/ssl/${DOMAIN_NICENAME}/${CHECKSUM_FILENAME} ]]; then
    # Create the target directory
    mkdir -p /etc/ssl/${DOMAIN_NICENAME}
    # Download the cert
    do_download
else
    # Verify if the checksum value matches the stored checksum
    EXISTING_CHECKSUM="$( cat /etc/ssl/${DOMAIN_NICENAME}/${CHECKSUM_FILENAME} | awk '{ print $1 }' )"
    if [[ ${EXISTING_CHECKSUM} == ${REMOTE_CHECKSUM_VALUE} ]]; then
        echo "Local archive matches remote archive; update not required."
        exit 0
    fi
    # Download the cert
    do_download
    # Refresh any services that might need a reload for the updated cert
    do_svcrefresh
fi

# vim: cindent:expandtab:number:shiftwidth=4:tabstop=4
