VCL-1086 - improve modularization of authentication
authentication.php:
-added $authFuncs['local'] array to top of file
-modified getAuthCookieData: changed argument list from ($loginid, $valid) to ($loginid, $authtype, $valid, $shibauthid); added $authtype to data that is encrypted as 4th item
-modified readAuthCookie: added more checks for cookie being invalid - if invalid, clear VCLAUTH cookie so user will be redirected back to login screen; decrypt encrypted data based on new number of parameters
-added getAuthTypeFromAuthCookie
-moved ldapLogin to authmethods/ldapauth.php
-modified localLogin: added 'local' as 2nd argument when calling getAuthCookieData
-added unauthLocal
itecsauth.php:
-added $authFuncs['itecs'] array to top of file
-added testITECSAuth
-added processITECSAuth
-added unauthITECS
ldapauth.php:
-added $authFuncs['ldap'] array to top of file
-added unauthLDAP
-moved ldapLogin from authentication.php to here
shibauth.php:
-moved login code from vcl/shibauth/index.php to here
-moved logout code from utils.php to here
-added $authFuncs['shibboleth'] array to top of file
-added testShibAuth
-added processShibAuth (mostly stuff from shibauth/index.php)
-added unauthShib (contains stuff from utils.php logout)
-added getShibauthDataByUser
-modified updateShibUser: utilize getShibVar to process data passed in
from Shibboleth
-modified updateShibGroups: added additional attempt to get id from affiliation table to use a wildcard with $shibaffil if first attempt fails
-added getShibVar
conf-default.php: removed "shibauth/" from example URL for Shibboleth authentication
utils.php: modified sendHeaders: moved shibboleth logout code to shibauth.php and updated to use $authFuncs array and $authtype from getAuthTypeFromCookie to call correct logout functions
shibauth/index.php:
-moved code to authmethods/shibauth.php
-replaced everything with a simple redirect to the main index page; this script no longer needs to be called - IdP's can redirect straight back to the main index page now
diff --git a/web/.ht-inc/authentication.php b/web/.ht-inc/authentication.php
index 7a93cc0..cb72534 100644
--- a/web/.ht-inc/authentication.php
+++ b/web/.ht-inc/authentication.php
@@ -19,13 +19,21 @@
/**
* \file
*/
+
+$authFuncs['local'] = array('test' => function() {return 0;},
+ 'auth' => function() {return NULL;},
+ 'unauth' => 'unauthLocal');
+
////////////////////////////////////////////////////////////////////////////////
///
-/// \fn getAuthCookieData($loginid, $valid)
+/// \fn getAuthCookieData($loginid, $authtype, $valid, $shibauthid)
///
/// \param $loginid - login id for user
+/// \param $authtype - type of authentication used; should be an index from the
+/// global $authFuncs array
/// \param $valid - (optional, default=600) - time in minutes the cookie
/// should be valid
+/// \param $shibauthid - (optional) id of shibboleth session
///
/// \return on failure, an error message; on success, an array with 2 elements:\n
/// data - encrypted payload for auth cookie\n
@@ -35,16 +43,16 @@
/// a timestamp
///
////////////////////////////////////////////////////////////////////////////////
-function getAuthCookieData($loginid, $valid=600, $shibauthid=0) {
+function getAuthCookieData($loginid, $authtype, $valid=600, $shibauthid=0) {
global $keys;
$ts = time() + ($valid * 60);
$remoteIP = $_SERVER["REMOTE_ADDR"];
if(empty($remoteIP))
return "Failed to obtain remote IP address for fixed cookie type";
if($shibauthid)
- $cdata = "$loginid|$remoteIP|$ts|$shibauthid";
+ $cdata = "$loginid|$remoteIP|$ts|$authtype|$shibauthid";
else
- $cdata = "$loginid|$remoteIP|$ts";
+ $cdata = "$loginid|$remoteIP|$ts|$authtype";
# 245 characters can be encrypted; anything over that, and
# openssl_private_encrypt will fail
@@ -75,19 +83,32 @@
else
$cookie = $_COOKIE["VCLAUTH"];
$cookie = base64_decode($cookie);
- if(! openssl_public_decrypt($cookie, $tmp, $keys['public'])) {
- $AUTHERROR["code"] = 3;
- $AUTHERROR["message"] = "Failed to decrypt auth cookie";
- return NULL;
- }
+ if(! openssl_public_decrypt($cookie, $tmp, $keys['public'])) {
+ # cookie is invalid; clear it and return NULL so will get redirected to log in again
+ setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
+ $AUTHERROR["code"] = 3;
+ $AUTHERROR["message"] = "Failed to decrypt auth cookie";
+ return NULL;
+ }
- $tmparr = explode('|', $tmp);
+ # $loginid|$remoteIP|$ts|$authtype|$shibauthid (shibauthd optional)
+ $tmparr = explode('|', $tmp);
$loginid = $tmparr[0];
$remoteIP = $tmparr[1];
$ts = $tmparr[2];
- if(count($tmparr) > 3) {
- $shibauthed = $tmparr[3];
-
+
+ # check for old style auth cookie before $authtype was included
+ if(count($tmparr) < 4 || is_numeric($tmparr[3])) {
+ # log user out to get new style auth cookie
+ setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
+ stopSession();
+ dbDisconnect();
+ header("Location: " . BASEURL);
+ exit;
+ }
+ if(count($tmparr) > 4) {
+ $shibauthed = $tmparr[5];
+
# check to see if shibauth entry still exists for $shibauthed
$query = "SELECT ts FROM shibauth WHERE id = $shibauthed";
$qh = doQuery($query, 101);
@@ -105,19 +126,61 @@
}
}
- if($ts < time()) {
- $AUTHERROR["code"] = 4;
- $AUTHERROR["message"] = "Auth cookie has expired";
- return NULL;
- }
- if($_SERVER["REMOTE_ADDR"] != $remoteIP) {
- //setcookie("ITECSAUTH", "", time() - 10, "/", COOKIEDOMAIN);
- $AUTHERROR["code"] = 4;
- $AUTHERROR["message"] = "remote IP in auth cookie doesn't match user's remote IP";
- return NULL;
- }
+ if($ts < time()) {
+ # cookie is expired; clear it and return NULL so will get redirected to log in again
+ setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
+ $AUTHERROR["code"] = 4;
+ $AUTHERROR["message"] = "Auth cookie has expired";
+ return NULL;
+ }
+ if($_SERVER["REMOTE_ADDR"] != $remoteIP) {
+ # cookie has wrong IP; clear it and return NULL so will get redirected to log in again
+ setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
+ $AUTHERROR["code"] = 4;
+ $AUTHERROR["message"] = "remote IP in auth cookie doesn't match user's remote IP";
+ return NULL;
+ }
- return $loginid;
+ return $loginid;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getAuthTypeFromAuthCookie()
+///
+/// \return on success, type of authentication used; NULL on failure
+///
+/// \brief parses the VCLAUTH cookie to get the authtype saved in it
+///
+////////////////////////////////////////////////////////////////////////////////
+function getAuthTypeFromAuthCookie() {
+ global $keys, $AUTHERROR;
+ if(! array_key_exists('VCLAUTH', $_COOKIE))
+ return NULL;
+ if(get_magic_quotes_gpc())
+ $cookie = stripslashes($_COOKIE["VCLAUTH"]);
+ else
+ $cookie = $_COOKIE["VCLAUTH"];
+ $cookie = base64_decode($cookie);
+ if(! openssl_public_decrypt($cookie, $tmp, $keys['public'])) {
+ $AUTHERROR["code"] = 3;
+ $AUTHERROR["message"] = "Failed to decrypt auth cookie";
+ return NULL;
+ }
+
+ # $loginid|$remoteIP|$ts|$authtype|$shibauthid (shibauthd optional)
+ $tmparr = explode('|', $tmp);
+ $remoteIP = $tmparr[1];
+ $authtype = $tmparr[3];
+
+ if($_SERVER["REMOTE_ADDR"] != $remoteIP) {
+ //setcookie("ITECSAUTH", "", time() - 10, "/", COOKIEDOMAIN);
+ $AUTHERROR["code"] = 4;
+ $AUTHERROR["message"] = "remote IP in auth cookie doesn't match user's remote IP";
+ return NULL;
+ }
+
+ return $authtype;
}
////////////////////////////////////////////////////////////////////////////////
@@ -351,120 +414,6 @@
////////////////////////////////////////////////////////////////////////////////
///
-/// \fn ldapLogin($authtype, $userid, $passwd)
-///
-/// \param $authtype - index from $authMechs array
-/// \param $userid - userid without affiliation
-/// \param $passwd - submitted password
-///
-/// \brief tries to authenticate user via ldap; calls printLoginPageWithSkin if
-/// authentication fails
-///
-////////////////////////////////////////////////////////////////////////////////
-function ldapLogin($authtype, $userid, $passwd) {
- global $HTMLheader, $printedHTMLheader, $authMechs, $phpVer;
- $esc_userid = vcl_mysql_escape_string($userid);
- if(! $fh = fsockopen($authMechs[$authtype]['server'], 636, $errno, $errstr, 5)) {
- printLoginPageWithSkin($authtype, 1);
- return;
- }
- fclose($fh);
- $ds = ldap_connect("ldaps://{$authMechs[$authtype]['server']}/");
- if(! $ds) {
- addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 0);
- print $HTMLheader;
- $printedHTMLheader = 1;
- selectAuth();
- return;
- }
- ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
- ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
- if(array_key_exists('lookupuserbeforeauth', $authMechs[$authtype]) &&
- $authMechs[$authtype]['lookupuserbeforeauth'] &&
- array_key_exists('lookupuserfield', $authMechs[$authtype])) {
- # in this case, we have to look up what part of the tree the user is in
- # before we can actually look up the user
- $auth = $authMechs[$authtype];
- if(array_key_exists('masterlogin', $auth) && strlen($auth['masterlogin']))
- $res = ldap_bind($ds, $auth['masterlogin'], $auth['masterpwd']);
- else
- $res = ldap_bind($ds);
- if(! $res) {
- addLoginLog($userid, $authtype, $auth['affiliationid'], 0);
- printLoginPageWithSkin($authtype);
- return;
- }
- $search = ldap_search($ds,
- $auth['binddn'],
- "{$auth['lookupuserfield']}=$userid",
- array('dn'), 0, 3, 15);
- if($search) {
- $tmpdata = ldap_get_entries($ds, $search);
- if(! $tmpdata['count'] || ! array_key_exists('dn', $tmpdata[0])) {
- addLoginLog($userid, $authtype, $auth['affiliationid'], 0);
- printLoginPageWithSkin($authtype);
- return;
- }
- $ldapuser = $tmpdata[0]['dn'];
- }
- else {
- addLoginLog($userid, $authtype, $auth['affiliationid'], 0);
- printLoginPageWithSkin($authtype);
- return;
- }
- }
- else
- $ldapuser = sprintf($authMechs[$authtype]['userid'], $userid);
- $res = ldap_bind($ds, $ldapuser, $passwd);
- if(! $res) {
- // login failed
- $err = ldap_error($ds);
- if($err == 'Invalid credentials')
- addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 0, $err);
- else
- addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 0);
- printLoginPageWithSkin($authtype);
- return;
- }
- else {
- addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 1);
- # used to rely on later code to update user info if update timestamp was expired
- // see if user in our db
- /*$query = "SELECT id "
- . "FROM user "
- . "WHERE unityid = '$esc_userid' AND "
- . "affiliationid = {$authMechs[$authtype]['affiliationid']}";
- $qh = doQuery($query, 101);
- if(! mysqli_num_rows($qh)) {
- // if not, add user
- $newid = updateLDAPUser($authtype, $userid);
- if(is_null($newid))
- abort(8);
- }*/
- # now, we always update the user info
- $newid = updateLDAPUser($authtype, $userid);
- if(is_null($newid))
- abort(8);
- // get cookie data
- $cookie = getAuthCookieData("$userid@" . getAffiliationName($authMechs[$authtype]['affiliationid']));
- // set cookie
- if(version_compare(PHP_VERSION, "5.2", ">=") == true)
- setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0, 1);
- else
- setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0);
- # set skin cookie based on affiliation
- $skin = getAffiliationTheme($authMechs[$authtype]['affiliationid']);
- $ucskin = strtoupper($skin);
- setcookie("VCLSKIN", "$ucskin", (time() + (SECINDAY * 31)), "/", COOKIEDOMAIN);
- // redirect to main page
- header("Location: " . BASEURL . SCRIPT);
- dbDisconnect();
- exit;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-///
/// \fn localLogin($userid, $passwd, $authtype)
///
/// \param $userid - userid without affiliation
@@ -480,7 +429,7 @@
if(validateLocalAccount($userid, $passwd)) {
addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 1);
//set cookie
- $cookie = getAuthCookieData("$userid@local");
+ $cookie = getAuthCookieData("$userid@local", 'local');
if(version_compare(PHP_VERSION, "5.2", ">=") == true)
setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0, 1);
else
@@ -503,6 +452,24 @@
////////////////////////////////////////////////////////////////////////////////
///
+/// \fn unauthLocal
+///
+/// \param $mode - headers or content
+///
+/// \brief for headers, simply returns; for content, prints information that
+/// user has been logged out; VCLAUTH cookie is cleared elsewhere
+///
+////////////////////////////////////////////////////////////////////////////////
+function unauthLocal($mode) {
+ if($mode == 'headers')
+ return;
+ print "<h2>Logout</h2>\n";
+ print "You are now logged out of VCL.<br><br>\n";
+ print "<a href=\"" . BASEURL . SCRIPT . "?mode=selectauth\">Return to Login</a><br><br><br>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
/// \fn validateLocalAccount($user, $pass)
///
/// \param $user - unityid from user table
diff --git a/web/.ht-inc/authmethods/itecsauth.php b/web/.ht-inc/authmethods/itecsauth.php
index be9b537..a271450 100644
--- a/web/.ht-inc/authmethods/itecsauth.php
+++ b/web/.ht-inc/authmethods/itecsauth.php
@@ -22,6 +22,79 @@
* \file
*/
+$authFuncs['itecs'] = array('test' => 'testITECSAuth',
+ 'auth' => 'processITECSAuth',
+ 'unauth' => 'unauthITECS');
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn testITECSAuth()
+///
+/// \return 1 if ITECSAUTH cookie found, 0 if not
+///
+/// \brief tests for existance of authentication information for ITECS auth
+///
+////////////////////////////////////////////////////////////////////////////////
+function testITECSAuth() {
+ if(array_key_exists('ITECSAUTH', $_COOKIE))
+ return 1;
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn processITECSAuth()
+///
+/// \return userid in form of emailaddress@ITECS or NULL
+///
+/// \brief processes authentication information; returns userid or NULL if
+/// unsuccessful
+///
+////////////////////////////////////////////////////////////////////////////////
+function processITECSAuth() {
+ $authdata = authUser();
+ if(! ($error = getAuthError())) {
+ $userid = "{$authdata["email"]}@ITECS";
+ $affilid = getAffiliationID('ITECS');
+ addLoginLog($userid, 'ITECS', $affilid, 1);
+
+ # get cookie data
+ $cookie = getAuthCookieData($userid, 'itecs', 600);
+ # set cookie
+ if(version_compare(PHP_VERSION, "5.2", ">=") == true)
+ setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0, 1);
+ else
+ setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN);
+
+ return $userid;
+ }
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn unauthITECS($mode)
+///
+/// \param $mode - headers or content
+///
+/// \brief for headers mode, destroys authentication information; for content
+/// mode, prints information about having been logged out
+///
+////////////////////////////////////////////////////////////////////////////////
+function unauthITECS($mode) {
+ if($mode == 'headers') {
+ $time = time() - 10;
+ setcookie("ITECSAUTH_RETURN", "", $time, "/", COOKIEDOMAIN);
+ setcookie("ITECSAUTH_CSS", "", $time, "/", COOKIEDOMAIN);
+ setcookie("ITECSAUTH", "", $time, "/", COOKIEDOMAIN);
+ }
+ elseif($mode == 'content') {
+ print "<h2>Logout</h2>\n";
+ print "You are now logged out of VCL.<br><br>\n";
+ print "<a href=\"" . BASEURL . SCRIPT . "?mode=selectauth\">Return to Login</a><br><br><br>\n";
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
///
/// \fn addITECSUser($loginid)
diff --git a/web/.ht-inc/authmethods/ldapauth.php b/web/.ht-inc/authmethods/ldapauth.php
index 8aa53c6..1c2ee53 100644
--- a/web/.ht-inc/authmethods/ldapauth.php
+++ b/web/.ht-inc/authmethods/ldapauth.php
@@ -20,6 +20,143 @@
* \file
*/
+$authFuncs['ldap'] = array('test' => function() {return 0;},
+ 'auth' => function() {return NULL;},
+ 'unauth' => 'unauthLDAP');
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn unauthLDAP($mode)
+///
+/// \param $mode - headers or content
+///
+/// \brief for headers, simply returns; for content, prints information that
+/// user has been logged out; VCLAUTH cookie is cleared elsewhere
+///
+////////////////////////////////////////////////////////////////////////////////
+function unauthLDAP($mode) {
+ if($mode == 'headers')
+ return;
+ print "<h2>" . _('Logout') . "</h2>\n";
+ print _("You are now logged out of VCL.") . "<br><br>\n";
+ print "<a href=\"" . BASEURL . SCRIPT . "?mode=selectauth\">" . _("Return to Login");
+ print "</a><br><br><br>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn ldapLogin($authtype, $userid, $passwd)
+///
+/// \param $authtype - index from $authMechs array
+/// \param $userid - userid without affiliation
+/// \param $passwd - submitted password
+///
+/// \brief tries to authenticate user via ldap; calls printLoginPageWithSkin if
+/// authentication fails
+///
+////////////////////////////////////////////////////////////////////////////////
+function ldapLogin($authtype, $userid, $passwd) {
+ global $HTMLheader, $printedHTMLheader, $authMechs, $phpVer;
+ $esc_userid = vcl_mysql_escape_string($userid);
+ if(! $fh = fsockopen($authMechs[$authtype]['server'], 636, $errno, $errstr, 5)) {
+ printLoginPageWithSkin($authtype, 1);
+ return;
+ }
+ fclose($fh);
+ $ds = ldap_connect("ldaps://{$authMechs[$authtype]['server']}/");
+ if(! $ds) {
+ addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 0);
+ print $HTMLheader;
+ $printedHTMLheader = 1;
+ selectAuth();
+ return;
+ }
+ ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
+ ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
+ if(array_key_exists('lookupuserbeforeauth', $authMechs[$authtype]) &&
+ $authMechs[$authtype]['lookupuserbeforeauth'] &&
+ array_key_exists('lookupuserfield', $authMechs[$authtype])) {
+ # in this case, we have to look up what part of the tree the user is in
+ # before we can actually look up the user
+ $auth = $authMechs[$authtype];
+ if(array_key_exists('masterlogin', $auth) && strlen($auth['masterlogin']))
+ $res = ldap_bind($ds, $auth['masterlogin'], $auth['masterpwd']);
+ else
+ $res = ldap_bind($ds);
+ if(! $res) {
+ addLoginLog($userid, $authtype, $auth['affiliationid'], 0);
+ printLoginPageWithSkin($authtype);
+ return;
+ }
+ $search = ldap_search($ds,
+ $auth['binddn'],
+ "{$auth['lookupuserfield']}=$userid",
+ array('dn'), 0, 3, 15);
+ if($search) {
+ $tmpdata = ldap_get_entries($ds, $search);
+ if(! $tmpdata['count'] || ! array_key_exists('dn', $tmpdata[0])) {
+ addLoginLog($userid, $authtype, $auth['affiliationid'], 0);
+ printLoginPageWithSkin($authtype);
+ return;
+ }
+ $ldapuser = $tmpdata[0]['dn'];
+ }
+ else {
+ addLoginLog($userid, $authtype, $auth['affiliationid'], 0);
+ printLoginPageWithSkin($authtype);
+ return;
+ }
+ }
+ else
+ $ldapuser = sprintf($authMechs[$authtype]['userid'], $userid);
+ $res = ldap_bind($ds, $ldapuser, $passwd);
+ if(! $res) {
+ // login failed
+ $err = ldap_error($ds);
+ if($err == 'Invalid credentials')
+ addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 0, $err);
+ else
+ addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 0);
+ printLoginPageWithSkin($authtype);
+ return;
+ }
+ else {
+ addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 1);
+ # used to rely on later code to update user info if update timestamp was expired
+ // see if user in our db
+ /*$query = "SELECT id "
+ . "FROM user "
+ . "WHERE unityid = '$esc_userid' AND "
+ . "affiliationid = {$authMechs[$authtype]['affiliationid']}";
+ $qh = doQuery($query, 101);
+ if(! mysqli_num_rows($qh)) {
+ // if not, add user
+ $newid = updateLDAPUser($authtype, $userid);
+ if(is_null($newid))
+ abort(8);
+ }*/
+ # now, we always update the user info
+ $newid = updateLDAPUser($authtype, $userid);
+ if(is_null($newid))
+ abort(8);
+ // get cookie data
+ $cookie = getAuthCookieData("$userid@" . getAffiliationName($authMechs[$authtype]['affiliationid']), 'ldap');
+ // set cookie
+ if(version_compare(PHP_VERSION, "5.2", ">=") == true)
+ setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0, 1);
+ else
+ setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0);
+ # set skin cookie based on affiliation
+ $skin = getAffiliationTheme($authMechs[$authtype]['affiliationid']);
+ $ucskin = strtoupper($skin);
+ setcookie("VCLSKIN", "$ucskin", (time() + (SECINDAY * 31)), "/", COOKIEDOMAIN);
+ // redirect to main page
+ header("Location: " . BASEURL . SCRIPT);
+ dbDisconnect();
+ exit;
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
///
/// \fn addLDAPUser($authtype, $userid)
diff --git a/web/.ht-inc/authmethods/shibauth.php b/web/.ht-inc/authmethods/shibauth.php
index 33d7b5d..947035e 100644
--- a/web/.ht-inc/authmethods/shibauth.php
+++ b/web/.ht-inc/authmethods/shibauth.php
@@ -20,6 +20,286 @@
* \file
*/
+$authFuncs['shibboleth'] = array('test' => 'testShibAuth',
+ 'auth' => 'processShibAuth',
+ 'unauth' => 'unauthShib');
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn testShibAuth()
+///
+/// \returns 1 if SHIB_EPPN found in $_SERVER; 0 otherwise
+///
+/// \brief checks for authentication information related to Shibboleth
+///
+////////////////////////////////////////////////////////////////////////////////
+function testShibAuth() {
+ // TODO check for other shib variables, if found but EPPN not found, alert user that EPPN is not being released
+ if(array_key_exists('SHIB_EPPN', $_SERVER))
+ return 1;
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn processShibAuth()
+///
+/// \returns userid in userid@AFFILIATION form
+///
+/// \brief processes Shibboleth authentication information
+///
+////////////////////////////////////////////////////////////////////////////////
+function processShibAuth() {
+ # get VCL affiliation from shib affiliation
+ $tmp = explode(';', $_SERVER['SHIB_EPPN']);
+ $tmp = explode('@', $tmp[0]);
+ $username = strtolower($tmp[0]);
+ $shibaffil = vcl_mysql_escape_string(strtolower($tmp[1]));
+ $query = "SELECT name, shibonly FROM affiliation WHERE shibname = '$shibaffil'";
+ $qh = doQuery($query, 101);
+ # if shib affiliation not already in VCL, create affiliation
+ if(! ($row = mysqli_fetch_assoc($qh))) {
+ $affil = strtolower($tmp[1]);
+ $tmp = explode('.', $affil);
+ array_pop($tmp);
+ $affilname = strtoupper(implode('', $tmp));
+ $affilname = preg_replace('/[^A-Z0-9]/', '', $affilname);
+ $query = "SELECT name, "
+ . "shibname "
+ . "FROM affiliation "
+ . "WHERE name LIKE '$affilname%' "
+ . "ORDER BY name DESC "
+ . "LIMIT 1";
+ $qh = doQuery($query, 101);
+ if($row = mysqli_fetch_assoc($qh)) {
+ if(preg_match("/$affilname([0-9]+)/", $row['name'], $matches)) {
+ $cnt = $matches[1];
+ $cnt++;
+ $newaffilname = $affilname . $cnt;
+ }
+ elseif($affilname != strtoupper($row['name']) && $affil != $row['shibname']) {
+ $newaffilname = $affilname;
+ }
+ else {
+ $msg = "Someone tried to log in to VCL using Shibboleth from an IdP "
+ . "affiliation that could not be automatically added.\n\n"
+ . "eppn: {$_SERVER['SHIB_EPPN']}\n"
+ . "givenName: {$_SERVER['SHIB_GIVENNAME']}\n"
+ . "sn: {$_SERVER['SHIB_SN']}\n";
+ if(array_key_exists('SHIB_MAIL', $_SERVER))
+ $msg .= "mail: {$_SERVER['SHIB_MAIL']}\n\n";
+ $msg .="tried to add VCL affiliation name \"$affilname\" with "
+ . "shibname \"$affil\"";
+ $mailParams = "-f" . ENVELOPESENDER;
+ mail(ERROREMAIL, "Error with VCL pages (problem adding shib affil)", $msg, '', $mailParams);
+ print "<html><head></head><body>\n";
+ print "<h2>Error encountered</h2>\n";
+ print "You have attempted to log in to VCL using a Shibboleth<br>\n";
+ print "Identity Provider that VCL has not been configured to<br>\n";
+ print "work with. VCL administrators have been notified of the<br>\n";
+ print "problem.<br>\n";
+ print "</body></html>\n";
+ dbDisconnect();
+ exit;
+ }
+ }
+ else
+ $newaffilname = $affilname;
+ $query = "INSERT INTO affiliation "
+ . "(name, "
+ . "shibname, "
+ . "shibonly) "
+ . "VALUES "
+ . "('$newaffilname', "
+ . "'" . vcl_mysql_escape_string($affil) . "', "
+ . "1)";
+ doQuery($query, 101, 'vcl', 1);
+ unset($row);
+ $row = array('name' => $newaffilname, 'shibonly' => 1);
+ }
+ $affil = $row['name'];
+ $affilid = getAffiliationID($affil);
+
+ # create VCL userid
+ $userid = "$username@$affil";
+
+ if($row['shibonly']) {
+ $userdata = updateShibUser($userid);
+ if(array_key_exists('SHIB_AFFILIATION', $_SERVER))
+ $groups = $_SERVER['SHIB_AFFILIATION'];
+ else
+ $groups = array('shibaffil' => $shibaffil);
+ updateShibGroups($userdata['id'], $groups);
+ $usernid = $userdata['id'];
+ }
+ else {
+ $usernid = getUserlistID($userid, 1);
+ # NCSU specific
+ if(is_null($userid) && $affil == 'NCSU') {
+ $tmp = updateLDAPUser('NCSU LDAP', $username);
+ $usernid = $tmp['id'];
+ }
+ /*if($affil == 'NCSU') {
+ if(array_key_exists('SHIB_AFFILIATION', $_SERVER))
+ $groups = $_SERVER['SHIB_AFFILIATION'];
+ else
+ $groups = array('shibaffil' => $shibaffil);
+ updateShibGroups($usernid, $groups);
+ }*/
+ # end NCSU specific
+ if(is_null($usernid)) {
+ $tmp = updateShibUser($userid);
+ $usernid = $tmp['id'];
+ # call this so that user groups get correctly populated
+ updateUserData($usernid, "numeric", $affilid);
+ }
+ }
+
+ addLoginLog($userid, 'shibboleth', $affilid, 1);
+
+ if($affil == 'UNCG') {
+ $gid = getUserGroupID('All UNCG Users', $affilid);
+ $query = "INSERT IGNORE INTO usergroupmembers "
+ . "(userid, usergroupid) "
+ . "VALUES ($usernid, $gid)";
+ doQuery($query, 307);
+ }
+
+ if(array_key_exists('SHIB_LOGOUTURL', $_SERVER))
+ $logouturl = $_SERVER['SHIB_LOGOUTURL'];
+ else
+ $logouturl = '';
+
+ # save data to shibauth table
+ $shibdata = array('Shib-Application-ID' => $_SERVER['Shib-Application-ID'],
+ 'Shib-Identity-Provider' => $_SERVER['Shib-Identity-Provider'],
+ #'Shib-AuthnContext-Dec' => $_SERVER['Shib-AuthnContext-Decl'],
+ 'SHIB_LOGOUTURL' => $logouturl,
+ 'SHIB_EPPN' => $_SERVER['SHIB_EPPN'],
+ #'SHIB_UNAFFILIATION' => $_SERVER['SHIB_UNAFFILIATION'],
+ 'SHIB_AFFILIATION' => $_SERVER['SHIB_AFFILIATION'],
+ );
+ $serdata = vcl_mysql_escape_string(serialize($shibdata));
+ $query = "SELECT id "
+ . "FROM shibauth "
+ . "WHERE sessid = '{$_SERVER['Shib-Session-ID']}'";
+ $qh = doQuery($query, 101);
+ if($row = mysqli_fetch_assoc($qh)) {
+ $shibauthid = $row['id'];
+ }
+ else {
+ $ts = strtotime($_SERVER['Shib-Authentication-Instant']);
+ $ts = unixToDatetime($ts);
+ $query = "INSERT INTO shibauth "
+ . "(userid, "
+ . "ts, "
+ . "sessid, "
+ . "data) "
+ . "VALUES "
+ . "($usernid, "
+ . "'$ts', "
+ . "'{$_SERVER['Shib-Session-ID']}', "
+ . "'$serdata')";
+ doQuery($query, 101);
+ $qh = doQuery("SELECT LAST_INSERT_ID()", 101);
+ if(! $row = mysqli_fetch_row($qh)) {
+ # todo
+ }
+ $shibauthid = $row[0];
+ }
+
+ # get cookie data
+ $cookie = getAuthCookieData($userid, 'shibboleth', 600, $shibauthid);
+ # set cookie
+ if(version_compare(PHP_VERSION, "5.2", ">=") == true)
+ #setcookie("VCLAUTH", "{$cookie['data']}", $cookie['ts'], "/", COOKIEDOMAIN, 1, 1);
+ setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0, 1);
+ else
+ #setcookie("VCLAUTH", "{$cookie['data']}", $cookie['ts'], "/", COOKIEDOMAIN, 1);
+ setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN);
+
+ # TODO do something to set VCLSKIN cookie based on affiliation
+
+ return $userid;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn unauthShib($mode)
+///
+/// \param $mode - headers or content
+//
+/// \brief for headers, simply returns; for content, prints information that
+/// user has been logged out and an iframe to log user out of Shibboleth if
+/// SHIB_LOGOUTURL was provided; VCLAUTH cookie is cleared elsewhere
+///
+////////////////////////////////////////////////////////////////////////////////
+function unauthShib($mode) {
+ global $user;
+ if($mode == 'headers')
+ return;
+
+ print "<h2>Logout</h2>\n";
+ print "You are now logged out of VCL and other Shibboleth authenticated web sites.<br><br>\n";
+ print "<a href=\"" . BASEURL . SCRIPT . "?mode=selectauth\">Return to Login</a><br><br><br>\n";
+ print "<iframe src=\"https://{$_SERVER['SERVER_NAME']}/Shibboleth.sso/Logout\" class=hidden>\n";
+ print "</iframe>\n";
+ if(array_key_exists('SHIB_LOGOUTURL', $_SERVER)) {
+ print "<iframe src=\"{$_SERVER['SHIB_LOGOUTURL']}\" class=hidden>\n";
+ print "</iframe>\n";
+ }
+ $shibdata = getShibauthDataByUser($user['id']);
+ if(array_key_exists('Shib-Identity-Provider', $shibdata) &&
+ ! empty($shibdata['Shib-Identity-Provider'])) {
+ $tmp = explode('/', $shibdata['Shib-Identity-Provider']);
+ $idp = "{$tmp[0]}//{$tmp[2]}";
+ print "<iframe src=\"$idp/idp/logout.jsp\" class=hidden>\n";
+ print "</iframe>\n";
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getShibauthDataByUser($userid)
+///
+/// \param $userid - numeric id of a user
+///
+/// \return NULL if id not found in table or array of data with these keys:\n
+/// \b userid - id of user that data belongs to\n
+/// \b ts - datetime of when authdata was created\n
+/// \b sessid - shibboleth session id\n
+/// \b Shib-Application-ID - ??\n
+/// \b Shib-Identity-Provider - ??\n
+/// \b Shib-AuthnContext-Dec - ??\n
+/// \b Shib-logouturl - idp's logout url\n
+/// \b eppn - edu person principal name for user\n
+/// \b unscoped-affiliation - shibboleth unscoped affiliation\n
+/// \b affiliation - shibboleth scoped affiliation
+///
+/// \brief gets entry from shibauth table
+///
+////////////////////////////////////////////////////////////////////////////////
+function getShibauthDataByUser($userid) {
+ $query = "SELECT id, "
+ . "userid, "
+ . "ts, "
+ . "sessid, "
+ . "data "
+ . "FROM shibauth "
+ . "WHERE userid = $userid AND "
+ . "ts > DATE_SUB(NOW(), INTERVAL 12 HOUR) "
+ . "ORDER BY ts DESC "
+ . "LIMIT 1";
+ $qh = doQuery($query, 101);
+ if($row = mysqli_fetch_assoc($qh)) {
+ $data = unserialize($row['data']);
+ unset($row['data']);
+ $data2 = array_merge($row, $data);
+ return $data2;
+ }
+ return NULL;
+}
+
////////////////////////////////////////////////////////////////////////////////
///
/// \fn updateShibUser($userid)
@@ -45,35 +325,40 @@
return NULL;
$displast = '';
- if(array_key_exists('displayName', $_SERVER) &&
- ! empty($_SERVER['displayName'])) {
- # split displayName into first and last names
- if(preg_match('/,/', $_SERVER['displayName'])) {
- $names = explode(',', $_SERVER['displayName']);
+
+ $displayname = getShibVar('displayName');
+ $givenname = getShibVar('givenName');
+ $sn = getShibVar('sn');
+ $mail = getShibVar('mail');
+
+ if($displayname != '') {
+ # split displayname into first and last names
+ if(preg_match('/,/', $displayname)) {
+ $names = explode(',', $displayname);
$user['firstname'] = preg_replace('/^\s+/', '', $names[1]);
$user['firstname'] = preg_replace('/\s+$/', '', $user['firstname']);
$displast = preg_replace('/^\s+/', '', $names[0]);
$displast = preg_replace('/\s+$/', '', $displast);
}
else {
- $names = explode(' ', $_SERVER['displayName']);
+ $names = explode(' ', $displayname);
$displast = array_pop($names);
$user['firstname'] = array_shift($names);
}
}
- elseif(array_key_exists('givenName', $_SERVER) &&
- ! empty($_SERVER['givenName']))
- $user['firstname'] = $_SERVER['givenName'];
+ elseif($givenname != '')
+ $user['firstname'] = $givenname;
else
$user['firstname'] = '';
- if(array_key_exists('sn', $_SERVER) &&
- ! empty($_SERVER['sn']))
- $user["lastname"] = $_SERVER['sn'];
+ if($sn != '')
+ $user["lastname"] = $sn;
else
$user['lastname'] = $displast;
- if(array_key_exists('mail', $_SERVER))
- $user["email"] = $_SERVER['mail'];
+
+ if($mail != '')
+ $user["email"] = $mail;
+
$user['unityid'] = $userid;
$user['affilid'] = $affilid;
@@ -188,7 +473,12 @@
# get id for the group's affiliation
$query = "SELECT id FROM affiliation WHERE shibname = '$shibaffil'";
$qh = doQuery($query, 101);
- $row = mysqli_fetch_assoc($qh);
+ if(! ($row = mysqli_fetch_assoc($qh))) {
+ $query = "SELECT id FROM affiliation WHERE shibname LIKE '%.$shibaffil'";
+ $qh = doQuery($query, 101);
+ if(! ($row = mysqli_fetch_assoc($qh)))
+ continue;
+ }
$affilid = $row['id'];
# prepend shib- and escape it for mysql
$grp = vcl_mysql_escape_string("shib-" . $name);
@@ -244,4 +534,24 @@
return NULL;
}
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getShibVar($key)
+///
+/// \param $key - shib variable to check for
+///
+/// \return value of shib variable or empty string if not found
+///
+/// \brief checks for various forms of $key in $_SERVER
+///
+////////////////////////////////////////////////////////////////////////////////
+function getShibVar($key) {
+ $key2 = "SHIB_" . strtoupper($key);
+ $val = '';
+ if(isset($_SERVER[$key]) && ! empty($_SERVER[$key]))
+ return $_SERVER[$key];
+ elseif(isset($_SERVER[$key2]) && ! empty($_SERVER[$key2]))
+ return $_SERVER[$key2];
+}
+
?>
diff --git a/web/.ht-inc/conf-default.php b/web/.ht-inc/conf-default.php
index d9022e3..50f204b 100644
--- a/web/.ht-inc/conf-default.php
+++ b/web/.ht-inc/conf-default.php
@@ -138,7 +138,7 @@
"affiliationid" => 1,
"help" => "Only use Local Account if there are no other options"),
/*"Shibboleth (UNC Federation)" => array("type" => "redirect",
- "URL" => "https://federation.northcarolina.edu/wayf/wayf_framed.php?fed=FED_SHIB_UNC_DEV&version=dropdown&entityID=https%3A%2F%2Fvcl.ncsu.edu%2Fsp%2Fshibboleth&return=http%3A%2F%2Fvcl.ncsu.edu%2FShibboleth.sso%2FDS%3FSAMLDS%3D1%26target%3Dhttp%3A%2F%2Fvcl.ncsu.edu%2Fscheduling%2Fshibauth%2F",
+ "URL" => "https://federation.northcarolina.edu/wayf/wayf_framed.php?fed=FED_SHIB_UNC_DEV&version=dropdown&entityID=https%3A%2F%2Fvcl.ncsu.edu%2Fsp%2Fshibboleth&return=http%3A%2F%2Fvcl.ncsu.edu%2FShibboleth.sso%2FDS%3FSAMLDS%3D1%26target%3Dhttp%3A%2F%2Fvcl.ncsu.edu%2Fscheduling%2F/",
"affiliationid" => 0, // this should always be 0 for Shibboleth authentication
"help" => "Use Shibboleth (UNC Federation) if you are from a University in the UNC system and do not see another method specifically for your university"),*/
/*"EXAMPLE1 LDAP" => array("type" => "ldap",
diff --git a/web/.ht-inc/utils.php b/web/.ht-inc/utils.php
index 763e4b2..c13be06 100644
--- a/web/.ht-inc/utils.php
+++ b/web/.ht-inc/utils.php
@@ -170,11 +170,17 @@
if(! is_null($userid))
$authed = 1;
}
- elseif(preg_match('/_shibsession/', join(',', array_keys($_COOKIE)))) {
- # redirect to shibauth directory
- header('Location: ' . BASEURL . "/shibauth/");
- dbDisconnect();
- exit;
+ else {
+ global $authFuncs;
+ foreach($authFuncs as $type) {
+ if($type['test']()) {
+ $userid = $type['auth']();
+ if(! is_null($userid)) {
+ $authed = 1;
+ break;
+ }
+ }
+ }
}
# end auth check
@@ -13106,7 +13112,7 @@
////////////////////////////////////////////////////////////////////////////////
function sendHeaders() {
global $mode, $user, $authed, $oldmode, $actionFunction;
- global $shibauthed;
+ global $shibauthed, $authFuncs;
if(! $authed && $mode == "auth") {
header("Location: " . BASEURL . SCRIPT . "?mode=selectauth");
dbDisconnect();
@@ -13114,78 +13120,22 @@
}
switch($mode) {
case 'logout':
- if($shibauthed) {
- $shibdata = getShibauthData($shibauthed);
- // TODO make shib-logouturl comparison caseless
- if(array_key_exists('Shib-logouturl', $shibdata) &&
- ! empty($shibdata['Shib-logouturl'])) {
- dbDisconnect();
- header("Location: {$shibdata['Shib-logouturl']}");
- exit;
- }
- }
- case 'shiblogout':
- setcookie("ITECSAUTH", "", time() - 10, "/", COOKIEDOMAIN);
- setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
- if($shibauthed) {
- $msg = '';
- $shibdata = getShibauthData($shibauthed);
- # find and clear shib cookies
- /*foreach(array_keys($_COOKIE) as $key) {
- if(preg_match('/^_shibsession[_0-9a-fA-F]+$/', $key))
- setcookie($key, "", time() - 10, "/", $_SERVER['SERVER_NAME']);
- elseif(preg_match('/^_shibstate_/', $key))
- setcookie($key, "", time() - 10, "/", $_SERVER['SERVER_NAME']);
- }*/
- doQuery("DELETE FROM shibauth WHERE id = $shibauthed", 101);
+ $authtype = getAuthTypeFromAuthCookie();
+ if(is_null($authtype)) {
stopSession();
dbDisconnect();
- if(array_key_exists('Shib-logouturl', $shibdata) &&
- ! empty($shibdata['Shib-logouturl'])) {
- print "<html>\n";
- print " <head>\n";
- print " <style type=\"text/css\">\n";
- print " .red {\n";
- print " color: red;\n";
- print " }\n";
- print " body{\n";
- print " margin:0px; color: red;\n";
- print " }\n";
- print " </style>\n";
- print " </head>\n";
- print " <body>\n";
- print " <span class=red>Done.</span> <a target=\"_top\" href=\"" . BASEURL . "/\">Return to VCL</a>\n";
- print " </body>\n";
- print "</html>\n";
- }
- else {
- print "<html>\n";
- print "<head>\n";
- print "<META HTTP-EQUIV=REFRESH CONTENT=\"5;url=" . BASEURL . "\">\n";
- print "<style type=\"text/css\">\n";
- print " .hidden {\n";
- print " display: none;\n";
- print " }\n";
- print "</style>\n";
- print "</head>\n";
- print "<body>\n";
- print "Logging out of VCL...";
- print "<iframe src=\"https://{$_SERVER['SERVER_NAME']}/Shibboleth.sso/Logout\" class=hidden>\n";
- print "</iframe>\n";
- if(array_key_exists('Shib-Identity-Provider', $shibdata) &&
- ! empty($shibdata['Shib-Identity-Provider'])) {
- $tmp = explode('/', $shibdata['Shib-Identity-Provider']);
- $idp = "{$tmp[0]}//{$tmp[2]}";
- print "<iframe src=\"$idp/idp/logout.jsp\" class=hidden>\n";
- print "</iframe>\n";
- }
- print "</body>\n";
- print "</html>\n";
- }
+ header("Location: " . BASEURL . SCRIPT);
exit;
}
- header("Location: " . HOMEURL);
+ $authFuncs[$authtype]['unauth']('headers');
+ setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
+ $authed = 0;
+ ob_start();
+ printHTMLHeader();
+ $authFuncs[$authtype]['unauth']('content');
+ printHTMLFooter();
stopSession();
+ ob_end_flush();
dbDisconnect();
exit;
}
diff --git a/web/shibauth/index.php b/web/shibauth/index.php
index 64c33c5..c6ad42a 100644
--- a/web/shibauth/index.php
+++ b/web/shibauth/index.php
@@ -1,263 +1,4 @@
<?php
-/*
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You 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.
-*/
-
-chdir("..");
-require_once('.ht-inc/conf.php');
-
-require_once('.ht-inc/utils.php');
-require_once('.ht-inc/errors.php');
-function getFooter() {}
-$noHTMLwrappers = array();
-
-dbConnect();
-
-header("Cache-Control: no-cache, must-revalidate");
-header("Expires: Sat, 1 Jan 2000 00:00:00 GMT");
-
-/*
- # check for eppn; if there, see if it is a user we already have
- if(array_key_exists('eppn', $_SERVER)) {
- #$tmp = explode('@', $_SERVER['eppn']);
- $tmp = explode(';', $_SERVER['eppn']);
- $tmp = explode('@', $tmp[0]);
- $query = "SELECT u.firstname, "
- . "u.lastname "
- . "FROM user u, "
- . "affiliation a "
- . "WHERE u.unityid = '{$tmp[0]}' AND "
- . "a.shibname = '{$tmp[1]}' AND "
- . "u.affiliationid = a.id";
- $qh = doQuery($query, 101);
- if($row = mysqli_fetch_assoc($qh)) {
- $_SERVER['sn'] = $row['lastname'];
- $_SERVER['givenName'] = $row['firstname'];
- }
- else {
-*/
-
-if(! array_key_exists('eppn', $_SERVER)) {
- # check to see if any shib stuff in $_SERVER, if not redirect
- $keys = array_keys($_SERVER);
- $allkeys = '{' . implode('{', $keys);
- if(! preg_match('/\{Shib-/', $allkeys)) {
- # no shib data, clear _shibsession cookie
- #print "$allkeys<br>\n";
- foreach(array_keys($_COOKIE) as $key) {
- if(preg_match('/^_shibsession[_0-9a-fA-F]+$/', $key))
- setcookie($key, "", time() - 10, "/", $_SERVER['SERVER_NAME']);
- }
- # redirect to main select auth page
- header("Location: " . BASEURL . SCRIPT . "?mode=selectauth");
- dbDisconnect();
- exit;
- }
- print "<h2>Error with Shibboleth authentication</h2>\n";
- print "You have attempted to log in using Shibboleth from an<br>\n";
- print "institution that does not allow VCL to see your<br><br>\n";
- print "eduPersonPrincipalName.<br><br>\n";
- print "You need to contact the administrator of your institution's<br>\n";
- print "IdP to have eduPersonPrincipalName made available to VCL in<br>\n";
- print "order to log in using Shibboleth.\n";
-
- $msg = "Someone tried to log in to VCL using Shibboleth from an IdP "
- . "that does not release eppn to us.\n\n"
- . "The following data was in \$_SERVER:\n\n";
- foreach($_SERVER as $key => $val)
- $msg .= "$key => $val\n";
- $mailParams = "-f" . ENVELOPESENDER;
- mail(ERROREMAIL, "Error with VCL pages (eppn not provided)", $msg, '', $mailParams);
- dbDisconnect();
- exit;
-}
-
-// open keys
-$fp = fopen(".ht-inc/keys.pem", "r");
-$key = fread($fp, 8192);
-fclose($fp);
-$keys["private"] = openssl_pkey_get_private($key, $pemkey);
-if(! $keys['private'])
- abort(6);
-$fp = fopen(".ht-inc/pubkey.pem", "r");
-$key = fread($fp, 8192);
-fclose($fp);
-$keys["public"] = openssl_pkey_get_public($key);
-if(! $keys['public'])
- abort(7);
-
-# get VCL affiliation from shib affiliation
-$tmp = explode(';', $_SERVER['eppn']);
-$tmp = explode('@', $tmp[0]);
-$username = strtolower($tmp[0]);
-$tmp1 = vcl_mysql_escape_string(strtolower($tmp[1]));
-$query = "SELECT name, shibonly FROM affiliation WHERE shibname = '$tmp1'";
-$qh = doQuery($query, 101);
-# if shib affiliation not already in VCL, create affiliation
-if(! ($row = mysqli_fetch_assoc($qh))) {
- $affil = strtolower($tmp[1]);
- $tmp = explode('.', $affil);
- array_pop($tmp);
- $affilname = strtoupper(implode('', $tmp));
- $affilname = preg_replace('/[^A-Z0-9]/', '', $affilname);
- $query = "SELECT name, "
- . "shibname "
- . "FROM affiliation "
- . "WHERE name LIKE '$affilname%' "
- . "ORDER BY name DESC "
- . "LIMIT 1";
- $qh = doQuery($query, 101);
- if($row = mysqli_fetch_assoc($qh)) {
- if(preg_match("/$affilname([0-9]+)/", $row['name'], $matches)) {
- $cnt = $matches[1];
- $cnt++;
- $newaffilname = $affilname . $cnt;
- }
- elseif($affilname != $row['name'] && $affil != $row['shibname']) {
- $newaffilname = $affilname;
- }
- else {
- $msg = "Someone tried to log in to VCL using Shibboleth from an IdP "
- . "affiliation that could not be automatically added.\n\n"
- . "eppn: {$_SERVER['eppn']}\n"
- . "givenName: {$_SERVER['givenName']}\n"
- . "sn: {$_SERVER['sn']}\n";
- if(array_key_exists('mail', $_SERVER))
- $msg .= "mail: {$_SERVER['mail']}\n\n";
- $msg .="tried to add VCL affiliation name \"$affilname\" with "
- . "shibname \"$affil\"";
- $mailParams = "-f" . ENVELOPESENDER;
- mail(ERROREMAIL, "Error with VCL pages (problem adding shib affil)", $msg, '', $mailParams);
- print "<html><head></head><body>\n";
- print "<h2>Error encountered</h2>\n";
- print "You have attempted to log in to VCL using a Shibboleth<br>\n";
- print "Identity Provider that VCL has not been configured to<br>\n";
- print "work with. VCL administrators have been notified of the<br>\n";
- print "problem.<br>\n";
- print "</body></html>\n";
- dbDisconnect();
- exit;
- }
- }
- else
- $newaffilname = $affilname;
- $query = "INSERT INTO affiliation "
- . "(name, "
- . "shibname, "
- . "shibonly) "
- . "VALUES "
- . "('$newaffilname', "
- . "'" . vcl_mysql_escape_string($affil) . "', "
- . "1)";
- doQuery($query, 101, 'vcl', 1);
- unset($row);
- $row = array('name' => $newaffilname, 'shibonly' => 1);
-}
-$affil = $row['name'];
-# create VCL userid
-$userid = "$username@$affil";
-
-if($row['shibonly']) {
- $userdata = updateShibUser($userid);
- updateShibGroups($userdata['id'], $_SERVER['affiliation']);
- $usernid = $userdata['id'];
-}
-else {
- $usernid = getUserlistID($userid, 1);
- if(is_null($usernid)) {
- $tmp = updateShibUser($userid);
- $usernid = $tmp['id'];
- }
-}
-
-$affilid = getAffiliationID($affil);
-addLoginLog($userid, 'shibboleth', $affilid, 1);
-
-# uncomment the following and change EXAMPLE1 to match your needs to add all
-# users from a specific affiliation to a particular user group
-/*if($affil == 'EXAMPLE1') {
- $gid = getUserGroupID('All EXAMPLE1 Users', $affilid);
- $query = "INSERT IGNORE INTO usergroupmembers "
- . "(userid, usergroupid) "
- . "VALUES ($usernid, $gid)";
- doQuery($query, 307);
-}*/
-
-if(array_key_exists('Shib-logouturl', $_SERVER))
- $logouturl = $_SERVER['Shib-logouturl'];
-else
- $logouturl = '';
-
-# save data to shibauth table
-$shibdata = array('Shib-Application-ID' => $_SERVER['Shib-Application-ID'],
- 'Shib-Identity-Provider' => $_SERVER['Shib-Identity-Provider'],
- #'Shib-AuthnContext-Dec' => $_SERVER['Shib-AuthnContext-Decl'],
- 'Shib-logouturl' => $logouturl,
- 'eppn' => $_SERVER['eppn'],
- 'unscoped-affiliation' => $_SERVER['unscoped-affiliation'],
- 'affiliation' => $_SERVER['affiliation'],
-);
-$serdata = vcl_mysql_escape_string(serialize($shibdata));
-$query = "SELECT id "
- . "FROM shibauth "
- . "WHERE sessid = '{$_SERVER['Shib-Session-ID']}'";
-$qh = doQuery($query, 101);
-if($row = mysqli_fetch_assoc($qh)) {
- $shibauthid = $row['id'];
-}
-else {
- $ts = strtotime($_SERVER['Shib-Authentication-Instant']);
- $ts = unixToDatetime($ts);
- $query = "INSERT INTO shibauth "
- . "(userid, "
- . "ts, "
- . "sessid, "
- . "data) "
- . "VALUES "
- . "($usernid, "
- . "'$ts', "
- . "'{$_SERVER['Shib-Session-ID']}', "
- . "'$serdata')";
- doQuery($query, 101);
- $qh = doQuery("SELECT LAST_INSERT_ID() FROM shibauth", 101);
- if(! $row = mysqli_fetch_row($qh)) {
- # todo
- }
- $shibauthid = $row[0];
-}
-
-# get cookie data
-$cookie = getAuthCookieData($userid, 600, $shibauthid);
-# set cookie
-if(version_compare(PHP_VERSION, "5.2", ">=") == true)
- #setcookie("VCLAUTH", "{$cookie['data']}", $cookie['ts'], "/", COOKIEDOMAIN, 1, 1);
- setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0, 1);
-else
- #setcookie("VCLAUTH", "{$cookie['data']}", $cookie['ts'], "/", COOKIEDOMAIN, 1);
- setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN);
-# set skin cookie based on affiliation
-switch($affil) {
- case 'Example1':
- case 'EXAMPLE2':
- $skin = strtoupper($affil);
- setcookie("VCLSKIN", $skin, (time() + 2678400), "/", COOKIEDOMAIN);
- break;
- default:
- setcookie("VCLSKIN", "default", (time() + 2678400), "/", COOKIEDOMAIN);
-}
-header("Location: " . BASEURL . "/");
-dbDisconnect();
+@require_once('../.ht-inc/conf.php');
+header("Location: " . BASEURL . SCRIPT);
?>