Source for file Auth.php
Documentation is available at Auth.php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
* The main include file for Auth package
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
* @category Authentication
* @author Martin Jansen <mj@php.net>
* @author Adam Ashley <aashley@php.net>
* @copyright 2001-2006 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: Auth.php 289651 2009-10-15 04:39:07Z aashley $
* @link http://pear.php.net/package/Auth
* Returned if session exceeds idle time
* Returned if session has expired
* Returned if container is unable to authenticate user/password pair
define('AUTH_WRONG_LOGIN', -3 );
* Returned if a container method is not supported.
define('AUTH_METHOD_NOT_SUPPORTED', -4 );
* Returned if new Advanced security system detects a breach
define('AUTH_SECURITY_BREACH', -5 );
* Returned if checkAuthCallback says session should not continue.
define('AUTH_CALLBACK_ABORT', -6 );
* Auth Advanced Security - IP Checks
define('AUTH_ADV_IPCHECK', 1 );
* Auth Advanced Security - User Agent Checks
define('AUTH_ADV_USERAGENT', 2 );
* Auth Advanced Security - Challenge Response
define('AUTH_ADV_CHALLENGE', 3 );
* The PEAR::Auth class provides methods for creating an
* authentication system using PHP.
* @category Authentication
* @author Martin Jansen <mj@php.net>
* @author Adam Ashley <aashley@php.net>
* @copyright 2001-2006 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version Release: @package_version@ File: $Revision: 289651 $
* @link http://pear.php.net/package/Auth
* Auth lifetime in seconds
* If this variable is set to 0, auth never expires
* @see setExpire(), checkAuth()
* Has the auth session expired?
* Maximum idletime in seconds
* The difference to $expire is, that the idletime gets
* refreshed each time checkAuth() is called. If this
* variable is set to 0, idletime is never checked.
* @see setIdle(), checkAuth()
* Is the maximum idletime over?
* @see Auth(), validateLogin()
* User-defined function that creates the login screen
* Should the login form be displayed
* Is Login Allowed from this page
* Current authentication status
* checkAuth callback function name
* @see setCheckAuthCallback()
* Login callback function name
* @see setLoginCallback()
* Failed Login callback function name
* @see setFailedLoginCallback()
* Logout callback function name
* @see setLogoutCallback()
* Auth session-array name
var $_sessionName = '_authsession';
* Flag to use advanced security
* When set extra checks will be made to see if the
* user's IP or useragent have changed across requests.
* Turned off by default to preserve BC.
* @var mixed Boolean to turn all advanced security options on or off
* Array containing named values turning specific advanced
* security features on or off individually
* AUTH_ADV_IPCHECK => true,
* AUTH_ADV_USERAGENT => true,
* AUTH_ADV_CHALLENGE => true,
* Username key in POST array
var $_postUsername = 'username';
* Password key in POST array
var $_postPassword = 'password';
* Holds a reference to the session auth variable
* Holds a reference to the global server variable
* Holds a reference to the global post variable
* Holds a reference to the global cookie variable
* A hash to hold various superglobals as reference
* How many times has checkAuth been called
* Whether to enable logging of behaviour
* Whether to regenerate session id everytime start is called
// {{{ Auth() [constructor]
* Set up the storage driver.
* @param string Type of the storage driver
* @param mixed Additional options for the storage driver
* (example: if you are using DB as the storage
* driver, you have to pass the dsn string here)
* @param string Name of the function that creates the login form
* @param boolean Should the login form be displayed if necessary?
function Auth($storageDriver, $options = '', $loginFunction = '', $showLogin = true )
$this->applyAuthOptions ($options);
// Start the session suppress error if already started
PEAR ::throwError ('Session could not be started by Auth, '
. 'possibly headers are already sent, try putting '
. 'ob_start in the beginning of your script');
// Make Sure Auth session variable is there
if(!isset ($_SESSION[$this->_sessionName])) {
$_SESSION[$this->_sessionName] = array ();
// Assign Some globals to internal references, this will replace _importGlobalVariable
$this->session = & $_SESSION[$this->_sessionName];
if ($loginFunction != '' && is_callable($loginFunction)) {
// Pass a reference to auth to the container, ugly but works
// this is used by the DB container to use method setAuthData not staticaly.
$this->storage->_auth_obj = & $this;
// $this->storage = $this->_factory($storageDriver, $options);
$this->storage_driver = $storageDriver;
$this->storage_options = & $options;
// {{{ applyAuthOptions()
* Some options which are Auth specific will be applied
* the rest will be left for usage by the container
* @param array An array of Auth options
* @return array The options which were not applied
function &applyAuthOptions (&$options)
if (!empty ($options['sessionName'])) {
$this->_sessionName = $options['sessionName'];
unset ($options['sessionName']);
if (isset ($options['allowLogin'])) {
unset ($options['allowLogin']);
if (!empty ($options['postUsername'])) {
$this->_postUsername = $options['postUsername'];
unset ($options['postUsername']);
if (!empty ($options['postPassword'])) {
$this->_postPassword = $options['postPassword'];
unset ($options['postPassword']);
if (isset ($options['advancedsecurity'])) {
unset ($options['advancedsecurity']);
if (isset ($options['enableLogging'])) {
unset ($options['enableLogging']);
if (isset ($options['regenerateSessionId']) && is_bool($options['regenerateSessionId'])) {
* Load Storage Driver if not already loaded
* Suspend storage instantiation to make Auth lighter to use
* for calls which do not require login
* @return bool True if the conainer is loaded, false if the container
$this->storage = & $this->_factory ($this->storage_driver,
$this->storage->_auth_obj = & $this;
* Return a storage driver based on $driver and $options
* @param string $driver Type of storage class to return
* @param string $options Optional parameters for the storage class
* @return object Object Storage object
function &_factory ($driver, $options = '')
$storage_class = 'Auth_Container_' . $driver;
include_once 'Auth/Container/' . $driver . '.php';
$obj = & new $storage_class($options);
* Assign data from login form to internal values
* This function takes the values for username and password
* from $HTTP_POST_VARS/$_POST and assigns them to internal variables.
* If you wish to use another source apart from $HTTP_POST_VARS/$_POST,
* you have to derive this function.
* @global $HTTP_POST_VARS, $_POST
if ( isset ($this->post[$this->_postUsername])
&& $this->post[$this->_postUsername] != '') {
: $this->post[$this->_postUsername]);
if ( isset ($this->post[$this->_postPassword])
&& $this->post[$this->_postPassword] != '') {
: $this->post[$this->_postPassword] );
// #10729 - Regenerate session id here if we are generating it on every
// Check if using challenge response
(isset ($this->post['authsecret']) && $this->post['authsecret'] == 1 )
// When the user has already entered a username, we have to validate it.
if (!empty ($this->username) && $login_ok) {
// If the login failed or the user entered no username,
// output the login screen again.
if (!empty ($this->username) && !$login_ok) {
// BC fix Auth used to use drawLogin for this
// call is sub classes implement this
return $this->drawLogin ($this->username, $this);
include_once 'Auth/Frontend/Html.php';
* Set the maximum expire time
* @param integer time in seconds
* @param bool add time to current expire time or not
* Set the maximum idle time
* @param integer time in seconds
* @param bool add time to current maximum idle time or not
function setIdle($time, $add = false )
$add ? $this->idle += $time : $this->idle = $time;
* Set name of the session to a customized value.
* If you are using multiple instances of PEAR::Auth
* on the same domain, you can change the name of
* session per application via this function.
* This will chnage the name of the session variable
* auth uses to store it's data in the session
* @param string New name for the session
$this->_sessionName = '_auth_'. $name;
// Make Sure Auth session variable is there
if(!isset ($_SESSION[$this->_sessionName])) {
$_SESSION[$this->_sessionName] = array ();
$this->session = & $_SESSION[$this->_sessionName];
* Should the login form be displayed if necessary?
* @param bool show login form or not
* Is Login Allowed from this page?
* @param bool allow login from this page or not
// {{{ setCheckAuthCallback()
* Register a callback function to be called whenever the validity of the login is checked
* The function will receive two parameters, the username and a reference to the auth object.
* @param string callback function name
* @since Method available since Release 1.4.3
// {{{ setLoginCallback()
* Register a callback function to be called on user login.
* The function will receive two parameters, the username and a reference to the auth object.
* @param string callback function name
* @see setLogoutCallback()
// {{{ setFailedLoginCallback()
* Register a callback function to be called on failed user login.
* The function will receive two parameters, the username and a reference to the auth object.
* @param string callback function name
// {{{ setLogoutCallback()
* Register a callback function to be called on user logout.
* The function will receive three parameters, the username and a reference to the auth object.
* @param string callback function name
* @see setLoginCallback()
* Register additional information that is to be stored
* @param string Name of the data field
* @param mixed Value of the data field
* @param boolean Should existing data be overwritten? (default
if (!empty ($this->session['data'][$name]) && $overwrite == false ) {
$this->session['data'][$name] = $value;
* Get additional information that is stored in the session.
* If no value for the first parameter is passed, the method will
* return all data that is currently stored.
* @param string Name of the data field
* @return mixed Value of the data field.
if (!isset ($this->session['data'])) {
if (isset ($name) && isset ($this->session['data'][$name])) {
return $this->session['data'][$name];
* Register variable in a session telling that the user
* has logged in successfully
// #10729 - Regenerate session id here only if generating at login only
// Don't do it if we are regenerating on every request so we don't
// regenerate it twice in one request.
// #2021 - Change the session id to avoid session fixation attacks php 4.3.3 >
if (!isset ($this->session['data'])) {
$this->session['sessionip'] = isset ($this->server['REMOTE_ADDR'])
? $this->server['REMOTE_ADDR']
$this->session['sessionuseragent'] = isset ($this->server['HTTP_USER_AGENT'])
? $this->server['HTTP_USER_AGENT']
$this->session['sessionforwardedfor'] = isset ($this->server['HTTP_X_FORWARDED_FOR'])
? $this->server['HTTP_X_FORWARDED_FOR']
// This should be set by the container to something more safe
// Like md5(passwd.microtime)
if(empty ($this->session['challengekey'])) {
$this->session['registered'] = true;
$this->session['username'] = $username;
// {{{ setAdvancedSecurity()
* Enables advanced security checks
* Currently only ip change and useragent change
* @todo Add challenge cookies - Create a cookie which changes every time
* and contains some challenge key which the server can verify with
* a session var cookie might need to be crypted (user pass)
* @param bool Enable or disable
* Checks if there is a session with valid auth information.
* @return boolean Whether or not the user is authenticated.
// Check if authentication session is expired
&& isset ($this->session['timestamp'])
// Check if maximum idle time is reached
if ( isset ($this->session['registered'])
&& isset ($this->session['username'])
&& $this->session['registered'] == true
&& $this->session['username'] != '') {
if ($this->_isAdvancedSecurityEnabled ()) {
// Only Generate the challenge once
$this->session['challengecookieold'] = $this->session['challengecookie'];
&& isset ($this->server['REMOTE_ADDR'])
&& $this->session['sessionip'] != $this->server['REMOTE_ADDR']) {
// Check if the IP of the user has changed, if so we
// assume a man in the middle attack and log him out
// Check for ip change (if connected via proxy)
&& isset ($this->server['HTTP_X_FORWARDED_FOR'])
&& $this->session['sessionforwardedfor'] != $this->server['HTTP_X_FORWARDED_FOR']) {
$this->log('Security Breach. Forwarded For IP Address changed.', AUTH_LOG_INFO);
// Check if the IP of the user connecting via proxy has
// changed, if so we assume a man in the middle attack
// Check for useragent change
&& isset ($this->server['HTTP_USER_AGENT'])
&& $this->session['sessionuseragent'] != $this->server['HTTP_USER_AGENT']) {
// Check if the User-Agent of the user has changed, if
// so we assume a man in the middle attack and log him out
// Check challenge cookie here, if challengecookieold is not set
// this is the first time and check is skipped
// TODO when user open two pages similtaneuly (open in new window,open
// in tab) auth breach is caused find out a way around that if possible
&& isset ($this->session['challengecookieold'])
&& $this->session['challengecookieold'] != $this->cookie['authchallenge']) {
if ($checkCallback == false ) {
// {{{ staticCheckAuth() [static]
* Statically checks if there is a session with valid auth information.
* @return boolean Whether or not the user is authenticated.
if(!isset ($staticAuth)) {
$staticAuth = new Auth('null', $options);
return $staticAuth->checkAuth ();
* Has the user been authenticated?
* Is there a valid login session. Previously this was different from
* checkAuth() but now it is just an alias.
* @return bool True if the user is logged in, otherwise false.
* This function clears any auth tokens in the currently
* active session and executes the logout callback function,
if (isset ($this->session['username'])) {
return($this->session['username']);
// {{{ getPostUsernameField()
* Gets the post varible used for the username
return($this->_postUsername);
// {{{ getPostPasswordField()
* Gets the post varible used for the username
return($this->_postPassword);
// {{{ sessionValidThru()
* Returns the time up to the session is valid
if (!isset ($this->session['idle'])) {
* List all users that are currently available in the storage
return $this->storage->listUsers ();
* Add user to the storage container
* @param mixed Additional parameters
* @return mixed True on success, PEAR error object on error
* and AUTH_METHOD_NOT_SUPPORTED otherwise.
function addUser($username, $password, $additional = '')
return $this->storage->addUser ($username, $password, $additional);
* Remove user from the storage container
* @return mixed True on success, PEAR error object on error
* and AUTH_METHOD_NOT_SUPPORTED otherwise.
return $this->storage->removeUser ($username);
* Change password for user in the storage container
* @param string The new password
* @return mixed True on success, PEAR error object on error
* and AUTH_METHOD_NOT_SUPPORTED otherwise.
return $this->storage->changePassword ($username, $password);
* Log a message from the Auth system
* @param string The message to log
* @param string The log level to log the message under. See the Log documentation for more info.
function log($message, $level = AUTH_LOG_DEBUG )
$this->logger->log ('AUTH: '. $message, $level);
* Load Log object if not already loaded
* Suspend logger instantiation to make Auth lighter to use
* for calls which do not require logging
* @return bool True if the logger is loaded, false if the logger
$this->logger = & Log ::singleton ('null',
// {{{ attachLogObserver()
* Attach an Observer to the Auth Log Source
* @param object Log_Observer A Log Observer instance
return $this->logger->attach ($observer);
// {{{ _isAdvancedSecurityEnabled()
* Is advanced security enabled?
* Pass one of the Advanced Security constants as the first parameter
* to check if that advanced security check is enabled.
function _isAdvancedSecurityEnabled ($feature = null ) {
Documentation generated on Mon, 25 Oct 2010 15:30:29 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.
|