Auth
[ class tree: Auth ] [ index: Auth ] [ all elements ]

Source for file Auth.php

Documentation is available at Auth.php

  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 289651 2009-10-15 04:39:07Z aashley $
  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.  * Returned if checkAuthCallback says session should not continue.
  47.  */
  48. define('AUTH_CALLBACK_ABORT',           -6);
  49.  
  50. /**
  51.  * Auth Log level - INFO
  52.  */
  53. define('AUTH_LOG_INFO',     6);
  54. /**
  55.  * Auth Log level - DEBUG
  56.  */
  57. define('AUTH_LOG_DEBUG',    7);
  58.  
  59. /**
  60.  * Auth Advanced Security - IP Checks
  61.  */
  62. define('AUTH_ADV_IPCHECK'1);
  63. /**
  64.  * Auth Advanced Security - User Agent Checks
  65.  */
  66. define('AUTH_ADV_USERAGENT'2);
  67. /**
  68.  * Auth Advanced Security - Challenge Response
  69.  */
  70. define('AUTH_ADV_CHALLENGE'3);
  71.  
  72.  
  73. /**
  74.  * PEAR::Auth
  75.  *
  76.  * The PEAR::Auth class provides methods for creating an
  77.  * authentication system using PHP.
  78.  *
  79.  * @category   Authentication
  80.  * @package    Auth
  81.  * @author     Martin Jansen <mj@php.net>
  82.  * @author     Adam Ashley <aashley@php.net>
  83.  * @copyright  2001-2006 The PHP Group
  84.  * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
  85.  * @version    Release: @package_version@  File: $Revision: 289651 $
  86.  * @link       http://pear.php.net/package/Auth
  87.  */
  88. class Auth {
  89.  
  90.     // {{{ properties
  91.  
  92.     /**
  93.      * Auth lifetime in seconds
  94.      *
  95.      * If this variable is set to 0, auth never expires
  96.      *
  97.      * @var  integer 
  98.      * @see  setExpire(), checkAuth()
  99.      */
  100.     var $expire = 0;
  101.  
  102.     /**
  103.      * Has the auth session expired?
  104.      *
  105.      * @var   bool 
  106.      * @see   checkAuth()
  107.      */
  108.     var $expired = false;
  109.  
  110.     /**
  111.      * Maximum idletime in seconds
  112.      *
  113.      * The difference to $expire is, that the idletime gets
  114.      * refreshed each time checkAuth() is called. If this
  115.      * variable is set to 0, idletime is never checked.
  116.      *
  117.      * @var integer 
  118.      * @see setIdle(), checkAuth()
  119.      */
  120.     var $idle = 0;
  121.  
  122.     /**
  123.      * Is the maximum idletime over?
  124.      *
  125.      * @var boolean 
  126.      * @see checkAuth()
  127.      */
  128.     var $idled = false;
  129.  
  130.     /**
  131.      * Storage object
  132.      *
  133.      * @var object 
  134.      * @see Auth(), validateLogin()
  135.      */
  136.     var $storage = '';
  137.  
  138.     /**
  139.      * User-defined function that creates the login screen
  140.      *
  141.      * @var string 
  142.      */
  143.     var $loginFunction = '';
  144.  
  145.     /**
  146.      * Should the login form be displayed
  147.      *
  148.      * @var   bool 
  149.      * @see   setShowlogin()
  150.      */
  151.     var $showLogin = true;
  152.  
  153.     /**
  154.       * Is Login Allowed from this page
  155.       *
  156.       * @var  bool 
  157.       * @see setAllowLogin
  158.       */
  159.     var $allowLogin = true;
  160.  
  161.     /**
  162.      * Current authentication status
  163.      *
  164.      * @var string 
  165.      */
  166.     var $status = '';
  167.  
  168.     /**
  169.      * Username
  170.      *
  171.      * @var string 
  172.      */
  173.     var $username = '';
  174.  
  175.     /**
  176.      * Password
  177.      *
  178.      * @var string 
  179.      */
  180.     var $password = '';
  181.  
  182.     /**
  183.      * checkAuth callback function name
  184.      *
  185.      * @var string 
  186.      * @see setCheckAuthCallback()
  187.      */
  188.     var $checkAuthCallback = '';
  189.  
  190.     /**
  191.      * Login callback function name
  192.      *
  193.      * @var string 
  194.      * @see setLoginCallback()
  195.      */
  196.     var $loginCallback = '';
  197.  
  198.     /**
  199.      * Failed Login callback function name
  200.      *
  201.      * @var string 
  202.      * @see setFailedLoginCallback()
  203.      */
  204.     var $loginFailedCallback = '';
  205.  
  206.     /**
  207.      * Logout callback function name
  208.      *
  209.      * @var string 
  210.      * @see setLogoutCallback()
  211.      */
  212.     var $logoutCallback = '';
  213.  
  214.     /**
  215.      * Auth session-array name
  216.      *
  217.      * @var string 
  218.      */
  219.     var $_sessionName '_authsession';
  220.  
  221.     /**
  222.      * Package Version
  223.      *
  224.      * @var string 
  225.      */
  226.     var $version = "@version@";
  227.  
  228.     /**
  229.      * Flag to use advanced security
  230.      * When set extra checks will be made to see if the
  231.      * user's IP or useragent have changed across requests.
  232.      * Turned off by default to preserve BC.
  233.      *
  234.      * @var mixed Boolean to turn all advanced security options on or off
  235.      *             Array containing named values turning specific advanced
  236.      *             security features on or off individually
  237.      *               array(
  238.      *                   AUTH_ADV_IPCHECK    => true,
  239.      *                   AUTH_ADV_USERAGENT  => true,
  240.      *                   AUTH_ADV_CHALLENGE  => true,
  241.      *               );
  242.      */
  243.     var $advancedsecurity = false;
  244.  
  245.     /**
  246.      * Username key in POST array
  247.      *
  248.      * @var string 
  249.      */
  250.     var $_postUsername 'username';
  251.  
  252.     /**
  253.      * Password key in POST array
  254.      *
  255.      * @var string 
  256.      */
  257.     var $_postPassword 'password';
  258.  
  259.     /**
  260.      * Holds a reference to the session auth variable
  261.      * @var array 
  262.      */
  263.     var $session;
  264.  
  265.     /**
  266.      * Holds a reference to the global server variable
  267.      * @var array 
  268.      */
  269.     var $server;
  270.  
  271.     /**
  272.      * Holds a reference to the global post variable
  273.      * @var array 
  274.      */
  275.     var $post;
  276.  
  277.     /**
  278.      * Holds a reference to the global cookie variable
  279.      * @var array 
  280.      */
  281.     var $cookie;
  282.  
  283.     /**
  284.      * A hash to hold various superglobals as reference
  285.      * @var array 
  286.      */
  287.     var $authdata;
  288.  
  289.     /**
  290.       * How many times has checkAuth been called
  291.       * @var int 
  292.       */
  293.     var $authChecks = 0;
  294.  
  295.     /**
  296.      * PEAR::Log object
  297.      *
  298.      * @var object Log 
  299.      */
  300.     var $logger = null;
  301.  
  302.     /**
  303.      * Whether to enable logging of behaviour
  304.      *
  305.      * @var boolean 
  306.      */
  307.     var $enableLogging = false;
  308.  
  309.     /**
  310.      * Whether to regenerate session id everytime start is called
  311.      *
  312.      * @var boolean 
  313.      */
  314.     var $regenerateSessionId = false;
  315.  
  316.     // }}}
  317.     // {{{ Auth() [constructor]
  318.  
  319.     /**
  320.      * Constructor
  321.      *
  322.      * Set up the storage driver.
  323.      *
  324.      * @param string    Type of the storage driver
  325.      * @param mixed     Additional options for the storage driver
  326.      *                   (example: if you are using DB as the storage
  327.      *                    driver, you have to pass the dsn string here)
  328.      *
  329.      * @param string    Name of the function that creates the login form
  330.      * @param boolean   Should the login form be displayed if necessary?
  331.      * @return void 
  332.      */
  333.     function Auth($storageDriver$options ''$loginFunction ''$showLogin = true)
  334.     {
  335.         $this->applyAuthOptions($options);
  336.  
  337.         // Start the session suppress error if already started
  338.         if(!session_id()){
  339.             @session_start();
  340.             if(!session_id()) {
  341.                 // Throw error
  342.                 include_once 'PEAR.php';
  343.                 PEAR::throwError('Session could not be started by Auth, '
  344.                         .'possibly headers are already sent, try putting '
  345.                         .'ob_start in the beginning of your script');
  346.             }
  347.         }
  348.  
  349.         // Make Sure Auth session variable is there
  350.         if(!isset($_SESSION[$this->_sessionName])) {
  351.             $_SESSION[$this->_sessionName= array();
  352.         }
  353.  
  354.         // Assign Some globals to internal references, this will replace _importGlobalVariable
  355.         $this->session =$_SESSION[$this->_sessionName];
  356.         $this->server =$_SERVER;
  357.         $this->post =$_POST;
  358.         $this->cookie =$_COOKIE;
  359.  
  360.         if ($loginFunction != '' && is_callable($loginFunction)) {
  361.             $this->loginFunction = $loginFunction;
  362.         }
  363.  
  364.         if (is_bool($showLogin)) {
  365.             $this->showLogin = $showLogin;
  366.         }
  367.  
  368.         if (is_object($storageDriver)) {
  369.             $this->storage =$storageDriver;
  370.             // Pass a reference to auth to the container, ugly but works
  371.             // this is used by the DB container to use method setAuthData not staticaly.
  372.             $this->storage->_auth_obj =$this;
  373.         else {
  374.             // $this->storage = $this->_factory($storageDriver, $options);
  375.             //
  376.             $this->storage_driver $storageDriver;
  377.             $this->storage_options =$options;
  378.         }
  379.     }
  380.  
  381.     // }}}
  382.     // {{{ applyAuthOptions()
  383.  
  384.     /**
  385.       * Set the Auth options
  386.       *
  387.       * Some options which are Auth specific will be applied
  388.       * the rest will be left for usage by the container
  389.       *
  390.       * @param array    An array of Auth options
  391.       * @return array   The options which were not applied
  392.       * @access private
  393.       */
  394.     function &applyAuthOptions(&$options)
  395.     {
  396.         if(is_array($options)){
  397.             if (!empty($options['sessionName'])) {
  398.                 $this->_sessionName $options['sessionName'];
  399.                 unset($options['sessionName']);
  400.             }
  401.             if (isset($options['allowLogin'])) {
  402.                 $this->allowLogin = $options['allowLogin'];
  403.                 unset($options['allowLogin']);
  404.             }
  405.             if (!empty($options['postUsername'])) {
  406.                 $this->_postUsername $options['postUsername'];
  407.                 unset($options['postUsername']);
  408.             }
  409.             if (!empty($options['postPassword'])) {
  410.                 $this->_postPassword $options['postPassword'];
  411.                 unset($options['postPassword']);
  412.             }
  413.             if (isset($options['advancedsecurity'])) {
  414.                 $this->advancedsecurity = $options['advancedsecurity'];
  415.                 unset($options['advancedsecurity']);
  416.             }
  417.             if (isset($options['enableLogging'])) {
  418.                 $this->enableLogging = $options['enableLogging'];
  419.                 unset($options['enableLogging']);
  420.             }
  421.             if (isset($options['regenerateSessionId']&& is_bool($options['regenerateSessionId'])) {
  422.                 $this->regenerateSessionId = $options['regenerateSessionId'];
  423.             }
  424.         }
  425.         return($options);
  426.     }
  427.  
  428.     // }}}
  429.     // {{{ _loadStorage()
  430.  
  431.     /**
  432.       * Load Storage Driver if not already loaded
  433.       *
  434.       * Suspend storage instantiation to make Auth lighter to use
  435.       * for calls which do not require login
  436.       *
  437.       * @return bool    True if the conainer is loaded, false if the container
  438.       *                  is already loaded
  439.       * @access private
  440.       */
  441.     function _loadStorage()
  442.     {
  443.         if(!is_object($this->storage)) {
  444.             $this->storage =$this->_factory($this->storage_driver,
  445.                     $this->storage_options);
  446.             $this->storage->_auth_obj =$this;
  447.             $this->log('Loaded storage container ('.$this->storage_driver.')'AUTH_LOG_DEBUG);
  448.             return(true);
  449.         }
  450.         return(false);
  451.     }
  452.  
  453.     // }}}
  454.     // {{{ _factory()
  455.  
  456.     /**
  457.      * Return a storage driver based on $driver and $options
  458.      *
  459.      * @static
  460.      * @param  string $driver  Type of storage class to return
  461.      * @param  string $options Optional parameters for the storage class
  462.      * @return object Object   Storage object
  463.      * @access private
  464.      */
  465.     function &_factory($driver$options '')
  466.     {
  467.         $storage_class 'Auth_Container_' $driver;
  468.         include_once 'Auth/Container/' $driver '.php';
  469.         $obj =new $storage_class($options);
  470.         return $obj;
  471.     }
  472.  
  473.     // }}}
  474.     // {{{ assignData()
  475.  
  476.     /**
  477.      * Assign data from login form to internal values
  478.      *
  479.      * This function takes the values for username and password
  480.      * from $HTTP_POST_VARS/$_POST and assigns them to internal variables.
  481.      * If you wish to use another source apart from $HTTP_POST_VARS/$_POST,
  482.      * you have to derive this function.
  483.      *
  484.      * @global $HTTP_POST_VARS, $_POST 
  485.      * @see    Auth
  486.      * @return void 
  487.      * @access private
  488.      */
  489.     function assignData()
  490.     {
  491.         $this->log('Auth::assignData() called.'AUTH_LOG_DEBUG);
  492.  
  493.         if (   isset($this->post[$this->_postUsername])
  494.             && $this->post[$this->_postUsername!= ''{
  495.             $this->username = (get_magic_quotes_gpc(== 1
  496.                     ? stripslashes($this->post[$this->_postUsername])
  497.                     : $this->post[$this->_postUsername]);
  498.         }
  499.         if (   isset($this->post[$this->_postPassword])
  500.             && $this->post[$this->_postPassword!= ''{
  501.             $this->password = (get_magic_quotes_gpc(== 1
  502.                     ? stripslashes($this->post[$this->_postPassword])
  503.                     : $this->post[$this->_postPassword);
  504.         }
  505.     }
  506.  
  507.     // }}}
  508.     // {{{ start()
  509.  
  510.     /**
  511.      * Start new auth session
  512.      *
  513.      * @return void 
  514.      * @access public
  515.      */
  516.     function start()
  517.     {
  518.         $this->log('Auth::start() called.'AUTH_LOG_DEBUG);
  519.  
  520.         // #10729 - Regenerate session id here if we are generating it on every
  521.         //          page load.
  522.         if ($this->regenerateSessionId{
  523.             session_regenerate_id(true);
  524.         }
  525.  
  526.         $this->assignData();
  527.         if (!$this->checkAuth(&& $this->allowLogin{
  528.             $this->login();
  529.         }
  530.     }
  531.  
  532.     // }}}
  533.     // {{{ login()
  534.  
  535.     /**
  536.      * Login function
  537.      *
  538.      * @return void 
  539.      * @access private
  540.      */
  541.     function login()
  542.     {
  543.         $this->log('Auth::login() called.'AUTH_LOG_DEBUG);
  544.  
  545.         $login_ok = false;
  546.         $this->_loadStorage();
  547.  
  548.         // Check if using challenge response
  549.         (isset($this->post['authsecret']&& $this->post['authsecret'== 1)
  550.             ? $usingChap = true
  551.             : $usingChap = false;
  552.  
  553.  
  554.         // When the user has already entered a username, we have to validate it.
  555.         if (!empty($this->username)) {
  556.             if (true === $this->storage->fetchData($this->username$this->password$usingChap)) {
  557.                 $this->session['challengekey'md5($this->username.$this->password);
  558.                 $login_ok = true;
  559.                 $this->log('Successful login.'AUTH_LOG_INFO);
  560.             }
  561.         }
  562.  
  563.         if (!empty($this->username&& $login_ok{
  564.             $this->setAuth($this->username);
  565.             if (is_callable($this->loginCallback)) {
  566.                 $this->log('Calling loginCallback ('.$this->loginCallback.').'AUTH_LOG_DEBUG);
  567.                 call_user_func_array($this->loginCallbackarray($this->username&$this));
  568.             }
  569.         }
  570.  
  571.         // If the login failed or the user entered no username,
  572.         // output the login screen again.
  573.         if (!empty($this->username&& !$login_ok{
  574.             $this->log('Incorrect login.'AUTH_LOG_INFO);
  575.             $this->status = AUTH_WRONG_LOGIN;
  576.             if (is_callable($this->loginFailedCallback)) {
  577.                 $this->log('Calling loginFailedCallback ('.$this->loginFailedCallback.').'AUTH_LOG_DEBUG);
  578.                 call_user_func_array($this->loginFailedCallbackarray($this->username&$this));
  579.             }
  580.         }
  581.  
  582.         if ((empty($this->username|| !$login_ok&& $this->showLogin{
  583.             $this->log('Rendering Login Form.'AUTH_LOG_INFO);
  584.             if (is_callable($this->loginFunction)) {
  585.                 $this->log('Calling loginFunction ('.$this->loginFunction.').'AUTH_LOG_DEBUG);
  586.                 call_user_func_array($this->loginFunctionarray($this->username$this->status&$this));
  587.             else {
  588.                 // BC fix Auth used to use drawLogin for this
  589.                 // call is sub classes implement this
  590.                 if (is_callable(array($this'drawLogin'))) {
  591.                     $this->log('Calling Auth::drawLogin()'AUTH_LOG_DEBUG);
  592.                     return $this->drawLogin($this->username$this);
  593.                 }
  594.  
  595.                 $this->log('Using default Auth_Frontend_Html'AUTH_LOG_DEBUG);
  596.  
  597.                 // New Login form
  598.                 include_once 'Auth/Frontend/Html.php';
  599.                 return Auth_Frontend_Html::render($this$this->username);
  600.             }
  601.         else {
  602.             return;
  603.         }
  604.     }
  605.  
  606.     // }}}
  607.     // {{{ setExpire()
  608.  
  609.     /**
  610.      * Set the maximum expire time
  611.      *
  612.      * @param  integer time in seconds
  613.      * @param  bool    add time to current expire time or not
  614.      * @return void 
  615.      * @access public
  616.      */
  617.     function setExpire($time$add = false)
  618.     {
  619.         $add $this->expire += $time $this->expire = $time;
  620.     }
  621.  
  622.     // }}}
  623.     // {{{ setIdle()
  624.  
  625.     /**
  626.      * Set the maximum idle time
  627.      *
  628.      * @param  integer time in seconds
  629.      * @param  bool    add time to current maximum idle time or not
  630.      * @return void 
  631.      * @access public
  632.      */
  633.     function setIdle($time$add = false)
  634.     {
  635.         $add $this->idle += $time $this->idle = $time;
  636.     }
  637.  
  638.     // }}}
  639.     // {{{ setSessionName()
  640.  
  641.     /**
  642.      * Set name of the session to a customized value.
  643.      *
  644.      * If you are using multiple instances of PEAR::Auth
  645.      * on the same domain, you can change the name of
  646.      * session per application via this function.
  647.      * This will chnage the name of the session variable
  648.      * auth uses to store it's data in the session
  649.      *
  650.      * @param  string New name for the session
  651.      * @return void 
  652.      * @access public
  653.      */
  654.     function setSessionName($name 'session')
  655.     {
  656.         $this->_sessionName '_auth_'.$name;
  657.         // Make Sure Auth session variable is there
  658.         if(!isset($_SESSION[$this->_sessionName])) {
  659.             $_SESSION[$this->_sessionName= array();
  660.         }
  661.         $this->session =$_SESSION[$this->_sessionName];
  662.     }
  663.  
  664.     // }}}
  665.     // {{{ setShowLogin()
  666.  
  667.     /**
  668.      * Should the login form be displayed if necessary?
  669.      *
  670.      * @param  bool    show login form or not
  671.      * @return void 
  672.      * @access public
  673.      */
  674.     function setShowLogin($showLogin = true)
  675.     {
  676.         $this->showLogin = $showLogin;
  677.     }
  678.  
  679.     // }}}
  680.     // {{{ setAllowLogin()
  681.  
  682.     /**
  683.      * Is Login Allowed from this page?
  684.      *
  685.      * @param  bool    allow login from this page or not
  686.      * @return void 
  687.      * @access public
  688.      */
  689.     function setAllowLogin($allowLogin = true)
  690.     {
  691.         $this->allowLogin = $allowLogin;
  692.     }
  693.  
  694.     // }}}
  695.     // {{{ setCheckAuthCallback()
  696.  
  697.     /**
  698.      * Register a callback function to be called whenever the validity of the login is checked
  699.      * The function will receive two parameters, the username and a reference to the auth object.
  700.      *
  701.      * @param  string  callback function name
  702.      * @return void 
  703.      * @access public
  704.      * @since Method available since Release 1.4.3
  705.      */
  706.     function setCheckAuthCallback($checkAuthCallback)
  707.     {
  708.         $this->checkAuthCallback = $checkAuthCallback;
  709.     }
  710.  
  711.     // }}}
  712.     // {{{ setLoginCallback()
  713.  
  714.     /**
  715.      * Register a callback function to be called on user login.
  716.      * The function will receive two parameters, the username and a reference to the auth object.
  717.      *
  718.      * @param  string  callback function name
  719.      * @return void 
  720.      * @see    setLogoutCallback()
  721.      * @access public
  722.      */
  723.     function setLoginCallback($loginCallback)
  724.     {
  725.         $this->loginCallback = $loginCallback;
  726.     }
  727.  
  728.     // }}}
  729.     // {{{ setFailedLoginCallback()
  730.  
  731.     /**
  732.      * Register a callback function to be called on failed user login.
  733.      * The function will receive two parameters, the username and a reference to the auth object.
  734.      *
  735.      * @param  string  callback function name
  736.      * @return void 
  737.      * @access public
  738.      */
  739.     function setFailedLoginCallback($loginFailedCallback)
  740.     {
  741.         $this->loginFailedCallback = $loginFailedCallback;
  742.     }
  743.  
  744.     // }}}
  745.     // {{{ setLogoutCallback()
  746.  
  747.     /**
  748.      * Register a callback function to be called on user logout.
  749.      * The function will receive three parameters, the username and a reference to the auth object.
  750.      *
  751.      * @param  string  callback function name
  752.      * @return void 
  753.      * @see    setLoginCallback()
  754.      * @access public
  755.      */
  756.     function setLogoutCallback($logoutCallback)
  757.     {
  758.         $this->logoutCallback = $logoutCallback;
  759.     }
  760.  
  761.     // }}}
  762.     // {{{ setAuthData()
  763.  
  764.     /**
  765.      * Register additional information that is to be stored
  766.      * in the session.
  767.      *
  768.      * @param  string  Name of the data field
  769.      * @param  mixed   Value of the data field
  770.      * @param  boolean Should existing data be overwritten? (default
  771.      *                  is true)
  772.      * @return void 
  773.      * @access public
  774.      */
  775.     function setAuthData($name$value$overwrite = true)
  776.     {
  777.         if (!empty($this->session['data'][$name]&& $overwrite == false{
  778.             return;
  779.         }
  780.         $this->session['data'][$name$value;
  781.     }
  782.  
  783.     // }}}
  784.     // {{{ getAuthData()
  785.  
  786.     /**
  787.      * Get additional information that is stored in the session.
  788.      *
  789.      * If no value for the first parameter is passed, the method will
  790.      * return all data that is currently stored.
  791.      *
  792.      * @param  string Name of the data field
  793.      * @return mixed  Value of the data field.
  794.      * @access public
  795.      */
  796.     function getAuthData($name = null)
  797.     {
  798.         if (!isset($this->session['data'])) {
  799.             return null;
  800.         }
  801.         if(!isset($name)) {
  802.             return $this->session['data'];
  803.         }
  804.         if (isset($name&& isset($this->session['data'][$name])) {
  805.             return $this->session['data'][$name];
  806.         }
  807.         return null;
  808.     }
  809.  
  810.     // }}}
  811.     // {{{ setAuth()
  812.  
  813.     /**
  814.      * Register variable in a session telling that the user
  815.      * has logged in successfully
  816.      *
  817.      * @param  string Username
  818.      * @return void 
  819.      * @access public
  820.      */
  821.     function setAuth($username)
  822.     {
  823.         $this->log('Auth::setAuth() called.'AUTH_LOG_DEBUG);
  824.  
  825.         // #10729 - Regenerate session id here only if generating at login only
  826.         //          Don't do it if we are regenerating on every request so we don't
  827.         //          regenerate it twice in one request.
  828.         if (!$this->regenerateSessionId{
  829.             // #2021 - Change the session id to avoid session fixation attacks php 4.3.3 >
  830.             session_regenerate_id(true);
  831.         }
  832.  
  833.         if (!isset($this->session|| !is_array($this->session)) {
  834.             $this->session = array();
  835.         }
  836.  
  837.         if (!isset($this->session['data'])) {
  838.             $this->session['data'= array();
  839.         }
  840.  
  841.         $this->session['sessionip'= isset($this->server['REMOTE_ADDR'])
  842.             ? $this->server['REMOTE_ADDR']
  843.             : '';
  844.         $this->session['sessionuseragent'= isset($this->server['HTTP_USER_AGENT'])
  845.             ? $this->server['HTTP_USER_AGENT']
  846.             : '';
  847.         $this->session['sessionforwardedfor'= isset($this->server['HTTP_X_FORWARDED_FOR'])
  848.             ? $this->server['HTTP_X_FORWARDED_FOR']
  849.             : '';
  850.  
  851.         // This should be set by the container to something more safe
  852.         // Like md5(passwd.microtime)
  853.         if(empty($this->session['challengekey'])) {
  854.             $this->session['challengekey'md5($username.microtime());
  855.         }
  856.  
  857.         $this->session['challengecookie'md5($this->session['challengekey'].microtime());
  858.         setcookie('authchallenge'$this->session['challengecookie']0'/');
  859.  
  860.         $this->session['registered'= true;
  861.         $this->session['username']   $username;
  862.         $this->session['timestamp']  time();
  863.         $this->session['idle']       time();
  864.     }
  865.  
  866.     // }}}
  867.     // {{{ setAdvancedSecurity()
  868.  
  869.     /**
  870.       * Enables advanced security checks
  871.       *
  872.       * Currently only ip change and useragent change
  873.       * are detected
  874.       * @todo Add challenge cookies - Create a cookie which changes every time
  875.       *        and contains some challenge key which the server can verify with
  876.       *        a session var cookie might need to be crypted (user pass)
  877.       * @param bool Enable or disable
  878.       * @return void 
  879.       * @access public
  880.       */
  881.     function setAdvancedSecurity($flag=true)
  882.     {
  883.         $this->advancedsecurity = $flag;
  884.     }
  885.  
  886.     // }}}
  887.     // {{{ checkAuth()
  888.  
  889.     /**
  890.      * Checks if there is a session with valid auth information.
  891.      *
  892.      * @access public
  893.      * @return boolean  Whether or not the user is authenticated.
  894.      */
  895.     function checkAuth()
  896.     {
  897.         $this->log('Auth::checkAuth() called.'AUTH_LOG_DEBUG);
  898.         $this->authChecks++;
  899.         if (isset($this->session)) {
  900.             // Check if authentication session is expired
  901.             if (   $this->expire > 0
  902.                 && isset($this->session['timestamp'])
  903.                 && ($this->session['timestamp'$this->expiretime()) {
  904.                 $this->log('Session Expired'AUTH_LOG_INFO);
  905.                 $this->expired = true;
  906.                 $this->status = AUTH_EXPIRED;
  907.                 $this->logout();
  908.                 return false;
  909.             }
  910.  
  911.             // Check if maximum idle time is reached
  912.             if (   $this->idle > 0
  913.                 && isset($this->session['idle'])
  914.                 && ($this->session['idle'$this->idletime()) {
  915.                 $this->log('Session Idle Time Reached'AUTH_LOG_INFO);
  916.                 $this->idled = true;
  917.                 $this->status = AUTH_IDLED;
  918.                 $this->logout();
  919.                 return false;
  920.             }
  921.  
  922.             if (   isset($this->session['registered'])
  923.                 && isset($this->session['username'])
  924.                 && $this->session['registered'== true
  925.                 && $this->session['username'!= ''{
  926.                 Auth::updateIdle();
  927.  
  928.                 if ($this->_isAdvancedSecurityEnabled()) {
  929.                     $this->log('Advanced Security Mode Enabled.'AUTH_LOG_DEBUG);
  930.  
  931.                     // Only Generate the challenge once
  932.                     if (   $this->authChecks == 1
  933.                         && $this->_isAdvancedSecurityEnabled(AUTH_ADV_CHALLENGE)) {
  934.                         $this->log('Generating new Challenge Cookie.'AUTH_LOG_DEBUG);
  935.                         $this->session['challengecookieold'$this->session['challengecookie'];
  936.                         $this->session['challengecookie'md5($this->session['challengekey'].microtime());
  937.                         setcookie('authchallenge'$this->session['challengecookie']0'/');
  938.                     }
  939.  
  940.                     // Check for ip change
  941.                     if (   $this->_isAdvancedSecurityEnabled(AUTH_ADV_IPCHECK)
  942.                         && isset($this->server['REMOTE_ADDR'])
  943.                         && $this->session['sessionip'!= $this->server['REMOTE_ADDR']{
  944.                         $this->log('Security Breach. Remote IP Address changed.'AUTH_LOG_INFO);
  945.                         // Check if the IP of the user has changed, if so we
  946.                         // assume a man in the middle attack and log him out
  947.                         $this->expired = true;
  948.                         $this->status = AUTH_SECURITY_BREACH;
  949.                         $this->logout();
  950.                         return false;
  951.                     }
  952.  
  953.                     // Check for ip change (if connected via proxy)
  954.                     if (   $this->_isAdvancedSecurityEnabled(AUTH_ADV_IPCHECK)
  955.                         && isset($this->server['HTTP_X_FORWARDED_FOR'])
  956.                         && $this->session['sessionforwardedfor'!= $this->server['HTTP_X_FORWARDED_FOR']{
  957.                         $this->log('Security Breach. Forwarded For IP Address changed.'AUTH_LOG_INFO);
  958.                         // Check if the IP of the user connecting via proxy has
  959.                         // changed, if so we assume a man in the middle attack
  960.                         // and log him out.
  961.                         $this->expired = true;
  962.                         $this->status = AUTH_SECURITY_BREACH;
  963.                         $this->logout();
  964.                         return false;
  965.                     }
  966.  
  967.                     // Check for useragent change
  968.                     if (   $this->_isAdvancedSecurityEnabled(AUTH_ADV_USERAGENT)
  969.                         && isset($this->server['HTTP_USER_AGENT'])
  970.                         && $this->session['sessionuseragent'!= $this->server['HTTP_USER_AGENT']{
  971.                         $this->log('Security Breach. User Agent changed.'AUTH_LOG_INFO);
  972.                         // Check if the User-Agent of the user has changed, if
  973.                         // so we assume a man in the middle attack and log him out
  974.                         $this->expired = true;
  975.                         $this->status = AUTH_SECURITY_BREACH;
  976.                         $this->logout();
  977.                         return false;
  978.                     }
  979.  
  980.                     // Check challenge cookie here, if challengecookieold is not set
  981.                     // this is the first time and check is skipped
  982.                     // TODO when user open two pages similtaneuly (open in new window,open
  983.                     // in tab) auth breach is caused find out a way around that if possible
  984.                     if (   $this->_isAdvancedSecurityEnabled(AUTH_ADV_CHALLENGE)
  985.                         && isset($this->session['challengecookieold'])
  986.                         && $this->session['challengecookieold'!= $this->cookie['authchallenge']{
  987.                         $this->log('Security Breach. Challenge Cookie mismatch.'AUTH_LOG_INFO);
  988.                         $this->expired = true;
  989.                         $this->status = AUTH_SECURITY_BREACH;
  990.                         $this->logout();
  991.                         $this->login();
  992.                         return false;
  993.                     }
  994.                 }
  995.  
  996.                 if (is_callable($this->checkAuthCallback)) {
  997.                     $this->log('Calling checkAuthCallback ('.$this->checkAuthCallback.').'AUTH_LOG_DEBUG);
  998.                     $checkCallback call_user_func_array($this->checkAuthCallbackarray($this->username&$this));
  999.                     if ($checkCallback == false{
  1000.                         $this->log('checkAuthCallback failed.'AUTH_LOG_INFO);
  1001.                         $this->expired = true;
  1002.                         $this->status = AUTH_CALLBACK_ABORT;
  1003.                         $this->logout();
  1004.                         return false;
  1005.                     }
  1006.                 }
  1007.  
  1008.                 $this->log('Session OK.'AUTH_LOG_INFO);
  1009.                 return true;
  1010.             }
  1011.         else {
  1012.             $this->log('Unable to locate session storage.'AUTH_LOG_DEBUG);
  1013.             return false;
  1014.         }
  1015.         $this->log('No login session.'AUTH_LOG_DEBUG);
  1016.         return false;
  1017.     }
  1018.  
  1019.     // }}}
  1020.     // {{{ staticCheckAuth() [static]
  1021.  
  1022.     /**
  1023.      * Statically checks if there is a session with valid auth information.
  1024.      *
  1025.      * @access public
  1026.      * @see checkAuth
  1027.      * @return boolean  Whether or not the user is authenticated.
  1028.      * @static
  1029.      */
  1030.     function staticCheckAuth($options = null)
  1031.     {
  1032.         static $staticAuth;
  1033.         if(!isset($staticAuth)) {
  1034.             $staticAuth = new Auth('null'$options);
  1035.         }
  1036.         $staticAuth->log('Auth::staticCheckAuth() called'AUTH_LOG_DEBUG);
  1037.         return $staticAuth->checkAuth();
  1038.     }
  1039.  
  1040.     // }}}
  1041.     // {{{ getAuth()
  1042.  
  1043.     /**
  1044.      * Has the user been authenticated?
  1045.      *
  1046.      * Is there a valid login session. Previously this was different from
  1047.      * checkAuth() but now it is just an alias.
  1048.      *
  1049.      * @access public
  1050.      * @return bool  True if the user is logged in, otherwise false.
  1051.      */
  1052.     function getAuth()
  1053.     {
  1054.         $this->log('Auth::getAuth() called.'AUTH_LOG_DEBUG);
  1055.         return $this->checkAuth();
  1056.     }
  1057.  
  1058.     // }}}
  1059.     // {{{ logout()
  1060.  
  1061.     /**
  1062.      * Logout function
  1063.      *
  1064.      * This function clears any auth tokens in the currently
  1065.      * active session and executes the logout callback function,
  1066.      * if any
  1067.      *
  1068.      * @access public
  1069.      * @return void 
  1070.      */
  1071.     function logout()
  1072.     {
  1073.         $this->log('Auth::logout() called.'AUTH_LOG_DEBUG);
  1074.  
  1075.         if (is_callable($this->logoutCallback&& isset($this->session['username'])) {
  1076.             $this->log('Calling logoutCallback ('.$this->logoutCallback.').'AUTH_LOG_DEBUG);
  1077.             call_user_func_array($this->logoutCallbackarray($this->session['username']&$this));
  1078.         }
  1079.  
  1080.         $this->username = '';
  1081.         $this->password = '';
  1082.  
  1083.         $this->session = null;
  1084.     }
  1085.  
  1086.     // }}}
  1087.     // {{{ updateIdle()
  1088.  
  1089.     /**
  1090.      * Update the idletime
  1091.      *
  1092.      * @access private
  1093.      * @return void 
  1094.      */
  1095.     function updateIdle()
  1096.     {
  1097.         $this->session['idle'time();
  1098.     }
  1099.  
  1100.     // }}}
  1101.     // {{{ getUsername()
  1102.  
  1103.     /**
  1104.      * Get the username
  1105.      *
  1106.      * @return string 
  1107.      * @access public
  1108.      */
  1109.     function getUsername()
  1110.     {
  1111.         if (isset($this->session['username'])) {
  1112.             return($this->session['username']);
  1113.         }
  1114.         return('');
  1115.     }
  1116.  
  1117.     // }}}
  1118.     // {{{ getStatus()
  1119.  
  1120.     /**
  1121.      * Get the current status
  1122.      *
  1123.      * @return string 
  1124.      * @access public
  1125.      */
  1126.     function getStatus()
  1127.     {
  1128.         return $this->status;
  1129.     }
  1130.  
  1131.     // }}}
  1132.     // {{{ getPostUsernameField()
  1133.  
  1134.     /**
  1135.      * Gets the post varible used for the username
  1136.      *
  1137.      * @return string 
  1138.      * @access public
  1139.      */
  1140.     function getPostUsernameField()
  1141.     {
  1142.         return($this->_postUsername);
  1143.     }
  1144.  
  1145.     // }}}
  1146.     // {{{ getPostPasswordField()
  1147.  
  1148.     /**
  1149.      * Gets the post varible used for the username
  1150.      *
  1151.      * @return string 
  1152.      * @access public
  1153.      */
  1154.     function getPostPasswordField()
  1155.     {
  1156.         return($this->_postPassword);
  1157.     }
  1158.  
  1159.     // }}}
  1160.     // {{{ sessionValidThru()
  1161.  
  1162.     /**
  1163.      * Returns the time up to the session is valid
  1164.      *
  1165.      * @access public
  1166.      * @return integer 
  1167.      */
  1168.     function sessionValidThru()
  1169.     {
  1170.         if (!isset($this->session['idle'])) {
  1171.             return 0;
  1172.         }
  1173.         if ($this->idle == 0{
  1174.             return 0;
  1175.         }
  1176.         return ($this->session['idle'$this->idle);
  1177.     }
  1178.  
  1179.     // }}}
  1180.     // {{{ listUsers()
  1181.  
  1182.     /**
  1183.      * List all users that are currently available in the storage
  1184.      * container
  1185.      *
  1186.      * @access public
  1187.      * @return array 
  1188.      */
  1189.     function listUsers()
  1190.     {
  1191.         $this->log('Auth::listUsers() called.'AUTH_LOG_DEBUG);
  1192.         $this->_loadStorage();
  1193.         return $this->storage->listUsers();
  1194.     }
  1195.  
  1196.     // }}}
  1197.     // {{{ addUser()
  1198.  
  1199.     /**
  1200.      * Add user to the storage container
  1201.      *
  1202.      * @access public
  1203.      * @param  string Username
  1204.      * @param  string Password
  1205.      * @param  mixed  Additional parameters
  1206.      * @return mixed  True on success, PEAR error object on error
  1207.      *                 and AUTH_METHOD_NOT_SUPPORTED otherwise.
  1208.      */
  1209.     function addUser($username$password$additional '')
  1210.     {
  1211.         $this->log('Auth::addUser() called.'AUTH_LOG_DEBUG);
  1212.         $this->_loadStorage();
  1213.         return $this->storage->addUser($username$password$additional);
  1214.     }
  1215.  
  1216.     // }}}
  1217.     // {{{ removeUser()
  1218.  
  1219.     /**
  1220.      * Remove user from the storage container
  1221.      *
  1222.      * @access public
  1223.      * @param  string Username
  1224.      * @return mixed  True on success, PEAR error object on error
  1225.      *                 and AUTH_METHOD_NOT_SUPPORTED otherwise.
  1226.      */
  1227.     function removeUser($username)
  1228.     {
  1229.         $this->log('Auth::removeUser() called.'AUTH_LOG_DEBUG);
  1230.         $this->_loadStorage();
  1231.         return $this->storage->removeUser($username);
  1232.     }
  1233.  
  1234.     // }}}
  1235.     // {{{ changePassword()
  1236.  
  1237.     /**
  1238.      * Change password for user in the storage container
  1239.      *
  1240.      * @access public
  1241.      * @param string Username
  1242.      * @param string The new password
  1243.      * @return mixed True on success, PEAR error object on error
  1244.      *                and AUTH_METHOD_NOT_SUPPORTED otherwise.
  1245.      */
  1246.     function changePassword($username$password)
  1247.     {
  1248.         $this->log('Auth::changePassword() called'AUTH_LOG_DEBUG);
  1249.         $this->_loadStorage();
  1250.         return $this->storage->changePassword($username$password);
  1251.     }
  1252.  
  1253.     // }}}
  1254.     // {{{ log()
  1255.  
  1256.     /**
  1257.      * Log a message from the Auth system
  1258.      *
  1259.      * @access public
  1260.      * @param string The message to log
  1261.      * @param string The log level to log the message under. See the Log documentation for more info.
  1262.      * @return boolean 
  1263.      */
  1264.     function log($message$level = AUTH_LOG_DEBUG)
  1265.     {
  1266.         if (!$this->enableLoggingreturn false;
  1267.  
  1268.         $this->_loadLogger();
  1269.  
  1270.         $this->logger->log('AUTH: '.$message$level);
  1271.     }
  1272.  
  1273.     // }}}
  1274.     // {{{ _loadLogger()
  1275.  
  1276.     /**
  1277.       * Load Log object if not already loaded
  1278.       *
  1279.       * Suspend logger instantiation to make Auth lighter to use
  1280.       * for calls which do not require logging
  1281.       *
  1282.       * @return bool    True if the logger is loaded, false if the logger
  1283.       *                  is already loaded
  1284.       * @access private
  1285.       */
  1286.     function _loadLogger()
  1287.     {
  1288.         if(is_null($this->logger)) {
  1289.             if (!class_exists('Log')) {
  1290.                 include_once 'Log.php';
  1291.             }
  1292.             $this->logger =Log::singleton('null',
  1293.                     null,
  1294.                     'auth['.getmypid().']',
  1295.                     array(),
  1296.                     AUTH_LOG_DEBUG);
  1297.             return(true);
  1298.         }
  1299.         return(false);
  1300.     }
  1301.  
  1302.     // }}}
  1303.     // {{{ attachLogObserver()
  1304.  
  1305.     /**
  1306.      * Attach an Observer to the Auth Log Source
  1307.      *
  1308.      * @param object Log_Observer A Log Observer instance
  1309.      * @return boolean 
  1310.      */
  1311.     function attachLogObserver(&$observer{
  1312.  
  1313.         $this->_loadLogger();
  1314.  
  1315.         return $this->logger->attach($observer);
  1316.  
  1317.     }
  1318.  
  1319.     // }}}
  1320.     // {{{ _isAdvancedSecurityEnabled()
  1321.  
  1322.     /**
  1323.      * Is advanced security enabled?
  1324.      *
  1325.      * Pass one of the Advanced Security constants as the first parameter
  1326.      * to check if that advanced security check is enabled.
  1327.      *
  1328.      * @param integer 
  1329.      * @return boolean 
  1330.      */
  1331.     function _isAdvancedSecurityEnabled($feature = null{
  1332.  
  1333.         if (is_null($feature)) {
  1334.  
  1335.             if ($this->advancedsecurity === true)
  1336.                 return true;
  1337.  
  1338.             if (   is_array($this->advancedsecurity)
  1339.                 && in_array(true$this->advancedsecuritytrue))
  1340.                 return true;
  1341.  
  1342.             return false;
  1343.  
  1344.         else {
  1345.  
  1346.             if (is_array($this->advancedsecurity)) {
  1347.  
  1348.                 if (   isset($this->advancedsecurity[$feature])
  1349.                     && $this->advancedsecurity[$feature== true)
  1350.                     return true;
  1351.  
  1352.                 return false;
  1353.  
  1354.             }
  1355.  
  1356.             return (bool)$this->advancedsecurity;
  1357.  
  1358.         }
  1359.  
  1360.     }
  1361.  
  1362.     // }}}
  1363.  
  1364. }
  1365. ?>

Documentation generated on Mon, 25 Oct 2010 15:30:29 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.