Skip to content

Commit

Permalink
Initial commit of probe_saml_idp.sh and saml_tools.sh
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Scavo committed Dec 10, 2016
1 parent e0391d7 commit 3b13946
Show file tree
Hide file tree
Showing 3 changed files with 1,148 additions and 1 deletion.
334 changes: 334 additions & 0 deletions bin/probe_saml_idp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,334 @@
#!/bin/bash

#######################################################################
# Copyright 2016 Internet2
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#######################################################################

#######################################################################
# Bootstrap
#######################################################################

script_bin=${0%/*} # equivalent to dirname $0
script_name=${0##*/} # equivalent to basename $0

# determine the source lib directory
if [ -z "$LIB_DIR" ]; then
echo "ERROR: $script_name requires env var LIB_DIR" >&2
exit 2
fi
if [ ! -d "$LIB_DIR" ]; then
echo "ERROR: $script_name: LIB_DIR does not exist: $LIB_DIR" >&2
exit 2
fi

# library filenames (always list command_paths first)
LIB_FILENAMES="command_paths.sh
compatible_mktemp.sh
http_tools.sh
md_tools.sh
saml_tools.sh"

# source lib files
for lib_filename in $LIB_FILENAMES; do
lib_file="$LIB_DIR/$lib_filename"
if [ ! -f "$lib_file" ]; then
echo "ERROR: $script_name: lib file does not exist: $lib_file" >&2
exit 2
fi
source "$lib_file"
status_code=$?
if [ $status_code -ne 0 ]; then
echo "ERROR: $script_name failed to source lib file ($status_code) $lib_file" >&2
exit 2
fi
done

# default parameters
connect_timeout_default=2
max_redirs_default=7

# default env vars
saml2_sp_entity_id_default=https://fm.incommon.org/sp
saml2_sp_acs_url_default=https://service1.internet2.edu/Shibboleth.sso/SAML2/POST
saml2_sp_acs_binding_default=urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST

# check env vars, set defaults if neccessary
if [ -z "$SAML2_SP_ENTITY_ID" ]; then
echo "WARNING: $script_name: env var SAML2_SP_ENTITY_ID does not exist, using default: $saml2_sp_entity_id_default" >&2
SAML2_SP_ENTITY_ID=$saml2_sp_entity_id_default
fi
if [ -z "$SAML2_SP_ACS_URL" ]; then
echo "WARNING: $script_name: env var SAML2_SP_ACS_URL does not exist, using default: $saml2_sp_acs_url_default" >&2
SAML2_SP_ACS_URL=$saml2_sp_acs_url_default
fi
if [ -z "$SAML2_SP_ACS_BINDING" ]; then
echo "WARNING: $script_name: env var SAML2_SP_ACS_BINDING does not exist, using default: $saml2_sp_acs_binding_default" >&2
SAML2_SP_ACS_BINDING=$saml2_sp_acs_binding_default
fi

#######################################################################
# Process command-line options and arguments
#######################################################################

help_mode=false; quiet_mode=false; verbose_mode=false
md_query_mode=false; md_file_mode=false
local_opts=; connect_timeout=; max_time=; max_redirs=
while getopts ":hqvt:m:r:u:f:" opt; do
case $opt in
h)
help_mode=true
;;
q)
quiet_mode=true
verbose_mode=false
#local_opts="$local_opts -$opt"
;;
v)
quiet_mode=false
verbose_mode=true
local_opts="$local_opts -$opt"
;;
t)
connect_timeout="$OPTARG"
local_opts="$local_opts -t $OPTARG"
;;
m)
max_time="$OPTARG"
local_opts="$local_opts -m $OPTARG"
;;
r)
max_redirs="$OPTARG"
local_opts="$local_opts -r $OPTARG"
;;
u)
md_query_mode=true
md_file_mode=false
mdq_base_url="$OPTARG"
;;
f)
md_query_mode=false
md_file_mode=true
md_path="$OPTARG"
;;
\?)
echo "ERROR: $script_name: Unrecognized option: -$OPTARG" >&2
exit 2
;;
:)
echo "ERROR: $script_name: Option -$OPTARG requires an argument" >&2
exit 2
;;
esac
done

if $help_mode; then
display_help
exit 0
fi

# report bootstrap operations
if $verbose_mode; then
printf "$script_name using source lib directory: %s\n" "$LIB_DIR"
for lib_filename in $LIB_FILENAMES; do
lib_file="$LIB_DIR/$lib_filename"
printf "$script_name sourced lib file: %s\n" "$lib_file"
done
fi

# determine the metadata source
if $md_query_mode; then
if [ -z "$mdq_base_url" ]; then
echo "ERROR: $script_name: option -u requires an argument" >&2
exit 2
fi
$verbose_mode && printf "$script_name using base URL: %s\n" "$mdq_base_url"
elif $md_file_mode; then
if [ -z "$md_path" ]; then
echo "ERROR: $script_name: option -f requires an argument" >&2
exit 2
fi
if [ ! -f "$md_path" ]; then
echo "ERROR: $script_name: file does not exist: $md_path" >&2
exit 2
fi
$verbose_mode && printf "$script_name using metadata file: %s\n" "$md_path"
else
echo "ERROR: $script_name: one of options -u or -f required" >&2
exit 2
fi

# redirect stdout and stderr to the bit bucket
$quiet_mode && exec 1>/dev/null
$quiet_mode && exec 2>/dev/null

# check consistency of timeout options
if [ -n "$max_time" -a -z "$connect_timeout" ]; then
echo "ERROR: $script_name: the -m option requires the presence of the -t option" >&2
exit 2
fi

# set default connect timeout if necessary
if [ -z "$connect_timeout" ]; then
connect_timeout=$connect_timeout_default
local_opts="$local_opts -t $connect_timeout"
else
if [ "$connect_timeout" -le 0 ] ; then
echo "ERROR: $script_name: connect timeout ($connect_timeout) must be a positive integer" >&2
exit 2
fi
fi

# compute max time if necessary
if [ -z "$max_time" ]; then
max_time=$(( connect_timeout + 2 ))
local_opts="$local_opts -m $max_time"
else
if [ "$max_time" -le "$connect_timeout" ]; then
echo "ERROR: $script_name: max time ($max_time) must be greater than the connect timeout ($connect_timeout)" >&2
exit 2
fi
fi

# check maximum number of redirects
if [ -z "$max_redirs" ]; then
max_redirs=$max_redirs_default
local_opts="$local_opts -r $max_redirs"
fi

if $verbose_mode; then
printf "$script_name using connect timeout: %d secs\n" $connect_timeout
printf "$script_name using max time: %d secs\n" $max_time
printf "$script_name using max redirects: %d\n" $max_redirs
fi

# determine the entityID
shift $(( OPTIND - 1 ))
if [ $# -ne 1 ]; then
echo "ERROR: $script_name: wrong number of arguments: $# (1 required)" >&2
exit 2
fi
entityID="$1"
if [ -z "$entityID" ] ; then
echo "ERROR: $script_name: empty string" >&2
exit 2
fi
$verbose_mode && echo "$script_name using entityID $entityID"

#####################################################################
# Initialization
#####################################################################

# determine temporary directory
if [ -n "$TMPDIR" ] && [ -d "$TMPDIR" ]; then
# use system temporary directory (remove trailing slash)
TMP_DIR="${TMPDIR%%/}/probe_saml_idp_$$"
$verbose_mode && printf "$script_name using temp dir: %s\n" "$TMP_DIR"
else
# create temporary directory
tmp_dir="$( make_temp_file -d )"
if [ ! -d "$tmp_dir" ] ; then
printf "ERROR: $script_name unable to create temporary dir\n" >&2
exit 2
fi
# use temporary directory (remove trailing slash)
TMP_DIR="${tmp_dir%%/}/probe_saml_idp_$$"
$verbose_mode && printf "$script_name creating temp dir: %s\n" "$TMP_DIR"
fi

# create temporary directory if necessary
if [ ! -d "$TMP_DIR" ]; then
/bin/mkdir "$TMP_DIR"
exit_status=$?
if [ $exit_status -ne 0 ]; then
echo "ERROR: $script_name failed to create tmp dir ($exit_status) $TMP_DIR" >&2
exit 2
fi
fi

# create temporary subdirectories if necessary
for http_binding in Redirect POST POST-SimpleSign; do
if [ ! -d "$TMP_DIR/$http_binding" ]; then
/bin/mkdir "$TMP_DIR/$http_binding"
exit_status=$?
if [ $exit_status -ne 0 ]; then
echo "ERROR: $script_name failed to create tmp dir ($exit_status) $TMP_DIR/$http_binding" >&2
exit 2
fi
fi
done

#####################################################################
# Main processing
#####################################################################

# get entity metadata
entityDescriptor=$( getEntityFromServer -d "$TMP_DIR" -u "$mdq_base_url" $entityID )
exit_status=$?
if [ "$exit_status" -ne 0 ]; then
echo "ERROR: $script_name: unable to obtain metadata for entityID: $entityID" >&2
exit 3
fi

# extract the registrar ID from the entity descriptor
registrarID=$( echo "$entityDescriptor" \
| $_GREP -F -m 1 ' registrationAuthority=' \
| $_SED -e 's/^.* registrationAuthority="\([^"]*\)".*$/\1/'
)

# compute all SSO endpoints
endpoints=$( echo "$entityDescriptor" \
| $_GREP -E '<(md:)?SingleSignOnService '
)

# iterate over the SAML2 browser-facing endpoints
for http_binding in Redirect POST POST-SimpleSign; do

# compute the endpoint
endpoint=$( echo "$endpoints" \
| $_GREP -F -m 1 ' Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-'$http_binding'"'
)
[ -z "$endpoint" ] && continue

# 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"

# construct the SAML message
saml_message=$( construct_SAML2_AuthnRequest $location )
exit_status=$?
if [ "$exit_status" -ne 0 ]; then
echo "ERROR: $script_name: construct_SAML2_AuthnRequest failed ($exit_status)" >&2
exit 3
fi

# probe the endpoint
output=$( probe_saml2_idp_endpoint -v \
-t $connect_timeout -m $max_time -r $max_redirs \
-T "$TMP_DIR/$http_binding" \
$location $binding "$saml_message"
)
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"

done
4 changes: 3 additions & 1 deletion install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ while read script_file; do
fi
done <<SCRIPTS
$script_bin/bin/cget.sh
$script_bin/bin/probe_saml_idp.sh
SCRIPTS

# initialize lib dir
Expand All @@ -108,9 +109,10 @@ done <<SOURCES
$script_bin/lib/command_paths.sh
$script_bin/lib/compatible_date.sh
$script_bin/lib/compatible_mktemp.sh
$script_bin/lib/extract_entity.xsl
$script_bin/lib/http_tools.sh
$script_bin/lib/md_tools.sh
$script_bin/lib/extract_entity.xsl
$script_bin/lib/saml_tools.sh
SOURCES

$verbose_mode && echo "$script_name: installation complete"
Expand Down
Loading

0 comments on commit 3b13946

Please sign in to comment.