First commit

This commit is contained in:
Jonny007-MKD 2022-03-06 14:52:00 +01:00
commit 65a2d6d8bd
4 changed files with 369 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/test/tmp/

235
check_gpg_key_expiration.sh Executable file
View File

@ -0,0 +1,235 @@
#!/bin/bash
function echoerr { echo "$@" 1>&2; }
function checkEnvironment {
### Check the environment ###
if ! which gpg 2>&1 >/dev/null; then
echoerr "Missing gpg binary"
exit 3
fi
# Command to download a file
DOWNLOAD=""
if which curl 2>&1 >/dev/null; then
DOWNLOAD="curl -s -o "
elif which wget 2>&1 >/dev/null; then
DOWNLOAD="wget -o /dev/null -O "
else
echoerr "Missing curl or wget binary"
exit 3
fi
# Command to get information about all subkeys
GPG_SHOW="gpg --with-colon --fixed-list-mode --show-keys"
}
function parseArguments {
### Parse arguments ###
# We require a URL
# and have default values for expiration durations
URL=""
DEBUG=false
WARN=7 # days
CRIT=2 # days
while [[ $# -gt 0 ]]; do
case $1 in
-u|--url) URL="$2"; shift;;
-w|--warn) WARN=$2; shift;;
-c|--crit) CRIT=$2; shift;;
-d|--debug) DEBUG=true;;
-?|--help)
echo "Check gpg expiration date. Arguments:"
echo "--url URL: Where to find the GPG key"
echo "--warn DAYS: Warning threshold (integer in days)"
echo "--crit DAYS: Critical threshold (integer in days)"
exit 0
;;
*)
echoerr "Unknown argument: $1"
exit 3
;;
esac
shift
done
if [ -z "$URL" ]; then
echoerr "Missing url argument (--url)"
exit 3
fi
WARN_s=$(($WARN*24*60*60))
CRIT_s=$(($CRIT*24*60*60))
NOW=$(date '+%s')
}
function log {
if $DEBUG; then
echo " > $@"
fi
}
function logLine {
if $DEBUG; then
echo " : $@"
fi
}
RESULT=0 # 0:OK 1:WARN 2:CRIT
RESULT_INFO="" # Additional information
function clearResultInfoIfResultLessThan {
# if we increase the result level/severity,
# we want to clear RESULT_INFO to only show the most important information
if [ $RESULT -lt $1 ]; then
RESULT_INFO=""
fi
}
function expired {
# This function is called if a key expired
# we set RESULT to CRITICAL and prepend our information message
local key=$1
local expirationDate=$2
local msg
log "$key expired at $expirationDate -> RESULT=2"
clearResultInfoIfResultLessThan 2
RESULT=2
msg="${RESULT_INFO}Key $key expired at $(date '+%Y-%m-%dT%H:%M:%S' --date @$expirationDate)"
if [ -n "$RESULT_INFO" ]; then
RESULT_INFO="$msg. $RESULT_INFO"
else
RESULT_INFO=$msg
fi
}
function expire_crit {
# This function is called if a key is going to expire soon (critical)
# we set RESULT to CRITICAL and append our information message
local key=$1
local expirationDate=$2
log "$key expires at $expirationDate (critical) -> RESULT=2"
clearResultInfoIfResultLessThan 2
RESULT=2
if [ -n "$RESULT_INFO" ]; then
RESULT_INFO="$RESULT_INFO. "
fi
RESULT_INFO="${RESULT_INFO}Key $key will expire at $(date '+%Y-%m-%dT%H:%M:%S' --date @$expirationDate)"
}
function expire_warn {
# This function is called if a key is going to expire soon (warning)
local key=$1
local expirationDate=$2
log "$key expires at $expirationDate (critical) -> RESULT=1"
clearResultInfoIfResultLessThan 1
if [ $RESULT -le 1 ]; then
RESULT=1
if [ -n "$RESULT_INFO" ]; then
RESULT_INFO="$RESULT_INFO. "
fi
RESULT_INFO="${RESULT_INFO}Key $key will expire at $(date '+%Y-%m-%dT%H:%M:%S' --date @$expirationDate)"
fi
}
METRICS=""
function metrics {
# This function is called for every subkey to generate the METRICS string
local key=$1
local expirationDate=$2
local remaining_s=$3
METRICS="${METRICS}'$key expiration date'=$(date '+%Y-%m-%dT%H:%M:%S' --date @$expirationDate) "
METRICS="${METRICS}'$key remaining'=${remaining_s}s;${WARN_s}s;${CRIT_s}s "
}
function parseLine {
# Parse a line of GPG's output
# https://www.gnupg.org/documentation/manuals/gnupg-devel/Unattended-GPG-key-generation.html
local remaining_s
local recordType validity keyLength keyAlgorithm keyID creationDate expirationDate certSN ownertrust userID signatureClass keyCapabilities issuerCertFingerprint flags tokenSN hashAlgorithm curveName complianceFlags lastUpdate origin comment
#logLine "$@"
IFS=: read -r recordType validity keyLength keyAlgorithm keyID creationDate expirationDate certSN ownertrust userID signatureClass keyCapabilities issuerCertFingerprint flags tokenSN hashAlgorithm curveName complianceFlags lastUpdate origin comment < <(echo "$@")
log "keyID = $keyID, type = $recordType, expirationDate = $expirationDate"
if [ -n "$expirationDate" ]; then
remaining_s=$(($expirationDate-$NOW))
metrics $keyID $expirationDate $remaining_s
if [ $remaining_s -le 0 ]; then
expired $keyID $expirationDate
elif [ $remaining_s -le $CRIT_s ]; then
expire_crit $keyID $expirationDate
elif [ $remaining_s -le $WARN_s ]; then
expire_warn $keyID $expirationDate
fi
fi
}
function getAndParseKey {
local line
local infile
# for appropriate error handling we cannot use pipes (at least I don't know how to)
TMPFILE=$(mktemp) || exit 3
#trap 'rm -f "$TMPFILE"' RETURN
#trap 'rm -f "$TMPFILE"' EXIT
# If the URL is a local path, use it as input to GPG_SHOW
if [ ! -f "$URL" ]; then
log "Downloading $URL"
$DOWNLOAD "$TMPFILE" "$URL"
exit=$?
if [ $exit -ne 0 ]; then
echo "ERROR - Downloading failed with $exit"
exit 3
fi
infile="$TMPFILE"
else
log "Using local file $URL"
infile="$URL"
fi
# Process with GPG
cat "$infile" | $GPG_SHOW > "$TMPFILE"
exit=$?
if [ $exit -ne 0 ]; then
echo "ERROR - gpg failed with $exit"
exit 3
fi
while read -r line; do
parseLine "$line"
done < "$TMPFILE"
trap - EXIT
}
function printResult {
if [ $RESULT -eq 2 ]; then
echo -n "CRITICAL - $RESULT_INFO"
elif [ $RESULT -eq 1 ]; then
echo -n "WARNING - $RESULT_INFO"
else
echo -n "OK"
fi
echo -n " | "
echo -n "$METRICS"
}
checkEnvironment
parseArguments "$@"
getAndParseKey
printResult
exit $RESULT

BIN
test/expiredkey Normal file

Binary file not shown.

133
test/test.sh Normal file
View File

@ -0,0 +1,133 @@
cd $(dirname $0)
function echoerr { echo "$@" 1>&2; }
if [ -d tmp ]; then
rm -rf tmp
fi
mkdir tmp
chmod 700 tmp
function generateKey {
local expiry=$1
cat <<EOF | gpg --gen-key --homedir tmp --batch
%pubring tmp/pubkey
%no-protection
%transient-key
Key-Type: 1
Key-Length: 1024
Name-Real: Test
Name-Email: bla@test
Subkey-Type: 1
Subkey-Length: 1024
Expire-Date: ${expiry}
EOF
}
function testNotExpired {
generateKey 8d
output=$(../check_gpg_key_expiration.sh -u tmp/pubkey -w 7 -c 2)
exit=$?
if [ $exit -ne 0 ]; then
echoerr "testNotExpired failed. Exit code mismatch"
echoerr "Expected: 0"
echoerr "Actual: $exit"
fi
if [[ "$output" != "OK | "* ]]; then
echoerr "testNotExpired failed. Output did not match!"
echoerr "Expected: OK | *"
echoerr "Actual: $output"
fi
echo && echo
}
function testExpireWarn {
generateKey 3d
output=$(../check_gpg_key_expiration.sh -u tmp/pubkey -w 7 -c 2)
exit=$?
if [ $exit -ne 1 ]; then
echoerr "testExpireWarn failed. Exit code mismatch"
echoerr "Expected: 1"
echoerr "Actual: $exit"
fi
if [[ "$output" != "WARNING - Key "*" will expire at "*" | "* ]]; then
echoerr "testExpireWarn failed. Output did not match!"
echoerr "Expected: WARNING - Key **************** will expire at *"
echoerr "Actual: $output"
fi
echo && echo
}
function testExpireCritical {
generateKey 1d
output=$(../check_gpg_key_expiration.sh -u tmp/pubkey -w 7 -c 2)
exit=$?
if [ $exit -ne 2 ]; then
echoerr "testExpireCritical failed. Exit code mismatch"
echoerr "Expected: 2"
echoerr "Actual: $exit"
fi
if [[ "$output" != "CRITICAL - Key "*" will expire at "*" | "* ]]; then
echoerr "testExpireCritical failed. Output did not match!"
echoerr "Expected: CRITICAL - Key **************** will expire at *"
echoerr "Actual: $output"
fi
echo && echo
}
function testExpired {
output=$(../check_gpg_key_expiration.sh -u expiredkey -w 7 -c 2)
exit=$?
if [ $exit -ne 2 ]; then
echoerr "testExpired failed. Exit code mismatch"
echoerr "Expected: 2"
echoerr "Actual: $exit"
fi
if [[ "$output" != "CRITICAL - Key DAD15AEAD4609B87 expired at 2022-03-07T14:32:37. Key 2A8350447459F0C6 expired at 2022-03-07T14:32:37 | 'DAD15AEAD4609B87 expiration date'=2022-03-07T14:32:37 'DAD15AEAD4609B87 remaining'="*";604800s;172800s '2A8350447459F0C6 expiration date'=2022-03-07T14:32:37 '2A8350447459F0C6 remaining'="*";604800s;172800s" ]]; then
echoerr "testExpired failed. Output did not match!"
echoerr "Expected: CRITICAL - Key DAD15AEAD4609B87 expired at 2022-03-07T14:32:37. Key 2A8350447459F0C6 expired at 2022-03-07T14:32:37 | 'DAD15AEAD4609B87 expiration date'=2022-03-07T14:32:37 'DAD15AEAD4609B87 remaining'=*;604800s;172800s '2A8350447459F0C6 expiration date'=2022-03-07T14:32:37 '2A8350447459F0C6 remaining'=*;604800s;172800s"
echoerr "Actual: $output"
fi
echo && echo
}
function testFileDoesNotExist {
output=$(../check_gpg_key_expiration.sh -u this_file_does_not_exist_blablabla_43t0zq84whtrshq3tptsth)
exit=$?
if [ $exit -ne 3 ]; then
echoerr "testFileDoesNotExist failed. Exit code mismatch"
echoerr "Expected: 3"
echoerr "Actual: $exit"
fi
if [[ "$output" != "ERROR - Downloading failed with "* ]]; then
echoerr "testFileDoesNotExist failed. Output did not match!"
echoerr "Expected: ERROR - Downloading failed with *"
echoerr "Actual: $output"
fi
}
function testFileIsNotAGpgKey {
output=$(../check_gpg_key_expiration.sh -u test.sh)
exit=$?
if [ $exit -ne 3 ]; then
echoerr "testFileIsNotAGpgKey failed. Exit code mismatch"
echoerr "Expected: 3"
echoerr "Actual: $exit"
fi
if [[ "$output" != "ERROR - gpg failed with "* ]]; then
echoerr "testFileIsNotAGpgKey failed. Output did not match!"
echoerr "Expected: ERROR - gpg failed with *"
echoerr "Actual: $output"
fi
}
testNotExpired
testExpireWarn
testExpireCritical
testExpired
testFileDoesNotExist
testFileIsNotAGpgKey