diff options
Diffstat (limited to 'remote/modules/pam-bwidm/data/opt/openslx/scripts/pam_bwidm')
-rwxr-xr-x | remote/modules/pam-bwidm/data/opt/openslx/scripts/pam_bwidm | 73 |
1 files changed, 59 insertions, 14 deletions
diff --git a/remote/modules/pam-bwidm/data/opt/openslx/scripts/pam_bwidm b/remote/modules/pam-bwidm/data/opt/openslx/scripts/pam_bwidm index 13e40cb9..92379719 100755 --- a/remote/modules/pam-bwidm/data/opt/openslx/scripts/pam_bwidm +++ b/remote/modules/pam-bwidm/data/opt/openslx/scripts/pam_bwidm @@ -8,6 +8,15 @@ # fix PATH as PAM clears it export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin" + +# grab the password from stdin asap, since there is no guarantee some tool just reads it +unset USER_PASSWORD +if [ "x$PAM_TYPE" == "xauth" ]; then + read -r USER_PASSWORD > /dev/null 2>&1 + readonly USER_PASSWORD + [ -z "$USER_PASSWORD" ] && echo "No password given." && exit 1 +fi + if ! busybox which curl || ! busybox which mktemp; then echo "'curl/mktemp' missing. This script won't work without it." exit 1 @@ -27,14 +36,16 @@ exec > "${LOGFILE}" 2>&1 # check if we are allowed to run . /opt/openslx/config -[ -z "${SLX_BWIDM_AUTH}" -o "x${SLX_BWIDM_AUTH}" != "xyes" ] && echo "bwIDM login disabled in openslx-config." && exit 1 - -# grab the password from stdin asap, since there is no garantee some tool just reads it -unset USER_PASSWORD -if [ "x$PAM_TYPE" == "xauth" ]; then - read -r USER_PASSWORD > /dev/null 2>&1 - readonly USER_PASSWORD - [ -z "$USER_PASSWORD" ] && echo "No password given." && exit 1 +if [ "x${SLX_BWIDM_AUTH}" = "xyes" ]; then + : # Allow everything +elif [ "x${SLX_BWIDM_AUTH}" = "xselective" ]; then + if [ -z "${SLX_BWIDM_ORGS}" ]; then + echo "bwIDM selective mode with empty org list - exiting" + exit 1 + fi +else + echo "bwIDM login disabled in openslx-config." + exit 1 fi # sanity check on PAM_USER: contains '@'? @@ -50,6 +61,21 @@ readonly USER_ORGANISATION="${PAM_USER#*@}" [ -z "$USER_ORGANISATION" ] && echo "Could not parse organisation from given login: ${PAM_USER}. Aborting." && exit 1 [ -z "$USER_USERNAME" ] && echo "Could not parse user from given login: ${PAM_USER}. Aborting." && exit 1 +# Check if we're in selective mode and if so, whether the user's organization is whitelisted +if [ "x${SLX_BWIDM_AUTH}" = "xselective" ]; then + FOUND= + for org in ${SLX_BWIDM_ORGS}; do + if [ "x$org" = "x$USER_ORGANISATION" ]; then + FOUND=ya + break + fi + done + if [ -z "$FOUND" ]; then + echo "bwIDM organization $USER_ORGANISATION not in whitelist, abort" + exit 1 + fi +fi + # The given username is valid. Now we get the list of IdPs from the bwlp masterserver # and try to find the user's organisation @@ -76,7 +102,7 @@ USER_ECP_URL="$(awk -v idp="${USER_ORGANISATION}" -F '=' '{if($1==idp) print $2} # now create the bwidm group: find the first free GID from 1000 "downwards" to 100 BWIDM_GROUP="$(getent group bwidm)" if [ -z "$BWIDM_GROUP" ]; then - BWIDM_GID=1000 + BWIDM_GID=999 while [ "$BWIDM_GID" -gt 100 ]; do getent group "$BWIDM_GID" || break let BWIDM_GID-- @@ -107,18 +133,35 @@ readonly SOAP_ENVELOPE="/opt/openslx/bwidm_soap.xml" # now the pam-type specific part starts if [ "x$PAM_TYPE" == "xauth" ]; then + HA='Accept: text/html; application/vnd.paos+xml' + HP='PAOS: ver="urn:liberty:paos:2003-08";"urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp"' + CT='Content-Type: application/vnd.paos+xml; charset=utf-8' + NOW=$(date -u '+%Y-%m-%dT%H:%M:%SZ') + HOST=$(echo "${USER_ECP_URL}" | awk -F '/' '{print $3}') + RID="_c${RANDOM}a${RANDOM}f${RANDOM}f${RANDOM}e${RANDOM}e${RANDOM}" + RID="${RID:0:32}" + REQUEST=$(sed "s/%TIMESTAMP%/${NOW}/g;s/%REQUESTID%/${RID}/g" "${SOAP_ENVELOPE}") + NETRC=$(mktemp -p /run/) + [ -z "$NETRC" ] && NETRC="/run/netrc_$$_${USER}_${RANDOM}.tmp" + touch "$NETRC" + chmod 0600 "$NETRC" # now we are ready to actually send the credentials to the IdP # to be sure everything is working as expected - # we will first send a wrong password (by repeating the given password) and expect a 401 - ret=$(curl --connect-timeout 5 --max-time 15 -o /dev/null -w "%{http_code}" -d @"${SOAP_ENVELOPE}" -H "Content-Type: application/vnd.paos+xml" --basic -u "${USER_USERNAME}:${USER_PASSWORD}${USER_PASSWORD}" "$USER_ECP_URL") + # we will first send a wrong password and expect a 401 + echo "machine ${HOST} login ${USER_USERNAME} password ___invalid-INVALID++~" > "${NETRC}" + ret=$(curl --connect-timeout 5 --max-time 15 -o /dev/null -w "%{http_code}" -d "${REQUEST}" -H "$CT" -H "$HP" -H "$HA" --basic --netrc-file "$NETRC" "$USER_ECP_URL") if [ "x$ret" != "x401" ]; then # this means something else is bad, just exit echo "False authentication attempt did not return 401 as expected but: $ret" + rm -- "${NETRC}" exit 7 fi # the fake auth call behaved as expected, do the actualy login - ret=$(curl --connect-timeout 5 --max-time 15 -o /dev/null -w "%{http_code}" -d @"${SOAP_ENVELOPE}" -H "Content-Type: application/vnd.paos+xml" --basic -u "${USER_USERNAME}:${USER_PASSWORD}" "$USER_ECP_URL") + echo "machine ${HOST} login ${USER_USERNAME} password ${USER_PASSWORD}" > "${NETRC}" + ret=$(curl --connect-timeout 5 --max-time 15 -o /dev/null -w "%{http_code}" -d "${REQUEST}" -H "$CT" -H "$HP" -H "$HA" --basic --netrc-file "$NETRC" "$USER_ECP_URL") + echo "machine ${HOST} login ${USER_USERNAME} password ********************" > "${NETRC}" # It should be a tmpfs but you never know + rm -- "${NETRC}" if [ "x$ret" == "x200" ]; then # auth succeeded, lets create a local user representing the bwIDM user @@ -166,8 +209,10 @@ exit 1 mainret=$? if [ "x$mainret" == "x7" ]; then # exit code 7 is our marker to push the logfile to the sat - slxlog "pam-bwidm" "Internal error during bwIDM authentication" "${LOGFILE}" - ( sleep 1; rm -f -- "${LOGFILE}" ) & + slxlog --delete "pam-bwidm" "Internal error during bwIDM authentication" "${LOGFILE}" exit 1 +else + rm -- "${LOGFILE}" fi exit "${mainret}" + |