diff options
author | Craig Andrews <candrews@integralblue.com> | 2010-03-02 23:24:50 -0500 |
---|---|---|
committer | Craig Andrews <candrews@integralblue.com> | 2010-03-02 23:25:34 -0500 |
commit | 358556057a87c0cb9291223a2026782e6548ff2e (patch) | |
tree | 57272e299ccf0fde25d2dfe348f60de4aa4f648b /plugins/CasAuthentication/extlib/CAS/client.php | |
parent | ddf3614c843bcd8d9ecfd0850ac9a8cefae6dbba (diff) |
Bump to phpCAS 1.1.0RC6
Diffstat (limited to 'plugins/CasAuthentication/extlib/CAS/client.php')
-rw-r--r-- | plugins/CasAuthentication/extlib/CAS/client.php | 552 |
1 files changed, 465 insertions, 87 deletions
diff --git a/plugins/CasAuthentication/extlib/CAS/client.php b/plugins/CasAuthentication/extlib/CAS/client.php index bbde55a28..ad5a23f83 100644 --- a/plugins/CasAuthentication/extlib/CAS/client.php +++ b/plugins/CasAuthentication/extlib/CAS/client.php @@ -351,6 +351,43 @@ class CASClient { return $this->_server['login_url'] = $url; } + + + /** + * This method sets the serviceValidate URL of the CAS server. + * @param $url the serviceValidate URL + * @private + * @since 1.1.0 by Joachim Fritschi + */ + function setServerServiceValidateURL($url) + { + return $this->_server['service_validate_url'] = $url; + } + + + /** + * This method sets the proxyValidate URL of the CAS server. + * @param $url the proxyValidate URL + * @private + * @since 1.1.0 by Joachim Fritschi + */ + function setServerProxyValidateURL($url) + { + return $this->_server['proxy_validate_url'] = $url; + } + + + /** + * This method sets the samlValidate URL of the CAS server. + * @param $url the samlValidate URL + * @private + * @since 1.1.0 by Joachim Fritschi + */ + function setServerSamlValidateURL($url) + { + return $this->_server['saml_validate_url'] = $url; + } + /** * This method is used to retrieve the service validating URL of the CAS server. @@ -373,7 +410,25 @@ class CASClient // return $this->_server['service_validate_url'].'?service='.preg_replace('/&/','%26',$this->getURL()); return $this->_server['service_validate_url'].'?service='.urlencode($this->getURL()); } - + /** + * This method is used to retrieve the SAML validating URL of the CAS server. + * @return a URL. + * @private + */ + function getServerSamlValidateURL() + { + phpCAS::traceBegin(); + // the URL is build only when needed + if ( empty($this->_server['saml_validate_url']) ) { + switch ($this->getServerVersion()) { + case SAML_VERSION_1_1: + $this->_server['saml_validate_url'] = $this->getServerBaseURL().'samlValidate'; + break; + } + } + phpCAS::traceEnd($this->_server['saml_validate_url'].'?TARGET='.urlencode($this->getURL())); + return $this->_server['saml_validate_url'].'?TARGET='.urlencode($this->getURL()); + } /** * This method is used to retrieve the proxy validating URL of the CAS server. * @return a URL. @@ -497,31 +552,51 @@ class CASClient phpCAS::traceBegin(); - if (!$this->isLogoutRequest() && !empty($_GET['ticket']) && $start_session) { - // copy old session vars and destroy the current session - if (!isset($_SESSION)) { - session_start(); - } - $old_session = $_SESSION; - session_destroy(); - // set up a new session, of name based on the ticket - $session_id = preg_replace('/[^\w]/','',$_GET['ticket']); - phpCAS::LOG("Session ID: " . $session_id); - session_id($session_id); - if (!isset($_SESSION)) { - session_start(); - } - // restore old session vars - $_SESSION = $old_session; - // Redirect to location without ticket. - header('Location: '.$this->getURL()); - } - - //activate session mechanism if desired - if (!$this->isLogoutRequest() && $start_session) { - session_start(); + // the redirect header() call and DOM parsing code from domxml-php4-php5.php won't work in PHP4 compatibility mode + if (version_compare(PHP_VERSION,'5','>=') && ini_get('zend.ze1_compatibility_mode')) { + phpCAS::error('phpCAS cannot support zend.ze1_compatibility_mode. Sorry.'); + } + // skip Session Handling for logout requests and if don't want it' + if ($start_session && !$this->isLogoutRequest()) { + phpCAS::trace("Starting session handling"); + // Check for Tickets from the CAS server + if (empty($_GET['ticket'])){ + phpCAS::trace("No ticket found"); + // only create a session if necessary + if (!isset($_SESSION)) { + phpCAS::trace("No session found, creating new session"); + session_start(); + } + }else{ + phpCAS::trace("Ticket found"); + // We have to copy any old data before renaming the session + if (isset($_SESSION)) { + phpCAS::trace("Old active session found, saving old data and destroying session"); + $old_session = $_SESSION; + session_destroy(); + }else{ + session_start(); + phpCAS::trace("Starting possible old session to copy variables"); + $old_session = $_SESSION; + session_destroy(); + } + // set up a new session, of name based on the ticket + $session_id = preg_replace('/[^\w]/','',$_GET['ticket']); + phpCAS::LOG("Session ID: " . $session_id); + session_id($session_id); + session_start(); + // restore old session vars + if(isset($old_session)){ + phpCAS::trace("Restoring old session vars"); + $_SESSION = $old_session; + } + } + }else{ + phpCAS::trace("Skipping session creation"); } + + // are we in proxy mode ? $this->_proxy = $proxy; //check version @@ -533,6 +608,8 @@ class CASClient break; case CAS_VERSION_2_0: break; + case SAML_VERSION_1_1: + break; default: phpCAS::error('this version of CAS (`' .$server_version @@ -541,29 +618,29 @@ class CASClient } $this->_server['version'] = $server_version; - //check hostname + // check hostname if ( empty($server_hostname) || !preg_match('/[\.\d\-abcdefghijklmnopqrstuvwxyz]*/',$server_hostname) ) { phpCAS::error('bad CAS server hostname (`'.$server_hostname.'\')'); } $this->_server['hostname'] = $server_hostname; - //check port + // check port if ( $server_port == 0 || !is_int($server_port) ) { phpCAS::error('bad CAS server port (`'.$server_hostname.'\')'); } $this->_server['port'] = $server_port; - //check URI + // check URI if ( !preg_match('/[\.\d\-_abcdefghijklmnopqrstuvwxyz\/]*/',$server_uri) ) { phpCAS::error('bad CAS server URI (`'.$server_uri.'\')'); } - //add leading and trailing `/' and remove doubles + // add leading and trailing `/' and remove doubles $server_uri = preg_replace('/\/\//','/','/'.$server_uri.'/'); $this->_server['uri'] = $server_uri; - //set to callback mode if PgtIou and PgtId CGI GET parameters are provided + // set to callback mode if PgtIou and PgtId CGI GET parameters are provided if ( $this->isProxy() ) { $this->setCallbackMode(!empty($_GET['pgtIou'])&&!empty($_GET['pgtId'])); } @@ -590,8 +667,12 @@ class CASClient } break; case CAS_VERSION_2_0: // check for a Service or Proxy Ticket - if( preg_match('/^[SP]T-/',$ticket) ) { - phpCAS::trace('ST or PT \''.$ticket.'\' found'); + if (preg_match('/^ST-/', $ticket)) { + phpCAS::trace('ST \'' . $ticket . '\' found'); + $this->setST($ticket); + unset ($_GET['ticket']); + } else if (preg_match('/^PT-/', $ticket)) { + phpCAS::trace('PT \'' . $ticket . '\' found'); $this->setPT($ticket); unset($_GET['ticket']); } else if ( !empty($ticket) ) { @@ -599,6 +680,16 @@ class CASClient phpCAS::error('ill-formed ticket found in the URL (ticket=`'.htmlentities($ticket).'\')'); } break; + case SAML_VERSION_1_1: // SAML just does Service Tickets + if( preg_match('/^[SP]T-/',$ticket) ) { + phpCAS::trace('SA \''.$ticket.'\' found'); + $this->setSA($ticket); + unset($_GET['ticket']); + } else if ( !empty($ticket) ) { + //ill-formed ticket, halt + phpCAS::error('ill-formed ticket found in the URL (ticket=`'.htmlentities($ticket).'\')'); + } + break; } } phpCAS::traceEnd(); @@ -652,6 +743,45 @@ class CASClient } return $this->_user; } + + + + /*********************************************************************************************************************** + * Atrributes section + * + * @author Matthias Crauwels <matthias.crauwels@ugent.be>, Ghent University, Belgium + * + ***********************************************************************************************************************/ + /** + * The Authenticated users attributes. Written by CASClient::setAttributes(), read by CASClient::getAttributes(). + * @attention client applications should use phpCAS::getAttributes(). + * + * @hideinitializer + * @private + */ + var $_attributes = array(); + + function setAttributes($attributes) + { $this->_attributes = $attributes; } + + function getAttributes() { + if ( empty($this->_user) ) { // if no user is set, there shouldn't be any attributes also... + phpCAS::error('this method should be used only after '.__CLASS__.'::forceAuthentication() or '.__CLASS__.'::isAuthenticated()'); + } + return $this->_attributes; + } + + function hasAttributes() + { return !empty($this->_attributes); } + + function hasAttribute($key) + { return (is_array($this->_attributes) && array_key_exists($key, $this->_attributes)); } + + function getAttribute($key) { + if($this->hasAttribute($key)) { + return $this->_attributes[$key]; + } + } /** * This method is called to renew the authentication of the user @@ -778,55 +908,72 @@ class CASClient * This method is called to check if the user is authenticated (previously or by * tickets given in the URL). * - * @return TRUE when the user is authenticated. + * @return TRUE when the user is authenticated. Also may redirect to the same URL without the ticket. * * @public */ function isAuthenticated() { - phpCAS::traceBegin(); - $res = FALSE; - $validate_url = ''; - - if ( $this->wasPreviouslyAuthenticated() ) { - // the user has already (previously during the session) been - // authenticated, nothing to be done. - phpCAS::trace('user was already authenticated, no need to look for tickets'); - $res = TRUE; - } - elseif ( $this->hasST() ) { - // if a Service Ticket was given, validate it - phpCAS::trace('ST `'.$this->getST().'\' is present'); - $this->validateST($validate_url,$text_response,$tree_response); // if it fails, it halts - phpCAS::trace('ST `'.$this->getST().'\' was validated'); - if ( $this->isProxy() ) { - $this->validatePGT($validate_url,$text_response,$tree_response); // idem - phpCAS::trace('PGT `'.$this->getPGT().'\' was validated'); - $_SESSION['phpCAS']['pgt'] = $this->getPGT(); + phpCAS::traceBegin(); + $res = FALSE; + $validate_url = ''; + + if ( $this->wasPreviouslyAuthenticated() ) { + // the user has already (previously during the session) been + // authenticated, nothing to be done. + phpCAS::trace('user was already authenticated, no need to look for tickets'); + $res = TRUE; } - $_SESSION['phpCAS']['user'] = $this->getUser(); - $res = TRUE; - } - elseif ( $this->hasPT() ) { - // if a Proxy Ticket was given, validate it - phpCAS::trace('PT `'.$this->getPT().'\' is present'); - $this->validatePT($validate_url,$text_response,$tree_response); // note: if it fails, it halts - phpCAS::trace('PT `'.$this->getPT().'\' was validated'); - if ( $this->isProxy() ) { - $this->validatePGT($validate_url,$text_response,$tree_response); // idem - phpCAS::trace('PGT `'.$this->getPGT().'\' was validated'); - $_SESSION['phpCAS']['pgt'] = $this->getPGT(); + else { + if ( $this->hasST() ) { + // if a Service Ticket was given, validate it + phpCAS::trace('ST `'.$this->getST().'\' is present'); + $this->validateST($validate_url,$text_response,$tree_response); // if it fails, it halts + phpCAS::trace('ST `'.$this->getST().'\' was validated'); + if ( $this->isProxy() ) { + $this->validatePGT($validate_url,$text_response,$tree_response); // idem + phpCAS::trace('PGT `'.$this->getPGT().'\' was validated'); + $_SESSION['phpCAS']['pgt'] = $this->getPGT(); + } + $_SESSION['phpCAS']['user'] = $this->getUser(); + $res = TRUE; + } + elseif ( $this->hasPT() ) { + // if a Proxy Ticket was given, validate it + phpCAS::trace('PT `'.$this->getPT().'\' is present'); + $this->validatePT($validate_url,$text_response,$tree_response); // note: if it fails, it halts + phpCAS::trace('PT `'.$this->getPT().'\' was validated'); + if ( $this->isProxy() ) { + $this->validatePGT($validate_url,$text_response,$tree_response); // idem + phpCAS::trace('PGT `'.$this->getPGT().'\' was validated'); + $_SESSION['phpCAS']['pgt'] = $this->getPGT(); + } + $_SESSION['phpCAS']['user'] = $this->getUser(); + $res = TRUE; + } + elseif ( $this->hasSA() ) { + // if we have a SAML ticket, validate it. + phpCAS::trace('SA `'.$this->getSA().'\' is present'); + $this->validateSA($validate_url,$text_response,$tree_response); // if it fails, it halts + phpCAS::trace('SA `'.$this->getSA().'\' was validated'); + $_SESSION['phpCAS']['user'] = $this->getUser(); + $_SESSION['phpCAS']['attributes'] = $this->getAttributes(); + $res = TRUE; + } + else { + // no ticket given, not authenticated + phpCAS::trace('no ticket found'); + } + if ($res) { + // if called with a ticket parameter, we need to redirect to the app without the ticket so that CAS-ification is transparent to the browser (for later POSTS) + // most of the checks and errors should have been made now, so we're safe for redirect without masking error messages. + header('Location: '.$this->getURL()); + phpCAS::log( "Prepare redirect to : ".$this->getURL() ); + } } - $_SESSION['phpCAS']['user'] = $this->getUser(); - $res = TRUE; - } - else { - // no ticket given, not authenticated - phpCAS::trace('no ticket found'); - } - - phpCAS::traceEnd($res); - return $res; + + phpCAS::traceEnd($res); + return $res; } /** @@ -889,6 +1036,9 @@ class CASClient if ( $this->isSessionAuthenticated() ) { // authentication already done $this->setUser($_SESSION['phpCAS']['user']); + if(isset($_SESSION['phpCAS']['attributes'])){ + $this->setAttributes($_SESSION['phpCAS']['attributes']); + } phpCAS::trace('user = `'.$_SESSION['phpCAS']['user'].'\''); $auth = TRUE; } else { @@ -917,6 +1067,7 @@ class CASClient printf('<p>'.$this->getString(CAS_STR_SHOULD_HAVE_BEEN_REDIRECTED).'</p>',$cas_url); $this->printHTMLFooter(); + phpCAS::traceExit(); exit(); } @@ -962,11 +1113,15 @@ class CASClient $cas_url = $cas_url . $paramSeparator . "service=" . urlencode($params['service']); } header('Location: '.$cas_url); + phpCAS::log( "Prepare redirect to : ".$cas_url ); + session_unset(); session_destroy(); + $this->printHTMLHeader($this->getString(CAS_STR_LOGOUT)); printf('<p>'.$this->getString(CAS_STR_SHOULD_HAVE_BEEN_REDIRECTED).'</p>',$cas_url); $this->printHTMLFooter(); + phpCAS::traceExit(); exit(); } @@ -1009,10 +1164,10 @@ class CASClient } $client_ip = $_SERVER['REMOTE_ADDR']; $client = gethostbyaddr($client_ip); - phpCAS::log("Client: ".$client); + phpCAS::log("Client: ".$client."/".$client_ip); $allowed = false; foreach ($allowed_clients as $allowed_client) { - if ($client == $allowed_client) { + if (($client == $allowed_client) or ($client_ip == $allowed_client)) { phpCAS::log("Allowed client '".$allowed_client."' matches, logout request is allowed"); $allowed = true; break; @@ -1284,6 +1439,151 @@ class CASClient phpCAS::traceEnd(TRUE); return TRUE; } + + // ######################################################################## + // SAML VALIDATION + // ######################################################################## + /** + * @addtogroup internalBasic + * @{ + */ + + /** + * This method is used to validate a SAML TICKET; halt on failure, and sets $validate_url, + * $text_reponse and $tree_response on success. These parameters are used later + * by CASClient::validatePGT() for CAS proxies. + * + * @param $validate_url the URL of the request to the CAS server. + * @param $text_response the response of the CAS server, as is (XML text). + * @param $tree_response the response of the CAS server, as a DOM XML tree. + * + * @return bool TRUE when successfull, halt otherwise by calling CASClient::authError(). + * + * @private + */ + function validateSA($validate_url,&$text_response,&$tree_response) + { + phpCAS::traceBegin(); + + // build the URL to validate the ticket + $validate_url = $this->getServerSamlValidateURL(); + + // open and read the URL + if ( !$this->readURL($validate_url,''/*cookies*/,$headers,$text_response,$err_msg) ) { + phpCAS::trace('could not open URL \''.$validate_url.'\' to validate ('.$err_msg.')'); + $this->authError('SA not validated', $validate_url, TRUE/*$no_response*/); + } + + phpCAS::trace('server version: '.$this->getServerVersion()); + + // analyze the result depending on the version + switch ($this->getServerVersion()) { + case SAML_VERSION_1_1: + + // read the response of the CAS server into a DOM object + if ( !($dom = domxml_open_mem($text_response))) { + phpCAS::trace('domxml_open_mem() failed'); + $this->authError('SA not validated', + $validate_url, + FALSE/*$no_response*/, + TRUE/*$bad_response*/, + $text_response); + } + // read the root node of the XML tree + if ( !($tree_response = $dom->document_element()) ) { + phpCAS::trace('document_element() failed'); + $this->authError('SA not validated', + $validate_url, + FALSE/*$no_response*/, + TRUE/*$bad_response*/, + $text_response); + } + // insure that tag name is 'Envelope' + if ( $tree_response->node_name() != 'Envelope' ) { + phpCAS::trace('bad XML root node (should be `Envelope\' instead of `'.$tree_response->node_name().'\''); + $this->authError('SA not validated', + $validate_url, + FALSE/*$no_response*/, + TRUE/*$bad_response*/, + $text_response); + } + // check for the NameIdentifier tag in the SAML response + if ( sizeof($success_elements = $tree_response->get_elements_by_tagname("NameIdentifier")) != 0) { + phpCAS::trace('NameIdentifier found'); + $user = trim($success_elements[0]->get_content()); + phpCAS::trace('user = `'.$user.'`'); + $this->setUser($user); + $this->setSessionAttributes($text_response); + } else { + phpCAS::trace('no <NameIdentifier> tag found in SAML payload'); + $this->authError('SA not validated', + $validate_url, + FALSE/*$no_response*/, + TRUE/*$bad_response*/, + $text_response); + } + break; + } + + // at this step, ST has been validated and $this->_user has been set, + phpCAS::traceEnd(TRUE); + return TRUE; + } + + /** + * This method will parse the DOM and pull out the attributes from the SAML + * payload and put them into an array, then put the array into the session. + * + * @param $text_response the SAML payload. + * @return bool TRUE when successfull, halt otherwise by calling CASClient::authError(). + * + * @private + */ + function setSessionAttributes($text_response) + { + phpCAS::traceBegin(); + + $result = FALSE; + + if (isset($_SESSION[SAML_ATTRIBUTES])) { + phpCAS::trace("session attrs already set."); //testbml - do we care? + } + + $attr_array = array(); + + if (($dom = domxml_open_mem($text_response))) { + $xPath = $dom->xpath_new_context(); + $xPath->xpath_register_ns('samlp', 'urn:oasis:names:tc:SAML:1.0:protocol'); + $xPath->xpath_register_ns('saml', 'urn:oasis:names:tc:SAML:1.0:assertion'); + $nodelist = $xPath->xpath_eval("//saml:Attribute"); + $attrs = $nodelist->nodeset; + phpCAS::trace($text_response); + foreach($attrs as $attr){ + $xres = $xPath->xpath_eval("saml:AttributeValue", $attr); + $name = $attr->get_attribute("AttributeName"); + $value_array = array(); + foreach($xres->nodeset as $node){ + $value_array[] = $node->get_content(); + + } + phpCAS::trace("* " . $name . "=" . $value_array); + $attr_array[$name] = $value_array; + } + $_SESSION[SAML_ATTRIBUTES] = $attr_array; + // UGent addition... + foreach($attr_array as $attr_key => $attr_value) { + if(count($attr_value) > 1) { + $this->_attributes[$attr_key] = $attr_value; + } + else { + $this->_attributes[$attr_key] = $attr_value[0]; + } + } + $result = TRUE; + } + phpCAS::traceEnd($result); + return $result; + } /** @} */ @@ -1495,6 +1795,7 @@ class CASClient $this->storePGT($pgt,$pgt_iou); $this->printHTMLFooter(); phpCAS::traceExit(); + exit(); } /** @} */ @@ -1585,7 +1886,7 @@ class CASClient } // create the storage object - $this->_pgt_storage = &new PGTStorageFile($this,$format,$path); + $this->_pgt_storage = new PGTStorageFile($this,$format,$path); } /** @@ -1622,7 +1923,7 @@ class CASClient trigger_error('PGT storage into database is an experimental feature, use at your own risk',E_USER_WARNING); // create the storage object - $this->_pgt_storage = & new PGTStorageDB($this,$user,$password,$database_type,$hostname,$port,$database,$table); + $this->_pgt_storage = new PGTStorageDB($this,$user,$password,$database_type,$hostname,$port,$database,$table); } // ######################################################################## @@ -1643,7 +1944,8 @@ class CASClient */ function validatePGT(&$validate_url,$text_response,$tree_response) { - phpCAS::traceBegin(); + // here cannot use phpCAS::traceBegin(); alongside domxml-php4-to-php5.php + phpCAS::log('start validatePGT()'); if ( sizeof($arr = $tree_response->get_elements_by_tagname("proxyGrantingTicket")) == 0) { phpCAS::trace('<proxyGrantingTicket> not found'); // authentication succeded, but no PGT Iou was transmitted @@ -1666,7 +1968,8 @@ class CASClient } $this->setPGT($pgt); } - phpCAS::traceEnd(TRUE); + // here, cannot use phpCAS::traceEnd(TRUE); alongside domxml-php4-to-php5.php + phpCAS::log('end validatePGT()'); return TRUE; } @@ -1819,7 +2122,15 @@ class CASClient if ($this->_cas_server_cert == '' && $this->_cas_server_ca_cert == '' && !$this->_no_cas_server_validation) { phpCAS::error('one of the methods phpCAS::setCasServerCert(), phpCAS::setCasServerCACert() or phpCAS::setNoCasServerValidation() must be called.'); } - if ($this->_cas_server_cert != '' ) { + if ($this->_cas_server_cert != '' && $this->_cas_server_ca_cert != '') { + // This branch added by IDMS. Seems phpCAS implementor got a bit confused about the curl options CURLOPT_SSLCERT and CURLOPT_CAINFO + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); + curl_setopt($ch, CURLOPT_SSLCERT, $this->_cas_server_cert); + curl_setopt($ch, CURLOPT_CAINFO, $this->_cas_server_ca_cert); + curl_setopt($ch, CURLOPT_VERBOSE, '1'); + phpCAS::trace('CURL: Set all required opts for mutual authentication ------'); + } else if ($this->_cas_server_cert != '' ) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($ch, CURLOPT_SSLCERT, $this->_cas_server_cert); } else if ($this->_cas_server_ca_cert != '') { @@ -1839,11 +2150,28 @@ class CASClient if ( is_array($cookies) ) { curl_setopt($ch,CURLOPT_COOKIE,implode(';',$cookies)); } + // add extra stuff if SAML + if ($this->hasSA()) { + $more_headers = array ("soapaction: http://www.oasis-open.org/committees/security", + "cache-control: no-cache", + "pragma: no-cache", + "accept: text/xml", + "connection: keep-alive", + "content-type: text/xml"); + + curl_setopt($ch, CURLOPT_HTTPHEADER, $more_headers); + curl_setopt($ch, CURLOPT_POST, 1); + $data = $this->buildSAMLPayload(); + //phpCAS::trace('SAML Payload: '.print_r($data, TRUE)); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + } // perform the query $buf = curl_exec ($ch); + //phpCAS::trace('CURL: Call completed. Response body is: \''.$buf.'\''); if ( $buf === FALSE ) { phpCAS::trace('curl_exec() failed'); $err_msg = 'CURL error #'.curl_errno($ch).': '.curl_error($ch); + //phpCAS::trace('curl error: '.$err_msg); // close the CURL session curl_close ($ch); $res = FALSE; @@ -1858,7 +2186,28 @@ class CASClient phpCAS::traceEnd($res); return $res; } - + + /** + * This method is used to build the SAML POST body sent to /samlValidate URL. + * + * @return the SOAP-encased SAMLP artifact (the ticket). + * + * @private + */ + function buildSAMLPayload() + { + phpCAS::traceBegin(); + + //get the ticket + $sa = $this->getSA(); + //phpCAS::trace("SA: ".$sa); + + $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; + + phpCAS::traceEnd($body); + return ($body); + } + /** * This method is the callback used by readURL method to request HTTP headers. */ @@ -1951,6 +2300,7 @@ class CASClient * * @param $url a string giving the URL of the service, including the mailing box * for IMAP URLs, as accepted by imap_open(). + * @param $service a string giving for CAS retrieve Proxy ticket * @param $flags options given to imap_open(). * @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on * success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE, @@ -1964,11 +2314,11 @@ class CASClient * * @public */ - function serviceMail($url,$flags,&$err_code,&$err_msg,&$pt) + function serviceMail($url,$service,$flags,&$err_code,&$err_msg,&$pt) { phpCAS::traceBegin(); // at first retrieve a PT - $pt = $this->retrievePT($target_service,$err_code,$output); + $pt = $this->retrievePT($service,$err_code,$output); $stream = FALSE; @@ -2049,7 +2399,30 @@ class CASClient */ function hasPT() { return !empty($this->_pt); } - + /** + * This method returns the SAML Ticket provided in the URL of the request. + * @return The SAML ticket. + * @private + */ + function getSA() + { return 'ST'.substr($this->_sa, 2); } + + /** + * This method stores the SAML Ticket. + * @param $sa The SAML Ticket. + * @private + */ + function setSA($sa) + { $this->_sa = $sa; } + + /** + * This method tells if a SAML Ticket was stored. + * @return TRUE if a SAML Ticket has been stored. + * @private + */ + function hasSA() + { return !empty($this->_sa); } + /** @} */ // ######################################################################## // PT VALIDATION @@ -2213,8 +2586,13 @@ class CASClient } } - $final_uri .= strtok($_SERVER['REQUEST_URI'],"?"); - $cgi_params = '?'.strtok("?"); + $php_is_for_sissies = split("\?", $_SERVER['REQUEST_URI'], 2); + $final_uri .= $php_is_for_sissies[0]; + if(sizeof($php_is_for_sissies) > 1){ + $cgi_params = '?' . $php_is_for_sissies[1]; + } else { + $cgi_params = '?'; + } // remove the ticket if present in the CGI parameters $cgi_params = preg_replace('/&ticket=[^&]*/','',$cgi_params); $cgi_params = preg_replace('/\?ticket=[^&;]*/','?',$cgi_params); @@ -2294,4 +2672,4 @@ class CASClient /** @} */ } -?>
\ No newline at end of file +?> |