~ubuntu-branches/ubuntu/utopic/moodle/utopic

« back to all changes in this revision

Viewing changes to auth/cas/CAS/CAS.php

  • Committer: Package Import Robot
  • Author(s): Thijs Kinkhorst
  • Date: 2014-05-12 16:10:38 UTC
  • mfrom: (36.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20140512161038-puyqf65k4e0s8ytz
Tags: 2.6.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

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