00001 <?php
00002 
00008 
00009 include_once(dirname(__FILE__).'/languages/languages.php');
00010 
00011 
00012 include_once(dirname(__FILE__).'/PGTStorage/pgt-main.php');
00013 
00022 class CASClient
00023 {
00024         
00025         
00026         
00027         
00028         
00029         
00030         
00031         
00032         
00033         
00052         function HTMLFilterOutput($str)
00053                 {
00054                 $str = str_replace('__CAS_VERSION__',$this->getServerVersion(),$str);
00055                 $str = str_replace('__PHPCAS_VERSION__',phpCAS::getVersion(),$str);
00056                 $str = str_replace('__SERVER_BASE_URL__',$this->getServerBaseURL(),$str);
00057                 echo $str;
00058                 }
00059         
00068         var $_output_header = '';
00069         
00079         function printHTMLHeader($title)
00080                 {
00081                 $this->HTMLFilterOutput(str_replace('__TITLE__',
00082                         $title,
00083                         (empty($this->_output_header)
00084                                         ? '<html><head><title>__TITLE__</title></head><body><h1>__TITLE__</h1>'
00085                                                         : $this->_output_header)
00086                 )
00087                 );
00088                 }
00089         
00098         var $_output_footer = '';
00099         
00107         function printHTMLFooter()
00108                 {
00109                 $this->HTMLFilterOutput(empty($this->_output_footer)
00110                         ?('<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>')
00111                                         :$this->_output_footer);
00112                 }
00113         
00121         function setHTMLHeader($header)
00122                 {
00123                 $this->_output_header = $header;
00124                 }
00125         
00133         function setHTMLFooter($footer)
00134                 {
00135                 $this->_output_footer = $footer;
00136                 }
00137         
00139         
00140         
00141         
00156         var $_lang = '';
00157         
00165         function getLang()
00166                 {
00167                 if ( empty($this->_lang) )
00168                         $this->setLang(PHPCAS_LANG_DEFAULT);
00169                 return $this->_lang;
00170                 }
00171         
00181         var $_strings;
00182         
00192         function getString($str)
00193                 {
00194                 
00195                 $this->getLang();
00196                 
00197                 if ( !isset($this->_strings[$str]) ) {
00198                         trigger_error('string `'.$str.'\' not defined for language `'.$this->getLang().'\'',E_USER_ERROR);
00199                 }
00200                 return $this->_strings[$str];
00201                 }
00202         
00212         function setLang($lang)
00213                 {
00214                 
00215                 include_once(dirname(__FILE__).'/languages/'.$lang.'.php');
00216                 
00217                 if ( !is_array($this->_strings) ) {
00218                         trigger_error('language `'.$lang.'\' is not implemented',E_USER_ERROR);
00219                 }
00220                 $this->_lang = $lang;
00221                 }
00222         
00224         // ########################################################################
00225         //  CAS SERVER CONFIG
00226         // ########################################################################
00256         var $_server = array(
00257                 'version' => -1,
00258                 'hostname' => 'none',
00259                 'port' => -1,
00260                 'uri' => 'none'
00261         );
00262         
00268         function getServerVersion()
00269                 { 
00270                 return $this->_server['version']; 
00271                 }
00272         
00278         function getServerHostname()
00279                 { return $this->_server['hostname']; }
00280         
00286         function getServerPort()
00287                 { return $this->_server['port']; }
00288         
00294         function getServerURI()
00295                 { return $this->_server['uri']; }
00296         
00302         function getServerBaseURL()
00303                 { 
00304                 // the URL is build only when needed
00305                 if ( empty($this->_server['base_url']) ) {
00306                         $this->_server['base_url'] = 'https:
00307                                 .$this->getServerHostname()
00308                                 .':'
00309                                 .$this->getServerPort()
00310                                 .$this->getServerURI();
00311                 }
00312                 return $this->_server['base_url'];
00313                 }
00314         
00324         function getServerLoginURL($gateway=false,$renew=false) {
00325                 phpCAS::traceBegin();
00326                 
00327                 if ( empty($this->_server['login_url']) ) {
00328                         $this->_server['login_url'] = $this->getServerBaseURL();
00329                         $this->_server['login_url'] .= 'login?service=';
00330                         
00331                         $this->_server['login_url'] .= urlencode($this->getURL());
00332                         if($renew) {
00333                                 
00334                                 $this->_server['login_url'] .= '&renew=true';
00335                         } elseif ($gateway) {
00336                                 
00337                                 $this->_server['login_url'] .= '&gateway=true';
00338                         }
00339                 }
00340                 phpCAS::traceEnd($this->_server['login_url']);
00341                 return $this->_server['login_url'];
00342         } 
00343         
00350         function setServerLoginURL($url)
00351                 {
00352                 return $this->_server['login_url'] = $url;
00353                 }
00354         
00360         function getServerServiceValidateURL()
00361                 { 
00362                 
00363                 if ( empty($this->_server['service_validate_url']) ) {
00364                         switch ($this->getServerVersion()) {
00365                                 case CAS_VERSION_1_0:
00366                                         $this->_server['service_validate_url'] = $this->getServerBaseURL().'validate';
00367                                         break;
00368                                 case CAS_VERSION_2_0:
00369                                         $this->_server['service_validate_url'] = $this->getServerBaseURL().'serviceValidate';
00370                                         break;
00371                         }
00372                 }
00373                 
00374                 return $this->_server['service_validate_url'].'?service='.urlencode($this->getURL());
00375                 }
00376         
00382         function getServerProxyValidateURL()
00383                 { 
00384                 
00385                 if ( empty($this->_server['proxy_validate_url']) ) {
00386                         switch ($this->getServerVersion()) {
00387                                 case CAS_VERSION_1_0:
00388                                         $this->_server['proxy_validate_url'] = '';
00389                                         break;
00390                                 case CAS_VERSION_2_0:
00391                                         $this->_server['proxy_validate_url'] = $this->getServerBaseURL().'proxyValidate';
00392                                         break;
00393                         }
00394                 }
00395                 
00396                 return $this->_server['proxy_validate_url'].'?service='.urlencode($this->getURL());
00397                 }
00398         
00404         function getServerProxyURL()
00405                 { 
00406                 
00407                 if ( empty($this->_server['proxy_url']) ) {
00408                         switch ($this->getServerVersion()) {
00409                                 case CAS_VERSION_1_0:
00410                                         $this->_server['proxy_url'] = '';
00411                                         break;
00412                                 case CAS_VERSION_2_0:
00413                                         $this->_server['proxy_url'] = $this->getServerBaseURL().'proxy';
00414                                         break;
00415                         }
00416                 }
00417                 return $this->_server['proxy_url'];
00418                 }
00419         
00425         function getServerLogoutURL()
00426                 { 
00427                 
00428                 if ( empty($this->_server['logout_url']) ) {
00429                         $this->_server['logout_url'] = $this->getServerBaseURL().'logout';
00430                 }
00431                 return $this->_server['logout_url'];
00432                 }
00433         
00440         function setServerLogoutURL($url)
00441                 {
00442                 return $this->_server['logout_url'] = $url;
00443                 }
00444 
00448         var $_curl_options = array();
00449 
00453         function setExtraCurlOption($key, $value)
00454         {
00455                 $this->_curl_options[$key] = $value;
00456         }
00457  
00463         function isHttps() {
00464                 
00465                 
00466                 if ( isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
00467                         return true;
00468                 } else {
00469                         return false;
00470                 }
00471         }
00472         
00473         
00474         
00475         
00490         function CASClient(
00491                                            $server_version,
00492                                            $proxy,
00493                                            $server_hostname,
00494                                            $server_port,
00495                                            $server_uri,
00496                                            $start_session = true) {
00497                 
00498                 phpCAS::traceBegin();
00499                 
00500                 if (!$this->isLogoutRequest() && !empty($_GET['ticket']) && $start_session) {
00501             
00502             if (!isset($_SESSION)) {
00503                 session_start();
00504             }
00505             $old_session = $_SESSION;
00506             session_destroy();
00507             
00508                         $session_id = preg_replace('/[^\w]/','',$_GET['ticket']);
00509                         phpCAS::LOG("Session ID: " . $session_id);
00510                         session_id($session_id);
00511             if (!isset($_SESSION)) {
00512                 session_start();
00513             }
00514             
00515             $_SESSION = $old_session;
00516             
00517             header('Location: '.$this->getURL());
00518                 }
00519                 
00520                 
00521                 if (!$this->isLogoutRequest() && $start_session) {
00522                         session_start();
00523                 }
00524                 
00525                 $this->_proxy = $proxy;
00526                 
00527                 
00528                 switch ($server_version) {
00529                         case CAS_VERSION_1_0:
00530                                 if ( $this->isProxy() )
00531                                         phpCAS::error('CAS proxies are not supported in CAS '
00532                                                 .$server_version);
00533                                 break;
00534                         case CAS_VERSION_2_0:
00535                                 break;
00536                         default:
00537                                 phpCAS::error('this version of CAS (`'
00538                                         .$server_version
00539                                         .'\') is not supported by phpCAS '
00540                                         .phpCAS::getVersion());
00541                 }
00542                 $this->_server['version'] = $server_version;
00543                 
00544                 //check hostname
00545                 if ( empty($server_hostname) 
00546                                 || !preg_match('/[\.\d\-abcdefghijklmnopqrstuvwxyz]*/',$server_hostname) ) {
00547                         phpCAS::error('bad CAS server hostname (`'.$server_hostname.'\')');
00548                 }
00549                 $this->_server['hostname'] = $server_hostname;
00550                 
00551                 
00552                 if ( $server_port == 0 
00553                         || !is_int($server_port) ) {
00554                         phpCAS::error('bad CAS server port (`'.$server_hostname.'\')');
00555                 }
00556                 $this->_server['port'] = $server_port;
00557                 
00558                 //check URI
00559                 if ( !preg_match('/[\.\d\-_abcdefghijklmnopqrstuvwxyz\/]*/',$server_uri) ) {
00560                         phpCAS::error('bad CAS server URI (`'.$server_uri.'\')');
00561                 }
00562                 
00563                 $server_uri = preg_replace('/\/\//','/','/'.$server_uri.'/');
00564                 $this->_server['uri'] = $server_uri;
00565                 
00566                 
00567                 if ( $this->isProxy() ) {
00568                         $this->setCallbackMode(!empty($_GET['pgtIou'])&&!empty($_GET['pgtId']));
00569                 }
00570                 
00571                 if ( $this->isCallbackMode() ) {
00572                         
00573                         if ( !$this->isHttps() ) {
00574                                 phpCAS::error('CAS proxies must be secured to use phpCAS; PGT\'s will not be received from the CAS server');
00575                         }
00576                 } else {
00577                         
00578                         $ticket = (isset($_GET['ticket']) ? $_GET['ticket'] : null);
00579                         switch ($this->getServerVersion()) {
00580                                 case CAS_VERSION_1_0: 
00581                                         if( preg_match('/^ST-/',$ticket) ) {
00582                                                 phpCAS::trace('ST \''.$ticket.'\' found');
00583                                                 //ST present
00584                                                 $this->setST($ticket);
00585                                                 //ticket has been taken into account, unset it to hide it to applications
00586                                                 unset($_GET['ticket']);
00587                                         } else if ( !empty($ticket) ) {
00588                                                 //ill-formed ticket, halt
00589                                                 phpCAS::error('ill-formed ticket found in the URL (ticket=`'.htmlentities($ticket).'\')');
00590                                         }
00591                                         break;
00592                                 case CAS_VERSION_2_0: 
00593                                         if( preg_match('/^[SP]T-/',$ticket) ) {
00594                                                 phpCAS::trace('ST or PT \''.$ticket.'\' found');
00595                                                 $this->setPT($ticket);
00596                                                 unset($_GET['ticket']);
00597                                         } else if ( !empty($ticket) ) {
00598                                                 //ill-formed ticket, halt
00599                                                 phpCAS::error('ill-formed ticket found in the URL (ticket=`'.htmlentities($ticket).'\')');
00600                                         } 
00601                                         break;
00602                         }
00603                 }
00604                 phpCAS::traceEnd();
00605         }
00606         
00609         
00610         
00611         
00612         
00613         
00614         
00627         var $_user = '';
00628         
00636         function setUser($user)
00637                 {
00638                 $this->_user = $user;
00639                 }
00640         
00648         function getUser()
00649                 {
00650                 if ( empty($this->_user) ) {
00651                         phpCAS::error('this method should be used only after '.__CLASS__.'::forceAuthentication() or '.__CLASS__.'::isAuthenticated()');
00652                 }
00653                 return $this->_user;
00654                 }
00655         
00662         function renewAuthentication(){
00663                 phpCAS::traceBegin();
00664                 
00665                 if( isset( $_SESSION['phpCAS']['auth_checked'] ) )
00666                         unset($_SESSION['phpCAS']['auth_checked']);
00667                 if ( $this->isAuthenticated() ) {
00668                         phpCAS::trace('user already authenticated; renew');
00669                         $this->redirectToCas(false,true);
00670                 } else {
00671                         $this->redirectToCas();
00672                 }
00673                 phpCAS::traceEnd();
00674         }
00675 
00682         function forceAuthentication()
00683                 {
00684                 phpCAS::traceBegin();
00685                 
00686                 if ( $this->isAuthenticated() ) {
00687                         
00688                         phpCAS::trace('no need to authenticate');
00689                         $res = TRUE;
00690                 } else {
00691                         
00692                         if (isset($_SESSION['phpCAS']['auth_checked'])) {
00693                                 unset($_SESSION['phpCAS']['auth_checked']);
00694                         }
00695                         $this->redirectToCas(FALSE);
00696                         
00697                         $res = FALSE;
00698                 }
00699                 phpCAS::traceEnd($res);
00700                 return $res;
00701                 }
00702         
00709         var $_cache_times_for_auth_recheck = 0;
00710         
00718         function setCacheTimesForAuthRecheck($n)
00719                 {
00720                 $this->_cache_times_for_auth_recheck = $n;
00721                 }
00722         
00728         function checkAuthentication()
00729                 {
00730                 phpCAS::traceBegin();
00731                 
00732                 if ( $this->isAuthenticated() ) {
00733                         phpCAS::trace('user is authenticated');
00734                         $res = TRUE;
00735                 } else if (isset($_SESSION['phpCAS']['auth_checked'])) {
00736                         
00737                         unset($_SESSION['phpCAS']['auth_checked']);
00738                         $res = FALSE;
00739                 } else {
00740                         
00741                         
00742                         
00743                         
00744                         
00745                         if (! isset($_SESSION['phpCAS']['unauth_count']) )
00746                                 $_SESSION['phpCAS']['unauth_count'] = -2; 
00747                         
00748                         if (($_SESSION['phpCAS']['unauth_count'] != -2 && $this->_cache_times_for_auth_recheck == -1)
00749                                         || ($_SESSION['phpCAS']['unauth_count'] >= 0 && $_SESSION['phpCAS']['unauth_count'] < $this->_cache_times_for_auth_recheck))
00750                         {
00751                                 $res = FALSE;
00752                                 
00753                                 if ($this->_cache_times_for_auth_recheck != -1)
00754                                 {
00755                                         $_SESSION['phpCAS']['unauth_count']++;
00756                                         phpCAS::trace('user is not authenticated (cached for '.$_SESSION['phpCAS']['unauth_count'].' times of '.$this->_cache_times_for_auth_recheck.')');
00757                                 }
00758                                 else
00759                                 {
00760                                         phpCAS::trace('user is not authenticated (cached for until login pressed)');
00761                                 }
00762                         }
00763                         else
00764                         {
00765                                 $_SESSION['phpCAS']['unauth_count'] = 0;
00766                                 $_SESSION['phpCAS']['auth_checked'] = true;
00767                                 phpCAS::trace('user is not authenticated (cache reset)');
00768                                 $this->redirectToCas(TRUE);
00769                                 
00770                                 $res = FALSE;
00771                         }
00772                 }
00773                 phpCAS::traceEnd($res);
00774                 return $res;
00775                 }
00776         
00785         function isAuthenticated()
00786                 {
00787                 phpCAS::traceBegin();
00788                 $res = FALSE;
00789                 $validate_url = '';
00790                 
00791                 if ( $this->wasPreviouslyAuthenticated() ) {
00792                         
00793                         
00794                         phpCAS::trace('user was already authenticated, no need to look for tickets');
00795                         $res = TRUE;
00796                 } 
00797                 elseif ( $this->hasST() ) {
00798                         
00799                         phpCAS::trace('ST `'.$this->getST().'\' is present');
00800                         $this->validateST($validate_url,$text_response,$tree_response); // if it fails, it halts
00801                         phpCAS::trace('ST `'.$this->getST().'\' was validated');
00802                         if ( $this->isProxy() ) {
00803                                 $this->validatePGT($validate_url,$text_response,$tree_response); 
00804                                 phpCAS::trace('PGT `'.$this->getPGT().'\' was validated');
00805                                 $_SESSION['phpCAS']['pgt'] = $this->getPGT();
00806                         }
00807                         $_SESSION['phpCAS']['user'] = $this->getUser();
00808                         $res = TRUE;
00809                 }
00810                 elseif ( $this->hasPT() ) {
00811                         // if a Proxy Ticket was given, validate it
00812                         phpCAS::trace('PT `'.$this->getPT().'\' is present');
00813                         $this->validatePT($validate_url,$text_response,$tree_response); 
00814                         phpCAS::trace('PT `'.$this->getPT().'\' was validated');
00815                         if ( $this->isProxy() ) {
00816                                 $this->validatePGT($validate_url,$text_response,$tree_response); // idem
00817                                 phpCAS::trace('PGT `'.$this->getPGT().'\' was validated');
00818                                 $_SESSION['phpCAS']['pgt'] = $this->getPGT();
00819                         }
00820                         $_SESSION['phpCAS']['user'] = $this->getUser();
00821                         $res = TRUE;
00822                 } 
00823                 else {
00824                         
00825                         phpCAS::trace('no ticket found');
00826                 }
00827                 
00828                 phpCAS::traceEnd($res);
00829                 return $res;
00830                 }
00831         
00837         function isSessionAuthenticated ()
00838                 {
00839                 return !empty($_SESSION['phpCAS']['user']);
00840                 }
00841         
00852         function wasPreviouslyAuthenticated()
00853                 {
00854                 phpCAS::traceBegin();
00855                 
00856                 if ( $this->isCallbackMode() ) {
00857                         $this->callback();
00858                 }
00859                 
00860                 $auth = FALSE;
00861                 
00862                 if ( $this->isProxy() ) {
00863                         
00864                         if ( $this->isSessionAuthenticated() && !empty($_SESSION['phpCAS']['pgt']) ) {
00865                                 
00866                                 $this->setUser($_SESSION['phpCAS']['user']);
00867                                 $this->setPGT($_SESSION['phpCAS']['pgt']);
00868                                 phpCAS::trace('user = `'.$_SESSION['phpCAS']['user'].'\', PGT = `'.$_SESSION['phpCAS']['pgt'].'\'');
00869                                 $auth = TRUE;
00870                         } elseif ( $this->isSessionAuthenticated() && empty($_SESSION['phpCAS']['pgt']) ) {
00871                                 
00872                                 phpCAS::trace('username found (`'.$_SESSION['phpCAS']['user'].'\') but PGT is empty');
00873                                 // unset all tickets to enforce authentication
00874                                 unset($_SESSION['phpCAS']);
00875                                 $this->setST('');
00876                                 $this->setPT('');
00877                         } elseif ( !$this->isSessionAuthenticated() && !empty($_SESSION['phpCAS']['pgt']) ) {
00878                                 // these two variables should be empty or not empty at the same time
00879                                 phpCAS::trace('PGT found (`'.$_SESSION['phpCAS']['pgt'].'\') but username is empty');
00880                                 
00881                                 unset($_SESSION['phpCAS']);
00882                                 $this->setST('');
00883                                 $this->setPT('');
00884                         } else {
00885                                 phpCAS::trace('neither user not PGT found');
00886                         }
00887                 } else {
00888                         
00889                         if ( $this->isSessionAuthenticated() ) {
00890                                 
00891                                 $this->setUser($_SESSION['phpCAS']['user']);
00892                                 phpCAS::trace('user = `'.$_SESSION['phpCAS']['user'].'\'');
00893                                 $auth = TRUE;
00894                         } else {
00895                                 phpCAS::trace('no user found');
00896                         }
00897                 }
00898                 
00899                 phpCAS::traceEnd($auth);
00900                 return $auth;
00901                 }
00902         
00910         function redirectToCas($gateway=false,$renew=false){
00911                 phpCAS::traceBegin();
00912                 $cas_url = $this->getServerLoginURL($gateway,$renew);
00913                 header('Location: '.$cas_url);
00914                 phpCAS::log( "Redirect to : ".$cas_url );
00915                 
00916                 $this->printHTMLHeader($this->getString(CAS_STR_AUTHENTICATION_WANTED));
00917                 
00918                 printf('<p>'.$this->getString(CAS_STR_SHOULD_HAVE_BEEN_REDIRECTED).'</p>',$cas_url);
00919                 $this->printHTMLFooter();
00920                 phpCAS::traceExit();
00921                 exit();
00922         }
00923 
00924 
00925 
00926 
00927 
00928 
00929 
00930 
00931 
00932 
00933 
00934 
00935 
00936 
00937 
00938 
00939 
00940 
00941 
00942 
00943 
00944 
00945 
00946 
00947         
00953         function logout($params) {
00954                 phpCAS::traceBegin();
00955                 $cas_url = $this->getServerLogoutURL();
00956                 $paramSeparator = '?';
00957                 if (isset($params['url'])) {
00958                         $cas_url = $cas_url . $paramSeparator . "url=" . urlencode($params['url']);
00959                         $paramSeparator = '&';
00960                 }
00961                 if (isset($params['service'])) {
00962                         $cas_url = $cas_url . $paramSeparator . "service=" . urlencode($params['service']);
00963                 }
00964                 header('Location: '.$cas_url);
00965                 session_unset();
00966                 session_destroy();
00967                 $this->printHTMLHeader($this->getString(CAS_STR_LOGOUT));
00968                 printf('<p>'.$this->getString(CAS_STR_SHOULD_HAVE_BEEN_REDIRECTED).'</p>',$cas_url);
00969                 $this->printHTMLFooter();
00970                 phpCAS::traceExit();
00971                 exit();
00972         }
00973         
00978         function isLogoutRequest() {
00979                 return !empty($_POST['logoutRequest']);
00980         }
00981         
00986         function isLogoutRequestAllowed() {
00987         }
00988         
00997         function handleLogoutRequests($check_client=true, $allowed_clients=false) {
00998                 phpCAS::traceBegin();
00999                 if (!$this->isLogoutRequest()) {
01000                         phpCAS::log("Not a logout request");
01001                         phpCAS::traceEnd();
01002                         return;
01003                 }
01004                 phpCAS::log("Logout requested");
01005                 phpCAS::log("SAML REQUEST: ".$_POST['logoutRequest']);
01006                 if ($check_client) {
01007                         if (!$allowed_clients) {
01008                                 $allowed_clients = array( $this->getServerHostname() );
01009                         }
01010                         $client_ip = $_SERVER['REMOTE_ADDR'];
01011                         $client = gethostbyaddr($client_ip);
01012                         phpCAS::log("Client: ".$client);
01013                         $allowed = false;
01014                         foreach ($allowed_clients as $allowed_client) {
01015                                 if ($client == $allowed_client) {
01016                                         phpCAS::log("Allowed client '".$allowed_client."' matches, logout request is allowed");
01017                                         $allowed = true;
01018                                         break;
01019                                 } else {
01020                                         phpCAS::log("Allowed client '".$allowed_client."' does not match");
01021                                 }
01022                         }
01023                         if (!$allowed) {
01024                                 phpCAS::error("Unauthorized logout request from client '".$client."'");
01025                             printf("Unauthorized!");
01026                                 phpCAS::traceExit();
01027                                 exit();
01028                         }
01029                 } else {
01030                         phpCAS::log("No access control set");
01031                 }
01032                 
01033                 preg_match("|<samlp:SessionIndex>(.*)</samlp:SessionIndex>|", $_POST['logoutRequest'], $tick, PREG_OFFSET_CAPTURE, 3);
01034                 $wrappedSamlSessionIndex = preg_replace('|<samlp:SessionIndex>|','',$tick[0][0]);
01035                 $ticket2logout = preg_replace('|</samlp:SessionIndex>|','',$wrappedSamlSessionIndex);
01036                 phpCAS::log("Ticket to logout: ".$ticket2logout);
01037                 $session_id = preg_replace('/[^\w]/','',$ticket2logout);
01038                 phpCAS::log("Session id: ".$session_id);
01039 
01040                 
01041                 session_id($session_id);
01042                 $_COOKIE[session_name()]=$session_id;
01043                 $_GET[session_name()]=$session_id;
01044                 
01045                 
01046                 session_start();        
01047                 session_unset();
01048             session_destroy();
01049             printf("Disconnected!");
01050                 phpCAS::traceExit();
01051                 exit();
01052         }
01053         
01056         
01057         
01058         
01059         
01060         
01061         
01062         
01063         
01064         
01078         var $_st = '';
01079         
01085         function getST()
01086                 { return $this->_st; }
01087         
01093         function setST($st)
01094                 { $this->_st = $st; }
01095         
01101         function hasST()
01102                 { return !empty($this->_st); }
01103         
01106         
01107         
01108         
01120         var $_cas_server_cert = '';
01121         
01128         var $_cas_server_ca_cert = '';
01129         
01136         var $_no_cas_server_validation = false;
01137         
01143         function setCasServerCert($cert)
01144                 {
01145                 $this->_cas_server_cert = $cert;
01146                 }
01147         
01153         function setCasServerCACert($cert)
01154                 {
01155                 $this->_cas_server_ca_cert = $cert;
01156                 }
01157         
01161         function setNoCasServerValidation()
01162                 {
01163                 $this->_no_cas_server_validation = true;
01164                 }
01165         
01179         function validateST($validate_url,&$text_response,&$tree_response)
01180                 {
01181                 phpCAS::traceBegin();
01182                 
01183                 $validate_url = $this->getServerServiceValidateURL().'&ticket='.$this->getST();
01184                 if ( $this->isProxy() ) {
01185                         
01186                         $validate_url .= '&pgtUrl='.$this->getCallbackURL();
01187                 }
01188                 
01189                 
01190                 if ( !$this->readURL($validate_url,'',$headers,$text_response,$err_msg) ) {
01191                         phpCAS::trace('could not open URL \''.$validate_url.'\' to validate ('.$err_msg.')');
01192                         $this->authError('ST not validated',
01193                                 $validate_url,
01194                                 TRUE/*$no_response*/);
01195                 }
01196                 
01197                 // analyze the result depending on the version
01198                 switch ($this->getServerVersion()) {
01199                         case CAS_VERSION_1_0:
01200                                 if (preg_match('/^no\n/',$text_response)) {
01201                                         phpCAS::trace('ST has not been validated');
01202                                         $this->authError('ST not validated',
01203                                                 $validate_url,
01204                                                 FALSE/*$no_response*/,
01205                                                 FALSE/*$bad_response*/,
01206                                                 $text_response);
01207                                 }
01208                                 if (!preg_match('/^yes\n/',$text_response)) {
01209                                         phpCAS::trace('ill-formed response');
01210                                         $this->authError('ST not validated',
01211                                                 $validate_url,
01212                                                 FALSE/*$no_response*/,
01213                                                 TRUE/*$bad_response*/,
01214                                                 $text_response);
01215                                 }
01216                                 // ST has been validated, extract the user name
01217                                 $arr = preg_split('/\n/',$text_response);
01218                                 $this->setUser(trim($arr[1]));
01219                                 break;
01220                         case CAS_VERSION_2_0:
01221                                 // read the response of the CAS server into a DOM object
01222                                 if ( !($dom = domxml_open_mem($text_response))) {
01223                                         phpCAS::trace('domxml_open_mem() failed');
01224                                         $this->authError('ST not validated',
01225                                                 $validate_url,
01226                                                 FALSE/*$no_response*/,
01227                                                 TRUE/*$bad_response*/,
01228                                                 $text_response);
01229                                 }
01230                                 // read the root node of the XML tree
01231                                 if ( !($tree_response = $dom->document_element()) ) {
01232                                         phpCAS::trace('document_element() failed');
01233                                         $this->authError('ST not validated',
01234                                                 $validate_url,
01235                                                 FALSE/*$no_response*/,
01236                                                 TRUE/*$bad_response*/,
01237                                                 $text_response);
01238                                 }
01239                                 // insure that tag name is 'serviceResponse'
01240                                 if ( $tree_response->node_name() != 'serviceResponse' ) {
01241                                         phpCAS::trace('bad XML root node (should be `serviceResponse\' instead of `'.$tree_response->node_name().'\'');
01242                                         $this->authError('ST not validated',
01243                                                 $validate_url,
01244                                                 FALSE,
01245                                                 TRUE,
01246                                                 $text_response);
01247                                 }
01248                                 if ( sizeof($success_elements = $tree_response->get_elements_by_tagname("authenticationSuccess")) != 0) {
01249                                         
01250                                         if ( sizeof($user_elements = $success_elements[0]->get_elements_by_tagname("user")) == 0) {
01251                                                 phpCAS::trace('<authenticationSuccess> found, but no <user>');
01252                                                 $this->authError('ST not validated',
01253                                                         $validate_url,
01254                                                         FALSE,
01255                                                         TRUE,
01256                                                         $text_response);
01257                                         }
01258                                         $user = trim($user_elements[0]->get_content());
01259                                         phpCAS::trace('user = `'.$user);
01260                                         $this->setUser($user);
01261                                         
01262                                 } else if ( sizeof($failure_elements = $tree_response->get_elements_by_tagname("authenticationFailure")) != 0) {
01263                                         phpCAS::trace('<authenticationFailure> found');
01264                                         
01265                                         $this->authError('ST not validated',
01266                                                 $validate_url,
01267                                                 FALSE,
01268                                                 FALSE,
01269                                                 $text_response,
01270                                                 $failure_elements[0]->get_attribute('code'),
01271                                                 trim($failure_elements[0]->get_content()));
01272                                 } else {
01273                                         phpCAS::trace('neither <authenticationSuccess> nor <authenticationFailure> found');
01274                                         $this->authError('ST not validated',
01275                                                 $validate_url,
01276                                                 FALSE,
01277                                                 TRUE,
01278                                                 $text_response);
01279                                 }
01280                                 break;
01281                 }
01282                 
01283                 
01284                 phpCAS::traceEnd(TRUE);
01285                 return TRUE;
01286                 }
01287         
01290         
01291         
01292         
01293         
01294         
01295         
01296         
01297         
01298         
01310         var $_proxy;
01311         
01319         function isProxy()
01320                 {
01321                 return $this->_proxy;
01322                 }
01323         
01325         
01326         
01327         
01340         var $_pgt = '';
01341         
01347         function getPGT()
01348                 { return $this->_pgt; }
01349         
01355         function setPGT($pgt)
01356                 { $this->_pgt = $pgt; }
01357         
01363         function hasPGT()
01364                 { return !empty($this->_pgt); }
01365         
01368         
01369         
01370         
01388         var $_callback_mode = FALSE;
01389         
01397         function setCallbackMode($callback_mode)
01398                 {
01399                 $this->_callback_mode = $callback_mode;
01400                 }
01401         
01410         function isCallbackMode()
01411                 {
01412                 return $this->_callback_mode;
01413                 }
01414         
01423         var $_callback_url = '';
01424         
01434         function getCallbackURL()
01435                 {
01436                 
01437                 if ( empty($this->_callback_url) ) {
01438                         $final_uri = '';
01439                         
01440                         $final_uri = 'https://';
01441                         
01442 
01443 
01444                         if(empty($_SERVER['HTTP_X_FORWARDED_SERVER'])){
01445                                 
01446 
01447 
01448                                 if (empty($_SERVER['SERVER_NAME'])) {
01449                                         $final_uri .= $_SERVER['HTTP_HOST'];
01450                                 } else {
01451                                         $final_uri .= $_SERVER['SERVER_NAME'];
01452                                 }
01453                         } else {
01454                                 $final_uri .= $_SERVER['HTTP_X_FORWARDED_SERVER'];
01455                         }
01456                         if ( ($this->isHttps() && $_SERVER['SERVER_PORT']!=443)
01457                                         || (!$this->isHttps() && $_SERVER['SERVER_PORT']!=80) ) {
01458                                 $final_uri .= ':';
01459                                 $final_uri .= $_SERVER['SERVER_PORT'];
01460                         }
01461                         $request_uri = $_SERVER['REQUEST_URI'];
01462                         $request_uri = preg_replace('/\?.*$/','',$request_uri);
01463                         $final_uri .= $request_uri;
01464                         $this->setCallbackURL($final_uri);
01465                 }
01466                 return $this->_callback_url;
01467                 }
01468         
01476         function setCallbackURL($url)
01477                 {
01478                 return $this->_callback_url = $url;
01479                 }
01480         
01487         function callback()
01488                 {
01489                 phpCAS::traceBegin();
01490                 $this->printHTMLHeader('phpCAS callback');
01491                 $pgt_iou = $_GET['pgtIou'];
01492                 $pgt = $_GET['pgtId'];
01493                 phpCAS::trace('Storing PGT `'.$pgt.'\' (id=`'.$pgt_iou.'\')');
01494                 echo '<p>Storing PGT `'.$pgt.'\' (id=`'.$pgt_iou.'\').</p>';
01495                 $this->storePGT($pgt,$pgt_iou);
01496                 $this->printHTMLFooter();
01497                 phpCAS::traceExit();
01498                 }
01499         
01502         
01503         
01504         
01518         var $_pgt_storage = null;
01519         
01526         function initPGTStorage()
01527                 {
01528                 
01529                 if ( !is_object($this->_pgt_storage) ) {
01530                         $this->setPGTStorageFile();
01531                 }
01532                 
01533                 
01534                 $this->_pgt_storage->init();
01535                 }
01536         
01545         function storePGT($pgt,$pgt_iou)
01546                 {
01547                 
01548                 $this->initPGTStorage();
01549                 
01550                 $this->_pgt_storage->write($pgt,$pgt_iou);
01551                 }
01552         
01562         function loadPGT($pgt_iou)
01563                 {
01564                 
01565                 $this->initPGTStorage();
01566                 
01567                 return $this->_pgt_storage->read($pgt_iou);
01568                 }
01569         
01579         function setPGTStorageFile($format='',
01580                 $path='')
01581                 {
01582                 
01583                 if ( is_object($this->_pgt_storage) ) {
01584                         phpCAS::error('PGT storage already defined');
01585                 }
01586                 
01587                 
01588                 $this->_pgt_storage = &new PGTStorageFile($this,$format,$path);
01589                 }
01590         
01608         function setPGTStorageDB($user,
01609                                                          $password,
01610                                                          $database_type,
01611                                                          $hostname,
01612                                                          $port,
01613                                                          $database,
01614                                                          $table)
01615                 {
01616                 
01617                 if ( is_object($this->_pgt_storage) ) {
01618                         phpCAS::error('PGT storage already defined');
01619                 }
01620                 
01621                 
01622                 trigger_error('PGT storage into database is an experimental feature, use at your own risk',E_USER_WARNING);
01623                 
01624                 
01625                 $this->_pgt_storage = & new PGTStorageDB($this,$user,$password,$database_type,$hostname,$port,$database,$table);
01626                 }
01627         
01628         
01629         
01630         
01644         function validatePGT(&$validate_url,$text_response,$tree_response)
01645                 {
01646                 phpCAS::traceBegin();
01647                 if ( sizeof($arr = $tree_response->get_elements_by_tagname("proxyGrantingTicket")) == 0) {
01648                         phpCAS::trace('<proxyGrantingTicket> not found');
01649                         
01650                         $this->authError('Ticket validated but no PGT Iou transmitted',
01651                                 $validate_url,
01652                                 FALSE,
01653                                 FALSE,
01654                                 $text_response);
01655                 } else {
01656                         
01657                         $pgt_iou = trim($arr[0]->get_content());
01658                         $pgt = $this->loadPGT($pgt_iou);
01659                         if ( $pgt == FALSE ) {
01660                                 phpCAS::trace('could not load PGT');
01661                                 $this->authError('PGT Iou was transmitted but PGT could not be retrieved',
01662                                         $validate_url,
01663                                         FALSE,
01664                                         FALSE,
01665                                         $text_response);
01666                         }
01667                         $this->setPGT($pgt);
01668                 }
01669                 phpCAS::traceEnd(TRUE);
01670                 return TRUE;
01671                 }
01672         
01673         
01674         
01675         
01676         
01688         function retrievePT($target_service,&$err_code,&$err_msg)
01689                 {
01690                 phpCAS::traceBegin();
01691                 
01692                 
01693                 
01694                 
01695                 
01696                 $err_msg = '';
01697                 
01698                 
01699                 
01700                 $cas_url = $this->getServerProxyURL().'?targetService='.urlencode($target_service).'&pgt='.$this->getPGT();
01701                 
01702                 
01703                 if ( !$this->readURL($cas_url,'',$headers,$cas_response,$err_msg) ) {
01704                         phpCAS::trace('could not open URL \''.$cas_url.'\' to validate ('.$err_msg.')');
01705                         $err_code = PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE;
01706                         $err_msg = 'could not retrieve PT (no response from the CAS server)';
01707                         phpCAS::traceEnd(FALSE);
01708                         return FALSE;
01709                 }
01710                 
01711                 $bad_response = FALSE;
01712                 
01713                 if ( !$bad_response ) {
01714                         // read the response of the CAS server into a DOM object
01715                         if ( !($dom = @domxml_open_mem($cas_response))) {
01716                                 phpCAS::trace('domxml_open_mem() failed');
01717                                 // read failed
01718                                 $bad_response = TRUE;
01719                         } 
01720                 }
01721                 
01722                 if ( !$bad_response ) {
01723                         // read the root node of the XML tree
01724                         if ( !($root = $dom->document_element()) ) {
01725                                 phpCAS::trace('document_element() failed');
01726                                 // read failed
01727                                 $bad_response = TRUE;
01728                         } 
01729                 }
01730                 
01731                 if ( !$bad_response ) {
01732                         // insure that tag name is 'serviceResponse'
01733                         if ( $root->node_name() != 'serviceResponse' ) {
01734                                 phpCAS::trace('node_name() failed');
01735                                 // bad root node
01736                                 $bad_response = TRUE;
01737                         } 
01738                 }
01739                 
01740                 if ( !$bad_response ) {
01741                         // look for a proxySuccess tag
01742                         if ( sizeof($arr = $root->get_elements_by_tagname("proxySuccess")) != 0) {
01743                                 // authentication succeded, look for a proxyTicket tag
01744                                 if ( sizeof($arr = $root->get_elements_by_tagname("proxyTicket")) != 0) {
01745                                         $err_code = PHPCAS_SERVICE_OK;
01746                                         $err_msg = '';
01747                                         phpCAS::trace('original PT: '.trim($arr[0]->get_content()));
01748                                         $pt = trim($arr[0]->get_content());
01749                                         phpCAS::traceEnd($pt);
01750                                         return $pt;
01751                                 } else {
01752                                         phpCAS::trace('<proxySuccess> was found, but not <proxyTicket>');
01753                                 }
01754                         } 
01755                         // look for a proxyFailure tag
01756                         else if ( sizeof($arr = $root->get_elements_by_tagname("proxyFailure")) != 0) {
01757                                 // authentication failed, extract the error
01758                                 $err_code = PHPCAS_SERVICE_PT_FAILURE;
01759                                 $err_msg = 'PT retrieving failed (code=`'
01760                                         .$arr[0]->get_attribute('code')
01761                                         .'\', message=`'
01762                                         .trim($arr[0]->get_content())
01763                                         .'\')';
01764                                 phpCAS::traceEnd(FALSE);
01765                                 return FALSE;
01766                         } else {
01767                                 phpCAS::trace('neither <proxySuccess> nor <proxyFailure> found');
01768                         }
01769                 }
01770                 
01771                 // at this step, we are sure that the response of the CAS server was ill-formed
01772                 $err_code = PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE;
01773                 $err_msg = 'Invalid response from the CAS server (response=`'.$cas_response.'\')';
01774                 
01775                 phpCAS::traceEnd(FALSE);
01776                 return FALSE;
01777                 }
01778         
01779         
01780         
01781         
01782         
01798         function readURL($url,$cookies,&$headers,&$body,&$err_msg)
01799                 {
01800                 phpCAS::traceBegin();
01801                 $headers = '';
01802                 $body = '';
01803                 $err_msg = '';
01804                 
01805                 $res = TRUE;
01806                 
01807                 
01808                 $ch = curl_init($url);
01809                 
01810                 if (version_compare(PHP_VERSION,'5.1.3','>=')) {
01811                         
01812                         curl_setopt_array($ch, $this->_curl_options);
01813                 } else {
01814                         foreach ($this->_curl_options as $key => $value) {
01815                                 curl_setopt($ch, $key, $value);
01816                         }
01817                 }
01818 
01819                 if ($this->_cas_server_cert == '' && $this->_cas_server_ca_cert == '' && !$this->_no_cas_server_validation) {
01820                         phpCAS::error('one of the methods phpCAS::setCasServerCert(), phpCAS::setCasServerCACert() or phpCAS::setNoCasServerValidation() must be called.');
01821                 }
01822                 if ($this->_cas_server_cert != '' ) {
01823                         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
01824                         curl_setopt($ch, CURLOPT_SSLCERT, $this->_cas_server_cert);
01825                 } else if ($this->_cas_server_ca_cert != '') {
01826                         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
01827                         curl_setopt($ch, CURLOPT_CAINFO, $this->_cas_server_ca_cert);
01828                 } else {
01829                         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
01830                         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
01831                 }
01832                 
01833                 
01834                 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
01835                 
01836                 $this->_curl_headers = array(); 
01837                 curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, '_curl_read_headers'));
01838                 
01839                 if ( is_array($cookies) ) {
01840                         curl_setopt($ch,CURLOPT_COOKIE,implode(';',$cookies));
01841                 }
01842                 
01843                 $buf = curl_exec ($ch);
01844                 if ( $buf === FALSE ) {
01845                         phpCAS::trace('curl_exec() failed');
01846                         $err_msg = 'CURL error #'.curl_errno($ch).': '.curl_error($ch);
01847                         
01848                         curl_close ($ch);
01849                         $res = FALSE;
01850                 } else {
01851                         
01852                         curl_close ($ch);
01853                         
01854                         $headers = $this->_curl_headers;
01855                         $body = $buf;
01856                 }
01857                 
01858                 phpCAS::traceEnd($res);
01859                 return $res;
01860         }
01861         
01865         var $_curl_headers = array();
01866         function _curl_read_headers($ch, $header)
01867         {
01868                 $this->_curl_headers[] = $header;
01869                 return strlen($header);
01870         }
01871 
01887         function serviceWeb($url,&$err_code,&$output)
01888                 {
01889                 phpCAS::traceBegin();
01890                 
01891                 $pt = $this->retrievePT($url,$err_code,$output);
01892                 
01893                 $res = TRUE;
01894                 
01895                 
01896                 if ( !$pt ) {
01897                         
01898                         phpCAS::trace('PT was not retrieved correctly');
01899                         $res = FALSE;
01900                 } else {
01901                         
01902                         if ( is_array($_SESSION['phpCAS']['services'][$url]['cookies']) ) {
01903                                 foreach ( $_SESSION['phpCAS']['services'][$url]['cookies'] as $name => $val ) {
01904                                         $cookies[] = $name.'='.$val;
01905                                 }
01906                         }
01907                         
01908                         
01909                         if ( strstr($url,'?') === FALSE ) {
01910                                 $service_url = $url.'?ticket='.$pt;
01911                         } else {
01912                                 $service_url = $url.'&ticket='.$pt;
01913                         }
01914                         
01915                         phpCAS::trace('reading URL`'.$service_url.'\'');
01916                         if ( !$this->readURL($service_url,$cookies,$headers,$output,$err_msg) ) {
01917                                 phpCAS::trace('could not read URL`'.$service_url.'\'');
01918                                 $err_code = PHPCAS_SERVICE_NOT_AVAILABLE;
01919                                 
01920                                 $output = sprintf($this->getString(CAS_STR_SERVICE_UNAVAILABLE),
01921                                         $service_url,
01922                                         $err_msg);
01923                                 $res = FALSE;
01924                         } else {
01925                                 
01926                                 phpCAS::trace('URL`'.$service_url.'\' has been read, storing cookies:');
01927                                 foreach ( $headers as $header ) {
01928                                         // test if the header is a cookie
01929                                         if ( preg_match('/^Set-Cookie:/',$header) ) {
01930                                                 // the header is a cookie, remove the beginning
01931                                                 $header_val = preg_replace('/^Set-Cookie: */','',$header);
01932                                                 // extract interesting information
01933                                                 $name_val = strtok($header_val,'; ');
01934                                                 // extract the name and the value of the cookie
01935                                                 $cookie_name = strtok($name_val,'=');
01936                                                 $cookie_val = strtok('=');
01937                                                 // store the cookie 
01938                                                 $_SESSION['phpCAS']['services'][$url]['cookies'][$cookie_name] = $cookie_val;
01939                                                 phpCAS::trace($cookie_name.' -> '.$cookie_val);
01940                                         }
01941                                 }
01942                         }
01943                 }
01944                 
01945                 phpCAS::traceEnd($res);
01946                 return $res;
01947                 }
01948         
01967         function serviceMail($url,$flags,&$err_code,&$err_msg,&$pt)
01968                 {
01969                 phpCAS::traceBegin();
01970                 // at first retrieve a PT
01971                 $pt = $this->retrievePT($target_service,$err_code,$output);
01972                 
01973                 $stream = FALSE;
01974                 
01975                 // test if PT was retrieved correctly
01976                 if ( !$pt ) {
01977                         // note: $err_code and $err_msg are filled by CASClient::retrievePT()
01978                         phpCAS::trace('PT was not retrieved correctly');
01979                 } else {
01980                         phpCAS::trace('opening IMAP URL `'.$url.'\'...');
01981                         $stream = @imap_open($url,$this->getUser(),$pt,$flags);
01982                         if ( !$stream ) {
01983                                 phpCAS::trace('could not open URL');
01984                                 $err_code = PHPCAS_SERVICE_NOT_AVAILABLE;
01985                                 
01986                                 $err_msg = sprintf($this->getString(CAS_STR_SERVICE_UNAVAILABLE),
01987                                         $service_url,
01988                                         var_export(imap_errors(),TRUE));
01989                                 $pt = FALSE;
01990                                 $stream = FALSE;
01991                         } else {
01992                                 phpCAS::trace('ok');
01993                         }
01994                 }
01995                 
01996                 phpCAS::traceEnd($stream);
01997                 return $stream;
01998                 }
01999         
02002         
02003         
02004         
02005         
02006         
02007         
02008         
02009         
02010         
02024         var $_pt = '';
02025         
02031         function getPT()
02032                 {
02033                 
02034                 return $this->_pt;
02035                 }
02036         
02042         function setPT($pt)
02043                 { $this->_pt = $pt; }
02044         
02050         function hasPT()
02051                 { return !empty($this->_pt); }
02052         
02054         
02055         
02056         
02069         function validatePT(&$validate_url,&$text_response,&$tree_response)
02070                 {
02071                 phpCAS::traceBegin();
02072                 
02073                 $validate_url = $this->getServerProxyValidateURL().'&ticket='.$this->getPT();
02074                 
02075                 if ( $this->isProxy() ) {
02076                         
02077                         $validate_url .= '&pgtUrl='.$this->getCallbackURL();
02078                 }
02079                 
02080                 
02081                 if ( !$this->readURL($validate_url,'',$headers,$text_response,$err_msg) ) {
02082                         phpCAS::trace('could not open URL \''.$validate_url.'\' to validate ('.$err_msg.')');
02083                         $this->authError('PT not validated',
02084                                 $validate_url,
02085                                 TRUE/*$no_response*/);
02086                 }
02087                 
02088                 // read the response of the CAS server into a DOM object
02089                 if ( !($dom = domxml_open_mem($text_response))) {
02090                         // read failed
02091                         $this->authError('PT not validated',
02092                                 $validate_url,
02093                                 FALSE/*$no_response*/,
02094                                 TRUE/*$bad_response*/,
02095                                 $text_response);
02096                 }
02097                 // read the root node of the XML tree
02098                 if ( !($tree_response = $dom->document_element()) ) {
02099                         // read failed
02100                         $this->authError('PT not validated',
02101                                 $validate_url,
02102                                 FALSE/*$no_response*/,
02103                                 TRUE/*$bad_response*/,
02104                                 $text_response);
02105                 }
02106                 // insure that tag name is 'serviceResponse'
02107                 if ( $tree_response->node_name() != 'serviceResponse' ) {
02108                         // bad root node
02109                         $this->authError('PT not validated',
02110                                 $validate_url,
02111                                 FALSE/*$no_response*/,
02112                                 TRUE/*$bad_response*/,
02113                                 $text_response);
02114                 }
02115                 if ( sizeof($arr = $tree_response->get_elements_by_tagname("authenticationSuccess")) != 0) {
02116                         // authentication succeded, extract the user name
02117                         if ( sizeof($arr = $tree_response->get_elements_by_tagname("user")) == 0) {
02118                                 // no user specified => error
02119                                 $this->authError('PT not validated',
02120                                         $validate_url,
02121                                         FALSE/*$no_response*/,
02122                                         TRUE/*$bad_response*/,
02123                                         $text_response);
02124                         }
02125                         $this->setUser(trim($arr[0]->get_content()));
02126                         
02127                 } else if ( sizeof($arr = $tree_response->get_elements_by_tagname("authenticationFailure")) != 0) {
02128                         // authentication succeded, extract the error code and message
02129                         $this->authError('PT not validated',
02130                                 $validate_url,
02131                                 FALSE/*$no_response*/,
02132                                 FALSE/*$bad_response*/,
02133                                 $text_response,
02134                                 $arr[0]->get_attribute('code')/*$err_code*/,
02135                                 trim($arr[0]->get_content())/*$err_msg*/);
02136                 } else {
02137                         $this->authError('PT not validated',
02138                                 $validate_url,  
02139                                 FALSE/*$no_response*/,
02140                                 TRUE/*$bad_response*/,
02141                                 $text_response);
02142                 }
02143                 
02144                 // at this step, PT has been validated and $this->_user has been set,
02145                 
02146                 phpCAS::traceEnd(TRUE);
02147                 return TRUE;
02148                 }
02149         
02152         // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
02153         // XX                                                                    XX
02154         // XX                               MISC                                 XX
02155         // XX                                                                    XX
02156         // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
02157         
02163         // ########################################################################
02164         //  URL
02165         // ########################################################################
02173         var $_url = '';
02174         
02183         function getURL()
02184                 {
02185                 phpCAS::traceBegin();
02186                 // the URL is built when needed only
02187                 if ( empty($this->_url) ) {
02188                         $final_uri = '';
02189                         // remove the ticket if present in the URL
02190                         $final_uri = ($this->isHttps()) ? 'https' : 'http';
02191                         $final_uri .= ':
02192                         
02193 
02194 
02195                         if(empty($_SERVER['HTTP_X_FORWARDED_SERVER'])){
02196                                 
02197 
02198 
02199                                 if (empty($_SERVER['SERVER_NAME'])) {
02200                                         $server_name = $_SERVER['HTTP_HOST'];
02201                                 } else {
02202                                         $server_name = $_SERVER['SERVER_NAME'];
02203                                 }
02204                         } else {
02205                                 $server_name = $_SERVER['HTTP_X_FORWARDED_SERVER'];
02206                         }
02207                         $final_uri .= $server_name;
02208                         if (!strpos($server_name, ':')) {
02209                                 if ( ($this->isHttps() && $_SERVER['SERVER_PORT']!=443)
02210                                                 || (!$this->isHttps() && $_SERVER['SERVER_PORT']!=80) ) {
02211                                         $final_uri .= ':';
02212                                         $final_uri .= $_SERVER['SERVER_PORT'];
02213                                 }
02214                         }
02215                         
02216                         $final_uri .= strtok($_SERVER['REQUEST_URI'],"?");
02217                         $cgi_params = '?'.strtok("?");
02218                         
02219                         $cgi_params = preg_replace('/&ticket=[^&]*/','',$cgi_params);
02220                         $cgi_params = preg_replace('/\?ticket=[^&;]*/','?',$cgi_params);
02221                         $cgi_params = preg_replace('/\?%26/','?',$cgi_params);
02222                         $cgi_params = preg_replace('/\?&/','?',$cgi_params);
02223                         $cgi_params = preg_replace('/\?$/','',$cgi_params);
02224                         $final_uri .= $cgi_params;
02225                         $this->setURL($final_uri);
02226                 }
02227                 phpCAS::traceEnd($this->_url);
02228                 return $this->_url;
02229                 }
02230         
02238         function setURL($url)
02239                 {
02240                 $this->_url = $url;
02241                 }
02242         
02243         
02244         
02245         
02261         function authError($failure,$cas_url,$no_response,$bad_response='',$cas_response='',$err_code='',$err_msg='')
02262                 {
02263                 phpCAS::traceBegin();
02264                 
02265                 $this->printHTMLHeader($this->getString(CAS_STR_AUTHENTICATION_FAILED));
02266                 printf($this->getString(CAS_STR_YOU_WERE_NOT_AUTHENTICATED),$this->getURL(),$_SERVER['SERVER_ADMIN']);
02267                 phpCAS::trace('CAS URL: '.$cas_url);
02268                 phpCAS::trace('Authentication failure: '.$failure);
02269                 if ( $no_response ) {
02270                         phpCAS::trace('Reason: no response from the CAS server');
02271                 } else {
02272                         if ( $bad_response ) {
02273                                 phpCAS::trace('Reason: bad response from the CAS server');
02274                         } else {
02275                                 switch ($this->getServerVersion()) {
02276                                         case CAS_VERSION_1_0:
02277                                                 phpCAS::trace('Reason: CAS error');
02278                                                 break;
02279                                         case CAS_VERSION_2_0:
02280                                                 if ( empty($err_code) )
02281                                                         phpCAS::trace('Reason: no CAS error');
02282                                                 else
02283                                                         phpCAS::trace('Reason: ['.$err_code.'] CAS error: '.$err_msg);
02284                                                 break;
02285                                 }
02286                         }
02287                         phpCAS::trace('CAS response: '.$cas_response);
02288                 }
02289                 $this->printHTMLFooter();
02290                 phpCAS::traceExit();
02291                 exit();
02292                 }
02293         
02295 }
02296 
02297 ?>