Projet

Général

Profil

Paste
Statistiques
| Branche: | Révision:

ryxeo-glpi-git / lib / phpcas / CAS.php @ b67d8923

Historique | Voir | Annoter | Télécharger (38,6 ko)

1
<?php
2

    
3
// commented in 0.4.22-RC2 for Sylvain Derosiaux
4
// error_reporting(E_ALL ^ E_NOTICE);
5

    
6
//
7
// hack by Vangelis Haniotakis to handle the absence of $_SERVER['REQUEST_URI'] in IIS
8
//
9
if (!$_SERVER['REQUEST_URI']) {
10
     $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING'];
11
}
12

    
13
//
14
// another one by Vangelis Haniotakis also to make phpCAS work with PHP5
15
//
16
if (version_compare(PHP_VERSION,'5','>=')&&!function_exists("domxml_new_doc")) {
17
    require_once(dirname(__FILE__).'/domxml-php4-php5.php');
18
}
19

    
20
/**
21
 * @file CAS/CAS.php
22
 * Interface class of the phpCAS library
23
 *
24
 * @ingroup public
25
 */
26

    
27
// ########################################################################
28
//  CONSTANTS
29
// ########################################################################
30

    
31
// ------------------------------------------------------------------------
32
//  CAS VERSIONS
33
// ------------------------------------------------------------------------
34

    
35
/**
36
 * phpCAS version. accessible for the user by $this->getVersion().
37
 */
38
define('PHPCAS_VERSION','0.5.1-1');
39

    
40
// ------------------------------------------------------------------------
41
//  CAS VERSIONS
42
// ------------------------------------------------------------------------
43
/**
44
 * @addtogroup public
45
 * @{
46
 */
47

    
48
/**
49
 * CAS version 1.0
50
 */
51
define("CAS_VERSION_1_0",'1.0');
52
/*!
53
 * CAS version 2.0
54
 */
55
define("CAS_VERSION_2_0",'2.0');
56

    
57
/** @} */
58
/**
59
 * @addtogroup publicPGTStorage
60
 * @{
61
 */
62
// ------------------------------------------------------------------------
63
//  FILE PGT STORAGE
64
// ------------------------------------------------------------------------
65
/**
66
 * Default path used when storing PGT's to file
67
 */
68
define("CAS_PGT_STORAGE_FILE_DEFAULT_PATH",'/tmp');
69
/**
70
 * $this->setPGTStorageFile()'s 2nd parameter to write plain text files
71
 */
72
define("CAS_PGT_STORAGE_FILE_FORMAT_PLAIN",'plain');
73
/**
74
 * $this->setPGTStorageFile()'s 2nd parameter to write xml files
75
 */
76
define("CAS_PGT_STORAGE_FILE_FORMAT_XML",'xml');
77
/**
78
 * Default format used when storing PGT's to file
79
 */
80
define("CAS_PGT_STORAGE_FILE_DEFAULT_FORMAT",CAS_PGT_STORAGE_FILE_FORMAT_PLAIN);
81
// ------------------------------------------------------------------------
82
//  DATABASE PGT STORAGE
83
// ------------------------------------------------------------------------
84
/**
85
 * default database type when storing PGT's to database
86
 */
87
define("CAS_PGT_STORAGE_DB_DEFAULT_DATABASE_TYPE",'mysql');
88
/**
89
 * default host when storing PGT's to database
90
 */
91
define("CAS_PGT_STORAGE_DB_DEFAULT_HOSTNAME",'localhost');
92
/**
93
 * default port when storing PGT's to database
94
 */
95
define("CAS_PGT_STORAGE_DB_DEFAULT_PORT",'');
96
/**
97
 * default database when storing PGT's to database
98
 */
99
define("CAS_PGT_STORAGE_DB_DEFAULT_DATABASE",'phpCAS');
100
/**
101
 * default table when storing PGT's to database
102
 */
103
define("CAS_PGT_STORAGE_DB_DEFAULT_TABLE",'pgt');
104

    
105
/** @} */
106
// ------------------------------------------------------------------------
107
// SERVICE ACCESS ERRORS
108
// ------------------------------------------------------------------------
109
/**
110
 * @addtogroup publicServices
111
 * @{
112
 */
113

    
114
/**
115
 * $this->service() error code on success
116
 */
117
define("PHPCAS_SERVICE_OK",0);
118
/**
119
 * $this->service() error code when the PT could not retrieve because
120
 * the CAS server did not respond.
121
 */
122
define("PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE",1);
123
/**
124
 * $this->service() error code when the PT could not retrieve because
125
 * the response of the CAS server was ill-formed.
126
 */
127
define("PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE",2);
128
/**
129
 * $this->service() error code when the PT could not retrieve because
130
 * the CAS server did not want to.
131
 */
132
define("PHPCAS_SERVICE_PT_FAILURE",3);
133
/**
134
 * $this->service() error code when the service was not available.
135
 */
136
define("PHPCAS_SERVICE_NOT AVAILABLE",4);
137

    
138
/** @} */
139
// ------------------------------------------------------------------------
140
//  LANGUAGES
141
// ------------------------------------------------------------------------
142
/**
143
 * @addtogroup publicLang
144
 * @{
145
 */
146

    
147
define("PHPCAS_LANG_ENGLISH",    'english');
148
define("PHPCAS_LANG_FRENCH",     'french');
149
define("PHPCAS_LANG_GREEK",      'greek');
150
define("PHPCAS_LANG_GERMAN",     'german');
151
define("PHPCAS_LANG_JAPANESE",   'japanese');
152

    
153
/** @} */
154

    
155
/**
156
 * @addtogroup internalLang
157
 * @{
158
 */
159

    
160
/**
161
 * phpCAS default language (when $this->setLang() is not used)
162
 */
163
define("PHPCAS_LANG_DEFAULT", PHPCAS_LANG_ENGLISH);
164

    
165
/** @} */
166
// ------------------------------------------------------------------------
167
//  MISC
168
// ------------------------------------------------------------------------
169
/**
170
 * @addtogroup internalMisc
171
 * @{
172
 */
173

    
174
/**
175
 * This global variable is used by the interface class phpCAS.
176
 *
177
 * @hideinitializer
178
 */
179
$PHPCAS_CLIENT  = null;
180

    
181
/**
182
 * This global variable is used to store where the initializer is called from 
183
 * (to print a comprehensive error in case of multiple calls).
184
 *
185
 * @hideinitializer
186
 */
187
$PHPCAS_INIT_CALL = array('done' => FALSE,
188
                          'file' => '?',
189
                          'line' => -1,
190
                          'method' => '?');
191

    
192
/**
193
 * This global variable is used to store where the method checking
194
 * the authentication is called from (to print comprehensive errors)
195
 *
196
 * @hideinitializer
197
 */
198
$PHPCAS_AUTH_CHECK_CALL = array('done' => FALSE,
199
                                'file' => '?',
200
                                'line' => -1,
201
                                'method' => '?',
202
                                'result' => FALSE);
203

    
204
/**
205
 * This global variable is used to store phpCAS debug mode.
206
 *
207
 * @hideinitializer
208
 */
209
$PHPCAS_DEBUG  = array('filename' => FALSE,
210
                       'indent' => 0,
211
                       'unique_id' => '');
212

    
213
/** @} */
214

    
215
// ########################################################################
216
//  CLIENT CLASS
217
// ########################################################################
218

    
219
// include client class
220
include_once(dirname(__FILE__).'/client.php');
221

    
222
// ########################################################################
223
//  INTERFACE CLASS
224
// ########################################################################
225

    
226
/**
227
 * @class phpCAS
228
 * The phpCAS class is a simple container for the phpCAS library. It provides CAS
229
 * authentication for web applications written in PHP.
230
 *
231
 * @ingroup public
232
 * @author Pascal Aubry <pascal.aubry at univ-rennes1.fr>
233
 *
234
 * \internal All its methods access the same object ($PHPCAS_CLIENT, declared 
235
 * at the end of CAS/client.php).
236
 */
237

    
238

    
239

    
240
class phpCAS
241
{
242

    
243
  // ########################################################################
244
  //  INITIALIZATION
245
  // ########################################################################
246

    
247
  /**
248
   * @addtogroup publicInit
249
   * @{
250
   */
251

    
252
  /**
253
   * phpCAS client initializer.
254
   * @note Only one of the $this->client() and $this->proxy functions should be
255
   * called, only once, and before all other methods (except $this->getVersion()
256
   * and $this->setDebug()).
257
   *
258
   * @param $server_version the version of the CAS server
259
   * @param $server_hostname the hostname of the CAS server
260
   * @param $server_port the port the CAS server is running on
261
   * @param $server_uri the URI the CAS server is responding on
262
   * @param $start_session Have phpCAS start PHP sessions (default true)
263
   *
264
   * @return a newly created CASClient object
265
   */
266
  function client($server_version,
267
                  $server_hostname,
268
                  $server_port,
269
                  $server_uri,
270
                   $start_session = true)
271
    {
272
      global $PHPCAS_CLIENT, $PHPCAS_INIT_CALL;
273

    
274
      $this->traceBegin();
275
      if ( is_object($PHPCAS_CLIENT) ) {
276
        $this->error($PHPCAS_INIT_CALL['method'].'() has already been called (at '.$PHPCAS_INIT_CALL['file'].':'.$PHPCAS_INIT_CALL['line'].')');
277
      }
278
      if ( gettype($server_version) != 'string' ) {
279
        $this->error('type mismatched for parameter $server_version (should be `string\')');
280
      }
281
      if ( gettype($server_hostname) != 'string' ) {
282
        $this->error('type mismatched for parameter $server_hostname (should be `string\')');
283
      }
284
      if ( gettype($server_port) != 'integer' ) {
285
        $this->error('type mismatched for parameter $server_port (should be `integer\')');
286
      }
287
      if ( gettype($server_uri) != 'string' ) {
288
        $this->error('type mismatched for parameter $server_uri (should be `string\')');
289
      }
290

    
291
      // store where the initialzer is called from
292
      $dbg = $this->backtrace();
293
      $PHPCAS_INIT_CALL = array('done' => TRUE,
294
                                'file' => $dbg[0]['file'],
295
                                'line' => $dbg[0]['line'],
296
                                'method' => __CLASS__.'::'.__FUNCTION__);
297

    
298
      // initialize the global object $PHPCAS_CLIENT
299
      $PHPCAS_CLIENT = new CASClient($server_version,FALSE/*proxy*/,$server_hostname,$server_port,$server_uri,$start_session);
300
      $this->traceEnd();
301
    }
302

    
303
  /**
304
   * phpCAS proxy initializer.
305
   * @note Only one of the $this->client() and $this->proxy functions should be
306
   * called, only once, and before all other methods (except $this->getVersion()
307
   * and $this->setDebug()).
308
   *
309
   * @param $server_version the version of the CAS server
310
   * @param $server_hostname the hostname of the CAS server
311
   * @param $server_port the port the CAS server is running on
312
   * @param $server_uri the URI the CAS server is responding on
313
   * @param $start_session Have phpCAS start PHP sessions (default true)
314
   *
315
   * @return a newly created CASClient object
316
   */
317
  function proxy($server_version,
318
                 $server_hostname,
319
                 $server_port,
320
                 $server_uri,
321
                  $start_session = true)
322
    {
323
      global $PHPCAS_CLIENT, $PHPCAS_INIT_CALL;
324

    
325
      $this->traceBegin();
326
      if ( is_object($PHPCAS_CLIENT) ) {
327
        $this->error($PHPCAS_INIT_CALL['method'].'() has already been called (at '.$PHPCAS_INIT_CALL['file'].':'.$PHPCAS_INIT_CALL['line'].')');
328
      }
329
      if ( gettype($server_version) != 'string' ) {
330
        $this->error('type mismatched for parameter $server_version (should be `string\')');
331
      }
332
      if ( gettype($server_hostname) != 'string' ) {
333
        $this->error('type mismatched for parameter $server_hostname (should be `string\')');
334
      }
335
      if ( gettype($server_port) != 'integer' ) {
336
        $this->error('type mismatched for parameter $server_port (should be `integer\')');
337
      }
338
      if ( gettype($server_uri) != 'string' ) {
339
        $this->error('type mismatched for parameter $server_uri (should be `string\')');
340
      }
341

    
342
      // store where the initialzer is called from
343
      $dbg = $this->backtrace();
344
      $PHPCAS_INIT_CALL = array('done' => TRUE,
345
                                'file' => $dbg[0]['file'],
346
                                'line' => $dbg[0]['line'],
347
                                'method' => __CLASS__.'::'.__FUNCTION__);
348

    
349
      // initialize the global object $PHPCAS_CLIENT
350
      $PHPCAS_CLIENT = new CASClient($server_version,TRUE/*proxy*/,$server_hostname,$server_port,$server_uri,$start_session);
351
      $this->traceEnd();
352
    }
353

    
354
  /** @} */
355
  // ########################################################################
356
  //  DEBUGGING
357
  // ########################################################################
358

    
359
  /**
360
   * @addtogroup publicDebug
361
   * @{
362
   */
363

    
364
  /**
365
   * Set/unset debug mode
366
   *
367
   * @param $filename the name of the file used for logging, or FALSE to stop debugging.
368
   */
369
  function setDebug($filename='')
370
    {
371
      global $PHPCAS_DEBUG;
372

    
373
      if ( $filename != FALSE && gettype($filename) != 'string' ) {
374
        $this->error('type mismatched for parameter $dbg (should be FALSE or the name of the log file)');
375
      }
376

    
377
      if ( empty($filename) ) {
378
              if ( preg_match('/^Win.*/',getenv('OS')) ) {
379
                if ( isset($_ENV['TMP']) ) {
380
                  $debugDir = $_ENV['TMP'].'/';
381
                } else if ( isset($_ENV['TEMP']) ) {
382
                  $debugDir = $_ENV['TEMP'].'/';
383
                } else {
384
                  $debugDir = '';
385
                }
386
              } else {
387
                $debugDir = '/tmp/';
388
              }
389
              $filename = $debugDir . 'phpCAS.log';
390
      }
391

    
392
      if ( empty($PHPCAS_DEBUG['unique_id']) ) {
393
        $PHPCAS_DEBUG['unique_id'] = substr(strtoupper(md5(uniqid(''))),0,4);
394
      }
395

    
396
      $PHPCAS_DEBUG['filename'] = $filename;
397

    
398
      $this->trace('START ******************');
399
    }
400
  
401
  /** @} */
402
  /**
403
   * @addtogroup internalDebug
404
   * @{
405
   */
406

    
407
  /**
408
   * This method is a wrapper for debug_backtrace() that is not available 
409
   * in all PHP versions (>= 4.3.0 only)
410
   */
411
  function backtrace()
412
    {
413
      if ( function_exists('debug_backtrace') ) {
414
        return debug_backtrace();
415
      } else {
416
        // poor man's hack ... but it does work ...
417
        return array();
418
      }
419
    }
420

    
421
  /**
422
   * Logs a string in debug mode.
423
   *
424
   * @param $str the string to write
425
   *
426
   * @private
427
   */
428
  function log($str)
429
    {
430
      $indent_str = ".";
431
      global $PHPCAS_DEBUG;
432

    
433
      if ( $PHPCAS_DEBUG['filename'] ) {
434
        for ($i=0;$i<$PHPCAS_DEBUG['indent'];$i++) {
435
          $indent_str .= '|    ';
436
        }
437
        error_log($PHPCAS_DEBUG['unique_id'].' '.$indent_str.$str."\n",3,$PHPCAS_DEBUG['filename']);
438
      }
439

    
440
    }
441
  
442
  /**
443
   * This method is used by interface methods to print an error and where the function
444
   * was originally called from.
445
   *
446
   * @param $msg the message to print
447
   *
448
   * @private
449
   */
450
  function error($msg)
451
    {
452
      $dbg = $this->backtrace();
453
      $function = '?';
454
      $file = '?';
455
      $line = '?';
456
      if ( is_array($dbg) ) {
457
        for ( $i=1; $i<sizeof($dbg); $i++) {
458
          if ( is_array($dbg[$i]) ) {
459
            if ( $dbg[$i]['class'] == __CLASS__ ) {
460
              $function = $dbg[$i]['function'];
461
              $file = $dbg[$i]['file'];
462
              $line = $dbg[$i]['line'];
463
            }
464
          }
465
        }
466
      }
467
      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";
468
      $this->trace($msg);
469
      $this->traceExit();
470
      exit();
471
    }
472

    
473
  /**
474
   * This method is used to log something in debug mode.
475
   */
476
  function trace($str)
477
    {
478
      $dbg = $this->backtrace();
479
      $this->log($str.' ['.basename($dbg[1]['file']).':'.$dbg[1]['line'].']');
480
    }
481

    
482
  /**
483
   * This method is used to indicate the start of the execution of a function in debug mode.
484
   */
485
  function traceBegin()
486
    {
487
      global $PHPCAS_DEBUG;
488
         if ( $PHPCAS_DEBUG['filename'] ) {
489
      $dbg = $this->backtrace();
490
      $str = '=> ';
491
      if ( !empty($dbg[2]['class']) ) {
492
        $str .= $dbg[2]['class'].'::';
493
      }
494
      $str .= $dbg[2]['function'].'(';      
495
      if ( is_array($dbg[2]['args']) ) {
496
        foreach ($dbg[2]['args'] as $index => $arg) {
497
          if ( $index != 0 ) {
498
            $str .= ', ';
499
          }
500
          $str .= str_replace("\n","",var_export($arg,TRUE));
501
        }
502
      }
503
      $str .= ') ['.basename($dbg[2]['file']).':'.$dbg[2]['line'].']';
504
      $this->log($str);
505
      $PHPCAS_DEBUG['indent'] ++;
506
        }
507
    }
508

    
509
  /**
510
   * This method is used to indicate the end of the execution of a function in debug mode.
511
   *
512
   * @param $res the result of the function
513
   */
514
  function traceEnd($res='')
515
    {
516
      global $PHPCAS_DEBUG;
517
         if ( $PHPCAS_DEBUG['filename'] ) {
518
      $PHPCAS_DEBUG['indent'] --;
519
      $dbg = $this->backtrace();
520
      $str = '';
521
      $str .= '<= '.str_replace("\n","",var_export($res,TRUE));
522
      $this->log($str);
523
        }
524
    }
525

    
526
  /**
527
   * This method is used to indicate the end of the execution of the program
528
   */
529
  function traceExit()
530
    {
531
      global $PHPCAS_DEBUG;
532

    
533
      $this->log('exit()');
534
      while ( $PHPCAS_DEBUG['indent'] > 0 ) {
535
        $this->log('-');
536
        $PHPCAS_DEBUG['indent'] --;
537
      }
538
    }
539

    
540
  /** @} */
541
  // ########################################################################
542
  //  INTERNATIONALIZATION
543
  // ########################################################################
544
  /**
545
   * @addtogroup publicLang
546
   * @{
547
   */
548

    
549
  /**
550
   * This method is used to set the language used by phpCAS. 
551
   * @note Can be called only once.
552
   *
553
   * @param $lang a string representing the language.
554
   *
555
   * @sa PHPCAS_LANG_FRENCH, PHPCAS_LANG_ENGLISH
556
   */
557
  function setLang($lang)
558
    {
559
      global $PHPCAS_CLIENT;
560
      if ( !is_object($PHPCAS_CLIENT) ) {
561
        $this->error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');
562
      }
563
      if ( gettype($lang) != 'string' ) {
564
        $this->error('type mismatched for parameter $lang (should be `string\')');
565
      }
566
      $PHPCAS_CLIENT->setLang($lang);
567
    }
568

    
569
  /** @} */
570
  // ########################################################################
571
  //  VERSION
572
  // ########################################################################
573
  /**
574
   * @addtogroup public
575
   * @{
576
   */
577

    
578
  /**
579
   * This method returns the phpCAS version.
580
   *
581
   * @return the phpCAS version.
582
   */
583
  function getVersion()
584
    {
585
      return PHPCAS_VERSION;
586
    }
587
  
588
  /** @} */
589
  // ########################################################################
590
  //  HTML OUTPUT
591
  // ########################################################################
592
  /**
593
   * @addtogroup publicOutput
594
   * @{
595
   */
596

    
597
  /**
598
   * This method sets the HTML header used for all outputs.
599
   *
600
   * @param $header the HTML header.
601
   */
602
  function setHTMLHeader($header)
603
    {
604
      global $PHPCAS_CLIENT;
605
      if ( !is_object($PHPCAS_CLIENT) ) {
606
        $this->error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');
607
      }
608
      if ( gettype($header) != 'string' ) {
609
        $this->error('type mismatched for parameter $header (should be `string\')');
610
      }
611
      $PHPCAS_CLIENT->setHTMLHeader($header);
612
    }
613

    
614
  /**
615
   * This method sets the HTML footer used for all outputs.
616
   *
617
   * @param $footer the HTML footer.
618
   */
619
  function setHTMLFooter($footer)
620
    {
621
      global $PHPCAS_CLIENT;
622
      if ( !is_object($PHPCAS_CLIENT) ) {
623
        $this->error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');
624
      }
625
      if ( gettype($footer) != 'string' ) {
626
        $this->error('type mismatched for parameter $footer (should be `string\')');
627
      }
628
      $PHPCAS_CLIENT->setHTMLFooter($footer);
629
    }
630

    
631
  /** @} */
632
  // ########################################################################
633
  //  PGT STORAGE
634
  // ########################################################################
635
  /**
636
   * @addtogroup publicPGTStorage
637
   * @{
638
   */
639

    
640
  /**
641
   * This method is used to tell phpCAS to store the response of the
642
   * CAS server to PGT requests onto the filesystem. 
643
   *
644
   * @param $format the format used to store the PGT's (`plain' and `xml' allowed)
645
   * @param $path the path where the PGT's should be stored
646
   */
647
  function setPGTStorageFile($format='',
648
                             $path='')
649
    {
650
      global $PHPCAS_CLIENT,$PHPCAS_AUTH_CHECK_CALL;
651

    
652
      $this->traceBegin();
653
      if ( !is_object($PHPCAS_CLIENT) ) {
654
        $this->error('this method should only be called after '.__CLASS__.'::proxy()');
655
      }
656
      if ( !$PHPCAS_CLIENT->isProxy() ) {
657
        $this->error('this method should only be called after '.__CLASS__.'::proxy()');
658
      }
659
      if ( $PHPCAS_AUTH_CHECK_CALL['done'] ) {
660
        $this->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'].')');
661
      }
662
      if ( gettype($format) != 'string' ) {
663
        $this->error('type mismatched for parameter $format (should be `string\')');
664
      }
665
      if ( gettype($path) != 'string' ) {
666
        $this->error('type mismatched for parameter $format (should be `string\')');
667
      }
668
      $PHPCAS_CLIENT->setPGTStorageFile($format,$path);
669
      $this->traceEnd();
670
    }
671
  
672
  /**
673
   * This method is used to tell phpCAS to store the response of the
674
   * CAS server to PGT requests into a database. 
675
   * @note The connection to the database is done only when needed. 
676
   * As a consequence, bad parameters are detected only when 
677
   * initializing PGT storage, except in debug mode.
678
   *
679
   * @param $user the user to access the data with
680
   * @param $password the user's password
681
   * @param $database_type the type of the database hosting the data
682
   * @param $hostname the server hosting the database
683
   * @param $port the port the server is listening on
684
   * @param $database the name of the database
685
   * @param $table the name of the table storing the data
686
   */
687
  function setPGTStorageDB($user,
688
                           $password,
689
                           $database_type='',
690
                           $hostname='',
691
                           $port=0,
692
                           $database='',
693
                           $table='')
694
    {
695
      global $PHPCAS_CLIENT,$PHPCAS_AUTH_CHECK_CALL;
696

    
697
      $this->traceBegin();
698
      if ( !is_object($PHPCAS_CLIENT) ) {
699
        $this->error('this method should only be called after '.__CLASS__.'::proxy()');
700
      }
701
      if ( !$PHPCAS_CLIENT->isProxy() ) {
702
        $this->error('this method should only be called after '.__CLASS__.'::proxy()');
703
      }
704
      if ( $PHPCAS_AUTH_CHECK_CALL['done'] ) {
705
        $this->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'].')');
706
      }
707
      if ( gettype($user) != 'string' ) {
708
        $this->error('type mismatched for parameter $user (should be `string\')');
709
      }
710
      if ( gettype($password) != 'string' ) {
711
        $this->error('type mismatched for parameter $password (should be `string\')');
712
      }
713
      if ( gettype($database_type) != 'string' ) {
714
        $this->error('type mismatched for parameter $database_type (should be `string\')');
715
      }
716
      if ( gettype($hostname) != 'string' ) {
717
        $this->error('type mismatched for parameter $hostname (should be `string\')');
718
      }
719
      if ( gettype($port) != 'integer' ) {
720
        $this->error('type mismatched for parameter $port (should be `integer\')');
721
      }
722
      if ( gettype($database) != 'string' ) {
723
        $this->error('type mismatched for parameter $database (should be `string\')');
724
      }
725
      if ( gettype($table) != 'string' ) {
726
        $this->error('type mismatched for parameter $table (should be `string\')');
727
      }
728
      $PHPCAS_CLIENT->setPGTStorageDB($this,$user,$password,$hostname,$port,$database,$table);
729
      $this->traceEnd();
730
    }
731
  
732
  /** @} */
733
  // ########################################################################
734
  // ACCESS TO EXTERNAL SERVICES
735
  // ########################################################################
736
  /**
737
   * @addtogroup publicServices
738
   * @{
739
   */
740

    
741
  /**
742
   * This method is used to access an HTTP[S] service.
743
   * 
744
   * @param $url the service to access.
745
   * @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on
746
   * success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE,
747
   * PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_NOT AVAILABLE.
748
   * @param $output the output of the service (also used to give an error
749
   * message on failure).
750
   *
751
   * @return TRUE on success, FALSE otherwise (in this later case, $err_code
752
   * gives the reason why it failed and $output contains an error message).
753
   */
754
  function serviceWeb($url,&$err_code,&$output)
755
    {
756
      global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
757

    
758
      $this->traceBegin();
759
      if ( !is_object($PHPCAS_CLIENT) ) {
760
        $this->error('this method should only be called after '.__CLASS__.'::proxy()');
761
      }
762
      if ( !$PHPCAS_CLIENT->isProxy() ) {
763
        $this->error('this method should only be called after '.__CLASS__.'::proxy()');
764
      }
765
      if ( !$PHPCAS_AUTH_CHECK_CALL['done'] ) {
766
        $this->error('this method should only be called after the programmer is sure the user has been authenticated (by calling '.__CLASS__.'::checkAuthentication() or '.__CLASS__.'::forceAuthentication()');
767
      }
768
      if ( !$PHPCAS_AUTH_CHECK_CALL['result'] ) {
769
        $this->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');
770
      }
771
      if ( gettype($url) != 'string' ) {
772
        $this->error('type mismatched for parameter $url (should be `string\')');
773
      }
774
      
775
      $res = $PHPCAS_CLIENT->serviceWeb($url,$err_code,$output);
776

    
777
      $this->traceEnd($res);
778
      return $res;
779
    }
780

    
781
  /**
782
   * This method is used to access an IMAP/POP3/NNTP service.
783
   * 
784
   * @param $url a string giving the URL of the service, including the mailing box
785
   * for IMAP URLs, as accepted by imap_open().
786
   * @param $flags options given to imap_open().
787
   * @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on
788
   * success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE,
789
   * PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_NOT AVAILABLE.
790
   * @param $err_msg an error message on failure
791
   * @param $pt the Proxy Ticket (PT) retrieved from the CAS server to access the URL
792
   * on success, FALSE on error).
793
   *
794
   * @return an IMAP stream on success, FALSE otherwise (in this later case, $err_code
795
   * gives the reason why it failed and $err_msg contains an error message).
796
   */
797
  function serviceMail($url,$flags,&$err_code,&$err_msg,&$pt)
798
    {
799
      global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
800

    
801
      $this->traceBegin();
802
      if ( !is_object($PHPCAS_CLIENT) ) {
803
        $this->error('this method should only be called after '.__CLASS__.'::proxy()');
804
      }
805
      if ( !$PHPCAS_CLIENT->isProxy() ) {
806
        $this->error('this method should only be called after '.__CLASS__.'::proxy()');
807
      }
808
      if ( !$PHPCAS_AUTH_CHECK_CALL['done'] ) {
809
        $this->error('this method should only be called after the programmer is sure the user has been authenticated (by calling '.__CLASS__.'::checkAuthentication() or '.__CLASS__.'::forceAuthentication()');
810
      }
811
      if ( !$PHPCAS_AUTH_CHECK_CALL['result'] ) {
812
        $this->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');
813
      }
814
      if ( gettype($url) != 'string' ) {
815
        $this->error('type mismatched for parameter $url (should be `string\')');
816
      }
817
      
818
      if ( gettype($flags) != 'integer' ) {
819
        $this->error('type mismatched for parameter $flags (should be `integer\')');
820
      }
821
      
822
      $res = $PHPCAS_CLIENT->serviceMail($url,$flags,$err_code,$err_msg,$pt);
823

    
824
      $this->traceEnd($res);
825
      return $res;
826
    }
827

    
828
  /** @} */
829
  // ########################################################################
830
  //  AUTHENTICATION
831
  // ########################################################################
832
  /**
833
   * @addtogroup publicAuth
834
   * @{
835
   */
836

    
837
  /**
838
   * Set the times authentication will be cached before really accessing the CAS server in gateway mode: 
839
   * - -1: check only once, and then never again (until you pree login)
840
   * - 0: always check
841
   * - n: check every "n" time
842
   *
843
   * @param $n an integer.
844
   */
845
  function setCacheTimesForAuthRecheck($n)
846
    {
847
      global $PHPCAS_CLIENT;
848
      if ( !is_object($PHPCAS_CLIENT) ) {
849
        $this->error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');
850
      }
851
      if ( gettype($header) != 'integer' ) {
852
        $this->error('type mismatched for parameter $header (should be `string\')');
853
      }
854
      $PHPCAS_CLIENT->setCacheTimesForAuthRecheck($n);
855
    }
856
  
857
  /**
858
   * This method is called to check if the user is authenticated (use the gateway feature).
859
   * @return TRUE when the user is authenticated; otherwise FALSE.
860
   */
861
  function checkAuthentication()
862
    {
863
      global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
864

    
865
      $this->traceBegin();
866
      if ( !is_object($PHPCAS_CLIENT) ) {
867
        $this->error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');
868
      }
869

    
870
      $auth = $PHPCAS_CLIENT->checkAuthentication();
871

    
872
      // store where the authentication has been checked and the result
873
      $dbg = $this->backtrace();
874
      $PHPCAS_AUTH_CHECK_CALL = array('done' => TRUE,
875
                                      'file' => $dbg[0]['file'],
876
                                      'line' => $dbg[0]['line'],
877
                                      'method' => __CLASS__.'::'.__FUNCTION__,
878
                                      'result' => $auth );
879
      $this->traceEnd($auth);
880
      return $auth; 
881
    }
882
  
883
  /**
884
   * This method is called to force authentication if the user was not already 
885
   * authenticated. If the user is not authenticated, halt by redirecting to 
886
   * the CAS server.
887
   */
888
  function forceAuthentication()
889
    {
890
      global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
891

    
892
      $this->traceBegin();
893
      if ( !is_object($PHPCAS_CLIENT) ) {
894
        $this->error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');
895
      }
896
      
897
      $auth = $PHPCAS_CLIENT->forceAuthentication();
898

    
899
      // store where the authentication has been checked and the result
900
      $dbg = $this->backtrace();
901
      $PHPCAS_AUTH_CHECK_CALL = array('done' => TRUE,
902
                                      'file' => $dbg[0]['file'],
903
                                      'line' => $dbg[0]['line'],
904
                                      'method' => __CLASS__.'::'.__FUNCTION__,
905
                                      'result' => $auth );
906

    
907
      if ( !$auth ) {
908
        $this->trace('user is not authenticated, redirecting to the CAS server');
909
        $PHPCAS_CLIENT->forceAuthentication();
910
      } else {
911
        $this->trace('no need to authenticate (user `'.$this->getUser().'\' is already authenticated)');
912
      }
913

    
914
      $this->traceEnd();
915
      return $auth; 
916
    }
917
  
918
  /**
919
   * This method has been left from version 0.4.1 for compatibility reasons.
920
   */
921
  function authenticate()
922
    {
923
      $this->error('this method is deprecated. You should use '.__CLASS__.'::forceAuthentication() instead');
924
    }
925
  
926
  /**
927
   * This method is called to check if the user is authenticated (previously or by
928
   * tickets given in the URL).
929
   *
930
   * @return TRUE when the user is authenticated.
931
   */
932
  function isAuthenticated()
933
    {
934
      global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
935

    
936
      $this->traceBegin();
937
      if ( !is_object($PHPCAS_CLIENT) ) {
938
        $this->error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');
939
      }
940

    
941
      // call the isAuthenticated method of the global $PHPCAS_CLIENT object
942
      $auth = $PHPCAS_CLIENT->isAuthenticated();
943

    
944
      // store where the authentication has been checked and the result
945
      $dbg = $this->backtrace();
946
      $PHPCAS_AUTH_CHECK_CALL = array('done' => TRUE,
947
                                     'file' => $dbg[0]['file'],
948
                                     'line' => $dbg[0]['line'],
949
                                     'method' => __CLASS__.'::'.__FUNCTION__,
950
                                     'result' => $auth );
951
      $this->traceEnd($auth);
952
      return $auth;
953
    }
954
  
955
  /**
956
   * Checks whether authenticated based on $_SESSION. Useful to avoid
957
   * server calls.
958
   * @return true if authenticated, false otherwise.
959
   * @since 0.4.22 by Brendan Arnold
960
   */
961
  function isSessionAuthenticated ()
962
        {
963
      global $PHPCAS_CLIENT;
964
      if ( !is_object($PHPCAS_CLIENT) ) {
965
        $this->error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');
966
      }
967
      return($PHPCAS_CLIENT->isSessionAuthenticated());
968
    }
969

    
970
  /**
971
   * This method returns the CAS user's login name.
972
   * @warning should not be called only after $this->forceAuthentication()
973
   * or $this->checkAuthentication().
974
   *
975
   * @return the login name of the authenticated user
976
   */
977
  function getUser()
978
    {
979
      global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
980
      if ( !is_object($PHPCAS_CLIENT) ) {
981
        $this->error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');
982
      }
983
      if ( !$PHPCAS_AUTH_CHECK_CALL['done'] ) {
984
        $this->error('this method should only be called after '.__CLASS__.'::forceAuthentication() or '.__CLASS__.'::isAuthenticated()');
985
      }
986
      if ( !$PHPCAS_AUTH_CHECK_CALL['result'] ) {
987
        $this->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');
988
      }
989
      return $PHPCAS_CLIENT->getUser();
990
    }
991

    
992
  /**
993
   * This method returns the URL to be used to login.
994
   * or $this->isAuthenticated().
995
   *
996
   * @return the login name of the authenticated user
997
   */
998
  function getServerLoginURL()
999
    {
1000
      global $PHPCAS_CLIENT;
1001
      if ( !is_object($PHPCAS_CLIENT) ) {
1002
        $this->error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');
1003
      }
1004
      return $PHPCAS_CLIENT->getServerLoginURL();
1005
    }
1006

    
1007
  /**
1008
   * Set the login URL of the CAS server.
1009
   * @param $url the login URL
1010
   * @since 0.4.21 by Wyman Chan
1011
   */
1012
  function setServerLoginURL($url='')
1013
   {
1014
     global $PHPCAS_CLIENT;
1015
     $this->traceBegin();
1016
     if ( !is_object($PHPCAS_CLIENT) ) {
1017
        $this->error('this method should only be called after
1018
'.__CLASS__.'::client()');
1019
     }
1020
     if ( gettype($url) != 'string' ) {
1021
        $this->error('type mismatched for parameter $url (should be
1022
`string\')');
1023
     }
1024
     $PHPCAS_CLIENT->setServerLoginURL($url);
1025
     $this->traceEnd();
1026
   }
1027

    
1028
  /**
1029
   * This method returns the URL to be used to login.
1030
   * or $this->isAuthenticated().
1031
   *
1032
   * @return the login name of the authenticated user
1033
   */
1034
  function getServerLogoutURL()
1035
    {
1036
      global $PHPCAS_CLIENT;
1037
      if ( !is_object($PHPCAS_CLIENT) ) {
1038
        $this->error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');
1039
      }
1040
      return $PHPCAS_CLIENT->getServerLogoutURL();
1041
    }
1042

    
1043
  /**
1044
   * Set the logout URL of the CAS server.
1045
   * @param $url the logout URL
1046
   * @since 0.4.21 by Wyman Chan
1047
   */
1048
  function setServerLogoutURL($url='')
1049
   {
1050
     global $PHPCAS_CLIENT;
1051
     $this->traceBegin();
1052
     if ( !is_object($PHPCAS_CLIENT) ) {
1053
        $this->error('this method should only be called after
1054
'.__CLASS__.'::client()');
1055
     }
1056
     if ( gettype($url) != 'string' ) {
1057
        $this->error('type mismatched for parameter $url (should be
1058
`string\')');
1059
     }
1060
     $PHPCAS_CLIENT->setServerLogoutURL($url);
1061
     $this->traceEnd();
1062
   }
1063

    
1064
  /**
1065
   * This method is used to logout from CAS. Halts by redirecting to the CAS server.
1066
   * @param $url a URL that will be transmitted to the CAS server (to come back to when logged out)
1067
   */
1068
  function logout($url = "")
1069
    {
1070
      global $PHPCAS_CLIENT;
1071

    
1072
      $this->traceBegin();
1073
      if ( !is_object($PHPCAS_CLIENT) ) {
1074
        $this->error('this method should only be called after '.__CLASS__.'::client() or'.__CLASS__.'::proxy()');
1075
      }
1076
      $PHPCAS_CLIENT->logout($url);
1077
      // never reached
1078
      $this->traceEnd();
1079
    }
1080

    
1081
  /**
1082
   * Set the fixed URL that will be used by the CAS server to transmit the PGT.
1083
   * When this method is not called, a phpCAS script uses its own URL for the callback.
1084
   *
1085
   * @param $url the URL
1086
   */
1087
  function setFixedCallbackURL($url='')
1088
   {
1089
     global $PHPCAS_CLIENT;
1090
     $this->traceBegin();
1091
     if ( !is_object($PHPCAS_CLIENT) ) {
1092
        $this->error('this method should only be called after '.__CLASS__.'::proxy()');
1093
     }
1094
     if ( !$PHPCAS_CLIENT->isProxy() ) {
1095
        $this->error('this method should only be called after '.__CLASS__.'::proxy()');
1096
     }
1097
     if ( gettype($url) != 'string' ) {
1098
        $this->error('type mismatched for parameter $url (should be `string\')');
1099
     }
1100
     $PHPCAS_CLIENT->setCallbackURL($url);
1101
     $this->traceEnd();
1102
   }
1103
   
1104
  /**
1105
   * Set the fixed URL that will be set as the CAS service parameter. When this
1106
   * method is not called, a phpCAS script uses its own URL.
1107
   *
1108
   * @param $url the URL
1109
   */
1110
   function setFixedServiceURL($url)
1111
   {
1112
     global $PHPCAS_CLIENT;
1113
     $this->traceBegin();
1114
     if ( !is_object($PHPCAS_CLIENT) ) {
1115
         $this->error('this method should only be called after '.__CLASS__.'::proxy()');
1116
     }  
1117
     if ( gettype($url) != 'string' ) {
1118
        $this->error('type mismatched for parameter $url (should be `string\')');
1119
     }
1120
     $PHPCAS_CLIENT->setURL($url);
1121
     $this->traceEnd();
1122
   }
1123

    
1124
  /**
1125
   * Get the URL that is set as the CAS service parameter.
1126
   */
1127
   function getServiceURL()
1128
   {
1129
     global $PHPCAS_CLIENT;
1130
     if ( !is_object($PHPCAS_CLIENT) ) {
1131
        $this->error('this method should only be called after '.__CLASS__.'::proxy()');
1132
     }  
1133
     return($PHPCAS_CLIENT->getURL());
1134
   }
1135

    
1136
  /**
1137
   * Retrieve a Proxy Ticket from the CAS server.
1138
   */
1139
   function retrievePT($target_service,&$err_code,&$err_msg)
1140
   {
1141
     global $PHPCAS_CLIENT;
1142
     if ( !is_object($PHPCAS_CLIENT) ) {
1143
        $this->error('this method should only be called after '.__CLASS__.'::proxy()');
1144
     }  
1145
     if ( gettype($target_service) != 'string' ) {
1146
        $this->error('type mismatched for parameter $target_service(should be `string\')');
1147
     }
1148
     return($PHPCAS_CLIENT->retrievePT($target_service,$err_code,$err_msg));
1149
   }
1150
  /** @} */
1151

    
1152
}
1153

    
1154
// ########################################################################
1155
// DOCUMENTATION
1156
// ########################################################################
1157

    
1158
// ########################################################################
1159
//  MAIN PAGE
1160

    
1161
/**
1162
 * @mainpage
1163
 *
1164
 * The following pages only show the source documentation.
1165
 *
1166
 * For more information on phpCAS, please refer to http://esup-phpcas.sourceforge.net
1167
 *
1168
 */
1169

    
1170
// ########################################################################
1171
//  MODULES DEFINITION
1172

    
1173
/** @defgroup public User interface */
1174

    
1175
/** @defgroup publicInit Initialization
1176
 *  @ingroup public */
1177

    
1178
/** @defgroup publicAuth Authentication
1179
 *  @ingroup public */
1180

    
1181
/** @defgroup publicServices Access to external services
1182
 *  @ingroup public */
1183

    
1184
/** @defgroup publicConfig Configuration
1185
 *  @ingroup public */
1186

    
1187
/** @defgroup publicLang Internationalization
1188
 *  @ingroup publicConfig */
1189

    
1190
/** @defgroup publicOutput HTML output
1191
 *  @ingroup publicConfig */
1192

    
1193
/** @defgroup publicPGTStorage PGT storage
1194
 *  @ingroup publicConfig */
1195

    
1196
/** @defgroup publicDebug Debugging
1197
 *  @ingroup public */
1198

    
1199

    
1200
/** @defgroup internal Implementation */
1201

    
1202
/** @defgroup internalAuthentication Authentication
1203
 *  @ingroup internal */
1204

    
1205
/** @defgroup internalBasic CAS Basic client features (CAS 1.0, Service Tickets)
1206
 *  @ingroup internal */
1207

    
1208
/** @defgroup internalProxy CAS Proxy features (CAS 2.0, Proxy Granting Tickets)
1209
 *  @ingroup internal */
1210

    
1211
/** @defgroup internalPGTStorage PGT storage
1212
 *  @ingroup internalProxy */
1213

    
1214
/** @defgroup internalPGTStorageDB PGT storage in a database
1215
 *  @ingroup internalPGTStorage */
1216

    
1217
/** @defgroup internalPGTStorageFile PGT storage on the filesystem
1218
 *  @ingroup internalPGTStorage */
1219

    
1220
/** @defgroup internalCallback Callback from the CAS server
1221
 *  @ingroup internalProxy */
1222

    
1223
/** @defgroup internalProxied CAS proxied client features (CAS 2.0, Proxy Tickets)
1224
 *  @ingroup internal */
1225

    
1226
/** @defgroup internalConfig Configuration
1227
 *  @ingroup internal */
1228

    
1229
/** @defgroup internalOutput HTML output
1230
 *  @ingroup internalConfig */
1231

    
1232
/** @defgroup internalLang Internationalization
1233
 *  @ingroup internalConfig
1234
 *
1235
 * To add a new language:
1236
 * - 1. define a new constant PHPCAS_LANG_XXXXXX in CAS/CAS.php
1237
 * - 2. copy any file from CAS/languages to CAS/languages/XXXXXX.php
1238
 * - 3. Make the translations
1239
 */
1240

    
1241
/** @defgroup internalDebug Debugging
1242
 *  @ingroup internal */
1243

    
1244
/** @defgroup internalMisc Miscellaneous
1245
 *  @ingroup internal */
1246

    
1247
// ########################################################################
1248
//  EXAMPLES
1249

    
1250
/**
1251
 * @example example_simple.php
1252
 */
1253
/**
1254
 * @example example_proxy.php
1255
 */
1256
/**
1257
 * @example example_proxy2.php
1258
 */
1259
/**
1260
 * @example example_lang.php
1261
 */
1262
/**
1263
 * @example example_html.php
1264
 */
1265
/**
1266
 * @example example_file.php
1267
 */
1268
/**
1269
 * @example example_db.php
1270
 */
1271
/**
1272
 * @example example_service.php
1273
 */
1274
/**
1275
 * @example example_session_proxy.php
1276
 */
1277
/**
1278
 * @example example_session_service.php
1279
 */
1280
/**
1281
 * @example example_gateway.php
1282
 */
1283

    
1284

    
1285

    
1286
?>
Redmine Appliance - Powered by TurnKey Linux