Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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