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>&nbsp;&nbsp;&nbsp;<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();
+?>


Reply via email to