Merge branch 'develop' into VCL-1087_VCL_CAS_SSO
diff --git a/web/.ht-inc/authentication.php b/web/.ht-inc/authentication.php
index cb72534..b2a3a80 100644
--- a/web/.ht-inc/authentication.php
+++ b/web/.ht-inc/authentication.php
@@ -212,6 +212,11 @@
printLoginPageWithSkin($authtype);
return;
}
+ elseif($authMechs[$authtype]['type'] == 'cas') {
+ validateCASUser($authtype);
+ dbDisconnect();
+ return;
+ }
}
require_once("themes/$skin/page.php");
$HTMLheader = getHeader(0);
diff --git a/web/.ht-inc/authmethods/casauth.php b/web/.ht-inc/authmethods/casauth.php
new file mode 100644
index 0000000..31325ac
--- /dev/null
+++ b/web/.ht-inc/authmethods/casauth.php
@@ -0,0 +1,206 @@
+<?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.
+ */
+
+/**
+ * \file
+ */
+
+require_once 'CAS.php';
+
+// Enable debugging
+phpCAS::setDebug();
+// Enable verbose error messages. Disable in production!
+phpCAS::setVerbose(FALSE);
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn validateCASUser($type, $loginid)
+///
+/// \param $type - an array from the $authMechs table
+///
+/// \return 1 user redirectied to CAS server, 0 if not, -1 on CAS error
+///
+/// \brief forces CAS authentication
+///
+////////////////////////////////////////////////////////////////////////////////
+function validateCASUser($type) {
+ global $authMechs;
+ $auth = $authMechs[$type];
+ $callbackURL = BASEURL . "/casauth/index.php?authtype=" . $type;
+ $casversion = ($auth['version'] == 2 ? CAS_VERSION_2_0 : CAS_VERSION_3_0);
+
+ if($auth['cacertpath'] != null)
+ if(file_exists($auth['cacertpath']))
+ phpCAS::setCasServerCACert($auth['cacertpath']);
+
+ phpCAS::client($casversion, $auth['host'], $auth['port'], $auth['context']);
+
+ // Set the service URL to use custom casauth directly within the VCL website
+ phpCAS::setFixedServiceURL($callbackURL);
+ if($auth['validatecassslcerts'] != true)
+ phpCAS::setNoCasServerValidation();
+
+ phpCAS::forceAuthentication();
+
+ # TODO - Check if server is available.
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn checkCASUserInDatabase($userid)
+///
+/// \param $type - an array from the $authMechs table
+/// \param $userid - a userid without the affiliation part
+///
+/// \return true if the user exists in the database, else false
+///
+/// \brief looks up $userid in VCL database
+///
+////////////////////////////////////////////////////////////////////////////////
+function checkCASUserInDatabase($type, $userid) {
+ global $authMechs, $mysql_link_vcl;
+ $loweruserid = strtolower($userid);
+ $loweruserid = mysql_real_escape_string($loweruserid);
+ $query = "SELECT id "
+ . "FROM user "
+ . "WHERE unityid = '$userid' AND "
+ . "affiliationid = {$authMechs[$type]['affiliationid']}";
+ $qh = doQuery($query, 101);
+ if($row = mysql_fetch_assoc($qh)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn addCASUser($authtype, $userid)
+///
+/// \param $userinfo - an array with user information
+///
+/// \return id from the user table or NULL on failure
+///
+/// \brief looks up $userid in CAS according to info in $authMechs array, adds
+/// the user to the user table, and returns the new id from the table
+///
+////////////////////////////////////////////////////////////////////////////////
+function addCASUser($userinfo) {
+ global $authMechs, $mysql_link_vcl;
+ $now = unixToDatetime(time());
+ if(array_key_exists('firstname', $userinfo))
+ $esc_firstname = mysql_real_escape_string($userinfo['firstname']);
+ if(array_key_exists('lastname', $userinfo))
+ $esc_lastname = mysql_real_escape_string($userinfo['lastname']);
+ if(array_key_exists('preferredname', $userinfo))
+ $esc_preferredname = mysql_real_escape_string($userinfo['preferredname']);
+ $query = "INSERT INTO user (unityid, affiliationid";
+ if(array_key_exists('firstname', $userinfo))
+ $query .= ", firstname";
+ if(array_key_exists('lastname', $userinfo))
+ $query .= ", lastname";
+ if(array_key_exists('preferredname', $userinfo))
+ $query .= ", preferredname";
+ if(array_key_exists('email', $userinfo))
+ $query .= ", email";
+ $query .= ", lastupdated) VALUES ( '{$userinfo['unityid']}', {$userinfo['affiliationid']}";
+ if(array_key_exists('firstname', $userinfo))
+ $query .= ",'{$esc_firstname}'";
+ if(array_key_exists('lastname', $userinfo))
+ $query .= ",'{$esc_lastname}'";
+ if(array_key_exists('preferredname', $userinfo))
+ $query .= ",'{$esc_preferredname}'";
+ if(array_key_exists('email', $userinfo))
+ $query .= ",'{$userinfo['email']}'";
+ $query .= ",'{$now}')";
+
+ doQuery($query, 101, 'vcl', 1);
+ if(mysql_affected_rows($mysql_link_vcl)) {
+ $qh = doQuery("SELECT LAST_INSERT_ID() FROM user", 101);
+ if(! $row = mysql_fetch_row($qh)) {
+ abort(101);
+ }
+
+ // Add to default group
+ if($userinfo['defaultgroup'] != null) {
+ $usergroups = array();
+ array_push($usergroups, getUserGroupID($userinfo['defaultgroup'], $userinfo['affiliationid']));
+ updateGroups($usergroups, $row[0]);
+ }
+
+ return $row[0];
+ }
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn updateCASUser($authtype, $userid)
+///
+/// \param $userinfo - an array with user information
+///
+/// \return FALSE if update failed, else TRUE
+///
+/// \brief pulls the user's information from CAS, updates it in the db, and
+/// returns an array of the information
+///
+////////////////////////////////////////////////////////////////////////////////
+function updateCASUser($userinfo) {
+ global $mysql_link_vcl;
+ $now = unixToDatetime(time());
+ $esc_userid = mysql_real_escape_string($userinfo['unityid']);
+ if(array_key_exists('firstname', $userinfo))
+ $esc_firstname = mysql_real_escape_string($userinfo['firstname']);
+ if(array_key_exists('lastname', $userinfo))
+ $esc_lastname = mysql_real_escape_string($userinfo['lastname']);
+ if(array_key_exists('preferredname', $userinfo))
+ $esc_preferredname = mysql_real_escape_string($userinfo['preferredname']);
+ $query = "UPDATE user SET unityid = '{$userinfo['unityid']}', lastupdated = '{$now}'";
+ if(array_key_exists('firstname', $userinfo))
+ $query .= ", firstname = '{$esc_firstname}' ";
+ if(array_key_exists('lastname', $userinfo))
+ $query .= ", lastname = '{$esc_lastname}' ";
+ if(array_key_exists('preferredname', $userinfo))
+ $query .= ", preferredname = '{$esc_preferredname}' ";
+ if(array_key_exists('email', $userinfo))
+ $query .= ", email = '{$userinfo['email']}' ";
+ $query .= "WHERE unityid = '{$esc_userid}' AND affiliationid = {$userinfo['affiliationid']}";
+ doQuery($query, 256, 'vcl', 1);
+ if(mysql_affected_rows($mysql_link_vcl) == -1) {
+ error_log(mysql_error($mysql_link_vcl));
+ error_log($query);
+ return FALSE;
+ }
+
+ // get id of current user
+ $query = "SELECT id FROM user WHERE unityid = '{$esc_userid}' AND affiliationid = {$userinfo['affiliationid']}";
+ $qh = doQuery($query, 255);
+ if($user = mysql_fetch_assoc($qh)) {
+ // Add to default group
+ if($userinfo['defaultgroup'] != null) {
+ $usergroups = array();
+ $newgroupid = getUserGroupID($userinfo['defaultgroup'], $userinfo['affiliationid']);
+ array_push($usergroups, $newgroupid);
+ $usergroups = array_unique($usergroups);
+ if(! empty($usergroups))
+ updateGroups($usergroups, $user["id"]);
+ }
+ }
+
+ return TRUE;
+}
+?>
diff --git a/web/.ht-inc/conf-default.php b/web/.ht-inc/conf-default.php
index 50f204b..6993ee2 100644
--- a/web/.ht-inc/conf-default.php
+++ b/web/.ht-inc/conf-default.php
@@ -165,6 +165,17 @@
# for the user. Typically either 'cn', 'uid', or 'samaccountname'
"help" => "Use EXAMPLE1 LDAP if you are using an EXAMPLE1 account"), # message to be displayed on login page about when
# to use this login mechanism*/
+ /*"CAS (Central Authentication Service)" => array("type" => "cas",
+ "affiliationid" => 3, # id from affiliation id this login method is associated with
+ "version" => 3, # this denotes the CAS protocol version used. currently supported values is 3. this value is maintained to track furture updates to the protocol
+ "host" => "cas.example.edu", # the CAS server DNS name
+ "port" => "8443", # the CAS Server port
+ "context" => "/cas", # the CAS context
+ "validatecassslcerts" => true, # validates the SSL certificates used by CAS server. strictly set to true for production (like) environments
+ "cacertpath" => "/etc/cas/cachain.pem", # if using self signed certificates on the CAS server set this to the path where the CA chain is stored. Set to '' if using publicly trusted certificates
+ "attributemap" => array("sn" => "lastname", "givenName" => "firstname", "cn" => "preferredname", "mail" => "email"), # a list of CAS user attributes mapped to VCL user attributes
+ "defaultgroup" => "global", # the default group name (excluding the affiliation name) that each CAS user should be added. make sure this group is pre-created
+ "help" => "Use CAS authentication to use your university CAS environment"), # message to be displayed on login page about when to use this login mechanism*/
);
$affilValFunc = array();
@@ -182,7 +193,7 @@
$updateUserFunc[$item['affiliationid']] = 'updateLDAPUser';
$updateUserFuncArgs[$item['affiliationid']] = $key;
}
- elseif($item['type'] == 'local') {
+ elseif($item['type'] == 'local' || $item['type'] == 'cas') {
$affilValFunc[$item['affiliationid']] = create_function('', 'return 0;');
$addUserFunc[$item['affiliationid']] = create_function('', 'return NULL;');
$updateUserFunc[$item['affiliationid']] = create_function('', 'return NULL;');
@@ -194,4 +205,5 @@
#require_once(".ht-inc/authmethods/itecsauth.php");
#require_once(".ht-inc/authmethods/ldapauth.php");
#require_once(".ht-inc/authmethods/shibauth.php");
+#require_once(".ht-inc/authmethods/casauth.php");
?>
diff --git a/web/.ht-inc/utils.php b/web/.ht-inc/utils.php
index 662ab77..a9928eb 100644
--- a/web/.ht-inc/utils.php
+++ b/web/.ht-inc/utils.php
@@ -363,13 +363,19 @@
////////////////////////////////////////////////////////////////////////////////
function __autoload($class) {
global $actions;
- $class = strtolower($class);
- if(array_key_exists($class, $actions['classmapping'])) {
- require_once(".ht-inc/{$actions['classmapping'][$class]}.php");
- return;
+ $_class = strtolower($class);
+ if(array_key_exists($_class, $actions['classmapping'])) {
+ require_once(".ht-inc/{$actions['classmapping'][$_class]}.php");
}
- require_once(".ht-inc/resource.php");
- require_once(".ht-inc/$class.php");
+ elseif(file_exists(".ht-inc/{$_class}.php")) {
+ require_once(".ht-inc/{$_class}.php");
+ if(get_parent_class($class) == 'Resource')
+ require_once(".ht-inc/resource.php");
+ }
+}
+// register autoload function in case CAS or something else has used spl_autoload_register
+if(function_exists('spl_autoload_register')) {
+ spl_autoload_register('__autoload');
}
////////////////////////////////////////////////////////////////////////////////
@@ -1508,7 +1514,7 @@
. "u.affiliationid = a.id ";
if(! $includedeleted)
$query .= "AND i.deleted = 0 ";
- $query .= "ORDER BY i.prettyname";
+ $query .= "ORDER BY i.prettyname";
$qh = doQuery($query, 120);
while($row = mysqli_fetch_assoc($qh)) {
if(is_null($row['maxconcurrent']))
@@ -1534,8 +1540,8 @@
$imagelist[$includedeleted][$row["id"]]["subimages"] = array();
if($allmetadata[$metaid]["subimages"]) {
$query2 = "SELECT imageid "
- . "FROM subimages "
- . "WHERE imagemetaid = $metaid";
+ . "FROM subimages "
+ . "WHERE imagemetaid = $metaid";
$qh2 = doQuery($query2, 101);
while($row2 = mysqli_fetch_assoc($qh2))
$imagelist[$includedeleted][$row["id"]]["subimages"][] = $row2["imageid"];
@@ -2993,11 +2999,10 @@
///
////////////////////////////////////////////////////////////////////////////////
function getCryptKeyID() {
- $reg = "|" . SCRIPT . "$|";
- $filebase = preg_replace($reg, '', $_SERVER['SCRIPT_FILENAME']);
- $filebase = preg_replace('|/shibauth|', '', $filebase);
- $filebase .= "/.ht-inc/cryptkey";
- $idfile = "$filebase/cryptkeyid";
+ $me = new ReflectionFunction('getCryptKeyID');
+ $myfile = $me->getFileName();
+ $path = dirname($myfile);
+ $idfile = "$path/cryptkey/cryptkeyid";
static $create = 1; # set flag so that recursion only goes one level deep
@@ -3991,12 +3996,12 @@
! is_array($_POST[$vartag]) &&
strncmp("{$_POST[$vartag]}", "0", 1) == 0 &&
$type == ARG_NUMERIC &&
- strncmp("{$_POST[$vartag]}", "0x0", 3) != 0) ||
+ strncmp("{$_POST[$vartag]}", "0x0", 3) != 0) ||
(array_key_exists($vartag, $_GET) &&
! is_array($_GET[$vartag]) &&
strncmp("{$_GET[$vartag]}", "0", 1) == 0 &&
$type == ARG_NUMERIC &&
- strncmp("{$_GET[$vartag]}", "0x0", 3) != 0)) {
+ strncmp("{$_GET[$vartag]}", "0x0", 3) != 0)) {
$_POST[$vartag] = "zero";
}
if(!empty($_POST[$vartag])) {
@@ -4140,7 +4145,7 @@
function processInputData($data, $type, $addslashes=0, $defaultvalue=NULL) {
if(strncmp("$data", "0", 1) == 0 &&
$type == ARG_NUMERIC &&
- strncmp("$data", "0x0", 3) != 0) {
+ strncmp("$data", "0x0", 3) != 0) {
$data = "zero";
}
if(!empty($data))
@@ -6407,7 +6412,7 @@
$checkstart = unixToDatetime(time() + 180);
if($compid == 0) {
$resources = getUserResources(array("imageAdmin", "imageCheckOut"),
- array("available"), 0, 0);
+ array("available"), 0, 0);
$computers = implode("','", array_keys($resources["computer"]));
$computers = "'$computers'";
$query = "SELECT DISTINCT COUNT(rs.id) AS reservations, "
@@ -7535,7 +7540,7 @@
}
# Get items from variable table for specific management node id
- foreach ($return as $mn_id => $value ) {
+ foreach($return as $mn_id => $value) {
if(array_key_exists("hostname", $value)) {
$mn_hostname = $value['hostname'];
$timeservers = getVariable('timesource|'.$mn_hostname);
@@ -8074,9 +8079,9 @@
# or aren't mapped in resourcemap
if($computer_platformids[$id] != $platformid ||
($computerData[$id]["stateid"] != 2 &&
- $computerData[$id]["stateid"] != 3 &&
- $computerData[$id]["stateid"] != 6 &&
- $computerData[$id]["stateid"] != 8) ||
+ $computerData[$id]["stateid"] != 3 &&
+ $computerData[$id]["stateid"] != 6 &&
+ $computerData[$id]["stateid"] != 8) ||
$computerData[$id]["ram"] < $imageData[$imageid]["minram"] ||
$computerData[$id]["procnumber"] < $imageData[$imageid]["minprocnumber"] ||
$computerData[$id]["procspeed"] < $imageData[$imageid]["minprocspeed"] ||
@@ -8189,7 +8194,7 @@
continue;
}
if($links && ($computer_platformids[$id] != $platformid ||
- $computerData[$id]["stateid"] == 10 ||
+ $computerData[$id]["stateid"] == 10 ||
$computerData[$id]["stateid"] == 5)) {
continue;
}
@@ -8212,7 +8217,7 @@
elseif($timeslots[$id][$stamp]['blockAllocation'] &&
($timeslots[$id][$stamp]['blockInfo']['imageid'] != $imageid || # this line threw an error at one point, but we couldn't recreate it later
(! in_array($timeslots[$id][$stamp]['blockInfo']['groupid'], array_keys($user['groups'])))) &&
- $timeslots[$id][$stamp]['available']) {
+ $timeslots[$id][$stamp]['available']) {
if($links) {
print " <TD bgcolor=\"#ff0000\"><img src=images/red.jpg ";
print "alt=blockallocation border=0></TD>\n";
@@ -10846,7 +10851,7 @@
. "imagerevisionid, "
. "computerid, "
. "managementnodeid, "
- . "predictivemoduleid, ";
+ . "predictivemoduleid, ";
if($fromblock) {
$query .= "blockRequestid, "
. "blockStart, "
@@ -11387,7 +11392,7 @@
. "cm.affiliationid = a.id AND "
. "(cm.affiliationid = {$user['affiliationid']} OR "
. "a.name = 'Global') AND "
- . "cm.configstageid = cs.id AND ";
+ . "cm.configstageid = cs.id AND ";
if($mode) {
$query .= "cmt.name = 'config' AND "
. " cm.subid IN ($inlist)";
@@ -11591,7 +11596,7 @@
. "configmaptype cmt, "
. "configsubimage csi, "
. "image i, "
- . "OS o, "
+ . "OS o, "
. "OStype ot, "
. "affiliation a "
. "WHERE ct.name = 'cluster' AND "
@@ -12613,7 +12618,7 @@
///
/// \fn validateHostname($name)
///
-/// \param $name the hostname to validate
+/// \param $name - the hostname to validate
///
/// \return 1 if valid hostname else 0
///
@@ -13049,28 +13054,28 @@
if($a === true)
return 'true';
if(is_scalar($a)) {
- if (is_float($a)) {
- // Always use "." for floats.
- return floatval(str_replace(",", ".", strval($a)));
+ if(is_float($a)) {
+ // Always use "." for floats.
+ return floatval(str_replace(",", ".", strval($a)));
}
- if (is_string($a)) {
- static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
+ if(is_string($a)) {
+ static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"';
}
else
return $a;
}
$isList = true;
- for ($i = 0, reset($a); $i < count($a); $i++, next($a)) {
- if (key($a) !== $i) {
+ for($i = 0, reset($a); $i < count($a); $i++, next($a)) {
+ if(key($a) !== $i) {
$isList = false;
break;
}
}
$result = array();
- if ($isList) {
- foreach ($a as $v) $result[] = json_encode($v);
+ if($isList) {
+ foreach($a as $v) $result[] = json_encode($v);
return '[' . join(',', $result) . ']';
}
else {
@@ -13181,8 +13186,8 @@
if(! array_key_exists('ownergroup', $data))
$data['ownergroup'] = processInputVar('ownergroup', ARG_NUMERIC, 0);
$ownergroupids = explode(',', $data['ownergroupids']);
- if(in_array($data['ownergroup'], $ownergroupids) &&
- array_key_exists($data['ownergroup'], $user['groups'])) {
+ if(in_array($data['ownergroup'], $ownergroupids) &&
+ array_key_exists($data['ownergroup'], $user['groups'])) {
$expire = time() + 31536000; //expire in 1 year
setcookie("VCLOWNERGROUPID", $data['ownergroup'], $expire, "/", COOKIEDOMAIN);
}
@@ -13241,7 +13246,7 @@
$HTMLheader .= getHeader($refresh);
if(! in_array($mode, $noHTMLwrappers) &&
- (! is_array($contdata) ||
+ (! is_array($contdata) ||
! array_key_exists('noHTMLwrappers', $contdata) ||
$contdata['noHTMLwrappers'] == 0)) {
print $HTMLheader;
@@ -13514,7 +13519,7 @@
global $NOAUTH_HOMENAV;
$rt = '';
foreach($NOAUTH_HOMENAV as $name => $url)
- $rt .= "<li><a href=\"$url\">" . i($name) . "</a></li>\n";
+ $rt .= "<li><a href=\"$url\">" . i($name) . "</a></li>\n";
return $rt;
}
@@ -14343,9 +14348,9 @@
# use UTF8 encoding for any locales other than English (we may just be able
# to always use UTF8)
if(preg_match('/^en/', $locale))
- setlocale(LC_ALL, $locale);
+ setlocale(LC_ALL, $locale);
else
- setlocale(LC_ALL, $locale . '.UTF8');
+ setlocale(LC_ALL, $locale . '.UTF8');
bindtextdomain('vcl', './locale');
textdomain('vcl');
bind_textdomain_codeset('vcl', 'UTF-8');
@@ -14375,7 +14380,7 @@
if(! is_array($user))
$user['id'] = 0;
- $rt = "<form name=\"localeform\" class=\"localeform\" action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+ $rt = "<form name=\"localeform\" class=\"localeform\" action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
if($authed) {
$rt .= "<select name=\"continuation\" onChange=\"this.form.submit();\" autocomplete=\"off\">\n";
$cdata = array('IP' => $remoteIP, 'oldmode' => $mode);
@@ -14469,4 +14474,60 @@
$_SESSION['locales'] = $locales;
return $locales;
}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn curlDoSSLWebRequest()
+/// \param $url - the URL to fetch
+/// \param $validatecert - boolean value indicating if server certificates
+/// should be validated
+///
+/// \return response - string returned by web request
+///
+/// \brief performs an HTTPS web request for given URL
+///
+////////////////////////////////////////////////////////////////////////////////
+function curlDoSSLWebRequest($url, $validatecert = TRUE) {
+ if(! function_exists('curl_init')) {
+ $message = "php cURL library is not configured.";
+ if(ONLINEDEBUG && checkUserHasPerm('View Debug Information')) {
+ print "<font color=red>" . $message . "</font><br>\n";
+ }
+ error_log('php cURL library is not configured.');
+ return;
+ }
+
+ $ch = curl_init();
+
+ curl_setopt($ch, CURLOPT_HEADER, false);
+ curl_setopt($ch, CURLOPT_URL, $url) ;
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
+
+ if($validatecert == TRUE) {
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
+ }
+ curl_setopt($ch, CURLOPT_VERBOSE, true);
+
+ $response = curl_exec($ch);
+
+ if(curl_errno($ch)) {
+ $info = curl_getinfo($ch);
+ if(ONLINEDEBUG && checkUserHasPerm('View Debug Information')) {
+ print "<font color=red>" . curl_error($ch) . print_r($info, TRUE) . "</font><br>\n";
+ }
+ print "ERROR(curl_errno($ch)): " . $ERRORS[$info] . "<BR>\n";
+ error_log("===========================================================================");
+ error_log("ERROR(curl_errno($ch)): " . $ERRORS[$info]);
+ $backtrace = getBacktraceString(FALSE);
+ print "<pre>\n";
+ print $backtrace;
+ print "</pre>\n";
+ error_log($backtrace);
+ }
+ curl_close($ch);
+ return $response;
+}
?>
diff --git a/web/casauth/index.php b/web/casauth/index.php
new file mode 100644
index 0000000..df95bfd
--- /dev/null
+++ b/web/casauth/index.php
@@ -0,0 +1,137 @@
+<?php
+
+chdir("..");
+require_once('.ht-inc/conf.php');
+require_once('.ht-inc/utils.php');
+require_once('.ht-inc/errors.php');
+
+global $authMechs;
+global $keys;
+
+function getFooter() {}
+$noHTMLwrappers = array();
+
+dbConnect();
+
+// Validate the Ticket
+if(array_key_exists('ticket', $_GET)) {
+ $serviceticket = $_GET['ticket'];
+ if(array_key_exists('authtype', $_GET)) {
+ $authtype = $_GET['authtype'];
+ $auth = $authMechs[$authtype];
+ $casversion = ($auth['version'] == 2 ? CAS_VERSION_2_0 : CAS_VERSION_3_0);
+ $cashost = $auth['host'];
+ $casport = $auth['port'];
+ $cascontext = $auth['context'];
+ $validatecassslcerts = $auth['validatecassslcerts'];
+ $attributemap = $auth['attributemap'];
+
+ if($auth['cacertpath'] != null)
+ if(file_exists($auth['cacertpath']))
+ phpCAS::setCasServerCACert($auth['cacertpath']);
+
+ $serviceurl = BASEURL . '/casauth/index.php?authtype=' . $_GET['authtype'];
+ if($casversion == CAS_VERSION_2_0)
+ $servicevalidateurl = 'https://' . $cashost . ':' . $casport
+ . $cascontext . '/serviceValidate' . '?' . 'service='
+ . urlencode($serviceurl) . '&' . 'ticket=' . $serviceticket;
+ else
+ $servicevalidateurl = 'https://' . $cashost . ':' . $casport . $cascontext
+ . '/p3/serviceValidate' . '?' . 'service='
+ . urlencode($serviceurl) . '&' . 'ticket=' . $serviceticket;
+
+ $response = curlDoSSLWebRequest($servicevalidateurl, $validatecassslcerts);
+
+ // check for authentication success
+ $xmldata = new DOMDocument();
+ $xmldata->loadXML($response);
+ $xpath = new DOMXPath($xmldata);
+ $authresults = $xpath->query('//cas:serviceResponse/cas:authenticationSuccess/cas:user');
+ $userid = '';
+ $userinfo = array();
+ $vcluser = array();
+ foreach($authresults as $authresult) {
+ $userid = $authresult->nodeValue;
+ $vcluser['unityid'] = $userid;
+ $vcluser['affiliationid'] = $auth['affiliationid'];
+ if($auth['defaultgroup'] != null)
+ $vcluser['defaultgroup'] = $auth['defaultgroup'];
+ }
+
+ // extract user attributes provided by CAS
+ $attributeresults = $xpath->query('//cas:serviceResponse/cas:authenticationSuccess/cas:attributes');
+ if($attributeresults->length > 0) {
+ $userattributeitems = $attributeresults->item(0);
+ foreach($userattributeitems->childNodes as $userattributeitem) {
+ $attributename = preg_replace('#^cas:#', '', $userattributeitem->nodeName);
+ $userinfo[$attributename] = $userattributeitem->nodeValue;
+ }
+ }
+ // convert CAS attributes to VCL user attributes
+ foreach(array_keys($userinfo) as $attribute) {
+ if(array_key_exists($attribute, $attributemap)) {
+ $vcluser[$attributemap[$attribute]] = $userinfo[$attribute];
+ }
+ }
+
+ unset($xmldata);
+ unset($xpath);
+
+ if($userid != '') {
+ // read 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);
+
+ // valid user returned, login if user exists
+ if(checkCASUserInDatabase($authtype, $userid) == TRUE) {
+ updateCASUser($vcluser);
+ # get cookie data
+ $cookie = getAuthCookieData("$userid@" . getAffiliationName($auth['affiliationid']));
+ if($cookie != "Failed to encrypt cookie data") {
+ # 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);
+
+ addLoginLog($userid, $authtype, $auth['affiliationid'], 1);
+ }
+ }
+ else {
+ // user does not exists in VCL database, so add user
+ if(addCASUser($vcluser) != NULL) {
+ # get cookie data
+ $cookie = getAuthCookieData("$userid@" . getAffiliationName($auth['affiliationid']));
+ if($cookie != "Failed to encrypt cookie data") {
+ # 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);
+
+ addLoginLog($userid, $authtype, $auth['affiliationid'], 1);
+ }
+ }
+ }
+ // Set theme
+ $theme = getAffiliationTheme($auth['affiliationid']);
+ setcookie("VCLSKIN", $theme, (time() + 2678400), "/", COOKIEDOMAIN);
+ }
+ }
+}
+
+// Redirect to homepage
+header("Location: " . BASEURL . "/");
+dbDisconnect();
+
+?>