38 include_once(dirname(__FILE__).
'/languages/languages.php');
41 include_once(dirname(__FILE__).
'/PGTStorage/pgt-main.php');
112 (empty($this->_output_header)
113 ?
'<html><head><title>__TITLE__</title></head><body><h1>__TITLE__</h1>' 114 : $this->_output_header)
139 ?(
'<hr><address>phpCAS __PHPCAS_VERSION__ '.$this->
getString(
CAS_STR_USING_SERVER).
' <a href="__SERVER_BASE_URL__">__SERVER_BASE_URL__</a> (CAS __CAS_VERSION__)</a></address></body></html>')
140 :$this->_output_footer);
152 $this->_output_header = $header;
164 $this->_output_footer = $footer;
196 if ( empty($this->_lang) )
226 if ( !isset($this->
_strings[$str]) ) {
227 trigger_error(
'string `'.$str.
'\' not defined
for language `
'.$this->getLang().'\
'',E_USER_ERROR);
244 include_once(dirname(__FILE__).
'/languages/'.
$lang.
'.php');
247 trigger_error(
'language `'.
$lang.
'\' is not implemented
',E_USER_ERROR); 249 $this->_lang = $lang; 253 // ######################################################################## 255 // ######################################################################## 285 var $_server = array( 287 'hostname
' => 'none
', 297 function getServerVersion() 299 return $this->_server['version
']; 307 function getServerHostname() 308 { return $this->_server['hostname
']; } 315 function getServerPort() 316 { return $this->_server['port
']; } 323 function getServerURI() 324 { return $this->_server['uri
']; } 331 function getServerBaseURL() 333 // the URL is build only when needed 334 if ( empty($this->_server['base_url
']) ) { 335 $this->_server['base_url
'] = 'https:
336 .$this->getServerHostname()
338 .$this->getServerPort()
339 .$this->getServerURI();
341 return $this->_server[
'base_url'];
356 if ( empty($this->_server[
'login_url']) ) {
358 $this->_server[
'login_url'] .=
'login?service=';
360 $this->_server[
'login_url'] .= urlencode($this->
getURL());
363 $this->_server[
'login_url'] .=
'&renew=true';
364 } elseif ($gateway) {
366 $this->_server[
'login_url'] .=
'&gateway=true';
370 return $this->_server[
'login_url'];
381 return $this->_server[
'login_url'] = $url;
393 return $this->_server[
'service_validate_url'] = $url;
405 return $this->_server[
'proxy_validate_url'] = $url;
417 return $this->_server[
'saml_validate_url'] = $url;
429 if ( empty($this->_server[
'service_validate_url']) ) {
432 $this->_server[
'service_validate_url'] = $this->
getServerBaseURL().
'validate';
435 $this->_server[
'service_validate_url'] = $this->
getServerBaseURL().
'serviceValidate';
440 return $this->_server[
'service_validate_url'].
'?service='.urlencode($this->
getURL());
451 if ( empty($this->_server[
'saml_validate_url']) ) {
454 $this->_server[
'saml_validate_url'] = $this->
getServerBaseURL().
'samlValidate';
459 return $this->_server[
'saml_validate_url'].
'?TARGET='.urlencode($this->
getURL());
469 if ( empty($this->_server[
'proxy_validate_url']) ) {
472 $this->_server[
'proxy_validate_url'] =
'';
475 $this->_server[
'proxy_validate_url'] = $this->
getServerBaseURL().
'proxyValidate';
480 return $this->_server[
'proxy_validate_url'].
'?service='.urlencode($this->
getURL());
491 if ( empty($this->_server[
'proxy_url']) ) {
494 $this->_server[
'proxy_url'] =
'';
501 return $this->_server[
'proxy_url'];
512 if ( empty($this->_server[
'logout_url']) ) {
515 return $this->_server[
'logout_url'];
526 return $this->_server[
'logout_url'] = $url;
539 $this->_curl_options[$key] = $value;
550 if ( isset($_SERVER[
'HTTPS']) && !empty($_SERVER[
'HTTPS']) && $_SERVER[
'HTTPS'] ==
'on') {
551 # mantis: 0013115: CAS not work on HTTPS 581 $start_session =
true) {
586 if (version_compare(PHP_VERSION,
'5',
'>=') && ini_get(
'zend.ze1_compatibility_mode')) {
587 phpCAS::error(
'phpCAS cannot support zend.ze1_compatibility_mode. Sorry.');
589 $this->_start_session = $start_session;
591 if ($this->_start_session && session_id())
593 phpCAS :: error(
"Another session was started before phpcas. Either disable the session" .
594 " handling for phpcas in the client() call or modify your application to leave" .
595 " session handling to phpcas");
606 $this->_proxy = $proxy;
609 switch ($server_version) {
622 .
'\') is not supported by
phpCAS ' 623 .phpCAS::getVersion()); 625 $this->_server['version
'] = $server_version; 628 if ( empty($server_hostname) 629 || !preg_match('/[\.\d\-abcdefghijklmnopqrstuvwxyz]*/
',$server_hostname) ) { 630 phpCAS::error('bad CAS server hostname (`
'.$server_hostname.'\
')');
632 $this->_server[
'hostname'] = $server_hostname;
635 if ( $server_port == 0
636 || !is_int($server_port) ) {
637 phpCAS::error(
'bad CAS server port (`'.$server_hostname.
'\')
'); 639 $this->_server['port
'] = $server_port; 642 if ( !preg_match('/[\.\d\-_abcdefghijklmnopqrstuvwxyz\/]*/
',$server_uri) ) { 643 phpCAS::error('bad CAS server URI (`
'.$server_uri.'\
')');
646 $server_uri = preg_replace(
'/\/\//',
'/',
'/'.$server_uri.
'/');
647 $this->_server[
'uri'] = $server_uri;
657 phpCAS::error(
'CAS proxies must be secured to use phpCAS; PGT\'s will not be received from the CAS server');
661 $ticket = (isset(
$_GET[
'ticket']) ?
$_GET[
'ticket'] : null);
664 if( preg_match(
'/^ST-/',$ticket) ) {
667 $this->setST($ticket); 668 //ticket has been taken into account, unset it to hide it to applications 669 unset($_GET['ticket
']); 670 } else if ( !empty($ticket) ) { 671 //ill-formed ticket, halt 672 phpCAS::error('ill-formed ticket found in the URL (ticket=`
'.htmlentities($ticket).'\
')');
676 if( preg_match(
'/^ST-/',$ticket) ) {
678 $this->setST($ticket); 679 unset($_GET['ticket
']); 681 elseif(preg_match('/PT-/
', $ticket)) { 682 phpCAS::trace('PT \
''.$ticket.
'\' found
'); 683 $this->setPT($ticket); 684 unset($_GET['ticket
']); 685 } else if ( !empty($ticket) ) { 686 //ill-formed ticket, halt 687 phpCAS::error('ill-formed ticket found in the URL (ticket=`
'.htmlentities($ticket).'\
')');
691 if( preg_match(
'/^[SP]T-/',$ticket) ) {
693 $this->setSA($ticket); 694 unset($_GET['ticket
']); 695 } else if ( !empty($ticket) ) { 696 //ill-formed ticket, halt 697 phpCAS::error('ill-formed ticket found in the URL (ticket=`
'.htmlentities($ticket).'\
')');
722 $this->_start_session = session;
727 $this->_start_session = session;
736 if($this->_start_session){
737 if (!empty ($this->_user))
743 if(version_compare(PHP_VERSION,
'5.3.0',
'<'))
745 include_once
'./Services/Init/classes/class.ilInitialisation.php';
750 $session_id = preg_replace(
'/[^\w]/',
'', $ticket);
752 session_id($session_id);
758 phpCAS :: error(
'Session should only be renamed after successfull authentication');
761 phpCAS :: trace(
"Skipping session rename since phpCAS is not handling the session.");
795 $this->_user = $user;
807 if ( empty($this->_user) ) {
808 phpCAS::error(
'this method should be used only after '.__CLASS__.
'::forceAuthentication() or '.__CLASS__.
'::isAuthenticated()');
831 { $this->_attributes = $attributes; }
834 if ( empty($this->_user) ) {
835 phpCAS::error(
'this method should be used only after '.__CLASS__.
'::forceAuthentication() or '.__CLASS__.
'::isAuthenticated()');
841 {
return !empty($this->_attributes); }
844 {
return (is_array($this->_attributes) && array_key_exists($key, $this->_attributes)); }
848 return $this->_attributes[$key];
861 if( isset(
$_SESSION[
'phpCAS'][
'auth_checked'] ) )
862 unset(
$_SESSION[
'phpCAS'][
'auth_checked']);
888 if (isset(
$_SESSION[
'phpCAS'][
'auth_checked'])) {
889 unset(
$_SESSION[
'phpCAS'][
'auth_checked']);
916 $this->_cache_times_for_auth_recheck =
$n;
931 }
else if (isset(
$_SESSION[
'phpCAS'][
'auth_checked'])) {
933 unset(
$_SESSION[
'phpCAS'][
'auth_checked']);
941 if (! isset(
$_SESSION[
'phpCAS'][
'unauth_count']) )
942 $_SESSION[
'phpCAS'][
'unauth_count'] = -2;
944 if ((
$_SESSION[
'phpCAS'][
'unauth_count'] != -2 && $this->_cache_times_for_auth_recheck == -1)
945 || (
$_SESSION[
'phpCAS'][
'unauth_count'] >= 0 &&
$_SESSION[
'phpCAS'][
'unauth_count'] < $this->_cache_times_for_auth_recheck))
949 if ($this->_cache_times_for_auth_recheck != -1)
952 phpCAS::trace(
'user is not authenticated (cached for '.
$_SESSION[
'phpCAS'][
'unauth_count'].
' times of '.$this->_cache_times_for_auth_recheck.
')');
956 phpCAS::trace(
'user is not authenticated (cached for until login pressed)');
962 $_SESSION[
'phpCAS'][
'auth_checked'] =
true;
990 phpCAS::trace(
'ticket was present and will be discarded, use renewAuthenticate()');
991 header(
'Location: '.$this->
getURL());
996 phpCAS::trace(
'user was already authenticated, no need to look for tickets');
1001 if ( $this->
hasST() ) {
1004 $this->validateST($validate_url,$text_response,$tree_response); // if it fails, it halts 1005 phpCAS::trace('ST `
'.$this->getST().'\
' was validated');
1007 $this->
validatePGT($validate_url,$text_response,$tree_response);
1009 $_SESSION['phpCAS']['pgt
'] = $this->getPGT(); 1011 $_SESSION['phpCAS']['user
'] = $this->getUser(); 1014 elseif ( $this->hasPT() ) { 1015 // if a Proxy Ticket was given, validate it 1016 phpCAS::trace('PT `
'.$this->getPT().'\
' is present');
1017 $this->
validatePT($validate_url,$text_response,$tree_response);
1019 if ( $this->isProxy() ) { 1020 $this->validatePGT($validate_url,$text_response,$tree_response); // idem 1021 phpCAS::trace('PGT `
'.$this->getPGT().'\
' was validated');
1027 elseif ( $this->
hasSA() ) {
1030 $this->validateSA($validate_url,$text_response,$tree_response); // if it fails, it halts 1031 phpCAS::trace('SA `
'.$this->getSA().'\
' was validated');
1043 header(
'Location: '.$this->
getURL());
1059 return !empty(
$_SESSION[
'phpCAS'][
'user']);
1093 // unset all tickets to enforce authentication 1094 unset($_SESSION['phpCAS']); 1097 } elseif ( !$this->isSessionAuthenticated() && !empty($_SESSION['phpCAS']['pgt
']) ) { 1098 // these two variables should be empty or not empty at the same time 1099 phpCAS::trace('PGT found (`
'.$_SESSION['phpCAS']['pgt
'].'\
') but username is empty');
1112 if(isset(
$_SESSION[
'phpCAS'][
'attributes'])){
1136 header(
'Location: '.$cas_url);
1157 $paramSeparator =
'?';
1158 if (isset($params[
'url'])) {
1159 $cas_url = $cas_url . $paramSeparator .
"url=" . urlencode($params[
'url']);
1160 $paramSeparator =
'&';
1162 if (isset($params[
'service'])) {
1163 $cas_url = $cas_url . $paramSeparator .
"service=" . urlencode($params[
'service']);
1165 header(
'Location: '.$cas_url);
1184 return !empty(
$_POST[
'logoutRequest']);
1209 if(!$this->_start_session){
1210 phpCAS::log(
"phpCAS can't handle logout requests if it does not manage the session.");
1214 if ($check_client) {
1215 if (!$allowed_clients) {
1218 $client_ip = $_SERVER[
'REMOTE_ADDR'];
1219 $client = gethostbyaddr($client_ip);
1222 foreach ($allowed_clients as $allowed_client) {
1223 if ((
$client == $allowed_client) or ($client_ip == $allowed_client)) {
1224 phpCAS::log(
"Allowed client '".$allowed_client.
"' matches, logout request is allowed");
1228 phpCAS::log(
"Allowed client '".$allowed_client.
"' does not match");
1233 printf(
"Unauthorized!");
1241 preg_match(
"|<samlp:SessionIndex>(.*)</samlp:SessionIndex>|",
$_POST[
'logoutRequest'], $tick, PREG_OFFSET_CAPTURE, 3);
1242 $wrappedSamlSessionIndex = preg_replace(
'|<samlp:SessionIndex>|',
'',$tick[0][0]);
1243 $ticket2logout = preg_replace(
'|</samlp:SessionIndex>|',
'',$wrappedSamlSessionIndex);
1245 $session_id = preg_replace(
'/[^\w]/',
'',$ticket2logout);
1254 session_id($session_id);
1255 $_COOKIE[session_name()]=$session_id;
1256 $_GET[session_name()]=$session_id;
1262 printf(
"Disconnected!");
1307 { $this->_st = $st; }
1315 {
return !empty($this->_st); }
1358 $this->_cas_server_cert = $cert;
1368 $this->_cas_server_ca_cert = $cert;
1376 $this->_no_cas_server_validation =
true;
1392 function validateST($validate_url,&$text_response,&$tree_response)
1403 if ( !$this->
readURL($validate_url,
'',$headers,$text_response,$err_msg) ) {
1404 phpCAS::trace(
'could not open URL \''.$validate_url.
'\' to validate (
'.$err_msg.')
'); 1405 $this->authError('ST not validated
', 1407 TRUE/*$no_response*/); 1410 // analyze the result depending on the version 1411 switch ($this->getServerVersion()) { 1412 case CAS_VERSION_1_0: 1413 if (preg_match('/^no\
n/
',$text_response)) { 1414 phpCAS::trace('ST has not been validated
'); 1415 $this->authError('ST not validated
', 1417 FALSE/*$no_response*/, 1418 FALSE/*$bad_response*/, 1421 if (!preg_match('/^yes\
n/
',$text_response)) { 1422 phpCAS::trace('ill-formed response
'); 1423 $this->authError('ST not validated
', 1425 FALSE/*$no_response*/, 1426 TRUE/*$bad_response*/, 1429 // ST has been validated, extract the user name 1430 $arr = preg_split('/\
n/
',$text_response); 1431 $this->setUser(trim($arr[1])); 1433 case CAS_VERSION_2_0: 1434 // read the response of the CAS server into a DOM object 1435 if ( !($dom = domxml_open_mem($text_response))) { 1437 $this->authError('ST not validated
', 1439 FALSE/*$no_response*/, 1440 TRUE/*$bad_response*/, 1443 // read the root node of the XML tree 1444 if ( !($tree_response = $dom->document_element()) ) { 1445 phpCAS::trace('document_element() failed
'); 1446 $this->authError('ST not validated
', 1448 FALSE/*$no_response*/, 1449 TRUE/*$bad_response*/, 1452 // insure that tag name is 'serviceResponse
' 1453 if ( $tree_response->node_name() != 'serviceResponse
' ) { 1454 phpCAS::trace('bad XML root node (should be `serviceResponse\
' instead of `'.$tree_response->node_name().
'\'');
1461 if (
sizeof($success_elements = $tree_response->get_elements_by_tagname(
"authenticationSuccess")) != 0) {
1463 if (
sizeof($user_elements = $success_elements[0]->get_elements_by_tagname(
"user")) == 0) {
1464 phpCAS::trace(
'<authenticationSuccess> found, but no <user>');
1471 $user = trim($user_elements[0]->get_content());
1475 }
else if (
sizeof($failure_elements = $tree_response->get_elements_by_tagname(
"authenticationFailure")) != 0) {
1483 $failure_elements[0]->get_attribute(
'code'),
1484 trim($failure_elements[0]->get_content()));
1486 phpCAS::trace(
'neither <authenticationSuccess> nor <authenticationFailure> found');
1522 function validateSA($validate_url,&$text_response,&$tree_response)
1530 if ( !$this->
readURL($validate_url,
'',$headers,$text_response,$err_msg) ) {
1531 phpCAS::trace(
'could not open URL \''.$validate_url.
'\' to validate (
'.$err_msg.')
'); 1532 $this->authError('SA not validated
', $validate_url, TRUE/*$no_response*/); 1535 phpCAS::trace('server version:
'.$this->getServerVersion()); 1537 // analyze the result depending on the version 1538 switch ($this->getServerVersion()) { 1539 case SAML_VERSION_1_1: 1541 // read the response of the CAS server into a DOM object 1542 if ( !($dom = domxml_open_mem($text_response))) { 1544 $this->authError('SA not validated
', 1546 FALSE/*$no_response*/, 1547 TRUE/*$bad_response*/, 1550 // read the root node of the XML tree 1551 if ( !($tree_response = $dom->document_element()) ) { 1552 phpCAS::trace('document_element() failed
'); 1553 $this->authError('SA not validated
', 1555 FALSE/*$no_response*/, 1556 TRUE/*$bad_response*/, 1559 // insure that tag name is 'Envelope
' 1560 if ( $tree_response->node_name() != 'Envelope
' ) { 1561 phpCAS::trace('bad XML root node (should be `Envelope\
' instead of `'.$tree_response->node_name().
'\'');
1569 if (
sizeof($success_elements = $tree_response->get_elements_by_tagname(
"NameIdentifier")) != 0) {
1571 $user = trim($success_elements[0]->get_content());
1576 phpCAS::trace(
'no <NameIdentifier> tag found in SAML payload');
1610 $attr_array = array();
1613 $xPath = $dom->xpath_new_context();
1614 $xPath->xpath_register_ns(
'samlp',
'urn:oasis:names:tc:SAML:1.0:protocol');
1615 $xPath->xpath_register_ns(
'saml',
'urn:oasis:names:tc:SAML:1.0:assertion');
1616 $nodelist = $xPath->xpath_eval(
"//saml:Attribute");
1618 $attrs = $nodelist->nodeset;
1619 foreach($attrs as $attr){
1620 $xres = $xPath->xpath_eval(
"saml:AttributeValue", $attr);
1621 $name = $attr->get_attribute(
"AttributeName");
1622 $value_array = array();
1623 foreach($xres->nodeset as $node){
1624 $value_array[] = $node->get_content();
1626 $attr_array[$name] = $value_array;
1630 foreach($attr_array as $attr_key => $attr_value) {
1631 if(count($attr_value) > 1) {
1632 $this->_attributes[$attr_key] = $attr_value;
1636 $this->_attributes[$attr_key] = $attr_value[0];
1718 { $this->_pgt = $pgt; }
1726 {
return !empty($this->_pgt); }
1761 $this->_callback_mode = $callback_mode;
1799 if ( empty($this->_callback_url) ) {
1802 $final_uri =
'https://';
1806 if(empty($_SERVER[
'HTTP_X_FORWARDED_SERVER'])){
1810 if (empty($_SERVER[
'SERVER_NAME'])) {
1811 $final_uri .= $_SERVER[
'HTTP_HOST'];
1813 $final_uri .= $_SERVER[
'SERVER_NAME'];
1816 $final_uri .= $_SERVER[
'HTTP_X_FORWARDED_SERVER'];
1818 if ( ($this->
isHttps() && $_SERVER[
'SERVER_PORT']!=443)
1819 || (!$this->
isHttps() && $_SERVER[
'SERVER_PORT']!=80) ) {
1821 $final_uri .= $_SERVER[
'SERVER_PORT'];
1823 $request_uri = $_SERVER[
'REQUEST_URI'];
1824 $request_uri = preg_replace(
'/\?.*$/',
'',$request_uri);
1825 $final_uri .= $request_uri;
1840 return $this->_callback_url = $url;
1853 $pgt_iou =
$_GET[
'pgtIou'];
1854 $pgt =
$_GET[
'pgtId'];
1855 phpCAS::trace(
'Storing PGT `'.$pgt.
'\' (
id=`
'.$pgt_iou.'\
')');
1856 echo
'<p>Storing PGT `'.$pgt.
'\' (
id=`
'.$pgt_iou.'\
').</p>';
1857 $this->storePGT($pgt,$pgt_iou);
1892 if ( !is_object($this->_pgt_storage) ) {
1897 $this->_pgt_storage->init();
1913 $this->_pgt_storage->write($pgt,$pgt_iou);
1930 return $this->_pgt_storage->read($pgt_iou);
1946 if ( is_object($this->_pgt_storage) ) {
1980 if ( is_object($this->_pgt_storage) ) {
1985 trigger_error(
'PGT storage into database is an experimental feature, use at your own risk',E_USER_WARNING);
1988 $this->_pgt_storage =
new PGTStorageDB($this,$user,$password,$database_type,$hostname,$port,$database,$table);
2011 if (
sizeof($arr = $tree_response->get_elements_by_tagname(
"proxyGrantingTicket")) == 0) {
2014 $this->
authError(
'Ticket validated but no PGT Iou transmitted',
2021 $pgt_iou = trim($arr[0]->get_content());
2022 $pgt = $this->
loadPGT($pgt_iou);
2023 if ( $pgt == FALSE ) {
2025 $this->
authError(
'PGT Iou was transmitted but PGT could not be retrieved',
2068 if ( !$this->
readURL($cas_url,
'',$headers,$cas_response,$err_msg) ) {
2069 phpCAS::trace(
'could not open URL \''.$cas_url.
'\' to validate (
'.$err_msg.')
'); 2070 $err_code = PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE; 2071 $err_msg = 'could not retrieve PT (no response from the CAS server)
'; 2072 phpCAS::traceEnd(FALSE); 2076 $bad_response = FALSE; 2078 if ( !$bad_response ) { 2079 // read the response of the CAS server into a DOM object 2080 if ( !($dom = @domxml_open_mem($cas_response))) { 2083 $bad_response = TRUE; 2087 if ( !$bad_response ) { 2088 // read the root node of the XML tree 2089 if ( !($root = $dom->document_element()) ) { 2090 phpCAS::trace('document_element() failed
'); 2092 $bad_response = TRUE; 2096 if ( !$bad_response ) { 2097 // insure that tag name is 'serviceResponse
' 2098 if ( $root->node_name() != 'serviceResponse
' ) { 2099 phpCAS::trace('node_name() failed
'); 2101 $bad_response = TRUE; 2105 if ( !$bad_response ) { 2106 // look for a proxySuccess tag 2107 if ( sizeof($arr = $root->get_elements_by_tagname("proxySuccess")) != 0) { 2108 // authentication succeded, look for a proxyTicket tag 2109 if ( sizeof($arr = $root->get_elements_by_tagname("proxyTicket")) != 0) { 2110 $err_code = PHPCAS_SERVICE_OK; 2112 phpCAS::trace('original PT:
'.trim($arr[0]->get_content())); 2113 $pt = trim($arr[0]->get_content()); 2114 phpCAS::traceEnd($pt); 2117 phpCAS::trace('<proxySuccess> was found, but not <proxyTicket>
'); 2120 // look for a proxyFailure tag 2121 else if ( sizeof($arr = $root->get_elements_by_tagname("proxyFailure")) != 0) { 2122 // authentication failed, extract the error 2123 $err_code = PHPCAS_SERVICE_PT_FAILURE; 2124 $err_msg = 'PT retrieving failed (code=`
' 2125 .$arr[0]->get_attribute('code
') 2127 .trim($arr[0]->get_content())
2129 phpCAS::traceEnd(FALSE); 2132 phpCAS::trace('neither <proxySuccess> nor <proxyFailure> found
'); 2136 // at this step, we are sure that the response of the CAS server was ill-formed 2137 $err_code = PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE; 2138 $err_msg = 'Invalid response from the CAS server (response=`
'.$cas_response.'\
')';
2163 function readURL($url,$cookies,&$headers,&$body,&$err_msg)
2173 $ch = curl_init($url);
2175 if (version_compare(PHP_VERSION,
'5.1.3',
'>=')) {
2177 curl_setopt_array($ch, $this->_curl_options);
2179 foreach ($this->_curl_options as $key => $value) {
2180 curl_setopt($ch, $key, $value);
2184 if ($this->_cas_server_cert ==
'' && $this->_cas_server_ca_cert ==
'' && !$this->_no_cas_server_validation) {
2185 phpCAS::error(
'one of the methods phpCAS::setCasServerCert(), phpCAS::setCasServerCACert() or phpCAS::setNoCasServerValidation() must be called.');
2187 if ($this->_cas_server_cert !=
'' && $this->_cas_server_ca_cert !=
'') {
2189 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
2190 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
2191 curl_setopt($ch, CURLOPT_SSLCERT, $this->_cas_server_cert);
2192 curl_setopt($ch, CURLOPT_CAINFO, $this->_cas_server_ca_cert);
2193 curl_setopt($ch, CURLOPT_VERBOSE,
'1');
2194 phpCAS::trace(
'CURL: Set all required opts for mutual authentication ------');
2195 }
else if ($this->_cas_server_cert !=
'' ) {
2196 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
2197 curl_setopt($ch, CURLOPT_SSLCERT, $this->_cas_server_cert);
2198 }
else if ($this->_cas_server_ca_cert !=
'') {
2199 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
2200 curl_setopt($ch, CURLOPT_CAINFO, $this->_cas_server_ca_cert);
2202 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
2203 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
2207 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
2209 $this->_curl_headers = array();
2210 curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this,
'_curl_read_headers'));
2212 if ( is_array($cookies) ) {
2213 curl_setopt($ch,CURLOPT_COOKIE,implode(
';',$cookies));
2216 if ($this->
hasSA()) {
2217 $more_headers = array (
"soapaction: http://www.oasis-open.org/committees/security",
2218 "cache-control: no-cache",
2221 "connection: keep-alive",
2222 "content-type: text/xml");
2224 curl_setopt($ch, CURLOPT_HTTPHEADER, $more_headers);
2225 curl_setopt($ch, CURLOPT_POST, 1);
2228 curl_setopt($ch, CURLOPT_POSTFIELDS,
$data);
2231 $buf = curl_exec ($ch);
2233 if ( $buf === FALSE ) {
2235 $err_msg =
'CURL error #'.curl_errno($ch).
': '.curl_error($ch);
2264 $sa = $this->
getSA();
2267 $body=
SAML_SOAP_ENV.SAML_SOAP_BODY.SAMLP_REQUEST.SAML_ASSERTION_ARTIFACT.$sa.SAML_ASSERTION_ARTIFACT_CLOSE.SAMLP_REQUEST_CLOSE.SAML_SOAP_BODY_CLOSE.SAML_SOAP_ENV_CLOSE;
2279 $this->_curl_headers[] = $header;
2280 return strlen($header);
2303 $pt = $this->
retrievePT($url,$err_code,$output);
2314 if ( isset(
$_SESSION[
'phpCAS'][
'services'][$url][
'cookies']) &&
2315 is_array(
$_SESSION[
'phpCAS'][
'services'][$url][
'cookies']) ) {
2316 foreach (
$_SESSION[
'phpCAS'][
'services'][$url][
'cookies'] as $name => $val ) {
2317 $cookies[] = $name.
'='.$val;
2322 if ( strstr($url,
'?') === FALSE ) {
2323 $service_url = $url.
'?ticket='.$pt;
2325 $service_url = $url.
'&ticket='.$pt;
2329 if ( !$this->
readURL($service_url,$cookies,$headers,$output,$err_msg) ) {
2331 $err_code = PHPCAS_SERVICE_NOT_AVAILABLE;
2339 phpCAS::trace(
'URL`'.$service_url.
'\' has been read, storing cookies:
'); 2340 foreach ( $headers as $header ) { 2341 // test if the header is a cookie 2342 if ( preg_match('/^Set-Cookie:/
',$header) ) { 2343 // the header is a cookie, remove the beginning 2344 $header_val = preg_replace('/^Set-Cookie: */
','',$header); 2345 // extract interesting information 2346 $name_val = strtok($header_val,';
'); 2347 // extract the name and the value of the cookie 2348 $cookie_name = strtok($name_val,'=
'); 2349 $cookie_val = strtok('=
'); 2351 $_SESSION['phpCAS']['services
'][$url]['cookies
'][$cookie_name] = $cookie_val; 2352 phpCAS::trace($cookie_name.' ->
'.$cookie_val); 2358 phpCAS::traceEnd($res); 2381 function serviceMail($url,$service,$flags,&$err_code,&$err_msg,&$pt) 2383 phpCAS::traceBegin(); 2384 // at first retrieve a PT 2385 $pt = $this->retrievePT($service,$err_code,$output); 2389 // test if PT was retrieved correctly 2391 // note: $err_code and $err_msg are filled by CASClient::retrievePT() 2392 phpCAS::trace('PT was not retrieved correctly
'); 2394 phpCAS::trace('opening IMAP URL `
'.$url.'\
'...');
2395 $stream = @imap_open($url,$this->
getUser(),$pt,$flags);
2398 $err_code = PHPCAS_SERVICE_NOT_AVAILABLE;
2402 var_export(imap_errors(),TRUE));
2457 { $this->_pt = $pt; }
2465 {
return !empty($this->_pt); }
2472 {
return 'ST'.substr($this->_sa, 2); }
2480 { $this->_sa = $sa; }
2488 {
return !empty($this->_sa); }
2506 function validatePT(&$validate_url,&$text_response,&$tree_response)
2518 if ( !$this->
readURL($validate_url,
'',$headers,$text_response,$err_msg) ) {
2519 phpCAS::trace(
'could not open URL \''.$validate_url.
'\' to validate (
'.$err_msg.')
'); 2520 $this->authError('PT not validated
', 2522 TRUE/*$no_response*/); 2525 // read the response of the CAS server into a DOM object 2526 if ( !($dom = domxml_open_mem($text_response))) { 2528 $this->authError('PT not validated
', 2530 FALSE/*$no_response*/, 2531 TRUE/*$bad_response*/, 2534 // read the root node of the XML tree 2535 if ( !($tree_response = $dom->document_element()) ) { 2537 $this->authError('PT not validated
', 2539 FALSE/*$no_response*/, 2540 TRUE/*$bad_response*/, 2543 // insure that tag name is 'serviceResponse
' 2544 if ( $tree_response->node_name() != 'serviceResponse
' ) { 2546 $this->authError('PT not validated
', 2548 FALSE/*$no_response*/, 2549 TRUE/*$bad_response*/, 2552 if ( sizeof($arr = $tree_response->get_elements_by_tagname("authenticationSuccess")) != 0) { 2553 // authentication succeded, extract the user name 2554 if ( sizeof($arr = $tree_response->get_elements_by_tagname("user")) == 0) { 2555 // no user specified => error 2556 $this->authError('PT not validated
', 2558 FALSE/*$no_response*/, 2559 TRUE/*$bad_response*/, 2562 $this->setUser(trim($arr[0]->get_content())); 2564 } else if ( sizeof($arr = $tree_response->get_elements_by_tagname("authenticationFailure")) != 0) { 2565 // authentication succeded, extract the error code and message 2566 $this->authError('PT not validated
', 2568 FALSE/*$no_response*/, 2569 FALSE/*$bad_response*/, 2571 $arr[0]->get_attribute('code
')/*$err_code*/, 2572 trim($arr[0]->get_content())/*$err_msg*/); 2574 $this->authError('PT not validated
', 2576 FALSE/*$no_response*/, 2577 TRUE/*$bad_response*/, 2581 $this->renameSession($this->getPT()); 2582 // at this step, PT has been validated and $this->_user has been set, 2584 phpCAS::traceEnd(TRUE); 2590 // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 2594 // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 2601 // ######################################################################## 2603 // ######################################################################## 2623 phpCAS::traceBegin(); 2624 // the URL is built when needed only 2625 if ( empty($this->_url) ) { 2627 // remove the ticket if present in the URL 2628 $final_uri = ($this->isHttps()) ? 'https
' : 'http
'; 2633 if(empty($_SERVER[
'HTTP_X_FORWARDED_SERVER'])){
2637 if (empty($_SERVER[
'SERVER_NAME'])) {
2638 $server_name = $_SERVER[
'HTTP_HOST'];
2640 $server_name = $_SERVER[
'SERVER_NAME'];
2643 $server_name = $_SERVER[
'HTTP_X_FORWARDED_SERVER'];
2645 $final_uri .= $server_name;
2646 if (!strpos($server_name,
':')) {
2647 if ( ($this->
isHttps() && $_SERVER[
'SERVER_PORT']!=443)
2648 || (!$this->
isHttps() && $_SERVER[
'SERVER_PORT']!=80) ) {
2650 $final_uri .= $_SERVER[
'SERVER_PORT'];
2654 $request_uri = explode(
'?', $_SERVER[
'REQUEST_URI'], 2);
2655 $final_uri .= $request_uri[0];
2657 if (isset($request_uri[1]) && $request_uri[1])
2662 if ($query_string !==
'')
2663 $final_uri .=
"?$query_string";
2668 $this->
setURL($final_uri);
2687 $parameterName = preg_quote($parameterName);
2688 return preg_replace(
"/&$parameterName(=[^&]*)?|^$parameterName(=[^&]*)?&?/",
'', $queryString);
2722 function authError(
$failure,$cas_url,$no_response,$bad_response=
'',$cas_response=
'',$err_code=
'',$err_msg=
'')
2730 if ( $no_response ) {
2733 if ( $bad_response ) {
2741 if ( empty($err_code) )
2744 phpCAS::trace(
'Reason: ['.$err_code.
'] CAS error: '.$err_msg);
getURL()
This method returns the URL of the current request (without any ticket CGI parameter).
setExtraCurlOption($key, $value)
This method is used to set additional user curl options.
$_user
The Authenticated user.
callback()
This method is called by CASClient::CASClient() when running in callback mode.
hasSA()
This method tells if a SAML Ticket was stored.
domxml_open_mem($str, $mode=DOMXML_LOAD_PARSING, &$error=NULL)
_curl_read_headers($ch, $header)
The PGTStorageDB class is a class for PGT database storage.
$_proxy
A boolean telling if the client is a CAS proxy or not.
hasPT()
This method tells if a Proxy Ticket was stored.
getServerVersion()
This method is used to retrieve the version of the CAS server.
const CAS_VERSION_1_0
CAS version 1.0.
The phpCAS class is a simple container for the phpCAS library.
setSA($sa)
This method stores the SAML Ticket.
removeParameterFromQueryString($parameterName, $queryString)
Removes a parameter from a query string.
setHTMLFooter($footer)
This method set the HTML footer used for all outputs.
setCasServerCACert($cert)
Set the CA certificate of the CAS server.
const SAML_VERSION_1_1
SAML protocol.
CASClient( $server_version, $proxy, $server_hostname, $server_port, $server_uri, $start_session=true)
CASClient constructor.
const SAML_SOAP_ENV
SOAP envelope for SAML POST.
setCallbackURL($url)
This method sets the callback url.
$_callback_mode
each PHP script using phpCAS in proxy mode is its own callback to get the PGT back from the CAS serve...
forceAuthentication()
This method is called to be sure that the user is authenticated.
$_st
the Service Ticket provided in the URL of the request if present (empty otherwise).
getServerProxyValidateURL()
This method is used to retrieve the proxy validating URL of the CAS server.
setPGT($pgt)
This method stores the Proxy Granting Ticket.
setCasServerCert($cert)
Set the certificate of the CAS server.
setAttributes($attributes)
$_callback_url
the URL that should be used for the PGT callback (in fact the URL of the current request without any ...
serviceWeb($url, &$err_code, &$output)
This method is used to access an HTTP[S] service.
setST($st)
This method stores the Service Ticket.
traceEnd($res='')
This method is used to indicate the end of the execution of a function in debug mode.
setStartSession($session)
The PGTStorageFile class is a class for PGT file storage.
getLang()
This method returns the language used by phpCAS.
redirectToCas($gateway=false, $renew=false)
This method is used to redirect the client to the CAS server.
$_cas_server_ca_cert
the certificate of the CAS server CA.
hasPGT()
This method tells if a Proxy Granting Ticket was stored.
setServerLogoutURL($url)
This method sets the logout URL of the CAS server.
static setSessionHandler()
set session handler to db
const PHPCAS_LANG_DEFAULT
phpCAS default language (when phpCAS::setLang() is not used)
const CAS_STR_YOU_WERE_NOT_AUTHENTICATED
getStartSession($session)
$_cas_server_cert
the certificate of the CAS server.
setPGTStorageFile($format='', $path='')
This method is used to tell phpCAS to store the response of the CAS server to PGT requests onto the f...
getServerServiceValidateURL()
This method is used to retrieve the service validating URL of the CAS server.
setUser($user)
This method sets the CAS user's login name.
setNoCasServerValidation()
Set no SSL validation for the CAS server.
loadPGT($pgt_iou)
This method reads a PGT from its Iou and deletes the corresponding storage entry. ...
getServerSamlValidateURL()
This method is used to retrieve the SAML validating URL of the CAS server.
getString($str)
This method returns a string depending on the language.
$_pgt_storage
an instance of a class inheriting of PGTStorage, used to deal with PGT storage.
validateSA($validate_url, &$text_response, &$tree_response)
This method is used to validate a SAML TICKET; halt on failure, and sets $validate_url, $text_reponse and $tree_response on success.
printHTMLHeader($title)
This method prints the header of the HTML output (after filtering).
setServerProxyValidateURL($url)
This method sets the proxyValidate URL of the CAS server.
$_pt
the Proxy Ticket provided in the URL of the request if present (empty otherwise). ...
getCallbackURL()
This method returns the URL that should be used for the PGT callback (in fact the URL of the current ...
$_start_session
A variable to whether phpcas will use its own session handling.
getServerProxyURL()
This method is used to retrieve the proxy URL of the CAS server.
authError($failure, $cas_url, $no_response, $bad_response='', $cas_response='', $err_code='', $err_msg='')
This method is used to print the HTML output when the user was not authenticated. ...
getST()
This method returns the Service Ticket provided in the URL of the request.
$_pgt
the Proxy Grnting Ticket given by the CAS server (empty otherwise).
traceBegin()
This method is used to indicate the start of the execution of a function in debug mode...
setHTMLHeader($header)
This method set the HTML header used for all outputs.
getServerLogoutURL()
This method is used to retrieve the logout URL of the CAS server.
setLang($lang)
This method is used to set the language used by phpCAS.
const CAS_STR_AUTHENTICATION_WANTED
setServerLoginURL($url)
This method sets the login URL of the CAS server.
getVersion()
This method returns the phpCAS version.
getSA()
This method returns the SAML Ticket provided in the URL of the request.
const CAS_STR_SHOULD_HAVE_BEEN_REDIRECTED
$_cache_times_for_auth_recheck
An integer that gives the number of times authentication will be cached before rechecked.
$_no_cas_server_validation
Set to true not to validate the CAS server.
error($msg)
This method is used by interface methods to print an error and where the function was originally call...
getServerLoginURL($gateway=false, $renew=false)
This method is used to retrieve the login URL of the CAS server.
$_curl_options
An array to store extra curl options.
printHTMLFooter()
This method prints the footer of the HTML output (after filtering).
retrievePT($target_service, &$err_code, &$err_msg)
This method is used to retrieve PT's from the CAS server thanks to a PGT.
isSessionAuthenticated()
This method tells if the current session is authenticated.
setSessionAttributes($text_response)
This method will parse the DOM and pull out the attributes from the SAML payload and put them into an...
getPGT()
This method returns the Proxy Granting Ticket given by the CAS server.
readURL($url, $cookies, &$headers, &$body, &$err_msg)
This method is used to acces a remote URL.
$_curl_headers
This method is the callback used by readURL method to request HTTP headers.
$_output_footer
A string used to print the footer of HTML pages.
handleLogoutRequests($check_client=true, $allowed_clients=false)
This method handles logout requests.
getServerHostname()
This method is used to retrieve the hostname of the CAS server.
setPT($pt)
This method stores the Proxy Ticket.
validateST($validate_url, &$text_response, &$tree_response)
This method is used to validate a ST; halt on failure, and sets $validate_url, $text_reponse and $tre...
getPT()
This method returns the Proxy Ticket provided in the URL of the request.
buildSAMLPayload()
This method is used to build the SAML POST body sent to /samlValidate URL.
$_strings
array containing the strings used by phpCAS.
isProxy()
Tells if a CAS client is a CAS proxy or not.
validatePGT(&$validate_url, $text_response, $tree_response)
This method is used to validate a PGT; halt on failure.
trace($str)
This method is used to log something in debug mode.
const CAS_STR_AUTHENTICATION_FAILED
$_output_header
A string used to print the header of HTML pages.
getUser()
This method returns the CAS user's login name.
isAuthenticated()
This method is called to check if the user is authenticated (previously or by tickets given in the UR...
getServerBaseURL()
This method is used to retrieve the base URL of the CAS server.
isHttps()
This method checks to see if the request is secured via HTTPS.
initPGTStorage()
This method is used to initialize the storage of PGT's.
$_lang
A string corresponding to the language used by phpCAS.
setServerServiceValidateURL($url)
This method sets the serviceValidate URL of the CAS server.
setCacheTimesForAuthRecheck($n)
Set the number of times authentication will be cached before rechecked.
log($str)
Logs a string in debug mode.
renameSession($ticket)
Renaming the session.
const SAML_ATTRIBUTES
SAML Attributes.
const CAS_STR_USING_SERVER
a phpCAS string index
renewAuthentication()
This method is called to renew the authentication of the user If the user is authenticated, renew the connection If not, redirect to CAS.
checkAuthentication()
This method is called to check whether the user is authenticated or not.
setURL($url)
This method sets the URL of the current request.
setPGTStorageDB($user, $password, $database_type, $hostname, $port, $database, $table)
This method is used to tell phpCAS to store the response of the CAS server to PGT requests into a dat...
traceExit()
This method is used to indicate the end of the execution of the program.
$_url
the URL of the current request (without any ticket CGI parameter).
hasST()
This method tells if a Service Ticket was stored.
HTMLFilterOutput($str)
This method filters a string by replacing special tokens by appropriate values and prints it...
wasPreviouslyAuthenticated()
This method tells if the user has already been (previously) authenticated by looking into the session...
if(! $in) print Initializing normalization quick check tables n
The CASClient class is a client interface that provides CAS authentication to PHP applications...
validatePT(&$validate_url, &$text_response, &$tree_response)
This method is used to validate a ST or PT; halt on failure Used for all CAS 2.0 validations.
logout($params)
This method is used to logout from CAS.
storePGT($pgt, $pgt_iou)
This method stores a PGT.
$_attributes
The Authenticated users attributes.
const CAS_STR_SERVICE_UNAVAILABLE
setCallbackMode($callback_mode)
This method sets/unsets callback mode.
isCallbackMode()
This method returns TRUE when the CAs client is running i callback mode, FALSE otherwise.
setServerSamlValidateURL($url)
This method sets the samlValidate URL of the CAS server.