slackware-current/source/n/openssl/certwatch

136 lines
4.1 KiB
Text
Raw Normal View History

#!/bin/sh
#
# Will check all certificates stored in $CERTDIR for their expiration date,
# and will display (if optional "stdout" argument is given), or mail a warning
# message to $MAILADDR (if script is executed without any parameter
# - unattended mode suitable for cron execution) for each particular certificate
# that is about to expire in time less to, or equal to $DAYS after this script
# has been executed, or if it has already expired.
# This stupid script (C) 2006,2007 Jan Rafaj
########################## CONFIGURATION SECTION BEGIN #########################
# Note: all settings are mandatory
# Warning will be sent if a certificate expires in time <= days given here
DAYS=7
# E-mail address where to send warnings
MAILADDR=root
# Directory with certificates to check
CERTDIR=/etc/ssl/certs
# Directory where to keep state files if this script isnt executed with "stdout"
STATEDIR=/var/state/certwatch
########################### CONFIGURATION SECTION END ##########################
PATH=/bin:/usr/bin:/sbin:/usr/sbin
DAY_IN_SECS=$((60*60*24))
DATE_CURRENT=$(date '+%s')
# Ensure $STATEDIR exists:
if [ ! -d $STATEDIR ]; then
mkdir -p $STATEDIR
fi
usage()
{
echo "Usage: $0 [stdout]"
echo
echo "Detailed description and configuration is embedded within the script."
exit 0
}
message()
{
cat << EOF
WARNING: certificate $certfile
is about to expire in time equal to or less than $DAYS days from now on,
or has already expired - it might be a good idea to obtain/create new one.
EOF
}
message_mail()
{
message
cat << EOF
NOTE: This message is being sent only once.
A lock-file
$STATEDIR/certwatch-mailwarning-sent-$certfilebase
has been created, which will prevent this script from mailing you again
upon its subsequent executions by crond. You dont need to care about it;
the file will be auto-deleted as soon as you'll prolong your certificate.
EOF
}
unset stdout
case $# in
0) ;;
1) if [ "$1" = "-h" -o "$1" == "--help" ]; then
usage
elif [ "$1" = "stdout" ]; then
stdout=1
else
usage
fi
;;
*) usage ;;
esac
for dir in $STATEDIR $CERTDIR ; do
if [ ! -d $dir ]; then
echo "ERROR: directory $dir does not exist"
exit 1
fi
done
for binary in basename date find grep mail openssl touch ; do
if [ ! \( -x /usr/bin/$binary -o -x /bin/$binary \) ]; then
echo "ERROR: /usr/bin/$binary not found"
exit 1
fi
done
find $CERTDIR -type f -maxdepth 1 | while read certfile ; do
if [ "$certfile" != "/etc/ssl/certs/ca-certificates.crt" ]; then
certfilebase="$(basename "$certfile")"
inform=PEM
echo "$certfile" | grep -q -i '\.net$'
if [ $? -eq 0 ]; then
# This is based purely on filename extension, so may give false results.
# But lets assume noone uses NET format certs today, ok?
continue
fi
echo "$certfile" | grep -q -i '\.der$'
if [ $? -eq 0 -o "$(file "$certfile" | egrep '(ASCII|PEM)')" == "" ]; then
inform=DER
fi
# We wont use '-checkend' since it is not properly documented (as of
# OpenSSL 0.9.8e).
DATE_CERT_EXPIRES=$(openssl x509 -in "$certfile" -inform $inform -noout -enddate | sed 's/^notAfter=//')
DATE_CERT_EXPIRES=$(date -d"$DATE_CERT_EXPIRES" +%s)
if [ $(($DATE_CERT_EXPIRES - $DATE_CURRENT)) -le $(($DAYS * $DAY_IN_SECS)) ]
then
if [ $stdout ]; then
message
else
if [ ! -f $STATEDIR/certwatch-mailwarning-sent-"$certfilebase" ]; then
subject="$0: certificate $certfile expiration warning"
message_mail | mail -r "certwatch@$HOSTNAME" \
-s "$subject" \
$MAILADDR 2>/dev/null
# echo "Mail about expiring certificate $certfile sent to $MAILADDR."
# echo "If you need to send it again, please remove lock-file"
# echo "$STATEDIR/certwatch-mailwarning-sent-$certfilebase ."
# echo
fi
touch $STATEDIR/certwatch-mailwarning-sent-"$certfilebase"
fi
else
if [ ! $stdout ]; then
if [ -f $STATEDIR/certwatch-mailwarning-sent-"$certfilebase" ]; then
rm $STATEDIR/certwatch-mailwarning-sent-"$certfilebase"
fi
fi
fi
fi
done