#!/bin/sh
# ssl_check v1.0.4  (c) 20.6.2011 by Andreas Ley  (u) 24.5.2024
# Check certificates

# Debugging:
# To run this script manually, call ssl_check as root and with the FQDNs to process as arguments
# E.g.: sudo ssl_check <FQDN>
# Logs of runs of this script are stored as /var/www/log/ssl_check/<PID>.*

PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
export PATH

# DEBUG
mkdir -p /var/www/log/ssl_check && chown 0:9998 /var/www/log/ssl_check && chmod 750 /var/www/log/ssl_check && exec >/var/www/log/ssl_check/$$.out 2>/var/www/log/ssl_check/$$.err && set -x && printenv >/var/www/log/ssl_check/$$.env && find /var/www/log/ssl_check -mtime +7 -delete

days=42

usage()
{
	echo "Usage: `basename $0` [-v] [-d days] fqdn [...]" >&2
	echo "-v  verbose mode" >&2
	exit 1
}

set -- `getopt hxvd: $*` || usage

trace=false
verbose=false
while :; do
	case $1 in
		-h)	sed '1d;s/^# *//;/^$/q' $0; usage;;
		-x)	set -x; trace=true; D="-D"; shift;;
		-v)	verbose=true; v="-v"; shift;;
		-d)	days="$2"; shift 2;;
		--)	shift; break;;
	esac
done

test $# -eq 0 && usage

root="/var/www"

# For the transit, consider all clusters
#servers="/etc/apache2/servers"
#servers="/etc/cluster/nodes"
servers="/etc/cluster/nodes.all"

ini='/etc/apache2/vhost.ini'

identity=$(sed -n '/^\[shibboleth\]/,/^\[/s/^identity[[:space:]]*=[[:space:]]*//p' "${ini}")
auth=$(sed -n '/^\[shibboleth\]/,/^\[/s/^auth[[:space:]]*=[[:space:]]*//p' "${ini}")

if test -s '/etc/apache2/servers'; then
	# Determine local and (alphabetically) first node
	localnode="`hostname --fqdn`"
	firstnode=`awk '{print$1}' "${servers}" | egrep -v '(test|legacy)' | fping -a -r1 2>/dev/null | sort | head -1`

	# Don't run but on the first available node
	test "${localnode}" = "${firstnode}" || exit 0
fi

for fqdn do
	ssl="${root}/${fqdn}/conf/ssl"

	#if test ! -s "/var/lib/acme/live/${fqdn}/cert"; then
	# Check for ACME cert if we already have one, or if an explicit type is configured (which usually is dns-01 and thus stops vhost from getting a certificate right away)
	if test -s "${ssl}/dehydrated/cert.pem" -o -s "${ssl}/dehydrated/type"; then
		if test -x /usr/bin/dehydrated; then
			# We're assuming dehydrated uses RENEW_DAYS=30
			# WATCH OUT! Don't use errmail apache@scc.kit.edu -- acme_cert â¦ â it tries to exec "--" :-(
			openssl x509 -in "${ssl}/dehydrated/cert.pem" -checkend 2592000 -noout >/dev/null 2>&1 || \
				errmail -- apache@scc.kit.edu acme_cert -D dehydrated "${fqdn}"
		fi
	else

		# Check for CA-certified certificate to overwrite self-signed one
		owner -i "${ssl}" -- \
			ssl-request ${D} ${v} -A -u -K "${ssl}/server.key"
		test $? -eq 2 -a -s '/etc/apache2/servers' && \
			dist -v -u -s all "${ssl}"
			#dist -q -u -s all "${ssl}"

		# Check for expiring certificate
		# Upgrade to MustStaple
		# Check crt: 1.3.6.1.5.5.7.1.24
		owner -i "${ssl}" -- \
			ssl-request ${D} ${v} -A -e "${days}" -U -u -K "${ssl}/server.key"
		test $? -ge 2 -a -s '/etc/apache2/servers' && \
			dist -v -u -s all "${ssl}"
			#dist -q -u -s all "${ssl}"
	fi

	# Check for expiring shibboleth certificate
	if test -s "${ssl}/sp.key"; then
			# DFN AAI wants max 39 months for www.bwhpc-c5.de
		owner -i "${ssl}" -- \
			ssl-request ${D} ${v} -A -e "${days}" -g 1092 -K "${ssl}/sp.key"
		retval=$?
		test $retval -ge 2 -a -s '/etc/apache2/servers' && \
			dist -v -u -s all "${ssl}"
			#dist -q -u -s all "${ssl}"
		test $retval -eq 2 && \
			ssh -o 'BatchMode=yes' -a -k -x -q -i "${identity}" "${auth}" create "${fqdn}" <"${ssl}/sp.crt"
	fi

	# A manual dist could delete the *.new files before we were able to get the new certificate if we distribute only after the new certificate is available :(
	#ssl-request -e "${days}" -u -K "${ssl}/server.key" -a "dist -s all ${ssl}"
done

exit 0
