PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/common/libraries/plugin/pear/CAS/client.php

https://bitbucket.org/renaatdemuynck/chamilo
PHP | 2980 lines | 1885 code | 199 blank | 896 comment | 184 complexity | a7645b235ce744b6a2030d88bb6025cc MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. * Copyright Š 2003-2010, The ESUP-Portail consortium & the JA-SIG Collaborative.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. * * Neither the name of the ESUP-Portail consortium & the JA-SIG
  15. * Collaborative nor the names of its contributors may be used to endorse or
  16. * promote products derived from this software without specific prior
  17. * written permission.
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  22. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  25. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. /**
  30. * @file CAS/client.php
  31. * Main class of the phpCAS library
  32. */
  33. // include internationalization stuff
  34. include_once (dirname(__FILE__) . '/languages/languages.php');
  35. // include PGT storage classes
  36. include_once (dirname(__FILE__) . '/PGTStorage/pgt-main.php');
  37. /**
  38. * @class CASClient
  39. * The CASClient class is a client interface that provides CAS authentication
  40. * to PHP applications.
  41. *
  42. * @author Pascal Aubry <pascal.aubry at univ-rennes1.fr>
  43. */
  44. class CASClient
  45. {
  46. // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  47. // XX XX
  48. // XX CONFIGURATION XX
  49. // XX XX
  50. // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  51. // ########################################################################
  52. // HTML OUTPUT
  53. // ########################################################################
  54. /**
  55. * @addtogroup internalOutput
  56. * @{
  57. */
  58. /**
  59. * This method filters a string by replacing special tokens by appropriate values
  60. * and prints it. The corresponding tokens are taken into account:
  61. * - __CAS_VERSION__
  62. * - __PHPCAS_VERSION__
  63. * - __SERVER_BASE_URL__
  64. *
  65. * Used by CASClient::PrintHTMLHeader() and CASClient::printHTMLFooter().
  66. *
  67. * @param $str the string to filter and output
  68. *
  69. * @private
  70. */
  71. function HTMLFilterOutput($str)
  72. {
  73. $str = str_replace('__CAS_VERSION__', $this->getServerVersion(), $str);
  74. $str = str_replace('__PHPCAS_VERSION__', phpCAS :: getVersion(), $str);
  75. $str = str_replace('__SERVER_BASE_URL__', $this->getServerBaseURL(), $str);
  76. echo $str;
  77. }
  78. /**
  79. * A string used to print the header of HTML pages. Written by CASClient::setHTMLHeader(),
  80. * read by CASClient::printHTMLHeader().
  81. *
  82. * @hideinitializer
  83. * @private
  84. * @see CASClient::setHTMLHeader, CASClient::printHTMLHeader()
  85. */
  86. var $_output_header = '';
  87. /**
  88. * This method prints the header of the HTML output (after filtering). If
  89. * CASClient::setHTMLHeader() was not used, a default header is output.
  90. *
  91. * @param $title the title of the page
  92. *
  93. * @see HTMLFilterOutput()
  94. * @private
  95. */
  96. function printHTMLHeader($title)
  97. {
  98. $this->HTMLFilterOutput(str_replace('__TITLE__', $title, (empty($this->_output_header) ? '<html><head><title>__TITLE__</title></head><body><h1>__TITLE__</h1>' : $this->_output_header)));
  99. }
  100. /**
  101. * A string used to print the footer of HTML pages. Written by CASClient::setHTMLFooter(),
  102. * read by printHTMLFooter().
  103. *
  104. * @hideinitializer
  105. * @private
  106. * @see CASClient::setHTMLFooter, CASClient::printHTMLFooter()
  107. */
  108. var $_output_footer = '';
  109. /**
  110. * This method prints the footer of the HTML output (after filtering). If
  111. * CASClient::setHTMLFooter() was not used, a default footer is output.
  112. *
  113. * @see HTMLFilterOutput()
  114. * @private
  115. */
  116. function printHTMLFooter()
  117. {
  118. $this->HTMLFilterOutput(empty($this->_output_footer) ? ('<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>') : $this->_output_footer);
  119. }
  120. /**
  121. * This method set the HTML header used for all outputs.
  122. *
  123. * @param $header the HTML header.
  124. *
  125. * @public
  126. */
  127. function setHTMLHeader($header)
  128. {
  129. $this->_output_header = $header;
  130. }
  131. /**
  132. * This method set the HTML footer used for all outputs.
  133. *
  134. * @param $footer the HTML footer.
  135. *
  136. * @public
  137. */
  138. function setHTMLFooter($footer)
  139. {
  140. $this->_output_footer = $footer;
  141. }
  142. /** @} */
  143. // ########################################################################
  144. // INTERNATIONALIZATION
  145. // ########################################################################
  146. /**
  147. * @addtogroup internalLang
  148. * @{
  149. */
  150. /**
  151. * A string corresponding to the language used by phpCAS. Written by
  152. * CASClient::setLang(), read by CASClient::getLang().
  153. * @note debugging information is always in english (debug purposes only).
  154. *
  155. * @hideinitializer
  156. * @private
  157. * @sa CASClient::_strings, CASClient::getString()
  158. */
  159. var $_lang = '';
  160. /**
  161. * This method returns the language used by phpCAS.
  162. *
  163. * @return a string representing the language
  164. *
  165. * @private
  166. */
  167. function getLang()
  168. {
  169. if (empty($this->_lang))
  170. $this->setLang(PHPCAS_LANG_DEFAULT);
  171. return $this->_lang;
  172. }
  173. /**
  174. * array containing the strings used by phpCAS. Written by CASClient::setLang(), read by
  175. * CASClient::getString() and used by CASClient::setLang().
  176. *
  177. * @note This array is filled by instructions in CAS/languages/<$this->_lang>.php
  178. *
  179. * @private
  180. * @see CASClient::_lang, CASClient::getString(), CASClient::setLang(), CASClient::getLang()
  181. */
  182. var $_strings;
  183. /**
  184. * This method returns a string depending on the language.
  185. *
  186. * @param $str the index of the string in $_string.
  187. *
  188. * @return the string corresponding to $index in $string.
  189. *
  190. * @private
  191. */
  192. function getString($str)
  193. {
  194. // call CASclient::getLang() to be sure the language is initialized
  195. $this->getLang();
  196. if (! isset($this->_strings[$str]))
  197. {
  198. trigger_error('string `' . $str . '\' not defined for language `' . $this->getLang() . '\'', E_USER_ERROR);
  199. }
  200. return $this->_strings[$str];
  201. }
  202. /**
  203. * This method is used to set the language used by phpCAS.
  204. * @note Can be called only once.
  205. *
  206. * @param $lang a string representing the language.
  207. *
  208. * @public
  209. * @sa CAS_LANG_FRENCH, CAS_LANG_ENGLISH
  210. */
  211. function setLang($lang)
  212. {
  213. // include the corresponding language file
  214. include_once (dirname(__FILE__) . '/languages/' . $lang . '.php');
  215. if (! is_array($this->_strings))
  216. {
  217. trigger_error('language `' . $lang . '\' is not implemented', E_USER_ERROR);
  218. }
  219. $this->_lang = $lang;
  220. }
  221. /** @} */
  222. // ########################################################################
  223. // CAS SERVER CONFIG
  224. // ########################################################################
  225. /**
  226. * @addtogroup internalConfig
  227. * @{
  228. */
  229. /**
  230. * a record to store information about the CAS server.
  231. * - $_server["version"]: the version of the CAS server
  232. * - $_server["hostname"]: the hostname of the CAS server
  233. * - $_server["port"]: the port the CAS server is running on
  234. * - $_server["uri"]: the base URI the CAS server is responding on
  235. * - $_server["base_url"]: the base URL of the CAS server
  236. * - $_server["login_url"]: the login URL of the CAS server
  237. * - $_server["service_validate_url"]: the service validating URL of the CAS server
  238. * - $_server["proxy_url"]: the proxy URL of the CAS server
  239. * - $_server["proxy_validate_url"]: the proxy validating URL of the CAS server
  240. * - $_server["logout_url"]: the logout URL of the CAS server
  241. *
  242. * $_server["version"], $_server["hostname"], $_server["port"] and $_server["uri"]
  243. * are written by CASClient::CASClient(), read by CASClient::getServerVersion(),
  244. * CASClient::getServerHostname(), CASClient::getServerPort() and CASClient::getServerURI().
  245. *
  246. * The other fields are written and read by CASClient::getServerBaseURL(),
  247. * CASClient::getServerLoginURL(), CASClient::getServerServiceValidateURL(),
  248. * CASClient::getServerProxyValidateURL() and CASClient::getServerLogoutURL().
  249. *
  250. * @hideinitializer
  251. * @private
  252. */
  253. var $_server = array('version' => - 1, 'hostname' => 'none', 'port' => - 1, 'uri' => 'none');
  254. /**
  255. * This method is used to retrieve the version of the CAS server.
  256. * @return the version of the CAS server.
  257. * @private
  258. */
  259. function getServerVersion()
  260. {
  261. return $this->_server['version'];
  262. }
  263. /**
  264. * This method is used to retrieve the hostname of the CAS server.
  265. * @return the hostname of the CAS server.
  266. * @private
  267. */
  268. function getServerHostname()
  269. {
  270. return $this->_server['hostname'];
  271. }
  272. /**
  273. * This method is used to retrieve the port of the CAS server.
  274. * @return the port of the CAS server.
  275. * @private
  276. */
  277. function getServerPort()
  278. {
  279. return $this->_server['port'];
  280. }
  281. /**
  282. * This method is used to retrieve the URI of the CAS server.
  283. * @return a URI.
  284. * @private
  285. */
  286. function getServerURI()
  287. {
  288. return $this->_server['uri'];
  289. }
  290. /**
  291. * This method is used to retrieve the base URL of the CAS server.
  292. * @return a URL.
  293. * @private
  294. */
  295. function getServerBaseURL()
  296. {
  297. // the URL is build only when needed
  298. if (empty($this->_server['base_url']))
  299. {
  300. $this->_server['base_url'] = 'https://' . $this->getServerHostname();
  301. if ($this->getServerPort() != 443)
  302. {
  303. $this->_server['base_url'] .= ':' . $this->getServerPort();
  304. }
  305. $this->_server['base_url'] .= $this->getServerURI();
  306. }
  307. return $this->_server['base_url'];
  308. }
  309. /**
  310. * This method is used to retrieve the login URL of the CAS server.
  311. * @param $gateway true to check authentication, false to force it
  312. * @param $renew true to force the authentication with the CAS server
  313. * NOTE : It is recommended that CAS implementations ignore the
  314. "gateway" parameter if "renew" is set
  315. * @return a URL.
  316. * @private
  317. */
  318. function getServerLoginURL($gateway = false, $renew = false)
  319. {
  320. phpCAS :: traceBegin();
  321. // the URL is build only when needed
  322. if (empty($this->_server['login_url']))
  323. {
  324. $this->_server['login_url'] = $this->getServerBaseURL();
  325. $this->_server['login_url'] .= 'login?service=';
  326. // $this->_server['login_url'] .= preg_replace('/&/','%26',$this->getURL());
  327. $this->_server['login_url'] .= urlencode($this->getURL());
  328. if ($renew)
  329. {
  330. // It is recommended that when the "renew" parameter is set, its value be "true"
  331. $this->_server['login_url'] .= '&renew=true';
  332. }
  333. elseif ($gateway)
  334. {
  335. // It is recommended that when the "gateway" parameter is set, its value be "true"
  336. $this->_server['login_url'] .= '&gateway=true';
  337. }
  338. }
  339. phpCAS :: traceEnd($this->_server['login_url']);
  340. return $this->_server['login_url'];
  341. }
  342. /**
  343. * This method sets the login URL of the CAS server.
  344. * @param $url the login URL
  345. * @private
  346. * @since 0.4.21 by Wyman Chan
  347. */
  348. function setServerLoginURL($url)
  349. {
  350. return $this->_server['login_url'] = $url;
  351. }
  352. /**
  353. * This method sets the serviceValidate URL of the CAS server.
  354. * @param $url the serviceValidate URL
  355. * @private
  356. * @since 1.1.0 by Joachim Fritschi
  357. */
  358. function setServerServiceValidateURL($url)
  359. {
  360. return $this->_server['service_validate_url'] = $url;
  361. }
  362. /**
  363. * This method sets the proxyValidate URL of the CAS server.
  364. * @param $url the proxyValidate URL
  365. * @private
  366. * @since 1.1.0 by Joachim Fritschi
  367. */
  368. function setServerProxyValidateURL($url)
  369. {
  370. return $this->_server['proxy_validate_url'] = $url;
  371. }
  372. /**
  373. * This method sets the samlValidate URL of the CAS server.
  374. * @param $url the samlValidate URL
  375. * @private
  376. * @since 1.1.0 by Joachim Fritschi
  377. */
  378. function setServerSamlValidateURL($url)
  379. {
  380. return $this->_server['saml_validate_url'] = $url;
  381. }
  382. /**
  383. * This method is used to retrieve the service validating URL of the CAS server.
  384. * @return a URL.
  385. * @private
  386. */
  387. function getServerServiceValidateURL()
  388. {
  389. // the URL is build only when needed
  390. if (empty($this->_server['service_validate_url']))
  391. {
  392. switch ($this->getServerVersion())
  393. {
  394. case CAS_VERSION_1_0 :
  395. $this->_server['service_validate_url'] = $this->getServerBaseURL() . 'validate';
  396. break;
  397. case CAS_VERSION_2_0 :
  398. $this->_server['service_validate_url'] = $this->getServerBaseURL() . 'serviceValidate';
  399. break;
  400. }
  401. }
  402. // return $this->_server['service_validate_url'].'?service='.preg_replace('/&/','%26',$this->getURL());
  403. return $this->_server['service_validate_url'] . '?service=' . urlencode($this->getURL());
  404. }
  405. /**
  406. * This method is used to retrieve the SAML validating URL of the CAS server.
  407. * @return a URL.
  408. * @private
  409. */
  410. function getServerSamlValidateURL()
  411. {
  412. phpCAS :: traceBegin();
  413. // the URL is build only when needed
  414. if (empty($this->_server['saml_validate_url']))
  415. {
  416. switch ($this->getServerVersion())
  417. {
  418. case SAML_VERSION_1_1 :
  419. $this->_server['saml_validate_url'] = $this->getServerBaseURL() . 'samlValidate';
  420. break;
  421. }
  422. }
  423. phpCAS :: traceEnd($this->_server['saml_validate_url'] . '?TARGET=' . urlencode($this->getURL()));
  424. return $this->_server['saml_validate_url'] . '?TARGET=' . urlencode($this->getURL());
  425. }
  426. /**
  427. * This method is used to retrieve the proxy validating URL of the CAS server.
  428. * @return a URL.
  429. * @private
  430. */
  431. function getServerProxyValidateURL()
  432. {
  433. // the URL is build only when needed
  434. if (empty($this->_server['proxy_validate_url']))
  435. {
  436. switch ($this->getServerVersion())
  437. {
  438. case CAS_VERSION_1_0 :
  439. $this->_server['proxy_validate_url'] = '';
  440. break;
  441. case CAS_VERSION_2_0 :
  442. $this->_server['proxy_validate_url'] = $this->getServerBaseURL() . 'proxyValidate';
  443. break;
  444. }
  445. }
  446. // return $this->_server['proxy_validate_url'].'?service='.preg_replace('/&/','%26',$this->getURL());
  447. return $this->_server['proxy_validate_url'] . '?service=' . urlencode($this->getURL());
  448. }
  449. /**
  450. * This method is used to retrieve the proxy URL of the CAS server.
  451. * @return a URL.
  452. * @private
  453. */
  454. function getServerProxyURL()
  455. {
  456. // the URL is build only when needed
  457. if (empty($this->_server['proxy_url']))
  458. {
  459. switch ($this->getServerVersion())
  460. {
  461. case CAS_VERSION_1_0 :
  462. $this->_server['proxy_url'] = '';
  463. break;
  464. case CAS_VERSION_2_0 :
  465. $this->_server['proxy_url'] = $this->getServerBaseURL() . 'proxy';
  466. break;
  467. }
  468. }
  469. return $this->_server['proxy_url'];
  470. }
  471. /**
  472. * This method is used to retrieve the logout URL of the CAS server.
  473. * @return a URL.
  474. * @private
  475. */
  476. function getServerLogoutURL()
  477. {
  478. // the URL is build only when needed
  479. if (empty($this->_server['logout_url']))
  480. {
  481. $this->_server['logout_url'] = $this->getServerBaseURL() . 'logout';
  482. }
  483. return $this->_server['logout_url'];
  484. }
  485. /**
  486. * This method sets the logout URL of the CAS server.
  487. * @param $url the logout URL
  488. * @private
  489. * @since 0.4.21 by Wyman Chan
  490. */
  491. function setServerLogoutURL($url)
  492. {
  493. return $this->_server['logout_url'] = $url;
  494. }
  495. /**
  496. * An array to store extra curl options.
  497. */
  498. var $_curl_options = array();
  499. /**
  500. * This method is used to set additional user curl options.
  501. */
  502. function setExtraCurlOption($key, $value)
  503. {
  504. $this->_curl_options[$key] = $value;
  505. }
  506. /**
  507. * This method checks to see if the request is secured via HTTPS
  508. * @return true if https, false otherwise
  509. * @private
  510. */
  511. function isHttps()
  512. {
  513. //if ( isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) ) {
  514. //0.4.24 by Hinnack
  515. if (isset($_SERVER['HTTPS']) && ! empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
  516. {
  517. return true;
  518. }
  519. else
  520. {
  521. return false;
  522. }
  523. }
  524. // ########################################################################
  525. // CONSTRUCTOR
  526. // ########################################################################
  527. /**
  528. * CASClient constructor.
  529. *
  530. * @param $server_version the version of the CAS server
  531. * @param $proxy TRUE if the CAS client is a CAS proxy, FALSE otherwise
  532. * @param $server_hostname the hostname of the CAS server
  533. * @param $server_port the port the CAS server is running on
  534. * @param $server_uri the URI the CAS server is responding on
  535. * @param $start_session Have phpCAS start PHP sessions (default true)
  536. *
  537. * @return a newly created CASClient object
  538. *
  539. * @public
  540. */
  541. function __construct($server_version, $proxy, $server_hostname, $server_port, $server_uri, $start_session = true)
  542. {
  543. phpCAS :: traceBegin();
  544. // the redirect header() call and DOM parsing code from domxml-php4-php5.php won't work in PHP4 compatibility mode
  545. if (version_compare(PHP_VERSION, '5', '>=') && ini_get('zend.ze1_compatibility_mode'))
  546. {
  547. phpCAS :: error('phpCAS cannot support zend.ze1_compatibility_mode. Sorry.');
  548. }
  549. $this->_start_session = $start_session;
  550. if ($this->_start_session && session_id() !== "")
  551. {
  552. phpCAS :: error("Another session was started before phpcas. Either disable the session" . " handling for phpcas in the client() call or modify your application to leave" . " session handling to phpcas");
  553. }
  554. // skip Session Handling for logout requests and if don't want it'
  555. if ($start_session && ! $this->isLogoutRequest())
  556. {
  557. phpCAS :: trace("Starting a new session");
  558. session_start();
  559. }
  560. // are we in proxy mode ?
  561. $this->_proxy = $proxy;
  562. //check version
  563. switch ($server_version)
  564. {
  565. case CAS_VERSION_1_0 :
  566. if ($this->isProxy())
  567. phpCAS :: error('CAS proxies are not supported in CAS ' . $server_version);
  568. break;
  569. case CAS_VERSION_2_0 :
  570. break;
  571. case SAML_VERSION_1_1 :
  572. break;
  573. default :
  574. phpCAS :: error('this version of CAS (`' . $server_version . '\') is not supported by phpCAS ' . phpCAS :: getVersion());
  575. }
  576. $this->_server['version'] = $server_version;
  577. // check hostname
  578. if (empty($server_hostname) || ! preg_match('/[\.\d\-abcdefghijklmnopqrstuvwxyz]*/', $server_hostname))
  579. {
  580. phpCAS :: error('bad CAS server hostname (`' . $server_hostname . '\')');
  581. }
  582. $this->_server['hostname'] = $server_hostname;
  583. // check port
  584. if ($server_port == 0 || ! is_int($server_port))
  585. {
  586. phpCAS :: error('bad CAS server port (`' . $server_hostname . '\')');
  587. }
  588. $this->_server['port'] = $server_port;
  589. // check URI
  590. if (! preg_match('/[\.\d\-_abcdefghijklmnopqrstuvwxyz\/]*/', $server_uri))
  591. {
  592. phpCAS :: error('bad CAS server URI (`' . $server_uri . '\')');
  593. }
  594. // add leading and trailing `/' and remove doubles
  595. $server_uri = preg_replace('/\/\//', '/', '/' . $server_uri . '/');
  596. $this->_server['uri'] = $server_uri;
  597. // set to callback mode if PgtIou and PgtId CGI GET parameters are provided
  598. if ($this->isProxy())
  599. {
  600. $this->setCallbackMode(! empty($_GET['pgtIou']) && ! empty($_GET['pgtId']));
  601. }
  602. if ($this->isCallbackMode())
  603. {
  604. //callback mode: check that phpCAS is secured
  605. if (! $this->isHttps())
  606. {
  607. phpCAS :: error('CAS proxies must be secured to use phpCAS; PGT\'s will not be received from the CAS server');
  608. }
  609. }
  610. else
  611. {
  612. //normal mode: get ticket and remove it from CGI parameters for developpers
  613. $ticket = (isset($_GET['ticket']) ? $_GET['ticket'] : null);
  614. switch ($this->getServerVersion())
  615. {
  616. case CAS_VERSION_1_0 : // check for a Service Ticket
  617. if (preg_match('/^ST-/', $ticket))
  618. {
  619. phpCAS :: trace('ST \'' . $ticket . '\' found');
  620. //ST present
  621. $this->setST($ticket);
  622. //ticket has been taken into account, unset it to hide it to applications
  623. unset($_GET['ticket']);
  624. }
  625. else
  626. if (! empty($ticket))
  627. {
  628. //ill-formed ticket, halt
  629. phpCAS :: error('ill-formed ticket found in the URL (ticket=`' . htmlentities($ticket) . '\')');
  630. }
  631. break;
  632. case CAS_VERSION_2_0 : // check for a Service or Proxy Ticket
  633. if (preg_match('/^[SP]T-/', $ticket))
  634. {
  635. phpCAS :: trace('ST or PT \'' . $ticket . '\' found');
  636. $this->setPT($ticket);
  637. unset($_GET['ticket']);
  638. }
  639. else
  640. if (! empty($ticket))
  641. {
  642. //ill-formed ticket, halt
  643. phpCAS :: error('ill-formed ticket found in the URL (ticket=`' . htmlentities($ticket) . '\')');
  644. }
  645. break;
  646. case SAML_VERSION_1_1 : // SAML just does Service Tickets
  647. if (preg_match('/^[SP]T-/', $ticket))
  648. {
  649. phpCAS :: trace('SA \'' . $ticket . '\' found');
  650. $this->setSA($ticket);
  651. unset($_GET['ticket']);
  652. }
  653. else
  654. if (! empty($ticket))
  655. {
  656. //ill-formed ticket, halt
  657. phpCAS :: error('ill-formed ticket found in the URL (ticket=`' . htmlentities($ticket) . '\')');
  658. }
  659. break;
  660. }
  661. }
  662. phpCAS :: traceEnd();
  663. }
  664. /** @} */
  665. // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  666. // XX XX
  667. // XX Session Handling XX
  668. // XX XX
  669. // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  670. /**
  671. * A variable to whether phpcas will use its own session handling. Default = true
  672. * @hideinitializer
  673. * @private
  674. */
  675. var $_start_session = true;
  676. function setStartSession($session)
  677. {
  678. $this->_start_session = session;
  679. }
  680. function getStartSession($session)
  681. {
  682. $this->_start_session = session;
  683. }
  684. /**
  685. * Renaming the session
  686. */
  687. function renameSession($ticket)
  688. {
  689. phpCAS :: traceBegin();
  690. if ($this->_start_session)
  691. {
  692. if (! empty($this->_user))
  693. {
  694. $old_session = $_SESSION;
  695. session_destroy();
  696. // set up a new session, of name based on the ticket
  697. $session_id = preg_replace('/[^\w]/', '', $ticket);
  698. phpCAS :: trace("Session ID: " . $session_id);
  699. session_id($session_id);
  700. session_start();
  701. phpCAS :: trace("Restoring old session vars");
  702. $_SESSION = $old_session;
  703. }
  704. else
  705. {
  706. phpCAS :: error('Session should only be renamed after successfull authentication');
  707. }
  708. }
  709. else
  710. {
  711. phpCAS :: trace("Skipping session rename since phpCAS is not handling the session.");
  712. }
  713. phpCAS :: traceEnd();
  714. }
  715. // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  716. // XX XX
  717. // XX AUTHENTICATION XX
  718. // XX XX
  719. // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  720. /**
  721. * @addtogroup internalAuthentication
  722. * @{
  723. */
  724. /**
  725. * The Authenticated user. Written by CASClient::setUser(), read by CASClient::getUser().
  726. * @attention client applications should use phpCAS::getUser().
  727. *
  728. * @hideinitializer
  729. * @private
  730. */
  731. var $_user = '';
  732. /**
  733. * This method sets the CAS user's login name.
  734. *
  735. * @param $user the login name of the authenticated user.
  736. *
  737. * @private
  738. */
  739. function setUser($user)
  740. {
  741. $this->_user = $user;
  742. }
  743. /**
  744. * This method returns the CAS user's login name.
  745. * @warning should be called only after CASClient::forceAuthentication() or
  746. * CASClient::isAuthenticated(), otherwise halt with an error.
  747. *
  748. * @return the login name of the authenticated user
  749. */
  750. function getUser()
  751. {
  752. if (empty($this->_user))
  753. {
  754. phpCAS :: error('this method should be used only after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
  755. }
  756. return $this->_user;
  757. }
  758. /***********************************************************************************************************************
  759. * Atrributes section
  760. *
  761. * @author Matthias Crauwels <matthias.crauwels@ugent.be>, Ghent University, Belgium
  762. *
  763. ***********************************************************************************************************************/
  764. /**
  765. * The Authenticated users attributes. Written by CASClient::setAttributes(), read by CASClient::getAttributes().
  766. * @attention client applications should use phpCAS::getAttributes().
  767. *
  768. * @hideinitializer
  769. * @private
  770. */
  771. var $_attributes = array();
  772. function setAttributes($attributes)
  773. {
  774. $this->_attributes = $attributes;
  775. }
  776. function getAttributes()
  777. {
  778. if (empty($this->_user))
  779. { // if no user is set, there shouldn't be any attributes also...
  780. phpCAS :: error('this method should be used only after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
  781. }
  782. return $this->_attributes;
  783. }
  784. function hasAttributes()
  785. {
  786. return ! empty($this->_attributes);
  787. }
  788. function hasAttribute($key)
  789. {
  790. return (is_array($this->_attributes) && array_key_exists($key, $this->_attributes));
  791. }
  792. function getAttribute($key)
  793. {
  794. if ($this->hasAttribute($key))
  795. {
  796. return $this->_attributes[$key];
  797. }
  798. }
  799. /**
  800. * This method is called to renew the authentication of the user
  801. * If the user is authenticated, renew the connection
  802. * If not, redirect to CAS
  803. * @public
  804. */
  805. function renewAuthentication()
  806. {
  807. phpCAS :: traceBegin();
  808. // Either way, the user is authenticated by CAS
  809. if (isset($_SESSION['phpCAS']['auth_checked']))
  810. unset($_SESSION['phpCAS']['auth_checked']);
  811. if ($this->isAuthenticated())
  812. {
  813. phpCAS :: trace('user already authenticated; renew');
  814. $this->redirectToCas(false, true);
  815. }
  816. else
  817. {
  818. $this->redirectToCas();
  819. }
  820. phpCAS :: traceEnd();
  821. }
  822. /**
  823. * This method is called to be sure that the user is authenticated. When not
  824. * authenticated, halt by redirecting to the CAS server; otherwise return TRUE.
  825. * @return TRUE when the user is authenticated; otherwise halt.
  826. * @public
  827. */
  828. function forceAuthentication()
  829. {
  830. phpCAS :: traceBegin();
  831. if ($this->isAuthenticated())
  832. {
  833. // the user is authenticated, nothing to be done.
  834. phpCAS :: trace('no need to authenticate');
  835. $res = TRUE;
  836. }
  837. else
  838. {
  839. // the user is not authenticated, redirect to the CAS server
  840. if (isset($_SESSION['phpCAS']['auth_checked']))
  841. {
  842. unset($_SESSION['phpCAS']['auth_checked']);
  843. }
  844. $this->redirectToCas(FALSE/* no gateway */);
  845. // never reached
  846. $res = FALSE;
  847. }
  848. phpCAS :: traceEnd($res);
  849. return $res;
  850. }
  851. /**
  852. * An integer that gives the number of times authentication will be cached before rechecked.
  853. *
  854. * @hideinitializer
  855. * @private
  856. */
  857. var $_cache_times_for_auth_recheck = 0;
  858. /**
  859. * Set the number of times authentication will be cached before rechecked.
  860. *
  861. * @param $n an integer.
  862. *
  863. * @public
  864. */
  865. function setCacheTimesForAuthRecheck($n)
  866. {
  867. $this->_cache_times_for_auth_recheck = $n;
  868. }
  869. /**
  870. * This method is called to check whether the user is authenticated or not.
  871. * @return TRUE when the user is authenticated, FALSE otherwise.
  872. * @public
  873. */
  874. function checkAuthentication()
  875. {
  876. phpCAS :: traceBegin();
  877. if ($this->isAuthenticated())
  878. {
  879. phpCAS :: trace('user is authenticated');
  880. $res = TRUE;
  881. }
  882. else
  883. if (isset($_SESSION['phpCAS']['auth_checked']))
  884. {
  885. // the previous request has redirected the client to the CAS server with gateway=true
  886. unset($_SESSION['phpCAS']['auth_checked']);
  887. $res = FALSE;
  888. }
  889. else
  890. {
  891. // $_SESSION['phpCAS']['auth_checked'] = true;
  892. // $this->redirectToCas(TRUE/* gateway */);
  893. // // never reached
  894. // $res = FALSE;
  895. // avoid a check against CAS on every request
  896. if (! isset($_SESSION['phpCAS']['unauth_count']))
  897. $_SESSION['phpCAS']['unauth_count'] = - 2; // uninitialized
  898. if (($_SESSION['phpCAS']['unauth_count'] != - 2 && $this->_cache_times_for_auth_recheck == - 1) || ($_SESSION['phpCAS']['unauth_count'] >= 0 && $_SESSION['phpCAS']['unauth_count'] < $this->_cache_times_for_auth_recheck))
  899. {
  900. $res = FALSE;
  901. if ($this->_cache_times_for_auth_recheck != - 1)
  902. {
  903. $_SESSION['phpCAS']['unauth_count'] ++;
  904. phpCAS :: trace('user is not authenticated (cached for ' . $_SESSION['phpCAS']['unauth_count'] . ' times of ' . $this->_cache_times_for_auth_recheck . ')');
  905. }
  906. else
  907. {
  908. phpCAS :: trace('user is not authenticated (cached for until login pressed)');
  909. }
  910. }
  911. else
  912. {
  913. $_SESSION['phpCAS']['unauth_count'] = 0;
  914. $_SESSION['phpCAS']['auth_checked'] = true;
  915. phpCAS :: trace('user is not authenticated (cache reset)');
  916. $this->redirectToCas(TRUE/* gateway */);
  917. // never reached
  918. $res = FALSE;
  919. }
  920. }
  921. phpCAS :: traceEnd($res);
  922. return $res;
  923. }
  924. /**
  925. * This method is called to check if the user is authenticated (previously or by
  926. * tickets given in the URL).
  927. *
  928. * @return TRUE when the user is authenticated. Also may redirect to the same URL without the ticket.
  929. *
  930. * @public
  931. */
  932. function isAuthenticated()
  933. {
  934. phpCAS :: traceBegin();
  935. $res = FALSE;
  936. $validate_url = '';
  937. if ($this->wasPreviouslyAuthenticated())
  938. {
  939. if ($this->hasST() || $this->hasPT() || $this->hasSA())
  940. {
  941. // User has a additional ticket but was already authenticated
  942. phpCAS :: trace('ticket was present and will be discarded, use renewAuthenticate()');
  943. header('Location: ' . $this->getURL());
  944. phpCAS :: log("Prepare redirect to remove ticket: " . $this->getURL());
  945. phpCAS :: traceExit();
  946. exit();
  947. }
  948. else
  949. {
  950. // the user has already (previously during the session) been
  951. // authenticated, nothing to be done.
  952. phpCAS :: trace('user was already authenticated, no need to look for tickets');
  953. $res = TRUE;
  954. }
  955. }
  956. else
  957. {
  958. if ($this->hasST())
  959. {
  960. // if a Service Ticket was given, validate it
  961. phpCAS :: trace('ST `' . $this->getST() . '\' is present');
  962. $this->validateST($validate_url, $text_response, $tree_response); // if it fails, it halts
  963. phpCAS :: trace('ST `' . $this->getST() . '\' was validated');
  964. if ($this->isProxy())
  965. {
  966. $this->validatePGT($validate_url, $text_response, $tree_response); // idem
  967. phpCAS :: trace('PGT `' . $this->getPGT() . '\' was validated');
  968. $_SESSION['phpCAS']['pgt'] = $this->getPGT();
  969. }
  970. $_SESSION['phpCAS']['user'] = $this->getUser();
  971. $res = TRUE;
  972. }
  973. elseif ($this->hasPT())
  974. {
  975. // if a Proxy Ticket was given, validate it
  976. phpCAS :: trace('PT `' . $this->getPT() . '\' is present');
  977. $this->validatePT($validate_url, $text_response, $tree_response); // note: if it fails, it halts
  978. phpCAS :: trace('PT `' . $this->getPT() . '\' was validated');
  979. if ($this->isProxy())
  980. {
  981. $this->validatePGT($validate_url, $text_response, $tree_response); // idem
  982. phpCAS :: trace('PGT `' . $this->getPGT() . '\' was validated');
  983. $_SESSION['phpCAS']['pgt'] = $this->getPGT();
  984. }
  985. $_SESSION['phpCAS']['user'] = $this->getUser();
  986. $res = TRUE;
  987. }
  988. elseif ($this->hasSA())
  989. {
  990. // if we have a SAML ticket, validate it.
  991. phpCAS :: trace('SA `' . $this->getSA() . '\' is present');
  992. $this->validateSA($validate_url, $text_response, $tree_response); // if it fails, it halts
  993. phpCAS :: trace('SA `' . $this->getSA() . '\' was validated');
  994. $_SESSION['phpCAS']['user'] = $this->getUser();
  995. $_SESSION['phpCAS']['attributes'] = $this->getAttributes();
  996. $res = TRUE;
  997. }
  998. else
  999. {
  1000. // no ticket given, not authenticated
  1001. phpCAS :: trace('no ticket found');
  1002. }
  1003. if ($res)
  1004. {
  1005. // 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)
  1006. // most of the checks and errors should have been made now, so we're safe for redirect without masking error messages.
  1007. // remove the ticket as a security precaution to prevent a ticket in the HTTP_REFERRER
  1008. header('Location: ' . $this->getURL());
  1009. phpCAS :: log("Prepare redirect to : " . $this->getURL());
  1010. phpCAS :: traceExit();
  1011. exit();
  1012. }
  1013. }
  1014. phpCAS :: traceEnd($res);
  1015. return $res;
  1016. }
  1017. /**
  1018. * This method tells if the current session is authenticated.
  1019. * @return true if authenticated based soley on $_SESSION variable
  1020. * @since 0.4.22 by Brendan Arnold
  1021. */
  1022. function isSessionAuthenticated()
  1023. {
  1024. return ! empty($_SESSION['phpCAS']['user']);
  1025. }
  1026. /**
  1027. * This method tells if the user has already been (previously) authenticated
  1028. * by looking into the session variables.
  1029. *
  1030. * @note This function switches to callback mode when needed.
  1031. *
  1032. * @return TRUE when the user has already been authenticated; FALSE otherwise.
  1033. *
  1034. * @private
  1035. */
  1036. function wasPreviouslyAuthenticated()
  1037. {
  1038. phpCAS :: traceBegin();
  1039. if ($this->isCallbackMode())
  1040. {
  1041. $this->callback();
  1042. }
  1043. $auth = FALSE;
  1044. if ($this->isProxy())
  1045. {
  1046. // CAS proxy: username and PGT must be present
  1047. if ($this->isSessionAuthenticated() && ! empty($_SESSION['phpCAS']['pgt']))
  1048. {
  1049. // authentication already done
  1050. $this->setUser($_SESSION['phpCAS']['user']);
  1051. $this->setPGT($_SESSION['phpCAS']['pgt']);
  1052. phpCAS :: trace('user = `' . $_SESSION['phpCAS']['user'] . '\', PGT = `' . $_SESSION['phpCAS']['pgt'] . '\'');
  1053. $auth = TRUE;
  1054. }
  1055. elseif ($this->isSessionAuthenticated() && empty($_SESSION['phpCAS']['pgt']))
  1056. {
  1057. // these two variables should be empty or not empty at the same time
  1058. phpCAS :: trace('username found (`' . $_SESSION['phpCAS']['user'] . '\') but PGT is empty');
  1059. // unset all tickets to enforce authentication
  1060. unset($_SESSION['phpCAS']);
  1061. $this->setST('');
  1062. $this->setPT('');
  1063. }
  1064. elseif (! $this->isSessionAuthenticated() && ! empty($_SESSION['phpCAS']['pgt']))
  1065. {
  1066. // these two variables should be empty or not empty at the same time
  1067. phpCAS :: trace('PGT found (`' . $_SESSION['phpCAS']['pgt'] . '\') but username is empty');
  1068. // unset all tickets to enforce authentication
  1069. unset($_SESSION['phpCAS']);
  1070. $this->setST('');
  1071. $this->setPT('');
  1072. }
  1073. else
  1074. {
  1075. phpCAS :: trace('neither user not PGT found');
  1076. }
  1077. }
  1078. else
  1079. {
  1080. // `simple' CAS client (not a proxy): username must be present
  1081. if ($this->isSessionAuthenticated())
  1082. {
  1083. // authentication already done
  1084. $this->setUser($_SESSION['phpCAS']['user']);
  1085. if (isset($_SESSION['phpCAS']['attributes']))
  1086. {
  1087. $this->setAttributes($_SESSION['phpCAS']['attributes']);
  1088. }
  1089. phpCAS :: trace('user = `' . $_SESSION['phpCAS']['user'] . '\'');
  1090. $auth = TRUE;
  1091. }
  1092. else
  1093. {
  1094. phpCAS :: trace('no user found');
  1095. }
  1096. }
  1097. phpCAS :: traceEnd($auth);
  1098. return $auth;
  1099. }
  1100. /**
  1101. * This method is used to redirect the client to the CAS server.
  1102. * It is used by CASClient::forceAuthentication() and CASClient::checkAuthentication().
  1103. * @param $gateway true to check authentication, false to force it
  1104. * @param $renew true to force the authentication with the CAS server
  1105. * @public
  1106. */
  1107. function redirectToCas($gateway = false, $renew = false)
  1108. {
  1109. phpCAS :: traceBegin();
  1110. $cas_url = $this->getServerLoginURL($gateway, $renew);
  1111. header('Location: ' . $cas_url);
  1112. phpCAS :: log("Redirect to : " . $cas_url);
  1113. $this->printHTMLHeader($this->getString(CAS_STR_AUTHENTICATION_WANTED));
  1114. printf('<p>' . $this->getString(CAS_STR_SHOULD_HAVE_BEEN_REDIRECTED) . '</p>', $cas_url);
  1115. $this->printHTMLFooter();
  1116. phpCAS :: traceExit();
  1117. exit();
  1118. }
  1119. /**
  1120. * This method is used to logout from CAS.
  1121. * @params $params an array that contains the optional url and service parameters that will be passed to the CAS server
  1122. * @public
  1123. */
  1124. function logout($params)
  1125. {
  1126. phpCAS :: traceBegin();
  1127. $cas_url = $this->getServerLogoutURL();
  1128. $paramSeparator = '?';
  1129. if (isset($params['url']))
  1130. {
  1131. $cas_url = $cas_url . $paramSeparator . "url=" . urlencode($params['url']);
  1132. $paramSeparator = '&';
  1133. }
  1134. if (isset($params['service']))
  1135. {
  1136. $cas_url = $cas_url . $paramSeparator . "service=" . urlencode($params['service']);
  1137. }
  1138. header('Location: ' . $cas_url);
  1139. phpCAS :: log("Prepare redirect to : " . $cas_url);
  1140. session_unset();
  1141. session_destroy();
  1142. $this->printHTMLHeader($this->getString(CAS_STR_LOGOUT));
  1143. printf('<p>' . $this->getString(CAS_STR_SHOULD_HAVE_BEEN_REDIRECTED) . '</p>', $cas_url);
  1144. $this->printHTMLFooter();
  1145. phpCAS :: traceExit();
  1146. exit();
  1147. }
  1148. /**
  1149. * @return true if the current request is a logout request.
  1150. * @private
  1151. */
  1152. function isLogoutRequest()
  1153. {
  1154. return ! empty($_POST['logoutRequest']);
  1155. }
  1156. /**
  1157. * @return true if a logout request is allowed.
  1158. * @private
  1159. */
  1160. function isLogoutRequestAllowed()
  1161. {
  1162. }
  1163. /**
  1164. * This method handles logout requests.
  1165. * @param $check_client true to check the client bofore handling the request,
  1166. * false not to perform any access control. True by default.
  1167. * @param $allowed_clients an array of host names allowed to send logout requests.
  1168. * By default, only the CAs server (declared in the constructor) will be allowed.
  1169. * @public
  1170. */
  1171. function handleLogoutRequests($check_client = true, $allowed_clients = false)
  1172. {
  1173. phpCAS :: traceBegin();
  1174. if (! $this->isLogoutRequest())
  1175. {
  1176. phpCAS :: log("Not a logout request");
  1177. phpCAS :: traceEnd();
  1178. return;
  1179. }
  1180. if (! $this->_start_session)
  1181. {
  1182. phpCAS :: log("phpCAS can't handle logout requests if it does not manage the session.");
  1183. }
  1184. phpCAS :: log("Logout requested");
  1185. phpCAS :: log("SAML REQUEST: " . $_POST['logoutRequest']);
  1186. if ($check_client)
  1187. {
  1188. if (! $allowed_clients)
  1189. {
  1190. $allowed_clients = array($this->getServerHostname());
  1191. }
  1192. $client_ip = $_SERVER['REMOTE_ADDR'];
  1193. $client = gethostbyaddr($client_ip);
  1194. phpCAS :: log("Client: " . $client . "/" . $client_ip);
  1195. $allowed = false;
  1196. foreach ($allowed_clients as $allowed_client)
  1197. {
  1198. if (($client == $allowed_client) or ($client_ip == $allowed_client))
  1199. {
  1200. phpCAS :: log("Allowed client '" . $allowed_client . "' matches, logout request is allowed");
  1201. $allowed = true;
  1202. break;
  1203. }
  1204. else
  1205. {
  1206. phpCAS :: log("Allowed client '" . $allowed_client . "' does not match");
  1207. }
  1208. }
  1209. if (! $allowed)
  1210. {
  1211. phpCAS :: error("Unauthorized logout request from client '" . $client . "'");
  1212. printf("Unauthorized!");
  1213. phpCAS :: traceExit();
  1214. exit();
  1215. }
  1216. }
  1217. else
  1218. {
  1219. phpCAS :: log("No access control set");
  1220. }
  1221. // Extract the ticket from the SAML Request
  1222. preg_match("|<samlp:SessionIndex>(.*)</samlp:SessionIndex>|", $_POST['logoutRequest'], $tick, PREG_OFFSET_CAPTURE, 3);
  1223. $wrappedSamlSessionIndex = preg_replace('|<samlp:SessionIndex>|', '', $tick[0][0]);
  1224. $ticket2logout = preg_replace('|</samlp:SessionIndex>|', '', $wrappedSamlSessionIndex);
  1225. phpCAS :: log("Ticket to logout: " . $ticket2logout);
  1226. $session_id = preg_replace('/[^\w]/', '', $ticket2logout);
  1227. phpCAS :: log("Session id: " . $session_id);
  1228. // destroy a possible application session created before phpcas
  1229. if (session_id() !== "")
  1230. {
  1231. session_unset();
  1232. session_destroy();
  1233. }
  1234. // fix session ID
  1235. session_id($session_id);
  1236. $_COOKIE[session_name()] = $session_id;
  1237. $_GET[session_name()] = $session_id;
  1238. // Overwrite session
  1239. session_start();
  1240. session_unset();
  1241. session_destroy();
  1242. printf("Disconnected!");
  1243. phpCAS :: traceExit();
  1244. exit();
  1245. }
  1246. /** @} */
  1247. // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  1248. // XX XX
  1249. // XX BASIC CLIENT FEATURES (CAS 1.0) XX
  1250. // XX XX
  1251. // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  1252. // ########################################################################
  1253. // ST
  1254. // ########################################################################
  1255. /**
  1256. * @addtogroup internalBasic
  1257. * @{
  1258. */
  1259. /**
  1260. * the Service Ticket provided in the URL of the request if present
  1261. * (empty otherwise). Written by CASClient::CASClient(), read by
  1262. * CASClient::getST() and CASClient::hasPGT().
  1263. *
  1264. * @hideinitializer
  1265. * @private
  1266. */
  1267. var $_st = '';
  1268. /**
  1269. * This method returns the Service Ticket provided in the URL of the request.
  1270. * @return The service ticket.
  1271. * @private
  1272. */
  1273. function getST()
  1274. {
  1275. return $this->_st;
  1276. }
  1277. /**
  1278. * This method stores the Service Ticket.
  1279. * @param $st The Service Ticket.
  1280. * @…

Large files files are truncated, but you can click here to view the full file