106 (empty($this->_output_header)
107 ?
'<html><head><title>__TITLE__</title></head><body><h1>__TITLE__</h1>' 108 : $this->_output_header)
133 empty($this->_output_footer)?
135 '<hr><address>phpCAS __PHPCAS_VERSION__ ' 136 .$lang->getUsingServer()
137 .
' <a href="__SERVER_BASE_URL__">__SERVER_BASE_URL__</a> (CAS __CAS_VERSION__)</a></address></body></html>' 153 if (gettype($header) !=
'string')
156 $this->_output_header = $header;
169 if (gettype($footer) !=
'string')
172 $this->_output_footer = $footer;
204 if (gettype($lang) !=
'string')
211 '$className must implement the CAS_Languages_LanguageInterface' 214 $this->_lang = $lang;
225 return new $classname();
264 'hostname' =>
'none',
275 return $this->_server[
'version'];
285 return $this->_server[
'hostname'];
295 return $this->_server[
'port'];
305 return $this->_server[
'uri'];
316 if ( empty($this->_server[
'base_url']) ) {
319 $this->_server[
'base_url'] .=
':' 320 .$this->_getServerPort();
324 return $this->_server[
'base_url'];
341 if ( empty($this->_server[
'login_url']) ) {
344 $url = $this->_server[
'login_url'];
349 } elseif ($gateway) {
368 if (gettype($url) !=
'string')
371 return $this->_server[
'login_url'] = $url;
385 if (gettype($url) !=
'string')
388 return $this->_server[
'service_validate_url'] = $url;
402 if (gettype($url) !=
'string')
405 return $this->_server[
'proxy_validate_url'] = $url;
419 if (gettype($url) !=
'string')
422 return $this->_server[
'saml_validate_url'] = $url;
435 if ( empty($this->_server[
'service_validate_url']) ) {
447 .
'p3/serviceValidate';
452 $this->_server[
'service_validate_url'],
453 'service='.urlencode($this->
getURL())
467 if ( empty($this->_server[
'saml_validate_url']) ) {
476 $this->_server[
'saml_validate_url'],
477 'TARGET='.urlencode($this->
getURL())
492 if ( empty($this->_server[
'proxy_validate_url']) ) {
495 $this->_server[
'proxy_validate_url'] =
'';
498 $this->_server[
'proxy_validate_url'] = $this->
_getServerBaseURL().
'proxyValidate';
501 $this->_server[
'proxy_validate_url'] = $this->
_getServerBaseURL().
'p3/proxyValidate';
506 $this->_server[
'proxy_validate_url'],
507 'service='.urlencode($this->
getURL())
522 if ( empty($this->_server[
'proxy_url']) ) {
525 $this->_server[
'proxy_url'] =
'';
533 return $this->_server[
'proxy_url'];
544 if ( empty($this->_server[
'logout_url']) ) {
547 return $this->_server[
'logout_url'];
560 if (gettype($url) !=
'string')
563 return $this->_server[
'logout_url'] = $url;
581 $this->_curl_options[$key] = $value;
613 $obj =
new $className;
616 '$className must implement the CAS_Request_RequestInterface' 619 $this->_requestImplementation = $className;
640 $this->_clearTicketsFromUrl =
false;
666 $this->_casAttributeParserCallbackFunction = $function;
667 $this->_casAttributeParserCallbackArgs = $additionalArgs;
700 $this->_postAuthenticateCallbackFunction = $function;
701 $this->_postAuthenticateCallbackArgs = $additionalArgs;
730 $this->_signoutCallbackFunction = $function;
731 $this->_signoutCallbackArgs = $additionalArgs;
764 $dbg = debug_backtrace();
765 $this->_authentication_caller = array (
766 'file' => $dbg[1][
'file'],
767 'line' => $dbg[1][
'line'],
768 'method' => $dbg[1][
'class'] .
'::' . $dbg[1][
'function'],
769 'result' => (
boolean)
$auth 781 return !empty($this->_authentication_caller);
810 return $this->_authentication_caller[
'result'];
825 if (!$this->_authentication_caller[
'result']) {
827 'authentication was checked (by ' 831 .
') but the method returned false' 847 return $this->_authentication_caller[
'file'];
861 return $this->_authentication_caller[
'line'];
875 return $this->_authentication_caller[
'method'];
908 $changeSessionID =
true 911 if (gettype($server_version) !=
'string')
913 if (gettype($proxy) !=
'boolean')
915 if (gettype($server_hostname) !=
'string')
917 if (gettype($server_port) !=
'integer')
919 if (gettype($server_uri) !=
'string')
921 if (gettype($changeSessionID) !=
'boolean')
936 phpCAS :: trace(
"Session is authenticated as: " . $_SESSION[
'phpCAS'][
'user']);
941 $this->_proxy = $proxy;
945 if (!isset($_SESSION[
'phpCAS'])) {
946 $_SESSION[
'phpCAS'] = array();
948 if (!isset($_SESSION[
'phpCAS'][
'service_cookies'])) {
949 $_SESSION[
'phpCAS'][
'service_cookies'] = array();
952 $_SESSION[
'phpCAS'][
'service_cookies']
957 switch ($server_version) {
961 'CAS proxies are not supported in CAS '.$server_version
972 'this version of CAS (`'.$server_version
973 .
'\') is not supported by
phpCAS '.phpCAS::getVersion() 976 $this->_server['version
'] = $server_version; 979 if ( empty($server_hostname) 980 || !preg_match('/[\.\d\-abcdefghijklmnopqrstuvwxyz]*/
', $server_hostname) 982 phpCAS::error('bad
CAS server hostname (`
'.$server_hostname.'\
')');
984 $this->_server[
'hostname'] = $server_hostname;
987 if ( $server_port == 0
988 || !is_int($server_port)
990 phpCAS::error(
'bad CAS server port (`'.$server_hostname.
'\')
'); 992 $this->_server['port
'] = $server_port; 995 if ( !preg_match('/[\.\d\-_abcdefghijklmnopqrstuvwxyz\/]*/
', $server_uri) ) { 996 phpCAS::error('bad
CAS server URI (`
'.$server_uri.'\
')');
999 if(strstr($server_uri,
'?') ===
false) $server_uri .=
'/';
1000 $server_uri = preg_replace(
'/\/\//',
'/',
'/'.$server_uri);
1001 $this->_server[
'uri'] = $server_uri;
1012 'CAS proxies must be secured to use phpCAS; PGT\'s will not be received from the CAS server' 1018 $ticket = (isset($_GET[
'ticket']) ? $_GET[
'ticket'] : null);
1019 if (preg_match(
'/^[SP]T-/', $ticket) ) {
1021 $this->setTicket($ticket); 1022 unset($_GET['ticket
']); 1023 } else if ( !empty($ticket) ) { 1024 //ill-formed ticket, halt 1026 'ill-formed ticket found in the URL (ticket=`
' 1027 .htmlentities($ticket).'\
')' 1064 $this->_change_session_id = $allowed;
1107 $this->_user = $user;
1137 if ( empty($this->_user) ) {
1139 'this method should be used only after '.__CLASS__
1140 .
'::forceAuthentication() or '.__CLASS__.
'::isAuthenticated()' 1164 $this->_attributes = $attributes;
1177 if ( empty($this->_user) ) {
1180 'this method should be used only after '.__CLASS__
1181 .
'::forceAuthentication() or '.__CLASS__.
'::isAuthenticated()' 1197 return !empty($this->_attributes);
1223 return (is_array($this->_attributes)
1224 && array_key_exists($key, $this->_attributes));
1240 return $this->_attributes[$key];
1255 if (isset( $_SESSION[
'phpCAS'][
'auth_checked'])) {
1256 unset($_SESSION[
'phpCAS'][
'auth_checked']);
1286 if (isset($_SESSION[
'phpCAS'][
'auth_checked'])) {
1287 unset($_SESSION[
'phpCAS'][
'auth_checked']);
1314 if (gettype($n) !=
'integer')
1317 $this->_cache_times_for_auth_recheck = $n;
1334 unset($_SESSION[
'phpCAS'][
'auth_checked']);
1336 }
else if (isset($_SESSION[
'phpCAS'][
'auth_checked'])) {
1339 unset($_SESSION[
'phpCAS'][
'auth_checked']);
1343 if (!isset($_SESSION[
'phpCAS'][
'unauth_count'])) {
1344 $_SESSION[
'phpCAS'][
'unauth_count'] = -2;
1347 if (($_SESSION[
'phpCAS'][
'unauth_count'] != -2
1348 && $this->_cache_times_for_auth_recheck == -1)
1349 || ($_SESSION[
'phpCAS'][
'unauth_count'] >= 0
1350 && $_SESSION[
'phpCAS'][
'unauth_count'] < $this->_cache_times_for_auth_recheck)
1354 if ($this->_cache_times_for_auth_recheck != -1) {
1355 $_SESSION[
'phpCAS'][
'unauth_count']++;
1357 'user is not authenticated (cached for ' 1358 .$_SESSION[
'phpCAS'][
'unauth_count'].
' times of ' 1359 .$this->_cache_times_for_auth_recheck.
')' 1363 'user is not authenticated (cached for until login pressed)' 1367 $_SESSION[
'phpCAS'][
'unauth_count'] = 0;
1368 $_SESSION[
'phpCAS'][
'auth_checked'] =
true;
1397 'ticket was present and will be discarded, use renewAuthenticate()' 1399 if ($this->_clearTicketsFromUrl) {
1401 session_write_close();
1402 header(
'Location: '.$this->
getURL());
1408 'Already authenticated, but skipping ticket clearing since setNoClearTicketsFromUrl() was used.' 1416 'user was already authenticated, no need to look for tickets' 1430 'CAS 1.0 ticket `'.$this->
getTicket().
'\' is present
' 1432 $this->validateCAS10( 1433 $validate_url, $text_response, $tree_response, $renew 1434 ); // if it fails, it halts 1436 'CAS 1.0 ticket `
'.$this->getTicket().'\
' was validated' 1438 $_SESSION[
'phpCAS'][
'user'] = $this->
_getUser();
1448 $this->validateCAS20( 1449 $validate_url, $text_response, $tree_response, $renew 1450 ); // note: if it fails, it halts 1452 'CAS '.$this->getServerVersion().' ticket `
'.$this->getTicket().'\
' was validated' 1456 $validate_url, $text_response, $tree_response
1459 $_SESSION['phpCAS']['pgt
'] = $this->_getPGT(); 1461 $_SESSION['phpCAS']['user
'] = $this->_getUser(); 1462 if (!empty($this->_attributes)) { 1463 $_SESSION['phpCAS']['attributes
'] = $this->_attributes; 1465 $proxies = $this->getProxies(); 1466 if (!empty($proxies)) { 1467 $_SESSION['phpCAS']['proxies
'] = $this->getProxies(); 1470 $logoutTicket = $this->getTicket(); 1472 case SAML_VERSION_1_1: 1473 // if we have a SAML ticket, validate it. 1475 'SAML 1.1 ticket `
'.$this->getTicket().'\
' is present' 1478 $validate_url, $text_response, $tree_response, $renew
1481 'SAML 1.1 ticket `'.$this->
getTicket().
'\' was validated
' 1483 $_SESSION['phpCAS']['user
'] = $this->_getUser(); 1484 $_SESSION['phpCAS']['attributes
'] = $this->_attributes; 1486 $logoutTicket = $this->getTicket(); 1489 phpCAS::trace('Protocoll error
'); 1493 // no ticket given, not authenticated 1494 phpCAS::trace('no ticket found
'); 1497 // Mark the auth-check as complete to allow post-authentication 1498 // callbacks to make use of phpCAS::getUser() and similar methods 1499 $this->markAuthenticationCall($res); 1502 // call the post-authenticate callback if registered. 1503 if ($this->_postAuthenticateCallbackFunction) { 1504 $args = $this->_postAuthenticateCallbackArgs; 1505 array_unshift($args, $logoutTicket); 1506 call_user_func_array( 1507 $this->_postAuthenticateCallbackFunction, $args 1511 // if called with a ticket parameter, we need to redirect to the 1512 // app without the ticket so that CAS-ification is transparent 1513 // to the browser (for later POSTS) most of the checks and 1514 // errors should have been made now, so we're safe
for redirect
1517 if ($this->_clearTicketsFromUrl) {
1519 session_write_close();
1520 header(
'Location: '.$this->
getURL());
1538 return !empty($_SESSION[
'phpCAS'][
'user']);
1555 if ($this->
_rebroadcast&&!isset($_POST[
'rebroadcast'])) {
1566 && !empty($_SESSION[
'phpCAS'][
'pgt'])
1569 $this->
_setUser($_SESSION[
'phpCAS'][
'user']);
1570 if (isset($_SESSION[
'phpCAS'][
'attributes'])) {
1573 $this->
_setPGT($_SESSION[
'phpCAS'][
'pgt']);
1575 'user = `'.$_SESSION[
'phpCAS'][
'user'].
'\', PGT = `
' 1576 .$_SESSION['phpCAS']['pgt
'].'\
'' 1580 if (isset($_SESSION[
'phpCAS'][
'proxies'])) {
1581 $this->
_setProxies($_SESSION[
'phpCAS'][
'proxies']);
1584 .implode(
'", "', $_SESSION[
'phpCAS'][
'proxies']).
'"' 1590 && empty($_SESSION[
'phpCAS'][
'pgt'])
1594 'username found (`'.$_SESSION[
'phpCAS'][
'user']
1595 .
'\') but PGT is empty
' 1597 // unset all tickets to enforce authentication 1598 unset($_SESSION['phpCAS']); 1599 $this->setTicket(''); 1600 } elseif ( !$this->isSessionAuthenticated() 1601 && !empty($_SESSION['phpCAS']['pgt
']) 1603 // these two variables should be empty or not empty at the same time 1605 'PGT found (`
'.$_SESSION['phpCAS']['pgt
'] 1606 .'\
') but username is empty' 1609 unset($_SESSION[
'phpCAS']);
1618 $this->
_setUser($_SESSION[
'phpCAS'][
'user']);
1619 if (isset($_SESSION[
'phpCAS'][
'attributes'])) {
1625 if (isset($_SESSION[
'phpCAS'][
'proxies'])) {
1626 $this->
_setProxies($_SESSION[
'phpCAS'][
'proxies']);
1629 .implode(
'", "', $_SESSION[
'phpCAS'][
'proxies']).
'"' 1657 session_write_close();
1658 if (php_sapi_name() ===
'cli') {
1666 printf(
'<p>'. $lang->getShouldHaveBeenRedirected().
'</p>',
$cas_url);
1685 $paramSeparator =
'?';
1686 if (isset($params[
'url'])) {
1688 . urlencode($params[
'url']);
1689 $paramSeparator =
'&';
1691 if (isset($params[
'service'])) {
1693 . urlencode($params[
'service']);
1701 if (session_status() === PHP_SESSION_NONE) {
1709 printf(
'<p>'.$lang->getShouldHaveBeenRedirected().
'</p>',
$cas_url);
1722 return !empty($_POST[
'logoutRequest']);
1744 && is_null($this->_signoutCallbackFunction)
1747 "phpCAS can't handle logout requests if it is not allowed to change session_id." 1751 $decoded_logout_rq = urldecode($_POST[
'logoutRequest']);
1754 if ($check_client) {
1755 if (!$allowed_clients) {
1758 $client_ip = $_SERVER[
'REMOTE_ADDR'];
1759 $client = gethostbyaddr($client_ip);
1761 foreach ($allowed_clients as $allowed_client) {
1762 if ((
$client == $allowed_client)
1763 || ($client_ip == $allowed_client)
1766 "Allowed client '".$allowed_client
1767 .
"' matches, logout request is allowed" 1773 "Allowed client '".$allowed_client.
"' does not match" 1785 if ($this->
_rebroadcast && !isset($_POST[
'rebroadcast'])) {
1790 "|<samlp:SessionIndex>(.*)</samlp:SessionIndex>|",
1791 $decoded_logout_rq, $tick, PREG_OFFSET_CAPTURE, 3
1793 $wrappedSamlSessionIndex = preg_replace(
1794 '|<samlp:SessionIndex>|',
'', $tick[0][0]
1796 $ticket2logout = preg_replace(
1797 '|</samlp:SessionIndex>|',
'', $wrappedSamlSessionIndex
1802 if ($this->_signoutCallbackFunction) {
1804 array_unshift($args, $ticket2logout);
1805 call_user_func_array($this->_signoutCallbackFunction, $args);
1815 if (session_id() !==
"") {
1820 session_id($session_id);
1821 $_COOKIE[session_name()]=$session_id;
1822 $_GET[session_name()]=$session_id;
1884 $this->_ticket = $st;
1894 return !empty($this->_ticket);
1947 if (gettype($cert) !=
'string') {
1950 if (gettype($validate_cn) !=
'boolean') {
1953 if ( !file_exists($cert) && $this->_requestImplementation !==
'CAS_TestHarness_DummyRequest'){
1956 $this->_cas_server_ca_cert = $cert;
1957 $this->_cas_server_cn_validate = $validate_cn;
1967 $this->_no_cas_server_validation =
true;
1985 public function validateCAS10(&$validate_url,&$text_response,&$tree_response,$renew=
false)
1991 .
'&ticket='.urlencode($this->
getTicket());
1995 $validate_url .=
'&renew=true';
1999 if ( !$this->
_readURL($validate_url, $headers, $text_response, $err_msg) ) {
2001 'could not open URL \''.$validate_url.
'\' to validate (
'.$err_msg.')
' 2003 throw new CAS_AuthenticationException( 2004 $this, 'CAS 1.0 ticket not validated
', $validate_url, 2005 true/*$no_response*/ 2010 if (preg_match('/^no\n/
', $text_response)) { 2011 phpCAS::trace('Ticket has not been validated
'); 2012 throw new CAS_AuthenticationException( 2013 $this, 'ST not validated
', $validate_url, false/*$no_response*/, 2014 false/*$bad_response*/, $text_response 2017 } else if (!preg_match('/^yes\n/
', $text_response)) { 2018 phpCAS::trace('ill-formed response
'); 2019 throw new CAS_AuthenticationException( 2020 $this, 'Ticket not validated
', $validate_url, 2021 false/*$no_response*/, true/*$bad_response*/, $text_response 2025 // ticket has been validated, extract the user name 2026 $arr = preg_split('/\n/
', $text_response); 2027 $this->_setUser(trim($arr[1])); 2031 $this->_renameSession($this->getTicket()); 2033 // at this step, ticket has been validated and $this->_user has been set, 2034 phpCAS::traceEnd(true); 2041 // ######################################################################## 2043 // ######################################################################## 2065 public function validateSA(&$validate_url,&$text_response,&$tree_response,$renew=false) 2067 phpCAS::traceBegin(); 2069 // build the URL to validate the ticket 2070 $validate_url = $this->getServerSamlValidateURL(); 2074 $validate_url .= '&renew=
true'; 2077 // open and read the URL 2078 if ( !$this->_readURL($validate_url, $headers, $text_response, $err_msg) ) { 2080 'could not open URL \
''.$validate_url.
'\' to validate (
'.$err_msg.')
' 2082 throw new CAS_AuthenticationException( 2083 $this, 'SA not validated
', $validate_url, true/*$no_response*/ 2087 phpCAS::trace('server version:
'.$this->getServerVersion()); 2089 // analyze the result depending on the version 2090 switch ($this->getServerVersion()) { 2091 case SAML_VERSION_1_1: 2092 // create new DOMDocument Object 2093 $dom = new DOMDocument(); 2094 // Fix possible whitspace problems 2095 $dom->preserveWhiteSpace = false; 2096 // read the response of the CAS server into a DOM object 2097 if (!($dom->loadXML($text_response))) { 2098 phpCAS::trace('dom->loadXML() failed
'); 2099 throw new CAS_AuthenticationException( 2100 $this, 'SA not validated
', $validate_url, 2101 false/*$no_response*/, true/*$bad_response*/, 2106 // read the root node of the XML tree 2107 if (!($tree_response = $dom->documentElement)) { 2108 phpCAS::trace('documentElement() failed');
2110 $this, 'SA not validated', $validate_url,
2115 }
else if ( $tree_response->localName != 'Envelope' ) {
2118 'bad XML root node (should be `Envelope\' instead of `' 2119 .$tree_response->localName.
'\'' 2122 $this,
'SA not validated', $validate_url,
2127 }
else if ($tree_response->getElementsByTagName(
"NameIdentifier")->length != 0) {
2129 $success_elements = $tree_response->getElementsByTagName(
"NameIdentifier");
2131 $user = trim($success_elements->item(0)->nodeValue);
2137 phpCAS::trace(
'no <NameIdentifier> tag found in SAML payload');
2139 $this,
'SA not validated', $validate_url,
2168 $attr_array = array();
2171 $dom =
new DOMDocument();
2173 $dom->preserveWhiteSpace =
false;
2174 if (($dom->loadXML($text_response))) {
2175 $xPath =
new DOMXpath($dom);
2176 $xPath->registerNamespace(
'samlp',
'urn:oasis:names:tc:SAML:1.0:protocol');
2177 $xPath->registerNamespace(
'saml',
'urn:oasis:names:tc:SAML:1.0:assertion');
2178 $nodelist = $xPath->query(
"//saml:Attribute");
2181 foreach ($nodelist as $node) {
2182 $xres = $xPath->query(
"saml:AttributeValue", $node);
2183 $name = $node->getAttribute(
"AttributeName");
2184 $value_array = array();
2185 foreach ($xres as $node2) {
2186 $value_array[] = $node2->nodeValue;
2188 $attr_array[$name] = $value_array;
2191 foreach ($attr_array as $attr_key => $attr_value) {
2192 if (count($attr_value) > 1) {
2193 $this->_attributes[$attr_key] = $attr_value;
2194 phpCAS::trace(
"* " . $attr_key .
"=" . print_r($attr_value,
true));
2196 $this->_attributes[$attr_key] = $attr_value[0];
2295 return !empty($this->_pgt);
2330 $this->_callback_mode = $callback_mode;
2363 if ( empty($this->_callback_url) ) {
2366 $final_uri =
'https://';
2368 $request_uri = $_SERVER[
'REQUEST_URI'];
2369 $request_uri = preg_replace(
'/\?.*$/',
'', $request_uri);
2370 $final_uri .= $request_uri;
2371 $this->_callback_url = $final_uri;
2388 if (gettype($url) !=
'string')
2391 return $this->_callback_url = $url;
2403 if (preg_match(
'/^PGTIOU-[\.\-\w]+$/', $_GET[
'pgtIou'])) {
2404 if (preg_match(
'/^[PT]GT-[\.\-\w]+$/', $_GET[
'pgtId'])) {
2406 $pgt_iou = $_GET[
'pgtIou'];
2407 $pgt = $_GET[
'pgtId'];
2408 phpCAS::trace(
'Storing PGT `'.$pgt.
'\' (
id=`
'.$pgt_iou.'\
')');
2409 echo
'<p>Storing PGT `'.$pgt.
'\' (
id=`
'.$pgt_iou.'\
').</p>';
2410 $this->_storePGT($pgt, $pgt_iou);
2458 if ( !is_object($this->_pgt_storage) ) {
2463 $this->_pgt_storage->init();
2479 $this->_pgt_storage->write($pgt, $pgt_iou);
2495 return $this->_pgt_storage->read($pgt_iou);
2512 if ( is_object($this->_pgt_storage) ) {
2521 $this->_pgt_storage = $storage;
2542 $dsn_or_pdo, $username=
'', $password=
'', $table=
'',
$driver_options=null
2548 if (!(is_object($dsn_or_pdo) && $dsn_or_pdo instanceof PDO) && gettype($dsn_or_pdo) !=
'string')
2550 if (gettype($username) !=
'string')
2552 if (gettype($password) !=
'string')
2554 if (gettype($table) !=
'string')
2579 if (gettype($path) !=
'string')
2604 private function _validatePGT(&$validate_url,$text_response,$tree_response)
2607 if ( $tree_response->getElementsByTagName(
"proxyGrantingTicket")->length == 0) {
2611 $this,
'Ticket validated but no PGT Iou transmitted',
2612 $validate_url,
false,
false,
2618 $tree_response->getElementsByTagName(
"proxyGrantingTicket")->item(0)->nodeValue
2620 if (preg_match(
'/^PGTIOU-[\.\-\w]+$/', $pgt_iou)) {
2622 if ( $pgt ==
false ) {
2626 'PGT Iou was transmitted but PGT could not be retrieved',
2627 $validate_url,
false,
2628 false, $text_response
2635 $this,
'PGT Iou was transmitted but has wrong format',
2636 $validate_url,
false,
false,
2661 if (gettype($target_service) !=
'string')
2674 .urlencode($target_service).
'&pgt='.$this->
_getPGT();
2679 'could not open URL \''.
$cas_url.
'\' to validate (
'.$err_msg.')
' 2681 $err_code = PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE; 2682 $err_msg = 'could not retrieve PT (no response from the
CAS server)
'; 2683 phpCAS::traceEnd(false); 2687 $bad_response = false; 2689 if ( !$bad_response ) { 2690 // create new DOMDocument object 2691 $dom = new DOMDocument(); 2692 // Fix possible whitspace problems 2693 $dom->preserveWhiteSpace = false; 2694 // read the response of the CAS server into a DOM object 2695 if ( !($dom->loadXML($cas_response))) { 2696 phpCAS::trace('dom->loadXML() failed
'); 2698 $bad_response = true; 2702 if ( !$bad_response ) { 2703 // read the root node of the XML tree 2704 if ( !($root = $dom->documentElement) ) { 2705 phpCAS::trace('documentElement failed
'); 2707 $bad_response = true; 2711 if ( !$bad_response ) { 2712 // insure that tag name is 'serviceResponse
' 2713 if ( $root->localName != 'serviceResponse
' ) { 2714 phpCAS::trace('localName failed
'); 2716 $bad_response = true; 2720 if ( !$bad_response ) { 2721 // look for a proxySuccess tag 2722 if ( $root->getElementsByTagName("proxySuccess")->length != 0) { 2723 $proxy_success_list = $root->getElementsByTagName("proxySuccess"); 2725 // authentication succeded, look for a proxyTicket tag 2726 if ( $proxy_success_list->item(0)->getElementsByTagName("proxyTicket")->length != 0) { 2727 $err_code = PHPCAS_SERVICE_OK; 2730 $proxy_success_list->item(0)->getElementsByTagName("proxyTicket")->item(0)->nodeValue 2732 phpCAS::trace('original PT:
'.trim($pt)); 2733 phpCAS::traceEnd($pt); 2736 phpCAS::trace('<proxySuccess> was found, but not <proxyTicket>
'); 2738 } else if ($root->getElementsByTagName("proxyFailure")->length != 0) { 2739 // look for a proxyFailure tag 2740 $proxy_failure_list = $root->getElementsByTagName("proxyFailure"); 2742 // authentication failed, extract the error 2743 $err_code = PHPCAS_SERVICE_PT_FAILURE; 2744 $err_msg = 'PT retrieving failed (code=`
' 2745 .$proxy_failure_list->item(0)->getAttribute('code
') 2747 .trim($proxy_failure_list->item(0)->nodeValue)
2749 phpCAS::traceEnd(false); 2752 phpCAS::trace('neither <proxySuccess> nor <proxyFailure> found
'); 2756 // at this step, we are sure that the response of the CAS server was 2758 $err_code = PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE; 2759 $err_msg = 'Invalid response from the
CAS server (response=`
' 2760 .$cas_response.'\
')';
2790 private function _readURL($url, &$headers, &$body, &$err_msg)
2794 $request =
new $className();
2796 if (count($this->_curl_options)) {
2797 $request->setCurlOptions($this->_curl_options);
2800 $request->setUrl($url);
2802 if (empty($this->_cas_server_ca_cert) && !$this->_no_cas_server_validation) {
2804 'one of the methods phpCAS::setCasServerCACert() or phpCAS::setNoCasServerValidation() must be called.' 2807 if ($this->_cas_server_ca_cert !=
'') {
2808 $request->setSslCaCert(
2809 $this->_cas_server_ca_cert, $this->_cas_server_cn_validate
2815 $request->addHeader(
"soapaction: http://www.oasis-open.org/committees/security");
2816 $request->addHeader(
"cache-control: no-cache");
2817 $request->addHeader(
"pragma: no-cache");
2818 $request->addHeader(
"accept: text/xml");
2819 $request->addHeader(
"connection: keep-alive");
2820 $request->addHeader(
"content-type: text/xml");
2821 $request->makePost();
2825 if ($request->send()) {
2826 $headers = $request->getResponseHeaders();
2827 $body = $request->getResponseBody();
2834 $err_msg = $request->getErrorMessage();
2853 .SAML_ASSERTION_ARTIFACT.$sa.SAML_ASSERTION_ARTIFACT_CLOSE
2854 .SAMLP_REQUEST_CLOSE.SAML_SOAP_BODY_CLOSE.SAML_SOAP_ENV_CLOSE;
2889 if (gettype($type) !=
'string')
2896 $request =
new $requestClass();
2897 if (count($this->_curl_options)) {
2898 $request->setCurlOptions($this->_curl_options);
2900 $proxiedService =
new $type($request, $this->_serviceCookieJar);
2902 $proxiedService->setCasClient($this);
2904 return $proxiedService;
2907 if ($proxiedService instanceof CAS_ProxiedService_Testable) {
2908 $proxiedService->setCasClient($this);
2910 return $proxiedService;
2913 "Unknown proxied-service type, $type." 2940 if (!is_string($url)) {
2942 "Proxied Service ".get_class($proxiedService)
2943 .
"->getServiceUrl() should have returned a string, returned a " 2944 .gettype($url).
" instead." 2947 $pt = $this->
retrievePT($url, $err_code, $err_msg);
2975 if (gettype($url) !=
'string')
2980 $service->setUrl($url);
2982 $output = $service->getResponseBody();
2986 $err_code = $e->getCode();
2987 $output = $e->getMessage();
2992 $lang->getServiceUnavailable(), $url, $e->getMessage()
3025 if (gettype($url) !=
'string')
3029 if (gettype($flags) !=
'integer')
3035 $service->setMailbox($url);
3036 $service->setOptions($flags);
3038 $stream = $service->open();
3040 $pt = $service->getImapProxyTicket();
3043 $err_msg = $e->getMessage();
3044 $err_code = $e->getCode();
3050 $lang->getServiceUnavailable(),
3112 $this->_proxies = $proxies;
3113 if (!empty($proxies)) {
3139 if (empty($this->_allowed_proxy_chains)) {
3166 public function validateCAS20(&$validate_url,&$text_response,&$tree_response, $renew=
false)
3187 $validate_url .=
'&renew=true';
3191 if ( !$this->
_readURL($validate_url, $headers, $text_response, $err_msg) ) {
3193 'could not open URL \''.$validate_url.
'\' to validate (
'.$err_msg.')
' 3195 throw new CAS_AuthenticationException( 3196 $this, 'Ticket not validated
', $validate_url, 3197 true/*$no_response*/ 3202 // create new DOMDocument object 3203 $dom = new DOMDocument(); 3204 // Fix possible whitspace problems 3205 $dom->preserveWhiteSpace = false; 3206 // CAS servers should only return data in utf-8 3207 $dom->encoding = "utf-8"; 3208 // read the response of the CAS server into a DOMDocument object 3209 if ( !($dom->loadXML($text_response))) { 3211 throw new CAS_AuthenticationException( 3212 $this, 'Ticket not validated
', $validate_url, 3213 false/*$no_response*/, true/*$bad_response*/, $text_response 3216 } else if ( !($tree_response = $dom->documentElement) ) { 3217 // read the root node of the XML tree 3219 throw new CAS_AuthenticationException( 3220 $this, 'Ticket not validated
', $validate_url, 3221 false/*$no_response*/, true/*$bad_response*/, $text_response 3224 } else if ($tree_response->localName != 'serviceResponse
') { 3225 // insure that tag name is 'serviceResponse
' 3227 throw new CAS_AuthenticationException( 3228 $this, 'Ticket not validated
', $validate_url, 3229 false/*$no_response*/, true/*$bad_response*/, $text_response 3232 } else if ( $tree_response->getElementsByTagName("authenticationFailure")->length != 0) { 3233 // authentication failed, extract the error code and message and throw exception 3234 $auth_fail_list = $tree_response 3235 ->getElementsByTagName("authenticationFailure"); 3236 throw new CAS_AuthenticationException( 3237 $this, 'Ticket not validated
', $validate_url, 3238 false/*$no_response*/, false/*$bad_response*/, 3240 $auth_fail_list->item(0)->getAttribute('code
')/*$err_code*/, 3241 trim($auth_fail_list->item(0)->nodeValue)/*$err_msg*/ 3244 } else if ($tree_response->getElementsByTagName("authenticationSuccess")->length != 0) { 3245 // authentication succeded, extract the user name 3246 $success_elements = $tree_response 3247 ->getElementsByTagName("authenticationSuccess"); 3248 if ( $success_elements->item(0)->getElementsByTagName("user")->length == 0) { 3249 // no user specified => error 3250 throw new CAS_AuthenticationException( 3251 $this, 'Ticket not validated
', $validate_url, 3252 false/*$no_response*/, true/*$bad_response*/, $text_response 3258 $success_elements->item(0)->getElementsByTagName("user")->item(0)->nodeValue 3261 $this->_readExtraAttributesCas20($success_elements); 3262 // Store the proxies we are sitting behind for authorization checking 3263 $proxyList = array(); 3264 if ( sizeof($arr = $success_elements->item(0)->getElementsByTagName("proxy")) > 0) { 3265 foreach ($arr as $proxyElem) { 3266 phpCAS::trace("Found Proxy: ".$proxyElem->nodeValue); 3267 $proxyList[] = trim($proxyElem->nodeValue); 3269 $this->_setProxies($proxyList); 3270 phpCAS::trace("Storing Proxy List"); 3272 // Check if the proxies in front of us are allowed 3273 if (!$this->getAllowedProxyChains()->isProxyListAllowed($proxyList)) { 3274 throw new CAS_AuthenticationException( 3275 $this, 'Proxy not allowed
', $validate_url, 3276 false/*$no_response*/, true/*$bad_response*/, 3285 throw new CAS_AuthenticationException( 3286 $this, 'Ticket not validated
', $validate_url, 3287 false/*$no_response*/, true/*$bad_response*/, 3293 $this->_renameSession($this->getTicket()); 3295 // at this step, Ticket has been validated and $this->_user has been set, 3297 phpCAS::traceEnd($result); 3311 private function _readExtraAttributesCas20($success_elements) 3313 phpCAS::traceBegin(); 3315 $extra_attributes = array(); 3317 // "Jasig Style" Attributes: 3319 // <cas:serviceResponse xmlns:cas='http:
3333 if ($this->_casAttributeParserCallbackFunction !== null
3334 && is_callable($this->_casAttributeParserCallbackFunction)
3336 array_unshift($this->_casAttributeParserCallbackArgs, $success_elements->item(0));
3337 phpCas :: trace(
"Calling attritubeParser callback");
3338 $extra_attributes = call_user_func_array(
3339 $this->_casAttributeParserCallbackFunction,
3340 $this->_casAttributeParserCallbackArgs
3342 } elseif ( $success_elements->item(0)->getElementsByTagName(
"attributes")->length != 0) {
3343 $attr_nodes = $success_elements->item(0)
3344 ->getElementsByTagName(
"attributes");
3345 phpCas :: trace(
"Found nested jasig style attributes");
3346 if ($attr_nodes->item(0)->hasChildNodes()) {
3348 foreach ($attr_nodes->item(0)->childNodes as $attr_child) {
3350 "Attribute [".$attr_child->localName.
"] = " 3351 .$attr_child->nodeValue
3354 $extra_attributes, $attr_child->localName,
3355 $attr_child->nodeValue
3376 phpCas :: trace(
"Testing for rubycas style attributes");
3377 $childnodes = $success_elements->item(0)->childNodes;
3378 foreach ($childnodes as $attr_node) {
3379 switch ($attr_node->localName) {
3382 case 'proxyGrantingTicket':
3385 if (strlen(trim($attr_node->nodeValue))) {
3387 "Attribute [".$attr_node->localName.
"] = ".$attr_node->nodeValue
3390 $extra_attributes, $attr_node->localName,
3391 $attr_node->nodeValue
3418 if (!count($extra_attributes)
3419 && $success_elements->item(0)->getElementsByTagName(
"attribute")->length != 0
3421 $attr_nodes = $success_elements->item(0)
3422 ->getElementsByTagName(
"attribute");
3423 $firstAttr = $attr_nodes->item(0);
3424 if (!$firstAttr->hasChildNodes()
3425 && $firstAttr->hasAttribute(
'name')
3426 && $firstAttr->hasAttribute(
'value')
3428 phpCas :: trace(
"Found Name-Value style attributes");
3430 foreach ($attr_nodes as $attr_node) {
3431 if ($attr_node->hasAttribute(
'name')
3432 && $attr_node->hasAttribute(
'value')
3435 "Attribute [".$attr_node->getAttribute(
'name')
3436 .
"] = ".$attr_node->getAttribute(
'value')
3439 $extra_attributes, $attr_node->getAttribute(
'name'),
3440 $attr_node->getAttribute(
'value')
3464 if (isset($attributeArray[$name])) {
3466 if (!is_array($attributeArray[$name])) {
3467 $existingValue = $attributeArray[$name];
3468 $attributeArray[$name] = array($existingValue);
3471 $attributeArray[$name][] = trim($value);
3473 $attributeArray[$name] = trim($value);
3512 if (gettype($url) !=
'string')
3528 if ( empty($this->_url) ) {
3531 $final_uri = ($this->
_isHttps()) ?
'https' :
'http';
3532 $final_uri .=
'://';
3535 $request_uri = explode(
'?', $_SERVER[
'REQUEST_URI'], 2);
3536 $final_uri .= $request_uri[0];
3538 if (isset($request_uri[1]) && $request_uri[1]) {
3543 if ($query_string !==
'') {
3544 $final_uri .=
"?$query_string";
3549 $this->
setURL($final_uri);
3565 if (gettype($url) !=
'string')
3568 return $this->_server[
'base_url'] = $url;
3580 if (!empty($_SERVER[
'HTTP_X_FORWARDED_HOST'])) {
3582 $hosts = explode(
',', $_SERVER[
'HTTP_X_FORWARDED_HOST']);
3585 }
else if (!empty($_SERVER[
'HTTP_X_FORWARDED_SERVER'])) {
3586 $server_url = $_SERVER[
'HTTP_X_FORWARDED_SERVER'];
3588 if (empty($_SERVER[
'SERVER_NAME'])) {
3589 $server_url = $_SERVER[
'HTTP_HOST'];
3591 $server_url = $_SERVER[
'SERVER_NAME'];
3594 if (!strpos($server_url,
':')) {
3595 if (empty($_SERVER[
'HTTP_X_FORWARDED_PORT'])) {
3596 $server_port = $_SERVER[
'SERVER_PORT'];
3598 $ports = explode(
',', $_SERVER[
'HTTP_X_FORWARDED_PORT']);
3599 $server_port = $ports[0];
3602 if ( ($this->
_isHttps() && $server_port!=443)
3603 || (!$this->
_isHttps() && $server_port!=80)
3606 $server_url .= $server_port;
3619 if (!empty($_SERVER[
'HTTP_X_FORWARDED_PROTO'])) {
3620 return ($_SERVER[
'HTTP_X_FORWARDED_PROTO'] ===
'https');
3621 } elseif (!empty($_SERVER[
'HTTP_X_FORWARDED_PROTOCOL'])) {
3622 return ($_SERVER[
'HTTP_X_FORWARDED_PROTOCOL'] ===
'https');
3623 } elseif ( isset($_SERVER[
'HTTPS'])
3624 && !empty($_SERVER[
'HTTPS'])
3625 && strcasecmp($_SERVER[
'HTTPS'],
'off') !== 0
3645 $parameterName = preg_quote($parameterName);
3646 return preg_replace(
3647 "/&$parameterName(=[^&]*)?|^$parameterName(=[^&]*)?&?/",
3664 $url .= (strstr($url,
'?') ===
false) ?
'?' :
'&';
3680 if (!empty($this->_user)) {
3681 $old_session = $_SESSION;
3687 session_id($session_id);
3690 $_SESSION = $old_session;
3693 'Session should only be renamed after successfull authentication' 3698 "Skipping session rename since phpCAS is not handling the session." 3719 return hash(
'sha256', $this->_sessionIdSalt . $ticket);
3737 $this->_sessionIdSalt = (string)$salt;
3772 $lang->getYouWereNotAuthenticated(), htmlentities($this->
getURL()),
3773 isset($_SERVER[
'SERVER_ADMIN']) ? $_SERVER[
'SERVER_ADMIN']:
'' 3777 if ( $no_response ) {
3780 if ( $bad_response ) {
3789 if ( empty($err_code) ) {
3793 'Reason: ['.$err_code.
'] CAS error: '.$err_msg
3834 if (preg_match(
"/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/", $nodeURL)) {
3839 return self::HOSTNAME;
3853 if ( !(
bool)preg_match(
"/^(http|https):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i", $rebroadcastNodeUrl))
3858 $this->_rebroadcast_nodes[] = $rebroadcastNodeUrl;
3876 if (gettype($header) !=
'string')
3879 $this->_rebroadcast_headers[] = $header;
3899 $rebroadcast_curl_options = array(
3900 CURLOPT_FAILONERROR => 1,
3901 CURLOPT_FOLLOWLOCATION => 1,
3902 CURLOPT_RETURNTRANSFER => 1,
3903 CURLOPT_CONNECTTIMEOUT => 1,
3904 CURLOPT_TIMEOUT => 4);
3907 if (!empty($_SERVER[
'SERVER_ADDR'])) {
3908 $ip = $_SERVER[
'SERVER_ADDR'];
3909 }
else if (!empty($_SERVER[
'LOCAL_ADDR'])) {
3911 $ip = $_SERVER[
'LOCAL_ADDR'];
3915 $dns = gethostbyaddr($ip);
3917 $multiClassName =
'CAS_Request_CurlMultiRequest';
3918 $multiRequest =
new $multiClassName();
3921 if ((($this->
_getNodeType($this->_rebroadcast_nodes[$i]) == self::HOSTNAME) && !empty($dns) && (stripos($this->_rebroadcast_nodes[$i], $dns) ===
false))
3922 || (($this->
_getNodeType($this->_rebroadcast_nodes[$i]) == self::IP) && !empty($ip) && (stripos($this->_rebroadcast_nodes[$i], $ip) ===
false))
3925 'Rebroadcast target URL: '.$this->_rebroadcast_nodes[$i]
3926 .$_SERVER[
'REQUEST_URI']
3929 $request =
new $className();
3931 $url = $this->_rebroadcast_nodes[$i].$_SERVER[
'REQUEST_URI'];
3932 $request->setUrl($url);
3934 if (count($this->_rebroadcast_headers)) {
3935 $request->addHeaders($this->_rebroadcast_headers);
3938 $request->makePost();
3939 if ($type == self::LOGOUT) {
3941 $request->setPostBody(
3942 'rebroadcast=false&logoutRequest='.$_POST[
'logoutRequest']
3944 }
else if ($type == self::PGTIOU) {
3946 $request->setPostBody(
'rebroadcast=false');
3949 $request->setCurlOptions($rebroadcast_curl_options);
3951 $multiRequest->addRequest($request);
3954 'Rebroadcast not sent to self: ' 3955 .$this->_rebroadcast_nodes[$i].
' == '.(!empty($ip)?$ip:
'')
3956 .
'/'.(!empty($dns)?$dns:
'')
3961 if ($multiRequest->getNumRequests() > 0) {
3962 $multiRequest->send();
getAuthenticationCallerFile()
$_cache_times_for_auth_recheck
setPGTStorageFile($path='')
setServerServiceValidateURL($url)
const PHPCAS_PROXIED_SERVICE_IMAP
initializeProxiedService(CAS_ProxiedService $proxiedService)
_ensureAuthenticationCalled()
retrievePT($target_service, &$err_code, &$err_msg)
setCasAttributeParserCallback($function, array $additionalArgs=array())
_authError( $failure, $cas_url, $no_response, $bad_response='', $cas_response='', $err_code='', $err_msg='')
setSingleSignoutCallback($function, array $additionalArgs=array())
if(isset( $_REQUEST[ 'logout']))
addRebroadcastHeader($header)
wasAuthenticationCalled()
_removeParameterFromQueryString($parameterName, $queryString)
wasAuthenticationCallSuccessful()
getServerProxyValidateURL()
_setChangeSessionID($allowed)
_validatePGT(&$validate_url, $text_response, $tree_response)
const PHPCAS_LANG_DEFAULT
setRequestImplementation($className)
isAuthenticated($renew=false)
_wasPreviouslyAuthenticated()
setProxyTicket($proxyTicket)
if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']=='on') else
$_casAttributeParserCallbackArgs
_buildQueryUrl($url, $query)
const PHPCAS_PROXIED_SERVICE_HTTP_POST
markAuthenticationCall($auth)
getServerServiceValidateURL()
_readURL($url, &$headers, &$body, &$err_msg)
redirectToCas($gateway=false, $renew=false)
const PHPCAS_SERVICE_NOT_AVAILABLE
setServerProxyValidateURL($url)
_setCallbackMode($callback_mode)
setPostAuthenticateCallback($function, array $additionalArgs=array())
_addAttributeToArray(array &$attributeArray, $name, $value)
$_postAuthenticateCallbackArgs
validateCAS20(&$validate_url, &$text_response, &$tree_response, $renew=false)
setAttributes($attributes)
ensureAuthenticationCallSuccessful()
_sessionIdForTicket($ticket)
validateSA(&$validate_url, &$text_response, &$tree_response, $renew=false)
setNoCasServerValidation()
getServerLoginURL($gateway=false, $renew=false)
$_no_cas_server_validation
getAuthenticationCallerLine()
setNoClearTicketsFromUrl()
__construct( $server_version, $proxy, $server_hostname, $server_port, $server_uri, $changeSessionID=true)
setServerSamlValidateURL($url)
setCasServerCACert($cert, $validate_cn)
getAuthenticationCallerMethod()
if(isset($_REQUEST['logout'])) if(isset($_REQUEST['login'])) $auth
addRebroadcastNode($rebroadcastNodeUrl)
setCacheTimesForAuthRecheck($n)
const PHPCAS_PROXIED_SERVICE_HTTP_GET
setExtraCurlOption($key, $value)
_storePGT($pgt, $pgt_iou)
_setSessionAttributes($text_response)
setPGTStorageDb( $dsn_or_pdo, $username='', $password='', $table='', $driver_options=null)
serviceMail($url, $serviceUrl, $flags, &$err_code, &$err_msg, &$pt)
$_casAttributeParserCallbackFunction
handleLogoutRequests($check_client=true, $allowed_clients=false)
getServerSamlValidateURL()
$_signoutCallbackFunction
validateCAS10(&$validate_url, &$text_response, &$tree_response, $renew=false)
$_postAuthenticateCallbackFunction
serviceWeb($url, &$err_code, &$output)