From ec415d703605f05be26e0c727b8baf0dbdd6a7de Mon Sep 17 00:00:00 2001 From: Tom Scavo Date: Wed, 21 Dec 2016 12:56:39 -0500 Subject: [PATCH] Implement probe_saml_idp_endpoint function --- lib/saml_tools.sh | 195 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) diff --git a/lib/saml_tools.sh b/lib/saml_tools.sh index 43adffc..1a15ef5 100755 --- a/lib/saml_tools.sh +++ b/lib/saml_tools.sh @@ -16,6 +16,201 @@ # limitations under the License. ####################################################################### +####################################################################### +# +# This function probes a browser-facing IdP endpoint location. The +# resulting HTTP exchange may include multiple round trips as the +# server negotiates an initial session with the client. The exchange +# usually terminates with the server presenting an HTML login form +# to the client. +# +# Usage: +# probe_saml_idp_endpoint \ +# -t CONNECT_TIME -m MAX_TIME \ +# -r MAX_REDIRS \ +# [-V CURL_TRACE_FILE] \ +# [-o RESPONSE_FILE] \ +# -T TMP_DIR \ +# IDP_ENDPOINT_LOCATION IDP_ENDPOINT_BINDING IDP_ENDPOINT_TYPE +# where +# IDP_ENDPOINT_LOCATION and IDP_ENDPOINT_BINDING are the +# Location and Binding XML attribute values of a browser- +# facing SAML endpoint at the IdP. Any such endpoint has one +# of the following binding URIs: +# +# urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect +# urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST +# urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign +# urn:mace:shibboleth:1.0:profiles:AuthnRequest +# +# The IDP_ENDPOINT_TYPE must be "SingleSignOnService", which is +# the only endpoint type supported by the script at this time. +# +# The output of this script consists of a single line with four +# space-separated fields: +# +# 1. curl error code +# 2. curl output string +# 3. IdP endpoint location +# 4. IdP endpoint binding +# +# The function records the details of the various processing steps +# and the resulting HTTP transaction in files stored in the given +# temporary directory. If the -v option is specified on the command +# line, a curl trace of the transaction is also provided. +# +####################################################################### +probe_saml_idp_endpoint () { + + # command-line options + local connect_timeout + local max_time + local max_redirs + local curl_trace_file + local response_file + local tmp_dir + + # command-line arguments + local idp_endpoint_binding + local idp_endpoint_location + local idp_endpoint_type + + # other local vars + local local_opts + local saml_message + local exit_status + + ################################################################### + # Process command-line options and arguments. + ################################################################### + + local opt + local OPTARG + local OPTIND + while getopts ":t:m:r:V:o:T:" opt; do + case $opt in + t) + connect_timeout="$OPTARG" + local_opts="$local_opts -t $connect_timeout" + ;; + m) + max_time="$OPTARG" + local_opts="$local_opts -m $max_time" + ;; + r) + max_redirs="$OPTARG" + local_opts="$local_opts -r $max_redirs" + ;; + V) + curl_trace_file="$OPTARG" + local_opts="$local_opts -V $curl_trace_file" + ;; + o) + response_file="$OPTARG" + local_opts="$local_opts -o $response_file" + ;; + T) + tmp_dir="$OPTARG" + local_opts="$local_opts -T $tmp_dir" + ;; + \?) + echo "ERROR: $FUNCNAME: Unrecognized option: -$OPTARG" >&2 + return 2 + ;; + :) + echo "ERROR: $FUNCNAME: Option -$OPTARG requires an argument" >&2 + return 2 + ;; + esac + done + + if [ -z "$connect_timeout" ]; then + echo "ERROR: $FUNCNAME: connection timeout (option -t) required" >&2 + return 2 + fi + + if [ -z "$max_time" ]; then + echo "ERROR: $FUNCNAME: max time (option -m) required" >&2 + return 2 + fi + + if [ -z "$max_redirs" ]; then + echo "ERROR: $FUNCNAME: max redirects (option -r) required" >&2 + return 2 + fi + + # check for a temporary directory + if [ -z "$tmp_dir" ]; then + echo "ERROR: $FUNCNAME: temporary directory (option -T) required" >&2 + return 2 + fi + if [ ! -d "$tmp_dir" ]; then + echo "ERROR: $FUNCNAME: temporary directory does not exist: $tmp_dir" >&2 + return 2 + fi + + # make sure there are the correct number of command-line arguments + shift $(( OPTIND - 1 )) + if [ $# -ne 3 ]; then + echo "ERROR: $FUNCNAME: incorrect number of arguments: $# (3 required)" >&2 + return 2 + fi + idp_endpoint_location="$1" + idp_endpoint_binding="$2" + idp_endpoint_type="$3" + + # SSO endpoints only + if [ "$idp_endpoint_type" != "SingleSignOnService" ]; then + echo "ERROR: $FUNCNAME: endpoint type not supported: $idp_endpoint_type" >&2 + return 2 + fi + + ################################################################### + # Probe the SAML endpoint. + ################################################################### + + # probe a browser-facing SAML2 SSO endpoint + if [ "$idp_endpoint_binding" = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" ] || \ + [ "$idp_endpoint_binding" = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" ] || \ + [ "$idp_endpoint_binding" = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" ]; then + + # construct an AuthnRequest message + saml_message=$( construct_SAML2_AuthnRequest $idp_endpoint_location ) + exit_status=$? + if [ "$exit_status" -ne 0 ]; then + echo "ERROR: $FUNCNAME: construct_SAML2_AuthnRequest failed ($exit_status)" >&2 + return 3 + fi + + # probe the endpoint + probe_saml2_idp_endpoint $local_opts $idp_endpoint_location $idp_endpoint_binding "$saml_message" + exit_status=$? + if [ "$exit_status" -ne 0 ]; then + echo "ERROR: $FUNCNAME: probe_saml2_idp_endpoint failed ($exit_status)" >&2 + return 3 + fi + + return 0 + fi + + # probe a browser-facing SAML1 SSO endpoint + if [ "$idp_endpoint_binding" = "urn:mace:shibboleth:1.0:profiles:AuthnRequest" ]; then + + # probe the endpoint + probe_shibboleth_sso_endpoint $local_opts $idp_endpoint_location $idp_endpoint_binding + exit_status=$? + if [ "$exit_status" -ne 0 ]; then + echo "ERROR: $FUNCNAME: probe_shibboleth_sso_endpoint failed ($exit_status)" >&2 + return 3 + fi + + return 0 + fi + + echo "ERROR: $FUNCNAME: endpoint binding not supported: $idp_endpoint_binding" >&2 + return 2 +} + ####################################################################### # # This function transmits a SAML V2.0 message to a browser-facing