#!/bin/sh # # Author: Jason Haar # Date: 09-Nov-2004 # Version: 1.0 # Copyright: GPL # # This script simply checks the status of the certificates used by # Qmail with Frederik Vermeulen's TLS patch - to ensure they are # valid, non-expired certs with the appropriate KeyUsage extensions # required to get their jobs done. # This script can be run on a nightly basis to check the cert status. # Note that when a cert is "bad" (typically because it's # expired), we send a warning via syslog. # If the cert is bad, Qmail will STOP WORKING FOR NEW TLS SESSIONS. # # The point of this script is to tell you *why* qmail is not working. LOGGER="logger -i -t qmail-tls-check_certs" dirlist="/etc/qmail/control /var/qmail/control" for trydir in $dirlist ; do if test -d $trydir ; then dir=$trydir break fi done certlist="" for arg in "$@" ; do case $arg in -stunnel) certlist=/etc/stunnel/stunnel.pem ;; -starttls) if test -z "$dir" ; then 1>&2 echo "Sorry, can't find the control directory ($dirlist)" exit1 fi certlist="$dir/servercert.pem $dir/clientcert.pem" ;; *) 1>&2 echo "Unrecognized verbiage: '$arg'" exit 1 esac done if test -z "$certlist" ; then if test -z "$dir" ; then 1>&2 echo "Cannot find any control directory ($dirlist)" exit 1 fi certlist="$dir/servercert.pem $dir/clientcert.pem" fi for cert in $certlist ; do if ! test -f "$cert"; then echo "Certificate missing: $cert" else #First, check that it's a valid cert for the task TEMP_PURPOSE=`openssl x509 -in $cert -noout -purpose 2>/dev/null` if [ "$?" != "0" ]; then echo "$cert is a broken cert." $LOGGER "$cert is a broken cert." continue fi #Now check it hasn't expired TEMP_DATE=$( openssl x509 -in $cert -noout -dates 2>/dev/null | \ grep -i after|cut -d= -f2 ) EXPIRE_IN_SECS=`date +%s --date $TEMP_DATE 2>/dev/null` if [ "`echo $EXPIRE_IN_SECS|egrep '^[0-9]+$'`" != "" ]; then NOW_IN_SECS=`date +%s 2>/dev/null` if [ "`echo $NOW_IN_SECS|egrep '^[0-9]+$'`" != "" ]; then if [ $NOW_IN_SECS -gt $EXPIRE_IN_SECS ]; then echo "$cert has EXPIRED." $LOGGER "$cert has EXPIRED." continue fi fi fi if [ "`echo $cert|grep server`" != "" ] ; then if [ "_$( echo $TEMP_PURPOSE | \ egrep -i '(any purpose|server).* yes' )" = "_" ]; then echo "$cert is NOT a server cert." $LOGGER "$cert is NOT a server cert." continue fi fi if [ "`echo $cert|grep client`" != "" ] ; then if [ "_$( echo $TEMP_PURPOSE | egrep -i '(any purpose|client).* yes' )" = "_" ]; then echo " $cert is NOT a client cert." $LOGGER "$cert is NOT a client cert." continue fi fi fi done