Skip to content

Instantly share code, notes, and snippets.

@borgand
Created September 26, 2013 13:54
Show Gist options
  • Save borgand/6714584 to your computer and use it in GitHub Desktop.
Save borgand/6714584 to your computer and use it in GitHub Desktop.
Round-trip check for Shibboleth and SimpleSAMLphp SSO setup. Uses sed to carve out tokens, so you must adapt to your HTML layout.
#!/bin/bash
# This script is used make a full roundtrip test to SimpleSAMLphp based SSO
# Exit statuses indicate problem and are suitable for usage in Nagios.
BASENAME=$(basename $0)
if [[ $1 == '-h' || $1 == '--help' ]]; then
cat <<EOF
USAGE: $BASENAME [URL] [test-string] [username] [password]
Default values:
URL - https://example.com/authtest
test-string - SUCCESS
username - test
password - test
Exit statuses (Nagios Plugin API):
0 - OK
1 - Warning (long overall time)
2 - Critical (could not finish AUTH)
3 - Unknown (process could not finish correctly)
EOF
fi
# The url to be tested
TESTSITE=${1:-https://example.com/authtest}
# A string that is supposed to exist on after successful authentication
TESTSTRING=${2:-SUCCESS}
USERNAME=${3:-test}
PASSWORD=${4:-test}
# How long is normal for total roundtrip (seconds)
WARNINGTIME=10
COOKIEJAR=$(mktemp /tmp/${BASENAME}.XXXXXX) || exit 3
starttime=$(date +"%s")
STATUS=0
# REQUEST #1: fetch URL for authentication page
HTML=$(curl -L -sS -c ${COOKIEJAR} -w 'LAST_URL:%{url_effective}' ${TESTSITE}) || STATUS=2
# Parse HTML to get the URL where to POST login (written out by curl itself above)
AUTHURL=$(echo $HTML | sed -e 's/.*LAST_URL:\(.*\)$/\1/')
AUTHSTATE=$(echo ${HTML} | sed -e 's/.*hidden[^>]*AuthState[^>]*value=[\"'\'']\([^\"'\'']*\)[\"'\''].*/\1/')
# We should be redirected
if [[ $AUTHURL == $TESTSITE ]]; then
MSG=${MSG:-"No redirect detected."}
STATUS=2
fi
if [[ $STATUS -eq 0 ]]; then
# REQUEST #2: log in
HTML=$(curl -L -sS -c ${COOKIEJAR} -b ${COOKIEJAR} -w 'LAST_URL:%{url_effective}' \
-d "username=$USERNAME" -d "password=$PASSWORD" --data-urlencode "AuthState=${AUTHSTATE}" ${AUTHURL}) || STATUS=2
# verify that login was successful (i.e no login form on page)
echo $HTML | grep -q 'ut-ldap-form'
if [[ $? -eq 0 ]]; then
STATUS=2
fi
# Continue to step #3
if [[ $STATUS -eq 0 ]]; then
# We do not support JS, so parse HTML for SAML endpoint and response
SAMLENDPOINT=$(echo ${HTML} | sed -e 's/.*form[^>]*method[^>]*action=[\"'\'']\([^\"'\'']*\)[\"'\''].*/\1/')
SAMLRESPONSE=$(echo ${HTML} | sed -e 's/.*hidden[^>]*SAMLResponse[^>]*value=[\"'\'']\([^\"'\'']*\)[\"'\''].*/\1/')
RELAYSTATE=$(echo ${HTML} | sed -e 's/.*hidden[^>]*RelayState[^>]*value=[\"'\'']\([^\"'\'']*\)[\"'\''].*/\1/')
# REQUEST #3: post the SAMLResponse
HTML=$(curl -L -sS -c ${COOKIEJAR} -b ${COOKIEJAR} -w 'LAST_URL:%{url_effective}' \
--data-urlencode "SAMLResponse=${SAMLRESPONSE}" --data-urlencode "RelayState=${RELAYSTATE}" ${SAMLENDPOINT}) || STATUS=2
if [[ $STATUS -eq 0 ]]; then
# Verify success
echo $HTML | grep -q "$TESTSTRING"
if [[ ! $? -eq 0 ]];
then
STATUS=2
MSG=${MSG:-"Final HTML validation failed."}
fi
else
MSG=${MSG:-"POSTing SAMLResponse failed"}
fi
else
MSG=${MSG:-"Login failed"}
fi
else
MSG=${MSG:-"Initial request failed"}
fi
# Clean up
rm -f ${COOKIEJAR}
# Calculate time difference
endtime=$( date +"%s" )
totaltime=$(($endtime-$starttime))
timestat="($totaltime s)"
# If not already set, assume OK
MSG=${MSG:-'OK'}
# If OK, but time > 10 s, set to WARNING
if [[ $STATUS -eq 0 && $totaltime -gt $WARNINGTIME ]]; then
STATUS=1
fi
echo $MSG $timestat
exit $STATUS
@32curveball
Copy link

Worked fantastically! Thanks for your hard work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment