diff --git a/bin/probe_saml_idp.sh b/bin/probe_saml_idp.sh index 75f2de7..7cc3e78 100755 --- a/bin/probe_saml_idp.sh +++ b/bin/probe_saml_idp.sh @@ -121,7 +121,7 @@ config_file_default="${script_bin}/.config" ####################################################################### help_mode=false; quiet_mode=false; verbose_mode=false -probe_saml1=false # TODO: implement -1 option +saml1_disabled=true # TODO: implement -1 option local_opts=; connect_timeout=; max_time=; max_redirs= curl_opts= while getopts ":hqvt:m:r:" opt; do @@ -302,20 +302,17 @@ if [ -z "$SAML2_SP_ACS_BINDING" ]; then echo "ERROR: $script_name requires config param SAML2_SP_ACS_BINDING" >&2 exit 2 fi - -if $probe_saml1; then - if [ -z "$SAML1_SP_ENTITY_ID" ]; then - echo "ERROR: $script_name requires config param SAML1_SP_ENTITY_ID" >&2 - exit 2 - fi - if [ -z "$SAML1_SP_ACS_URL" ]; then - echo "ERROR: $script_name requires config param SAML1_SP_ACS_URL" >&2 - exit 2 - fi - if [ -z "$SAML1_SP_ACS_BINDING" ]; then - echo "ERROR: $script_name requires config param SAML1_SP_ACS_BINDING" >&2 - exit 2 - fi +if [ -z "$SAML1_SP_ENTITY_ID" ]; then + echo "ERROR: $script_name requires config param SAML1_SP_ENTITY_ID" >&2 + exit 2 +fi +if [ -z "$SAML1_SP_ACS_URL" ]; then + echo "ERROR: $script_name requires config param SAML1_SP_ACS_URL" >&2 + exit 2 +fi +if [ -z "$SAML1_SP_ACS_BINDING" ]; then + echo "ERROR: $script_name requires config param SAML1_SP_ACS_BINDING" >&2 + exit 2 fi ##################################################################### @@ -345,7 +342,7 @@ endpoints=$( echo "$entityDescriptor" \ http_bindings="Redirect POST POST-SimpleSign" for http_binding in $http_bindings; do - # compute the endpoint + # compute the SAML2 SSO endpoint endpoint=$( echo "$endpoints" \ | $_GREP -F -m 1 ' Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-'$http_binding'"' ) @@ -369,7 +366,7 @@ for http_binding in $http_bindings; do fi # create temporary subdirectory if necessary - tmp_subdir="$tmp_dir/$http_binding" + tmp_subdir="$tmp_dir/${http_binding}_SSO" if [ ! -d "$tmp_subdir" ]; then /bin/mkdir "$tmp_subdir" exit_status=$? @@ -396,3 +393,52 @@ for http_binding in $http_bindings; do echo "$output $entityID $registrarID" done + +$saml1_disabled && exit 0 + +# compute the Shibboleth SSO endpoint +endpoint=$( echo "$endpoints" \ + | $_GREP -F -m 1 ' Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest"' +) +if [ -z "$endpoint" ]; then + $verbose_mode && echo "$script_name: Shibboleth SSO endpoint not found" + exit 0 +fi + +# compute the endpoint location and binding +location=$( echo "$endpoint" \ + | $_SED -e 's/^.* Location="\([^"]*\)".*$/\1/' +) +binding=$( echo "$endpoint" \ + | $_SED -e 's/^.* Binding="\([^"]*\)".*$/\1/' +) +$verbose_mode && printf "$script_name probing endpoint with Location=\"%s\" and Binding=\"%s\"\n" "$location" "$binding" + +# create temporary subdirectory if necessary +tmp_subdir="$tmp_dir/Shibboleth_SSO" +if [ ! -d "$tmp_subdir" ]; then + /bin/mkdir "$tmp_subdir" + exit_status=$? + if [ $exit_status -ne 0 ]; then + echo "ERROR: $script_name failed to create tmp dir ($exit_status) $tmp_subdir" >&2 + exit 2 + fi +fi + +# probe the endpoint +output=$( probe_shibboleth_sso_endpoint \ + -t $connect_timeout -m $max_time -r $max_redirs \ + -V "$tmp_subdir/curl_trace.txt" \ + -o "$tmp_subdir/idp_http_response.html" \ + -T "$tmp_subdir" \ + $location $binding +) +exit_status=$? +if [ "$exit_status" -ne 0 ]; then + echo "ERROR: $script_name: probe_saml2_idp_endpoint failed ($exit_status)" >&2 + exit 3 +fi + +echo "$output $entityID $registrarID" + +exit 0 diff --git a/lib/saml_tools.sh b/lib/saml_tools.sh index 2642fe5..43adffc 100755 --- a/lib/saml_tools.sh +++ b/lib/saml_tools.sh @@ -221,10 +221,10 @@ probe_saml2_idp_endpoint () { # temporary files header_file="${tmp_dir}/idp_http_header.txt" - curl_opts="${curl_opts} --dump-header $header_file" + curl_opts="$curl_opts --dump-header $header_file" printf "$FUNCNAME using IdP header file: %s\n" "$header_file" >> "$tmp_log_file" cookie_jar_file="${tmp_dir}/idp_cookie_jar.txt" - curl_opts="${curl_opts} --cookie-jar $cookie_jar_file --cookie $cookie_jar_file" + curl_opts="$curl_opts --cookie-jar $cookie_jar_file --cookie $cookie_jar_file" printf "$FUNCNAME using IdP cookie file: %s\n" "$cookie_jar_file" >> "$tmp_log_file" ################################################################### @@ -322,9 +322,11 @@ probe_saml2_idp_endpoint () { # the SAML1 Web Browser SSO profile. # # Usage: -# probe_shibboleth_sso_endpoint [-v] \ +# probe_shibboleth_sso_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] # where @@ -379,11 +381,10 @@ probe_shibboleth_sso_endpoint () { fi # user agent - local script_version="0.2" + local script_version="0.3" local user_agent_string="SAML1 IdP Endpoint Probe ${script_version}" # command-line options - local verbose_mode=false local local_opts local connect_timeout local max_time @@ -414,23 +415,34 @@ probe_shibboleth_sso_endpoint () { # Process command-line options and arguments. ################################################################### + # default curl options + curl_opts="--silent --show-error" + curl_opts="$curl_opts --insecure --tlsv1" + local opt local OPTARG local OPTIND - while getopts ":vt:m:r:T:" opt; do + while getopts ":t:m:r:V:o:T:" opt; do case $opt in - v) - verbose_mode=true - local_opts="$local_opts -$opt" - ;; t) connect_timeout="$OPTARG" + curl_opts="$curl_opts --connect-timeout $connect_timeout" ;; m) max_time="$OPTARG" + curl_opts="$curl_opts --max-time $max_time" ;; r) max_redirs="$OPTARG" + curl_opts="$curl_opts --location --max-redirs $max_redirs" + ;; + V) + curl_trace_file="$OPTARG" + curl_opts="$curl_opts --trace-ascii $curl_trace_file" + ;; + o) + response_file="$OPTARG" + curl_opts="$curl_opts --output $response_file" ;; T) tmp_dir="$OPTARG" @@ -518,26 +530,12 @@ probe_shibboleth_sso_endpoint () { # temporary files header_file="${tmp_dir}/idp_http_header.txt" + curl_opts="$curl_opts --dump-header $header_file" printf "$FUNCNAME using IdP header file: %s\n" "$header_file" >> "$tmp_log_file" - response_file="${tmp_dir}/idp_http_response.html" - printf "$FUNCNAME using IdP response file: %s\n" "$response_file" >> "$tmp_log_file" cookie_jar_file="${tmp_dir}/idp_cookie_jar.txt" + curl_opts="$curl_opts --cookie-jar $cookie_jar_file --cookie $cookie_jar_file" printf "$FUNCNAME using IdP cookie file: %s\n" "$cookie_jar_file" >> "$tmp_log_file" - # compute curl command-line options - curl_opts="--silent --show-error" - if $verbose_mode; then - curl_trace_file="${tmp_dir}/curl_trace.txt" - curl_opts="${curl_opts} --trace-ascii $curl_trace_file" - fi - curl_opts="${curl_opts} --connect-timeout $connect_timeout --max-time $max_time" - curl_opts="${curl_opts} --insecure --tlsv1" - curl_opts="${curl_opts} --location --max-redirs $max_redirs" - curl_opts="${curl_opts} --cookie-jar $cookie_jar_file --cookie $cookie_jar_file" - curl_opts="${curl_opts} --dump-header $header_file" - curl_opts="${curl_opts} --output $response_file" - printf "$FUNCNAME using curl opts: %s\n" "$curl_opts" >> "$tmp_log_file" - ################################################################### # Compute the protocol URL. ################################################################### @@ -568,6 +566,8 @@ probe_shibboleth_sso_endpoint () { # Probe the IdP endpoint. ################################################################### + printf "$FUNCNAME using curl opts: %s\n" "$curl_opts" >> "$tmp_log_file" + # transmit the request to the IdP curl_output=$( /usr/bin/curl ${curl_opts} \ --user-agent "$user_agent_string" \