CAS.php 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035
  1. <?php
  2. /**
  3. * Licensed to Jasig under one or more contributor license
  4. * agreements. See the NOTICE file distributed with this work for
  5. * additional information regarding copyright ownership.
  6. *
  7. * Jasig licenses this file to you under the Apache License,
  8. * Version 2.0 (the "License"); you may not use this file except in
  9. * compliance with the License. You may obtain a copy of the License at:
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. *
  20. *
  21. * Interface class of the phpCAS library
  22. * PHP Version 5
  23. *
  24. * @file CAS/CAS.php
  25. * @category Authentication
  26. * @package PhpCAS
  27. * @author Pascal Aubry <pascal.aubry@univ-rennes1.fr>
  28. * @author Olivier Berger <olivier.berger@it-sudparis.eu>
  29. * @author Brett Bieber <brett.bieber@gmail.com>
  30. * @author Joachim Fritschi <jfritschi@freenet.de>
  31. * @author Adam Franco <afranco@middlebury.edu>
  32. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
  33. * @link https://wiki.jasig.org/display/CASC/phpCAS
  34. * @ingroup public
  35. */
  36. //
  37. // hack by Vangelis Haniotakis to handle the absence of $_SERVER['REQUEST_URI']
  38. // in IIS
  39. //
  40. if (!isset($_SERVER['REQUEST_URI']) && isset($_SERVER['SCRIPT_NAME']) && isset($_SERVER['QUERY_STRING'])) {
  41. $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];
  42. }
  43. // Add a E_USER_DEPRECATED for php versions <= 5.2
  44. if (!defined('E_USER_DEPRECATED')) {
  45. define('E_USER_DEPRECATED', E_USER_NOTICE);
  46. }
  47. // ########################################################################
  48. // CONSTANTS
  49. // ########################################################################
  50. // ------------------------------------------------------------------------
  51. // CAS VERSIONS
  52. // ------------------------------------------------------------------------
  53. /**
  54. * phpCAS version. accessible for the user by phpCAS::getVersion().
  55. */
  56. define('PHPCAS_VERSION', '1.3.7');
  57. /**
  58. * @addtogroup public
  59. * @{
  60. */
  61. /**
  62. * phpCAS supported protocols. accessible for the user by phpCAS::getSupportedProtocols().
  63. */
  64. /**
  65. * CAS version 1.0
  66. */
  67. define("CAS_VERSION_1_0", '1.0');
  68. /*!
  69. * CAS version 2.0
  70. */
  71. define("CAS_VERSION_2_0", '2.0');
  72. /**
  73. * CAS version 3.0
  74. */
  75. define("CAS_VERSION_3_0", '3.0');
  76. // ------------------------------------------------------------------------
  77. // SAML defines
  78. // ------------------------------------------------------------------------
  79. /**
  80. * SAML protocol
  81. */
  82. define("SAML_VERSION_1_1", 'S1');
  83. /**
  84. * XML header for SAML POST
  85. */
  86. define("SAML_XML_HEADER", '<?xml version="1.0" encoding="UTF-8"?>');
  87. /**
  88. * SOAP envelope for SAML POST
  89. */
  90. define("SAML_SOAP_ENV", '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/>');
  91. /**
  92. * SOAP body for SAML POST
  93. */
  94. define("SAML_SOAP_BODY", '<SOAP-ENV:Body>');
  95. /**
  96. * SAMLP request
  97. */
  98. define("SAMLP_REQUEST", '<samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" MajorVersion="1" MinorVersion="1" RequestID="_192.168.16.51.1024506224022" IssueInstant="2002-06-19T17:03:44.022Z">');
  99. define("SAMLP_REQUEST_CLOSE", '</samlp:Request>');
  100. /**
  101. * SAMLP artifact tag (for the ticket)
  102. */
  103. define("SAML_ASSERTION_ARTIFACT", '<samlp:AssertionArtifact>');
  104. /**
  105. * SAMLP close
  106. */
  107. define("SAML_ASSERTION_ARTIFACT_CLOSE", '</samlp:AssertionArtifact>');
  108. /**
  109. * SOAP body close
  110. */
  111. define("SAML_SOAP_BODY_CLOSE", '</SOAP-ENV:Body>');
  112. /**
  113. * SOAP envelope close
  114. */
  115. define("SAML_SOAP_ENV_CLOSE", '</SOAP-ENV:Envelope>');
  116. /**
  117. * SAML Attributes
  118. */
  119. define("SAML_ATTRIBUTES", 'SAMLATTRIBS');
  120. /**
  121. * SAML Attributes
  122. */
  123. define("DEFAULT_ERROR", 'Internal script failure');
  124. /** @} */
  125. /**
  126. * @addtogroup publicPGTStorage
  127. * @{
  128. */
  129. // ------------------------------------------------------------------------
  130. // FILE PGT STORAGE
  131. // ------------------------------------------------------------------------
  132. /**
  133. * Default path used when storing PGT's to file
  134. */
  135. define("CAS_PGT_STORAGE_FILE_DEFAULT_PATH", session_save_path());
  136. /** @} */
  137. // ------------------------------------------------------------------------
  138. // SERVICE ACCESS ERRORS
  139. // ------------------------------------------------------------------------
  140. /**
  141. * @addtogroup publicServices
  142. * @{
  143. */
  144. /**
  145. * phpCAS::service() error code on success
  146. */
  147. define("PHPCAS_SERVICE_OK", 0);
  148. /**
  149. * phpCAS::service() error code when the PT could not retrieve because
  150. * the CAS server did not respond.
  151. */
  152. define("PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE", 1);
  153. /**
  154. * phpCAS::service() error code when the PT could not retrieve because
  155. * the response of the CAS server was ill-formed.
  156. */
  157. define("PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE", 2);
  158. /**
  159. * phpCAS::service() error code when the PT could not retrieve because
  160. * the CAS server did not want to.
  161. */
  162. define("PHPCAS_SERVICE_PT_FAILURE", 3);
  163. /**
  164. * phpCAS::service() error code when the service was not available.
  165. */
  166. define("PHPCAS_SERVICE_NOT_AVAILABLE", 4);
  167. // ------------------------------------------------------------------------
  168. // SERVICE TYPES
  169. // ------------------------------------------------------------------------
  170. /**
  171. * phpCAS::getProxiedService() type for HTTP GET
  172. */
  173. define("PHPCAS_PROXIED_SERVICE_HTTP_GET", 'CAS_ProxiedService_Http_Get');
  174. /**
  175. * phpCAS::getProxiedService() type for HTTP POST
  176. */
  177. define("PHPCAS_PROXIED_SERVICE_HTTP_POST", 'CAS_ProxiedService_Http_Post');
  178. /**
  179. * phpCAS::getProxiedService() type for IMAP
  180. */
  181. define("PHPCAS_PROXIED_SERVICE_IMAP", 'CAS_ProxiedService_Imap');
  182. /** @} */
  183. // ------------------------------------------------------------------------
  184. // LANGUAGES
  185. // ------------------------------------------------------------------------
  186. /**
  187. * @addtogroup publicLang
  188. * @{
  189. */
  190. define("PHPCAS_LANG_ENGLISH", 'CAS_Languages_English');
  191. define("PHPCAS_LANG_FRENCH", 'CAS_Languages_French');
  192. define("PHPCAS_LANG_GREEK", 'CAS_Languages_Greek');
  193. define("PHPCAS_LANG_GERMAN", 'CAS_Languages_German');
  194. define("PHPCAS_LANG_JAPANESE", 'CAS_Languages_Japanese');
  195. define("PHPCAS_LANG_SPANISH", 'CAS_Languages_Spanish');
  196. define("PHPCAS_LANG_CATALAN", 'CAS_Languages_Catalan');
  197. define("PHPCAS_LANG_CHINESE_SIMPLIFIED", 'CAS_Languages_ChineseSimplified');
  198. /** @} */
  199. /**
  200. * @addtogroup internalLang
  201. * @{
  202. */
  203. /**
  204. * phpCAS default language (when phpCAS::setLang() is not used)
  205. */
  206. define("PHPCAS_LANG_DEFAULT", PHPCAS_LANG_ENGLISH);
  207. /** @} */
  208. // ------------------------------------------------------------------------
  209. // DEBUG
  210. // ------------------------------------------------------------------------
  211. /**
  212. * @addtogroup publicDebug
  213. * @{
  214. */
  215. /**
  216. * The default directory for the debug file under Unix.
  217. * @return string directory for the debug file
  218. */
  219. function gettmpdir() {
  220. if (!empty($_ENV['TMP'])) { return realpath($_ENV['TMP']); }
  221. if (!empty($_ENV['TMPDIR'])) { return realpath( $_ENV['TMPDIR']); }
  222. if (!empty($_ENV['TEMP'])) { return realpath( $_ENV['TEMP']); }
  223. return "/tmp";
  224. }
  225. define('DEFAULT_DEBUG_DIR', gettmpdir()."/");
  226. /** @} */
  227. // include the class autoloader
  228. require_once dirname(__FILE__) . '/CAS/Autoload.php';
  229. /**
  230. * The phpCAS class is a simple container for the phpCAS library. It provides CAS
  231. * authentication for web applications written in PHP.
  232. *
  233. * @ingroup public
  234. * @class phpCAS
  235. * @category Authentication
  236. * @package PhpCAS
  237. * @author Pascal Aubry <pascal.aubry@univ-rennes1.fr>
  238. * @author Olivier Berger <olivier.berger@it-sudparis.eu>
  239. * @author Brett Bieber <brett.bieber@gmail.com>
  240. * @author Joachim Fritschi <jfritschi@freenet.de>
  241. * @author Adam Franco <afranco@middlebury.edu>
  242. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
  243. * @link https://wiki.jasig.org/display/CASC/phpCAS
  244. */
  245. class phpCAS
  246. {
  247. /**
  248. * This variable is used by the interface class phpCAS.
  249. *
  250. * @var CAS_Client
  251. * @hideinitializer
  252. */
  253. private static $_PHPCAS_CLIENT;
  254. /**
  255. * @var array
  256. * This variable is used to store where the initializer is called from
  257. * (to print a comprehensive error in case of multiple calls).
  258. *
  259. * @hideinitializer
  260. */
  261. private static $_PHPCAS_INIT_CALL;
  262. /**
  263. * @var array
  264. * This variable is used to store phpCAS debug mode.
  265. *
  266. * @hideinitializer
  267. */
  268. private static $_PHPCAS_DEBUG;
  269. /**
  270. * This variable is used to enable verbose mode
  271. * This pevents debug info to be show to the user. Since it's a security
  272. * feature the default is false
  273. *
  274. * @hideinitializer
  275. */
  276. private static $_PHPCAS_VERBOSE = false;
  277. // ########################################################################
  278. // INITIALIZATION
  279. // ########################################################################
  280. /**
  281. * @addtogroup publicInit
  282. * @{
  283. */
  284. /**
  285. * phpCAS client initializer.
  286. *
  287. * @param string $server_version the version of the CAS server
  288. * @param string $server_hostname the hostname of the CAS server
  289. * @param int $server_port the port the CAS server is running on
  290. * @param string $server_uri the URI the CAS server is responding on
  291. * @param bool $changeSessionID Allow phpCAS to change the session_id (Single
  292. * Sign Out/handleLogoutRequests is based on that change)
  293. *
  294. * @return void a newly created CAS_Client object
  295. * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be
  296. * called, only once, and before all other methods (except phpCAS::getVersion()
  297. * and phpCAS::setDebug()).
  298. */
  299. public static function client($server_version, $server_hostname,
  300. $server_port, $server_uri, $changeSessionID = true
  301. ) {
  302. phpCAS :: traceBegin();
  303. if (is_object(self::$_PHPCAS_CLIENT)) {
  304. phpCAS :: error(self::$_PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . self::$_PHPCAS_INIT_CALL['file'] . ':' . self::$_PHPCAS_INIT_CALL['line'] . ')');
  305. }
  306. // store where the initializer is called from
  307. $dbg = debug_backtrace();
  308. self::$_PHPCAS_INIT_CALL = array (
  309. 'done' => true,
  310. 'file' => $dbg[0]['file'],
  311. 'line' => $dbg[0]['line'],
  312. 'method' => __CLASS__ . '::' . __FUNCTION__
  313. );
  314. // initialize the object $_PHPCAS_CLIENT
  315. try {
  316. self::$_PHPCAS_CLIENT = new CAS_Client(
  317. $server_version, false, $server_hostname, $server_port, $server_uri,
  318. $changeSessionID
  319. );
  320. } catch (Exception $e) {
  321. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  322. }
  323. phpCAS :: traceEnd();
  324. }
  325. /**
  326. * phpCAS proxy initializer.
  327. *
  328. * @param string $server_version the version of the CAS server
  329. * @param string $server_hostname the hostname of the CAS server
  330. * @param int $server_port the port the CAS server is running on
  331. * @param string $server_uri the URI the CAS server is responding on
  332. * @param bool $changeSessionID Allow phpCAS to change the session_id (Single
  333. * Sign Out/handleLogoutRequests is based on that change)
  334. *
  335. * @return void a newly created CAS_Client object
  336. * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be
  337. * called, only once, and before all other methods (except phpCAS::getVersion()
  338. * and phpCAS::setDebug()).
  339. */
  340. public static function proxy($server_version, $server_hostname,
  341. $server_port, $server_uri, $changeSessionID = true
  342. ) {
  343. phpCAS :: traceBegin();
  344. if (is_object(self::$_PHPCAS_CLIENT)) {
  345. phpCAS :: error(self::$_PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . self::$_PHPCAS_INIT_CALL['file'] . ':' . self::$_PHPCAS_INIT_CALL['line'] . ')');
  346. }
  347. // store where the initialzer is called from
  348. $dbg = debug_backtrace();
  349. self::$_PHPCAS_INIT_CALL = array (
  350. 'done' => true,
  351. 'file' => $dbg[0]['file'],
  352. 'line' => $dbg[0]['line'],
  353. 'method' => __CLASS__ . '::' . __FUNCTION__
  354. );
  355. // initialize the object $_PHPCAS_CLIENT
  356. try {
  357. self::$_PHPCAS_CLIENT = new CAS_Client(
  358. $server_version, true, $server_hostname, $server_port, $server_uri,
  359. $changeSessionID
  360. );
  361. } catch (Exception $e) {
  362. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  363. }
  364. phpCAS :: traceEnd();
  365. }
  366. /**
  367. * Answer whether or not the client or proxy has been initialized
  368. *
  369. * @return bool
  370. */
  371. public static function isInitialized ()
  372. {
  373. return (is_object(self::$_PHPCAS_CLIENT));
  374. }
  375. /** @} */
  376. // ########################################################################
  377. // DEBUGGING
  378. // ########################################################################
  379. /**
  380. * @addtogroup publicDebug
  381. * @{
  382. */
  383. /**
  384. * Set/unset debug mode
  385. *
  386. * @param string $filename the name of the file used for logging, or false
  387. * to stop debugging.
  388. *
  389. * @return void
  390. */
  391. public static function setDebug($filename = '')
  392. {
  393. if ($filename != false && gettype($filename) != 'string') {
  394. phpCAS :: error('type mismatched for parameter $dbg (should be false or the name of the log file)');
  395. }
  396. if ($filename === false) {
  397. self::$_PHPCAS_DEBUG['filename'] = false;
  398. } else {
  399. if (empty ($filename)) {
  400. if (preg_match('/^Win.*/', getenv('OS'))) {
  401. if (isset ($_ENV['TMP'])) {
  402. $debugDir = $_ENV['TMP'] . '/';
  403. } else {
  404. $debugDir = '';
  405. }
  406. } else {
  407. $debugDir = DEFAULT_DEBUG_DIR;
  408. }
  409. $filename = $debugDir . 'phpCAS.log';
  410. }
  411. if (empty (self::$_PHPCAS_DEBUG['unique_id'])) {
  412. self::$_PHPCAS_DEBUG['unique_id'] = substr(strtoupper(md5(uniqid(''))), 0, 4);
  413. }
  414. self::$_PHPCAS_DEBUG['filename'] = $filename;
  415. self::$_PHPCAS_DEBUG['indent'] = 0;
  416. phpCAS :: trace('START ('.date("Y-m-d H:i:s").') phpCAS-' . PHPCAS_VERSION . ' ******************');
  417. }
  418. }
  419. /**
  420. * Enable verbose errors messages in the website output
  421. * This is a security relevant since internal status info may leak an may
  422. * help an attacker. Default is therefore false
  423. *
  424. * @param bool $verbose enable verbose output
  425. *
  426. * @return void
  427. */
  428. public static function setVerbose($verbose)
  429. {
  430. if ($verbose === true) {
  431. self::$_PHPCAS_VERBOSE = true;
  432. } else {
  433. self::$_PHPCAS_VERBOSE = false;
  434. }
  435. }
  436. /**
  437. * Show is verbose mode is on
  438. *
  439. * @return bool verbose
  440. */
  441. public static function getVerbose()
  442. {
  443. return self::$_PHPCAS_VERBOSE;
  444. }
  445. /**
  446. * Logs a string in debug mode.
  447. *
  448. * @param string $str the string to write
  449. *
  450. * @return void
  451. * @private
  452. */
  453. public static function log($str)
  454. {
  455. $indent_str = ".";
  456. if (!empty(self::$_PHPCAS_DEBUG['filename'])) {
  457. // Check if file exists and modifiy file permissions to be only
  458. // readable by the webserver
  459. if (!file_exists(self::$_PHPCAS_DEBUG['filename'])) {
  460. touch(self::$_PHPCAS_DEBUG['filename']);
  461. // Chmod will fail on windows
  462. @chmod(self::$_PHPCAS_DEBUG['filename'], 0600);
  463. }
  464. for ($i = 0; $i < self::$_PHPCAS_DEBUG['indent']; $i++) {
  465. $indent_str .= '| ';
  466. }
  467. // allow for multiline output with proper identing. Usefull for
  468. // dumping cas answers etc.
  469. $str2 = str_replace("\n", "\n" . self::$_PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str, $str);
  470. error_log(self::$_PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str . $str2 . "\n", 3, self::$_PHPCAS_DEBUG['filename']);
  471. }
  472. }
  473. /**
  474. * This method is used by interface methods to print an error and where the
  475. * function was originally called from.
  476. *
  477. * @param string $msg the message to print
  478. *
  479. * @return void
  480. * @private
  481. */
  482. public static function error($msg)
  483. {
  484. phpCAS :: traceBegin();
  485. $dbg = debug_backtrace();
  486. $function = '?';
  487. $file = '?';
  488. $line = '?';
  489. if (is_array($dbg)) {
  490. for ($i = 1; $i < sizeof($dbg); $i++) {
  491. if (is_array($dbg[$i]) && isset($dbg[$i]['class']) ) {
  492. if ($dbg[$i]['class'] == __CLASS__) {
  493. $function = $dbg[$i]['function'];
  494. $file = $dbg[$i]['file'];
  495. $line = $dbg[$i]['line'];
  496. }
  497. }
  498. }
  499. }
  500. if (self::$_PHPCAS_VERBOSE) {
  501. echo "<br />\n<b>phpCAS error</b>: <font color=\"FF0000\"><b>" . __CLASS__ . "::" . $function . '(): ' . htmlentities($msg) . "</b></font> in <b>" . $file . "</b> on line <b>" . $line . "</b><br />\n";
  502. } else {
  503. echo "<br />\n<b>Error</b>: <font color=\"FF0000\"><b>". DEFAULT_ERROR ."</b><br />\n";
  504. }
  505. phpCAS :: trace($msg . ' in ' . $file . 'on line ' . $line );
  506. phpCAS :: traceEnd();
  507. throw new CAS_GracefullTerminationException(__CLASS__ . "::" . $function . '(): ' . $msg);
  508. }
  509. /**
  510. * This method is used to log something in debug mode.
  511. *
  512. * @param string $str string to log
  513. *
  514. * @return void
  515. */
  516. public static function trace($str)
  517. {
  518. $dbg = debug_backtrace();
  519. phpCAS :: log($str . ' [' . basename($dbg[0]['file']) . ':' . $dbg[0]['line'] . ']');
  520. }
  521. /**
  522. * This method is used to indicate the start of the execution of a function
  523. * in debug mode.
  524. *
  525. * @return void
  526. */
  527. public static function traceBegin()
  528. {
  529. $dbg = debug_backtrace();
  530. $str = '=> ';
  531. if (!empty ($dbg[1]['class'])) {
  532. $str .= $dbg[1]['class'] . '::';
  533. }
  534. $str .= $dbg[1]['function'] . '(';
  535. if (is_array($dbg[1]['args'])) {
  536. foreach ($dbg[1]['args'] as $index => $arg) {
  537. if ($index != 0) {
  538. $str .= ', ';
  539. }
  540. if (is_object($arg)) {
  541. $str .= get_class($arg);
  542. } else {
  543. $str .= str_replace(array("\r\n", "\n", "\r"), "", var_export($arg, true));
  544. }
  545. }
  546. }
  547. if (isset($dbg[1]['file'])) {
  548. $file = basename($dbg[1]['file']);
  549. } else {
  550. $file = 'unknown_file';
  551. }
  552. if (isset($dbg[1]['line'])) {
  553. $line = $dbg[1]['line'];
  554. } else {
  555. $line = 'unknown_line';
  556. }
  557. $str .= ') [' . $file . ':' . $line . ']';
  558. phpCAS :: log($str);
  559. if (!isset(self::$_PHPCAS_DEBUG['indent'])) {
  560. self::$_PHPCAS_DEBUG['indent'] = 0;
  561. } else {
  562. self::$_PHPCAS_DEBUG['indent']++;
  563. }
  564. }
  565. /**
  566. * This method is used to indicate the end of the execution of a function in
  567. * debug mode.
  568. *
  569. * @param mixed $res the result of the function
  570. *
  571. * @return void
  572. */
  573. public static function traceEnd($res = '')
  574. {
  575. if (empty(self::$_PHPCAS_DEBUG['indent'])) {
  576. self::$_PHPCAS_DEBUG['indent'] = 0;
  577. } else {
  578. self::$_PHPCAS_DEBUG['indent']--;
  579. }
  580. $str = '';
  581. if (is_object($res)) {
  582. $str .= '<= ' . get_class($res);
  583. } else {
  584. $str .= '<= ' . str_replace(array("\r\n", "\n", "\r"), "", var_export($res, true));
  585. }
  586. phpCAS :: log($str);
  587. }
  588. /**
  589. * This method is used to indicate the end of the execution of the program
  590. *
  591. * @return void
  592. */
  593. public static function traceExit()
  594. {
  595. phpCAS :: log('exit()');
  596. while (self::$_PHPCAS_DEBUG['indent'] > 0) {
  597. phpCAS :: log('-');
  598. self::$_PHPCAS_DEBUG['indent']--;
  599. }
  600. }
  601. /** @} */
  602. // ########################################################################
  603. // INTERNATIONALIZATION
  604. // ########################################################################
  605. /**
  606. * @addtogroup publicLang
  607. * @{
  608. */
  609. /**
  610. * This method is used to set the language used by phpCAS.
  611. *
  612. * @param string $lang string representing the language.
  613. *
  614. * @return void
  615. *
  616. * @sa PHPCAS_LANG_FRENCH, PHPCAS_LANG_ENGLISH
  617. * @note Can be called only once.
  618. */
  619. public static function setLang($lang)
  620. {
  621. phpCAS::_validateClientExists();
  622. try {
  623. self::$_PHPCAS_CLIENT->setLang($lang);
  624. } catch (Exception $e) {
  625. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  626. }
  627. }
  628. /** @} */
  629. // ########################################################################
  630. // VERSION
  631. // ########################################################################
  632. /**
  633. * @addtogroup public
  634. * @{
  635. */
  636. /**
  637. * This method returns the phpCAS version.
  638. *
  639. * @return string the phpCAS version.
  640. */
  641. public static function getVersion()
  642. {
  643. return PHPCAS_VERSION;
  644. }
  645. /**
  646. * This method returns supported protocols.
  647. *
  648. * @return array an array of all supported protocols. Use internal protocol name as array key.
  649. */
  650. public static function getSupportedProtocols()
  651. {
  652. $supportedProtocols = array();
  653. $supportedProtocols[CAS_VERSION_1_0] = 'CAS 1.0';
  654. $supportedProtocols[CAS_VERSION_2_0] = 'CAS 2.0';
  655. $supportedProtocols[CAS_VERSION_3_0] = 'CAS 3.0';
  656. $supportedProtocols[SAML_VERSION_1_1] = 'SAML 1.1';
  657. return $supportedProtocols;
  658. }
  659. /** @} */
  660. // ########################################################################
  661. // HTML OUTPUT
  662. // ########################################################################
  663. /**
  664. * @addtogroup publicOutput
  665. * @{
  666. */
  667. /**
  668. * This method sets the HTML header used for all outputs.
  669. *
  670. * @param string $header the HTML header.
  671. *
  672. * @return void
  673. */
  674. public static function setHTMLHeader($header)
  675. {
  676. phpCAS::_validateClientExists();
  677. try {
  678. self::$_PHPCAS_CLIENT->setHTMLHeader($header);
  679. } catch (Exception $e) {
  680. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  681. }
  682. }
  683. /**
  684. * This method sets the HTML footer used for all outputs.
  685. *
  686. * @param string $footer the HTML footer.
  687. *
  688. * @return void
  689. */
  690. public static function setHTMLFooter($footer)
  691. {
  692. phpCAS::_validateClientExists();
  693. try {
  694. self::$_PHPCAS_CLIENT->setHTMLFooter($footer);
  695. } catch (Exception $e) {
  696. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  697. }
  698. }
  699. /** @} */
  700. // ########################################################################
  701. // PGT STORAGE
  702. // ########################################################################
  703. /**
  704. * @addtogroup publicPGTStorage
  705. * @{
  706. */
  707. /**
  708. * This method can be used to set a custom PGT storage object.
  709. *
  710. * @param CAS_PGTStorage_AbstractStorage $storage a PGT storage object that inherits from the
  711. * CAS_PGTStorage_AbstractStorage class
  712. *
  713. * @return void
  714. */
  715. public static function setPGTStorage($storage)
  716. {
  717. phpCAS :: traceBegin();
  718. phpCAS::_validateProxyExists();
  719. try {
  720. self::$_PHPCAS_CLIENT->setPGTStorage($storage);
  721. } catch (Exception $e) {
  722. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  723. }
  724. phpCAS :: traceEnd();
  725. }
  726. /**
  727. * This method is used to tell phpCAS to store the response of the
  728. * CAS server to PGT requests in a database.
  729. *
  730. * @param string $dsn_or_pdo a dsn string to use for creating a PDO
  731. * object or a PDO object
  732. * @param string $username the username to use when connecting to the
  733. * database
  734. * @param string $password the password to use when connecting to the
  735. * database
  736. * @param string $table the table to use for storing and retrieving
  737. * PGT's
  738. * @param string $driver_options any driver options to use when connecting
  739. * to the database
  740. *
  741. * @return void
  742. */
  743. public static function setPGTStorageDb($dsn_or_pdo, $username='',
  744. $password='', $table='', $driver_options=null
  745. ) {
  746. phpCAS :: traceBegin();
  747. phpCAS::_validateProxyExists();
  748. try {
  749. self::$_PHPCAS_CLIENT->setPGTStorageDb($dsn_or_pdo, $username, $password, $table, $driver_options);
  750. } catch (Exception $e) {
  751. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  752. }
  753. phpCAS :: traceEnd();
  754. }
  755. /**
  756. * This method is used to tell phpCAS to store the response of the
  757. * CAS server to PGT requests onto the filesystem.
  758. *
  759. * @param string $path the path where the PGT's should be stored
  760. *
  761. * @return void
  762. */
  763. public static function setPGTStorageFile($path = '')
  764. {
  765. phpCAS :: traceBegin();
  766. phpCAS::_validateProxyExists();
  767. try {
  768. self::$_PHPCAS_CLIENT->setPGTStorageFile($path);
  769. } catch (Exception $e) {
  770. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  771. }
  772. phpCAS :: traceEnd();
  773. }
  774. /** @} */
  775. // ########################################################################
  776. // ACCESS TO EXTERNAL SERVICES
  777. // ########################################################################
  778. /**
  779. * @addtogroup publicServices
  780. * @{
  781. */
  782. /**
  783. * Answer a proxy-authenticated service handler.
  784. *
  785. * @param string $type The service type. One of
  786. * PHPCAS_PROXIED_SERVICE_HTTP_GET; PHPCAS_PROXIED_SERVICE_HTTP_POST;
  787. * PHPCAS_PROXIED_SERVICE_IMAP
  788. *
  789. * @return CAS_ProxiedService
  790. * @throws InvalidArgumentException If the service type is unknown.
  791. */
  792. public static function getProxiedService ($type)
  793. {
  794. phpCAS :: traceBegin();
  795. phpCAS::_validateProxyExists();
  796. try {
  797. $res = self::$_PHPCAS_CLIENT->getProxiedService($type);
  798. } catch (Exception $e) {
  799. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  800. }
  801. phpCAS :: traceEnd();
  802. return $res;
  803. }
  804. /**
  805. * Initialize a proxied-service handler with the proxy-ticket it should use.
  806. *
  807. * @param CAS_ProxiedService $proxiedService Proxied Service Handler
  808. *
  809. * @return void
  810. * @throws CAS_ProxyTicketException If there is a proxy-ticket failure.
  811. * The code of the Exception will be one of:
  812. * PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE
  813. * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE
  814. * PHPCAS_SERVICE_PT_FAILURE
  815. */
  816. public static function initializeProxiedService (CAS_ProxiedService $proxiedService)
  817. {
  818. phpCAS::_validateProxyExists();
  819. try {
  820. self::$_PHPCAS_CLIENT->initializeProxiedService($proxiedService);
  821. } catch (Exception $e) {
  822. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  823. }
  824. }
  825. /**
  826. * This method is used to access an HTTP[S] service.
  827. *
  828. * @param string $url the service to access.
  829. * @param int &$err_code an error code Possible values are
  830. * PHPCAS_SERVICE_OK (on success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE,
  831. * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE, PHPCAS_SERVICE_PT_FAILURE,
  832. * PHPCAS_SERVICE_NOT_AVAILABLE.
  833. * @param string &$output the output of the service (also used to give an
  834. * error message on failure).
  835. *
  836. * @return bool true on success, false otherwise (in this later case,
  837. * $err_code gives the reason why it failed and $output contains an error
  838. * message).
  839. */
  840. public static function serviceWeb($url, & $err_code, & $output)
  841. {
  842. phpCAS :: traceBegin();
  843. phpCAS::_validateProxyExists();
  844. try {
  845. $res = self::$_PHPCAS_CLIENT->serviceWeb($url, $err_code, $output);
  846. } catch (Exception $e) {
  847. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  848. }
  849. phpCAS :: traceEnd($res);
  850. return $res;
  851. }
  852. /**
  853. * This method is used to access an IMAP/POP3/NNTP service.
  854. *
  855. * @param string $url a string giving the URL of the service,
  856. * including the mailing box for IMAP URLs, as accepted by imap_open().
  857. * @param string $service a string giving for CAS retrieve Proxy ticket
  858. * @param string $flags options given to imap_open().
  859. * @param int &$err_code an error code Possible values are
  860. * PHPCAS_SERVICE_OK (on success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE,
  861. * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE, PHPCAS_SERVICE_PT_FAILURE,
  862. * PHPCAS_SERVICE_NOT_AVAILABLE.
  863. * @param string &$err_msg an error message on failure
  864. * @param string &$pt the Proxy Ticket (PT) retrieved from the CAS
  865. * server to access the URL on success, false on error).
  866. *
  867. * @return object|false IMAP stream on success, false otherwise (in this later
  868. * case, $err_code gives the reason why it failed and $err_msg contains an
  869. * error message).
  870. */
  871. public static function serviceMail($url, $service, $flags, & $err_code, & $err_msg, & $pt)
  872. {
  873. phpCAS :: traceBegin();
  874. phpCAS::_validateProxyExists();
  875. try {
  876. $res = self::$_PHPCAS_CLIENT->serviceMail($url, $service, $flags, $err_code, $err_msg, $pt);
  877. } catch (Exception $e) {
  878. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  879. }
  880. phpCAS :: traceEnd($res);
  881. return $res;
  882. }
  883. /** @} */
  884. // ########################################################################
  885. // AUTHENTICATION
  886. // ########################################################################
  887. /**
  888. * @addtogroup publicAuth
  889. * @{
  890. */
  891. /**
  892. * Set the times authentication will be cached before really accessing the
  893. * CAS server in gateway mode:
  894. * - -1: check only once, and then never again (until you pree login)
  895. * - 0: always check
  896. * - n: check every "n" time
  897. *
  898. * @param int $n an integer.
  899. *
  900. * @return void
  901. */
  902. public static function setCacheTimesForAuthRecheck($n)
  903. {
  904. phpCAS::_validateClientExists();
  905. try {
  906. self::$_PHPCAS_CLIENT->setCacheTimesForAuthRecheck($n);
  907. } catch (Exception $e) {
  908. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  909. }
  910. }
  911. /**
  912. * Set a callback function to be run when receiving CAS attributes
  913. *
  914. * The callback function will be passed an $success_elements
  915. * payload of the response (\DOMElement) as its first parameter.
  916. *
  917. * @param string $function Callback function
  918. * @param array $additionalArgs optional array of arguments
  919. *
  920. * @return void
  921. */
  922. public static function setCasAttributeParserCallback($function, array $additionalArgs = array())
  923. {
  924. phpCAS::_validateClientExists();
  925. self::$_PHPCAS_CLIENT->setCasAttributeParserCallback($function, $additionalArgs);
  926. }
  927. /**
  928. * Set a callback function to be run when a user authenticates.
  929. *
  930. * The callback function will be passed a $logoutTicket as its first
  931. * parameter, followed by any $additionalArgs you pass. The $logoutTicket
  932. * parameter is an opaque string that can be used to map the session-id to
  933. * logout request in order to support single-signout in applications that
  934. * manage their own sessions (rather than letting phpCAS start the session).
  935. *
  936. * phpCAS::forceAuthentication() will always exit and forward client unless
  937. * they are already authenticated. To perform an action at the moment the user
  938. * logs in (such as registering an account, performing logging, etc), register
  939. * a callback function here.
  940. *
  941. * @param callable $function Callback function
  942. * @param array $additionalArgs optional array of arguments
  943. *
  944. * @return void
  945. */
  946. public static function setPostAuthenticateCallback ($function, array $additionalArgs = array())
  947. {
  948. phpCAS::_validateClientExists();
  949. self::$_PHPCAS_CLIENT->setPostAuthenticateCallback($function, $additionalArgs);
  950. }
  951. /**
  952. * Set a callback function to be run when a single-signout request is
  953. * received. The callback function will be passed a $logoutTicket as its
  954. * first parameter, followed by any $additionalArgs you pass. The
  955. * $logoutTicket parameter is an opaque string that can be used to map a
  956. * session-id to the logout request in order to support single-signout in
  957. * applications that manage their own sessions (rather than letting phpCAS
  958. * start and destroy the session).
  959. *
  960. * @param callable $function Callback function
  961. * @param array $additionalArgs optional array of arguments
  962. *
  963. * @return void
  964. */
  965. public static function setSingleSignoutCallback ($function, array $additionalArgs = array())
  966. {
  967. phpCAS::_validateClientExists();
  968. self::$_PHPCAS_CLIENT->setSingleSignoutCallback($function, $additionalArgs);
  969. }
  970. /**
  971. * This method is called to check if the user is already authenticated
  972. * locally or has a global cas session. A already existing cas session is
  973. * determined by a cas gateway call.(cas login call without any interactive
  974. * prompt)
  975. *
  976. * @return bool true when the user is authenticated, false when a previous
  977. * gateway login failed or the function will not return if the user is
  978. * redirected to the cas server for a gateway login attempt
  979. */
  980. public static function checkAuthentication()
  981. {
  982. phpCAS :: traceBegin();
  983. phpCAS::_validateClientExists();
  984. $auth = self::$_PHPCAS_CLIENT->checkAuthentication();
  985. // store where the authentication has been checked and the result
  986. self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
  987. phpCAS :: traceEnd($auth);
  988. return $auth;
  989. }
  990. /**
  991. * This method is called to force authentication if the user was not already
  992. * authenticated. If the user is not authenticated, halt by redirecting to
  993. * the CAS server.
  994. *
  995. * @return bool Authentication
  996. */
  997. public static function forceAuthentication()
  998. {
  999. phpCAS :: traceBegin();
  1000. phpCAS::_validateClientExists();
  1001. $auth = self::$_PHPCAS_CLIENT->forceAuthentication();
  1002. // store where the authentication has been checked and the result
  1003. self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
  1004. /* if (!$auth) {
  1005. phpCAS :: trace('user is not authenticated, redirecting to the CAS server');
  1006. self::$_PHPCAS_CLIENT->forceAuthentication();
  1007. } else {
  1008. phpCAS :: trace('no need to authenticate (user `' . phpCAS :: getUser() . '\' is already authenticated)');
  1009. }*/
  1010. phpCAS :: traceEnd();
  1011. return $auth;
  1012. }
  1013. /**
  1014. * This method is called to renew the authentication.
  1015. *
  1016. * @return void
  1017. **/
  1018. public static function renewAuthentication()
  1019. {
  1020. phpCAS :: traceBegin();
  1021. phpCAS::_validateClientExists();
  1022. $auth = self::$_PHPCAS_CLIENT->renewAuthentication();
  1023. // store where the authentication has been checked and the result
  1024. self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
  1025. //self::$_PHPCAS_CLIENT->renewAuthentication();
  1026. phpCAS :: traceEnd();
  1027. }
  1028. /**
  1029. * This method is called to check if the user is authenticated (previously or by
  1030. * tickets given in the URL).
  1031. *
  1032. * @return bool true when the user is authenticated.
  1033. */
  1034. public static function isAuthenticated()
  1035. {
  1036. phpCAS :: traceBegin();
  1037. phpCAS::_validateClientExists();
  1038. // call the isAuthenticated method of the $_PHPCAS_CLIENT object
  1039. $auth = self::$_PHPCAS_CLIENT->isAuthenticated();
  1040. // store where the authentication has been checked and the result
  1041. self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
  1042. phpCAS :: traceEnd($auth);
  1043. return $auth;
  1044. }
  1045. /**
  1046. * Checks whether authenticated based on $_SESSION. Useful to avoid
  1047. * server calls.
  1048. *
  1049. * @return bool true if authenticated, false otherwise.
  1050. * @since 0.4.22 by Brendan Arnold
  1051. */
  1052. public static function isSessionAuthenticated()
  1053. {
  1054. phpCAS::_validateClientExists();
  1055. return (self::$_PHPCAS_CLIENT->isSessionAuthenticated());
  1056. }
  1057. /**
  1058. * This method returns the CAS user's login name.
  1059. *
  1060. * @return string the login name of the authenticated user
  1061. * @warning should only be called after phpCAS::forceAuthentication()
  1062. * or phpCAS::checkAuthentication().
  1063. * */
  1064. public static function getUser()
  1065. {
  1066. phpCAS::_validateClientExists();
  1067. try {
  1068. return self::$_PHPCAS_CLIENT->getUser();
  1069. } catch (Exception $e) {
  1070. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1071. }
  1072. }
  1073. /**
  1074. * Answer attributes about the authenticated user.
  1075. *
  1076. * @warning should only be called after phpCAS::forceAuthentication()
  1077. * or phpCAS::checkAuthentication().
  1078. *
  1079. * @return array
  1080. */
  1081. public static function getAttributes()
  1082. {
  1083. phpCAS::_validateClientExists();
  1084. try {
  1085. return self::$_PHPCAS_CLIENT->getAttributes();
  1086. } catch (Exception $e) {
  1087. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1088. }
  1089. }
  1090. /**
  1091. * Answer true if there are attributes for the authenticated user.
  1092. *
  1093. * @warning should only be called after phpCAS::forceAuthentication()
  1094. * or phpCAS::checkAuthentication().
  1095. *
  1096. * @return bool
  1097. */
  1098. public static function hasAttributes()
  1099. {
  1100. phpCAS::_validateClientExists();
  1101. try {
  1102. return self::$_PHPCAS_CLIENT->hasAttributes();
  1103. } catch (Exception $e) {
  1104. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1105. }
  1106. }
  1107. /**
  1108. * Answer true if an attribute exists for the authenticated user.
  1109. *
  1110. * @param string $key attribute name
  1111. *
  1112. * @return bool
  1113. * @warning should only be called after phpCAS::forceAuthentication()
  1114. * or phpCAS::checkAuthentication().
  1115. */
  1116. public static function hasAttribute($key)
  1117. {
  1118. phpCAS::_validateClientExists();
  1119. try {
  1120. return self::$_PHPCAS_CLIENT->hasAttribute($key);
  1121. } catch (Exception $e) {
  1122. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1123. }
  1124. }
  1125. /**
  1126. * Answer an attribute for the authenticated user.
  1127. *
  1128. * @param string $key attribute name
  1129. *
  1130. * @return mixed string for a single value or an array if multiple values exist.
  1131. * @warning should only be called after phpCAS::forceAuthentication()
  1132. * or phpCAS::checkAuthentication().
  1133. */
  1134. public static function getAttribute($key)
  1135. {
  1136. phpCAS::_validateClientExists();
  1137. try {
  1138. return self::$_PHPCAS_CLIENT->getAttribute($key);
  1139. } catch (Exception $e) {
  1140. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1141. }
  1142. }
  1143. /**
  1144. * Handle logout requests.
  1145. *
  1146. * @param bool $check_client additional safety check
  1147. * @param array $allowed_clients array of allowed clients
  1148. *
  1149. * @return void
  1150. */
  1151. public static function handleLogoutRequests($check_client = true, $allowed_clients = array())
  1152. {
  1153. phpCAS::_validateClientExists();
  1154. return (self::$_PHPCAS_CLIENT->handleLogoutRequests($check_client, $allowed_clients));
  1155. }
  1156. /**
  1157. * This method returns the URL to be used to login.
  1158. *
  1159. * @return string the login URL
  1160. */
  1161. public static function getServerLoginURL()
  1162. {
  1163. phpCAS::_validateClientExists();
  1164. return self::$_PHPCAS_CLIENT->getServerLoginURL();
  1165. }
  1166. /**
  1167. * Set the login URL of the CAS server.
  1168. *
  1169. * @param string $url the login URL
  1170. *
  1171. * @return void
  1172. * @since 0.4.21 by Wyman Chan
  1173. */
  1174. public static function setServerLoginURL($url = '')
  1175. {
  1176. phpCAS :: traceBegin();
  1177. phpCAS::_validateClientExists();
  1178. try {
  1179. self::$_PHPCAS_CLIENT->setServerLoginURL($url);
  1180. } catch (Exception $e) {
  1181. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1182. }
  1183. phpCAS :: traceEnd();
  1184. }
  1185. /**
  1186. * Set the serviceValidate URL of the CAS server.
  1187. * Used for all CAS versions of URL validations.
  1188. * Examples:
  1189. * CAS 1.0 http://www.exemple.com/validate
  1190. * CAS 2.0 http://www.exemple.com/validateURL
  1191. * CAS 3.0 http://www.exemple.com/p3/serviceValidate
  1192. *
  1193. * @param string $url the serviceValidate URL
  1194. *
  1195. * @return void
  1196. */
  1197. public static function setServerServiceValidateURL($url = '')
  1198. {
  1199. phpCAS :: traceBegin();
  1200. phpCAS::_validateClientExists();
  1201. try {
  1202. self::$_PHPCAS_CLIENT->setServerServiceValidateURL($url);
  1203. } catch (Exception $e) {
  1204. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1205. }
  1206. phpCAS :: traceEnd();
  1207. }
  1208. /**
  1209. * Set the proxyValidate URL of the CAS server.
  1210. * Used for all CAS versions of proxy URL validations
  1211. * Examples:
  1212. * CAS 1.0 http://www.exemple.com/
  1213. * CAS 2.0 http://www.exemple.com/proxyValidate
  1214. * CAS 3.0 http://www.exemple.com/p3/proxyValidate
  1215. *
  1216. * @param string $url the proxyValidate URL
  1217. *
  1218. * @return void
  1219. */
  1220. public static function setServerProxyValidateURL($url = '')
  1221. {
  1222. phpCAS :: traceBegin();
  1223. phpCAS::_validateClientExists();
  1224. try {
  1225. self::$_PHPCAS_CLIENT->setServerProxyValidateURL($url);
  1226. } catch (Exception $e) {
  1227. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1228. }
  1229. phpCAS :: traceEnd();
  1230. }
  1231. /**
  1232. * Set the samlValidate URL of the CAS server.
  1233. *
  1234. * @param string $url the samlValidate URL
  1235. *
  1236. * @return void
  1237. */
  1238. public static function setServerSamlValidateURL($url = '')
  1239. {
  1240. phpCAS :: traceBegin();
  1241. phpCAS::_validateClientExists();
  1242. try {
  1243. self::$_PHPCAS_CLIENT->setServerSamlValidateURL($url);
  1244. } catch (Exception $e) {
  1245. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1246. }
  1247. phpCAS :: traceEnd();
  1248. }
  1249. /**
  1250. * This method returns the URL to be used to logout.
  1251. *
  1252. * @return string the URL to use to log out
  1253. */
  1254. public static function getServerLogoutURL()
  1255. {
  1256. phpCAS::_validateClientExists();
  1257. return self::$_PHPCAS_CLIENT->getServerLogoutURL();
  1258. }
  1259. /**
  1260. * Set the logout URL of the CAS server.
  1261. *
  1262. * @param string $url the logout URL
  1263. *
  1264. * @return void
  1265. * @since 0.4.21 by Wyman Chan
  1266. */
  1267. public static function setServerLogoutURL($url = '')
  1268. {
  1269. phpCAS :: traceBegin();
  1270. phpCAS::_validateClientExists();
  1271. try {
  1272. self::$_PHPCAS_CLIENT->setServerLogoutURL($url);
  1273. } catch (Exception $e) {
  1274. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1275. }
  1276. phpCAS :: traceEnd();
  1277. }
  1278. /**
  1279. * This method is used to logout from CAS.
  1280. *
  1281. * @param string $params an array that contains the optional url and
  1282. * service parameters that will be passed to the CAS server
  1283. *
  1284. * @return void
  1285. */
  1286. public static function logout($params = "")
  1287. {
  1288. phpCAS :: traceBegin();
  1289. phpCAS::_validateClientExists();
  1290. $parsedParams = array ();
  1291. if ($params != "") {
  1292. if (is_string($params)) {
  1293. phpCAS :: error('method `phpCAS::logout($url)\' is now deprecated, use `phpCAS::logoutWithUrl($url)\' instead');
  1294. }
  1295. if (!is_array($params)) {
  1296. phpCAS :: error('type mismatched for parameter $params (should be `array\')');
  1297. }
  1298. foreach ($params as $key => $value) {
  1299. if ($key != "service" && $key != "url") {
  1300. phpCAS :: error('only `url\' and `service\' parameters are allowed for method `phpCAS::logout($params)\'');
  1301. }
  1302. $parsedParams[$key] = $value;
  1303. }
  1304. }
  1305. self::$_PHPCAS_CLIENT->logout($parsedParams);
  1306. // never reached
  1307. phpCAS :: traceEnd();
  1308. }
  1309. /**
  1310. * This method is used to logout from CAS. Halts by redirecting to the CAS
  1311. * server.
  1312. *
  1313. * @param string $service a URL that will be transmitted to the CAS server
  1314. *
  1315. * @return void
  1316. */
  1317. public static function logoutWithRedirectService($service)
  1318. {
  1319. phpCAS :: traceBegin();
  1320. phpCAS::_validateClientExists();
  1321. if (!is_string($service)) {
  1322. phpCAS :: error('type mismatched for parameter $service (should be `string\')');
  1323. }
  1324. self::$_PHPCAS_CLIENT->logout(array ( "service" => $service ));
  1325. // never reached
  1326. phpCAS :: traceEnd();
  1327. }
  1328. /**
  1329. * This method is used to logout from CAS. Halts by redirecting to the CAS
  1330. * server.
  1331. *
  1332. * @param string $url a URL that will be transmitted to the CAS server
  1333. *
  1334. * @return void
  1335. * @deprecated The url parameter has been removed from the CAS server as of
  1336. * version 3.3.5.1
  1337. */
  1338. public static function logoutWithUrl($url)
  1339. {
  1340. trigger_error('Function deprecated for cas servers >= 3.3.5.1', E_USER_DEPRECATED);
  1341. phpCAS :: traceBegin();
  1342. if (!is_object(self::$_PHPCAS_CLIENT)) {
  1343. phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
  1344. }
  1345. if (!is_string($url)) {
  1346. phpCAS :: error('type mismatched for parameter $url (should be `string\')');
  1347. }
  1348. self::$_PHPCAS_CLIENT->logout(array ( "url" => $url ));
  1349. // never reached
  1350. phpCAS :: traceEnd();
  1351. }
  1352. /**
  1353. * This method is used to logout from CAS. Halts by redirecting to the CAS
  1354. * server.
  1355. *
  1356. * @param string $service a URL that will be transmitted to the CAS server
  1357. * @param string $url a URL that will be transmitted to the CAS server
  1358. *
  1359. * @return void
  1360. *
  1361. * @deprecated The url parameter has been removed from the CAS server as of
  1362. * version 3.3.5.1
  1363. */
  1364. public static function logoutWithRedirectServiceAndUrl($service, $url)
  1365. {
  1366. trigger_error('Function deprecated for cas servers >= 3.3.5.1', E_USER_DEPRECATED);
  1367. phpCAS :: traceBegin();
  1368. phpCAS::_validateClientExists();
  1369. if (!is_string($service)) {
  1370. phpCAS :: error('type mismatched for parameter $service (should be `string\')');
  1371. }
  1372. if (!is_string($url)) {
  1373. phpCAS :: error('type mismatched for parameter $url (should be `string\')');
  1374. }
  1375. self::$_PHPCAS_CLIENT->logout(
  1376. array (
  1377. "service" => $service,
  1378. "url" => $url
  1379. )
  1380. );
  1381. // never reached
  1382. phpCAS :: traceEnd();
  1383. }
  1384. /**
  1385. * Set the fixed URL that will be used by the CAS server to transmit the
  1386. * PGT. When this method is not called, a phpCAS script uses its own URL
  1387. * for the callback.
  1388. *
  1389. * @param string $url the URL
  1390. *
  1391. * @return void
  1392. */
  1393. public static function setFixedCallbackURL($url = '')
  1394. {
  1395. phpCAS :: traceBegin();
  1396. phpCAS::_validateProxyExists();
  1397. try {
  1398. self::$_PHPCAS_CLIENT->setCallbackURL($url);
  1399. } catch (Exception $e) {
  1400. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1401. }
  1402. phpCAS :: traceEnd();
  1403. }
  1404. /**
  1405. * Set the fixed URL that will be set as the CAS service parameter. When this
  1406. * method is not called, a phpCAS script uses its own URL.
  1407. *
  1408. * @param string $url the URL
  1409. *
  1410. * @return void
  1411. */
  1412. public static function setFixedServiceURL($url)
  1413. {
  1414. phpCAS :: traceBegin();
  1415. phpCAS::_validateProxyExists();
  1416. try {
  1417. self::$_PHPCAS_CLIENT->setURL($url);
  1418. } catch (Exception $e) {
  1419. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1420. }
  1421. phpCAS :: traceEnd();
  1422. }
  1423. /**
  1424. * Get the URL that is set as the CAS service parameter.
  1425. *
  1426. * @return string Service Url
  1427. */
  1428. public static function getServiceURL()
  1429. {
  1430. phpCAS::_validateProxyExists();
  1431. return (self::$_PHPCAS_CLIENT->getURL());
  1432. }
  1433. /**
  1434. * Retrieve a Proxy Ticket from the CAS server.
  1435. *
  1436. * @param string $target_service Url string of service to proxy
  1437. * @param int &$err_code error code
  1438. * @param string &$err_msg error message
  1439. *
  1440. * @return string Proxy Ticket
  1441. */
  1442. public static function retrievePT($target_service, & $err_code, & $err_msg)
  1443. {
  1444. phpCAS::_validateProxyExists();
  1445. try {
  1446. return (self::$_PHPCAS_CLIENT->retrievePT($target_service, $err_code, $err_msg));
  1447. } catch (Exception $e) {
  1448. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1449. }
  1450. }
  1451. /**
  1452. * Set the certificate of the CAS server CA and if the CN should be properly
  1453. * verified.
  1454. *
  1455. * @param string $cert CA certificate file name
  1456. * @param bool $validate_cn Validate CN in certificate (default true)
  1457. *
  1458. * @return void
  1459. */
  1460. public static function setCasServerCACert($cert, $validate_cn = true)
  1461. {
  1462. phpCAS :: traceBegin();
  1463. phpCAS::_validateClientExists();
  1464. try {
  1465. self::$_PHPCAS_CLIENT->setCasServerCACert($cert, $validate_cn);
  1466. } catch (Exception $e) {
  1467. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1468. }
  1469. phpCAS :: traceEnd();
  1470. }
  1471. /**
  1472. * Set no SSL validation for the CAS server.
  1473. *
  1474. * @return void
  1475. */
  1476. public static function setNoCasServerValidation()
  1477. {
  1478. phpCAS :: traceBegin();
  1479. phpCAS::_validateClientExists();
  1480. phpCAS :: trace('You have configured no validation of the legitimacy of the cas server. This is not recommended for production use.');
  1481. self::$_PHPCAS_CLIENT->setNoCasServerValidation();
  1482. phpCAS :: traceEnd();
  1483. }
  1484. /**
  1485. * Disable the removal of a CAS-Ticket from the URL when authenticating
  1486. * DISABLING POSES A SECURITY RISK:
  1487. * We normally remove the ticket by an additional redirect as a security
  1488. * precaution to prevent a ticket in the HTTP_REFERRER or be carried over in
  1489. * the URL parameter
  1490. *
  1491. * @return void
  1492. */
  1493. public static function setNoClearTicketsFromUrl()
  1494. {
  1495. phpCAS :: traceBegin();
  1496. phpCAS::_validateClientExists();
  1497. self::$_PHPCAS_CLIENT->setNoClearTicketsFromUrl();
  1498. phpCAS :: traceEnd();
  1499. }
  1500. /** @} */
  1501. /**
  1502. * Change CURL options.
  1503. * CURL is used to connect through HTTPS to CAS server
  1504. *
  1505. * @param string $key the option key
  1506. * @param string $value the value to set
  1507. *
  1508. * @return void
  1509. */
  1510. public static function setExtraCurlOption($key, $value)
  1511. {
  1512. phpCAS :: traceBegin();
  1513. phpCAS::_validateClientExists();
  1514. self::$_PHPCAS_CLIENT->setExtraCurlOption($key, $value);
  1515. phpCAS :: traceEnd();
  1516. }
  1517. /**
  1518. * Set a salt/seed for the session-id hash to make it harder to guess.
  1519. *
  1520. * When $changeSessionID = true phpCAS will create a session-id that is derived
  1521. * from the service ticket. Doing so allows phpCAS to look-up and destroy the
  1522. * proper session on single-log-out requests. While the service tickets
  1523. * provided by the CAS server may include enough data to generate a strong
  1524. * hash, clients may provide an additional salt to ensure that session ids
  1525. * are not guessable if the session tickets do not have enough entropy.
  1526. *
  1527. * @param string $salt The salt to combine with the session ticket.
  1528. *
  1529. * @return void
  1530. */
  1531. public static function setSessionIdSalt($salt) {
  1532. phpCAS :: traceBegin();
  1533. phpCAS::_validateClientExists();
  1534. self::$_PHPCAS_CLIENT->setSessionIdSalt($salt);
  1535. phpCAS :: traceEnd();
  1536. }
  1537. /**
  1538. * If you want your service to be proxied you have to enable it (default
  1539. * disabled) and define an accepable list of proxies that are allowed to
  1540. * proxy your service.
  1541. *
  1542. * Add each allowed proxy definition object. For the normal CAS_ProxyChain
  1543. * class, the constructor takes an array of proxies to match. The list is in
  1544. * reverse just as seen from the service. Proxies have to be defined in reverse
  1545. * from the service to the user. If a user hits service A and gets proxied via
  1546. * B to service C the list of acceptable on C would be array(B,A). The definition
  1547. * of an individual proxy can be either a string or a regexp (preg_match is used)
  1548. * that will be matched against the proxy list supplied by the cas server
  1549. * when validating the proxy tickets. The strings are compared starting from
  1550. * the beginning and must fully match with the proxies in the list.
  1551. * Example:
  1552. * phpCAS::allowProxyChain(new CAS_ProxyChain(array(
  1553. * 'https://app.example.com/'
  1554. * )));
  1555. * phpCAS::allowProxyChain(new CAS_ProxyChain(array(
  1556. * '/^https:\/\/app[0-9]\.example\.com\/rest\//',
  1557. * 'http://client.example.com/'
  1558. * )));
  1559. *
  1560. * For quick testing or in certain production screnarios you might want to
  1561. * allow allow any other valid service to proxy your service. To do so, add
  1562. * the "Any" chain:
  1563. * phpCAS::allowProxyChain(new CAS_ProxyChain_Any);
  1564. * THIS SETTING IS HOWEVER NOT RECOMMENDED FOR PRODUCTION AND HAS SECURITY
  1565. * IMPLICATIONS: YOU ARE ALLOWING ANY SERVICE TO ACT ON BEHALF OF A USER
  1566. * ON THIS SERVICE.
  1567. *
  1568. * @param CAS_ProxyChain_Interface $proxy_chain A proxy-chain that will be
  1569. * matched against the proxies requesting access
  1570. *
  1571. * @return void
  1572. */
  1573. public static function allowProxyChain(CAS_ProxyChain_Interface $proxy_chain)
  1574. {
  1575. phpCAS :: traceBegin();
  1576. phpCAS::_validateClientExists();
  1577. if (self::$_PHPCAS_CLIENT->getServerVersion() !== CAS_VERSION_2_0
  1578. && self::$_PHPCAS_CLIENT->getServerVersion() !== CAS_VERSION_3_0
  1579. ) {
  1580. phpCAS :: error('this method can only be used with the cas 2.0/3.0 protocols');
  1581. }
  1582. self::$_PHPCAS_CLIENT->getAllowedProxyChains()->allowProxyChain($proxy_chain);
  1583. phpCAS :: traceEnd();
  1584. }
  1585. /**
  1586. * Answer an array of proxies that are sitting in front of this application.
  1587. * This method will only return a non-empty array if we have received and
  1588. * validated a Proxy Ticket.
  1589. *
  1590. * @return array
  1591. * @access public
  1592. * @since 6/25/09
  1593. */
  1594. public static function getProxies ()
  1595. {
  1596. phpCAS::_validateProxyExists();
  1597. return(self::$_PHPCAS_CLIENT->getProxies());
  1598. }
  1599. // ########################################################################
  1600. // PGTIOU/PGTID and logoutRequest rebroadcasting
  1601. // ########################################################################
  1602. /**
  1603. * Add a pgtIou/pgtId and logoutRequest rebroadcast node.
  1604. *
  1605. * @param string $rebroadcastNodeUrl The rebroadcast node URL. Can be
  1606. * hostname or IP.
  1607. *
  1608. * @return void
  1609. */
  1610. public static function addRebroadcastNode($rebroadcastNodeUrl)
  1611. {
  1612. phpCAS::traceBegin();
  1613. phpCAS::log('rebroadcastNodeUrl:'.$rebroadcastNodeUrl);
  1614. phpCAS::_validateClientExists();
  1615. try {
  1616. self::$_PHPCAS_CLIENT->addRebroadcastNode($rebroadcastNodeUrl);
  1617. } catch (Exception $e) {
  1618. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1619. }
  1620. phpCAS::traceEnd();
  1621. }
  1622. /**
  1623. * This method is used to add header parameters when rebroadcasting
  1624. * pgtIou/pgtId or logoutRequest.
  1625. *
  1626. * @param String $header Header to send when rebroadcasting.
  1627. *
  1628. * @return void
  1629. */
  1630. public static function addRebroadcastHeader($header)
  1631. {
  1632. phpCAS :: traceBegin();
  1633. phpCAS::_validateClientExists();
  1634. try {
  1635. self::$_PHPCAS_CLIENT->addRebroadcastHeader($header);
  1636. } catch (Exception $e) {
  1637. phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
  1638. }
  1639. phpCAS :: traceEnd();
  1640. }
  1641. /**
  1642. * Checks if a client already exists
  1643. *
  1644. * @throws CAS_OutOfSequenceBeforeClientException
  1645. *
  1646. * @return void
  1647. */
  1648. private static function _validateClientExists()
  1649. {
  1650. if (!is_object(self::$_PHPCAS_CLIENT)) {
  1651. throw new CAS_OutOfSequenceBeforeClientException();
  1652. }
  1653. }
  1654. /**
  1655. * Checks of a proxy client aready exists
  1656. *
  1657. * @throws CAS_OutOfSequenceBeforeProxyException
  1658. *
  1659. * @return void
  1660. */
  1661. private static function _validateProxyExists()
  1662. {
  1663. if (!is_object(self::$_PHPCAS_CLIENT)) {
  1664. throw new CAS_OutOfSequenceBeforeProxyException();
  1665. }
  1666. }
  1667. /**
  1668. * For testing purposes, use this method to set the client to a test double
  1669. *
  1670. * @return void
  1671. */
  1672. public static function setCasClient(\CAS_Client $client)
  1673. {
  1674. self::$_PHPCAS_CLIENT = $client;
  1675. }
  1676. }
  1677. // ########################################################################
  1678. // DOCUMENTATION
  1679. // ########################################################################
  1680. // ########################################################################
  1681. // MAIN PAGE
  1682. /**
  1683. * @mainpage
  1684. *
  1685. * The following pages only show the source documentation.
  1686. *
  1687. */
  1688. // ########################################################################
  1689. // MODULES DEFINITION
  1690. /** @defgroup public User interface */
  1691. /** @defgroup publicInit Initialization
  1692. * @ingroup public */
  1693. /** @defgroup publicAuth Authentication
  1694. * @ingroup public */
  1695. /** @defgroup publicServices Access to external services
  1696. * @ingroup public */
  1697. /** @defgroup publicConfig Configuration
  1698. * @ingroup public */
  1699. /** @defgroup publicLang Internationalization
  1700. * @ingroup publicConfig */
  1701. /** @defgroup publicOutput HTML output
  1702. * @ingroup publicConfig */
  1703. /** @defgroup publicPGTStorage PGT storage
  1704. * @ingroup publicConfig */
  1705. /** @defgroup publicDebug Debugging
  1706. * @ingroup public */
  1707. /** @defgroup internal Implementation */
  1708. /** @defgroup internalAuthentication Authentication
  1709. * @ingroup internal */
  1710. /** @defgroup internalBasic CAS Basic client features (CAS 1.0, Service Tickets)
  1711. * @ingroup internal */
  1712. /** @defgroup internalProxy CAS Proxy features (CAS 2.0, Proxy Granting Tickets)
  1713. * @ingroup internal */
  1714. /** @defgroup internalSAML CAS SAML features (SAML 1.1)
  1715. * @ingroup internal */
  1716. /** @defgroup internalPGTStorage PGT storage
  1717. * @ingroup internalProxy */
  1718. /** @defgroup internalPGTStorageDb PGT storage in a database
  1719. * @ingroup internalPGTStorage */
  1720. /** @defgroup internalPGTStorageFile PGT storage on the filesystem
  1721. * @ingroup internalPGTStorage */
  1722. /** @defgroup internalCallback Callback from the CAS server
  1723. * @ingroup internalProxy */
  1724. /** @defgroup internalProxyServices Proxy other services
  1725. * @ingroup internalProxy */
  1726. /** @defgroup internalService CAS client features (CAS 2.0, Proxied service)
  1727. * @ingroup internal */
  1728. /** @defgroup internalConfig Configuration
  1729. * @ingroup internal */
  1730. /** @defgroup internalBehave Internal behaviour of phpCAS
  1731. * @ingroup internalConfig */
  1732. /** @defgroup internalOutput HTML output
  1733. * @ingroup internalConfig */
  1734. /** @defgroup internalLang Internationalization
  1735. * @ingroup internalConfig
  1736. *
  1737. * To add a new language:
  1738. * - 1. define a new constant PHPCAS_LANG_XXXXXX in CAS/CAS.php
  1739. * - 2. copy any file from CAS/languages to CAS/languages/XXXXXX.php
  1740. * - 3. Make the translations
  1741. */
  1742. /** @defgroup internalDebug Debugging
  1743. * @ingroup internal */
  1744. /** @defgroup internalMisc Miscellaneous
  1745. * @ingroup internal */
  1746. // ########################################################################
  1747. // EXAMPLES
  1748. /**
  1749. * @example example_simple.php
  1750. */
  1751. /**
  1752. * @example example_service.php
  1753. */
  1754. /**
  1755. * @example example_service_that_proxies.php
  1756. */
  1757. /**
  1758. * @example example_service_POST.php
  1759. */
  1760. /**
  1761. * @example example_proxy_serviceWeb.php
  1762. */
  1763. /**
  1764. * @example example_proxy_serviceWeb_chaining.php
  1765. */
  1766. /**
  1767. * @example example_proxy_POST.php
  1768. */
  1769. /**
  1770. * @example example_proxy_GET.php
  1771. */
  1772. /**
  1773. * @example example_lang.php
  1774. */
  1775. /**
  1776. * @example example_html.php
  1777. */
  1778. /**
  1779. * @example example_pgt_storage_file.php
  1780. */
  1781. /**
  1782. * @example example_pgt_storage_db.php
  1783. */
  1784. /**
  1785. * @example example_gateway.php
  1786. */
  1787. /**
  1788. * @example example_logout.php
  1789. */
  1790. /**
  1791. * @example example_rebroadcast.php
  1792. */
  1793. /**
  1794. * @example example_custom_urls.php
  1795. */
  1796. /**
  1797. * @example example_advanced_saml11.php
  1798. */