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