Skip to content

Commit

Permalink
Implement probe_saml_idp_endpoint function
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Scavo committed Dec 21, 2016
1 parent 1a52b96 commit ec415d7
Showing 1 changed file with 195 additions and 0 deletions.
195 changes: 195 additions & 0 deletions lib/saml_tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ec415d7

Please sign in to comment.