Author: jfthomps
Date: Thu Jan 15 14:40:30 2009
New Revision: 734842
URL: http://svn.apache.org/viewvc?rev=734842&view=rev
Log:
VCL-4
added support for Shibboleth authentication
authentication.php:
-modified getAuthCookieData to accept $shibauthid as an extra argument; if
passed in, it is added to the end of the cookie data before encryption
-corrected description header for readAuthCookie
-modified readAuthCookie to set global $shibauthed to the value passed to
getAuthCookieData as $shibauthid; if $shibauthed gets set, the shibauth table
is checked to see if a corresponding record exists for it; if not the VCLAUTH
cookie is cleared and the user is redirected to the login page
-modified ldapLogin and localLogin to set VCLAUTH as a session cookie instead
of a lifetime cookie - this was done because the UNC Federation logout page
uses iframes to load each SP's logout page and IE7 seems to only pass session
cookies to iframes (and not lifetime cookies) so the user was not authenticated
in the iframe to be correctly logged out
conf.php:
-added (commented out) Shibboleth as a type in $authMechs, leaving the UNC
federation config as an example
-added (commented out ) require_once for .ht-inc/authmethods/shibauth.php
states.php:
-added shiblogout to $actions['entry']
-created entries for logout and shiblogout in $actions['pages'] array
utils.php:
-modified initGlobals - added check for _shibsession cookie to block of
conditionals checking to see if user is authenticated
-modified getUserInfo to include shibonly in user data and to not try to pull
updated information about the user if shibonly is true
-added getShibauthData
-modified sendHeaders - changed conditional for $mode being logout to a switch
statement that handles $mode being both logout and shiblogout
index.php:
-added initialization of global $shibauthed
added .ht-inc/authmethods/shibauth.php
added added shibauth directory
added shibauth/.htaccess
added shibauth/index.php
Added:
incubator/vcl/trunk/web/.ht-inc/authmethods/shibauth.php
incubator/vcl/trunk/web/shibauth/
incubator/vcl/trunk/web/shibauth/.htaccess
incubator/vcl/trunk/web/shibauth/index.php
Modified:
incubator/vcl/trunk/web/.ht-inc/authentication.php
incubator/vcl/trunk/web/.ht-inc/conf.php
incubator/vcl/trunk/web/.ht-inc/states.php
incubator/vcl/trunk/web/.ht-inc/utils.php
incubator/vcl/trunk/web/index.php
Modified: incubator/vcl/trunk/web/.ht-inc/authentication.php
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/authentication.php?rev=734842&r1=734841&r2=734842&view=diff
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/authentication.php (original)
+++ incubator/vcl/trunk/web/.ht-inc/authentication.php Thu Jan 15 14:40:30 2009
@@ -35,14 +35,19 @@
/// a timestamp
///
////////////////////////////////////////////////////////////////////////////////
-function getAuthCookieData($loginid, $valid=600) {
+function getAuthCookieData($loginid, $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";
- $cdata = "$loginid|$remoteIP|$ts";
+ if($shibauthid)
+ $cdata = "$loginid|$remoteIP|$ts|$shibauthid";
+ else
+ $cdata = "$loginid|$remoteIP|$ts";
+ # 245 characters can be encrypted; anything over that, and
+ # openssl_private_encrypt will fail
if(! openssl_private_encrypt($cdata, $cryptdata, $keys["private"]))
return "Failed to encrypt cookie data";
@@ -53,26 +58,16 @@
///
/// \fn readAuthCookie()
///
-/// \return on success, an array with the following indices:\n
-/// \b userid - numeric user id\n
-/// \b first - first name\n
-/// \b middle - middle name (may be an empty string)\n
-/// \b last - last name\n
-/// \b email - email address\n
-/// \b created - timestamp of account creation (in mysql datetime format)\n
-/// \b ts - timestamp that authentication cookie will expire (in unix timestamp
-/// format)\n
-/// \b type - 'fixed' or 'floating' - fixed = tied to specific IP address;
-/// floating = not tied to any IP address (only fixed is supported at this
time)\n
-/// \b remoteIP - empty for type 'floating'; user's IP address for type 'fixed'
-///
-/// \brief parses the ITECSAUTH cookie and returns an array; on failure,
returns
-/// an empty array. You will then need to call ITECSAUTH_getError to get
-/// the reason.
+/// \return on success, userid of user in VCLAUTH cookie in u...@affil form;
+/// NULL on failure
+///
+/// \brief parses the VCLAUTH cookie to get the contained userid; also checks
+/// that the contained remoteIP matches the current remoteIP and that the
cookie
+/// has not expired
///
////////////////////////////////////////////////////////////////////////////////
function readAuthCookie() {
- global $keys, $AUTHERROR;
+ global $keys, $AUTHERROR, $shibauthed;
if(get_magic_quotes_gpc())
$cookie = stripslashes($_COOKIE["VCLAUTH"]);
else
@@ -87,6 +82,25 @@
$loginid = $tmparr[0];
$remoteIP = $tmparr[1];
$ts = $tmparr[2];
+ if(count($tmparr) > 3) {
+ $shibauthed = $tmparr[3];
+
+ # check to see if shibauth entry still exists for $shibauthed
+ $query = "SELECT ts FROM shibauth WHERE id = $shibauthed";
+ $qh = doQuery($query, 101);
+ if($row = mysql_fetch_assoc($qh)) {
+ $shibstart = $row['ts'];
+ # TODO if $shibstart is too old, expire the login
session
+ }
+ else {
+ # user should have been logged out, log them out now
+ setcookie("VCLAUTH", "", time() - 10, "/",
COOKIEDOMAIN);
+ stopSession();
+ dbDisconnect();
+ header("Location: " . BASEURL);
+ exit;
+ }
+ }
if($ts < time()) {
$AUTHERROR["code"] = 4;
@@ -409,9 +423,9 @@
$cookie = getAuthCookieData("$userid@" .
getAffiliationName($authMechs[$authtype]['affiliationid']));
// 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, 0);
# set skin cookie based on affiliation
/*if(getAffiliationName($authMechs[$authtype]['affiliationid'])
== 'EXAMPLE1')
setcookie("VCLSKIN", "EXAMPLE1", (time() + (SECINDAY *
31)), "/", COOKIEDOMAIN);
@@ -452,9 +466,9 @@
//set cookie
$cookie = getAuthCookieData("$use...@local");
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);
//load main page
setcookie("VCLSKIN", "NCSU", (time() + (SECINDAY * 31)), "/",
COOKIEDOMAIN);
header("Location: " . BASEURL . SCRIPT);
Added: incubator/vcl/trunk/web/.ht-inc/authmethods/shibauth.php
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/authmethods/shibauth.php?rev=734842&view=auto
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/authmethods/shibauth.php (added)
+++ incubator/vcl/trunk/web/.ht-inc/authmethods/shibauth.php Thu Jan 15
14:40:30 2009
@@ -0,0 +1,155 @@
+<?php
+/**
+ * \file
+ */
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn updateShibUser($userid)
+///
+/// \param $userid - id of a user in use...@affiliation form
+///
+/// \return an array with these keys:\n
+/// \b firstname
+/// \b lastname
+/// \b email
+/// \b unityid - userid for user
+/// \b affilid - id from affiliation table for user's affiliation
+/// \b id - id of user from user table
+///
+/// \brief updates user's first name, last name, and email address, and
+/// lastupdated timestamp in the user table from data provided by shibboleth
+///
+////////////////////////////////////////////////////////////////////////////////
+function updateShibUser($userid) {
+ global $mysql_link_vcl;
+ getAffilidAndLogin($userid, $affilid);
+
+ 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']);
+ $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']);
+ $displast = array_pop($names);
+ $user['firstname'] = implode(' ', $names);
+ }
+ }
+ else
+ $user['firstname'] = $_SERVER['givenName'];
+ if(array_key_exists('sn', $_SERVER))
+ $user["lastname"] = $_SERVER['sn'];
+ else
+ $user['lastname'] = $displast;
+ $user["email"] = $_SERVER['mail'];
+ $user['unityid'] = $userid;
+ $user['affilid'] = $affilid;
+
+ # check to see if this user already exists in our db
+ $query = "SELECT id "
+ . "FROM user "
+ . "WHERE unityid = '$userid' AND "
+ . "affiliationid = $affilid";
+ $qh = doQuery($query, 101);
+ if(! $row = mysql_fetch_assoc($qh))
+ # add user to our db
+ return addShibUser($user);
+
+ # update user's data in db
+ $user['id'] = $row['id'];
+ $query = "UPDATE user "
+ . "SET firstname = '{$user['firstname']}', "
+ . "lastname = '{$user['lastname']}', "
+ . "email = '{$user['email']}', "
+ . "emailnotices = 0, "
+ . "lastupdated = NOW() "
+ . "WHERE uid = {$user['id']}";
+ doQuery($query, 101, 'vcl', 1);
+ return $user;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn addShibUser($user)
+///
+/// \param $user - array of user data with these keys:\n
+/// \b unityid - userid\n
+/// \b affilid - id from affiliation table matching user's affiliation\n
+/// \b firstname\n
+/// \b lastname\n
+/// \b email
+///
+/// \return an array with all of the values from $user along with an additional
+/// key named 'id' that is the new user's id from the user table
+///
+/// \brief adds $user to the user table
+///
+////////////////////////////////////////////////////////////////////////////////
+function addShibUser($user) {
+ global $mysql_link_vcl;
+ $query = "INSERT INTO user "
+ . "(unityid, "
+ . "affiliationid, "
+ . "firstname, "
+ . "lastname, "
+ . "email, "
+ . "emailnotices, "
+ . "lastupdated) "
+ . "VALUES ("
+ . "'{$user['unityid']}', "
+ . "{$user['affilid']}, "
+ . "'{$user['firstname']}', "
+ . "'{$user['lastname']}', "
+ . "'{$user['email']}', "
+ . "0, "
+ . "NOW())";
+ doQuery($query, 101, 'vcl', 1);
+ if(mysql_affected_rows($mysql_link_vcl)) {
+ $user['id'] = mysql_insert_id($mysql_link_vcl);
+ return $user;
+ }
+ else
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn updateShibGroups($usernid, $groups)
+///
+/// \param $usernid - id from user table
+/// \param $groups - data provided in the eduPersonScopedAffiliation attribute
+///
+/// \brief converts the shibboleth affiliation to VCL affiliation, prepends
+/// 'shib-' to each of the group names and calls updateGroups to add the user
+/// to each of the shibboleth groups
+///
+////////////////////////////////////////////////////////////////////////////////
+function updateShibGroups($usernid, $groups) {
+ $groups = explode(';', $groups);
+ $newusergroups = array();
+ foreach($groups as $group) {
+ # make sure $group contains non-whitespace
+ if(! preg_match('/\w/', $group))
+ continue;
+ list($name, $shibaffil) = explode('@', $group);
+ # get id for the group's affiliation
+ $query = "SELECT id FROM affiliation WHERE shibname =
'$shibaffil'";
+ $qh = doQuery($query, 101);
+ $row = mysql_fetch_assoc($qh);
+ $affilid = $row['id'];
+ # prepend shib- and escape it for mysql
+ $grp = mysql_escape_string("shib-" . $name);
+ array_push($newusergroups, getUserGroupID($grp, $affilid));
+ }
+ $newusergroups = array_unique($newusergroups);
+ if(! empty($newusergroups))
+ updateGroups($newusergroups, $usernid);
+}
+
+?>
Modified: incubator/vcl/trunk/web/.ht-inc/conf.php
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/conf.php?rev=734842&r1=734841&r2=734842&view=diff
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/conf.php (original)
+++ incubator/vcl/trunk/web/.ht-inc/conf.php Thu Jan 15 14:40:30 2009
@@ -77,6 +77,10 @@
"Local Account" => array("type" => "local",
"affiliationid" => 4,
"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",
+ "affiliationid" => 0,
+ "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",
"server" => "ldap.example.com", # hostname
of the ldap server
"binddn" => "dc=example,dc=com", # base dn
for ldap server
@@ -124,4 +128,5 @@
#require_once(".ht-inc/authmethods/itecsauth.php");
#require_once(".ht-inc/authmethods/ldapauth.php");
+#require_once(".ht-inc/authmethods/shibauth.php");
?>
Modified: incubator/vcl/trunk/web/.ht-inc/states.php
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/states.php?rev=734842&r1=734841&r2=734842&view=diff
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/states.php (original)
+++ incubator/vcl/trunk/web/.ht-inc/states.php Thu Jan 15 14:40:30 2009
@@ -42,6 +42,7 @@
'helpform',
'viewdocs',
'logout',
+ 'shiblogout',
'xmlrpccall',
'selectauth',
'xmlrpcaffiliations',
@@ -583,5 +584,7 @@
$actions['pages']['continuationsError'] = "misc";
$actions['pages']['clearCache'] = "misc";
$actions['pages']['errorrpt'] = "misc";
+$actions['pages']['logout'] = "misc";
+$actions['pages']['shiblogout'] = "misc";
?>
Modified: incubator/vcl/trunk/web/.ht-inc/utils.php
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/utils.php?rev=734842&r1=734841&r2=734842&view=diff
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/utils.php (original)
+++ incubator/vcl/trunk/web/.ht-inc/utils.php Thu Jan 15 14:40:30 2009
@@ -160,6 +160,12 @@
if(! is_null($userid))
$authed = 1;
}
+ elseif(preg_match('/_shibsession/', join(',', array_keys($_COOKIE)))) {
+ # redirect to shibauth directory
+ header('Location: ' . BASEURL . "/shibauth/");
+ dbDisconnect();
+ exit;
+ }
# end auth check
if($authed && $mode == 'selectauth')
@@ -189,6 +195,7 @@
require_once(".ht-inc/requests.php");
if($mode != "logout" &&
+ $mode != "shiblogout" &&
$mode != "vcldquery" &&
$mode != "xmlrpccall" &&
$mode != "xmlrpcaffiliations" &&
@@ -3117,7 +3124,8 @@
. "u.mapprinters AS mapprinters, "
. "u.mapserial AS mapserial, "
. "u.showallgroups, "
- . "u.lastupdated AS lastupdated "
+ . "u.lastupdated AS lastupdated, "
+ . "af.shibonly "
. "FROM user u, "
. "curriculum c, "
. "IMtype i, "
@@ -3136,7 +3144,8 @@
if($user = mysql_fetch_assoc($qh)) {
if((datetimeToUnix($user["lastupdated"]) > time() - SECINDAY) ||
$user['unityid'] == 'vclreload' ||
- $user['affiliation'] == 'Local') {
+ $user['affiliation'] == 'Local' ||
+ $user['shibonly']) {
# get user's groups
$user["groups"] = getUsersGroups($user["id"], 1);
@@ -7991,6 +8000,45 @@
////////////////////////////////////////////////////////////////////////////////
///
+/// \fn getShibauthData($id)
+///
+/// \param $id - id for entry in shibauth table
+///
+/// \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 getShibauthData($id) {
+ $query = "SELECT id, "
+ . "userid, "
+ . "ts, "
+ . "sessid, "
+ . "data "
+ . "FROM shibauth "
+ . "WHERE id = $id";
+ $qh = doQuery($query, 101);
+ if($row = mysql_fetch_assoc($qh)) {
+ $data = unserialize($row['data']);
+ unset($row['data']);
+ $data2 = array_merge($row, $data);
+ return $data2;
+ }
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
/// \fn xmlrpccall()
///
/// \brief registers all functions available to xmlrpc, handles the current
@@ -8321,6 +8369,7 @@
////////////////////////////////////////////////////////////////////////////////
function sendHeaders() {
global $mode, $user, $authed, $oldmode, $viewmode, $actionFunction,
$skin;
+ global $shibauthed;
$setwrapreferer = processInputVar('am', ARG_NUMERIC, 0);
if(! $authed && $mode == "auth") {
/*if($oldmode != "auth" && $oldmode != "" &&
array_key_exists('mode', $_GET)) {
@@ -8346,12 +8395,59 @@
$cookieHeaderString =
"WRAP_REFERER=https://vcl.ncsu.edu/; path=/; domain=" . COOKIEDOMAIN;
header("Set-Cookie: $cookieHeaderString");
}
- if($mode == "logout") {
- setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
- header("Location: " . HOMEURL);
- stopSession();
- dbDisconnect();
- exit;
+ switch($mode) {
+ case 'logout':
+ if($shibauthed) {
+ $shibdata = getShibauthData($shibauthed);
+ dbDisconnect();
+ header("Location:
{$shibdata['Shib-logouturl']}");
+ exit;
+ }
+ case 'shiblogout':
+ setcookie("WRAP16", "", time() - 10, "/", COOKIEDOMAIN);
+ setcookie("WRAP_REFERER", "", time() - 10, "/",
COOKIEDOMAIN);
+ 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);
+ stopSession();
+ dbDisconnect();
+ 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 " <iframe
src=\"http://{$_SERVER['SERVER_NAME']}/Shibboleth.sso/Logout\" class=hidden>\n";
+ #print " </iframe>\n";
+ /*if($mode == 'logout') {
+ print " <iframe
src=\"{$shibdata['Shib-logouturl']}\" class=hidden>\n";
+ print " </iframe>\n";
+ }*/
+ print " </body>\n";
+ print "</html>\n";
+ exit;
+ }
+ header("Location: " . HOMEURL);
+ stopSession();
+ dbDisconnect();
+ exit;
}
if($mode == "submitviewmode") {
$expire = time() + 31536000; //expire in 1 year
Modified: incubator/vcl/trunk/web/index.php
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/web/index.php?rev=734842&r1=734841&r2=734842&view=diff
==============================================================================
--- incubator/vcl/trunk/web/index.php (original)
+++ incubator/vcl/trunk/web/index.php Thu Jan 15 14:40:30 2009
@@ -40,6 +40,7 @@
$cache['unityids'] = array();
$cache['nodeprivs']['resources'] = array();
$docreaders = array();
+$shibauthed = 0;
require_once(".ht-inc/states.php");
Added: incubator/vcl/trunk/web/shibauth/.htaccess
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/web/shibauth/.htaccess?rev=734842&view=auto
==============================================================================
--- incubator/vcl/trunk/web/shibauth/.htaccess (added)
+++ incubator/vcl/trunk/web/shibauth/.htaccess Thu Jan 15 14:40:30 2009
@@ -0,0 +1,3 @@
+AuthType shibboleth
+ShibRequireSession Off
+require shibboleth
Added: incubator/vcl/trunk/web/shibauth/index.php
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/web/shibauth/index.php?rev=734842&view=auto
==============================================================================
--- incubator/vcl/trunk/web/shibauth/index.php (added)
+++ incubator/vcl/trunk/web/shibauth/index.php Thu Jan 15 14:40:30 2009
@@ -0,0 +1,206 @@
+<?php
+chdir("..");
+require_once('.ht-inc/conf.php');
+
+header("Cache-Control: no-cache, must-revalidate");
+header("Expires: Sat, 1 Jan 2000 00:00:00 GMT");
+
+if(! array_key_exists('eppn', $_SERVER) ||
+ ! array_key_exists('mail', $_SERVER) ||
+ (! (array_key_exists('sn', $_SERVER) &&
+ array_key_exists('givenName', $_SERVER)) &&
+ ! array_key_exists('displayName', $_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
+ 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");
+ 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 all of these<br>\n";
+ print "attributes:<br>\n";
+ print "<ul>\n";
+ print "<li>eduPersonPrincipalName</li>\n";
+ print "<li>mail</li>\n";
+ print "</ul>\n";
+ print "and either:\n";
+ print "<ul>\n";
+ print "<li>sn and givenName</li>\n";
+ print "</ul>\n";
+ print "or:\n";
+ print "<ul>\n";
+ print "<li>displayName</li>\n";
+ print "</ul>\n";
+ print "You need to contact the administrator of your
institution's<br>\n";
+ print "IdP to have all of those attributes be available to VCL
in<br>\n";
+ print "order to log in using Shibboleth.\n";
+ exit;
+}
+
+require_once('.ht-inc/utils.php');
+require_once('.ht-inc/errors.php');
+function getFooter() {}
+$noHTMLwrappers = array();
+
+dbConnect();
+
+// 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']);
+$username = strtolower($tmp[0]);
+$tmp1 = 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 = mysql_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 "
+ . "FROM affiliation "
+ . "WHERE name LIKE '$affilname%' "
+ . "ORDER BY name DESC "
+ . "LIMIT 1";
+ $qh = doQuery($query, 101);
+ if($row = mysql_fetch_assoc($qh)) {
+ if(preg_match("/$affilname([0-9]+)/", $row['name'], $matches)) {
+ $cnt = $matches[1];
+ $cnt++;
+ $newaffilname = $affilname . $cnt;
+ }
+ 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"
+ . "mail: {$_SERVER['mail']}\n\n"
+ . "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', "
+ . "'" . 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 = "$usern...@$affil";
+
+if($row['shibonly']) {
+ $userdata = updateShibUser($userid);
+ updateShibGroups($userdata['id'], $_SERVER['affiliation']);
+ $usernid = $userdata['id'];
+}
+else
+ $usernid = getUserlistID($userid);
+
+# 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' => $_SERVER['Shib-logouturl'],
+ 'eppn' => $_SERVER['Shib-logouturl'],
+ 'unscoped-affiliation' => $_SERVER['unscoped-affiliation'],
+ 'affiliation' => $_SERVER['affiliation'],
+);
+$serdata = mysql_escape_string(serialize($shibdata));
+$query = "SELECT id "
+ . "FROM shibauth "
+ . "WHERE sessid = '{$_SERVER['Shib-Session-ID']}'";
+$qh = doQuery($query, 101);
+if($row = mysql_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 = mysql_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 'WakeTech':
+ case 'JohnstonCC':
+ $skin = strtoupper($affil);
+ case 'NCCU':
+ case 'ECU':
+ case 'UNCG':
+ case 'WCU':
+ setcookie("VCLSKIN", $skin, (time() + (SECINDAY * 31)), "/",
COOKIEDOMAIN);
+ break;
+ default:
+ setcookie("VCLSKIN", "NCSU", (time() + (SECINDAY * 31)), "/",
COOKIEDOMAIN);
+}
+header("Location: " . BASEURL . "/");
+dbDisconnect();
+?>