<?php 
 | 
// Thrown when internal error occurs 
 | 
class JasigException extends Exception {} 
 | 
// Thrown when CAS server return authentication error 
 | 
class JasigAuthException extends JasigException {} 
 | 
  
 | 
class JasigUser { 
 | 
    public $user; 
 | 
    public $attributes = array(); 
 | 
} 
 | 
  
 | 
class uphpCAS { 
 | 
    const VERSION = '1.0'; 
 | 
    protected $serverUrl = ''; 
 | 
    protected $serviceUrl; 
 | 
     
 | 
    function __construct($serverUrl = NULL, $serviceUrl = NULL) { 
 | 
        if($serverUrl != NULL) { 
 | 
            $this->serverUrl = rtrim($serverUrl, '/'); 
 | 
        } 
 | 
         
 | 
        if($serviceUrl != NULL) { 
 | 
            $this->serviceUrl = $serviceUrl; 
 | 
        } else { 
 | 
            $url = 'http://'; 
 | 
            $port = 0; 
 | 
            if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') { 
 | 
                $url = 'https://'; 
 | 
                if(isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] != '443') { 
 | 
                    $port = $_SERVER['SERVER_PORT']; 
 | 
                } 
 | 
            } elseif(isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] != '80') { 
 | 
                $port = $_SERVER['SERVER_PORT']; 
 | 
            } 
 | 
             
 | 
            $url .= $_SERVER['SERVER_NAME']; 
 | 
             
 | 
            if($port != 0) { 
 | 
                $url .= ':'.$port; 
 | 
            } 
 | 
            $url .= $_SERVER['REQUEST_URI']; 
 | 
             
 | 
            $this->serviceUrl = $url; 
 | 
        } 
 | 
    } 
 | 
     
 | 
    public function setServerUrl($serverUrl) { 
 | 
        $this->serverUrl = $serverUrl; 
 | 
    } 
 | 
     
 | 
    public function setServiceUrl($serviceUrl) { 
 | 
        $this->serviceUrl = $serviceUrl; 
 | 
    } 
 | 
     
 | 
    public function loginUrl() { 
 | 
        return $this->serverUrl.'/login?service='.urlencode($this->serviceUrl); 
 | 
    } 
 | 
     
 | 
    public function logoutUrl() { 
 | 
        return $this->serverUrl.'/logout'; 
 | 
    } 
 | 
     
 | 
    public function logout() { 
 | 
        session_start(); 
 | 
        if(isset($_SESSION['uphpCAS-user'])) { 
 | 
            unset($_SESSION['uphpCAS-user']); 
 | 
        } 
 | 
        header('Location: '.$this->logoutUrl()); 
 | 
        die(); 
 | 
    } 
 | 
     
 | 
    public function authenticate() { 
 | 
        session_start(); 
 | 
        if(isset($_SESSION['uphpCAS-user'])) { 
 | 
            return $_SESSION['uphpCAS-user']; 
 | 
        } elseif(isset($_GET['ticket'])) { 
 | 
            $user = $this->verifyTicket($_GET['ticket']); 
 | 
            $_SESSION['uphpCAS-user'] = $user; 
 | 
            return $user; 
 | 
        } else { 
 | 
            header('Location: '.$this->loginUrl()); 
 | 
            die(); 
 | 
        } 
 | 
    } 
 | 
     
 | 
    public function verifyTicket($ticket) { 
 | 
        $context = array( 
 | 
            'http' => array( 
 | 
                'method' => 'GET', 
 | 
                'user_agent' => 'uphpCAS/'.self::VERSION, 
 | 
                'max_redirects' => 3, 
 | 
            ), 
 | 
            'ssl' => array( 
 | 
                'verify_peer' => TRUE, 
 | 
                'allow_self_signed' => FALSE, 
 | 
                'verify_depth' => 5, 
 | 
                'ciphers' => 'HIGH:-MD5:-aNULL:-DES', 
 | 
            ), 
 | 
        ); 
 | 
         
 | 
        $data = file_get_contents($this->serverUrl.'/serviceValidate?service='.urlencode($this->serviceUrl).'&ticket='.urlencode($ticket), 
 | 
                FALSE, stream_context_create($context)); 
 | 
        if($data === FALSE) { 
 | 
            throw new JasigException('Authentication error: CAS server is unavailable'); 
 | 
        } 
 | 
         
 | 
        $xmlEntityLoader = libxml_disable_entity_loader(TRUE); 
 | 
        $xmlInternalErrors = libxml_use_internal_errors(TRUE); 
 | 
        try { 
 | 
            $xml = new DOMDocument(); 
 | 
            $xml->loadXML($data); 
 | 
             
 | 
            foreach(libxml_get_errors() as $error) { 
 | 
                $e = new ErrorException($error->message, $error->code, 1, $error->file, $error->line); 
 | 
                switch ($error->level) { 
 | 
                    case LIBXML_ERR_ERROR: 
 | 
                        throw new Exception('Fatal error during XML parsing', 0, $e); 
 | 
                        break; 
 | 
                    case LIBXML_ERR_FATAL: 
 | 
                        throw new Exception('Fatal error during XML parsing', 0, $e); 
 | 
                        break; 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
        catch(Exception $e) { 
 | 
            throw new JasigException('Authentication error: CAS server response invalid - parse error', 0, $e); 
 | 
        } finally { 
 | 
            libxml_clear_errors(); 
 | 
            libxml_disable_entity_loader($xmlEntityLoader); 
 | 
            libxml_use_internal_errors($xmlInternalErrors); 
 | 
        } 
 | 
         
 | 
        $failure = $xml->getElementsByTagName('authenticationFailure'); 
 | 
        $success = $xml->getElementsByTagName('authenticationSuccess'); 
 | 
         
 | 
        if($failure->length > 0) { 
 | 
            $failure = $failure->item(0); 
 | 
            if(!($failure instanceof DOMElement)) { 
 | 
                throw new JasigException('Authentication error: CAS server response invalid - authenticationFailure'); 
 | 
            } 
 | 
            throw new JasigAuthException('Authentication error: '.$failure->textContent); 
 | 
        } elseif($success->length > 0) { 
 | 
            $success = $success->item(0); 
 | 
            if(!($success instanceof DOMElement)) { 
 | 
                throw new JasigException('Authentication error: CAS server response invalid - authenticationSuccess'); 
 | 
            } 
 | 
             
 | 
            $user = $success->getElementsByTagName('user'); 
 | 
            if($user->length == 0) { 
 | 
                throw new JasigException('Authentication error: CAS server response invalid - user'); 
 | 
            } 
 | 
             
 | 
            $user = trim($user->item(0)->textContent); 
 | 
            if(strlen($user)<1) { 
 | 
                throw new JasigException('Authentication error: CAS server response invalid - user value'); 
 | 
            } 
 | 
             
 | 
            $jusr = new JasigUser(); 
 | 
            $jusr->user = $user; 
 | 
             
 | 
            $attrs = $success->getElementsByTagName('attributes'); 
 | 
            if($attrs->length > 0) { 
 | 
                $attrs = $attrs->item(0); 
 | 
                foreach($attrs->childNodes as $node) { 
 | 
                    $jusr->attributes[$node->localName] = $node->textContent; 
 | 
                } 
 | 
            } 
 | 
             
 | 
            return $jusr; 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
            throw new JasigException('Authentication error: CAS server response invalid - required tag not found'); 
 | 
        } 
 | 
    } 
 | 
} 
 |