e6bae3fe45d56a0e8c9c8b122a056be6178c3aa6
[piwik-CASLogin.git] / CAS / CAS.php
1 <?php\r
2 \r
3 /*\r
4  * Copyright © 2003-2010, The ESUP-Portail consortium & the JA-SIG Collaborative.\r
5  * All rights reserved.\r
6  * \r
7  * Redistribution and use in source and binary forms, with or without\r
8  * modification, are permitted provided that the following conditions are met:\r
9  * \r
10  *     * Redistributions of source code must retain the above copyright notice,\r
11  *       this list of conditions and the following disclaimer.\r
12  *     * Redistributions in binary form must reproduce the above copyright notice,\r
13  *       this list of conditions and the following disclaimer in the documentation\r
14  *       and/or other materials provided with the distribution.\r
15  *     * Neither the name of the ESUP-Portail consortium & the JA-SIG\r
16  *       Collaborative nor the names of its contributors may be used to endorse or\r
17  *       promote products derived from this software without specific prior\r
18  *       written permission.\r
19 \r
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
22  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
23  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\r
24  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\r
27  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
30  */\r
31 \r
32 //\r
33 // hack by Vangelis Haniotakis to handle the absence of $_SERVER['REQUEST_URI'] in IIS\r
34 //\r
35 if (!isset($_SERVER['REQUEST_URI'])) {\r
36         $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];\r
37 }\r
38 \r
39 //\r
40 // another one by Vangelis Haniotakis also to make phpCAS work with PHP5\r
41 //\r
42 if (version_compare(PHP_VERSION, '5', '>=') && !(function_exists('domxml_new_doc'))) {\r
43         require_once (dirname(__FILE__) . '/CAS/domxml-php4-to-php5.php');\r
44 }\r
45 \r
46 /**\r
47  * @file CAS/CAS.php\r
48  * Interface class of the phpCAS library\r
49  *\r
50  * @ingroup public\r
51  */\r
52 \r
53 // ########################################################################\r
54 //  CONSTANTS\r
55 // ########################################################################\r
56 \r
57 // ------------------------------------------------------------------------\r
58 //  CAS VERSIONS\r
59 // ------------------------------------------------------------------------\r
60 \r
61 /**\r
62  * phpCAS version. accessible for the user by phpCAS::getVersion().\r
63  */\r
64 define('PHPCAS_VERSION', '1.1.3');\r
65 \r
66 // ------------------------------------------------------------------------\r
67 //  CAS VERSIONS\r
68 // ------------------------------------------------------------------------\r
69 /**\r
70  * @addtogroup public\r
71  * @{\r
72  */\r
73 \r
74 /**\r
75  * CAS version 1.0\r
76  */\r
77 define("CAS_VERSION_1_0", '1.0');\r
78 /*!\r
79  * CAS version 2.0\r
80  */\r
81 define("CAS_VERSION_2_0", '2.0');\r
82 \r
83 // ------------------------------------------------------------------------\r
84 //  SAML defines\r
85 // ------------------------------------------------------------------------\r
86 \r
87 /**\r
88  * SAML protocol\r
89  */\r
90 define("SAML_VERSION_1_1", 'S1');\r
91 \r
92 /**\r
93  * XML header for SAML POST\r
94  */\r
95 define("SAML_XML_HEADER", '<?xml version="1.0" encoding="UTF-8"?>');\r
96 \r
97 /**\r
98  * SOAP envelope for SAML POST\r
99  */\r
100 define("SAML_SOAP_ENV", '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/>');\r
101 \r
102 /**\r
103  * SOAP body for SAML POST\r
104  */\r
105 define("SAML_SOAP_BODY", '<SOAP-ENV:Body>');\r
106 \r
107 /**\r
108  * SAMLP request\r
109  */\r
110 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">');\r
111 define("SAMLP_REQUEST_CLOSE", '</samlp:Request>');\r
112 \r
113 /**\r
114  * SAMLP artifact tag (for the ticket)\r
115  */\r
116 define("SAML_ASSERTION_ARTIFACT", '<samlp:AssertionArtifact>');\r
117 \r
118 /**\r
119  * SAMLP close\r
120  */\r
121 define("SAML_ASSERTION_ARTIFACT_CLOSE", '</samlp:AssertionArtifact>');\r
122 \r
123 /**\r
124  * SOAP body close\r
125  */\r
126 define("SAML_SOAP_BODY_CLOSE", '</SOAP-ENV:Body>');\r
127 \r
128 /**\r
129  * SOAP envelope close\r
130  */\r
131 define("SAML_SOAP_ENV_CLOSE", '</SOAP-ENV:Envelope>');\r
132 \r
133 /**\r
134  * SAML Attributes\r
135  */\r
136 define("SAML_ATTRIBUTES", 'SAMLATTRIBS');\r
137 \r
138 /** @} */\r
139 /**\r
140  * @addtogroup publicPGTStorage\r
141  * @{\r
142  */\r
143 // ------------------------------------------------------------------------\r
144 //  FILE PGT STORAGE\r
145 // ------------------------------------------------------------------------\r
146 /**\r
147  * Default path used when storing PGT's to file\r
148  */\r
149 define("CAS_PGT_STORAGE_FILE_DEFAULT_PATH", '/tmp');\r
150 /**\r
151  * phpCAS::setPGTStorageFile()'s 2nd parameter to write plain text files\r
152  */\r
153 define("CAS_PGT_STORAGE_FILE_FORMAT_PLAIN", 'plain');\r
154 /**\r
155  * phpCAS::setPGTStorageFile()'s 2nd parameter to write xml files\r
156  */\r
157 define("CAS_PGT_STORAGE_FILE_FORMAT_XML", 'xml');\r
158 /**\r
159  * Default format used when storing PGT's to file\r
160  */\r
161 define("CAS_PGT_STORAGE_FILE_DEFAULT_FORMAT", CAS_PGT_STORAGE_FILE_FORMAT_PLAIN);\r
162 /** @} */\r
163 // ------------------------------------------------------------------------\r
164 // SERVICE ACCESS ERRORS\r
165 // ------------------------------------------------------------------------\r
166 /**\r
167  * @addtogroup publicServices\r
168  * @{\r
169  */\r
170 \r
171 /**\r
172  * phpCAS::service() error code on success\r
173  */\r
174 define("PHPCAS_SERVICE_OK", 0);\r
175 /**\r
176  * phpCAS::service() error code when the PT could not retrieve because\r
177  * the CAS server did not respond.\r
178  */\r
179 define("PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE", 1);\r
180 /**\r
181  * phpCAS::service() error code when the PT could not retrieve because\r
182  * the response of the CAS server was ill-formed.\r
183  */\r
184 define("PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE", 2);\r
185 /**\r
186  * phpCAS::service() error code when the PT could not retrieve because\r
187  * the CAS server did not want to.\r
188  */\r
189 define("PHPCAS_SERVICE_PT_FAILURE", 3);\r
190 /**\r
191  * phpCAS::service() error code when the service was not available.\r
192  */\r
193 define("PHPCAS_SERVICE_NOT AVAILABLE", 4);\r
194 \r
195 /** @} */\r
196 // ------------------------------------------------------------------------\r
197 //  LANGUAGES\r
198 // ------------------------------------------------------------------------\r
199 /**\r
200  * @addtogroup publicLang\r
201  * @{\r
202  */\r
203 \r
204 define("PHPCAS_LANG_ENGLISH", 'english');\r
205 define("PHPCAS_LANG_FRENCH", 'french');\r
206 define("PHPCAS_LANG_GREEK", 'greek');\r
207 define("PHPCAS_LANG_GERMAN", 'german');\r
208 define("PHPCAS_LANG_JAPANESE", 'japanese');\r
209 define("PHPCAS_LANG_SPANISH", 'spanish');\r
210 define("PHPCAS_LANG_CATALAN", 'catalan');\r
211 \r
212 /** @} */\r
213 \r
214 /**\r
215  * @addtogroup internalLang\r
216  * @{\r
217  */\r
218 \r
219 /**\r
220  * phpCAS default language (when phpCAS::setLang() is not used)\r
221  */\r
222 define("PHPCAS_LANG_DEFAULT", PHPCAS_LANG_ENGLISH);\r
223 \r
224 /** @} */\r
225 // ------------------------------------------------------------------------\r
226 //  DEBUG\r
227 // ------------------------------------------------------------------------\r
228 /**\r
229  * @addtogroup publicDebug\r
230  * @{\r
231  */\r
232 \r
233 /**\r
234  * The default directory for the debug file under Unix.\r
235  */\r
236 define('DEFAULT_DEBUG_DIR', '/tmp/');\r
237 \r
238 /** @} */\r
239 // ------------------------------------------------------------------------\r
240 //  MISC\r
241 // ------------------------------------------------------------------------\r
242 /**\r
243  * @addtogroup internalMisc\r
244  * @{\r
245  */\r
246 \r
247 /**\r
248  * This global variable is used by the interface class phpCAS.\r
249  *\r
250  * @hideinitializer\r
251  */\r
252 $GLOBALS['PHPCAS_CLIENT'] = null;\r
253 \r
254 /**\r
255  * This global variable is used to store where the initializer is called from \r
256  * (to print a comprehensive error in case of multiple calls).\r
257  *\r
258  * @hideinitializer\r
259  */\r
260 $GLOBALS['PHPCAS_INIT_CALL'] = array (\r
261         'done' => FALSE,\r
262         'file' => '?',\r
263         'line' => -1,\r
264         'method' => '?'\r
265 );\r
266 \r
267 /**\r
268  * This global variable is used to store where the method checking\r
269  * the authentication is called from (to print comprehensive errors)\r
270  *\r
271  * @hideinitializer\r
272  */\r
273 $GLOBALS['PHPCAS_AUTH_CHECK_CALL'] = array (\r
274         'done' => FALSE,\r
275         'file' => '?',\r
276         'line' => -1,\r
277         'method' => '?',\r
278         'result' => FALSE\r
279 );\r
280 \r
281 /**\r
282  * This global variable is used to store phpCAS debug mode.\r
283  *\r
284  * @hideinitializer\r
285  */\r
286 $GLOBALS['PHPCAS_DEBUG'] = array (\r
287         'filename' => FALSE,\r
288         'indent' => 0,\r
289         'unique_id' => ''\r
290 );\r
291 \r
292 /** @} */\r
293 \r
294 // ########################################################################\r
295 //  CLIENT CLASS\r
296 // ########################################################################\r
297 \r
298 // include client class\r
299 include_once (dirname(__FILE__) . '/CAS/client.php');\r
300 \r
301 // ########################################################################\r
302 //  INTERFACE CLASS\r
303 // ########################################################################\r
304 \r
305 /**\r
306  * @class phpCAS\r
307  * The phpCAS class is a simple container for the phpCAS library. It provides CAS\r
308  * authentication for web applications written in PHP.\r
309  *\r
310  * @ingroup public\r
311  * @author Pascal Aubry <pascal.aubry at univ-rennes1.fr>\r
312  *\r
313  * \internal All its methods access the same object ($PHPCAS_CLIENT, declared \r
314  * at the end of CAS/client.php).\r
315  */\r
316 \r
317 class phpCAS {\r
318 \r
319         // ########################################################################\r
320         //  INITIALIZATION\r
321         // ########################################################################\r
322 \r
323         /**\r
324          * @addtogroup publicInit\r
325          * @{\r
326          */\r
327 \r
328         /**\r
329          * phpCAS client initializer.\r
330          * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be\r
331          * called, only once, and before all other methods (except phpCAS::getVersion()\r
332          * and phpCAS::setDebug()).\r
333          *\r
334          * @param $server_version the version of the CAS server\r
335          * @param $server_hostname the hostname of the CAS server\r
336          * @param $server_port the port the CAS server is running on\r
337          * @param $server_uri the URI the CAS server is responding on\r
338          * @param $start_session Have phpCAS start PHP sessions (default true)\r
339          *\r
340          * @return a newly created CASClient object\r
341          */\r
342         function client($server_version, $server_hostname, $server_port, $server_uri, $start_session = true) {\r
343                 global $PHPCAS_CLIENT, $PHPCAS_INIT_CALL;\r
344 \r
345                 phpCAS :: traceBegin();\r
346                 if (is_object($PHPCAS_CLIENT)) {\r
347                         phpCAS :: error($PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . $PHPCAS_INIT_CALL['file'] . ':' . $PHPCAS_INIT_CALL['line'] . ')');\r
348                 }\r
349                 if (gettype($server_version) != 'string') {\r
350                         phpCAS :: error('type mismatched for parameter $server_version (should be `string\')');\r
351                 }\r
352                 if (gettype($server_hostname) != 'string') {\r
353                         phpCAS :: error('type mismatched for parameter $server_hostname (should be `string\')');\r
354                 }\r
355                 if (gettype($server_port) != 'integer') {\r
356                         phpCAS :: error('type mismatched for parameter $server_port (should be `integer\')');\r
357                 }\r
358                 if (gettype($server_uri) != 'string') {\r
359                         phpCAS :: error('type mismatched for parameter $server_uri (should be `string\')');\r
360                 }\r
361 \r
362                 // store where the initializer is called from\r
363                 $dbg = phpCAS :: backtrace();\r
364                 $PHPCAS_INIT_CALL = array (\r
365                         'done' => TRUE,\r
366                         'file' => $dbg[0]['file'],\r
367                         'line' => $dbg[0]['line'],\r
368                         'method' => __CLASS__ . '::' . __FUNCTION__\r
369                 );\r
370 \r
371                 // initialize the global object $PHPCAS_CLIENT\r
372                 $PHPCAS_CLIENT = new CASClient($server_version, FALSE /*proxy*/\r
373                 , $server_hostname, $server_port, $server_uri, $start_session);\r
374                 phpCAS :: traceEnd();\r
375         }\r
376 \r
377         /**\r
378          * phpCAS proxy initializer.\r
379          * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be\r
380          * called, only once, and before all other methods (except phpCAS::getVersion()\r
381          * and phpCAS::setDebug()).\r
382          *\r
383          * @param $server_version the version of the CAS server\r
384          * @param $server_hostname the hostname of the CAS server\r
385          * @param $server_port the port the CAS server is running on\r
386          * @param $server_uri the URI the CAS server is responding on\r
387          * @param $start_session Have phpCAS start PHP sessions (default true)\r
388          *\r
389          * @return a newly created CASClient object\r
390          */\r
391         function proxy($server_version, $server_hostname, $server_port, $server_uri, $start_session = true) {\r
392                 global $PHPCAS_CLIENT, $PHPCAS_INIT_CALL;\r
393 \r
394                 phpCAS :: traceBegin();\r
395                 if (is_object($PHPCAS_CLIENT)) {\r
396                         phpCAS :: error($PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . $PHPCAS_INIT_CALL['file'] . ':' . $PHPCAS_INIT_CALL['line'] . ')');\r
397                 }\r
398                 if (gettype($server_version) != 'string') {\r
399                         phpCAS :: error('type mismatched for parameter $server_version (should be `string\')');\r
400                 }\r
401                 if (gettype($server_hostname) != 'string') {\r
402                         phpCAS :: error('type mismatched for parameter $server_hostname (should be `string\')');\r
403                 }\r
404                 if (gettype($server_port) != 'integer') {\r
405                         phpCAS :: error('type mismatched for parameter $server_port (should be `integer\')');\r
406                 }\r
407                 if (gettype($server_uri) != 'string') {\r
408                         phpCAS :: error('type mismatched for parameter $server_uri (should be `string\')');\r
409                 }\r
410 \r
411                 // store where the initialzer is called from\r
412                 $dbg = phpCAS :: backtrace();\r
413                 $PHPCAS_INIT_CALL = array (\r
414                         'done' => TRUE,\r
415                         'file' => $dbg[0]['file'],\r
416                         'line' => $dbg[0]['line'],\r
417                         'method' => __CLASS__ . '::' . __FUNCTION__\r
418                 );\r
419 \r
420                 // initialize the global object $PHPCAS_CLIENT\r
421                 $PHPCAS_CLIENT = new CASClient($server_version, TRUE /*proxy*/\r
422                 , $server_hostname, $server_port, $server_uri, $start_session);\r
423                 phpCAS :: traceEnd();\r
424         }\r
425 \r
426         /** @} */\r
427         // ########################################################################\r
428         //  DEBUGGING\r
429         // ########################################################################\r
430 \r
431         /**\r
432          * @addtogroup publicDebug\r
433          * @{\r
434          */\r
435 \r
436         /**\r
437          * Set/unset debug mode\r
438          *\r
439          * @param $filename the name of the file used for logging, or FALSE to stop debugging.\r
440          */\r
441         function setDebug($filename = '') {\r
442                 global $PHPCAS_DEBUG;\r
443 \r
444                 if ($filename != FALSE && gettype($filename) != 'string') {\r
445                         phpCAS :: error('type mismatched for parameter $dbg (should be FALSE or the name of the log file)');\r
446                 }\r
447 \r
448                 if (empty ($filename)) {\r
449                         if (preg_match('/^Win.*/', getenv('OS'))) {\r
450                                 if (isset ($_ENV['TMP'])) {\r
451                                         $debugDir = $_ENV['TMP'] . '/';\r
452                                 } else\r
453                                         if (isset ($_ENV['TEMP'])) {\r
454                                                 $debugDir = $_ENV['TEMP'] . '/';\r
455                                         } else {\r
456                                                 $debugDir = '';\r
457                                         }\r
458                         } else {\r
459                                 $debugDir = DEFAULT_DEBUG_DIR;\r
460                         }\r
461                         $filename = $debugDir . 'phpCAS.log';\r
462                 }\r
463 \r
464                 if (empty ($PHPCAS_DEBUG['unique_id'])) {\r
465                         $PHPCAS_DEBUG['unique_id'] = substr(strtoupper(md5(uniqid(''))), 0, 4);\r
466                 }\r
467 \r
468                 $PHPCAS_DEBUG['filename'] = $filename;\r
469 \r
470                 phpCAS :: trace('START phpCAS-' . PHPCAS_VERSION . ' ******************');\r
471         }\r
472 \r
473         /** @} */\r
474         /**\r
475          * @addtogroup internalDebug\r
476          * @{\r
477          */\r
478 \r
479         /**\r
480          * This method is a wrapper for debug_backtrace() that is not available \r
481          * in all PHP versions (>= 4.3.0 only)\r
482          */\r
483         function backtrace() {\r
484                 if (function_exists('debug_backtrace')) {\r
485                         return debug_backtrace();\r
486                 } else {\r
487                         // poor man's hack ... but it does work ...\r
488                         return array ();\r
489                 }\r
490         }\r
491 \r
492         /**\r
493          * Logs a string in debug mode.\r
494          *\r
495          * @param $str the string to write\r
496          *\r
497          * @private\r
498          */\r
499         function log($str) {\r
500                 $indent_str = ".";\r
501                 global $PHPCAS_DEBUG;\r
502 \r
503                 if ($PHPCAS_DEBUG['filename']) {\r
504                         for ($i = 0; $i < $PHPCAS_DEBUG['indent']; $i++) {\r
505                                 $indent_str .= '|    ';\r
506                         }\r
507                         error_log($PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str . $str . "\n", 3, $PHPCAS_DEBUG['filename']);\r
508                 }\r
509 \r
510         }\r
511 \r
512         /**\r
513          * This method is used by interface methods to print an error and where the function\r
514          * was originally called from.\r
515          *\r
516          * @param $msg the message to print\r
517          *\r
518          * @private\r
519          */\r
520         function error($msg) {\r
521                 $dbg = phpCAS :: backtrace();\r
522                 $function = '?';\r
523                 $file = '?';\r
524                 $line = '?';\r
525                 if (is_array($dbg)) {\r
526                         for ($i = 1; $i < sizeof($dbg); $i++) {\r
527                                 if (is_array($dbg[$i])) {\r
528                                         if ($dbg[$i]['class'] == __CLASS__) {\r
529                                                 $function = $dbg[$i]['function'];\r
530                                                 $file = $dbg[$i]['file'];\r
531                                                 $line = $dbg[$i]['line'];\r
532                                         }\r
533                                 }\r
534                         }\r
535                 }\r
536                 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";\r
537                 phpCAS :: trace($msg);\r
538                 phpCAS :: traceExit();\r
539                 exit ();\r
540         }\r
541 \r
542         /**\r
543          * This method is used to log something in debug mode.\r
544          */\r
545         function trace($str) {\r
546                 $dbg = phpCAS :: backtrace();\r
547                 phpCAS :: log($str . ' [' . basename($dbg[1]['file']) . ':' . $dbg[1]['line'] . ']');\r
548         }\r
549 \r
550         /**\r
551          * This method is used to indicate the start of the execution of a function in debug mode.\r
552          */\r
553         function traceBegin() {\r
554                 global $PHPCAS_DEBUG;\r
555 \r
556                 $dbg = phpCAS :: backtrace();\r
557                 $str = '=> ';\r
558                 if (!empty ($dbg[2]['class'])) {\r
559                         $str .= $dbg[2]['class'] . '::';\r
560                 }\r
561                 $str .= $dbg[2]['function'] . '(';\r
562                 if (is_array($dbg[2]['args'])) {\r
563                         foreach ($dbg[2]['args'] as $index => $arg) {\r
564                                 if ($index != 0) {\r
565                                         $str .= ', ';\r
566                                 }\r
567                                 $str .= str_replace("\n", "", var_export($arg, TRUE));\r
568                         }\r
569                 }\r
570                 $str .= ') [' . basename($dbg[2]['file']) . ':' . $dbg[2]['line'] . ']';\r
571                 phpCAS :: log($str);\r
572                 $PHPCAS_DEBUG['indent']++;\r
573         }\r
574 \r
575         /**\r
576          * This method is used to indicate the end of the execution of a function in debug mode.\r
577          *\r
578          * @param $res the result of the function\r
579          */\r
580         function traceEnd($res = '') {\r
581                 global $PHPCAS_DEBUG;\r
582 \r
583                 $PHPCAS_DEBUG['indent']--;\r
584                 $dbg = phpCAS :: backtrace();\r
585                 $str = '';\r
586                 $str .= '<= ' . str_replace("\n", "", var_export($res, TRUE));\r
587                 phpCAS :: log($str);\r
588         }\r
589 \r
590         /**\r
591          * This method is used to indicate the end of the execution of the program\r
592          */\r
593         function traceExit() {\r
594                 global $PHPCAS_DEBUG;\r
595 \r
596                 phpCAS :: log('exit()');\r
597                 while ($PHPCAS_DEBUG['indent'] > 0) {\r
598                         phpCAS :: log('-');\r
599                         $PHPCAS_DEBUG['indent']--;\r
600                 }\r
601         }\r
602 \r
603         /** @} */\r
604         // ########################################################################\r
605         //  INTERNATIONALIZATION\r
606         // ########################################################################\r
607         /**\r
608          * @addtogroup publicLang\r
609          * @{\r
610          */\r
611 \r
612         /**\r
613          * This method is used to set the language used by phpCAS. \r
614          * @note Can be called only once.\r
615          *\r
616          * @param $lang a string representing the language.\r
617          *\r
618          * @sa PHPCAS_LANG_FRENCH, PHPCAS_LANG_ENGLISH\r
619          */\r
620         function setLang($lang) {\r
621                 global $PHPCAS_CLIENT;\r
622                 if (!is_object($PHPCAS_CLIENT)) {\r
623                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
624                 }\r
625                 if (gettype($lang) != 'string') {\r
626                         phpCAS :: error('type mismatched for parameter $lang (should be `string\')');\r
627                 }\r
628                 $PHPCAS_CLIENT->setLang($lang);\r
629         }\r
630 \r
631         /** @} */\r
632         // ########################################################################\r
633         //  VERSION\r
634         // ########################################################################\r
635         /**\r
636          * @addtogroup public\r
637          * @{\r
638          */\r
639 \r
640         /**\r
641          * This method returns the phpCAS version.\r
642          *\r
643          * @return the phpCAS version.\r
644          */\r
645         function getVersion() {\r
646                 return PHPCAS_VERSION;\r
647         }\r
648 \r
649         /** @} */\r
650         // ########################################################################\r
651         //  HTML OUTPUT\r
652         // ########################################################################\r
653         /**\r
654          * @addtogroup publicOutput\r
655          * @{\r
656          */\r
657 \r
658         /**\r
659          * This method sets the HTML header used for all outputs.\r
660          *\r
661          * @param $header the HTML header.\r
662          */\r
663         function setHTMLHeader($header) {\r
664                 global $PHPCAS_CLIENT;\r
665                 if (!is_object($PHPCAS_CLIENT)) {\r
666                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
667                 }\r
668                 if (gettype($header) != 'string') {\r
669                         phpCAS :: error('type mismatched for parameter $header (should be `string\')');\r
670                 }\r
671                 $PHPCAS_CLIENT->setHTMLHeader($header);\r
672         }\r
673 \r
674         /**\r
675          * This method sets the HTML footer used for all outputs.\r
676          *\r
677          * @param $footer the HTML footer.\r
678          */\r
679         function setHTMLFooter($footer) {\r
680                 global $PHPCAS_CLIENT;\r
681                 if (!is_object($PHPCAS_CLIENT)) {\r
682                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
683                 }\r
684                 if (gettype($footer) != 'string') {\r
685                         phpCAS :: error('type mismatched for parameter $footer (should be `string\')');\r
686                 }\r
687                 $PHPCAS_CLIENT->setHTMLFooter($footer);\r
688         }\r
689 \r
690         /** @} */\r
691         // ########################################################################\r
692         //  PGT STORAGE\r
693         // ########################################################################\r
694         /**\r
695          * @addtogroup publicPGTStorage\r
696          * @{\r
697          */\r
698 \r
699         /**\r
700          * This method is used to tell phpCAS to store the response of the\r
701          * CAS server to PGT requests onto the filesystem. \r
702          *\r
703          * @param $format the format used to store the PGT's (`plain' and `xml' allowed)\r
704          * @param $path the path where the PGT's should be stored\r
705          */\r
706         function setPGTStorageFile($format = '', $path = '') {\r
707                 global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;\r
708 \r
709                 phpCAS :: traceBegin();\r
710                 if (!is_object($PHPCAS_CLIENT)) {\r
711                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');\r
712                 }\r
713                 if (!$PHPCAS_CLIENT->isProxy()) {\r
714                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');\r
715                 }\r
716                 if ($PHPCAS_AUTH_CHECK_CALL['done']) {\r
717                         phpCAS :: error('this method should only be called before ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() (called at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ')');\r
718                 }\r
719                 if (gettype($format) != 'string') {\r
720                         phpCAS :: error('type mismatched for parameter $format (should be `string\')');\r
721                 }\r
722                 if (gettype($path) != 'string') {\r
723                         phpCAS :: error('type mismatched for parameter $format (should be `string\')');\r
724                 }\r
725                 $PHPCAS_CLIENT->setPGTStorageFile($format, $path);\r
726                 phpCAS :: traceEnd();\r
727         }\r
728 \r
729 \r
730         /** @} */\r
731         // ########################################################################\r
732         // ACCESS TO EXTERNAL SERVICES\r
733         // ########################################################################\r
734         /**\r
735          * @addtogroup publicServices\r
736          * @{\r
737          */\r
738 \r
739         /**\r
740          * This method is used to access an HTTP[S] service.\r
741          * \r
742          * @param $url the service to access.\r
743          * @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on\r
744          * success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE,\r
745          * PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_NOT AVAILABLE.\r
746          * @param $output the output of the service (also used to give an error\r
747          * message on failure).\r
748          *\r
749          * @return TRUE on success, FALSE otherwise (in this later case, $err_code\r
750          * gives the reason why it failed and $output contains an error message).\r
751          */\r
752         function serviceWeb($url, & $err_code, & $output) {\r
753                 global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;\r
754 \r
755                 phpCAS :: traceBegin();\r
756                 if (!is_object($PHPCAS_CLIENT)) {\r
757                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');\r
758                 }\r
759                 if (!$PHPCAS_CLIENT->isProxy()) {\r
760                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');\r
761                 }\r
762                 if (!$PHPCAS_AUTH_CHECK_CALL['done']) {\r
763                         phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()');\r
764                 }\r
765                 if (!$PHPCAS_AUTH_CHECK_CALL['result']) {\r
766                         phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE');\r
767                 }\r
768                 if (gettype($url) != 'string') {\r
769                         phpCAS :: error('type mismatched for parameter $url (should be `string\')');\r
770                 }\r
771 \r
772                 $res = $PHPCAS_CLIENT->serviceWeb($url, $err_code, $output);\r
773 \r
774                 phpCAS :: traceEnd($res);\r
775                 return $res;\r
776         }\r
777 \r
778         /**\r
779          * This method is used to access an IMAP/POP3/NNTP service.\r
780          * \r
781          * @param $url a string giving the URL of the service, including the mailing box\r
782          * for IMAP URLs, as accepted by imap_open().\r
783          * @param $service a string giving for CAS retrieve Proxy ticket\r
784          * @param $flags options given to imap_open().\r
785          * @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on\r
786          * success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE,\r
787          * PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_NOT AVAILABLE.\r
788          * @param $err_msg an error message on failure\r
789          * @param $pt the Proxy Ticket (PT) retrieved from the CAS server to access the URL\r
790          * on success, FALSE on error).\r
791          *\r
792          * @return an IMAP stream on success, FALSE otherwise (in this later case, $err_code\r
793          * gives the reason why it failed and $err_msg contains an error message).\r
794          */\r
795         function serviceMail($url, $service, $flags, & $err_code, & $err_msg, & $pt) {\r
796                 global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;\r
797 \r
798                 phpCAS :: traceBegin();\r
799                 if (!is_object($PHPCAS_CLIENT)) {\r
800                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');\r
801                 }\r
802                 if (!$PHPCAS_CLIENT->isProxy()) {\r
803                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');\r
804                 }\r
805                 if (!$PHPCAS_AUTH_CHECK_CALL['done']) {\r
806                         phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()');\r
807                 }\r
808                 if (!$PHPCAS_AUTH_CHECK_CALL['result']) {\r
809                         phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE');\r
810                 }\r
811                 if (gettype($url) != 'string') {\r
812                         phpCAS :: error('type mismatched for parameter $url (should be `string\')');\r
813                 }\r
814 \r
815                 if (gettype($flags) != 'integer') {\r
816                         phpCAS :: error('type mismatched for parameter $flags (should be `integer\')');\r
817                 }\r
818 \r
819                 $res = $PHPCAS_CLIENT->serviceMail($url, $service, $flags, $err_code, $err_msg, $pt);\r
820 \r
821                 phpCAS :: traceEnd($res);\r
822                 return $res;\r
823         }\r
824 \r
825         /** @} */\r
826         // ########################################################################\r
827         //  AUTHENTICATION\r
828         // ########################################################################\r
829         /**\r
830          * @addtogroup publicAuth\r
831          * @{\r
832          */\r
833 \r
834         /**\r
835          * Set the times authentication will be cached before really accessing the CAS server in gateway mode: \r
836          * - -1: check only once, and then never again (until you pree login)\r
837          * - 0: always check\r
838          * - n: check every "n" time\r
839          *\r
840          * @param $n an integer.\r
841          */\r
842         function setCacheTimesForAuthRecheck($n) {\r
843                 global $PHPCAS_CLIENT;\r
844                 if (!is_object($PHPCAS_CLIENT)) {\r
845                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
846                 }\r
847                 if (gettype($n) != 'integer') {\r
848                         phpCAS :: error('type mismatched for parameter $header (should be `string\')');\r
849                 }\r
850                 $PHPCAS_CLIENT->setCacheTimesForAuthRecheck($n);\r
851         }\r
852 \r
853         /**\r
854          * This method is called to check if the user is authenticated (use the gateway feature).\r
855          * @return TRUE when the user is authenticated; otherwise FALSE.\r
856          */\r
857         function checkAuthentication() {\r
858                 global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;\r
859 \r
860                 phpCAS :: traceBegin();\r
861                 if (!is_object($PHPCAS_CLIENT)) {\r
862                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
863                 }\r
864 \r
865                 $auth = $PHPCAS_CLIENT->checkAuthentication();\r
866 \r
867                 // store where the authentication has been checked and the result\r
868                 $dbg = phpCAS :: backtrace();\r
869                 $PHPCAS_AUTH_CHECK_CALL = array (\r
870                         'done' => TRUE,\r
871                         'file' => $dbg[0]['file'],\r
872                         'line' => $dbg[0]['line'],\r
873                         'method' => __CLASS__ . '::' . __FUNCTION__,\r
874                         'result' => $auth\r
875                 );\r
876                 phpCAS :: traceEnd($auth);\r
877                 return $auth;\r
878         }\r
879 \r
880         /**\r
881          * This method is called to force authentication if the user was not already \r
882          * authenticated. If the user is not authenticated, halt by redirecting to \r
883          * the CAS server.\r
884          */\r
885         function forceAuthentication() {\r
886                 global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;\r
887 \r
888                 phpCAS :: traceBegin();\r
889                 if (!is_object($PHPCAS_CLIENT)) {\r
890                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
891                 }\r
892 \r
893                 $auth = $PHPCAS_CLIENT->forceAuthentication();\r
894 \r
895                 // store where the authentication has been checked and the result\r
896                 $dbg = phpCAS :: backtrace();\r
897                 $PHPCAS_AUTH_CHECK_CALL = array (\r
898                         'done' => TRUE,\r
899                         'file' => $dbg[0]['file'],\r
900                         'line' => $dbg[0]['line'],\r
901                         'method' => __CLASS__ . '::' . __FUNCTION__,\r
902                         'result' => $auth\r
903                 );\r
904 \r
905                 if (!$auth) {\r
906                         phpCAS :: trace('user is not authenticated, redirecting to the CAS server');\r
907                         $PHPCAS_CLIENT->forceAuthentication();\r
908                 } else {\r
909                         phpCAS :: trace('no need to authenticate (user `' . phpCAS :: getUser() . '\' is already authenticated)');\r
910                 }\r
911 \r
912                 phpCAS :: traceEnd();\r
913                 return $auth;\r
914         }\r
915 \r
916         /**\r
917          * This method is called to renew the authentication.\r
918          **/\r
919         function renewAuthentication() {\r
920                 global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;\r
921 \r
922                 phpCAS :: traceBegin();\r
923                 if (!is_object($PHPCAS_CLIENT)) {\r
924                         phpCAS :: error('this method should not be called before' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
925                 }\r
926 \r
927                 // store where the authentication has been checked and the result\r
928                 $dbg = phpCAS :: backtrace();\r
929                 $PHPCAS_AUTH_CHECK_CALL = array (\r
930                         'done' => TRUE,\r
931                         'file' => $dbg[0]['file'],\r
932                         'line' => $dbg[0]['line'],\r
933                         'method' => __CLASS__ . '::' . __FUNCTION__,\r
934                         'result' => $auth\r
935                 );\r
936 \r
937                 $PHPCAS_CLIENT->renewAuthentication();\r
938                 phpCAS :: traceEnd();\r
939         }\r
940 \r
941         /**\r
942          * This method has been left from version 0.4.1 for compatibility reasons.\r
943          */\r
944         function authenticate() {\r
945                 phpCAS :: error('this method is deprecated. You should use ' . __CLASS__ . '::forceAuthentication() instead');\r
946         }\r
947 \r
948         /**\r
949          * This method is called to check if the user is authenticated (previously or by\r
950          * tickets given in the URL).\r
951          *\r
952          * @return TRUE when the user is authenticated.\r
953          */\r
954         function isAuthenticated() {\r
955                 global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;\r
956 \r
957                 phpCAS :: traceBegin();\r
958                 if (!is_object($PHPCAS_CLIENT)) {\r
959                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
960                 }\r
961 \r
962                 // call the isAuthenticated method of the global $PHPCAS_CLIENT object\r
963                 $auth = $PHPCAS_CLIENT->isAuthenticated();\r
964 \r
965                 // store where the authentication has been checked and the result\r
966                 $dbg = phpCAS :: backtrace();\r
967                 $PHPCAS_AUTH_CHECK_CALL = array (\r
968                         'done' => TRUE,\r
969                         'file' => $dbg[0]['file'],\r
970                         'line' => $dbg[0]['line'],\r
971                         'method' => __CLASS__ . '::' . __FUNCTION__,\r
972                         'result' => $auth\r
973                 );\r
974                 phpCAS :: traceEnd($auth);\r
975                 return $auth;\r
976         }\r
977 \r
978         /**\r
979          * Checks whether authenticated based on $_SESSION. Useful to avoid\r
980          * server calls.\r
981          * @return true if authenticated, false otherwise.\r
982          * @since 0.4.22 by Brendan Arnold\r
983          */\r
984         function isSessionAuthenticated() {\r
985                 global $PHPCAS_CLIENT;\r
986                 if (!is_object($PHPCAS_CLIENT)) {\r
987                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
988                 }\r
989                 return ($PHPCAS_CLIENT->isSessionAuthenticated());\r
990         }\r
991 \r
992         /**\r
993          * This method returns the CAS user's login name.\r
994          * @warning should not be called only after phpCAS::forceAuthentication()\r
995          * or phpCAS::checkAuthentication().\r
996          *\r
997          * @return the login name of the authenticated user\r
998          */\r
999         function getUser() {\r
1000                 global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;\r
1001                 if (!is_object($PHPCAS_CLIENT)) {\r
1002                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
1003                 }\r
1004                 if (!$PHPCAS_AUTH_CHECK_CALL['done']) {\r
1005                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');\r
1006                 }\r
1007                 if (!$PHPCAS_AUTH_CHECK_CALL['result']) {\r
1008                         phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE');\r
1009                 }\r
1010                 return $PHPCAS_CLIENT->getUser();\r
1011         }\r
1012 \r
1013         /**\r
1014          * This method returns the CAS user's login name.\r
1015          * @warning should not be called only after phpCAS::forceAuthentication()\r
1016          * or phpCAS::checkAuthentication().\r
1017          *\r
1018          * @return the login name of the authenticated user\r
1019          */\r
1020         function getAttributes() {\r
1021                 global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;\r
1022                 if (!is_object($PHPCAS_CLIENT)) {\r
1023                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
1024                 }\r
1025                 if (!$PHPCAS_AUTH_CHECK_CALL['done']) {\r
1026                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');\r
1027                 }\r
1028                 if (!$PHPCAS_AUTH_CHECK_CALL['result']) {\r
1029                         phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE');\r
1030                 }\r
1031                 return $PHPCAS_CLIENT->getAttributes();\r
1032         }\r
1033         /**\r
1034          * Handle logout requests.\r
1035          */\r
1036         function handleLogoutRequests($check_client = true, $allowed_clients = false) {\r
1037                 global $PHPCAS_CLIENT;\r
1038                 if (!is_object($PHPCAS_CLIENT)) {\r
1039                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
1040                 }\r
1041                 return ($PHPCAS_CLIENT->handleLogoutRequests($check_client, $allowed_clients));\r
1042         }\r
1043 \r
1044         /**\r
1045          * This method returns the URL to be used to login.\r
1046          * or phpCAS::isAuthenticated().\r
1047          *\r
1048          * @return the login name of the authenticated user\r
1049          */\r
1050         function getServerLoginURL() {\r
1051                 global $PHPCAS_CLIENT;\r
1052                 if (!is_object($PHPCAS_CLIENT)) {\r
1053                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
1054                 }\r
1055                 return $PHPCAS_CLIENT->getServerLoginURL();\r
1056         }\r
1057 \r
1058         /**\r
1059          * Set the login URL of the CAS server.\r
1060          * @param $url the login URL\r
1061          * @since 0.4.21 by Wyman Chan\r
1062          */\r
1063         function setServerLoginURL($url = '') {\r
1064                 global $PHPCAS_CLIENT;\r
1065                 phpCAS :: traceBegin();\r
1066                 if (!is_object($PHPCAS_CLIENT)) {\r
1067                         phpCAS :: error('this method should only be called after\r
1068                                                         ' . __CLASS__ . '::client()');\r
1069                 }\r
1070                 if (gettype($url) != 'string') {\r
1071                         phpCAS :: error('type mismatched for parameter $url (should be\r
1072                                                 `string\')');\r
1073                 }\r
1074                 $PHPCAS_CLIENT->setServerLoginURL($url);\r
1075                 phpCAS :: traceEnd();\r
1076         }\r
1077 \r
1078         /**\r
1079          * Set the serviceValidate URL of the CAS server.\r
1080          * Used only in CAS 1.0 validations\r
1081          * @param $url the serviceValidate URL\r
1082          * @since 1.1.0 by Joachim Fritschi\r
1083          */\r
1084         function setServerServiceValidateURL($url = '') {\r
1085                 global $PHPCAS_CLIENT;\r
1086                 phpCAS :: traceBegin();\r
1087                 if (!is_object($PHPCAS_CLIENT)) {\r
1088                         phpCAS :: error('this method should only be called after\r
1089                                                         ' . __CLASS__ . '::client()');\r
1090                 }\r
1091                 if (gettype($url) != 'string') {\r
1092                         phpCAS :: error('type mismatched for parameter $url (should be\r
1093                                                 `string\')');\r
1094                 }\r
1095                 $PHPCAS_CLIENT->setServerServiceValidateURL($url);\r
1096                 phpCAS :: traceEnd();\r
1097         }\r
1098 \r
1099         /**\r
1100          * Set the proxyValidate URL of the CAS server.\r
1101          * Used for all CAS 2.0 validations\r
1102          * @param $url the proxyValidate URL\r
1103          * @since 1.1.0 by Joachim Fritschi\r
1104          */\r
1105         function setServerProxyValidateURL($url = '') {\r
1106                 global $PHPCAS_CLIENT;\r
1107                 phpCAS :: traceBegin();\r
1108                 if (!is_object($PHPCAS_CLIENT)) {\r
1109                         phpCAS :: error('this method should only be called after\r
1110                                                         ' . __CLASS__ . '::client()');\r
1111                 }\r
1112                 if (gettype($url) != 'string') {\r
1113                         phpCAS :: error('type mismatched for parameter $url (should be\r
1114                                                 `string\')');\r
1115                 }\r
1116                 $PHPCAS_CLIENT->setServerProxyValidateURL($url);\r
1117                 phpCAS :: traceEnd();\r
1118         }\r
1119 \r
1120         /**\r
1121          * Set the samlValidate URL of the CAS server.\r
1122          * @param $url the samlValidate URL\r
1123          * @since 1.1.0 by Joachim Fritschi\r
1124          */\r
1125         function setServerSamlValidateURL($url = '') {\r
1126                 global $PHPCAS_CLIENT;\r
1127                 phpCAS :: traceBegin();\r
1128                 if (!is_object($PHPCAS_CLIENT)) {\r
1129                         phpCAS :: error('this method should only be called after\r
1130                                                         ' . __CLASS__ . '::client()');\r
1131                 }\r
1132                 if (gettype($url) != 'string') {\r
1133                         phpCAS :: error('type mismatched for parameter $url (should be\r
1134                                                 `string\')');\r
1135                 }\r
1136                 $PHPCAS_CLIENT->setServerSamlValidateURL($url);\r
1137                 phpCAS :: traceEnd();\r
1138         }\r
1139 \r
1140         /**\r
1141          * This method returns the URL to be used to login.\r
1142          * or phpCAS::isAuthenticated().\r
1143          *\r
1144          * @return the login name of the authenticated user\r
1145          */\r
1146         function getServerLogoutURL() {\r
1147                 global $PHPCAS_CLIENT;\r
1148                 if (!is_object($PHPCAS_CLIENT)) {\r
1149                         phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');\r
1150                 }\r
1151                 return $PHPCAS_CLIENT->getServerLogoutURL();\r
1152         }\r
1153 \r
1154         /**\r
1155          * Set the logout URL of the CAS server.\r
1156          * @param $url the logout URL\r
1157          * @since 0.4.21 by Wyman Chan\r
1158          */\r
1159         function setServerLogoutURL($url = '') {\r
1160                 global $PHPCAS_CLIENT;\r
1161                 phpCAS :: traceBegin();\r
1162                 if (!is_object($PHPCAS_CLIENT)) {\r
1163                         phpCAS :: error('this method should only be called after\r
1164                                                         ' . __CLASS__ . '::client()');\r
1165                 }\r
1166                 if (gettype($url) != 'string') {\r
1167                         phpCAS :: error('type mismatched for parameter $url (should be\r
1168                                                 `string\')');\r
1169                 }\r
1170                 $PHPCAS_CLIENT->setServerLogoutURL($url);\r
1171                 phpCAS :: traceEnd();\r
1172         }\r
1173 \r
1174         /**\r
1175          * This method is used to logout from CAS.\r
1176          * @params $params an array that contains the optional url and service parameters that will be passed to the CAS server\r
1177          * @public\r
1178          */\r
1179         function logout($params = "") {\r
1180                 global $PHPCAS_CLIENT;\r
1181                 phpCAS :: traceBegin();\r
1182                 if (!is_object($PHPCAS_CLIENT)) {\r
1183                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');\r
1184                 }\r
1185                 $parsedParams = array ();\r
1186                 if ($params != "") {\r
1187                         if (is_string($params)) {\r
1188                                 phpCAS :: error('method `phpCAS::logout($url)\' is now deprecated, use `phpCAS::logoutWithUrl($url)\' instead');\r
1189                         }\r
1190                         if (!is_array($params)) {\r
1191                                 phpCAS :: error('type mismatched for parameter $params (should be `array\')');\r
1192                         }\r
1193                         foreach ($params as $key => $value) {\r
1194                                 if ($key != "service" && $key != "url") {\r
1195                                         phpCAS :: error('only `url\' and `service\' parameters are allowed for method `phpCAS::logout($params)\'');\r
1196                                 }\r
1197                                 $parsedParams[$key] = $value;\r
1198                         }\r
1199                 }\r
1200                 $PHPCAS_CLIENT->logout($parsedParams);\r
1201                 // never reached\r
1202                 phpCAS :: traceEnd();\r
1203         }\r
1204 \r
1205         /**\r
1206          * This method is used to logout from CAS. Halts by redirecting to the CAS server.\r
1207          * @param $service a URL that will be transmitted to the CAS server\r
1208          */\r
1209         function logoutWithRedirectService($service) {\r
1210                 global $PHPCAS_CLIENT;\r
1211                 phpCAS :: traceBegin();\r
1212                 if (!is_object($PHPCAS_CLIENT)) {\r
1213                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');\r
1214                 }\r
1215                 if (!is_string($service)) {\r
1216                         phpCAS :: error('type mismatched for parameter $service (should be `string\')');\r
1217                 }\r
1218                 $PHPCAS_CLIENT->logout(array (\r
1219                         "service" => $service\r
1220                 ));\r
1221                 // never reached\r
1222                 phpCAS :: traceEnd();\r
1223         }\r
1224 \r
1225         /**\r
1226          * This method is used to logout from CAS. Halts by redirecting to the CAS server.\r
1227          * @param $url a URL that will be transmitted to the CAS server\r
1228          */\r
1229         function logoutWithUrl($url) {\r
1230                 global $PHPCAS_CLIENT;\r
1231                 phpCAS :: traceBegin();\r
1232                 if (!is_object($PHPCAS_CLIENT)) {\r
1233                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');\r
1234                 }\r
1235                 if (!is_string($url)) {\r
1236                         phpCAS :: error('type mismatched for parameter $url (should be `string\')');\r
1237                 }\r
1238                 $PHPCAS_CLIENT->logout(array (\r
1239                         "url" => $url\r
1240                 ));\r
1241                 // never reached\r
1242                 phpCAS :: traceEnd();\r
1243         }\r
1244 \r
1245         /**\r
1246          * This method is used to logout from CAS. Halts by redirecting to the CAS server.\r
1247          * @param $service a URL that will be transmitted to the CAS server\r
1248          * @param $url a URL that will be transmitted to the CAS server\r
1249          */\r
1250         function logoutWithRedirectServiceAndUrl($service, $url) {\r
1251                 global $PHPCAS_CLIENT;\r
1252                 phpCAS :: traceBegin();\r
1253                 if (!is_object($PHPCAS_CLIENT)) {\r
1254                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');\r
1255                 }\r
1256                 if (!is_string($service)) {\r
1257                         phpCAS :: error('type mismatched for parameter $service (should be `string\')');\r
1258                 }\r
1259                 if (!is_string($url)) {\r
1260                         phpCAS :: error('type mismatched for parameter $url (should be `string\')');\r
1261                 }\r
1262                 $PHPCAS_CLIENT->logout(array (\r
1263                         "service" => $service,\r
1264                         "url" => $url\r
1265                 ));\r
1266                 // never reached\r
1267                 phpCAS :: traceEnd();\r
1268         }\r
1269 \r
1270         /**\r
1271          * Set the fixed URL that will be used by the CAS server to transmit the PGT.\r
1272          * When this method is not called, a phpCAS script uses its own URL for the callback.\r
1273          *\r
1274          * @param $url the URL\r
1275          */\r
1276         function setFixedCallbackURL($url = '') {\r
1277                 global $PHPCAS_CLIENT;\r
1278                 phpCAS :: traceBegin();\r
1279                 if (!is_object($PHPCAS_CLIENT)) {\r
1280                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');\r
1281                 }\r
1282                 if (!$PHPCAS_CLIENT->isProxy()) {\r
1283                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');\r
1284                 }\r
1285                 if (gettype($url) != 'string') {\r
1286                         phpCAS :: error('type mismatched for parameter $url (should be `string\')');\r
1287                 }\r
1288                 $PHPCAS_CLIENT->setCallbackURL($url);\r
1289                 phpCAS :: traceEnd();\r
1290         }\r
1291 \r
1292         /**\r
1293          * Set the fixed URL that will be set as the CAS service parameter. When this\r
1294          * method is not called, a phpCAS script uses its own URL.\r
1295          *\r
1296          * @param $url the URL\r
1297          */\r
1298         function setFixedServiceURL($url) {\r
1299                 global $PHPCAS_CLIENT;\r
1300                 phpCAS :: traceBegin();\r
1301                 if (!is_object($PHPCAS_CLIENT)) {\r
1302                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');\r
1303                 }\r
1304                 if (gettype($url) != 'string') {\r
1305                         phpCAS :: error('type mismatched for parameter $url (should be `string\')');\r
1306                 }\r
1307                 $PHPCAS_CLIENT->setURL($url);\r
1308                 phpCAS :: traceEnd();\r
1309         }\r
1310 \r
1311         /**\r
1312          * Get the URL that is set as the CAS service parameter.\r
1313          */\r
1314         function getServiceURL() {\r
1315                 global $PHPCAS_CLIENT;\r
1316                 if (!is_object($PHPCAS_CLIENT)) {\r
1317                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');\r
1318                 }\r
1319                 return ($PHPCAS_CLIENT->getURL());\r
1320         }\r
1321 \r
1322         /**\r
1323          * Retrieve a Proxy Ticket from the CAS server.\r
1324          */\r
1325         function retrievePT($target_service, & $err_code, & $err_msg) {\r
1326                 global $PHPCAS_CLIENT;\r
1327                 if (!is_object($PHPCAS_CLIENT)) {\r
1328                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');\r
1329                 }\r
1330                 if (gettype($target_service) != 'string') {\r
1331                         phpCAS :: error('type mismatched for parameter $target_service(should be `string\')');\r
1332                 }\r
1333                 return ($PHPCAS_CLIENT->retrievePT($target_service, $err_code, $err_msg));\r
1334         }\r
1335 \r
1336         /**\r
1337          * Set the certificate of the CAS server.\r
1338          *\r
1339          * @param $cert the PEM certificate\r
1340          */\r
1341         function setCasServerCert($cert) {\r
1342                 global $PHPCAS_CLIENT;\r
1343                 phpCAS :: traceBegin();\r
1344                 if (!is_object($PHPCAS_CLIENT)) {\r
1345                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');\r
1346                 }\r
1347                 if (gettype($cert) != 'string') {\r
1348                         phpCAS :: error('type mismatched for parameter $cert (should be `string\')');\r
1349                 }\r
1350                 $PHPCAS_CLIENT->setCasServerCert($cert);\r
1351                 phpCAS :: traceEnd();\r
1352         }\r
1353 \r
1354         /**\r
1355          * Set the certificate of the CAS server CA.\r
1356          *\r
1357          * @param $cert the CA certificate\r
1358          */\r
1359         function setCasServerCACert($cert) {\r
1360                 global $PHPCAS_CLIENT;\r
1361                 phpCAS :: traceBegin();\r
1362                 if (!is_object($PHPCAS_CLIENT)) {\r
1363                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');\r
1364                 }\r
1365                 if (gettype($cert) != 'string') {\r
1366                         phpCAS :: error('type mismatched for parameter $cert (should be `string\')');\r
1367                 }\r
1368                 $PHPCAS_CLIENT->setCasServerCACert($cert);\r
1369                 phpCAS :: traceEnd();\r
1370         }\r
1371 \r
1372         /**\r
1373          * Set no SSL validation for the CAS server.\r
1374          */\r
1375         function setNoCasServerValidation() {\r
1376                 global $PHPCAS_CLIENT;\r
1377                 phpCAS :: traceBegin();\r
1378                 if (!is_object($PHPCAS_CLIENT)) {\r
1379                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');\r
1380                 }\r
1381                 $PHPCAS_CLIENT->setNoCasServerValidation();\r
1382                 phpCAS :: traceEnd();\r
1383         }\r
1384 \r
1385         /** @} */\r
1386 \r
1387         /**\r
1388          * Change CURL options.\r
1389          * CURL is used to connect through HTTPS to CAS server\r
1390          * @param $key the option key\r
1391          * @param $value the value to set\r
1392          */\r
1393         function setExtraCurlOption($key, $value) {\r
1394                 global $PHPCAS_CLIENT;\r
1395                 phpCAS :: traceBegin();\r
1396                 if (!is_object($PHPCAS_CLIENT)) {\r
1397                         phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');\r
1398                 }\r
1399                 $PHPCAS_CLIENT->setExtraCurlOption($key, $value);\r
1400                 phpCAS :: traceEnd();\r
1401         }\r
1402 \r
1403 }\r
1404 \r
1405 // ########################################################################\r
1406 // DOCUMENTATION\r
1407 // ########################################################################\r
1408 \r
1409 // ########################################################################\r
1410 //  MAIN PAGE\r
1411 \r
1412 /**\r
1413  * @mainpage\r
1414  *\r
1415  * The following pages only show the source documentation.\r
1416  *\r
1417  */\r
1418 \r
1419 // ########################################################################\r
1420 //  MODULES DEFINITION\r
1421 \r
1422 /** @defgroup public User interface */\r
1423 \r
1424 /** @defgroup publicInit Initialization\r
1425  *  @ingroup public */\r
1426 \r
1427 /** @defgroup publicAuth Authentication\r
1428  *  @ingroup public */\r
1429 \r
1430 /** @defgroup publicServices Access to external services\r
1431  *  @ingroup public */\r
1432 \r
1433 /** @defgroup publicConfig Configuration\r
1434  *  @ingroup public */\r
1435 \r
1436 /** @defgroup publicLang Internationalization\r
1437  *  @ingroup publicConfig */\r
1438 \r
1439 /** @defgroup publicOutput HTML output\r
1440  *  @ingroup publicConfig */\r
1441 \r
1442 /** @defgroup publicPGTStorage PGT storage\r
1443  *  @ingroup publicConfig */\r
1444 \r
1445 /** @defgroup publicDebug Debugging\r
1446  *  @ingroup public */\r
1447 \r
1448 /** @defgroup internal Implementation */\r
1449 \r
1450 /** @defgroup internalAuthentication Authentication\r
1451  *  @ingroup internal */\r
1452 \r
1453 /** @defgroup internalBasic CAS Basic client features (CAS 1.0, Service Tickets)\r
1454  *  @ingroup internal */\r
1455 \r
1456 /** @defgroup internalProxy CAS Proxy features (CAS 2.0, Proxy Granting Tickets)\r
1457  *  @ingroup internal */\r
1458 \r
1459 /** @defgroup internalPGTStorage PGT storage\r
1460  *  @ingroup internalProxy */\r
1461 \r
1462 /** @defgroup internalPGTStorageFile PGT storage on the filesystem\r
1463  *  @ingroup internalPGTStorage */\r
1464 \r
1465 /** @defgroup internalCallback Callback from the CAS server\r
1466  *  @ingroup internalProxy */\r
1467 \r
1468 /** @defgroup internalProxied CAS proxied client features (CAS 2.0, Proxy Tickets)\r
1469  *  @ingroup internal */\r
1470 \r
1471 /** @defgroup internalConfig Configuration\r
1472  *  @ingroup internal */\r
1473 \r
1474 /** @defgroup internalOutput HTML output\r
1475  *  @ingroup internalConfig */\r
1476 \r
1477 /** @defgroup internalLang Internationalization\r
1478  *  @ingroup internalConfig\r
1479  *\r
1480  * To add a new language:\r
1481  * - 1. define a new constant PHPCAS_LANG_XXXXXX in CAS/CAS.php\r
1482  * - 2. copy any file from CAS/languages to CAS/languages/XXXXXX.php\r
1483  * - 3. Make the translations\r
1484  */\r
1485 \r
1486 /** @defgroup internalDebug Debugging\r
1487  *  @ingroup internal */\r
1488 \r
1489 /** @defgroup internalMisc Miscellaneous\r
1490  *  @ingroup internal */\r
1491 \r
1492 // ########################################################################\r
1493 //  EXAMPLES\r
1494 \r
1495 /**\r
1496  * @example example_simple.php\r
1497  */\r
1498 /**\r
1499  * @example example_proxy.php\r
1500  */\r
1501 /**\r
1502  * @example example_proxy2.php\r
1503  */\r
1504 /**\r
1505  * @example example_lang.php\r
1506  */\r
1507 /**\r
1508  * @example example_html.php\r
1509  */\r
1510 /**\r
1511  * @example example_file.php\r
1512  */\r
1513 /**\r
1514  * @example example_db.php\r
1515  */\r
1516 /**\r
1517  * @example example_service.php\r
1518  */\r
1519 /**\r
1520  * @example example_session_proxy.php\r
1521  */\r
1522 /**\r
1523  * @example example_session_service.php\r
1524  */\r
1525 /**\r
1526  * @example example_gateway.php\r
1527  */\r
1528 /**\r
1529  * @example example_custom_urls.php\r
1530  */\r
1531 ?>\r