Subversion Repositories Sites.tela-botanica.org

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
420 florian 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
3
 
4
/**
5
 * The main include file for Auth package
6
 *
7
 * PHP versions 4 and 5
8
 *
9
 * LICENSE: This source file is subject to version 3.01 of the PHP license
10
 * that is available through the world-wide-web at the following URI:
11
 * http://www.php.net/license/3_01.txt.  If you did not receive a copy of
12
 * the PHP License and are unable to obtain it through the web, please
13
 * send a note to license@php.net so we can mail you a copy immediately.
14
 *
15
 * @category   Authentication
16
 * @package    Auth
17
 * @author     Martin Jansen <mj@php.net>
18
 * @author     Adam Ashley <aashley@php.net>
19
 * @copyright  2001-2006 The PHP Group
20
 * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
21
 * @version    CVS: $Id: Auth.php,v 1.107 2006/08/10 03:01:15 aashley Exp $
22
 * @link       http://pear.php.net/package/Auth
23
 */
24
 
25
/**
26
 * Returned if session exceeds idle time
27
 */
28
define('AUTH_IDLED',                    -1);
29
/**
30
 * Returned if session has expired
31
 */
32
define('AUTH_EXPIRED',                  -2);
33
/**
34
 * Returned if container is unable to authenticate user/password pair
35
 */
36
define('AUTH_WRONG_LOGIN',              -3);
37
/**
38
 * Returned if a container method is not supported.
39
 */
40
define('AUTH_METHOD_NOT_SUPPORTED',     -4);
41
/**
42
 * Returned if new Advanced security system detects a breach
43
 */
44
define('AUTH_SECURITY_BREACH',          -5);
45
 
46
/**
47
 * PEAR::Auth
48
 *
49
 * The PEAR::Auth class provides methods for creating an
50
 * authentication system using PHP.
51
 *
52
 * @category   Authentication
53
 * @package    Auth
54
 * @author     Martin Jansen <mj@php.net>
55
 * @author     Adam Ashley <aashley@php.net>
56
 * @copyright  2001-2006 The PHP Group
57
 * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
58
 * @version    Release: @package_version@  File: $Revision: 1.107 $
59
 * @link       http://pear.php.net/package/Auth
60
 */
61
class Auth {
62
 
63
    // {{{ properties
64
 
65
    /**
66
     * Auth lifetime in seconds
67
     *
68
     * If this variable is set to 0, auth never expires
69
     *
70
     * @var  integer
71
     * @see  setExpire(), checkAuth()
72
     */
73
    var $expire = 0;
74
 
75
    /**
76
     * Has the auth session expired?
77
     *
78
     * @var   bool
79
     * @see   checkAuth()
80
     */
81
    var $expired = false;
82
 
83
    /**
84
     * Maximum idletime in seconds
85
     *
86
     * The difference to $expire is, that the idletime gets
87
     * refreshed each time checkAuth() is called. If this
88
     * variable is set to 0, idletime is never checked.
89
     *
90
     * @var integer
91
     * @see setIdle(), checkAuth()
92
     */
93
    var $idle = 0;
94
 
95
    /**
96
     * Is the maximum idletime over?
97
     *
98
     * @var boolean
99
     * @see checkAuth()
100
     */
101
    var $idled = false;
102
 
103
    /**
104
     * Storage object
105
     *
106
     * @var object
107
     * @see Auth(), validateLogin()
108
     */
109
    var $storage = '';
110
 
111
    /**
112
     * User-defined function that creates the login screen
113
     *
114
     * @var string
115
     */
116
    var $loginFunction = '';
117
 
118
    /**
119
     * Should the login form be displayed
120
     *
121
     * @var   bool
122
     * @see   setShowlogin()
123
     */
124
    var $showLogin = true;
125
 
126
    /**
127
      * Is Login Allowed from this page
128
      *
129
      * @var  bool
130
      * @see setAllowLogin
131
      */
132
    var $allowLogin = true;
133
 
134
    /**
135
     * Current authentication status
136
     *
137
     * @var string
138
     */
139
    var $status = '';
140
 
141
    /**
142
     * Username
143
     *
144
     * @var string
145
     */
146
    var $username = '';
147
 
148
    /**
149
     * Password
150
     *
151
     * @var string
152
     */
153
    var $password = '';
154
 
155
    /**
156
     * Login callback function name
157
     *
158
     * @var string
159
     * @see setLoginCallback()
160
     */
161
    var $loginCallback = '';
162
 
163
    /**
164
     * Failed Login callback function name
165
     *
166
     * @var string
167
     * @see setFailedLoginCallback()
168
     */
169
    var $loginFailedCallback = '';
170
 
171
    /**
172
     * Logout callback function name
173
     *
174
     * @var string
175
     * @see setLogoutCallback()
176
     */
177
    var $logoutCallback = '';
178
 
179
    /**
180
     * Auth session-array name
181
     *
182
     * @var string
183
     */
184
    var $_sessionName = '_authsession';
185
 
186
    /**
187
     * Package Version
188
     *
189
     * @var string
190
     */
191
    var $version = "@version@";
192
 
193
    /**
194
     * Flag to use advanced security
195
     * When set extra checks will be made to see if the
196
     * user's IP or useragent have changed across requests.
197
     * Turned off by default to preserve BC.
198
     *
199
     * @var boolean
200
     */
201
    var $advancedsecurity = false;
202
 
203
    /**
204
     * Username key in POST array
205
     *
206
     * @var string
207
     */
208
    var $_postUsername = 'username';
209
 
210
    /**
211
     * Password key in POST array
212
     *
213
     * @var string
214
     */
215
    var $_postPassword = 'password';
216
 
217
    /**
218
     * Holds a reference to the session auth variable
219
     * @var array
220
     */
221
    var $session;
222
 
223
    /**
224
     * Holds a reference to the global server variable
225
     * @var array
226
     */
227
    var $server;
228
 
229
    /**
230
     * Holds a reference to the global post variable
231
     * @var array
232
     */
233
    var $post;
234
 
235
    /**
236
     * Holds a reference to the global cookie variable
237
     * @var array
238
     */
239
    var $cookie;
240
 
241
    /**
242
     * A hash to hold various superglobals as reference
243
     * @var array
244
     */
245
    var $authdata;
246
 
247
    /**
248
      * How many times has checkAuth been called
249
      * var int
250
      */
251
    var $authChecks = 0;
252
 
253
    // }}}
254
    // {{{ Auth() [constructor]
255
 
256
    /**
257
     * Constructor
258
     *
259
     * Set up the storage driver.
260
     *
261
     * @param string    Type of the storage driver
262
     * @param mixed     Additional options for the storage driver
263
     *                  (example: if you are using DB as the storage
264
     *                   driver, you have to pass the dsn string here)
265
     *
266
     * @param string    Name of the function that creates the login form
267
     * @param boolean   Should the login form be displayed if neccessary?
268
     * @return void
269
     */
270
    function Auth($storageDriver, $options = '', $loginFunction = '', $showLogin = true)
271
    {
272
        $this->applyAuthOptions($options);
273
 
274
        // Start the session suppress error if already started
275
        if(!session_id()){
276
            @session_start();
277
            if(!session_id()) {
278
                // Throw error
279
                include_once 'PEAR.php';
280
                PEAR::throwError('Session could not be started by Auth, '
281
                        .'possibly headers are already sent, try putting '
282
                        .'ob_start in the beginning of your script');
283
            }
284
        }
285
 
286
        // Make Sure Auth session variable is there
287
        if(   !isset($_SESSION[$this->_sessionName])
288
           && !isset($GLOBALS['HTTP_SESSION_VARS'][$this->_sessionName])) {
289
            isset($_SESSION)
290
                ? $_SESSION[$this->_sessionName] = array()
291
                : $GLOBALS['HTTP_SESSION_VARS'][$this->_sessionName] = array();
292
        }
293
 
294
        // Assign Some globals to internal references, this will replace _importGlobalVariable
295
        isset($_SESSION)
296
            ? $this->session =& $_SESSION[$this->_sessionName]
297
            : $this->session =& $GLOBALS['HTTP_SESSION_VARS'][$this->_sessionName] ;
298
        isset($_SERVER)
299
            ? $this->server =& $_SERVER
300
            : $this->server =& $GLOBALS['HTTP_SERVER_VARS'];
301
        isset($_POST)
302
            ? $this->post =& $_POST
303
            : $this->post =& $GLOBALS['HTTP_POST_VARS'];
304
        isset($_COOKIE)
305
            ? $this->cookie =& $_COOKIE
306
            : $this->cookie =& $GLOBALS['HTTP_COOKIE_VARS'];
307
        //isset($_GET) ? $var = &$_GET : $var = &$GLOBALS['HTTP_GET_VARS'];
308
 
309
        if ($loginFunction != '' && is_callable($loginFunction)) {
310
            $this->loginFunction = $loginFunction;
311
        }
312
 
313
        if (is_bool($showLogin)) {
314
            $this->showLogin = $showLogin;
315
        }
316
 
317
        if (is_object($storageDriver)) {
318
            $this->storage =& $storageDriver;
319
            // Pass a reference to auth to the container, ugly but works
320
            // this is used by the DB container to use method setAuthData not staticaly.
321
            $this->storage->_auth_obj =& $this;
322
        } else {
323
            // $this->storage = $this->_factory($storageDriver, $options);
324
            //
325
            $this->storage_driver = $storageDriver;
326
            $this->storage_options =& $options;
327
        }
328
    }
329
 
330
    // }}}
331
    // {{{ applyAuthOptions()
332
 
333
    /**
334
      * Set the Auth options
335
      *
336
      * Some options which are Auth specific will be applied
337
      * the rest will be left for usage by the container
338
      *
339
      * @param array    An array of Auth options
340
      * @return array   The options which were not applied
341
      * @access private
342
      */
343
    function &applyAuthOptions(&$options)
344
    {
345
        if(is_array($options)){
346
            if (!empty($options['sessionName'])) {
347
                $this->_sessionName = $options['sessionName'];
348
                unset($options['sessionName']);
349
            }
350
            if (isset($options['allowLogin'])) {
351
                $this->allowLogin = $options['allowLogin'];
352
                unset($options['allowLogin']);
353
            }
354
            if (!empty($options['postUsername'])) {
355
                $this->_postUsername = $options['postUsername'];
356
                unset($options['postUsername']);
357
            }
358
            if (!empty($options['postPassword'])) {
359
                $this->_postPassword = $options['postPassword'];
360
                unset($options['postPassword']);
361
            }
362
            if (isset($options['advancedsecurity'])) {
363
                $this->advancedsecurity = $options['advancedsecurity'];
364
                unset($options['advancedsecurity']);
365
            }
366
        }
367
        return($options);
368
    }
369
 
370
    // }}}
371
    // {{{ _loadStorage()
372
 
373
    /**
374
      * Load Storage Driver if not already loaded
375
      *
376
      * Suspend storage instantiation to make Auth lighter to use
377
      * for calls which do not require login
378
      *
379
      * @return bool    True if the conainer is loaded, false if the container
380
      *                 is already loaded
381
      * @access private
382
      */
383
    function _loadStorage()
384
    {
385
        if(!is_object($this->storage)) {
386
            $this->storage =& $this->_factory($this->storage_driver,
387
                    $this->storage_options);
388
            $this->storage->_auth_obj =& $this;
389
            return(true);
390
        }
391
        return(false);
392
    }
393
 
394
    // }}}
395
    // {{{ _factory()
396
 
397
    /**
398
     * Return a storage driver based on $driver and $options
399
     *
400
     * @static
401
     * @param  string $driver  Type of storage class to return
402
     * @param  string $options Optional parameters for the storage class
403
     * @return object Object   Storage object
404
     * @access private
405
     */
406
    function &_factory($driver, $options = '')
407
    {
408
        $storage_class = 'Auth_Container_' . $driver;
409
        include_once $driver . '.php';
410
        $obj =& new $storage_class($options);
411
        return $obj;
412
    }
413
 
414
    // }}}
415
    // {{{ assignData()
416
 
417
    /**
418
     * Assign data from login form to internal values
419
     *
420
     * This function takes the values for username and password
421
     * from $HTTP_POST_VARS/$_POST and assigns them to internal variables.
422
     * If you wish to use another source apart from $HTTP_POST_VARS/$_POST,
423
     * you have to derive this function.
424
     *
425
     * @global $HTTP_POST_VARS, $_POST
426
     * @see    Auth
427
     * @return void
428
     * @access private
429
     */
430
    function assignData()
431
    {
432
        if (   isset($this->post[$this->_postUsername])
433
            && $this->post[$this->_postUsername] != '') {
434
            $this->username = (get_magic_quotes_gpc() == 1
435
                    ? stripslashes($this->post[$this->_postUsername])
436
                    : $this->post[$this->_postUsername]);
437
        }
438
        if (   isset($this->post[$this->_postPassword])
439
            && $this->post[$this->_postPassword] != '') {
440
            $this->password = (get_magic_quotes_gpc() == 1
441
                    ? stripslashes($this->post[$this->_postPassword])
442
                    : $this->post[$this->_postPassword] );
443
        }
444
    }
445
 
446
    // }}}
447
    // {{{ start()
448
 
449
    /**
450
     * Start new auth session
451
     *
452
     * @return void
453
     * @access public
454
     */
455
    function start()
456
    {
457
        $this->assignData();
458
        if (!$this->checkAuth() && $this->allowLogin) {
459
            $this->login();
460
        }
461
    }
462
 
463
    // }}}
464
    // {{{ login()
465
 
466
    /**
467
     * Login function
468
     *
469
     * @return void
470
     * @access private
471
     */
472
    function login()
473
    {
474
        $login_ok = false;
475
        $this->_loadStorage();
476
 
477
        // Check if using challenge response
478
        (isset($this->post['authsecret']) && $this->post['authsecret'] == 1)
479
            ? $usingChap = true
480
            : $usingChap = false;
481
 
482
 
483
        // When the user has already entered a username, we have to validate it.
484
        if (!empty($this->username)) {
485
            if (true === $this->storage->fetchData($this->username, $this->password, $usingChap)) {
486
                $this->session['challengekey'] = md5($this->username.$this->password);
487
                $login_ok = true;
488
            }
489
        }
490
 
491
        if (!empty($this->username) && $login_ok) {
492
            $this->setAuth($this->username);
493
            if (is_callable($this->loginCallback)) {
494
                call_user_func_array($this->loginCallback, array($this->username, $this));
495
            }
496
        }
497
 
498
        // If the login failed or the user entered no username,
499
        // output the login screen again.
500
        if (!empty($this->username) && !$login_ok) {
501
            $this->status = AUTH_WRONG_LOGIN;
502
            if (is_callable($this->loginFailedCallback)) {
503
                call_user_func_array($this->loginFailedCallback, array($this->username, $this));
504
            }
505
        }
506
 
507
        if ((empty($this->username) || !$login_ok) && $this->showLogin) {
508
            if (is_callable($this->loginFunction)) {
509
                call_user_func_array($this->loginFunction, array($this->username, $this->status, $this));
510
            } else {
511
                // BC fix Auth used to use drawLogin for this
512
                // call is sub classes implement this
513
                if (is_callable(array($this, 'drawLogin'))) {
514
                    return $this->drawLogin($this->username, $this);
515
                }
516
 
517
                // New Login form
518
                include_once 'Html.php';
519
                return Auth_Frontend_Html::render($this, $this->username);
520
            }
521
        } else {
522
            return;
523
        }
524
    }
525
 
526
    // }}}
527
    // {{{ setExpire()
528
 
529
    /**
530
     * Set the maximum expire time
531
     *
532
     * @param  integer time in seconds
533
     * @param  bool    add time to current expire time or not
534
     * @return void
535
     * @access public
536
     */
537
    function setExpire($time, $add = false)
538
    {
539
        $add ? $this->expire += $time : $this->expire = $time;
540
    }
541
 
542
    // }}}
543
    // {{{ setIdle()
544
 
545
    /**
546
     * Set the maximum idle time
547
     *
548
     * @param  integer time in seconds
549
     * @param  bool    add time to current maximum idle time or not
550
     * @return void
551
     * @access public
552
     */
553
    function setIdle($time, $add = false)
554
    {
555
        $add ? $this->idle += $time : $this->idle = $time;
556
    }
557
 
558
    // }}}
559
    // {{{ setSessionName()
560
 
561
    /**
562
     * Set name of the session to a customized value.
563
     *
564
     * If you are using multiple instances of PEAR::Auth
565
     * on the same domain, you can change the name of
566
     * session per application via this function.
567
     * This will chnage the name of the session variable
568
     * auth uses to store it's data in the session
569
     *
570
     * @param  string New name for the session
571
     * @return void
572
     * @access public
573
     */
574
    function setSessionName($name = 'session')
575
    {
576
        $this->_sessionName = '_auth_'.$name;
577
        isset($_SESSION)
578
            ? $this->session =& $_SESSION[$this->_sessionName]
579
            : $this->session =& $GLOBALS['HTTP_SESSION_VARS'][$this->_sessionName] ;
580
    }
581
 
582
    // }}}
583
    // {{{ setShowLogin()
584
 
585
    /**
586
     * Should the login form be displayed if neccessary?
587
     *
588
     * @param  bool    show login form or not
589
     * @return void
590
     * @access public
591
     */
592
    function setShowLogin($showLogin = true)
593
    {
594
        $this->showLogin = $showLogin;
595
    }
596
 
597
    // }}}
598
    // {{{ setAllowLogin()
599
 
600
    /**
601
     * Should the login form be displayed if neccessary?
602
     *
603
     * @param  bool    show login form or not
604
     * @return void
605
     * @access public
606
     */
607
    function setAllowLogin($allowLogin = true)
608
    {
609
        $this->allowLogin = $allowLogin;
610
    }
611
 
612
    // }}}
613
    // {{{ setLoginCallback()
614
 
615
    /**
616
     * Register a callback function to be called on user login.
617
     * The function will receive two parameters, the username and a reference to the auth object.
618
     *
619
     * @param  string  callback function name
620
     * @return void
621
     * @see    setLogoutCallback()
622
     * @access public
623
     */
624
    function setLoginCallback($loginCallback)
625
    {
626
        $this->loginCallback = $loginCallback;
627
    }
628
 
629
    // }}}
630
    // {{{ setFailedLoginCallback()
631
 
632
    /**
633
     * Register a callback function to be called on failed user login.
634
     * The function will receive a single parameter, the username and a reference to the auth object.
635
     *
636
     * @param  string  callback function name
637
     * @return void
638
     * @access public
639
     */
640
    function setFailedLoginCallback($loginFailedCallback)
641
    {
642
        $this->loginFailedCallback = $loginFailedCallback;
643
    }
644
 
645
    // }}}
646
    // {{{ setLogoutCallback()
647
 
648
    /**
649
     * Register a callback function to be called on user logout.
650
     * The function will receive three parameters, the username and a reference to the auth object.
651
     *
652
     * @param  string  callback function name
653
     * @return void
654
     * @see    setLoginCallback()
655
     * @access public
656
     */
657
    function setLogoutCallback($logoutCallback)
658
    {
659
        $this->logoutCallback = $logoutCallback;
660
    }
661
 
662
    // }}}
663
    // {{{ setAuthData()
664
 
665
    /**
666
     * Register additional information that is to be stored
667
     * in the session.
668
     *
669
     * @param  string  Name of the data field
670
     * @param  mixed   Value of the data field
671
     * @param  boolean Should existing data be overwritten? (default
672
     *                 is true)
673
     * @return void
674
     * @access public
675
     */
676
    function setAuthData($name, $value, $overwrite = true)
677
    {
678
        if (!empty($this->session['data'][$name]) && $overwrite == false) {
679
            return;
680
        }
681
        $this->session['data'][$name] = $value;
682
    }
683
 
684
    // }}}
685
    // {{{ getAuthData()
686
 
687
    /**
688
     * Get additional information that is stored in the session.
689
     *
690
     * If no value for the first parameter is passed, the method will
691
     * return all data that is currently stored.
692
     *
693
     * @param  string Name of the data field
694
     * @return mixed  Value of the data field.
695
     * @access public
696
     */
697
    function getAuthData($name = null)
698
    {
699
        if (!isset($this->session['data'])) {
700
            return null;
701
        }
702
        if(!isset($name)) {
703
            return $this->session['data'];
704
        }
705
        if (isset($name) && isset($this->session['data'][$name])) {
706
            return $this->session['data'][$name];
707
        }
708
        return null;
709
    }
710
 
711
    // }}}
712
    // {{{ setAuth()
713
 
714
    /**
715
     * Register variable in a session telling that the user
716
     * has logged in successfully
717
     *
718
     * @param  string Username
719
     * @return void
720
     * @access public
721
     */
722
    function setAuth($username)
723
    {
724
 
725
        // #2021 - Change the session id to avoid session fixation attacks php 4.3.3 >
726
//        session_regenerate_id(true);
727
 
728
        if (!isset($this->session) || !is_array($this->session)) {
729
            $this->session = array();
730
        }
731
 
732
        if (!isset($this->session['data'])) {
733
            $this->session['data'] = array();
734
        }
735
 
736
        $this->session['sessionip'] = isset($this->server['REMOTE_ADDR'])
737
            ? $this->server['REMOTE_ADDR']
738
            : '';
739
        $this->session['sessionuseragent'] = isset($this->server['HTTP_USER_AGENT'])
740
            ? $this->server['HTTP_USER_AGENT']
741
            : '';
742
 
743
        // This should be set by the container to something more safe
744
        // Like md5(passwd.microtime)
745
        if(empty($this->session['challengekey'])) {
746
            $this->session['challengekey'] = md5($username.microtime());
747
        }
748
 
749
        $this->session['challengecookie'] = md5($this->session['challengekey'].microtime());
750
        setcookie('authchallenge', $this->session['challengecookie']);
751
 
752
        $this->session['registered'] = true;
753
        $this->session['username']   = $username;
754
        $this->session['timestamp']  = time();
755
        $this->session['idle']       = time();
756
    }
757
 
758
    // }}}
759
    // {{{ setAdvancedSecurity()
760
 
761
    /**
762
      * Enables advanced security checks
763
      *
764
      * Currently only ip change and useragent change
765
      * are detected
766
      * @todo Add challenge cookies - Create a cookie which changes every time
767
      *       and contains some challenge key which the server can verify with
768
      *       a session var cookie might need to be crypted (user pass)
769
      * @param bool Enable or disable
770
      * @return void
771
      * @access public
772
      */
773
    function setAdvancedSecurity($flag=true)
774
    {
775
        $this->advancedsecurity = $flag;
776
    }
777
 
778
    // }}}
779
    // {{{ checkAuth()
780
 
781
    /**
782
     * Checks if there is a session with valid auth information.
783
     *
784
     * @access public
785
     * @return boolean  Whether or not the user is authenticated.
786
     */
787
    function checkAuth()
788
    {
789
        $this->authChecks++;
790
        if (isset($this->session)) {
791
            // Check if authentication session is expired
792
            if (   $this->expire > 0
793
                && isset($this->session['timestamp'])
794
                && ($this->session['timestamp'] + $this->expire) < time()) {
795
                $this->expired = true;
796
                $this->status = AUTH_EXPIRED;
797
                $this->logout();
798
                return false;
799
            }
800
 
801
            // Check if maximum idle time is reached
802
            if (   $this->idle > 0
803
                && isset($this->session['idle'])
804
                && ($this->session['idle'] + $this->idle) < time()) {
805
                $this->idled = true;
806
                $this->status = AUTH_IDLED;
807
                $this->logout();
808
                return false;
809
            }
810
 
811
            if (   isset($this->session['registered'])
812
                && isset($this->session['username'])
813
                && $this->session['registered'] == true
814
                && $this->session['username'] != '') {
815
                Auth::updateIdle();
816
 
817
                if ($this->advancedsecurity) {
818
 
819
                    // Only Generate the challenge once
820
                    if($this->authChecks == 1) {
821
                        $this->session['challengecookieold'] = $this->session['challengecookie'];
822
                        $this->session['challengecookie'] = md5($this->session['challengekey'].microtime());
823
                        setcookie('authchallenge', $this->session['challengecookie']);
824
                    }
825
 
826
                    // Check for ip change
827
                    if (   isset($this->server['REMOTE_ADDR'])
828
                        && $this->session['sessionip'] != $this->server['REMOTE_ADDR']) {
829
                        // Check if the IP of the user has changed, if so we
830
                        // assume a man in the middle attack and log him out
831
                        $this->expired = true;
832
                        $this->status = AUTH_SECURITY_BREACH;
833
                        $this->logout();
834
                        return false;
835
                    }
836
 
837
                    // Check for useragent change
838
                    if (   isset($this->server['HTTP_USER_AGENT'])
839
                        && $this->session['sessionuseragent'] != $this->server['HTTP_USER_AGENT']) {
840
                        // Check if the User-Agent of the user has changed, if
841
                        // so we assume a man in the middle attack and log him out
842
                        $this->expired = true;
843
                        $this->status = AUTH_SECURITY_BREACH;
844
                        $this->logout();
845
                        return false;
846
                    }
847
 
848
                    // Check challenge cookie here, if challengecookieold is not set
849
                    // this is the first time and check is skipped
850
                    // TODO when user open two pages similtaneuly (open in new window,open
851
                    // in tab) auth breach is caused find out a way around that if possible
852
                    if (   isset($this->session['challengecookieold'])
853
                        && $this->session['challengecookieold'] != $this->cookie['authchallenge']) {
854
                        $this->expired = true;
855
                        $this->status = AUTH_SECURITY_BREACH;
856
                        $this->logout();
857
                        $this->login();
858
                        return false;
859
                    }
860
                }
861
 
862
                return true;
863
            }
864
        }
865
        return false;
866
    }
867
 
868
    // }}}
869
    // {{{ staticCheckAuth() [static]
870
 
871
    /**
872
     * Statically checks if there is a session with valid auth information.
873
     *
874
     * @access public
875
     * @see checkAuth
876
     * @return boolean  Whether or not the user is authenticated.
877
     * @static
878
     */
879
    function staticCheckAuth($options = null)
880
    {
881
        static $staticAuth;
882
        if(!isset($staticAuth)) {
883
            $staticAuth = new Auth('null', $options);
884
        }
885
        return $staticAuth->checkAuth();
886
    }
887
 
888
    // }}}
889
    // {{{ getAuth()
890
 
891
    /**
892
     * Has the user been authenticated?
893
     *
894
     * @access public
895
     * @return bool  True if the user is logged in, otherwise false.
896
     */
897
    function getAuth()
898
    {
899
        return $this->checkAuth();
900
    }
901
 
902
    // }}}
903
    // {{{ logout()
904
 
905
    /**
906
     * Logout function
907
     *
908
     * This function clears any auth tokens in the currently
909
     * active session and executes the logout callback function,
910
     * if any
911
     *
912
     * @access public
913
     * @return void
914
     */
915
    function logout()
916
    {
917
        if (is_callable($this->logoutCallback)) {
918
            call_user_func_array($this->logoutCallback, array($this->session['username'], $this));
919
        }
920
 
921
        $this->username = '';
922
        $this->password = '';
923
 
924
        $this->session = null;
925
    }
926
 
927
    // }}}
928
    // {{{ updateIdle()
929
 
930
    /**
931
     * Update the idletime
932
     *
933
     * @access private
934
     * @return void
935
     */
936
    function updateIdle()
937
    {
938
        $this->session['idle'] = time();
939
    }
940
 
941
    // }}}
942
    // {{{ getUsername()
943
 
944
    /**
945
     * Get the username
946
     *
947
     * @return string
948
     * @access public
949
     */
950
    function getUsername()
951
    {
952
        if (isset($this->session['username'])) {
953
            return($this->session['username']);
954
        }
955
        return('');
956
    }
957
 
958
    // }}}
959
    // {{{ getStatus()
960
 
961
    /**
962
     * Get the current status
963
     *
964
     * @return string
965
     * @access public
966
     */
967
    function getStatus()
968
    {
969
        return $this->status;
970
    }
971
 
972
    // }}}
973
    // {{{ getPostUsernameField()
974
 
975
    /**
976
     * Gets the post varible used for the username
977
     *
978
     * @return string
979
     * @access public
980
     */
981
    function getPostUsernameField()
982
    {
983
        return($this->_postUsername);
984
    }
985
 
986
    // }}}
987
    // {{{ getPostPasswordField()
988
 
989
    /**
990
     * Gets the post varible used for the username
991
     *
992
     * @return string
993
     * @access public
994
     */
995
    function getPostPasswordField()
996
    {
997
        return($this->_postPassword);
998
    }
999
 
1000
    // }}}
1001
    // {{{ sessionValidThru()
1002
 
1003
    /**
1004
     * Returns the time up to the session is valid
1005
     *
1006
     * @access public
1007
     * @return integer
1008
     */
1009
    function sessionValidThru()
1010
    {
1011
        if (!isset($this->session['idle'])) {
1012
            return 0;
1013
        }
1014
        if ($this->idle == 0) {
1015
            return 0;
1016
        }
1017
        return ($this->session['idle'] + $this->idle);
1018
    }
1019
 
1020
    // }}}
1021
    // {{{ listUsers()
1022
 
1023
    /**
1024
     * List all users that are currently available in the storage
1025
     * container
1026
     *
1027
     * @access public
1028
     * @return array
1029
     */
1030
    function listUsers()
1031
    {
1032
        $this->_loadStorage();
1033
        return $this->storage->listUsers();
1034
    }
1035
 
1036
    // }}}
1037
    // {{{ addUser()
1038
 
1039
    /**
1040
     * Add user to the storage container
1041
     *
1042
     * @access public
1043
     * @param  string Username
1044
     * @param  string Password
1045
     * @param  mixed  Additional parameters
1046
     * @return mixed  True on success, PEAR error object on error
1047
     *                and AUTH_METHOD_NOT_SUPPORTED otherwise.
1048
     */
1049
    function addUser($username, $password, $additional = '')
1050
    {
1051
        $this->_loadStorage();
1052
        return $this->storage->addUser($username, $password, $additional);
1053
    }
1054
 
1055
    // }}}
1056
    // {{{ removeUser()
1057
 
1058
    /**
1059
     * Remove user from the storage container
1060
     *
1061
     * @access public
1062
     * @param  string Username
1063
     * @return mixed  True on success, PEAR error object on error
1064
     *                and AUTH_METHOD_NOT_SUPPORTED otherwise.
1065
     */
1066
    function removeUser($username)
1067
    {
1068
        $this->_loadStorage();
1069
        return $this->storage->removeUser($username);
1070
    }
1071
 
1072
    // }}}
1073
    // {{{ changePassword()
1074
 
1075
    /**
1076
     * Change password for user in the storage container
1077
     *
1078
     * @access public
1079
     * @param string Username
1080
     * @param string The new password
1081
     * @return mixed True on success, PEAR error object on error
1082
     *               and AUTH_METHOD_NOT_SUPPORTED otherwise.
1083
     */
1084
    function changePassword($username, $password)
1085
    {
1086
        $this->_loadStorage();
1087
        return $this->storage->changePassword($username, $password);
1088
    }
1089
 
1090
    // }}}
1091
 
1092
}
1093
?>