[Pkg-php-commits] r1023 - in pear/php-auth/branches/upstream/current: . Auth-1.6.1 Auth-1.6.1/Auth Auth-1.6.1/Container Auth-1.6.1/Frontend Auth-1.6.1/examples Auth-1.6.1/tests
Gregory Colpart
reg-guest at alioth.debian.org
Mon Apr 28 01:36:51 UTC 2008
Author: reg-guest
Date: 2008-04-28 01:36:51 +0000 (Mon, 28 Apr 2008)
New Revision: 1023
Added:
pear/php-auth/branches/upstream/current/Auth-1.6.1/
pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/
pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/Anonymous.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/Auth.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/Controller.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/Array.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/DB.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/DBLite.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/File.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/IMAP.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/KADM5.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/LDAP.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/MDB.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/MDB2.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/Multiple.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/NetVPOPMaild.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/PEAR.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/POP3.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/RADIUS.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SAP.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SMBPasswd.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SOAP.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SOAP5.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/vpopmail.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Frontend/
pear/php-auth/branches/upstream/current/Auth-1.6.1/Frontend/Html.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/Frontend/md5.js
pear/php-auth/branches/upstream/current/Auth-1.6.1/README.AdvancedSecurity
pear/php-auth/branches/upstream/current/Auth-1.6.1/README.Auth
pear/php-auth/branches/upstream/current/Auth-1.6.1/examples/
pear/php-auth/branches/upstream/current/Auth-1.6.1/examples/logging.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/examples/multi-container.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/DBContainer.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/FileContainer.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/MDB2Container.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/MDBContainer.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/POP3Container.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/POP3aContainer.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/TestAuthContainer.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_db_options.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_file_options.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_mdb2_options.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_mdb_options.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_pop3_options.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_pop3a_options.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/bug8735.passwd
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/bug8735.phpt
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/mysql_test_db.sql
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/tests.php
pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/users
Removed:
pear/php-auth/branches/upstream/current/Auth-1.5.4/
Modified:
pear/php-auth/branches/upstream/current/package.xml
Log:
[svn-upgrade] Integrating new upstream version, php-auth (1.6.1)
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/Anonymous.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/Anonymous.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/Anonymous.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,138 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Anonymous authentication support
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Yavor Shahpasov <yavo at netsmart.com.cy>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: Anonymous.php,v 1.6 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.3.0
+ */
+
+/**
+ * Include Auth package
+ */
+require_once 'Auth.php';
+
+/**
+ * Anonymous Authentication
+ *
+ * This class provides anonymous authentication if username and password
+ * were not supplied
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Yavor Shahpasov <yavo at netsmart.com.cy>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.6 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.3.0
+ */
+class Auth_Anonymous extends Auth
+{
+
+ // {{{ properties
+
+ /**
+ * Whether to allow anonymous authentication
+ *
+ * @var boolean
+ */
+ var $allow_anonymous = true;
+
+ /**
+ * Username to use for anonymous user
+ *
+ * @var string
+ */
+ var $anonymous_username = 'anonymous';
+
+ // }}}
+ // {{{ Auth_Anonymous() [constructor]
+
+ /**
+ * Pass all parameters to Parent Auth class
+ *
+ * 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 neccessary?
+ * @return void
+ * @see Auth::Auth()
+ */
+ function Auth_Anonymous($storageDriver, $options = '', $loginFunction = '', $showLogin = true) {
+ parent::Auth($storageDriver, $options, $loginFunction, $showLogin);
+ }
+
+ // }}}
+ // {{{ login()
+
+ /**
+ * Login function
+ *
+ * If no username & password is passed then login as the username
+ * provided in $this->anonymous_username else call standard login()
+ * function.
+ *
+ * @return void
+ * @access private
+ * @see Auth::login()
+ */
+ function login() {
+ if ( $this->allow_anonymous
+ && empty($this->username)
+ && empty($this->password) ) {
+ $this->setAuth($this->anonymous_username);
+ if (is_callable($this->loginCallback)) {
+ call_user_func_array($this->loginCallback, array($this->username, $this) );
+ }
+ } else {
+ // Call normal login system
+ parent::login();
+ }
+ }
+
+ // }}}
+ // {{{ forceLogin()
+
+ /**
+ * Force the user to login
+ *
+ * Calling this function forces the user to provide a real username and
+ * password before continuing.
+ *
+ * @return void
+ */
+ function forceLogin() {
+ $this->allow_anonymous = false;
+ if( !empty($this->session['username']) && $this->session['username'] == $this->anonymous_username ) {
+ $this->logout();
+ }
+ }
+
+ // }}}
+
+}
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/Auth.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/Auth.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/Auth.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,30 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Provide compatibility with previous Auth include location.
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Martin Jansen <mj at 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,v 1.4 2006/03/02 06:53:08 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @deprecated File deprecated since Release 1.2.0
+ */
+
+/**
+ * Include Auth package
+ */
+require_once 'Auth.php';
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/Controller.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/Controller.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth/Controller.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,302 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Auth Controller
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Yavor Shahpasov <yavo at netsmart.com.cy>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: Controller.php,v 1.11 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.3.0
+ */
+
+/**
+ * Controlls access to a group of php access
+ * and redirects to a predefined login page as
+ * needed
+ *
+ * In all pages
+ * <code>
+ * include_once('Auth.php');
+ * include_once('Auth/Controller.php');
+ * $_auth = new Auth('File', 'passwd');
+ * $authController = new Auth_Controller($_auth, 'login.php', 'index.php');
+ * $authController->start();
+ * </code>
+ *
+ * In login.php
+ * <code>
+ * include_once('Auth.php');
+ * include_once('Auth/Controller.php');
+ * $_auth = new Auth('File', 'passwd');
+ * $authController = new Auth_Controller($_auth, 'login.php', 'index.php');
+ * $authController->start();
+ * if( $authController->isAuthorised() ){
+ * $authController->redirectBack();
+ * }
+ * </code>
+ *
+ * @category Authentication
+ * @author Yavor Shahpasov <yavo at netsmart.com.cy>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.11 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.3.0
+ */
+class Auth_Controller
+{
+
+ // {{{ properties
+
+ /**
+ * The Auth instance this controller is managing
+ *
+ * @var object Auth
+ */
+ var $auth = null;
+
+ /**
+ * The login URL
+ * @var string
+ * */
+ var $login = null;
+
+ /**
+ * The default index page to use when the caller page is not set
+ *
+ * @var string
+ */
+ var $default = null;
+
+ /**
+ * If this is set to true after a succesfull login the
+ * Auth_Controller::redirectBack() is invoked automatically
+ *
+ * @var boolean
+ */
+ var $autoRedirectBack = false;
+
+ // }}}
+ // {{{ Auth_Controller() [constructor]
+
+ /**
+ * Constructor
+ *
+ * @param Auth An auth instance
+ * @param string The login page
+ * @param string The default page to go to if return page is not set
+ * @param array Some rules about which urls need to be sent to the login page
+ * @return void
+ * @todo Add a list of urls which need redirection
+ */
+ function Auth_Controller(&$auth_obj, $login='login.php', $default='index.php', $accessList=array())
+ {
+ $this->auth =& $auth_obj;
+ $this->_loginPage = $login;
+ $this->_defaultPage = $default;
+ @session_start();
+ if (!empty($_GET['return']) && $_GET['return'] && !strstr($_GET['return'], $this->_loginPage)) {
+ $this->auth->setAuthData('returnUrl', $_GET['return']);
+ }
+
+ if(!empty($_GET['authstatus']) && $this->auth->status == '') {
+ $this->auth->status = $_GET['authstatus'];
+ }
+ }
+
+ // }}}
+ // {{{ setAutoRedirectBack()
+
+ /**
+ * Enables auto redirection when login is done
+ *
+ * @param bool Sets the autoRedirectBack flag to this
+ * @see Auth_Controller::autoRedirectBack
+ * @return void
+ */
+ function setAutoRedirectBack($flag = true)
+ {
+ $this->autoRedirectBack = $flag;
+ }
+
+ // }}}
+ // {{{ redirectBack()
+
+ /**
+ * Redirects Back to the calling page
+ *
+ * @return void
+ */
+ function redirectBack()
+ {
+ // If redirectback go there
+ // else go to the default page
+
+ $returnUrl = $this->auth->getAuthData('returnUrl');
+ if(!$returnUrl) {
+ $returnUrl = $this->_defaultPage;
+ }
+
+ // Add some entropy to the return to make it unique
+ // avoind problems with cached pages and proxies
+ if(strpos($returnUrl, '?') === false) {
+ $returnUrl .= '?';
+ }
+ $returnUrl .= uniqid('');
+
+ // Track the auth status
+ if($this->auth->status != '') {
+ $url .= '&authstatus='.$this->auth->status;
+ }
+ header('Location:'.$returnUrl);
+ print("You could not be redirected to <a href=\"$returnUrl\">$returnUrl</a>");
+ }
+
+ // }}}
+ // {{{ redirectLogin()
+
+ /**
+ * Redirects to the login Page if not authorised
+ *
+ * put return page on the query or in auth
+ *
+ * @return void
+ */
+ function redirectLogin()
+ {
+ // Go to the login Page
+
+ // For Auth, put some check to avoid infinite redirects, this should at least exclude
+ // the login page
+
+ $url = $this->_loginPage;
+ if(strpos($url, '?') === false) {
+ $url .= '?';
+ }
+
+ if(!strstr($_SERVER['PHP_SELF'], $this->_loginPage)) {
+ $url .= 'return='.urlencode($_SERVER['PHP_SELF']);
+ }
+
+ // Track the auth status
+ if($this->auth->status != '') {
+ $url .= '&authstatus='.$this->auth->status;
+ }
+
+ header('Location:'.$url);
+ print("You could not be redirected to <a href=\"$url\">$url</a>");
+ }
+
+ // }}}
+ // {{{ start()
+
+ /**
+ * Starts the Auth Procedure
+ *
+ * If the page requires login the user is redirected to the login page
+ * otherwise the Auth::start is called to initialize Auth
+ *
+ * @return void
+ * @todo Implement an access list which specifies which urls/pages need login and which do not
+ */
+ function start()
+ {
+ // Check the accessList here
+ // ACL should be a list of urls with allow/deny
+ // If allow set allowLogin to false
+ // Some wild card matching should be implemented ?,*
+ if(!strstr($_SERVER['PHP_SELF'], $this->_loginPage) && !$this->auth->checkAuth()) {
+ $this->redirectLogin();
+ } else {
+ $this->auth->start();
+ // Logged on and on login page
+ if(strstr($_SERVER['PHP_SELF'], $this->_loginPage) && $this->auth->checkAuth()){
+ $this->autoRedirectBack ?
+ $this->redirectBack() :
+ null ;
+ }
+ }
+
+
+ }
+
+ // }}}
+ // {{{ isAuthorised()
+
+ /**
+ * Checks is the user is logged on
+ * @see Auth::checkAuth()
+ */
+ function isAuthorised()
+ {
+ return($this->auth->checkAuth());
+ }
+
+ // }}}
+ // {{{ checkAuth()
+
+ /**
+ * Proxy call to auth
+ * @see Auth::checkAuth()
+ */
+ function checkAuth()
+ {
+ return($this->auth->checkAuth());
+ }
+
+ // }}}
+ // {{{ logout()
+
+ /**
+ * Proxy call to auth
+ * @see Auth::logout()
+ */
+ function logout()
+ {
+ return($this->auth->logout());
+ }
+
+ // }}}
+ // {{{ getUsername()
+
+ /**
+ * Proxy call to auth
+ * @see Auth::getUsername()
+ */
+ function getUsername()
+ {
+ return($this->auth->getUsername());
+ }
+
+ // }}}
+ // {{{ getStatus()
+
+ /**
+ * Proxy call to auth
+ * @see Auth::getStatus()
+ */
+ function getStatus()
+ {
+ return($this->auth->getStatus());
+ }
+
+ // }}}
+
+}
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Auth.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,1365 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * The main include file for Auth package
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Martin Jansen <mj at php.net>
+ * @author Adam Ashley <aashley at 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,v 1.123 2008/04/04 03:50:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ */
+
+/**
+ * Returned if session exceeds idle time
+ */
+define('AUTH_IDLED', -1);
+/**
+ * Returned if session has expired
+ */
+define('AUTH_EXPIRED', -2);
+/**
+ * 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 Log level - INFO
+ */
+define('AUTH_LOG_INFO', 6);
+/**
+ * Auth Log level - DEBUG
+ */
+define('AUTH_LOG_DEBUG', 7);
+
+/**
+ * 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);
+
+
+/**
+ * PEAR::Auth
+ *
+ * The PEAR::Auth class provides methods for creating an
+ * authentication system using PHP.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Martin Jansen <mj at php.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.123 $
+ * @link http://pear.php.net/package/Auth
+ */
+class Auth {
+
+ // {{{ properties
+
+ /**
+ * Auth lifetime in seconds
+ *
+ * If this variable is set to 0, auth never expires
+ *
+ * @var integer
+ * @see setExpire(), checkAuth()
+ */
+ var $expire = 0;
+
+ /**
+ * Has the auth session expired?
+ *
+ * @var bool
+ * @see checkAuth()
+ */
+ var $expired = false;
+
+ /**
+ * 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.
+ *
+ * @var integer
+ * @see setIdle(), checkAuth()
+ */
+ var $idle = 0;
+
+ /**
+ * Is the maximum idletime over?
+ *
+ * @var boolean
+ * @see checkAuth()
+ */
+ var $idled = false;
+
+ /**
+ * Storage object
+ *
+ * @var object
+ * @see Auth(), validateLogin()
+ */
+ var $storage = '';
+
+ /**
+ * User-defined function that creates the login screen
+ *
+ * @var string
+ */
+ var $loginFunction = '';
+
+ /**
+ * Should the login form be displayed
+ *
+ * @var bool
+ * @see setShowlogin()
+ */
+ var $showLogin = true;
+
+ /**
+ * Is Login Allowed from this page
+ *
+ * @var bool
+ * @see setAllowLogin
+ */
+ var $allowLogin = true;
+
+ /**
+ * Current authentication status
+ *
+ * @var string
+ */
+ var $status = '';
+
+ /**
+ * Username
+ *
+ * @var string
+ */
+ var $username = '';
+
+ /**
+ * Password
+ *
+ * @var string
+ */
+ var $password = '';
+
+ /**
+ * checkAuth callback function name
+ *
+ * @var string
+ * @see setCheckAuthCallback()
+ */
+ var $checkAuthCallback = '';
+
+ /**
+ * Login callback function name
+ *
+ * @var string
+ * @see setLoginCallback()
+ */
+ var $loginCallback = '';
+
+ /**
+ * Failed Login callback function name
+ *
+ * @var string
+ * @see setFailedLoginCallback()
+ */
+ var $loginFailedCallback = '';
+
+ /**
+ * Logout callback function name
+ *
+ * @var string
+ * @see setLogoutCallback()
+ */
+ var $logoutCallback = '';
+
+ /**
+ * Auth session-array name
+ *
+ * @var string
+ */
+ var $_sessionName = '_authsession';
+
+ /**
+ * Package Version
+ *
+ * @var string
+ */
+ var $version = "@version@";
+
+ /**
+ * 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
+ * array(
+ * AUTH_ADV_IPCHECK => true,
+ * AUTH_ADV_USERAGENT => true,
+ * AUTH_ADV_CHALLENGE => true,
+ * );
+ */
+ var $advancedsecurity = false;
+
+ /**
+ * Username key in POST array
+ *
+ * @var string
+ */
+ var $_postUsername = 'username';
+
+ /**
+ * Password key in POST array
+ *
+ * @var string
+ */
+ var $_postPassword = 'password';
+
+ /**
+ * Holds a reference to the session auth variable
+ * @var array
+ */
+ var $session;
+
+ /**
+ * Holds a reference to the global server variable
+ * @var array
+ */
+ var $server;
+
+ /**
+ * Holds a reference to the global post variable
+ * @var array
+ */
+ var $post;
+
+ /**
+ * Holds a reference to the global cookie variable
+ * @var array
+ */
+ var $cookie;
+
+ /**
+ * A hash to hold various superglobals as reference
+ * @var array
+ */
+ var $authdata;
+
+ /**
+ * How many times has checkAuth been called
+ * @var int
+ */
+ var $authChecks = 0;
+
+ /**
+ * PEAR::Log object
+ *
+ * @var object Log
+ */
+ var $logger = null;
+
+ /**
+ * Whether to enable logging of behaviour
+ *
+ * @var boolean
+ */
+ var $enableLogging = false;
+
+ /**
+ * Whether to regenerate session id everytime start is called
+ *
+ * @var boolean
+ */
+ var $regenerateSessionId = false;
+
+ // }}}
+ // {{{ Auth() [constructor]
+
+ /**
+ * 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 neccessary?
+ * @return void
+ */
+ function Auth($storageDriver, $options = '', $loginFunction = '', $showLogin = true)
+ {
+ $this->applyAuthOptions($options);
+
+ // Start the session suppress error if already started
+ if(!session_id()){
+ @session_start();
+ if(!session_id()) {
+ // Throw error
+ include_once 'PEAR.php';
+ 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];
+ $this->server =& $_SERVER;
+ $this->post =& $_POST;
+ $this->cookie =& $_COOKIE;
+
+ if ($loginFunction != '' && is_callable($loginFunction)) {
+ $this->loginFunction = $loginFunction;
+ }
+
+ if (is_bool($showLogin)) {
+ $this->showLogin = $showLogin;
+ }
+
+ if (is_object($storageDriver)) {
+ $this->storage =& $storageDriver;
+ // 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;
+ } else {
+ // $this->storage = $this->_factory($storageDriver, $options);
+ //
+ $this->storage_driver = $storageDriver;
+ $this->storage_options =& $options;
+ }
+ }
+
+ // }}}
+ // {{{ applyAuthOptions()
+
+ /**
+ * Set the Auth options
+ *
+ * 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
+ * @access private
+ */
+ function &applyAuthOptions(&$options)
+ {
+ if(is_array($options)){
+ if (!empty($options['sessionName'])) {
+ $this->_sessionName = $options['sessionName'];
+ unset($options['sessionName']);
+ }
+ if (isset($options['allowLogin'])) {
+ $this->allowLogin = $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'])) {
+ $this->advancedsecurity = $options['advancedsecurity'];
+ unset($options['advancedsecurity']);
+ }
+ if (isset($options['enableLogging'])) {
+ $this->enableLogging = $options['enableLogging'];
+ unset($options['enableLogging']);
+ }
+ if (isset($options['regenerateSessionId']) && is_bool($options['regenerateSessionId'])) {
+ $this->regenerateSessionId = $options['regenerateSessionId'];
+ }
+ }
+ return($options);
+ }
+
+ // }}}
+ // {{{ _loadStorage()
+
+ /**
+ * 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
+ * is already loaded
+ * @access private
+ */
+ function _loadStorage()
+ {
+ if(!is_object($this->storage)) {
+ $this->storage =& $this->_factory($this->storage_driver,
+ $this->storage_options);
+ $this->storage->_auth_obj =& $this;
+ $this->log('Loaded storage container ('.$this->storage_driver.')', AUTH_LOG_DEBUG);
+ return(true);
+ }
+ return(false);
+ }
+
+ // }}}
+ // {{{ _factory()
+
+ /**
+ * Return a storage driver based on $driver and $options
+ *
+ * @static
+ * @param string $driver Type of storage class to return
+ * @param string $options Optional parameters for the storage class
+ * @return object Object Storage object
+ * @access private
+ */
+ function &_factory($driver, $options = '')
+ {
+ $storage_class = 'Auth_Container_' . $driver;
+ include_once 'Auth/Container/' . $driver . '.php';
+ $obj =& new $storage_class($options);
+ return $obj;
+ }
+
+ // }}}
+ // {{{ assignData()
+
+ /**
+ * 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
+ * @see Auth
+ * @return void
+ * @access private
+ */
+ function assignData()
+ {
+ $this->log('Auth::assignData() called.', AUTH_LOG_DEBUG);
+
+ if ( isset($this->post[$this->_postUsername])
+ && $this->post[$this->_postUsername] != '') {
+ $this->username = (get_magic_quotes_gpc() == 1
+ ? stripslashes($this->post[$this->_postUsername])
+ : $this->post[$this->_postUsername]);
+ }
+ if ( isset($this->post[$this->_postPassword])
+ && $this->post[$this->_postPassword] != '') {
+ $this->password = (get_magic_quotes_gpc() == 1
+ ? stripslashes($this->post[$this->_postPassword])
+ : $this->post[$this->_postPassword] );
+ }
+ }
+
+ // }}}
+ // {{{ start()
+
+ /**
+ * Start new auth session
+ *
+ * @return void
+ * @access public
+ */
+ function start()
+ {
+ $this->log('Auth::start() called.', AUTH_LOG_DEBUG);
+
+ // #10729 - Regenerate session id here if we are generating it on every
+ // page load.
+ if ($this->regenerateSessionId) {
+ session_regenerate_id(true);
+ }
+
+ $this->assignData();
+ if (!$this->checkAuth() && $this->allowLogin) {
+ $this->login();
+ }
+ }
+
+ // }}}
+ // {{{ login()
+
+ /**
+ * Login function
+ *
+ * @return void
+ * @access private
+ */
+ function login()
+ {
+ $this->log('Auth::login() called.', AUTH_LOG_DEBUG);
+
+ $login_ok = false;
+ $this->_loadStorage();
+
+ // Check if using challenge response
+ (isset($this->post['authsecret']) && $this->post['authsecret'] == 1)
+ ? $usingChap = true
+ : $usingChap = false;
+
+
+ // When the user has already entered a username, we have to validate it.
+ if (!empty($this->username)) {
+ if (true === $this->storage->fetchData($this->username, $this->password, $usingChap)) {
+ $this->session['challengekey'] = md5($this->username.$this->password);
+ $login_ok = true;
+ $this->log('Successful login.', AUTH_LOG_INFO);
+ }
+ }
+
+ if (!empty($this->username) && $login_ok) {
+ $this->setAuth($this->username);
+ if (is_callable($this->loginCallback)) {
+ $this->log('Calling loginCallback ('.$this->loginCallback.').', AUTH_LOG_DEBUG);
+ call_user_func_array($this->loginCallback, array($this->username, &$this));
+ }
+ }
+
+ // If the login failed or the user entered no username,
+ // output the login screen again.
+ if (!empty($this->username) && !$login_ok) {
+ $this->log('Incorrect login.', AUTH_LOG_INFO);
+ $this->status = AUTH_WRONG_LOGIN;
+ if (is_callable($this->loginFailedCallback)) {
+ $this->log('Calling loginFailedCallback ('.$this->loginFailedCallback.').', AUTH_LOG_DEBUG);
+ call_user_func_array($this->loginFailedCallback, array($this->username, &$this));
+ }
+ }
+
+ if ((empty($this->username) || !$login_ok) && $this->showLogin) {
+ $this->log('Rendering Login Form.', AUTH_LOG_INFO);
+ if (is_callable($this->loginFunction)) {
+ $this->log('Calling loginFunction ('.$this->loginFunction.').', AUTH_LOG_DEBUG);
+ call_user_func_array($this->loginFunction, array($this->username, $this->status, &$this));
+ } else {
+ // BC fix Auth used to use drawLogin for this
+ // call is sub classes implement this
+ if (is_callable(array($this, 'drawLogin'))) {
+ $this->log('Calling Auth::drawLogin()', AUTH_LOG_DEBUG);
+ return $this->drawLogin($this->username, $this);
+ }
+
+ $this->log('Using default Auth_Frontend_Html', AUTH_LOG_DEBUG);
+
+ // New Login form
+ include_once 'Auth/Frontend/Html.php';
+ return Auth_Frontend_Html::render($this, $this->username);
+ }
+ } else {
+ return;
+ }
+ }
+
+ // }}}
+ // {{{ setExpire()
+
+ /**
+ * Set the maximum expire time
+ *
+ * @param integer time in seconds
+ * @param bool add time to current expire time or not
+ * @return void
+ * @access public
+ */
+ function setExpire($time, $add = false)
+ {
+ $add ? $this->expire += $time : $this->expire = $time;
+ }
+
+ // }}}
+ // {{{ setIdle()
+
+ /**
+ * Set the maximum idle time
+ *
+ * @param integer time in seconds
+ * @param bool add time to current maximum idle time or not
+ * @return void
+ * @access public
+ */
+ function setIdle($time, $add = false)
+ {
+ $add ? $this->idle += $time : $this->idle = $time;
+ }
+
+ // }}}
+ // {{{ setSessionName()
+
+ /**
+ * 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
+ * @return void
+ * @access public
+ */
+ function setSessionName($name = '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];
+ }
+
+ // }}}
+ // {{{ setShowLogin()
+
+ /**
+ * Should the login form be displayed if neccessary?
+ *
+ * @param bool show login form or not
+ * @return void
+ * @access public
+ */
+ function setShowLogin($showLogin = true)
+ {
+ $this->showLogin = $showLogin;
+ }
+
+ // }}}
+ // {{{ setAllowLogin()
+
+ /**
+ * Should the login form be displayed if neccessary?
+ *
+ * @param bool show login form or not
+ * @return void
+ * @access public
+ */
+ function setAllowLogin($allowLogin = true)
+ {
+ $this->allowLogin = $allowLogin;
+ }
+
+ // }}}
+ // {{{ 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
+ * @return void
+ * @access public
+ * @since Method available since Release 1.4.3
+ */
+ function setCheckAuthCallback($checkAuthCallback)
+ {
+ $this->checkAuthCallback = $checkAuthCallback;
+ }
+
+ // }}}
+ // {{{ 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
+ * @return void
+ * @see setLogoutCallback()
+ * @access public
+ */
+ function setLoginCallback($loginCallback)
+ {
+ $this->loginCallback = $loginCallback;
+ }
+
+ // }}}
+ // {{{ 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
+ * @return void
+ * @access public
+ */
+ function setFailedLoginCallback($loginFailedCallback)
+ {
+ $this->loginFailedCallback = $loginFailedCallback;
+ }
+
+ // }}}
+ // {{{ 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
+ * @return void
+ * @see setLoginCallback()
+ * @access public
+ */
+ function setLogoutCallback($logoutCallback)
+ {
+ $this->logoutCallback = $logoutCallback;
+ }
+
+ // }}}
+ // {{{ setAuthData()
+
+ /**
+ * Register additional information that is to be stored
+ * in the session.
+ *
+ * @param string Name of the data field
+ * @param mixed Value of the data field
+ * @param boolean Should existing data be overwritten? (default
+ * is true)
+ * @return void
+ * @access public
+ */
+ function setAuthData($name, $value, $overwrite = true)
+ {
+ if (!empty($this->session['data'][$name]) && $overwrite == false) {
+ return;
+ }
+ $this->session['data'][$name] = $value;
+ }
+
+ // }}}
+ // {{{ getAuthData()
+
+ /**
+ * 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.
+ * @access public
+ */
+ function getAuthData($name = null)
+ {
+ if (!isset($this->session['data'])) {
+ return null;
+ }
+ if(!isset($name)) {
+ return $this->session['data'];
+ }
+ if (isset($name) && isset($this->session['data'][$name])) {
+ return $this->session['data'][$name];
+ }
+ return null;
+ }
+
+ // }}}
+ // {{{ setAuth()
+
+ /**
+ * Register variable in a session telling that the user
+ * has logged in successfully
+ *
+ * @param string Username
+ * @return void
+ * @access public
+ */
+ function setAuth($username)
+ {
+ $this->log('Auth::setAuth() called.', AUTH_LOG_DEBUG);
+
+ // #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.
+ if (!$this->regenerateSessionId) {
+ // #2021 - Change the session id to avoid session fixation attacks php 4.3.3 >
+ session_regenerate_id(true);
+ }
+
+ if (!isset($this->session) || !is_array($this->session)) {
+ $this->session = array();
+ }
+
+ if (!isset($this->session['data'])) {
+ $this->session['data'] = array();
+ }
+
+ $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['challengekey'] = md5($username.microtime());
+ }
+
+ $this->session['challengecookie'] = md5($this->session['challengekey'].microtime());
+ setcookie('authchallenge', $this->session['challengecookie'], 0, '/');
+
+ $this->session['registered'] = true;
+ $this->session['username'] = $username;
+ $this->session['timestamp'] = time();
+ $this->session['idle'] = time();
+ }
+
+ // }}}
+ // {{{ setAdvancedSecurity()
+
+ /**
+ * Enables advanced security checks
+ *
+ * Currently only ip change and useragent change
+ * are detected
+ * @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
+ * @return void
+ * @access public
+ */
+ function setAdvancedSecurity($flag=true)
+ {
+ $this->advancedsecurity = $flag;
+ }
+
+ // }}}
+ // {{{ checkAuth()
+
+ /**
+ * Checks if there is a session with valid auth information.
+ *
+ * @access public
+ * @return boolean Whether or not the user is authenticated.
+ */
+ function checkAuth()
+ {
+ $this->log('Auth::checkAuth() called.', AUTH_LOG_DEBUG);
+ $this->authChecks++;
+ if (isset($this->session)) {
+ // Check if authentication session is expired
+ if ( $this->expire > 0
+ && isset($this->session['timestamp'])
+ && ($this->session['timestamp'] + $this->expire) < time()) {
+ $this->log('Session Expired', AUTH_LOG_INFO);
+ $this->expired = true;
+ $this->status = AUTH_EXPIRED;
+ $this->logout();
+ return false;
+ }
+
+ // Check if maximum idle time is reached
+ if ( $this->idle > 0
+ && isset($this->session['idle'])
+ && ($this->session['idle'] + $this->idle) < time()) {
+ $this->log('Session Idle Time Reached', AUTH_LOG_INFO);
+ $this->idled = true;
+ $this->status = AUTH_IDLED;
+ $this->logout();
+ return false;
+ }
+
+ if ( isset($this->session['registered'])
+ && isset($this->session['username'])
+ && $this->session['registered'] == true
+ && $this->session['username'] != '') {
+ Auth::updateIdle();
+
+ if ($this->_isAdvancedSecurityEnabled()) {
+ $this->log('Advanced Security Mode Enabled.', AUTH_LOG_DEBUG);
+
+ // Only Generate the challenge once
+ if ( $this->authChecks == 1
+ && $this->_isAdvancedSecurityEnabled(AUTH_ADV_CHALLENGE)) {
+ $this->log('Generating new Challenge Cookie.', AUTH_LOG_DEBUG);
+ $this->session['challengecookieold'] = $this->session['challengecookie'];
+ $this->session['challengecookie'] = md5($this->session['challengekey'].microtime());
+ setcookie('authchallenge', $this->session['challengecookie'], 0, '/');
+ }
+
+ // Check for ip change
+ if ( $this->_isAdvancedSecurityEnabled(AUTH_ADV_IPCHECK)
+ && isset($this->server['REMOTE_ADDR'])
+ && $this->session['sessionip'] != $this->server['REMOTE_ADDR']) {
+ $this->log('Security Breach. Remote IP Address changed.', AUTH_LOG_INFO);
+ // Check if the IP of the user has changed, if so we
+ // assume a man in the middle attack and log him out
+ $this->expired = true;
+ $this->status = AUTH_SECURITY_BREACH;
+ $this->logout();
+ return false;
+ }
+
+ // Check for ip change (if connected via proxy)
+ if ( $this->_isAdvancedSecurityEnabled(AUTH_ADV_IPCHECK)
+ && 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
+ // and log him out.
+ $this->expired = true;
+ $this->status = AUTH_SECURITY_BREACH;
+ $this->logout();
+ return false;
+ }
+
+ // Check for useragent change
+ if ( $this->_isAdvancedSecurityEnabled(AUTH_ADV_USERAGENT)
+ && isset($this->server['HTTP_USER_AGENT'])
+ && $this->session['sessionuseragent'] != $this->server['HTTP_USER_AGENT']) {
+ $this->log('Security Breach. User Agent changed.', AUTH_LOG_INFO);
+ // Check if the User-Agent of the user has changed, if
+ // so we assume a man in the middle attack and log him out
+ $this->expired = true;
+ $this->status = AUTH_SECURITY_BREACH;
+ $this->logout();
+ return false;
+ }
+
+ // 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
+ if ( $this->_isAdvancedSecurityEnabled(AUTH_ADV_CHALLENGE)
+ && isset($this->session['challengecookieold'])
+ && $this->session['challengecookieold'] != $this->cookie['authchallenge']) {
+ $this->log('Security Breach. Challenge Cookie mismatch.', AUTH_LOG_INFO);
+ $this->expired = true;
+ $this->status = AUTH_SECURITY_BREACH;
+ $this->logout();
+ $this->login();
+ return false;
+ }
+ }
+
+ if (is_callable($this->checkAuthCallback)) {
+ $this->log('Calling checkAuthCallback ('.$this->checkAuthCallback.').', AUTH_LOG_DEBUG);
+ $checkCallback = call_user_func_array($this->checkAuthCallback, array($this->username, &$this));
+ if ($checkCallback == false) {
+ $this->log('checkAuthCallback failed.', AUTH_LOG_INFO);
+ $this->expired = true;
+ $this->status = AUTH_CALLBACK_ABORT;
+ $this->logout();
+ return false;
+ }
+ }
+
+ $this->log('Session OK.', AUTH_LOG_INFO);
+ return true;
+ }
+ } else {
+ $this->log('Unable to locate session storage.', AUTH_LOG_DEBUG);
+ return false;
+ }
+ $this->log('No login session.', AUTH_LOG_DEBUG);
+ return false;
+ }
+
+ // }}}
+ // {{{ staticCheckAuth() [static]
+
+ /**
+ * Statically checks if there is a session with valid auth information.
+ *
+ * @access public
+ * @see checkAuth
+ * @return boolean Whether or not the user is authenticated.
+ * @static
+ */
+ function staticCheckAuth($options = null)
+ {
+ static $staticAuth;
+ if(!isset($staticAuth)) {
+ $staticAuth = new Auth('null', $options);
+ }
+ $staticAuth->log('Auth::staticCheckAuth() called', AUTH_LOG_DEBUG);
+ return $staticAuth->checkAuth();
+ }
+
+ // }}}
+ // {{{ getAuth()
+
+ /**
+ * Has the user been authenticated?
+ *
+ * Is there a valid login session. Previously this was different from
+ * checkAuth() but now it is just an alias.
+ *
+ * @access public
+ * @return bool True if the user is logged in, otherwise false.
+ */
+ function getAuth()
+ {
+ $this->log('Auth::getAuth() called.', AUTH_LOG_DEBUG);
+ return $this->checkAuth();
+ }
+
+ // }}}
+ // {{{ logout()
+
+ /**
+ * Logout function
+ *
+ * This function clears any auth tokens in the currently
+ * active session and executes the logout callback function,
+ * if any
+ *
+ * @access public
+ * @return void
+ */
+ function logout()
+ {
+ $this->log('Auth::logout() called.', AUTH_LOG_DEBUG);
+
+ if (is_callable($this->logoutCallback) && isset($this->session['username'])) {
+ $this->log('Calling logoutCallback ('.$this->logoutCallback.').', AUTH_LOG_DEBUG);
+ call_user_func_array($this->logoutCallback, array($this->session['username'], &$this));
+ }
+
+ $this->username = '';
+ $this->password = '';
+
+ $this->session = null;
+ }
+
+ // }}}
+ // {{{ updateIdle()
+
+ /**
+ * Update the idletime
+ *
+ * @access private
+ * @return void
+ */
+ function updateIdle()
+ {
+ $this->session['idle'] = time();
+ }
+
+ // }}}
+ // {{{ getUsername()
+
+ /**
+ * Get the username
+ *
+ * @return string
+ * @access public
+ */
+ function getUsername()
+ {
+ if (isset($this->session['username'])) {
+ return($this->session['username']);
+ }
+ return('');
+ }
+
+ // }}}
+ // {{{ getStatus()
+
+ /**
+ * Get the current status
+ *
+ * @return string
+ * @access public
+ */
+ function getStatus()
+ {
+ return $this->status;
+ }
+
+ // }}}
+ // {{{ getPostUsernameField()
+
+ /**
+ * Gets the post varible used for the username
+ *
+ * @return string
+ * @access public
+ */
+ function getPostUsernameField()
+ {
+ return($this->_postUsername);
+ }
+
+ // }}}
+ // {{{ getPostPasswordField()
+
+ /**
+ * Gets the post varible used for the username
+ *
+ * @return string
+ * @access public
+ */
+ function getPostPasswordField()
+ {
+ return($this->_postPassword);
+ }
+
+ // }}}
+ // {{{ sessionValidThru()
+
+ /**
+ * Returns the time up to the session is valid
+ *
+ * @access public
+ * @return integer
+ */
+ function sessionValidThru()
+ {
+ if (!isset($this->session['idle'])) {
+ return 0;
+ }
+ if ($this->idle == 0) {
+ return 0;
+ }
+ return ($this->session['idle'] + $this->idle);
+ }
+
+ // }}}
+ // {{{ listUsers()
+
+ /**
+ * List all users that are currently available in the storage
+ * container
+ *
+ * @access public
+ * @return array
+ */
+ function listUsers()
+ {
+ $this->log('Auth::listUsers() called.', AUTH_LOG_DEBUG);
+ $this->_loadStorage();
+ return $this->storage->listUsers();
+ }
+
+ // }}}
+ // {{{ addUser()
+
+ /**
+ * Add user to the storage container
+ *
+ * @access public
+ * @param string Username
+ * @param string Password
+ * @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 = '')
+ {
+ $this->log('Auth::addUser() called.', AUTH_LOG_DEBUG);
+ $this->_loadStorage();
+ return $this->storage->addUser($username, $password, $additional);
+ }
+
+ // }}}
+ // {{{ removeUser()
+
+ /**
+ * Remove user from the storage container
+ *
+ * @access public
+ * @param string Username
+ * @return mixed True on success, PEAR error object on error
+ * and AUTH_METHOD_NOT_SUPPORTED otherwise.
+ */
+ function removeUser($username)
+ {
+ $this->log('Auth::removeUser() called.', AUTH_LOG_DEBUG);
+ $this->_loadStorage();
+ return $this->storage->removeUser($username);
+ }
+
+ // }}}
+ // {{{ changePassword()
+
+ /**
+ * Change password for user in the storage container
+ *
+ * @access public
+ * @param string Username
+ * @param string The new password
+ * @return mixed True on success, PEAR error object on error
+ * and AUTH_METHOD_NOT_SUPPORTED otherwise.
+ */
+ function changePassword($username, $password)
+ {
+ $this->log('Auth::changePassword() called', AUTH_LOG_DEBUG);
+ $this->_loadStorage();
+ return $this->storage->changePassword($username, $password);
+ }
+
+ // }}}
+ // {{{ log()
+
+ /**
+ * Log a message from the Auth system
+ *
+ * @access public
+ * @param string The message to log
+ * @param string The log level to log the message under. See the Log documentation for more info.
+ * @return boolean
+ */
+ function log($message, $level = AUTH_LOG_DEBUG)
+ {
+ if (!$this->enableLogging) return false;
+
+ $this->_loadLogger();
+
+ $this->logger->log('AUTH: '.$message, $level);
+ }
+
+ // }}}
+ // {{{ _loadLogger()
+
+ /**
+ * 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
+ * is already loaded
+ * @access private
+ */
+ function _loadLogger()
+ {
+ if(is_null($this->logger)) {
+ if (!class_exists('Log')) {
+ include_once 'Log.php';
+ }
+ $this->logger =& Log::singleton('null',
+ null,
+ 'auth['.getmypid().']',
+ array(),
+ AUTH_LOG_DEBUG);
+ return(true);
+ }
+ return(false);
+ }
+
+ // }}}
+ // {{{ attachLogObserver()
+
+ /**
+ * Attach an Observer to the Auth Log Source
+ *
+ * @param object Log_Observer A Log Observer instance
+ * @return boolean
+ */
+ function attachLogObserver(&$observer) {
+
+ $this->_loadLogger();
+
+ 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.
+ *
+ * @param integer
+ * @return boolean
+ */
+ function _isAdvancedSecurityEnabled($feature = null) {
+
+ if (is_null($feature)) {
+
+ if ($this->advancedsecurity === true)
+ return true;
+
+ if ( is_array($this->advancedsecurity)
+ && in_array(true, $this->advancedsecurity, true))
+ return true;
+
+ return false;
+
+ } else {
+
+ if (is_array($this->advancedsecurity)) {
+
+ if ( isset($this->advancedsecurity[$feature])
+ && $this->advancedsecurity[$feature] == true)
+ return true;
+
+ return false;
+
+ }
+
+ return (bool)$this->advancedsecurity;
+
+ }
+
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/Array.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/Array.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/Array.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,161 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against a PHP Array
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author georg_1 at have2 dot com
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: Array.php,v 1.5 2007/06/12 03:11:26 aashley Exp $
+ * @since File available since Release 1.4.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once "Auth/Container.php";
+/**
+ * Include PEAR package for error handling
+ */
+require_once "PEAR.php";
+
+/**
+ * Storage driver for fetching authentication data from a PHP Array
+ *
+ * This container takes two options when configuring:
+ *
+ * cryptType: The crypt used to store the password. Currently recognised
+ * are: none, md5 and crypt. default: none
+ * users: A named array of usernames and passwords.
+ * Ex:
+ * array(
+ * 'guest' => '084e0343a0486ff05530df6c705c8bb4', // password guest
+ * 'georg' => 'fc77dba827fcc88e0243404572c51325' // password georg
+ * )
+ *
+ * Usage Example:
+ * <?php
+ * $AuthOptions = array(
+ * 'users' => array(
+ * 'guest' => '084e0343a0486ff05530df6c705c8bb4', // password guest
+ * 'georg' => 'fc77dba827fcc88e0243404572c51325' // password georg
+ * ),
+ * 'cryptType'=>'md5',
+ * );
+ *
+ * $auth = new Auth("Array", $AuthOptions);
+ * ?>
+ *
+ * @category Authentication
+ * @package Auth
+ * @author georg_1 at have2 dot com
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.5 $
+ * @since File available since Release 1.4.0
+ */
+
+class Auth_Container_Array extends Auth_Container {
+
+ // {{{ properties
+
+ /**
+ * The users and their password to authenticate against
+ *
+ * @var array $users
+ */
+ var $users;
+
+ /**
+ * The cryptType used on the passwords
+ *
+ * @var string $cryptType
+ */
+ var $cryptType = 'none';
+
+ // }}}
+ // {{{ Auth_Container_Array()
+
+ /**
+ * Constructor for Array Container
+ *
+ * @param array $data Options for the container
+ * @return void
+ */
+ function Auth_Container_Array($data)
+ {
+ if (!is_array($data)) {
+ PEAR::raiseError('The options for Auth_Container_Array must be an array');
+ }
+ if (isset($data['users']) && is_array($data['users'])) {
+ $this->users = $data['users'];
+ } else {
+ $this->users = array();
+ PEAR::raiseError('Auth_Container_Array: no user data found in options array');
+ }
+ if (isset($data['cryptType'])) {
+ $this->cryptType = $data['cryptType'];
+ }
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Get user information from array
+ *
+ * This function uses the given username to fetch the corresponding
+ * login data from the array. If an account that matches the passed
+ * username and password is found, the function returns true.
+ * Otherwise it returns false.
+ *
+ * @param string Username
+ * @param string Password
+ * @return boolean|PEAR_Error Error object or boolean
+ */
+ function fetchData($user, $pass)
+ {
+ $this->log('Auth_Container_Array::fetchData() called.', AUTH_LOG_DEBUG);
+ if ( isset($this->users[$user])
+ && $this->verifyPassword($pass, $this->users[$user], $this->cryptType)) {
+ return true;
+ }
+ return false;
+ }
+
+ // }}}
+ // {{{ listUsers()
+
+ /**
+ * Returns a list of users available within the container
+ *
+ * @return array
+ */
+ function listUsers()
+ {
+ $this->log('Auth_Container_Array::listUsers() called.', AUTH_LOG_DEBUG);
+ $ret = array();
+ foreach ($this->users as $username => $password) {
+ $ret[]['username'] = $username;
+ }
+ return $ret;
+ }
+
+ // }}}
+
+}
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/DB.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/DB.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/DB.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,639 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against PEAR DB
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Martin Jansen <mj at php.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: DB.php,v 1.74 2008/04/04 07:57:02 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once 'Auth/Container.php';
+/**
+ * Include PEAR DB
+ */
+require_once 'DB.php';
+
+/**
+ * Storage driver for fetching login data from a database
+ *
+ * This storage driver can use all databases which are supported
+ * by the PEAR DB abstraction layer to fetch login data.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Martin Jansen <mj at php.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.74 $
+ * @link http://pear.php.net/package/Auth
+ */
+class Auth_Container_DB extends Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * Additional options for the storage container
+ * @var array
+ */
+ var $options = array();
+
+ /**
+ * DB object
+ * @var object
+ */
+ var $db = null;
+ var $dsn = '';
+
+ /**
+ * User that is currently selected from the DB.
+ * @var string
+ */
+ var $activeUser = '';
+
+ // }}}
+ // {{{ Auth_Container_DB [constructor]
+
+ /**
+ * Constructor of the container class
+ *
+ * Save the initial options passed to the container. Initiation of the DB
+ * connection is no longer performed here and is only done when needed.
+ *
+ * @param string Connection data or DB object
+ * @return object Returns an error object if something went wrong
+ */
+ function Auth_Container_DB($dsn)
+ {
+ $this->_setDefaults();
+
+ if (is_array($dsn)) {
+ $this->_parseOptions($dsn);
+
+ if (empty($this->options['dsn'])) {
+ PEAR::raiseError('No connection parameters specified!');
+ }
+ } else {
+ $this->options['dsn'] = $dsn;
+ }
+ }
+
+ // }}}
+ // {{{ _connect()
+
+ /**
+ * Connect to database by using the given DSN string
+ *
+ * @access private
+ * @param string DSN string
+ * @return mixed Object on error, otherwise bool
+ */
+ function _connect($dsn)
+ {
+ $this->log('Auth_Container_DB::_connect() called.', AUTH_LOG_DEBUG);
+
+ if (is_string($dsn) || is_array($dsn)) {
+ $this->db = DB::Connect($dsn, $this->options['db_options']);
+ } elseif (is_subclass_of($dsn, 'db_common')) {
+ $this->db = $dsn;
+ } elseif (DB::isError($dsn)) {
+ return PEAR::raiseError($dsn->getMessage(), $dsn->getCode());
+ } else {
+ return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
+ 41,
+ PEAR_ERROR_RETURN,
+ null,
+ null
+ );
+ }
+
+ if (DB::isError($this->db) || PEAR::isError($this->db)) {
+ return PEAR::raiseError($this->db->getMessage(), $this->db->getCode());
+ } else {
+ return true;
+ }
+ }
+
+ // }}}
+ // {{{ _prepare()
+
+ /**
+ * Prepare database connection
+ *
+ * This function checks if we have already opened a connection to
+ * the database. If that's not the case, a new connection is opened.
+ *
+ * @access private
+ * @return mixed True or a DB error object.
+ */
+ function _prepare()
+ {
+ if (!DB::isConnection($this->db)) {
+ $res = $this->_connect($this->options['dsn']);
+ if (DB::isError($res) || PEAR::isError($res)) {
+ return $res;
+ }
+ }
+ if ($this->options['auto_quote'] && $this->db->dsn['phptype'] != 'sqlite') {
+ if (strpos('.', $this->options['table']) === false) {
+ $this->options['final_table'] = $this->db->quoteIdentifier($this->options['table']);
+ } else {
+ $t = explode('.', $this->options['table']);
+ for ($i = 0, $count = count($t); $i < $count; $i++)
+ $t[$i] = $this->db->quoteIdentifier($t[$i]);
+ $this->options['final_table'] = implode('.', $t);
+ }
+ $this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol']);
+ $this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol']);
+ } else {
+ $this->options['final_table'] = $this->options['table'];
+ $this->options['final_usernamecol'] = $this->options['usernamecol'];
+ $this->options['final_passwordcol'] = $this->options['passwordcol'];
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ query()
+
+ /**
+ * Prepare query to the database
+ *
+ * This function checks if we have already opened a connection to
+ * the database. If that's not the case, a new connection is opened.
+ * After that the query is passed to the database.
+ *
+ * @access public
+ * @param string Query string
+ * @return mixed a DB_result object or DB_OK on success, a DB
+ * or PEAR error on failure
+ */
+ function query($query)
+ {
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return $err;
+ }
+ return $this->db->query($query);
+ }
+
+ // }}}
+ // {{{ _setDefaults()
+
+ /**
+ * Set some default options
+ *
+ * @access private
+ * @return void
+ */
+ function _setDefaults()
+ {
+ $this->options['table'] = 'auth';
+ $this->options['usernamecol'] = 'username';
+ $this->options['passwordcol'] = 'password';
+ $this->options['dsn'] = '';
+ $this->options['db_fields'] = '';
+ $this->options['cryptType'] = 'md5';
+ $this->options['db_options'] = array();
+ $this->options['db_where'] = '';
+ $this->options['auto_quote'] = true;
+ }
+
+ // }}}
+ // {{{ _parseOptions()
+
+ /**
+ * Parse options passed to the container class
+ *
+ * @access private
+ * @param array
+ */
+ function _parseOptions($array)
+ {
+ foreach ($array as $key => $value) {
+ if (isset($this->options[$key])) {
+ $this->options[$key] = $value;
+ }
+ }
+ }
+
+ // }}}
+ // {{{ _quoteDBFields()
+
+ /**
+ * Quote the db_fields option to avoid the possibility of SQL injection.
+ *
+ * @access private
+ * @return string A properly quoted string that can be concatenated into a
+ * SELECT clause.
+ */
+ function _quoteDBFields()
+ {
+ if (isset($this->options['db_fields'])) {
+ if (is_array($this->options['db_fields'])) {
+ if ($this->options['auto_quote']) {
+ $fields = array();
+ foreach ($this->options['db_fields'] as $field) {
+ $fields[] = $this->db->quoteIdentifier($field);
+ }
+ return implode(', ', $fields);
+ } else {
+ return implode(', ', $this->options['db_fields']);
+ }
+ } else {
+ if (strlen($this->options['db_fields']) > 0) {
+ if ($this->options['auto_quote']) {
+ return $this->db->quoteIdentifier($this->options['db_fields']);
+ } else {
+ return $this->options['db_fields'];
+ }
+ }
+ }
+ }
+
+ return '';
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Get user information from database
+ *
+ * This function uses the given username to fetch
+ * the corresponding login data from the database
+ * table. If an account that matches the passed username
+ * and password is found, the function returns true.
+ * Otherwise it returns false.
+ *
+ * @param string Username
+ * @param string Password
+ * @param boolean If true password is secured using a md5 hash
+ * the frontend and auth are responsible for making sure the container supports
+ * challenge response password authentication
+ * @return mixed Error object or boolean
+ */
+ function fetchData($username, $password, $isChallengeResponse=false)
+ {
+ $this->log('Auth_Container_DB::fetchData() called.', AUTH_LOG_DEBUG);
+ // Prepare for a database query
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ // Find if db_fields contains a *, if so assume all columns are selected
+ if (is_string($this->options['db_fields'])
+ && strstr($this->options['db_fields'], '*')) {
+ $sql_from = "*";
+ } else {
+ $sql_from = $this->options['final_usernamecol'].
+ ", ".$this->options['final_passwordcol'];
+
+ if (strlen($fields = $this->_quoteDBFields()) > 0) {
+ $sql_from .= ', '.$fields;
+ }
+ }
+
+ $query = "SELECT ".$sql_from.
+ " FROM ".$this->options['final_table'].
+ " WHERE ".$this->options['final_usernamecol']." = ".$this->db->quoteSmart($username);
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $query .= " AND ".$this->options['db_where'];
+ }
+
+ $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->db->getRow($query, null, DB_FETCHMODE_ASSOC);
+
+ if (DB::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->getCode());
+ }
+
+ if (!is_array($res)) {
+ $this->activeUser = '';
+ return false;
+ }
+
+ // Perform trimming here before the hashihg
+ $password = trim($password, "\r\n");
+ $res[$this->options['passwordcol']] = trim($res[$this->options['passwordcol']], "\r\n");
+
+ // If using Challenge Response md5 the pass with the secret
+ if ($isChallengeResponse) {
+ $res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]
+ .$this->_auth_obj->session['loginchallenege']);
+
+ // UGLY cannot avoid without modifying verifyPassword
+ if ($this->options['cryptType'] == 'md5') {
+ $res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]);
+ }
+
+ //print " Hashed Password [{$res[$this->options['passwordcol']]}]<br/>\n";
+ }
+
+ if ($this->verifyPassword($password,
+ $res[$this->options['passwordcol']],
+ $this->options['cryptType'])) {
+ // Store additional field values in the session
+ foreach ($res as $key => $value) {
+ if ($key == $this->options['passwordcol'] ||
+ $key == $this->options['usernamecol']) {
+ continue;
+ }
+
+ $this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG);
+
+ // Use reference to the auth object if exists
+ // This is because the auth session variable can change so a
+ // static call to setAuthData does not make sence
+ $this->_auth_obj->setAuthData($key, $value);
+ }
+ return true;
+ }
+ $this->activeUser = $res[$this->options['usernamecol']];
+ return false;
+ }
+
+ // }}}
+ // {{{ listUsers()
+
+ /**
+ * Returns a list of users from the container
+ *
+ * @return mixed
+ * @access public
+ */
+ function listUsers()
+ {
+ $this->log('Auth_Container_DB::listUsers() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ $retVal = array();
+
+ // Find if db_fields contains a *, if so assume all col are selected
+ if ( is_string($this->options['db_fields'])
+ && strstr($this->options['db_fields'], '*')) {
+ $sql_from = "*";
+ } else {
+ $sql_from = $this->options['final_usernamecol'].
+ ", ".$this->options['final_passwordcol'];
+
+ if (strlen($fields = $this->_quoteDBFields()) > 0) {
+ $sql_from .= ', '.$fields;
+ }
+ }
+
+ $query = sprintf("SELECT %s FROM %s",
+ $sql_from,
+ $this->options['final_table']
+ );
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $query .= " WHERE ".$this->options['db_where'];
+ }
+
+ $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->db->getAll($query, null, DB_FETCHMODE_ASSOC);
+
+ if (DB::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->getCode());
+ } else {
+ foreach ($res as $user) {
+ $user['username'] = $user[$this->options['usernamecol']];
+ $retVal[] = $user;
+ }
+ }
+ $this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG);
+ return $retVal;
+ }
+
+ // }}}
+ // {{{ addUser()
+
+ /**
+ * Add user to the storage container
+ *
+ * @access public
+ * @param string Username
+ * @param string Password
+ * @param mixed Additional information that are stored in the DB
+ *
+ * @return mixed True on success, otherwise error object
+ */
+ function addUser($username, $password, $additional = "")
+ {
+ $this->log('Auth_Container_DB::addUser() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ if ( isset($this->options['cryptType'])
+ && $this->options['cryptType'] == 'none') {
+ $cryptFunction = 'strval';
+ } elseif ( isset($this->options['cryptType'])
+ && function_exists($this->options['cryptType'])) {
+ $cryptFunction = $this->options['cryptType'];
+ } else {
+ $cryptFunction = 'md5';
+ }
+
+ $password = $cryptFunction($password);
+
+ $additional_key = '';
+ $additional_value = '';
+
+ if (is_array($additional)) {
+ foreach ($additional as $key => $value) {
+ if ($this->options['auto_quote']) {
+ $additional_key .= ', ' . $this->db->quoteIdentifier($key);
+ } else {
+ $additional_key .= ', ' . $key;
+ }
+ $additional_value .= ", " . $this->db->quoteSmart($value);
+ }
+ }
+
+ $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)",
+ $this->options['final_table'],
+ $this->options['final_usernamecol'],
+ $this->options['final_passwordcol'],
+ $additional_key,
+ $this->db->quoteSmart($username),
+ $this->db->quoteSmart($password),
+ $additional_value
+ );
+
+ $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->query($query);
+
+ if (DB::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->getCode());
+ } else {
+ return true;
+ }
+ }
+
+ // }}}
+ // {{{ removeUser()
+
+ /**
+ * Remove user from the storage container
+ *
+ * @access public
+ * @param string Username
+ *
+ * @return mixed True on success, otherwise error object
+ */
+ function removeUser($username)
+ {
+ $this->log('Auth_Container_DB::removeUser() called.', AUTH_LOG_DEBUG);
+
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $where = " AND ".$this->options['db_where'];
+ } else {
+ $where = '';
+ }
+
+ $query = sprintf("DELETE FROM %s WHERE %s = %s %s",
+ $this->options['final_table'],
+ $this->options['final_usernamecol'],
+ $this->db->quoteSmart($username),
+ $where
+ );
+
+ $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->query($query);
+
+ if (DB::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->getCode());
+ } else {
+ return true;
+ }
+ }
+
+ // }}}
+ // {{{ changePassword()
+
+ /**
+ * Change password for user in the storage container
+ *
+ * @param string Username
+ * @param string The new password (plain text)
+ */
+ function changePassword($username, $password)
+ {
+ $this->log('Auth_Container_DB::changePassword() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ if ( isset($this->options['cryptType'])
+ && $this->options['cryptType'] == 'none') {
+ $cryptFunction = 'strval';
+ } elseif ( isset($this->options['cryptType'])
+ && function_exists($this->options['cryptType'])) {
+ $cryptFunction = $this->options['cryptType'];
+ } else {
+ $cryptFunction = 'md5';
+ }
+
+ $password = $cryptFunction($password);
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $where = " AND ".$this->options['db_where'];
+ } else {
+ $where = '';
+ }
+
+ $query = sprintf("UPDATE %s SET %s = %s WHERE %s = %s %s",
+ $this->options['final_table'],
+ $this->options['final_passwordcol'],
+ $this->db->quoteSmart($password),
+ $this->options['final_usernamecol'],
+ $this->db->quoteSmart($username),
+ $where
+ );
+
+ $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->query($query);
+
+ if (DB::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->getCode());
+ } else {
+ return true;
+ }
+ }
+
+ // }}}
+ // {{{ supportsChallengeResponse()
+
+ /**
+ * Determine if this container supports
+ * password authentication with challenge response
+ *
+ * @return bool
+ * @access public
+ */
+ function supportsChallengeResponse()
+ {
+ return in_array($this->options['cryptType'], array('md5', 'none', ''));
+ }
+
+ // }}}
+ // {{{ getCryptType()
+
+ /**
+ * Returns the selected crypt type for this container
+ */
+ function getCryptType()
+ {
+ return($this->options['cryptType']);
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/DBLite.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/DBLite.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/DBLite.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,320 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Reduced storage driver for use against PEAR DB
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Martin Jansen <mj at php.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: DBLite.php,v 1.20 2008/04/04 07:57:02 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.3.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once 'Auth/Container.php';
+/**
+ * Include PEAR DB package
+ */
+require_once 'DB.php';
+
+/**
+ * A lighter storage driver for fetching login data from a database
+ *
+ * This driver is derived from the DB storage container but
+ * with the user manipulation function removed for smaller file size
+ * by the PEAR DB abstraction layer to fetch login data.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Martin Jansen <mj at php.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.20 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.3.0
+ */
+class Auth_Container_DBLite extends Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * Additional options for the storage container
+ * @var array
+ */
+ var $options = array();
+
+ /**
+ * DB object
+ * @var object
+ */
+ var $db = null;
+ var $dsn = '';
+
+ /**
+ * User that is currently selected from the DB.
+ * @var string
+ */
+ var $activeUser = '';
+
+ // }}}
+ // {{{ Auth_Container_DBLite() [constructor]
+
+ /**
+ * Constructor of the container class
+ *
+ * Initate connection to the database via PEAR::DB
+ *
+ * @param string Connection data or DB object
+ * @return object Returns an error object if something went wrong
+ */
+ function Auth_Container_DBLite($dsn)
+ {
+ $this->options['table'] = 'auth';
+ $this->options['usernamecol'] = 'username';
+ $this->options['passwordcol'] = 'password';
+ $this->options['dsn'] = '';
+ $this->options['db_fields'] = '';
+ $this->options['cryptType'] = 'md5';
+ $this->options['db_options'] = array();
+ $this->options['db_where'] = '';
+ $this->options['auto_quote'] = true;
+
+ if (is_array($dsn)) {
+ $this->_parseOptions($dsn);
+ if (empty($this->options['dsn'])) {
+ PEAR::raiseError('No connection parameters specified!');
+ }
+ } else {
+ $this->options['dsn'] = $dsn;
+ }
+ }
+
+ // }}}
+ // {{{ _connect()
+
+ /**
+ * Connect to database by using the given DSN string
+ *
+ * @access private
+ * @param string DSN string
+ * @return mixed Object on error, otherwise bool
+ */
+ function _connect(&$dsn)
+ {
+ $this->log('Auth_Container_DBLite::_connect() called.', AUTH_LOG_DEBUG);
+ if (is_string($dsn) || is_array($dsn)) {
+ $this->db =& DB::connect($dsn, $this->options['db_options']);
+ } elseif (is_subclass_of($dsn, "db_common")) {
+ $this->db =& $dsn;
+ } else {
+ return PEAR::raiseError("Invalid dsn or db object given");
+ }
+
+ if (DB::isError($this->db) || PEAR::isError($this->db)) {
+ return PEAR::raiseError($this->db->getMessage(), $this->db->getCode());
+ } else {
+ return true;
+ }
+ }
+
+ // }}}
+ // {{{ _prepare()
+
+ /**
+ * Prepare database connection
+ *
+ * This function checks if we have already opened a connection to
+ * the database. If that's not the case, a new connection is opened.
+ *
+ * @access private
+ * @return mixed True or a DB error object.
+ */
+ function _prepare()
+ {
+ if (!DB::isConnection($this->db)) {
+ $res = $this->_connect($this->options['dsn']);
+ if (DB::isError($res) || PEAR::isError($res)) {
+ return $res;
+ }
+ }
+ if ($this->options['auto_quote'] && $this->db->dsn['phptype'] != 'sqlite') {
+ if (strpos('.', $this->options['table']) === false) {
+ $this->options['final_table'] = $this->db->quoteIdentifier($this->options['table']);
+ } else {
+ $t = explode('.', $this->options['table']);
+ for ($i = 0, $count = count($t); $i < $count; $i++)
+ $t[$i] = $this->db->quoteIdentifier($t[$i]);
+ $this->options['final_table'] = implode('.', $t);
+ }
+ $this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol']);
+ $this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol']);
+ } else {
+ $this->options['final_table'] = $this->options['table'];
+ $this->options['final_usernamecol'] = $this->options['usernamecol'];
+ $this->options['final_passwordcol'] = $this->options['passwordcol'];
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ _parseOptions()
+
+ /**
+ * Parse options passed to the container class
+ *
+ * @access private
+ * @param array
+ */
+ function _parseOptions($array)
+ {
+ foreach ($array as $key => $value) {
+ if (isset($this->options[$key])) {
+ $this->options[$key] = $value;
+ }
+ }
+ }
+
+ // }}}
+ // {{{ _quoteDBFields()
+
+ /**
+ * Quote the db_fields option to avoid the possibility of SQL injection.
+ *
+ * @access private
+ * @return string A properly quoted string that can be concatenated into a
+ * SELECT clause.
+ */
+ function _quoteDBFields()
+ {
+ if (isset($this->options['db_fields'])) {
+ if (is_array($this->options['db_fields'])) {
+ if ($this->options['auto_quote']) {
+ $fields = array();
+ foreach ($this->options['db_fields'] as $field) {
+ $fields[] = $this->db->quoteIdentifier($field);
+ }
+ return implode(', ', $fields);
+ } else {
+ return implode(', ', $this->options['db_fields']);
+ }
+ } else {
+ if (strlen($this->options['db_fields']) > 0) {
+ if ($this->options['auto_quote']) {
+ return $this->db->quoteIdentifier($this->options['db_fields']);
+ } else {
+ $this->options['db_fields'];
+ }
+ }
+ }
+ }
+
+ return '';
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Get user information from database
+ *
+ * This function uses the given username to fetch
+ * the corresponding login data from the database
+ * table. If an account that matches the passed username
+ * and password is found, the function returns true.
+ * Otherwise it returns false.
+ *
+ * @param string Username
+ * @param string Password
+ * @return mixed Error object or boolean
+ */
+ function fetchData($username, $password)
+ {
+ $this->log('Auth_Container_DBLite::fetchData() called.', AUTH_LOG_DEBUG);
+ // Prepare for a database query
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ // Find if db_fields contains a *, if so assume all col are selected
+ if (is_string($this->options['db_fields'])
+ && strstr($this->options['db_fields'], '*')) {
+ $sql_from = "*";
+ } else {
+ $sql_from = $this->options['final_usernamecol'].
+ ", ".$this->options['final_passwordcol'];
+
+ if (strlen($fields = $this->_quoteDBFields()) > 0) {
+ $sql_from .= ', '.$fields;
+ }
+ }
+
+ $query = "SELECT ".$sql_from.
+ " FROM ".$this->options['final_table'].
+ " WHERE ".$this->options['final_usernamecol']." = ".$this->db->quoteSmart($username);
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $query .= " AND ".$this->options['db_where'];
+ }
+
+ $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->db->getRow($query, null, DB_FETCHMODE_ASSOC);
+
+ if (DB::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->getCode());
+ }
+ if (!is_array($res)) {
+ $this->activeUser = '';
+ return false;
+ }
+ if ($this->verifyPassword(trim($password, "\r\n"),
+ trim($res[$this->options['passwordcol']], "\r\n"),
+ $this->options['cryptType'])) {
+ // Store additional field values in the session
+ foreach ($res as $key => $value) {
+ if ($key == $this->options['passwordcol'] ||
+ $key == $this->options['usernamecol']) {
+ continue;
+ }
+
+ $this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG);
+
+ // Use reference to the auth object if exists
+ // This is because the auth session variable can change so a static call to setAuthData does not make sence
+ if (is_object($this->_auth_obj)) {
+ $this->_auth_obj->setAuthData($key, $value);
+ } else {
+ Auth::setAuthData($key, $value);
+ }
+ }
+ $this->activeUser = $res[$this->options['usernamecol']];
+ return true;
+ }
+ $this->activeUser = $res[$this->options['usernamecol']];
+ return false;
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/File.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/File.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/File.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,314 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against a generic password file
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Stefan Ekman <stekman at sedata.org>
+ * @author Martin Jansen <mj at php.net>
+ * @author Mika Tuupola <tuupola at appelsiini.net>
+ * @author Michael Wallner <mike at php.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: File.php,v 1.25 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ */
+
+/**
+ * Include PEAR File_Passwd package
+ */
+require_once "File/Passwd.php";
+/**
+ * Include Auth_Container base class
+ */
+require_once "Auth/Container.php";
+/**
+ * Include PEAR package for error handling
+ */
+require_once "PEAR.php";
+
+/**
+ * Storage driver for fetching login data from an encrypted password file.
+ *
+ * This storage container can handle CVS pserver style passwd files.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Stefan Ekman <stekman at sedata.org>
+ * @author Martin Jansen <mj at php.net>
+ * @author Mika Tuupola <tuupola at appelsiini.net>
+ * @author Michael Wallner <mike at php.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.25 $
+ * @link http://pear.php.net/package/Auth
+ */
+class Auth_Container_File extends Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * Path to passwd file
+ *
+ * @var string
+ */
+ var $pwfile = '';
+
+ /**
+ * Options for container
+ *
+ * @var array
+ */
+ var $options = array();
+
+ // }}}
+ // {{{ Auth_Container_File() [constructor]
+
+ /**
+ * Constructor of the container class
+ *
+ * @param string $filename path to passwd file
+ * @return object Auth_Container_File new Auth_Container_File object
+ */
+ function Auth_Container_File($filename) {
+ $this->_setDefaults();
+
+ // Only file is a valid option here
+ if(is_array($filename)) {
+ $this->pwfile = $filename['file'];
+ $this->_parseOptions($filename);
+ } else {
+ $this->pwfile = $filename;
+ }
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Authenticate an user
+ *
+ * @param string username
+ * @param string password
+ * @return mixed boolean|PEAR_Error
+ */
+ function fetchData($user, $pass)
+ {
+ $this->log('Auth_Container_File::fetchData() called.', AUTH_LOG_DEBUG);
+ return File_Passwd::staticAuth($this->options['type'], $this->pwfile, $user, $pass);
+ }
+
+ // }}}
+ // {{{ listUsers()
+
+ /**
+ * List all available users
+ *
+ * @return array
+ */
+ function listUsers()
+ {
+ $this->log('Auth_Container_File::listUsers() called.', AUTH_LOG_DEBUG);
+
+ $pw_obj = &$this->_load();
+ if (PEAR::isError($pw_obj)) {
+ return array();
+ }
+
+ $users = $pw_obj->listUser();
+ if (!is_array($users)) {
+ return array();
+ }
+
+ foreach ($users as $key => $value) {
+ $retVal[] = array("username" => $key,
+ "password" => $value['passwd'],
+ "cvsuser" => $value['system']);
+ }
+
+ $this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG);
+
+ return $retVal;
+ }
+
+ // }}}
+ // {{{ addUser()
+
+ /**
+ * Add a new user to the storage container
+ *
+ * @param string username
+ * @param string password
+ * @param mixed Additional parameters to File_Password_*::addUser()
+ *
+ * @return boolean
+ */
+ function addUser($user, $pass, $additional='')
+ {
+ $this->log('Auth_Container_File::addUser() called.', AUTH_LOG_DEBUG);
+ $params = array($user, $pass);
+ if (is_array($additional)) {
+ foreach ($additional as $item) {
+ $params[] = $item;
+ }
+ } else {
+ $params[] = $additional;
+ }
+
+ $pw_obj = &$this->_load();
+ if (PEAR::isError($pw_obj)) {
+ return false;
+ }
+
+ $res = call_user_func_array(array(&$pw_obj, 'addUser'), $params);
+ if (PEAR::isError($res)) {
+ return false;
+ }
+
+ $res = $pw_obj->save();
+ if (PEAR::isError($res)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ // }}}
+ // {{{ removeUser()
+
+ /**
+ * Remove user from the storage container
+ *
+ * @param string Username
+ * @return boolean
+ */
+ function removeUser($user)
+ {
+ $this->log('Auth_Container_File::removeUser() called.', AUTH_LOG_DEBUG);
+ $pw_obj = &$this->_load();
+ if (PEAR::isError($pw_obj)) {
+ return false;
+ }
+
+ $res = $pw_obj->delUser($user);
+ if (PEAR::isError($res)) {
+ return false;
+ }
+
+ $res = $pw_obj->save();
+ if (PEAR::isError($res)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ // }}}
+ // {{{ changePassword()
+
+ /**
+ * Change password for user in the storage container
+ *
+ * @param string Username
+ * @param string The new password
+ */
+ function changePassword($username, $password)
+ {
+ $this->log('Auth_Container_File::changePassword() called.', AUTH_LOG_DEBUG);
+ $pw_obj = &$this->_load();
+ if (PEAR::isError($pw_obj)) {
+ return false;
+ }
+
+ $res = $pw_obj->changePasswd($username, $password);
+ if (PEAR::isError($res)) {
+ return false;
+ }
+
+ $res = $pw_obj->save();
+ if (PEAR::isError($res)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ // }}}
+ // {{{ _load()
+
+ /**
+ * Load and initialize the File_Passwd object
+ *
+ * @return object File_Passwd_Cvs|PEAR_Error
+ */
+ function &_load()
+ {
+ static $pw_obj;
+
+ if (!isset($pw_obj)) {
+ $this->log('Instanciating File_Password object of type '.$this->options['type'], AUTH_LOG_DEBUG);
+ $pw_obj = File_Passwd::factory($this->options['type']);
+ if (PEAR::isError($pw_obj)) {
+ return $pw_obj;
+ }
+
+ $pw_obj->setFile($this->pwfile);
+
+ $res = $pw_obj->load();
+ if (PEAR::isError($res)) {
+ return $res;
+ }
+ }
+
+ return $pw_obj;
+ }
+
+ // }}}
+ // {{{ _setDefaults()
+
+ /**
+ * Set some default options
+ *
+ * @access private
+ * @return void
+ */
+ function _setDefaults()
+ {
+ $this->options['type'] = 'Cvs';
+ }
+
+ // }}}
+ // {{{ _parseOptions()
+
+ /**
+ * Parse options passed to the container class
+ *
+ * @access private
+ * @param array
+ */
+ function _parseOptions($array)
+ {
+ foreach ($array as $key => $value) {
+ if (isset($this->options[$key])) {
+ $this->options[$key] = $value;
+ }
+ }
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/IMAP.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/IMAP.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/IMAP.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,210 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against IMAP servers
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Jeroen Houben <jeroen at terena.nl>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: IMAP.php,v 1.18 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.2.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once "Auth/Container.php";
+
+/**
+ * Include PEAR class for error handling
+ */
+require_once "PEAR.php";
+
+/**
+ * Storage driver for fetching login data from an IMAP server
+ *
+ * This class is based on LDAP containers, but it very simple.
+ * By default it connects to localhost:143
+ * The constructor will first check if the host:port combination is
+ * actually reachable. This behaviour can be disabled.
+ * It then tries to create an IMAP stream (without opening a mailbox)
+ * If you wish to pass extended options to the connections, you may
+ * do so by specifying protocol options.
+ *
+ * To use this storage containers, you have to use the
+ * following syntax:
+ *
+ * <?php
+ * ...
+ * $params = array(
+ * 'host' => 'mail.example.com',
+ * 'port' => 143,
+ * );
+ * $myAuth = new Auth('IMAP', $params);
+ * ...
+ *
+ * By default we connect without any protocol options set. However, some
+ * servers require you to connect with the notls or norsh options set.
+ * To do this you need to add the following value to the params array:
+ * 'baseDSN' => '/imap/notls/norsh'
+ *
+ * To connect to an SSL IMAP server:
+ * 'baseDSN' => '/imap/ssl'
+ *
+ * To connect to an SSL IMAP server with a self-signed certificate:
+ * 'baseDSN' => '/imap/ssl/novalidate-cert'
+ *
+ * Further options may be available and can be found on the php site at
+ * http://www.php.net/manual/function.imap-open.php
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Jeroen Houben <jeroen at terena.nl>
+ * @author Cipriano Groenendal <cipri at campai.nl>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.18 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.2.0
+ */
+class Auth_Container_IMAP extends Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * Options for the class
+ * @var array
+ */
+ var $options = array();
+
+ // }}}
+ // {{{ Auth_Container_IMAP() [constructor]
+
+ /**
+ * Constructor of the container class
+ *
+ * @param $params associative array with host, port, baseDSN, checkServer
+ * and userattr key
+ * @return object Returns an error object if something went wrong
+ * @todo Use PEAR Net_IMAP if IMAP extension not loaded
+ */
+ function Auth_Container_IMAP($params)
+ {
+ if (!extension_loaded('imap')) {
+ return PEAR::raiseError('Cannot use IMAP authentication, '
+ .'IMAP extension not loaded!', 41, PEAR_ERROR_DIE);
+ }
+ $this->_setDefaults();
+
+ // set parameters (if any)
+ if (is_array($params)) {
+ $this->_parseOptions($params);
+ }
+
+ if ($this->options['checkServer']) {
+ $this->_checkServer($this->options['timeout']);
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ _setDefaults()
+
+ /**
+ * Set some default options
+ *
+ * @access private
+ */
+ function _setDefaults()
+ {
+ $this->options['host'] = 'localhost';
+ $this->options['port'] = 143;
+ $this->options['baseDSN'] = '';
+ $this->options['checkServer'] = true;
+ $this->options['timeout'] = 20;
+ }
+
+ // }}}
+ // {{{ _checkServer()
+
+ /**
+ * Check if the given server and port are reachable
+ *
+ * @access private
+ */
+ function _checkServer() {
+ $this->log('Auth_Container_IMAP::_checkServer() called.', AUTH_LOG_DEBUG);
+ $fp = @fsockopen ($this->options['host'], $this->options['port'],
+ $errno, $errstr, $this->options['timeout']);
+ if (is_resource($fp)) {
+ @fclose($fp);
+ } else {
+ $message = "Error connecting to IMAP server "
+ . $this->options['host']
+ . ":" . $this->options['port'];
+ return PEAR::raiseError($message, 41);
+ }
+ }
+
+ // }}}
+ // {{{ _parseOptions()
+
+ /**
+ * Parse options passed to the container class
+ *
+ * @access private
+ * @param array
+ */
+ function _parseOptions($array)
+ {
+ foreach ($array as $key => $value) {
+ $this->options[$key] = $value;
+ }
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Try to open a IMAP stream using $username / $password
+ *
+ * @param string Username
+ * @param string Password
+ * @return boolean
+ */
+ function fetchData($username, $password)
+ {
+ $this->log('Auth_Container_IMAP::fetchData() called.', AUTH_LOG_DEBUG);
+ $dsn = '{'.$this->options['host'].':'.$this->options['port'].$this->options['baseDSN'].'}';
+ $conn = @imap_open ($dsn, $username, $password, OP_HALFOPEN);
+ if (is_resource($conn)) {
+ $this->log('Successfully connected to IMAP server.', AUTH_LOG_DEBUG);
+ $this->activeUser = $username;
+ @imap_close($conn);
+ return true;
+ } else {
+ $this->log('Connection to IMAP server failed.', AUTH_LOG_DEBUG);
+ $this->activeUser = '';
+ return false;
+ }
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/KADM5.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/KADM5.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/KADM5.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,171 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for Authentication on a Kerberos V server.
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Andrew Teixeira <ateixeira at gmail.com>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: KADM5.php,v 1.6 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.4.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once 'Auth/Container.php';
+/**
+ * Include PEAR for error handling
+ */
+require_once 'PEAR.php';
+
+/**
+ * Storage driver for Authentication on a Kerberos V server.
+ *
+ * Available options:
+ * hostname: The hostname of the kerberos server
+ * realm: The Kerberos V realm
+ * timeout: The timeout for checking the server
+ * checkServer: Set to true to check if the server is running when
+ * constructing the object
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Andrew Teixeira <ateixeira at gmail.com>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.6 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.4.0
+ */
+class Auth_Container_KADM5 extends Auth_Container {
+
+ // {{{ properties
+
+ /**
+ * Options for the class
+ * @var string
+ */
+ var $options = array();
+
+ // }}}
+ // {{{ Auth_Container_KADM5()
+
+ /**
+ * Constructor of the container class
+ *
+ * $options can have these keys:
+ * 'hostname' The hostname of the kerberos server
+ * 'realm' The Kerberos V realm
+ * 'timeout' The timeout for checking the server
+ * 'checkServer' Set to true to check if the server is running when
+ * constructing the object
+ *
+ * @param $options associative array
+ * @return object Returns an error object if something went wrong
+ */
+ function Auth_Container_KADM5($options) {
+ if (!extension_loaded('kadm5')) {
+ return PEAR::raiseError("Cannot use Kerberos V authentication, KADM5 extension not loaded!", 41, PEAR_ERROR_DIE);
+ }
+
+ $this->_setDefaults();
+
+ if (isset($options['hostname'])) {
+ $this->options['hostname'] = $options['hostname'];
+ }
+ if (isset($options['realm'])) {
+ $this->options['realm'] = $options['realm'];
+ }
+ if (isset($options['timeout'])) {
+ $this->options['timeout'] = $options['timeout'];
+ }
+ if (isset($options['checkServer'])) {
+ $this->options['checkServer'] = $options['checkServer'];
+ }
+
+ if ($this->options['checkServer']) {
+ $this->_checkServer();
+ }
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Try to login to the KADM5 server
+ *
+ * @param string Username
+ * @param string Password
+ * @return boolean
+ */
+ function fetchData($username, $password) {
+ $this->log('Auth_Container_KADM5::fetchData() called.', AUTH_LOG_DEBUG);
+ if ( ($username == NULL) || ($password == NULL) ) {
+ return false;
+ }
+
+ $server = $this->options['hostname'];
+ $realm = $this->options['realm'];
+ $check = @kadm5_init_with_password($server, $realm, $username, $password);
+
+ if ($check == false) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ // }}}
+ // {{{ _setDefaults()
+
+ /**
+ * Set some default options
+ *
+ * @access private
+ */
+ function _setDefaults() {
+ $this->options['hostname'] = 'localhost';
+ $this->options['realm'] = NULL;
+ $this->options['timeout'] = 10;
+ $this->options['checkServer'] = false;
+ }
+
+ // }}}
+ // {{{ _checkServer()
+
+ /**
+ * Check if the given server and port are reachable
+ *
+ * @access private
+ */
+ function _checkServer() {
+ $fp = @fsockopen ($this->options['hostname'], 88, $errno, $errstr, $this->options['timeout']);
+ if (is_resource($fp)) {
+ @fclose($fp);
+ } else {
+ $message = "Error connecting to Kerberos V server "
+ .$this->options['hostname'].":".$this->options['port'];
+ return PEAR::raiseError($message, 41, PEAR_ERROR_DIE);
+ }
+ }
+
+ // }}}
+
+}
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/LDAP.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/LDAP.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/LDAP.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,766 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against an LDAP server
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Jan Wagner <wagner at netsols.de>
+ * @author Adam Ashley <aashley at php.net>
+ * @author Hugues Peeters <hugues.peeters at claroline.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: LDAP.php,v 1.43 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once "Auth/Container.php";
+/**
+ * Include PEAR package for error handling
+ */
+require_once "PEAR.php";
+
+/**
+ * Storage driver for fetching login data from LDAP
+ *
+ * This class is heavily based on the DB and File containers. By default it
+ * connects to localhost:389 and searches for uid=$username with the scope
+ * "sub". If no search base is specified, it will try to determine it via
+ * the namingContexts attribute. It takes its parameters in a hash, connects
+ * to the ldap server, binds anonymously, searches for the user, and tries
+ * to bind as the user with the supplied password. When a group was set, it
+ * will look for group membership of the authenticated user. If all goes
+ * well the authentication was successful.
+ *
+ * Parameters:
+ *
+ * host: localhost (default), ldap.netsols.de or 127.0.0.1
+ * port: 389 (default) or 636 or whereever your server runs
+ * url: ldap://localhost:389/
+ * useful for ldaps://, works only with openldap2 ?
+ * it will be preferred over host and port
+ * version: LDAP version to use, ususally 2 (default) or 3,
+ * must be an integer!
+ * referrals: If set, determines whether the LDAP library automatically
+ * follows referrals returned by LDAP servers or not. Possible
+ * values are true (default) or false.
+ * binddn: If set, searching for user will be done after binding
+ * as this user, if not set the bind will be anonymous.
+ * This is reported to make the container work with MS
+ * Active Directory, but should work with any server that
+ * is configured this way.
+ * This has to be a complete dn for now (basedn and
+ * userdn will not be appended).
+ * bindpw: The password to use for binding with binddn
+ * basedn: the base dn of your server
+ * userdn: gets prepended to basedn when searching for user
+ * userscope: Scope for user searching: one, sub (default), or base
+ * userattr: the user attribute to search for (default: uid)
+ * userfilter: filter that will be added to the search filter
+ * this way: (&(userattr=username)(userfilter))
+ * default: (objectClass=posixAccount)
+ * attributes: array of additional attributes to fetch from entry.
+ * these will added to auth data and can be retrieved via
+ * Auth::getAuthData(). An empty array will fetch all attributes,
+ * array('') will fetch no attributes at all (default)
+ * If you add 'dn' as a value to this array, the users DN that was
+ * used for binding will be added to auth data as well.
+ * attrformat: The returned format of the additional data defined in the
+ * 'attributes' option. Two formats are available.
+ * LDAP returns data formatted in a
+ * multidimensional array where each array starts with a
+ * 'count' element providing the number of attributes in the
+ * entry, or the number of values for attributes. When set
+ * to this format, the only way to retrieve data from the
+ * Auth object is by calling getAuthData('attributes').
+ * AUTH returns data formatted in a
+ * structure more compliant with other Auth Containers,
+ * where each attribute element can be directly called by
+ * getAuthData() method from Auth.
+ * For compatibily with previous LDAP container versions,
+ * the default format is LDAP.
+ * groupdn: gets prepended to basedn when searching for group
+ * groupattr: the group attribute to search for (default: cn)
+ * groupfilter: filter that will be added to the search filter when
+ * searching for a group:
+ * (&(groupattr=group)(memberattr=username)(groupfilter))
+ * default: (objectClass=groupOfUniqueNames)
+ * memberattr : the attribute of the group object where the user dn
+ * may be found (default: uniqueMember)
+ * memberisdn: whether the memberattr is the dn of the user (default)
+ * or the value of userattr (usually uid)
+ * group: the name of group to search for
+ * groupscope: Scope for group searching: one, sub (default), or base
+ * start_tls: enable/disable the use of START_TLS encrypted connection
+ * (default: false)
+ * debug: Enable/Disable debugging output (default: false)
+ * try_all: Whether to try all user accounts returned from the search
+ * or just the first one. (default: false)
+ *
+ * To use this storage container, you have to use the following syntax:
+ *
+ * <?php
+ * ...
+ *
+ * $a1 = new Auth("LDAP", array(
+ * 'host' => 'localhost',
+ * 'port' => '389',
+ * 'version' => 3,
+ * 'basedn' => 'o=netsols,c=de',
+ * 'userattr' => 'uid'
+ * 'binddn' => 'cn=admin,o=netsols,c=de',
+ * 'bindpw' => 'password'));
+ *
+ * $a2 = new Auth('LDAP', array(
+ * 'url' => 'ldaps://ldap.netsols.de',
+ * 'basedn' => 'o=netsols,c=de',
+ * 'userscope' => 'one',
+ * 'userdn' => 'ou=People',
+ * 'groupdn' => 'ou=Groups',
+ * 'groupfilter' => '(objectClass=posixGroup)',
+ * 'memberattr' => 'memberUid',
+ * 'memberisdn' => false,
+ * 'group' => 'admin'
+ * ));
+ *
+ * $a3 = new Auth('LDAP', array(
+ * 'host' => 'ldap.netsols.de',
+ * 'port' => 389,
+ * 'version' => 3,
+ * 'referrals' => false,
+ * 'basedn' => 'dc=netsols,dc=de',
+ * 'binddn' => 'cn=Jan Wagner,cn=Users,dc=netsols,dc=de',
+ * 'bindpw' => 'password',
+ * 'userattr' => 'samAccountName',
+ * 'userfilter' => '(objectClass=user)',
+ * 'attributes' => array(''),
+ * 'group' => 'testing',
+ * 'groupattr' => 'samAccountName',
+ * 'groupfilter' => '(objectClass=group)',
+ * 'memberattr' => 'member',
+ * 'memberisdn' => true,
+ * 'groupdn' => 'cn=Users',
+ * 'groupscope' => 'one',
+ * 'debug' => true);
+ *
+ * The parameter values have to correspond
+ * to the ones for your LDAP server of course.
+ *
+ * When talking to a Microsoft ActiveDirectory server you have to
+ * use 'samaccountname' as the 'userattr' and follow special rules
+ * to translate the ActiveDirectory directory names into 'basedn'.
+ * The 'basedn' for the default 'Users' folder on an ActiveDirectory
+ * server for the ActiveDirectory Domain (which is not related to
+ * its DNS name) "win2000.example.org" would be:
+ * "CN=Users, DC=win2000, DC=example, DC=org'
+ * where every component of the domain name becomes a DC attribute
+ * of its own. If you want to use a custom users folder you have to
+ * replace "CN=Users" with a sequence of "OU" attributes that specify
+ * the path to your custom folder in reverse order.
+ * So the ActiveDirectory folder
+ * "win2000.example.org\Custom\Accounts"
+ * would become
+ * "OU=Accounts, OU=Custom, DC=win2000, DC=example, DC=org'
+ *
+ * It seems that binding anonymously to an Active Directory
+ * is not allowed, so you have to set binddn and bindpw for
+ * user searching.
+ *
+ * LDAP Referrals need to be set to false for AD to work sometimes.
+ *
+ * Example a3 shows a full blown and tested example for connection to
+ * Windows 2000 Active Directory with group mebership checking
+ *
+ * Note also that if you want an encrypted connection to an MS LDAP
+ * server, then, on your webserver, you must specify
+ * TLS_REQCERT never
+ * in /etc/ldap/ldap.conf or in the webserver user's ~/.ldaprc (which
+ * may or may not be read depending on your configuration).
+ *
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Jan Wagner <wagner at netsols.de>
+ * @author Adam Ashley <aashley at php.net>
+ * @author Hugues Peeters <hugues.peeters at claroline.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.43 $
+ * @link http://pear.php.net/package/Auth
+ */
+class Auth_Container_LDAP extends Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * Options for the class
+ * @var array
+ */
+ var $options = array();
+
+ /**
+ * Connection ID of LDAP Link
+ * @var string
+ */
+ var $conn_id = false;
+
+ // }}}
+
+ // {{{ Auth_Container_LDAP() [constructor]
+
+ /**
+ * Constructor of the container class
+ *
+ * @param $params, associative hash with host,port,basedn and userattr key
+ * @return object Returns an error object if something went wrong
+ */
+ function Auth_Container_LDAP($params)
+ {
+ if (false === extension_loaded('ldap')) {
+ return PEAR::raiseError('Auth_Container_LDAP: LDAP Extension not loaded',
+ 41, PEAR_ERROR_DIE);
+ }
+
+ $this->_setDefaults();
+
+ if (is_array($params)) {
+ $this->_parseOptions($params);
+ }
+ }
+
+ // }}}
+ // {{{ _prepare()
+
+ /**
+ * Prepare LDAP connection
+ *
+ * This function checks if we have already opened a connection to
+ * the LDAP server. If that's not the case, a new connection is opened.
+ *
+ * @access private
+ * @return mixed True or a PEAR error object.
+ */
+ function _prepare()
+ {
+ if (!$this->_isValidLink()) {
+ $res = $this->_connect();
+ if (PEAR::isError($res)) {
+ return $res;
+ }
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ _connect()
+
+ /**
+ * Connect to the LDAP server using the global options
+ *
+ * @access private
+ * @return object Returns a PEAR error object if an error occurs.
+ */
+ function _connect()
+ {
+ $this->log('Auth_Container_LDAP::_connect() called.', AUTH_LOG_DEBUG);
+ // connect
+ if (isset($this->options['url']) && $this->options['url'] != '') {
+ $this->log('Connecting with URL', AUTH_LOG_DEBUG);
+ $conn_params = array($this->options['url']);
+ } else {
+ $this->log('Connecting with host:port', AUTH_LOG_DEBUG);
+ $conn_params = array($this->options['host'], $this->options['port']);
+ }
+
+ if (($this->conn_id = @call_user_func_array('ldap_connect', $conn_params)) === false) {
+ $this->log('Connection to server failed.', AUTH_LOG_DEBUG);
+ $this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG);
+ return PEAR::raiseError('Auth_Container_LDAP: Could not connect to server.', 41);
+ }
+ $this->log('Successfully connected to server', AUTH_LOG_DEBUG);
+
+ // switch LDAP version
+ if (is_numeric($this->options['version']) && $this->options['version'] > 2) {
+ $this->log("Switching to LDAP version {$this->options['version']}", AUTH_LOG_DEBUG);
+ @ldap_set_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $this->options['version']);
+
+ // start TLS if available
+ if (isset($this->options['start_tls']) && $this->options['start_tls']) {
+ $this->log("Starting TLS session", AUTH_LOG_DEBUG);
+ if (@ldap_start_tls($this->conn_id) === false) {
+ $this->log('Could not start TLS session', AUTH_LOG_DEBUG);
+ $this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG);
+ return PEAR::raiseError('Auth_Container_LDAP: Could not start tls.', 41);
+ }
+ }
+ }
+
+ // switch LDAP referrals
+ if (is_bool($this->options['referrals'])) {
+ $this->log("Switching LDAP referrals to " . (($this->options['referrals']) ? 'true' : 'false'), AUTH_LOG_DEBUG);
+ if (@ldap_set_option($this->conn_id, LDAP_OPT_REFERRALS, $this->options['referrals']) === false) {
+ $this->log('Could not change LDAP referrals options', AUTH_LOG_DEBUG);
+ $this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG);
+ }
+ }
+
+ // bind with credentials or anonymously
+ if (strlen($this->options['binddn']) && strlen($this->options['bindpw'])) {
+ $this->log('Binding with credentials', AUTH_LOG_DEBUG);
+ $bind_params = array($this->conn_id, $this->options['binddn'], $this->options['bindpw']);
+ } else {
+ $this->log('Binding anonymously', AUTH_LOG_DEBUG);
+ $bind_params = array($this->conn_id);
+ }
+
+ // bind for searching
+ if ((@call_user_func_array('ldap_bind', $bind_params)) === false) {
+ $this->log('Bind failed', AUTH_LOG_DEBUG);
+ $this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG);
+ $this->_disconnect();
+ return PEAR::raiseError("Auth_Container_LDAP: Could not bind to LDAP server.", 41);
+ }
+ $this->log('Binding was successful', AUTH_LOG_DEBUG);
+
+ return true;
+ }
+
+ // }}}
+ // {{{ _disconnect()
+
+ /**
+ * Disconnects (unbinds) from ldap server
+ *
+ * @access private
+ */
+ function _disconnect()
+ {
+ $this->log('Auth_Container_LDAP::_disconnect() called.', AUTH_LOG_DEBUG);
+ if ($this->_isValidLink()) {
+ $this->log('disconnecting from server');
+ @ldap_unbind($this->conn_id);
+ }
+ }
+
+ // }}}
+ // {{{ _getBaseDN()
+
+ /**
+ * Tries to find Basedn via namingContext Attribute
+ *
+ * @access private
+ */
+ function _getBaseDN()
+ {
+ $this->log('Auth_Container_LDAP::_getBaseDN() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ if ($this->options['basedn'] == "" && $this->_isValidLink()) {
+ $this->log("basedn not set, searching via namingContexts.", AUTH_LOG_DEBUG);
+
+ $result_id = @ldap_read($this->conn_id, "", "(objectclass=*)", array("namingContexts"));
+
+ if (@ldap_count_entries($this->conn_id, $result_id) == 1) {
+
+ $this->log("got result for namingContexts", AUTH_LOG_DEBUG);
+
+ $entry_id = @ldap_first_entry($this->conn_id, $result_id);
+ $attrs = @ldap_get_attributes($this->conn_id, $entry_id);
+ $basedn = $attrs['namingContexts'][0];
+
+ if ($basedn != "") {
+ $this->log("result for namingContexts was $basedn", AUTH_LOG_DEBUG);
+ $this->options['basedn'] = $basedn;
+ }
+ }
+ @ldap_free_result($result_id);
+ }
+
+ // if base ist still not set, raise error
+ if ($this->options['basedn'] == "") {
+ return PEAR::raiseError("Auth_Container_LDAP: LDAP search base not specified!", 41);
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ _isValidLink()
+
+ /**
+ * determines whether there is a valid ldap conenction or not
+ *
+ * @accessd private
+ * @return boolean
+ */
+ function _isValidLink()
+ {
+ if (is_resource($this->conn_id)) {
+ if (get_resource_type($this->conn_id) == 'ldap link') {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // }}}
+ // {{{ _setDefaults()
+
+ /**
+ * Set some default options
+ *
+ * @access private
+ */
+ function _setDefaults()
+ {
+ $this->options['url'] = '';
+ $this->options['host'] = 'localhost';
+ $this->options['port'] = '389';
+ $this->options['version'] = 2;
+ $this->options['referrals'] = true;
+ $this->options['binddn'] = '';
+ $this->options['bindpw'] = '';
+ $this->options['basedn'] = '';
+ $this->options['userdn'] = '';
+ $this->options['userscope'] = 'sub';
+ $this->options['userattr'] = 'uid';
+ $this->options['userfilter'] = '(objectClass=posixAccount)';
+ $this->options['attributes'] = array(''); // no attributes
+ $this->options['attrformat'] = 'AUTH'; // returns attribute like other Auth containers
+ $this->options['group'] = '';
+ $this->options['groupdn'] = '';
+ $this->options['groupscope'] = 'sub';
+ $this->options['groupattr'] = 'cn';
+ $this->options['groupfilter'] = '(objectClass=groupOfUniqueNames)';
+ $this->options['memberattr'] = 'uniqueMember';
+ $this->options['memberisdn'] = true;
+ $this->options['start_tls'] = false;
+ $this->options['debug'] = false;
+ $this->options['try_all'] = false; // Try all user ids returned not just the first one
+ }
+
+ // }}}
+ // {{{ _parseOptions()
+
+ /**
+ * Parse options passed to the container class
+ *
+ * @access private
+ * @param array
+ */
+ function _parseOptions($array)
+ {
+ $array = $this->_setV12OptionsToV13($array);
+
+ foreach ($array as $key => $value) {
+ if (array_key_exists($key, $this->options)) {
+ if ($key == 'attributes') {
+ if (is_array($value)) {
+ $this->options[$key] = $value;
+ } else {
+ $this->options[$key] = explode(',', $value);
+ }
+ } else {
+ $this->options[$key] = $value;
+ }
+ }
+ }
+ }
+
+ // }}}
+ // {{{ _setV12OptionsToV13()
+
+ /**
+ * Adapt deprecated options from Auth 1.2 LDAP to Auth 1.3 LDAP
+ *
+ * @author Hugues Peeters <hugues.peeters at claroline.net>
+ * @access private
+ * @param array
+ * @return array
+ */
+ function _setV12OptionsToV13($array)
+ {
+ if (isset($array['useroc']))
+ $array['userfilter'] = "(objectClass=".$array['useroc'].")";
+ if (isset($array['groupoc']))
+ $array['groupfilter'] = "(objectClass=".$array['groupoc'].")";
+ if (isset($array['scope']))
+ $array['userscope'] = $array['scope'];
+
+ return $array;
+ }
+
+ // }}}
+ // {{{ _scope2function()
+
+ /**
+ * Get search function for scope
+ *
+ * @param string scope
+ * @return string ldap search function
+ */
+ function _scope2function($scope)
+ {
+ switch($scope) {
+ case 'one':
+ $function = 'ldap_list';
+ break;
+ case 'base':
+ $function = 'ldap_read';
+ break;
+ default:
+ $function = 'ldap_search';
+ break;
+ }
+ return $function;
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Fetch data from LDAP server
+ *
+ * Searches the LDAP server for the given username/password
+ * combination. Escapes all LDAP meta characters in username
+ * before performing the query.
+ *
+ * @param string Username
+ * @param string Password
+ * @return boolean
+ */
+ function fetchData($username, $password)
+ {
+ $this->log('Auth_Container_LDAP::fetchData() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ $err = $this->_getBaseDN();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ // UTF8 Encode username for LDAPv3
+ if (@ldap_get_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $ver) && $ver == 3) {
+ $this->log('UTF8 encoding username for LDAPv3', AUTH_LOG_DEBUG);
+ $username = utf8_encode($username);
+ }
+
+ // make search filter
+ $filter = sprintf('(&(%s=%s)%s)',
+ $this->options['userattr'],
+ $this->_quoteFilterString($username),
+ $this->options['userfilter']);
+
+ // make search base dn
+ $search_basedn = $this->options['userdn'];
+ if ($search_basedn != '' && substr($search_basedn, -1) != ',') {
+ $search_basedn .= ',';
+ }
+ $search_basedn .= $this->options['basedn'];
+
+ // attributes
+ $searchAttributes = $this->options['attributes'];
+
+ // make functions params array
+ $func_params = array($this->conn_id, $search_basedn, $filter, $searchAttributes);
+
+ // search function to use
+ $func_name = $this->_scope2function($this->options['userscope']);
+
+ $this->log("Searching with $func_name and filter $filter in $search_basedn", AUTH_LOG_DEBUG);
+
+ // search
+ if (($result_id = @call_user_func_array($func_name, $func_params)) === false) {
+ $this->log('User not found', AUTH_LOG_DEBUG);
+ } elseif (@ldap_count_entries($this->conn_id, $result_id) >= 1) { // did we get some possible results?
+
+ $this->log('User(s) found', AUTH_LOG_DEBUG);
+
+ $first = true;
+ $entry_id = null;
+
+ do {
+
+ // then get the user dn
+ if ($first) {
+ $entry_id = @ldap_first_entry($this->conn_id, $result_id);
+ $first = false;
+ } else {
+ $entry_id = @ldap_next_entry($this->conn_id, $entry_id);
+ if ($entry_id === false)
+ break;
+ }
+ $user_dn = @ldap_get_dn($this->conn_id, $entry_id);
+
+ // as the dn is not fetched as an attribute, we save it anyway
+ if (is_array($searchAttributes) && in_array('dn', $searchAttributes)) {
+ $this->log('Saving DN to AuthData', AUTH_LOG_DEBUG);
+ $this->_auth_obj->setAuthData('dn', $user_dn);
+ }
+
+ // fetch attributes
+ if ($attributes = @ldap_get_attributes($this->conn_id, $entry_id)) {
+
+ if (is_array($attributes) && isset($attributes['count']) &&
+ $attributes['count'] > 0) {
+
+ // ldap_get_attributes() returns a specific multi dimensional array
+ // format containing all the attributes and where each array starts
+ // with a 'count' element providing the number of attributes in the
+ // entry, or the number of values for attribute. For compatibility
+ // reasons, it remains the default format returned by LDAP container
+ // setAuthData().
+ // The code below optionally returns attributes in another format,
+ // more compliant with other Auth containers, where each attribute
+ // element are directly set in the 'authData' list. This option is
+ // enabled by setting 'attrformat' to
+ // 'AUTH' in the 'options' array.
+ // eg. $this->options['attrformat'] = 'AUTH'
+
+ if ( strtoupper($this->options['attrformat']) == 'AUTH' ) {
+ $this->log('Saving attributes to Auth data in AUTH format', AUTH_LOG_DEBUG);
+ unset ($attributes['count']);
+ foreach ($attributes as $attributeName => $attributeValue ) {
+ if (is_int($attributeName)) continue;
+ if (is_array($attributeValue) && isset($attributeValue['count'])) {
+ unset ($attributeValue['count']);
+ }
+ if (count($attributeValue)<=1) $attributeValue = $attributeValue[0];
+ $this->log('Storing additional field: '.$attributeName, AUTH_LOG_DEBUG);
+ $this->_auth_obj->setAuthData($attributeName, $attributeValue);
+ }
+ }
+ else
+ {
+ $this->log('Saving attributes to Auth data in LDAP format', AUTH_LOG_DEBUG);
+ $this->_auth_obj->setAuthData('attributes', $attributes);
+ }
+ }
+ }
+ @ldap_free_result($result_id);
+
+ // need to catch an empty password as openldap seems to return TRUE
+ // if anonymous binding is allowed
+ if ($password != "") {
+ $this->log("Bind as $user_dn", AUTH_LOG_DEBUG);
+
+ // try binding as this user with the supplied password
+ if (@ldap_bind($this->conn_id, $user_dn, $password)) {
+ $this->log('Bind successful', AUTH_LOG_DEBUG);
+
+ // check group if appropiate
+ if (strlen($this->options['group'])) {
+ // decide whether memberattr value is a dn or the username
+ $this->log('Checking group membership', AUTH_LOG_DEBUG);
+ $return = $this->checkGroup(($this->options['memberisdn']) ? $user_dn : $username);
+ $this->_disconnect();
+ return $return;
+ } else {
+ $this->log('Authenticated', AUTH_LOG_DEBUG);
+ $this->_disconnect();
+ return true; // user authenticated
+ } // checkGroup
+ } // bind
+ } // non-empty password
+ } while ($this->options['try_all'] == true); // interate through entries
+ } // get results
+ // default
+ $this->log('NOT authenticated!', AUTH_LOG_DEBUG);
+ $this->_disconnect();
+ return false;
+ }
+
+ // }}}
+ // {{{ checkGroup()
+
+ /**
+ * Validate group membership
+ *
+ * Searches the LDAP server for group membership of the
+ * supplied username. Quotes all LDAP filter meta characters in
+ * the user name before querying the LDAP server.
+ *
+ * @param string Distinguished Name of the authenticated User
+ * @return boolean
+ */
+ function checkGroup($user)
+ {
+ $this->log('Auth_Container_LDAP::checkGroup() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ // make filter
+ $filter = sprintf('(&(%s=%s)(%s=%s)%s)',
+ $this->options['groupattr'],
+ $this->options['group'],
+ $this->options['memberattr'],
+ $this->_quoteFilterString($user),
+ $this->options['groupfilter']);
+
+ // make search base dn
+ $search_basedn = $this->options['groupdn'];
+ if ($search_basedn != '' && substr($search_basedn, -1) != ',') {
+ $search_basedn .= ',';
+ }
+ $search_basedn .= $this->options['basedn'];
+
+ $func_params = array($this->conn_id, $search_basedn, $filter,
+ array($this->options['memberattr']));
+ $func_name = $this->_scope2function($this->options['groupscope']);
+
+ $this->log("Searching with $func_name and filter $filter in $search_basedn", AUTH_LOG_DEBUG);
+
+ // search
+ if (($result_id = @call_user_func_array($func_name, $func_params)) != false) {
+ if (@ldap_count_entries($this->conn_id, $result_id) == 1) {
+ @ldap_free_result($result_id);
+ $this->log('User is member of group', AUTH_LOG_DEBUG);
+ return true;
+ }
+ }
+ // default
+ $this->log('User is NOT member of group', AUTH_LOG_DEBUG);
+ return false;
+ }
+
+ // }}}
+ // {{{ _quoteFilterString()
+
+ /**
+ * Escapes LDAP filter special characters as defined in RFC 2254.
+ *
+ * @access private
+ * @param string Filter String
+ */
+ function _quoteFilterString($filter_str)
+ {
+ $metas = array( '\\', '*', '(', ')', "\x00");
+ $quoted_metas = array('\\\\', '\*', '\(', '\)', "\\\x00");
+ return str_replace($metas, $quoted_metas, $filter_str);
+ }
+
+ // }}}
+
+}
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/MDB.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/MDB.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/MDB.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,625 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against PEAR MDB
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Lorenzo Alberton <l.alberton at quipo.it>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: MDB.php,v 1.37 2008/04/04 07:57:02 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.2.3
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once 'Auth/Container.php';
+/**
+ * Include PEAR MDB package
+ */
+require_once 'MDB.php';
+
+/**
+ * Storage driver for fetching login data from a database
+ *
+ * This storage driver can use all databases which are supported
+ * by the PEAR MDB abstraction layer to fetch login data.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Lorenzo Alberton <l.alberton at quipo.it>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.37 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.2.3
+ */
+class Auth_Container_MDB extends Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * Additional options for the storage container
+ * @var array
+ */
+ var $options = array();
+
+ /**
+ * MDB object
+ * @var object
+ */
+ var $db = null;
+ var $dsn = '';
+
+ /**
+ * User that is currently selected from the DB.
+ * @var string
+ */
+ var $activeUser = '';
+
+ // }}}
+ // {{{ Auth_Container_MDB() [constructor]
+
+ /**
+ * Constructor of the container class
+ *
+ * Initate connection to the database via PEAR::MDB
+ *
+ * @param string Connection data or MDB object
+ * @return object Returns an error object if something went wrong
+ */
+ function Auth_Container_MDB($dsn)
+ {
+ $this->_setDefaults();
+
+ if (is_array($dsn)) {
+ $this->_parseOptions($dsn);
+ if (empty($this->options['dsn'])) {
+ PEAR::raiseError('No connection parameters specified!');
+ }
+ } else {
+ $this->options['dsn'] = $dsn;
+ }
+ }
+
+ // }}}
+ // {{{ _connect()
+
+ /**
+ * Connect to database by using the given DSN string
+ *
+ * @access private
+ * @param mixed DSN string | array | mdb object
+ * @return mixed Object on error, otherwise bool
+ */
+ function _connect($dsn)
+ {
+ $this->log('Auth_Container_MDB::_connect() called.', AUTH_LOG_DEBUG);
+ if (is_string($dsn) || is_array($dsn)) {
+ $this->db =& MDB::connect($dsn, $this->options['db_options']);
+ } elseif (is_subclass_of($dsn, 'mdb_common')) {
+ $this->db = $dsn;
+ } elseif (is_object($dsn) && MDB::isError($dsn)) {
+ return PEAR::raiseError($dsn->getMessage(), $dsn->code);
+ } else {
+ return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
+ 41,
+ PEAR_ERROR_RETURN,
+ null,
+ null
+ );
+
+ }
+
+ if (MDB::isError($this->db) || PEAR::isError($this->db)) {
+ return PEAR::raiseError($this->db->getMessage(), $this->db->code);
+ }
+
+ if ($this->options['auto_quote']) {
+ if (strpos('.', $this->options['table']) === false) {
+ $this->options['final_table'] = $this->db->quoteIdentifier($this->options['table']);
+ } else {
+ $t = explode('.', $this->options['table']);
+ for ($i = 0, $count = count($t); $i < $count; $i++)
+ $t[$i] = $this->db->quoteIdentifier($t[$i]);
+ $this->options['final_table'] = implode('.', $t);
+ }
+ $this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol']);
+ $this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol']);
+ } else {
+ $this->options['final_table'] = $this->options['table'];
+ $this->options['final_usernamecol'] = $this->options['usernamecol'];
+ $this->options['final_passwordcol'] = $this->options['passwordcol'];
+ }
+
+ return true;
+ }
+
+ // }}}
+ // {{{ _prepare()
+
+ /**
+ * Prepare database connection
+ *
+ * This function checks if we have already opened a connection to
+ * the database. If that's not the case, a new connection is opened.
+ *
+ * @access private
+ * @return mixed True or a MDB error object.
+ */
+ function _prepare()
+ {
+ if (is_subclass_of($this->db, 'mdb_common')) {
+ return true;
+ }
+ return $this->_connect($this->options['dsn']);
+ }
+
+ // }}}
+ // {{{ query()
+
+ /**
+ * Prepare query to the database
+ *
+ * This function checks if we have already opened a connection to
+ * the database. If that's not the case, a new connection is opened.
+ * After that the query is passed to the database.
+ *
+ * @access public
+ * @param string Query string
+ * @return mixed a MDB_result object or MDB_OK on success, a MDB
+ * or PEAR error on failure
+ */
+ function query($query)
+ {
+ $this->log('Auth_Container_MDB::query() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return $err;
+ }
+ return $this->db->query($query);
+ }
+
+ // }}}
+ // {{{ _setDefaults()
+
+ /**
+ * Set some default options
+ *
+ * @access private
+ * @return void
+ */
+ function _setDefaults()
+ {
+ $this->options['table'] = 'auth';
+ $this->options['usernamecol'] = 'username';
+ $this->options['passwordcol'] = 'password';
+ $this->options['dsn'] = '';
+ $this->options['db_fields'] = '';
+ $this->options['cryptType'] = 'md5';
+ $this->options['db_options'] = array();
+ $this->options['db_where'] = '';
+ $this->options['auto_quote'] = true;
+ }
+
+ // }}}
+ // {{{ _parseOptions()
+
+ /**
+ * Parse options passed to the container class
+ *
+ * @access private
+ * @param array
+ */
+ function _parseOptions($array)
+ {
+ foreach ($array as $key => $value) {
+ if (isset($this->options[$key])) {
+ $this->options[$key] = $value;
+ }
+ }
+ }
+
+ // }}}
+ // {{{ _quoteDBFields()
+
+ /**
+ * Quote the db_fields option to avoid the possibility of SQL injection.
+ *
+ * @access private
+ * @return string A properly quoted string that can be concatenated into a
+ * SELECT clause.
+ */
+ function _quoteDBFields()
+ {
+ if (isset($this->options['db_fields'])) {
+ if (is_array($this->options['db_fields'])) {
+ if ($this->options['auto_quote']) {
+ $fields = array();
+ foreach ($this->options['db_fields'] as $field) {
+ $fields[] = $this->db->quoteIdentifier($field);
+ }
+ return implode(', ', $fields);
+ } else {
+ return implode(', ', $this->options['db_fields']);
+ }
+ } else {
+ if (strlen($this->options['db_fields']) > 0) {
+ if ($this->options['auto_quote']) {
+ return $this->db->quoteIdentifier($this->options['db_fields']);
+ } else {
+ return $this->options['db_fields'];
+ }
+ }
+ }
+ }
+
+ return '';
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Get user information from database
+ *
+ * This function uses the given username to fetch
+ * the corresponding login data from the database
+ * table. If an account that matches the passed username
+ * and password is found, the function returns true.
+ * Otherwise it returns false.
+ *
+ * @param string Username
+ * @param string Password
+ * @param boolean If true password is secured using a md5 hash
+ * the frontend and auth are responsible for making sure the container supports
+ * challenge response password authentication
+ * @return mixed Error object or boolean
+ */
+ function fetchData($username, $password, $isChallengeResponse=false)
+ {
+ $this->log('Auth_Container_MDB::fetchData() called.', AUTH_LOG_DEBUG);
+ // Prepare for a database query
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ //Check if db_fields contains a *, if so assume all columns are selected
+ if (is_string($this->options['db_fields'])
+ && strstr($this->options['db_fields'], '*')) {
+ $sql_from = '*';
+ } else {
+ $sql_from = $this->options['final_usernamecol'].
+ ", ".$this->options['final_passwordcol'];
+
+ if (strlen($fields = $this->_quoteDBFields()) > 0) {
+ $sql_from .= ', '.$fields;
+ }
+ }
+
+ $query = sprintf("SELECT %s FROM %s WHERE %s = %s",
+ $sql_from,
+ $this->options['final_table'],
+ $this->options['final_usernamecol'],
+ $this->db->getTextValue($username)
+ );
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $query .= " AND ".$this->options['db_where'];
+ }
+
+ $this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->db->getRow($query, null, null, null, MDB_FETCHMODE_ASSOC);
+
+ if (MDB::isError($res) || PEAR::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->getCode());
+ }
+ if (!is_array($res)) {
+ $this->activeUser = '';
+ return false;
+ }
+
+ // Perform trimming here before the hashing
+ $password = trim($password, "\r\n");
+ $res[$this->options['passwordcol']] = trim($res[$this->options['passwordcol']], "\r\n");
+
+ // If using Challenge Response md5 the pass with the secret
+ if ($isChallengeResponse) {
+ $res[$this->options['passwordcol']] =
+ md5($res[$this->options['passwordcol']].$this->_auth_obj->session['loginchallenege']);
+ // UGLY cannot avoid without modifying verifyPassword
+ if ($this->options['cryptType'] == 'md5') {
+ $res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]);
+ }
+ }
+
+ if ($this->verifyPassword($password,
+ $res[$this->options['passwordcol']],
+ $this->options['cryptType'])) {
+ // Store additional field values in the session
+ foreach ($res as $key => $value) {
+ if ($key == $this->options['passwordcol'] ||
+ $key == $this->options['usernamecol']) {
+ continue;
+ }
+
+ $this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG);
+ // Use reference to the auth object if exists
+ // This is because the auth session variable can change so a static
+ // call to setAuthData does not make sense
+ $this->_auth_obj->setAuthData($key, $value);
+ }
+ return true;
+ }
+
+ $this->activeUser = $res[$this->options['usernamecol']];
+ return false;
+ }
+
+ // }}}
+ // {{{ listUsers()
+
+ /**
+ * Returns a list of users from the container
+ *
+ * @return mixed array|PEAR_Error
+ * @access public
+ */
+ function listUsers()
+ {
+ $this->log('Auth_Container_MDB::listUsers() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ $retVal = array();
+
+ //Check if db_fields contains a *, if so assume all columns are selected
+ if ( is_string($this->options['db_fields'])
+ && strstr($this->options['db_fields'], '*')) {
+ $sql_from = '*';
+ } else {
+ $sql_from = $this->options['final_usernamecol']
+ .', '.$this->options['final_passwordcol'];
+
+ if (strlen($fields = $this->_quoteDBFields()) > 0) {
+ $sql_from .= ', '.$fields;
+ }
+ }
+
+ $query = sprintf('SELECT %s FROM %s',
+ $sql_from,
+ $this->options['final_table']
+ );
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $query .= " WHERE ".$this->options['db_where'];
+ }
+
+ $this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->db->getAll($query, null, null, null, MDB_FETCHMODE_ASSOC);
+
+ if (MDB::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->getCode());
+ } else {
+ foreach ($res as $user) {
+ $user['username'] = $user[$this->options['usernamecol']];
+ $retVal[] = $user;
+ }
+ }
+ $this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG);
+ return $retVal;
+ }
+
+ // }}}
+ // {{{ addUser()
+
+ /**
+ * Add user to the storage container
+ *
+ * @access public
+ * @param string Username
+ * @param string Password
+ * @param mixed Additional information that are stored in the DB
+ *
+ * @return mixed True on success, otherwise error object
+ */
+ function addUser($username, $password, $additional = "")
+ {
+ $this->log('Auth_Container_MDB::addUser() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ if (isset($this->options['cryptType']) && $this->options['cryptType'] == 'none') {
+ $cryptFunction = 'strval';
+ } elseif (isset($this->options['cryptType']) && function_exists($this->options['cryptType'])) {
+ $cryptFunction = $this->options['cryptType'];
+ } else {
+ $cryptFunction = 'md5';
+ }
+
+ $password = $cryptFunction($password);
+
+ $additional_key = '';
+ $additional_value = '';
+
+ if (is_array($additional)) {
+ foreach ($additional as $key => $value) {
+ if ($this->options['auto_quote']) {
+ $additional_key .= ', ' . $this->db->quoteIdentifier($key);
+ } else {
+ $additional_key .= ', ' . $key;
+ }
+ $additional_value .= ', ' . $this->db->getTextValue($value);
+ }
+ }
+
+ $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)",
+ $this->options['final_table'],
+ $this->options['final_usernamecol'],
+ $this->options['final_passwordcol'],
+ $additional_key,
+ $this->db->getTextValue($username),
+ $this->db->getTextValue($password),
+ $additional_value
+ );
+
+ $this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->query($query);
+
+ if (MDB::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->code);
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ removeUser()
+
+ /**
+ * Remove user from the storage container
+ *
+ * @access public
+ * @param string Username
+ *
+ * @return mixed True on success, otherwise error object
+ */
+ function removeUser($username)
+ {
+ $this->log('Auth_Container_MDB::removeUser() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ $query = sprintf("DELETE FROM %s WHERE %s = %s",
+ $this->options['final_table'],
+ $this->options['final_usernamecol'],
+ $this->db->getTextValue($username)
+ );
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $query .= " AND ".$this->options['db_where'];
+ }
+
+ $this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->query($query);
+
+ if (MDB::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->code);
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ changePassword()
+
+ /**
+ * Change password for user in the storage container
+ *
+ * @param string Username
+ * @param string The new password (plain text)
+ */
+ function changePassword($username, $password)
+ {
+ $this->log('Auth_Container_MDB::changePassword() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ if (isset($this->options['cryptType']) && $this->options['cryptType'] == 'none') {
+ $cryptFunction = 'strval';
+ } elseif (isset($this->options['cryptType']) && function_exists($this->options['cryptType'])) {
+ $cryptFunction = $this->options['cryptType'];
+ } else {
+ $cryptFunction = 'md5';
+ }
+
+ $password = $cryptFunction($password);
+
+ $query = sprintf("UPDATE %s SET %s = %s WHERE %s = %s",
+ $this->options['final_table'],
+ $this->options['final_passwordcol'],
+ $this->db->getTextValue($password),
+ $this->options['final_usernamecol'],
+ $this->db->getTextValue($username)
+ );
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $query .= " AND ".$this->options['db_where'];
+ }
+
+ $this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->query($query);
+
+ if (MDB::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->code);
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ supportsChallengeResponse()
+
+ /**
+ * Determine if this container supports
+ * password authentication with challenge response
+ *
+ * @return bool
+ * @access public
+ */
+ function supportsChallengeResponse()
+ {
+ return in_array($this->options['cryptType'], array('md5', 'none', ''));
+ }
+
+ // }}}
+ // {{{ getCryptType()
+
+ /**
+ * Returns the selected crypt type for this container
+ *
+ * @return string Function used to crypt the password
+ */
+ function getCryptType()
+ {
+ return $this->options['cryptType'];
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/MDB2.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/MDB2.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/MDB2.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,624 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against PEAR MDB2
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Lorenzo Alberton <l.alberton at quipo.it>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: MDB2.php,v 1.24 2008/04/04 07:57:02 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.3.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once 'Auth/Container.php';
+/**
+ * Include PEAR MDB2 package
+ */
+require_once 'MDB2.php';
+
+/**
+ * Storage driver for fetching login data from a database
+ *
+ * This storage driver can use all databases which are supported
+ * by the PEAR MDB2 abstraction layer to fetch login data.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Lorenzo Alberton <l.alberton at quipo.it>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.24 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.3.0
+ */
+class Auth_Container_MDB2 extends Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * Additional options for the storage container
+ * @var array
+ */
+ var $options = array();
+
+ /**
+ * MDB object
+ * @var object
+ */
+ var $db = null;
+ var $dsn = '';
+
+ /**
+ * User that is currently selected from the DB.
+ * @var string
+ */
+ var $activeUser = '';
+
+ // }}}
+ // {{{ Auth_Container_MDB2() [constructor]
+
+ /**
+ * Constructor of the container class
+ *
+ * Initate connection to the database via PEAR::MDB2
+ *
+ * @param string Connection data or MDB2 object
+ * @return object Returns an error object if something went wrong
+ */
+ function Auth_Container_MDB2($dsn)
+ {
+ $this->_setDefaults();
+
+ if (is_array($dsn)) {
+ $this->_parseOptions($dsn);
+ if (empty($this->options['dsn'])) {
+ PEAR::raiseError('No connection parameters specified!');
+ }
+ } else {
+ $this->options['dsn'] = $dsn;
+ }
+ }
+
+ // }}}
+ // {{{ _connect()
+
+ /**
+ * Connect to database by using the given DSN string
+ *
+ * @access private
+ * @param mixed DSN string | array | mdb object
+ * @return mixed Object on error, otherwise bool
+ */
+ function _connect($dsn)
+ {
+ $this->log('Auth_Container_MDB2::_connect() called.', AUTH_LOG_DEBUG);
+ if (is_string($dsn) || is_array($dsn)) {
+ $this->db =& MDB2::connect($dsn, $this->options['db_options']);
+ } elseif (is_subclass_of($dsn, 'MDB2_Driver_Common')) {
+ $this->db = $dsn;
+ } elseif (is_object($dsn) && MDB2::isError($dsn)) {
+ return PEAR::raiseError($dsn->getMessage(), $dsn->code);
+ } else {
+ return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
+ 41,
+ PEAR_ERROR_RETURN,
+ null,
+ null
+ );
+
+ }
+
+ if (MDB2::isError($this->db) || PEAR::isError($this->db)) {
+ return PEAR::raiseError($this->db->getMessage(), $this->db->code);
+ }
+
+ if ($this->options['auto_quote']) {
+ if (strpos('.', $this->options['table']) === false) {
+ $this->options['final_table'] = $this->db->quoteIdentifier($this->options['table'], true);
+ } else {
+ $t = explode('.', $this->options['table']);
+ for ($i = 0, $count = count($t); $i < $count; $i++)
+ $t[$i] = $this->db->quoteIdentifier($t[$i], true);
+ $this->options['final_table'] = implode('.', $t);
+ }
+ $this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol'], true);
+ $this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol'], true);
+ } else {
+ $this->options['final_table'] = $this->options['table'];
+ $this->options['final_usernamecol'] = $this->options['usernamecol'];
+ $this->options['final_passwordcol'] = $this->options['passwordcol'];
+ }
+
+ return true;
+ }
+
+ // }}}
+ // {{{ _prepare()
+
+ /**
+ * Prepare database connection
+ *
+ * This function checks if we have already opened a connection to
+ * the database. If that's not the case, a new connection is opened.
+ *
+ * @access private
+ * @return mixed True or a MDB error object.
+ */
+ function _prepare()
+ {
+ if (is_subclass_of($this->db, 'MDB2_Driver_Common')) {
+ return true;
+ }
+ return $this->_connect($this->options['dsn']);
+ }
+
+ // }}}
+ // {{{ query()
+
+ /**
+ * Prepare query to the database
+ *
+ * This function checks if we have already opened a connection to
+ * the database. If that's not the case, a new connection is opened.
+ * After that the query is passed to the database.
+ *
+ * @access public
+ * @param string Query string
+ * @return mixed a MDB_result object or MDB_OK on success, a MDB
+ * or PEAR error on failure
+ */
+ function query($query)
+ {
+ $this->log('Auth_Container_MDB2::query() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return $err;
+ }
+ return $this->db->exec($query);
+ }
+
+ // }}}
+ // {{{ _setDefaults()
+
+ /**
+ * Set some default options
+ *
+ * @access private
+ * @return void
+ */
+ function _setDefaults()
+ {
+ $this->options['table'] = 'auth';
+ $this->options['usernamecol'] = 'username';
+ $this->options['passwordcol'] = 'password';
+ $this->options['dsn'] = '';
+ $this->options['db_fields'] = '';
+ $this->options['cryptType'] = 'md5';
+ $this->options['db_options'] = array();
+ $this->options['db_where'] = '';
+ $this->options['auto_quote'] = true;
+ }
+
+ // }}}
+ // {{{ _parseOptions()
+
+ /**
+ * Parse options passed to the container class
+ *
+ * @access private
+ * @param array
+ */
+ function _parseOptions($array)
+ {
+ foreach ($array as $key => $value) {
+ if (isset($this->options[$key])) {
+ $this->options[$key] = $value;
+ }
+ }
+ }
+
+ // }}}
+ // {{{ _quoteDBFields()
+
+ /**
+ * Quote the db_fields option to avoid the possibility of SQL injection.
+ *
+ * @access private
+ * @return string A properly quoted string that can be concatenated into a
+ * SELECT clause.
+ */
+ function _quoteDBFields()
+ {
+ if (isset($this->options['db_fields'])) {
+ if (is_array($this->options['db_fields'])) {
+ if ($this->options['auto_quote']) {
+ $fields = array();
+ foreach ($this->options['db_fields'] as $field) {
+ $fields[] = $this->db->quoteIdentifier($field, true);
+ }
+ return implode(', ', $fields);
+ } else {
+ return implode(', ', $this->options['db_fields']);
+ }
+ } else {
+ if (strlen($this->options['db_fields']) > 0) {
+ if ($this->options['auto_quote']) {
+ return $this->db->quoteIdentifier($this->options['db_fields'], true);
+ } else {
+ return $this->options['db_fields'];
+ }
+ }
+ }
+ }
+
+ return '';
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Get user information from database
+ *
+ * This function uses the given username to fetch
+ * the corresponding login data from the database
+ * table. If an account that matches the passed username
+ * and password is found, the function returns true.
+ * Otherwise it returns false.
+ *
+ * @param string Username
+ * @param string Password
+ * @param boolean If true password is secured using a md5 hash
+ * the frontend and auth are responsible for making sure the container supports
+ * challenge response password authentication
+ * @return mixed Error object or boolean
+ */
+ function fetchData($username, $password, $isChallengeResponse=false)
+ {
+ $this->log('Auth_Container_MDB2::fetchData() called.', AUTH_LOG_DEBUG);
+ // Prepare for a database query
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ //Check if db_fields contains a *, if so assume all columns are selected
+ if (is_string($this->options['db_fields'])
+ && strstr($this->options['db_fields'], '*')) {
+ $sql_from = '*';
+ } else {
+ $sql_from = $this->options['final_usernamecol'].
+ ", ".$this->options['final_passwordcol'];
+
+ if (strlen($fields = $this->_quoteDBFields()) > 0) {
+ $sql_from .= ', '.$fields;
+ }
+ }
+ $query = sprintf("SELECT %s FROM %s WHERE %s = %s",
+ $sql_from,
+ $this->options['final_table'],
+ $this->options['final_usernamecol'],
+ $this->db->quote($username, 'text')
+ );
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $query .= " AND ".$this->options['db_where'];
+ }
+
+ $this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->db->queryRow($query, null, MDB2_FETCHMODE_ASSOC);
+ if (MDB2::isError($res) || PEAR::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->getCode());
+ }
+ if (!is_array($res)) {
+ $this->activeUser = '';
+ return false;
+ }
+
+ // Perform trimming here before the hashing
+ $password = trim($password, "\r\n");
+ $res[$this->options['passwordcol']] = trim($res[$this->options['passwordcol']], "\r\n");
+ // If using Challenge Response md5 the pass with the secret
+ if ($isChallengeResponse) {
+ $res[$this->options['passwordcol']] =
+ md5($res[$this->options['passwordcol']].$this->_auth_obj->session['loginchallenege']);
+ // UGLY cannot avoid without modifying verifyPassword
+ if ($this->options['cryptType'] == 'md5') {
+ $res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]);
+ }
+ }
+ if ($this->verifyPassword($password,
+ $res[$this->options['passwordcol']],
+ $this->options['cryptType'])) {
+ // Store additional field values in the session
+ foreach ($res as $key => $value) {
+ if ($key == $this->options['passwordcol'] ||
+ $key == $this->options['usernamecol']) {
+ continue;
+ }
+
+ $this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG);
+
+ // Use reference to the auth object if exists
+ // This is because the auth session variable can change so a static call to setAuthData does not make sense
+ $this->_auth_obj->setAuthData($key, $value);
+ }
+ return true;
+ }
+
+ $this->activeUser = $res[$this->options['usernamecol']];
+ return false;
+ }
+
+ // }}}
+ // {{{ listUsers()
+
+ /**
+ * Returns a list of users from the container
+ *
+ * @return mixed array|PEAR_Error
+ * @access public
+ */
+ function listUsers()
+ {
+ $this->log('Auth_Container_MDB2::listUsers() called.', AUTH_LOG_DEBUG);
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ $retVal = array();
+
+ //Check if db_fields contains a *, if so assume all columns are selected
+ if ( is_string($this->options['db_fields'])
+ && strstr($this->options['db_fields'], '*')) {
+ $sql_from = '*';
+ } else {
+ $sql_from = $this->options['final_usernamecol'].
+ ", ".$this->options['final_passwordcol'];
+
+ if (strlen($fields = $this->_quoteDBFields()) > 0) {
+ $sql_from .= ', '.$fields;
+ }
+ }
+
+ $query = sprintf('SELECT %s FROM %s',
+ $sql_from,
+ $this->options['final_table']
+ );
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $query .= " WHERE ".$this->options['db_where'];
+ }
+
+ $this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
+ if (MDB2::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->getCode());
+ } else {
+ foreach ($res as $user) {
+ $user['username'] = $user[$this->options['usernamecol']];
+ $retVal[] = $user;
+ }
+ }
+ $this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG);
+ return $retVal;
+ }
+
+ // }}}
+ // {{{ addUser()
+
+ /**
+ * Add user to the storage container
+ *
+ * @access public
+ * @param string Username
+ * @param string Password
+ * @param mixed Additional information that are stored in the DB
+ *
+ * @return mixed True on success, otherwise error object
+ */
+ function addUser($username, $password, $additional = "")
+ {
+ $this->log('Auth_Container_MDB2::addUser() called.', AUTH_LOG_DEBUG);
+
+ // Prepare for a database query
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ if (isset($this->options['cryptType']) && $this->options['cryptType'] == 'none') {
+ $cryptFunction = 'strval';
+ } elseif (isset($this->options['cryptType']) && function_exists($this->options['cryptType'])) {
+ $cryptFunction = $this->options['cryptType'];
+ } else {
+ $cryptFunction = 'md5';
+ }
+
+ $password = $cryptFunction($password);
+
+ $additional_key = '';
+ $additional_value = '';
+
+ if (is_array($additional)) {
+ foreach ($additional as $key => $value) {
+ if ($this->options['auto_quote']) {
+ $additional_key .= ', ' . $this->db->quoteIdentifier($key, true);
+ } else {
+ $additional_key .= ', ' . $key;
+ }
+ $additional_value .= ', ' . $this->db->quote($value, 'text');
+ }
+ }
+
+ $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)",
+ $this->options['final_table'],
+ $this->options['final_usernamecol'],
+ $this->options['final_passwordcol'],
+ $additional_key,
+ $this->db->quote($username, 'text'),
+ $this->db->quote($password, 'text'),
+ $additional_value
+ );
+
+ $this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->query($query);
+
+ if (MDB2::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->code);
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ removeUser()
+
+ /**
+ * Remove user from the storage container
+ *
+ * @access public
+ * @param string Username
+ *
+ * @return mixed True on success, otherwise error object
+ */
+ function removeUser($username)
+ {
+ $this->log('Auth_Container_MDB2::removeUser() called.', AUTH_LOG_DEBUG);
+ // Prepare for a database query
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ $query = sprintf("DELETE FROM %s WHERE %s = %s",
+ $this->options['final_table'],
+ $this->options['final_usernamecol'],
+ $this->db->quote($username, 'text')
+ );
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $query .= " AND ".$this->options['db_where'];
+ }
+
+ $this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->query($query);
+
+ if (MDB2::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->code);
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ changePassword()
+
+ /**
+ * Change password for user in the storage container
+ *
+ * @param string Username
+ * @param string The new password (plain text)
+ */
+ function changePassword($username, $password)
+ {
+ $this->log('Auth_Container_MDB2::changePassword() called.', AUTH_LOG_DEBUG);
+ // Prepare for a database query
+ $err = $this->_prepare();
+ if ($err !== true) {
+ return PEAR::raiseError($err->getMessage(), $err->getCode());
+ }
+
+ if (isset($this->options['cryptType']) && $this->options['cryptType'] == 'none') {
+ $cryptFunction = 'strval';
+ } elseif (isset($this->options['cryptType']) && function_exists($this->options['cryptType'])) {
+ $cryptFunction = $this->options['cryptType'];
+ } else {
+ $cryptFunction = 'md5';
+ }
+
+ $password = $cryptFunction($password);
+
+ $query = sprintf("UPDATE %s SET %s = %s WHERE %s = %s",
+ $this->options['final_table'],
+ $this->options['final_passwordcol'],
+ $this->db->quote($password, 'text'),
+ $this->options['final_usernamecol'],
+ $this->db->quote($username, 'text')
+ );
+
+ // check if there is an optional parameter db_where
+ if ($this->options['db_where'] != '') {
+ // there is one, so add it to the query
+ $query .= " AND ".$this->options['db_where'];
+ }
+
+ $this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG);
+
+ $res = $this->query($query);
+
+ if (MDB2::isError($res)) {
+ return PEAR::raiseError($res->getMessage(), $res->code);
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ supportsChallengeResponse()
+
+ /**
+ * Determine if this container supports
+ * password authentication with challenge response
+ *
+ * @return bool
+ * @access public
+ */
+ function supportsChallengeResponse()
+ {
+ return in_array($this->options['cryptType'], array('md5', 'none', ''));
+ }
+
+ // }}}
+ // {{{ getCryptType()
+
+ /**
+ * Returns the selected crypt type for this container
+ *
+ * @return string Function used to crypt the password
+ */
+ function getCryptType()
+ {
+ return $this->options['cryptType'];
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/Multiple.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/Multiple.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/Multiple.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,188 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for using multiple storage drivers in a fall through fashion
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: Multiple.php,v 1.4 2007/06/12 03:11:26 aashley Exp $
+ * @since File available since Release 1.5.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once "Auth/Container.php";
+/**
+ * Include PEAR package for error handling
+ */
+require_once "PEAR.php";
+
+/**
+ * Storage driver for using multiple storage drivers in a fall through fashion
+ *
+ * This storage driver provides a mechanism for working through multiple
+ * storage drivers until either one allows successful login or the list is
+ * exhausted.
+ *
+ * This container takes an array of options of the following form:
+ *
+ * array(
+ * array(
+ * 'type' => <standard container type name>,
+ * 'options' => <normal array of options for container>,
+ * ),
+ * );
+ *
+ * Full example:
+ *
+ * $options = array(
+ * array(
+ * 'type' => 'DB',
+ * 'options' => array(
+ * 'dsn' => "mysql://user:password@localhost/database",
+ * ),
+ * ),
+ * array(
+ * 'type' => 'Array',
+ * 'options' => array(
+ * 'cryptType' => 'md5',
+ * 'users' => array(
+ * 'admin' => md5('password'),
+ * ),
+ * ),
+ * ),
+ * );
+ *
+ * $auth = new Auth('Multiple', $options);
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.4 $
+ * @since File available since Release 1.5.0
+ */
+
+class Auth_Container_Multiple extends Auth_Container {
+
+ // {{{ properties
+
+ /**
+ * The options for each container
+ *
+ * @var array $options
+ */
+ var $options = array();
+
+ /**
+ * The instanciated containers
+ *
+ * @var array $containers
+ */
+ var $containers = array();
+
+ // }}}
+ // {{{ Auth_Container_Multiple()
+
+ /**
+ * Constructor for Array Container
+ *
+ * @param array $data Options for the container
+ * @return void
+ */
+ function Auth_Container_Multiple($options)
+ {
+ if (!is_array($options)) {
+ PEAR::raiseError('The options for Auth_Container_Multiple must be an array');
+ }
+ if (count($options) < 1) {
+ PEAR::raiseError('You must define at least one sub container to use in Auth_Container_Multiple');
+ }
+ foreach ($options as $option) {
+ if (!isset($option['type'])) {
+ PEAR::raiseError('No type defined for sub container');
+ }
+ }
+ $this->options = $options;
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Get user information from array
+ *
+ * This function uses the given username to fetch the corresponding
+ * login data from the array. If an account that matches the passed
+ * username and password is found, the function returns true.
+ * Otherwise it returns false.
+ *
+ * @param string Username
+ * @param string Password
+ * @return boolean|PEAR_Error Error object or boolean
+ */
+ function fetchData($user, $pass)
+ {
+ $this->log('Auth_Container_Multiple::fetchData() called.', AUTH_LOG_DEBUG);
+
+ foreach ($this->options as $key => $options) {
+
+ $this->log('Using Container '.$key.' of type '.$options['type'].'.', AUTH_LOG_DEBUG);
+
+ if (isset($this->containers[$key]) && is_a($this->containers[$key], 'Auth_Container')) {
+
+ $container = &$this->containers[$key];
+
+ } else {
+
+ $this->containers[$key] = &$this->_auth_obj->_factory($options['type'], $options['options']);
+ $this->containers[$key]->_auth_obj = &$this->_auth_obj;
+ $container = &$this->containers[$key];
+
+ }
+
+ $result = $container->fetchData($user, $pass);
+
+ if (PEAR::isError($result)) {
+
+ $this->log('Container '.$key.': '.$result->getMessage(), AUTH_LOG_ERR);
+ return $result;
+
+ } elseif ($result == true) {
+
+ $this->log('Container '.$key.': Authentication successful.', AUTH_LOG_DEBUG);
+ return true;
+
+ } else {
+
+ $this->log('Container '.$key.': Authentication failed.', AUTH_LOG_DEBUG);
+
+ }
+
+ }
+
+ $this->log('Auth_Container_Multiple: All containers rejected user credentials.', AUTH_LOG_DEBUG);
+
+ return false;
+
+ }
+
+ // }}}
+
+}
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/NetVPOPMaild.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/NetVPOPMaild.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/NetVPOPMaild.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,129 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use with a Vpopmaild server
+ *
+ * PHP versions 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Bill Shupp <hostmaster at shupp.org>
+ * @author Stefan Ekman <stekman at sedata.org>
+ * @author Martin Jansen <mj at php.net>
+ * @author Mika Tuupola <tuupola at appelsiini.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.2.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once 'Auth/Container.php';
+/**
+ * Include PEAR package for error handling
+ */
+require_once 'PEAR.php';
+/**
+ * Include PEAR Net_Vpopmaild package
+ */
+require_once 'Net/Vpopmaild.php';
+
+/**
+ * Storage driver for Authentication on a Vpopmaild server.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Martin Jansen <mj at php.net>
+ * @author Mika Tuupola <tuupola at appelsiini.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.5.4 File: $Revision: 1.1 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.6.0
+ */
+class Auth_Container_Vpopmaild extends Auth_Container
+{
+
+ /**
+ * Vpopmaild Server
+ * @var string
+ */
+ var $server = 'localhost';
+
+ /**
+ * Vpopmaild Server port
+ * @var string
+ */
+ var $port = 89;
+
+ /**
+ * Constructor of the container class
+ *
+ * @param $server string server or server:port combination
+ * @return object Returns an error object if something went wrong
+ */
+ function Auth_Container_Vpopmaild($server=null)
+ {
+ if (isset($server) && !is_null($server)) {
+ if (is_array($server)) {
+ if (isset($server['host'])) {
+ $this->server = $server['host'];
+ }
+ if (isset($server['port'])) {
+ $this->port = $server['port'];
+ }
+ } else {
+ if (strstr($server, ':')) {
+ $serverparts = explode(':', trim($server));
+ $this->server = $serverparts[0];
+ $this->port = $serverparts[1];
+ } else {
+ $this->server = $server;
+ }
+ }
+ }
+ }
+
+ /**
+ * fetchData()
+ *
+ * Try to login to the Vpopmaild server
+ *
+ * @param string username
+ * @param string password
+ *
+ * @return boolean
+ */
+ function fetchData($username, $password)
+ {
+ $this->log('Auth_Container_Vpopmaild::fetchData() called.', AUTH_LOG_DEBUG);
+ $vpopmaild =& new Net_Vpopmaild();
+ // Connect
+ try {
+ $res = $vpopmaild->connect($this->server, $this->port, $this->method);
+ } catch (Net_Vpopmaild_FatalException $e) {
+ $this->log('Connection to Vpopmaild server failed.', AUTH_LOG_DEBUG);
+ return PEAR::raiseError($e->getMessage(), $e->getCode());
+ }
+ // Authenticate
+ try {
+ $result = $vpopmaild->clogin($username, $password);
+ $vpopmaild->quit();
+ } catch (Net_Vpopmaild_Exception $e) {
+ return PEAR::raiseError($e->getMessage(), $e->getCode());
+ }
+ return $result;
+ }
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/PEAR.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/PEAR.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/PEAR.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,159 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against PEAR website
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Yavor Shahpasov <yavo at netsmart.com.cy>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: PEAR.php,v 1.13 2008/04/04 00:53:53 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.3.0
+ */
+
+/**
+ * Include PEAR HTTP_Client.
+ */
+require_once 'HTTP/Client.php';
+/**
+ * Include Auth_Container base class
+ */
+require_once 'Auth/Container.php';
+
+/**
+ * Storage driver for authenticating against PEAR website
+ *
+ * This driver provides a method for authenticating against the pear.php.net
+ * authentication system.
+ *
+ * Supports two options:
+ * - "url": The base URL with schema to authenticate against
+ * - "karma": An array of karma levels which the user needs one of.
+ * When empty, no karma level is required.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Yavor Shahpasov <yavo at netsmart.com.cy>
+ * @author Adam Ashley <aashley at php.net>
+ * @author Adam Harvey <aharvey at php.net>
+ * @copyright 2001-2007 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.13 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.3.0
+ */
+class Auth_Container_Pear extends Auth_Container
+{
+ // {{{ properties
+
+ /**
+ * URL to connect to, with schema
+ *
+ * @var string
+ */
+ var $url = 'https://pear.php.net/rest-login.php/';
+
+ /**
+ * Array of karma levels the user can have.
+ * A user needs only one of the levels to succeed login.
+ * No levels mean that only username and password need to match
+ *
+ * @var array
+ */
+ var $karma = array();
+
+ // }}}
+ // {{{ Auth_Container_Pear() [constructor]
+
+ /**
+ * Constructor
+ *
+ * Accepts options "url" and "karma", see class docs.
+ *
+ * @param array $data Array of options
+ *
+ * @return void
+ */
+ function Auth_Container_Pear($data = null)
+ {
+ if (!is_array($data)) {
+ PEAR::raiseError('The options for Auth_Container_Pear must be an array');
+ }
+ if (isset($data['karma'])) {
+ if (is_array($data['karma'])) {
+ $this->karma = $data['karma'];
+ } else {
+ $this->karma = array($data['karma']);
+ }
+ }
+
+ if (isset($data['url'])) {
+ $this->url = $data['url'];
+ }
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Get user information from pear.php.net
+ *
+ * This function uses the given username and password to authenticate
+ * against the pear.php.net website
+ *
+ * @param string Username
+ * @param string Password
+ * @return mixed Error object or boolean
+ */
+ function fetchData($username, $password)
+ {
+ $this->log('Auth_Container_PEAR::fetchData() called.', AUTH_LOG_DEBUG);
+
+ $client = new HTTP_Client;
+
+ $this->log('Auth_Container_PEAR::fetchData() getting salt.', AUTH_LOG_DEBUG);
+ $code = $client->get($this->url . '/getsalt');
+ if ($code != 200) {
+ return PEAR::raiseError('Bad response to salt request.', $code);
+ }
+ $resp = $client->currentResponse();
+ $salt = $resp['body'];
+
+ $this->log('Auth_Container_PEAR::fetchData() calling validate.', AUTH_LOG_DEBUG);
+ $postOptions = array(
+ 'username' => $username,
+ 'password' => md5($salt . md5($password))
+ );
+ if (is_array($this->karma) && count($this->karma) > 0) {
+ $postOptions['karma'] = implode(',', $this->karma);
+ }
+
+ $code = $client->post($this->url . '/validate', $postOptions);
+ if ($code != 200) {
+ return PEAR::raiseError('Bad response to validate request.', $code);
+ }
+ $resp = $client->currentResponse();
+
+ list($code, $message) = explode(' ', $resp['body'], 1);
+ if ($code != 8) {
+ return PEAR::raiseError($message, $code);
+ }
+ return true;
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/POP3.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/POP3.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/POP3.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,145 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against a POP3 server
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Stefan Ekman <stekman at sedata.org>
+ * @author Martin Jansen <mj at php.net>
+ * @author Mika Tuupola <tuupola at appelsiini.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: POP3.php,v 1.12 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.2.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once 'Auth/Container.php';
+/**
+ * Include PEAR package for error handling
+ */
+require_once 'PEAR.php';
+/**
+ * Include PEAR Net_POP3 package
+ */
+require_once 'Net/POP3.php';
+
+/**
+ * Storage driver for Authentication on a POP3 server.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Martin Jansen <mj at php.net>
+ * @author Mika Tuupola <tuupola at appelsiini.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.12 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.2.0
+ */
+class Auth_Container_POP3 extends Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * POP3 Server
+ * @var string
+ */
+ var $server='localhost';
+
+ /**
+ * POP3 Server port
+ * @var string
+ */
+ var $port='110';
+
+ /**
+ * POP3 Authentication method
+ *
+ * Prefered POP3 authentication method. Acceptable values:
+ * Boolean TRUE - Use Net_POP3's autodetection
+ * String 'DIGEST-MD5','CRAM-MD5','LOGIN','PLAIN','APOP','USER'
+ * - Attempt this authentication style first
+ * then fallback to autodetection.
+ * @var mixed
+ */
+ var $method=true;
+
+ // }}}
+ // {{{ Auth_Container_POP3() [constructor]
+
+ /**
+ * Constructor of the container class
+ *
+ * @param $server string server or server:port combination
+ * @return object Returns an error object if something went wrong
+ */
+ function Auth_Container_POP3($server=null)
+ {
+ if (isset($server) && !is_null($server)) {
+ if (is_array($server)) {
+ if (isset($server['host'])) {
+ $this->server = $server['host'];
+ }
+ if (isset($server['port'])) {
+ $this->port = $server['port'];
+ }
+ if (isset($server['method'])) {
+ $this->method = $server['method'];
+ }
+ } else {
+ if (strstr($server, ':')) {
+ $serverparts = explode(':', trim($server));
+ $this->server = $serverparts[0];
+ $this->port = $serverparts[1];
+ } else {
+ $this->server = $server;
+ }
+ }
+ }
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Try to login to the POP3 server
+ *
+ * @param string Username
+ * @param string Password
+ * @return boolean
+ */
+ function fetchData($username, $password)
+ {
+ $this->log('Auth_Container_POP3::fetchData() called.', AUTH_LOG_DEBUG);
+ $pop3 =& new Net_POP3();
+ $res = $pop3->connect($this->server, $this->port, $this->method);
+ if (!$res) {
+ $this->log('Connection to POP3 server failed.', AUTH_LOG_DEBUG);
+ return $res;
+ }
+ $result = $pop3->login($username, $password);
+ $pop3->disconnect();
+ return $result;
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/RADIUS.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/RADIUS.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/RADIUS.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,182 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against RADIUS servers
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Michael Bretterklieber <michael at bretterklieber.com>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: RADIUS.php,v 1.16 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.2.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once "Auth/Container.php";
+/**
+ * Include PEAR Auth_RADIUS package
+ */
+require_once "Auth/RADIUS.php";
+
+/**
+ * Storage driver for authenticating users against RADIUS servers.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Michael Bretterklieber <michael at bretterklieber.com>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.16 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.2.0
+ */
+class Auth_Container_RADIUS extends Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * Contains a RADIUS object
+ * @var object
+ */
+ var $radius;
+
+ /**
+ * Contains the authentication type
+ * @var string
+ */
+ var $authtype;
+
+ // }}}
+ // {{{ Auth_Container_RADIUS() [constructor]
+
+ /**
+ * Constructor of the container class.
+ *
+ * $options can have these keys:
+ * 'servers' an array containing an array: servername, port,
+ * sharedsecret, timeout, maxtries
+ * 'configfile' The filename of the configuration file
+ * 'authtype' The type of authentication, one of: PAP, CHAP_MD5,
+ * MSCHAPv1, MSCHAPv2, default is PAP
+ *
+ * @param $options associative array
+ * @return object Returns an error object if something went wrong
+ */
+ function Auth_Container_RADIUS($options)
+ {
+ $this->authtype = 'PAP';
+ if (isset($options['authtype'])) {
+ $this->authtype = $options['authtype'];
+ }
+ $classname = 'Auth_RADIUS_' . $this->authtype;
+ if (!class_exists($classname)) {
+ PEAR::raiseError("Unknown Authtype, please use one of: "
+ ."PAP, CHAP_MD5, MSCHAPv1, MSCHAPv2!", 41, PEAR_ERROR_DIE);
+ }
+
+ $this->radius = new $classname;
+
+ if (isset($options['configfile'])) {
+ $this->radius->setConfigfile($options['configfile']);
+ }
+
+ $servers = $options['servers'];
+ if (is_array($servers)) {
+ foreach ($servers as $server) {
+ $servername = $server[0];
+ $port = isset($server[1]) ? $server[1] : 0;
+ $sharedsecret = isset($server[2]) ? $server[2] : 'testing123';
+ $timeout = isset($server[3]) ? $server[3] : 3;
+ $maxtries = isset($server[4]) ? $server[4] : 3;
+ $this->radius->addServer($servername, $port, $sharedsecret, $timeout, $maxtries);
+ }
+ }
+
+ if (!$this->radius->start()) {
+ PEAR::raiseError($this->radius->getError(), 41, PEAR_ERROR_DIE);
+ }
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Authenticate
+ *
+ * @param string Username
+ * @param string Password
+ * @return bool true on success, false on reject
+ */
+ function fetchData($username, $password, $challenge = null)
+ {
+ $this->log('Auth_Container_RADIUS::fetchData() called.', AUTH_LOG_DEBUG);
+
+ switch($this->authtype) {
+ case 'CHAP_MD5':
+ case 'MSCHAPv1':
+ if (isset($challenge)) {
+ $this->radius->challenge = $challenge;
+ $this->radius->chapid = 1;
+ $this->radius->response = pack('H*', $password);
+ } else {
+ require_once 'Crypt/CHAP.php';
+ $classname = 'Crypt_' . $this->authtype;
+ $crpt = new $classname;
+ $crpt->password = $password;
+ $this->radius->challenge = $crpt->challenge;
+ $this->radius->chapid = $crpt->chapid;
+ $this->radius->response = $crpt->challengeResponse();
+ }
+ break;
+
+ case 'MSCHAPv2':
+ require_once 'Crypt/CHAP.php';
+ $crpt = new Crypt_MSCHAPv2;
+ $crpt->username = $username;
+ $crpt->password = $password;
+ $this->radius->challenge = $crpt->authChallenge;
+ $this->radius->peerChallenge = $crpt->peerChallenge;
+ $this->radius->chapid = $crpt->chapid;
+ $this->radius->response = $crpt->challengeResponse();
+ break;
+
+ default:
+ $this->radius->password = $password;
+ break;
+ }
+
+ $this->radius->username = $username;
+
+ $this->radius->putAuthAttributes();
+ $result = $this->radius->send();
+ if (PEAR::isError($result)) {
+ return false;
+ }
+
+ $this->radius->getAttributes();
+// just for debugging
+// $this->radius->dumpAttributes();
+
+ return $result;
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SAP.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SAP.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SAP.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,179 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against a SAP system using the SAPRFC PHP extension.
+ *
+ * Requires the SAPRFC ext available at http://saprfc.sourceforge.net/
+ *
+ * PHP version 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Stoyan Stefanov <ssttoo at gmail.com>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: SAP.php,v 1.5 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.4.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once 'Auth/Container.php';
+/**
+ * Include PEAR for error handling
+ */
+require_once 'PEAR.php';
+
+/**
+ * Performs authentication against a SAP system using the SAPRFC PHP extension.
+ *
+ * When the option GETSSO2 is TRUE (default)
+ * the Single Sign-On (SSO) ticket is retrieved
+ * and stored as an Auth attribute called 'sap'
+ * in order to be reused for consecutive connections.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Stoyan Stefanov <ssttoo at gmail.com>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.5 $
+ * @since Class available since Release 1.4.0
+ */
+class Auth_Container_SAP extends Auth_Container {
+
+ // {{{ properties
+
+ /**
+ * @var array Default options
+ */
+ var $options = array(
+ 'CLIENT' => '000',
+ 'LANG' => 'EN',
+ 'GETSSO2' => true,
+ );
+
+ // }}}
+ // {{{ Auth_Container_SAP()
+
+ /**
+ * Class constructor. Checks that required options
+ * are present and that the SAPRFC extension is loaded
+ *
+ * Options that can be passed and their defaults:
+ * <pre>
+ * array(
+ * 'ASHOST' => "",
+ * 'SYSNR' => "",
+ * 'CLIENT' => "000",
+ * 'GWHOST' =>"",
+ * 'GWSERV' =>"",
+ * 'MSHOST' =>"",
+ * 'R3NAME' =>"",
+ * 'GROUP' =>"",
+ * 'LANG' =>"EN",
+ * 'TRACE' =>"",
+ * 'GETSSO2'=> true
+ * )
+ * </pre>
+ *
+ * @param array array of options.
+ * @return void
+ */
+ function Auth_Container_SAP($options)
+ {
+ $saprfc_loaded = PEAR::loadExtension('saprfc');
+ if (!$saprfc_loaded) {
+ return PEAR::raiseError('Cannot use SAP authentication, '
+ .'SAPRFC extension not loaded!');
+ }
+ if (empty($options['R3NAME']) && empty($options['ASHOST'])) {
+ return PEAR::raiseError('R3NAME or ASHOST required for authentication');
+ }
+ $this->options = array_merge($this->options, $options);
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Performs username and password check
+ *
+ * @param string Username
+ * @param string Password
+ * @return boolean TRUE on success (valid user), FALSE otherwise
+ */
+ function fetchData($username, $password)
+ {
+ $this->log('Auth_Container_SAP::fetchData() called.', AUTH_LOG_DEBUG);
+ $connection_options = $this->options;
+ $connection_options['USER'] = $username;
+ $connection_options['PASSWD'] = $password;
+ $rfc = saprfc_open($connection_options);
+ if (!$rfc) {
+ $message = "Couldn't connect to the SAP system.";
+ $error = $this->getError();
+ if ($error['message']) {
+ $message .= ': ' . $error['message'];
+ }
+ PEAR::raiseError($message, null, null, null, @$erorr['all']);
+ return false;
+ } else {
+ if (!empty($this->options['GETSSO2'])) {
+ $this->log('Attempting to retrieve SSO2 ticket.', AUTH_LOG_DEBUG);
+ if ($ticket = @saprfc_get_ticket($rfc)) {
+ $this->options['MYSAPSSO2'] = $ticket;
+ unset($this->options['GETSSO2']);
+ $this->_auth_obj->setAuthData('sap', $this->options);
+ } else {
+ PEAR::raiseError("SSO ticket retrieval failed");
+ }
+ }
+ @saprfc_close($rfc);
+ return true;
+ }
+
+ }
+
+ // }}}
+ // {{{ getError()
+
+ /**
+ * Retrieves the last error from the SAP connection
+ * and returns it as an array.
+ *
+ * @return array Array of error information
+ */
+ function getError()
+ {
+
+ $error = array();
+ $sap_error = saprfc_error();
+ if (empty($err)) {
+ return $error;
+ }
+ $err = explode("n", $sap_error);
+ foreach ($err AS $line) {
+ $item = split(':', $line);
+ $error[strtolower(trim($item[0]))] = trim($item[1]);
+ }
+ $error['all'] = $sap_error;
+ return $error;
+ }
+
+ // }}}
+
+}
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SMBPasswd.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SMBPasswd.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SMBPasswd.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,182 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against Samba password files
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Michael Bretterklieber <michael at bretterklieber.com>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: SMBPasswd.php,v 1.8 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.2.3
+ */
+
+/**
+ * Include PEAR File_SMBPasswd
+ */
+require_once "File/SMBPasswd.php";
+/**
+ * Include Auth_Container Base file
+ */
+require_once "Auth/Container.php";
+/**
+ * Include PEAR class for error handling
+ */
+require_once "PEAR.php";
+
+/**
+ * Storage driver for fetching login data from an SAMBA smbpasswd file.
+ *
+ * This storage container can handle SAMBA smbpasswd files.
+ *
+ * Example:
+ * $a = new Auth("SMBPasswd", '/usr/local/private/smbpasswd');
+ * $a->start();
+ * if ($a->getAuth()) {
+ * printf ("AUTH OK<br>\n");
+ * $a->logout();
+ * }
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Michael Bretterklieber <michael at bretterklieber.com>
+ * @author Adam Ashley <aashley at php.net>
+ * @package Auth
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.8 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.2.3
+ */
+class Auth_Container_SMBPasswd extends Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * File_SMBPasswd object
+ * @var object
+ */
+ var $pwfile;
+
+ // }}}
+
+ // {{{ Auth_Container_SMBPasswd() [constructor]
+
+ /**
+ * Constructor of the container class
+ *
+ * @param $filename string filename for a passwd type file
+ * @return object Returns an error object if something went wrong
+ */
+ function Auth_Container_SMBPasswd($filename)
+ {
+ $this->pwfile = new File_SMBPasswd($filename,0);
+
+ if (!$this->pwfile->load()) {
+ PEAR::raiseError("Error while reading file contents.", 41, PEAR_ERROR_DIE);
+ return;
+ }
+
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Get user information from pwfile
+ *
+ * @param string Username
+ * @param string Password
+ * @return boolean
+ */
+ function fetchData($username, $password)
+ {
+ $this->log('Auth_Container_SMBPasswd::fetchData() called.', AUTH_LOG_DEBUG);
+ return $this->pwfile->verifyAccount($username, $password);
+ }
+
+ // }}}
+ // {{{ listUsers()
+
+ function listUsers()
+ {
+ $this->log('Auth_Container_SMBPasswd::fetchData() called.', AUTH_LOG_DEBUG);
+ return $this->pwfile->getAccounts();
+ }
+
+ // }}}
+ // {{{ addUser()
+
+ /**
+ * Add a new user to the storage container
+ *
+ * @param string Username
+ * @param string Password
+ * @param array Additional information
+ *
+ * @return boolean
+ */
+ function addUser($username, $password, $additional = '')
+ {
+ $this->log('Auth_Container_SMBPasswd::addUser() called.', AUTH_LOG_DEBUG);
+ $res = $this->pwfile->addUser($user, $additional['userid'], $pass);
+ if ($res === true) {
+ return $this->pwfile->save();
+ }
+ return $res;
+ }
+
+ // }}}
+ // {{{ removeUser()
+
+ /**
+ * Remove user from the storage container
+ *
+ * @param string Username
+ */
+ function removeUser($username)
+ {
+ $this->log('Auth_Container_SMBPasswd::removeUser() called.', AUTH_LOG_DEBUG);
+ $res = $this->pwfile->delUser($username);
+ if ($res === true) {
+ return $this->pwfile->save();
+ }
+ return $res;
+ }
+
+ // }}}
+ // {{{ changePassword()
+
+ /**
+ * Change password for user in the storage container
+ *
+ * @param string Username
+ * @param string The new password
+ */
+ function changePassword($username, $password)
+ {
+ $this->log('Auth_Container_SMBPasswd::changePassword() called.', AUTH_LOG_DEBUG);
+ $res = $this->pwfile->modUser($username, '', $password);
+ if ($res === true) {
+ return $this->pwfile->save();
+ }
+ return $res;
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SOAP.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SOAP.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SOAP.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,229 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against a SOAP service
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Bruno Pedro <bpedro at co.sapo.pt>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: SOAP.php,v 1.13 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.2.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once "Auth/Container.php";
+/**
+ * Include PEAR package for error handling
+ */
+require_once "PEAR.php";
+/**
+ * Include PEAR SOAP_Client
+ */
+require_once 'SOAP/Client.php';
+
+/**
+ * Storage driver for fetching login data from SOAP
+ *
+ * This class takes one parameter (options), where
+ * you specify the following fields: endpoint, namespace,
+ * method, encoding, usernamefield and passwordfield.
+ *
+ * You can use specify features of your SOAP service
+ * by providing its parameters in an associative manner by
+ * using the '_features' array through the options parameter.
+ *
+ * The 'matchpassword' option should be set to false if your
+ * webservice doesn't return (username,password) pairs, but
+ * instead returns error when the login is invalid.
+ *
+ * Example usage:
+ *
+ * <?php
+ *
+ * ...
+ *
+ * $options = array (
+ * 'endpoint' => 'http://your.soap.service/endpoint',
+ * 'namespace' => 'urn:/Your/Namespace',
+ * 'method' => 'get',
+ * 'encoding' => 'UTF-8',
+ * 'usernamefield' => 'login',
+ * 'passwordfield' => 'password',
+ * 'matchpasswords' => false,
+ * '_features' => array (
+ * 'example_feature' => 'example_value',
+ * 'another_example' => ''
+ * )
+ * );
+ * $auth = new Auth('SOAP', $options, 'loginFunction');
+ * $auth->start();
+ *
+ * ...
+ *
+ * ?>
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Bruno Pedro <bpedro at co.sapo.pt>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.13 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.2.0
+ */
+class Auth_Container_SOAP extends Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * Required options for the class
+ * @var array
+ * @access private
+ */
+ var $_requiredOptions = array(
+ 'endpoint',
+ 'namespace',
+ 'method',
+ 'encoding',
+ 'usernamefield',
+ 'passwordfield',
+ );
+
+ /**
+ * Options for the class
+ * @var array
+ * @access private
+ */
+ var $_options = array();
+
+ /**
+ * Optional SOAP features
+ * @var array
+ * @access private
+ */
+ var $_features = array();
+
+ /**
+ * The SOAP response
+ * @var array
+ * @access public
+ */
+ var $soapResponse = array();
+
+ /**
+ * The SOAP client
+ * @var mixed
+ * @access public
+ */
+ var $soapClient = null;
+
+ // }}}
+ // {{{ Auth_Container_SOAP() [constructor]
+
+ /**
+ * Constructor of the container class
+ *
+ * @param $options, associative array with endpoint, namespace, method,
+ * usernamefield, passwordfield and optional features
+ */
+ function Auth_Container_SOAP($options)
+ {
+ $this->_options = $options;
+ if (!isset($this->_options['matchpasswords'])) {
+ $this->_options['matchpasswords'] = true;
+ }
+ if (!empty($this->_options['_features'])) {
+ $this->_features = $this->_options['_features'];
+ unset($this->_options['_features']);
+ }
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Fetch data from SOAP service
+ *
+ * Requests the SOAP service for the given username/password
+ * combination.
+ *
+ * @param string Username
+ * @param string Password
+ * @return mixed Returns the SOAP response or false if something went wrong
+ */
+ function fetchData($username, $password)
+ {
+ $this->log('Auth_Container_SOAP::fetchData() called.', AUTH_LOG_DEBUG);
+ // check if all required options are set
+ if (array_intersect($this->_requiredOptions, array_keys($this->_options)) != $this->_requiredOptions) {
+ return false;
+ } else {
+ // create a SOAP client and set encoding
+ $this->soapClient = new SOAP_Client($this->_options['endpoint']);
+ $this->soapClient->setEncoding($this->_options['encoding']);
+ }
+
+ // set the trace option if requested
+ if (isset($this->_options['trace'])) {
+ $this->soapClient->__options['trace'] = true;
+ }
+
+ // set the timeout option if requested
+ if (isset($this->_options['timeout'])) {
+ $this->soapClient->__options['timeout'] = $this->_options['timeout'];
+ }
+
+ // assign username and password fields
+ $usernameField = new SOAP_Value($this->_options['usernamefield'],'string', $username);
+ $passwordField = new SOAP_Value($this->_options['passwordfield'],'string', $password);
+ $SOAPParams = array($usernameField, $passwordField);
+
+ // assign optional features
+ foreach ($this->_features as $fieldName => $fieldValue) {
+ $SOAPParams[] = new SOAP_Value($fieldName, 'string', $fieldValue);
+ }
+
+ // make SOAP call
+ $this->soapResponse = $this->soapClient->call(
+ $this->_options['method'],
+ $SOAPParams,
+ array('namespace' => $this->_options['namespace'])
+ );
+
+ if (!PEAR::isError($this->soapResponse)) {
+ if ($this->_options['matchpasswords']) {
+ // check if passwords match
+ if ($password == $this->soapResponse->{$this->_options['passwordfield']}) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SOAP5.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SOAP5.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/SOAP5.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,268 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against a SOAP service using PHP5 SoapClient
+ *
+ * PHP version 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Based upon Auth_Container_SOAP by Bruno Pedro <bpedro at co.sapo.pt>
+ * @author Marcel Oelke <puRe at rednoize.com>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: SOAP5.php,v 1.9 2007/07/02 08:25:41 aashley Exp $
+ * @since File available since Release 1.4.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once "Auth/Container.php";
+/**
+ * Include PEAR package for error handling
+ */
+require_once "PEAR.php";
+
+/**
+ * Storage driver for fetching login data from SOAP using the PHP5 Builtin SOAP
+ * functions. This is a modification of the SOAP Storage driver from Bruno Pedro
+ * thats using the PEAR SOAP Package.
+ *
+ * This class takes one parameter (options), where
+ * you specify the following fields:
+ * * location and uri, or wsdl file
+ * * method to call on the SOAP service
+ * * usernamefield, the name of the parameter where the username is supplied
+ * * passwordfield, the name of the parameter where the password is supplied
+ * * matchpassword, whether to look for the password in the response from
+ * the function call or assume that no errors means user
+ * authenticated.
+ *
+ * See http://www.php.net/manual/en/ref.soap.php for further details
+ * on options for the PHP5 SoapClient which are passed through.
+ *
+ * Example usage without WSDL:
+ *
+ * <?php
+ *
+ * $options = array (
+ * 'wsdl' => NULL,
+ * 'location' => 'http://your.soap.service/endpoint',
+ * 'uri' => 'urn:/Your/Namespace',
+ * 'method' => 'checkAuth',
+ * 'usernamefield' => 'username',
+ * 'passwordfield' => 'password',
+ * 'matchpasswords' => false,
+ * '_features' => array (
+ * 'extra_parameter' => 'example_value',
+ * 'another_parameter' => 'foobar'
+ * )
+ * );
+ *
+ * $auth = new Auth('SOAP5', $options);
+ * $auth->start();
+ *
+ * ?>
+ *
+ * Example usage with WSDL:
+ *
+ * <?php
+ *
+ * $options = array (
+ * 'wsdl' => 'http://your.soap.service/wsdl',
+ * 'method' => 'checkAuth',
+ * 'usernamefield' => 'username',
+ * 'passwordfield' => 'password',
+ * 'matchpasswords' => false,
+ * '_features' => array (
+ * 'extra_parameter' => 'example_value',
+ * 'another_parameter' => 'foobar'
+ * )
+ * );
+ *
+ * $auth = new Auth('SOAP5', $options);
+ * $auth->start();
+ *
+ * ?>
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Based upon Auth_Container_SOAP by Bruno Pedro <bpedro at co.sapo.pt>
+ * @author Marcel Oelke <puRe at rednoize.com>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.9 $
+ * @since Class available since Release 1.4.0
+ */
+class Auth_Container_SOAP5 extends Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * Required options for the class
+ * @var array
+ * @access private
+ */
+ var $_requiredOptions = array(
+ 'location',
+ 'uri',
+ 'method',
+ 'usernamefield',
+ 'passwordfield',
+ 'wsdl',
+ );
+
+ /**
+ * Options for the class
+ * @var array
+ * @access private
+ */
+ var $_options = array();
+
+ /**
+ * Optional SOAP features
+ * @var array
+ * @access private
+ */
+ var $_features = array();
+
+ /**
+ * The SOAP response
+ * @var array
+ * @access public
+ */
+ var $soapResponse = array();
+
+ // }}}
+ // {{{ Auth_Container_SOAP5()
+
+ /**
+ * Constructor of the container class
+ *
+ * @param $options, associative array with endpoint, namespace, method,
+ * usernamefield, passwordfield and optional features
+ */
+ function Auth_Container_SOAP5($options)
+ {
+ $this->_setDefaults();
+
+ foreach ($options as $name => $value) {
+ $this->_options[$name] = $value;
+ }
+
+ if (!empty($this->_options['_features'])) {
+ $this->_features = $this->_options['_features'];
+ unset($this->_options['_features']);
+ }
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Fetch data from SOAP service
+ *
+ * Requests the SOAP service for the given username/password
+ * combination.
+ *
+ * @param string Username
+ * @param string Password
+ * @return mixed Returns the SOAP response or false if something went wrong
+ */
+ function fetchData($username, $password)
+ {
+ $this->log('Auth_Container_SOAP5::fetchData() called.', AUTH_LOG_DEBUG);
+ $result = $this->_validateOptions();
+ if (PEAR::isError($result))
+ return $result;
+
+ // create a SOAP client
+ $soapClient = new SoapClient($this->_options["wsdl"], $this->_options);
+
+ $params = array();
+ // first, assign the optional features
+ foreach ($this->_features as $fieldName => $fieldValue) {
+ $params[$fieldName] = $fieldValue;
+ }
+ // assign username and password ...
+ $params[$this->_options['usernamefield']] = $username;
+ $params[$this->_options['passwordfield']] = $password;
+
+ try {
+ $this->soapResponse = $soapClient->__soapCall($this->_options['method'], $params);
+
+ if ($this->_options['matchpasswords']) {
+ // check if passwords match
+ if ($password == $this->soapResponse[$this->_options['passwordfield']]) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ } catch (SoapFault $e) {
+ return PEAR::raiseError("Error retrieving authentication data. Received SOAP Fault: ".$e->faultstring, $e->faultcode);
+ }
+ }
+
+ // }}}
+ // {{{ _validateOptions()
+
+ /**
+ * Validate that the options passed to the container class are enough for us to proceed
+ *
+ * @access private
+ * @param array
+ */
+ function _validateOptions()
+ {
+ if ( ( is_null($this->_options['wsdl'])
+ && is_null($this->_options['location'])
+ && is_null($this->_options['uri']))
+ || ( is_null($this->_options['wsdl'])
+ && ( is_null($this->_options['location'])
+ || is_null($this->_options['uri'])))) {
+ return PEAR::raiseError('Either a WSDL file or a location/uri pair must be specified.');
+ }
+ if (is_null($this->_options['method'])) {
+ return PEAR::raiseError('A method to call on the soap service must be specified.');
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ _setDefaults()
+
+ /**
+ * Set some default options
+ *
+ * @access private
+ * @return void
+ */
+ function _setDefaults()
+ {
+ $this->_options['wsdl'] = null;
+ $this->_options['location'] = null;
+ $this->_options['uri'] = null;
+ $this->_options['method'] = null;
+ $this->_options['usernamefield'] = 'username';
+ $this->_options['passwordfield'] = 'password';
+ $this->_options['matchpasswords'] = true;
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/vpopmail.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/vpopmail.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container/vpopmail.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,88 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Storage driver for use against vpopmail setups
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Stanislav Grozev <tacho at orbitel.bg>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: vpopmail.php,v 1.10 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.2.0
+ */
+
+/**
+ * Include Auth_Container base class
+ */
+require_once "Auth/Container.php";
+/**
+ * Include PEAR package for error handling
+ */
+require_once "PEAR.php";
+
+/**
+ * Storage driver for fetching login data from vpopmail
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Stanislav Grozev <tacho at orbitel.bg>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.10 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.2.0
+ */
+class Auth_Container_vpopmail extends Auth_Container {
+
+ // {{{ Constructor
+
+ /**
+ * Constructor of the container class
+ *
+ * @return void
+ */
+ function Auth_Container_vpopmail()
+ {
+ if (!extension_loaded('vpopmail')) {
+ return PEAR::raiseError('Cannot use VPOPMail authentication, '
+ .'VPOPMail extension not loaded!', 41, PEAR_ERROR_DIE);
+ }
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Get user information from vpopmail
+ *
+ * @param string Username - has to be valid email address
+ * @param string Password
+ * @return boolean
+ */
+ function fetchData($username, $password)
+ {
+ $this->log('Auth_Container_vpopmail::fetchData() called.', AUTH_LOG_DEBUG);
+ $userdata = array();
+ $userdata = preg_split("/@/", $username, 2);
+ $result = @vpopmail_auth_user($userdata[0], $userdata[1], $password);
+
+ return $result;
+ }
+
+ // }}}
+
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Container.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Container.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Container.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,262 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Auth_Container Base Class
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Martin Jansen <mj at php.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: Container.php,v 1.28 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ */
+
+/**
+ * Storage class for fetching login data
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Martin Jansen <mj at php.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.28 $
+ * @link http://pear.php.net/package/Auth
+ */
+class Auth_Container
+{
+
+ // {{{ properties
+
+ /**
+ * User that is currently selected from the storage container.
+ *
+ * @access public
+ */
+ var $activeUser = "";
+
+ /**
+ * The Auth object this container is attached to.
+ *
+ * @access public
+ */
+ var $_auth_obj = null;
+
+ // }}}
+ // {{{ Auth_Container() [constructor]
+
+ /**
+ * Constructor
+ *
+ * Has to be overwritten by each storage class
+ *
+ * @access public
+ */
+ function Auth_Container()
+ {
+ }
+
+ // }}}
+ // {{{ fetchData()
+
+ /**
+ * Fetch data from storage container
+ *
+ * Has to be overwritten by each storage class
+ *
+ * @access public
+ */
+ function fetchData($username, $password, $isChallengeResponse=false)
+ {
+ $this->log('Auth_Container::fetchData() called.', AUTH_LOG_DEBUG);
+ }
+
+ // }}}
+ // {{{ verifyPassword()
+
+ /**
+ * Crypt and verfiy the entered password
+ *
+ * @param string Entered password
+ * @param string Password from the data container (usually this password
+ * is already encrypted.
+ * @param string Type of algorithm with which the password from
+ * the container has been crypted. (md5, crypt etc.)
+ * Defaults to "md5".
+ * @return bool True, if the passwords match
+ */
+ function verifyPassword($password1, $password2, $cryptType = "md5")
+ {
+ $this->log('Auth_Container::verifyPassword() called.', AUTH_LOG_DEBUG);
+ switch ($cryptType) {
+ case "crypt" :
+ return ((string)crypt($password1, $password2) === (string)$password2);
+ break;
+ case "none" :
+ case "" :
+ return ((string)$password1 === (string)$password2);
+ break;
+ case "md5" :
+ return ((string)md5($password1) === (string)$password2);
+ break;
+ default :
+ if (function_exists($cryptType)) {
+ return ((string)$cryptType($password1) === (string)$password2);
+ } elseif (method_exists($this,$cryptType)) {
+ return ((string)$this->$cryptType($password1) === (string)$password2);
+ } else {
+ return false;
+ }
+ break;
+ }
+ }
+
+ // }}}
+ // {{{ supportsChallengeResponse()
+
+ /**
+ * Returns true if the container supports Challenge Response
+ * password authentication
+ */
+ function supportsChallengeResponse()
+ {
+ return(false);
+ }
+
+ // }}}
+ // {{{ getCryptType()
+
+ /**
+ * Returns the crypt current crypt type of the container
+ *
+ * @return string
+ */
+ function getCryptType()
+ {
+ return('');
+ }
+
+ // }}}
+ // {{{ listUsers()
+
+ /**
+ * List all users that are available from the storage container
+ */
+ function listUsers()
+ {
+ $this->log('Auth_Container::listUsers() called.', AUTH_LOG_DEBUG);
+ return AUTH_METHOD_NOT_SUPPORTED;
+ }
+
+ // }}}
+ // {{{ getUser()
+
+ /**
+ * Returns a user assoc array
+ *
+ * Containers which want should overide this
+ *
+ * @param string The username
+ */
+ function getUser($username)
+ {
+ $this->log('Auth_Container::getUser() called.', AUTH_LOG_DEBUG);
+ $users = $this->listUsers();
+ if ($users === AUTH_METHOD_NOT_SUPPORTED) {
+ return AUTH_METHOD_NOT_SUPPORTED;
+ }
+ for ($i=0; $c = count($users), $i<$c; $i++) {
+ if ($users[$i]['username'] == $username) {
+ return $users[$i];
+ }
+ }
+ return false;
+ }
+
+ // }}}
+ // {{{ addUser()
+
+ /**
+ * Add a new user to the storage container
+ *
+ * @param string Username
+ * @param string Password
+ * @param array Additional information
+ *
+ * @return boolean
+ */
+ function addUser($username, $password, $additional=null)
+ {
+ $this->log('Auth_Container::addUser() called.', AUTH_LOG_DEBUG);
+ return AUTH_METHOD_NOT_SUPPORTED;
+ }
+
+ // }}}
+ // {{{ removeUser()
+
+ /**
+ * Remove user from the storage container
+ *
+ * @param string Username
+ */
+ function removeUser($username)
+ {
+ $this->log('Auth_Container::removeUser() called.', AUTH_LOG_DEBUG);
+ return AUTH_METHOD_NOT_SUPPORTED;
+ }
+
+ // }}}
+ // {{{ changePassword()
+
+ /**
+ * Change password for user in the storage container
+ *
+ * @param string Username
+ * @param string The new password
+ */
+ function changePassword($username, $password)
+ {
+ $this->log('Auth_Container::changePassword() called.', AUTH_LOG_DEBUG);
+ return AUTH_METHOD_NOT_SUPPORTED;
+ }
+
+ // }}}
+ // {{{ log()
+
+ /**
+ * Log a message to the Auth log
+ *
+ * @param string The message
+ * @param int
+ * @return boolean
+ */
+ function log($message, $level = AUTH_LOG_DEBUG) {
+
+ if (is_null($this->_auth_obj)) {
+
+ return false;
+
+ } else {
+
+ return $this->_auth_obj->log($message, $level);
+
+ }
+
+ }
+
+ // }}}
+
+}
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Frontend/Html.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Frontend/Html.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Frontend/Html.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,142 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+
+/**
+ * Standard Html Login form
+ *
+ * PHP versions 4 and 5
+ *
+ * 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 at php.net so we can mail you a copy immediately.
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Martin Jansen <mj at php.net>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: Html.php,v 1.11 2007/06/12 03:11:26 aashley Exp $
+ * @link http://pear.php.net/package/Auth
+ * @since File available since Release 1.3.0
+ */
+
+/**
+ * Standard Html Login form
+ *
+ * @category Authentication
+ * @package Auth
+ * @author Yavor Shahpasov <yavo at netsmart.com.cy>
+ * @author Adam Ashley <aashley at php.net>
+ * @copyright 2001-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 1.6.1 File: $Revision: 1.11 $
+ * @link http://pear.php.net/package/Auth
+ * @since Class available since Release 1.3.0
+ */
+class Auth_Frontend_Html {
+
+ // {{{ render()
+
+ /**
+ * Displays the login form
+ *
+ * @param object The calling auth instance
+ * @param string The previously used username
+ * @return void
+ */
+ function render(&$caller, $username = '') {
+ $loginOnClick = 'return true;';
+
+ // Try To Use Challene response
+ // TODO javascript might need some improvement for work on other browsers
+ if($caller->advancedsecurity && $caller->storage->supportsChallengeResponse() ) {
+
+ // Init the secret cookie
+ $caller->session['loginchallenege'] = md5(microtime());
+
+ print "\n";
+ print '<script language="JavaScript">'."\n";
+
+ include 'Auth/Frontend/md5.js';
+
+ print "\n";
+ print ' function securePassword() { '."\n";
+ print ' var pass = document.getElementById(\''.$caller->getPostPasswordField().'\');'."\n";
+ print ' var secret = document.getElementById(\'authsecret\')'."\n";
+ //print ' alert(pass);alert(secret); '."\n";
+
+ // If using md5 for password storage md5 the password before
+ // we hash it with the secret
+ // print ' alert(pass.value);';
+ if ($caller->storage->getCryptType() == 'md5' ) {
+ print ' pass.value = hex_md5(pass.value); '."\n";
+ #print ' alert(pass.value);';
+ }
+
+ print ' pass.value = hex_md5(pass.value+\''.$caller->session['loginchallenege'].'\'); '."\n";
+ // print ' alert(pass.value);';
+ print ' secret.value = 1;'."\n";
+ print ' var doLogin = document.getElementById(\'doLogin\')'."\n";
+ print ' doLogin.disabled = true;'."\n";
+ print ' return true;';
+ print ' } '."\n";
+ print '</script>'."\n";;
+ print "\n";
+
+ $loginOnClick = ' return securePassword(); ';
+ }
+
+ print '<center>'."\n";
+
+ $status = '';
+ if (!empty($caller->status) && $caller->status == AUTH_EXPIRED) {
+ $status = '<i>Your session has expired. Please login again!</i>'."\n";
+ } else if (!empty($caller->status) && $caller->status == AUTH_IDLED) {
+ $status = '<i>You have been idle for too long. Please login again!</i>'."\n";
+ } else if (!empty ($caller->status) && $caller->status == AUTH_WRONG_LOGIN) {
+ $status = '<i>Wrong login data!</i>'."\n";
+ } else if (!empty ($caller->status) && $caller->status == AUTH_SECURITY_BREACH) {
+ $status = '<i>Security problem detected. </i>'."\n";
+ }
+
+ print '<form method="post" action="'.$caller->server['PHP_SELF'].'" '
+ .'onSubmit="'.$loginOnClick.'">'."\n";
+ print '<table border="0" cellpadding="2" cellspacing="0" '
+ .'summary="login form" align="center" >'."\n";
+ print '<tr>'."\n";
+ print ' <td colspan="2" bgcolor="#eeeeee"><strong>Login </strong>'
+ .$status.'</td>'."\n";
+ print '</tr>'."\n";
+ print '<tr>'."\n";
+ print ' <td>Username:</td>'."\n";
+ print ' <td><input type="text" id="'.$caller->getPostUsernameField()
+ .'" name="'.$caller->getPostUsernameField().'" value="' . $username
+ .'" /></td>'."\n";
+ print '</tr>'."\n";
+ print '<tr>'."\n";
+ print ' <td>Password:</td>'."\n";
+ print ' <td><input type="password" id="'.$caller->getPostPasswordField()
+ .'" name="'.$caller->getPostPasswordField().'" /></td>'."\n";
+ print '</tr>'."\n";
+ print '<tr>'."\n";
+
+ //onClick=" '.$loginOnClick.' "
+ print ' <td colspan="2" bgcolor="#eeeeee"><input value="Login" '
+ .'id="doLogin" name="doLogin" type="submit" /></td>'."\n";
+ print '</tr>'."\n";
+ print '</table>'."\n";
+
+ // Might be a good idea to make the variable name variable
+ print '<input type="hidden" id="authsecret" name="authsecret" value="" />';
+ print '</form>'."\n";
+ print '</center>'."\n";
+ }
+
+ // }}}
+
+}
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/Frontend/md5.js
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/Frontend/md5.js (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/Frontend/md5.js 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,256 @@
+/*
+ * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
+ * Digest Algorithm, as defined in RFC 1321.
+ * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for more info.
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
+var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
+var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
+function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
+function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
+function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
+function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
+function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function md5_vm_test()
+{
+ return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
+}
+
+/*
+ * Calculate the MD5 of an array of little-endian words, and a bit length
+ */
+function core_md5(x, len)
+{
+ /* append padding */
+ x[len >> 5] |= 0x80 << ((len) % 32);
+ x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+
+ for(var i = 0; i < x.length; i += 16)
+ {
+ var olda = a;
+ var oldb = b;
+ var oldc = c;
+ var oldd = d;
+
+ a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
+ d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
+ c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
+ b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
+ a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
+ d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
+ c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
+ b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
+ a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
+ d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
+ c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
+ b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
+ a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
+ d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
+ c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
+ b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
+
+ a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
+ d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
+ c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
+ b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
+ a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
+ d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
+ c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
+ b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
+ a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
+ d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
+ c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
+ b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
+ a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
+ d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
+ c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
+ b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
+
+ a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
+ d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
+ c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
+ b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
+ a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
+ d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
+ c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
+ b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
+ a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
+ d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
+ c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
+ b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
+ a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
+ d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
+ c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
+ b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
+
+ a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
+ d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
+ c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
+ b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
+ a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
+ d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
+ c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
+ b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
+ a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
+ d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
+ c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
+ b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
+ a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
+ d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
+ c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
+ b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ }
+ return Array(a, b, c, d);
+
+}
+
+/*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+function md5_cmn(q, a, b, x, s, t)
+{
+ return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
+}
+function md5_ff(a, b, c, d, x, s, t)
+{
+ return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+}
+function md5_gg(a, b, c, d, x, s, t)
+{
+ return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+}
+function md5_hh(a, b, c, d, x, s, t)
+{
+ return md5_cmn(b ^ c ^ d, a, b, x, s, t);
+}
+function md5_ii(a, b, c, d, x, s, t)
+{
+ return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+}
+
+/*
+ * Calculate the HMAC-MD5, of a key and some data
+ */
+function core_hmac_md5(key, data)
+{
+ var bkey = str2binl(key);
+ if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
+
+ var ipad = Array(16), opad = Array(16);
+ for(var i = 0; i < 16; i++)
+ {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+
+ var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
+ return core_md5(opad.concat(hash), 512 + 128);
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt)
+{
+ return (num << cnt) | (num >>> (32 - cnt));
+}
+
+/*
+ * Convert a string to an array of little-endian words
+ * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
+ */
+function str2binl(str)
+{
+ var bin = Array();
+ var mask = (1 << chrsz) - 1;
+ for(var i = 0; i < str.length * chrsz; i += chrsz)
+ bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
+ return bin;
+}
+
+/*
+ * Convert an array of little-endian words to a string
+ */
+function binl2str(bin)
+{
+ var str = "";
+ var mask = (1 << chrsz) - 1;
+ for(var i = 0; i < bin.length * 32; i += chrsz)
+ str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
+ return str;
+}
+
+/*
+ * Convert an array of little-endian words to a hex string.
+ */
+function binl2hex(binarray)
+{
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var str = "";
+ for(var i = 0; i < binarray.length * 4; i++)
+ {
+ str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
+ hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
+ }
+ return str;
+}
+
+/*
+ * Convert an array of little-endian words to a base-64 string
+ */
+function binl2b64(binarray)
+{
+ var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var str = "";
+ for(var i = 0; i < binarray.length * 4; i += 3)
+ {
+ var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
+ | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
+ | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
+ for(var j = 0; j < 4; j++)
+ {
+ if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
+ else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
+ }
+ }
+ return str;
+}
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/README.AdvancedSecurity
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/README.AdvancedSecurity (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/README.AdvancedSecurity 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,63 @@
+03 July 2004
+
+TODO
+ * Session fixation attack (BUG #2021)
+ * Fix multiple open windows and challenge responce cookies (use a list of cookies which are allowed)
+
+Since Auth 1.3 new security functionality has been added.
+The main purpose for these advanced security checks is to avoid man-in-the-middle attacks and
+session hijacking.
+
+
+Session hijacking example
+ - Login to an Auth protected page. Write down the session id (should be something like PHPSESSID=36916b0aa1180386010f304b6160e3e8)
+ - Open a different browser (FireFox <> IE), or a browser on a different computer
+ - Type down the address of the secure page and add ?PHPSESSID=36916b0aa1180386010f304b6160e3e8 where
+ PHPSESSID is the php session name and 36916b0aa1180386010f304b6160e3e8 is the valid session id which you wrote down earlier
+ - You should be logged in with the same creditentials
+
+
+
+To enable the advanced scurity checks you have to call
+$auth->setAdvancedSecurity();
+
+If this has been enabled the following security checks will be performed
+
+ - Login screen will use md5 when submitting the password if java script is enabled in the browser
+ - If user ip address has been changed betwin requests the user will be logged out
+ - If user User-Agent string has been changed the user will be logged out
+ - If user does not provide a valid auth challenge cookied he will be logged out (read below for explanation)
+
+Limitations
+ * Challenge responce cookies would not allow a user to open multiple windows of the same page (Open in new window/tab). If
+ the user accesses the protected area from two browser windows he will be logged out. It can also create a problem if you
+ create dynamic images with php and that code passes through the auth layer. One way to avoid it is to disable advanced security for
+ those pages only selectively.
+ * Password saving does not work with login screens which use challenge responce (md5 hashing) of password
+ * Challenge responce on login only works with DB container and plain or md5 hashing
+
+
+
+
+Challenge Responce cookies
+
+
+ The challenge responce cookies provide a way to avoid most of the session hijacking problems. Since User-Agent headers
+ and IP address can be spoofed, or in the case of IP a proxy can be used an extra security step has been added using a
+ challenge cookie.
+
+ After the user is authenthicated by Auth he is presented with a challenge cookie. For his next request to be succesfull
+ he must present that cookie on his next request. If that is successfull he will be presented with a new
+ challenge cookie. This will be reapeated for each request the user makes.
+
+ While this method is not fool proof it does limit the possibilities for an attack.
+ First the attacker must must obtain the challenge cookie and use it before the user does.
+ If the user makes a request after the attacker the session will be logged out and both of them
+ will need to login again.
+
+ A problem which this scheme does not address well is users leaving their sessions without preforming a logout
+ in this case the attacker is free to abuse the user session (provided he has met all the prerequisites).
+
+ Ideas and sujestions for improvements are more than welcome.
+ send to yavo at siava.org
+
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/README.Auth
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/README.Auth (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/README.Auth 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,3 @@
+The documentation for PEAR::Auth is available at
+
+ http://pear.php.net/manual/
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/examples/logging.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/examples/logging.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/examples/logging.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,75 @@
+<?php
+
+require_once "Auth.php";
+require_once 'Log.php';
+require_once 'Log/observer.php';
+
+// Callback function to display login form
+function loginFunction($username = null, $status = null, &$auth = null)
+{
+ /*
+ * Change the HTML output so that it fits to your
+ * application.
+ */
+ echo "<form method=\"post\" action=\"".$_SERVER['PHP_SELF']."\">";
+ echo "Username: <input type=\"text\" name=\"username\"><br/>";
+ echo "Password: <input type=\"password\" name=\"password\"><br/>";
+ echo "<input type=\"submit\">";
+ echo "</form>";
+}
+
+class Auth_Log_Observer extends Log_observer {
+
+ var $messages = array();
+
+ function notify($event) {
+
+ $this->messages[] = $event;
+
+ }
+
+}
+
+$options = array(
+ 'enableLogging' => true,
+ 'cryptType' => 'md5',
+ 'users' => array(
+ 'guest' => md5('password'),
+ ),
+ );
+$a = new Auth("Array", $options, "loginFunction");
+
+$infoObserver = new Auth_Log_Observer(AUTH_LOG_INFO);
+
+$a->attachLogObserver($infoObserver);
+
+$debugObserver = new Auth_Log_Observer(AUTH_LOG_DEBUG);
+
+$a->attachLogObserver($debugObserver);
+
+$a->start();
+
+if ($a->checkAuth()) {
+ /*
+ * The output of your site goes here.
+ */
+ print "Authentication Successful.<br/>";
+}
+
+print '<h3>Logging Output:</h3>'
+ .'<b>AUTH_LOG_INFO level messages:</b><br/>';
+
+foreach ($infoObserver->messages as $event) {
+ print $event['priority'].': '.$event['message'].'<br/>';
+}
+
+print '<br/>'
+ .'<b>AUTH_LOG_DEBUG level messages:</b><br/>';
+
+foreach ($debugObserver->messages as $event) {
+ print $event['priority'].': '.$event['message'].'<br/>';
+}
+
+print '<br/>';
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/examples/multi-container.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/examples/multi-container.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/examples/multi-container.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,89 @@
+<?php
+
+require_once "Auth.php";
+require_once 'Log.php';
+require_once 'Log/observer.php';
+
+// Callback function to display login form
+function loginFunction($username = null, $status = null, &$auth = null)
+{
+ /*
+ * Change the HTML output so that it fits to your
+ * application.
+ */
+ echo "<form method=\"post\" action=\"".$_SERVER['PHP_SELF']."\">";
+ echo "Username: <input type=\"text\" name=\"username\"><br/>";
+ echo "Password: <input type=\"password\" name=\"password\"><br/>";
+ echo "<input type=\"submit\">";
+ echo "</form>";
+}
+
+class Auth_Log_Observer extends Log_observer {
+
+ var $messages = array();
+
+ function notify($event) {
+
+ $this->messages[] = $event;
+
+ }
+
+}
+
+$options = array(
+ 'enableLogging' => true,
+ array(
+ 'type' => 'Array',
+ 'options' => array(
+ 'cryptType' => 'md5',
+ 'users' => array(
+ 'guest' => md5('password'),
+ ),
+ ),
+ ),
+ array(
+ 'type' => 'Array',
+ 'options' => array(
+ 'cryptType' => 'md5',
+ 'users' => array(
+ 'admin' => md5('password'),
+ ),
+ ),
+ ),
+);
+$a = new Auth("Multiple", $options, "loginFunction");
+
+$infoObserver = new Auth_Log_Observer(AUTH_LOG_INFO);
+
+$a->attachLogObserver($infoObserver);
+
+$debugObserver = new Auth_Log_Observer(AUTH_LOG_DEBUG);
+
+$a->attachLogObserver($debugObserver);
+
+$a->start();
+
+if ($a->checkAuth()) {
+ /*
+ * The output of your site goes here.
+ */
+ print "Authentication Successful.<br/>";
+}
+
+print '<h3>Logging Output:</h3>'
+ .'<b>AUTH_LOG_INFO level messages:</b><br/>';
+
+foreach ($infoObserver->messages as $event) {
+ print $event['priority'].': '.$event['message'].'<br/>';
+}
+
+print '<br/>'
+ .'<b>AUTH_LOG_DEBUG level messages:</b><br/>';
+
+foreach ($debugObserver->messages as $event) {
+ print $event['priority'].': '.$event['message'].'<br/>';
+}
+
+print '<br/>';
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/DBContainer.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/DBContainer.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/DBContainer.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,40 @@
+<?php
+
+include_once 'TestAuthContainer.php';
+include_once 'Auth/Container/DB.php';
+
+
+class DBContainer extends TestAuthContainer {
+
+ function DBContainer($name){
+ $this->TestAuthContainer($name);
+ }
+
+ function &getContainer() {
+ static $container;
+ #print "In DBContainer::getContainer {$this->skip_tests}\n";
+ if(!isset($container)){
+ include './auth_container_db_options.php';
+ $container = new Auth_Container_DB($options);
+ // Catch if DB connection cannot be made
+ $res = $container->_prepare();
+ }
+
+ if(!DB::isConnection($container->db)){
+ #print "In DBContainer::getContainer container->db is error \n";
+ $this->skip_tests = true;
+ $this->skip_tests_message = "SKIP TEST:DB is not a connection object, check dsn !!!";
+ }
+ return($container);
+ }
+
+ function &getExtraOptions() {
+ include './auth_container_db_options.php';
+ return($extra_options);
+ }
+}
+
+
+
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/FileContainer.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/FileContainer.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/FileContainer.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,30 @@
+<?php
+
+include_once 'TestAuthContainer.php';
+include_once 'Auth/Container/File.php';
+
+class FileContaner extends TestAuthContainer {
+
+ function FileContaner($name){
+ $this->TestAuthContainer($name);
+ }
+
+ function &getContainer() {
+ static $container;
+ if(!isset($container)){
+ include './auth_container_file_options.php';
+ $container = new Auth_Container_File($options);
+ }
+ return($container);
+ }
+
+ function &getExtraOptions() {
+ include './auth_container_file_options.php';
+ return($extra_options);
+ }
+}
+
+
+
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/MDB2Container.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/MDB2Container.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/MDB2Container.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,36 @@
+<?php
+
+include_once 'TestAuthContainer.php';
+include_once 'Auth/Container/MDB2.php';
+
+
+class MDB2Container extends TestAuthContainer {
+
+ function MDB2Container($name){
+ $this->TestAuthContainer($name);
+ }
+
+ function &getContainer() {
+ static $container;
+ #print "In MDB2Container::getContainer {$this->skip_tests}\n";
+ if(!isset($container)){
+ include './auth_container_mdb2_options.php';
+ $container = new Auth_Container_MDB2($options);
+ // Catch if DB connection cannot be made
+ $res = $container->_prepare();
+ }
+
+ if(!MDB2::isConnection($container->db)){
+ #print "In MDB2Container::getContainer container->db is error \n";
+ $this->skip_tests = true;
+ $this->skip_tests_message = "SKIP TEST:MDB2 is not a connection object, check dsn !!!";
+ }
+ return $container;
+ }
+
+ function &getExtraOptions() {
+ include './auth_container_mdb2_options.php';
+ return $extra_options;
+ }
+}
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/MDBContainer.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/MDBContainer.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/MDBContainer.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,40 @@
+<?php
+
+include_once 'TestAuthContainer.php';
+include_once 'Auth/Container/MDB.php';
+
+
+class MDBContainer extends TestAuthContainer {
+
+ function MDBContainer($name){
+ $this->TestAuthContainer($name);
+ }
+
+ function &getContainer() {
+ static $container;
+ #print "In MDBContainer::getContainer {$this->skip_tests}\n";
+ if(!isset($container)){
+ include './auth_container_mdb_options.php';
+ $container = new Auth_Container_MDB($options);
+ // Catch if DB connection cannot be made
+ $res = $container->_prepare();
+ }
+
+ if(!MDB::isConnection($container->db)){
+ #print "In MDBContainer::getContainer container->db is error \n";
+ $this->skip_tests = true;
+ $this->skip_tests_message = "SKIP TEST:MDB is not a connection object, check dsn !!!";
+ }
+ return $container;
+ }
+
+ function &getExtraOptions() {
+ include './auth_container_mdb_options.php';
+ return $extra_options;
+ }
+}
+
+
+
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/POP3Container.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/POP3Container.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/POP3Container.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,31 @@
+<?php
+
+include_once 'TestAuthContainer.php';
+include_once 'Auth/Container/POP3.php';
+
+
+class POP3Container extends TestAuthContainer {
+
+ function POP3Container($name){
+ $this->TestAuthContainer($name);
+ }
+
+ function &getContainer() {
+ static $container;
+ if(!isset($container)){
+ include './auth_container_pop3_options.php';
+ $container = new Auth_Container_POP3($options);
+ }
+ return($container);
+ }
+
+ function &getExtraOptions() {
+ include './auth_container_pop3_options.php';
+ return($extra_options);
+ }
+}
+
+
+
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/POP3aContainer.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/POP3aContainer.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/POP3aContainer.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,31 @@
+<?php
+
+include_once 'TestAuthContainer.php';
+include_once 'Auth/Container/POP3.php';
+
+
+class POP3aContainer extends TestAuthContainer {
+
+ function POP3aContainer($name){
+ $this->TestAuthContainer($name);
+ }
+
+ function &getContainer() {
+ static $container;
+ if(!isset($container)){
+ include './auth_container_pop3a_options.php';
+ $container = new Auth_Container_POP3($options);
+ }
+ return($container);
+ }
+
+ function &getExtraOptions() {
+ include './auth_container_pop3a_options.php';
+ return($extra_options);
+ }
+}
+
+
+
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/TestAuthContainer.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/TestAuthContainer.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/TestAuthContainer.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,173 @@
+<?php
+
+include_once 'PHPUnit.php';
+
+
+class TestAuthContainer extends PHPUnit_TestCase
+{
+
+ var $skip_tests = false;
+ var $skip_tests_message = "SKIP TEST";
+
+ function TestAuthContainer($name)
+ {
+ $this->PHPUnit_TestCase($name);
+ $this->container =& $this->getContainer();
+ $this->user = 'joe';
+ $this->pass = 'doe';
+ $this->opt = 'VeryCoolUser';
+ // Nedded since lazy loading of container was introduced
+ $this->container->_auth_obj =& new Auth(&$this);
+ }
+
+ // Abstract
+ function getContainer() {}
+ function getExtraOptions() {}
+
+ function setUp()
+ {
+ $opt = $this->getExtraOptions();
+ // Add the default user to be used for some testing
+ $this->container->addUser($opt['username'], $opt['passwd']);
+ }
+
+ function tearDown()
+ {
+ $opt = $this->getExtraOptions();
+ // Remove default user
+ $this->container->removeUser($opt['username']);
+ }
+
+ function testListUsers()
+ {
+ if ($this->skip_tests) {
+ $this->fail($this->skip_tests_message.'');
+ return(false);
+ }
+
+ $users = $this->container->listUsers();
+ if (AUTH_METHOD_NOT_SUPPORTED === $users) {
+ $this->fail('This operation is not supported by '.get_class($this->container));
+ return(false);
+ }
+
+ $opt = $this->getExtraOptions();
+ $this->assertTrue(is_array($users[0]), 'First array element from result was not an array');
+ $this->assertTrue($users[0]['username'] == $opt['username'], sprintf('First username was not equal to default username "%s" ', $opt['username']));
+ }
+
+ function testAddUser()
+ {
+ if ($this->skip_tests) {
+ $this->fail($this->skip_tests_message.'');
+ return(false);
+ }
+
+ $cb = count($this->container->listUsers());
+ $res = $this->container->addUser($this->user, $this->pass, $this->opt);
+ if (AUTH_METHOD_NOT_SUPPORTED === $res) {
+ $this->fail("This operation is not supported by ".get_class($this->container));
+ return(false);
+ }
+
+ if (PEAR::isError($res)) {
+ $error = $res->getMessage().' ['.$res->getUserInfo().']';
+ } else {
+ $error = '';
+ }
+ $this->assertTrue(!PEAR::isError($res), 'error:'.$error);
+ $ca = count($this->container->listUsers());
+ $users = $this->container->listUsers();
+ $last_username = $users[$ca-1]['username'];
+ $this->assertTrue( ($cb === $ca-1) , sprintf('Count of users before (%s) and after (%s) does not differ by one', $cb, $ca));
+ $this->assertTrue( $this->container->fetchData($this->user, $this->pass) , sprintf('Could not verify with the newly created user %s',$this->user));
+
+ // Remove the user we just added, assumes removeUser works
+ $this->container->removeUser($this->user);
+ }
+
+ function testFetchData()
+ {
+ if ($this->skip_tests) {
+ $this->fail($this->skip_tests_message.'');
+ return(false);
+ }
+
+ $opt = $this->getExtraOptions();
+ $fetch_res = $this->container->fetchData($opt['username'], $opt['passwd']);
+ if (AUTH_METHOD_NOT_SUPPORTED === $fetch_res) {
+ $this->fail("This operation is not supported by ".get_class($this->container));
+ return(false);
+ }
+
+ $this->assertTrue($fetch_res,sprintf('Could not verify with the default username (%s) and passwd (%s)', $opt['username'], $opt['passwd']));
+
+ // Test for fail fetchData
+ $opt = $this->getExtraOptions();
+ $this->assertFalse(
+ $this->container->fetchData(md5($opt['username']), $opt['passwd']),
+ "fetchData returned true with invalid username and pass"
+ );
+
+ }
+
+
+ /**
+ * Tjis test depends on add user & remove user to work
+ */
+ function testFetchDataSpaceInPassword()
+ {
+
+ if ($this->skip_tests) {
+ $this->fail($this->skip_tests_message.'');
+ return(false);
+ }
+
+ $user = uniqid('user');
+ $pass = 'Some Pass ';
+
+ $res = $this->container->addUser($user, $pass, array());
+ if (AUTH_METHOD_NOT_SUPPORTED === $res) {
+ $this->fail("This operation is not supported by ".get_class($this->container));
+ return(false);
+ } else {
+ $fetch_res = $this->container->fetchData($user, $pass);
+ if (AUTH_METHOD_NOT_SUPPORTED === $fetch_res) {
+ $this->fail("This operation is not supported by ".get_class($this->container));
+ return(false);
+ } else {
+ $this->assertTrue($fetch_res, 'Could not verify user with space password');
+ }
+ }
+
+ $remove_res = $this->container->removeUser($user);
+ }
+
+
+
+
+ function testRemoveUser()
+ {
+ if ($this->skip_tests) {
+ $this->fail($this->skip_tests_message.'');
+ return(false);
+ }
+
+ // Add a user to be removed when testing removeUuser method
+ // Assume add user works
+ $this->container->addUser('for_remove', 'for_remove');
+ $cb = count($this->container->listUsers());
+ $remove_res = $this->container->removeUser('for_remove');
+ if (AUTH_METHOD_NOT_SUPPORTED === $remove_res) {
+ $this->fail("This operation is not supported by ".get_class($this->container));
+ return(false);
+ }
+
+ $this->assertTrue(AUTH_METHOD_NOT_SUPPORTED == $remove_res, "This operation is not supported by ".get_class($this));
+ $ca = count($this->container->listUsers());
+ $this->assertTrue($cb === $ca+1, sprintf('Could not remove user "%s", count before:%s count after:%s ', 'for_remove', $cb, $ca));
+ }
+
+}
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_db_options.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_db_options.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_db_options.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ $this->options['table'] = "auth";
+ $this->options['usernamecol'] = "username";
+ $this->options['passwordcol'] = "password";
+ $this->options['dsn'] = "";
+ $this->options['db_fields'] = "";
+ $this->options['cryptType'] = "md5";
+*/
+$options = array(
+ 'dsn'=>'mysql://root:@localhost/authtest',
+ 'table'=>'temp',
+ 'usernamecol'=>'username',
+ 'passwordcol'=>'password',
+ 'cryptType'=>'md5',
+ 'db_fields'=>'*'
+);
+
+$extra_options['username'] = 'test_user';
+$extra_options['passwd'] = 'test_user';
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_file_options.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_file_options.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_file_options.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,8 @@
+<?php
+
+$options = 'users';
+
+$extra_options['username'] = 'test_user';
+$extra_options['passwd'] = 'test_user';
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_mdb2_options.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_mdb2_options.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_mdb2_options.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,25 @@
+<?php
+/*
+//TEST DATABASE:
+-----------------------------------------------
+DROP TABLE IF EXISTS temp;
+CREATE TABLE temp (
+ username varchar(150) NOT NULL,
+ password varchar(200) NOT NULL
+);
+-----------------------------------------------
+*/
+
+$options = array(
+ 'dsn' => 'mysql://root:@localhost/authtest',
+ 'table' => 'temp',
+ 'usernamecol' => 'username',
+ 'passwordcol' => 'password',
+ 'db_fields' => '*',
+ 'cryptType' => 'md5'
+);
+
+$extra_options['username'] = 'test_user';
+$extra_options['passwd'] = 'test_user';
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_mdb_options.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_mdb_options.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_mdb_options.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,25 @@
+<?php
+/*
+//TEST DATABASE:
+-----------------------------------------------
+DROP TABLE IF EXISTS temp;
+CREATE TABLE temp (
+ username varchar(150) NOT NULL,
+ password varchar(200) NOT NULL
+);
+-----------------------------------------------
+*/
+
+$options = array(
+ 'dsn' => 'mysql://root:@localhost/authtest',
+ 'table' => 'temp',
+ 'usernamecol' => 'username',
+ 'passwordcol' => 'password',
+ 'db_fields' => '*',
+ 'cryptType' => 'md5'
+);
+
+$extra_options['username'] = 'test_user';
+$extra_options['passwd'] = 'test_user';
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_pop3_options.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_pop3_options.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_pop3_options.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,11 @@
+<?php
+
+$options = array(
+ 'host'=>'mail.example.com',
+ 'port'=>'110'
+);
+
+$extra_options['username'] = 'test_user';
+$extra_options['passwd'] = 'test_user';
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_pop3a_options.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_pop3a_options.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/auth_container_pop3a_options.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,8 @@
+<?php
+
+$options = 'mail.example.com:110';
+
+$extra_options['username'] = 'test_user';
+$extra_options['passwd'] = 'test_user';
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/bug8735.passwd
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/bug8735.passwd (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/bug8735.passwd 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1 @@
+test:fcfKBtvEwG4g.
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/bug8735.phpt
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/bug8735.phpt (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/bug8735.phpt 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,44 @@
+--TEST--
+Regression test for bug #8735
+--FILE--
+<?php
+set_include_path(dirname(dirname(__FILE__)) . ':' . get_include_path());
+$datasrc = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'bug8735.passwd';
+
+require_once 'PEAR.php';
+require_once 'Auth.php';
+
+$a = new Auth('File',
+ array('file' => $datasrc,
+ 'type' => 'AuthBasic'),
+ 'displayLogin');
+if (PEAR::isError($a)) {
+ print $a->getMessage();
+ exit;
+}
+
+$error = $a->removeUser('username');
+if (PEAR::isError($error)) {
+ print $error->getMessage();
+ exit;
+}
+
+readfile($datasrc);
+print "-- cut --\n";
+
+$error = $a->addUser('username', 'password');
+if (PEAR::isError($error) || $error === false) {
+ print "Error happened when adding.\n";
+ print $error->getMessage();
+ exit;
+}
+
+readfile($datasrc);
+
+$a->removeUser('username');
+?>
+--EXPECT--
+test:fcfKBtvEwG4g.
+-- cut --
+test:fcfKBtvEwG4g.
+username:{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/mysql_test_db.sql
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/mysql_test_db.sql (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/mysql_test_db.sql 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,4 @@
+CREATE TABLE `temp` (
+ `username` varchar(150) NOT NULL default '',
+ `password` varchar(200) NOT NULL default ''
+ ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/tests.php
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/tests.php (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/tests.php 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1,48 @@
+<?php
+
+include_once 'Auth.php';
+include_once 'TestAuthContainer.php';
+include_once 'FileContainer.php';
+include_once 'DBContainer.php';
+include_once 'DBLiteContainer.php';
+include_once 'MDBContainer.php';
+include_once 'MDB2Container.php';
+include_once 'POP3Container.php';
+include_once 'POP3aContainer.php';
+include_once 'IMAPContainer.php';
+include_once 'PHPUnit.php';
+
+
+function error($err){
+ print "Error\n";
+ print "Code:".trim($err->getCode())."\n";
+ print "Message:".trim($err->getMessage())."\n";
+ #print "UserInfo:".trim($err->getUserInfo())."\n";
+ #print "DebugInfo:".trim($err->getDebugInfo())."\n";
+
+}
+
+#error_reporting(0);
+PEAR::setErrorHandling(PEAR_ERROR_PRINT, "\nPear Error:%s \n");
+#PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, "error");
+
+set_time_limit(0);
+
+$suite = new PHPUnit_TestSuite();
+
+// File Container
+#$suite->addTest(new PHPUnit_TestSuite('IMAPContainer'));
+$suite->addTest(new PHPUnit_TestSuite('FileContainer'));
+$suite->addTest(new PHPUnit_TestSuite('DBContainer'));
+//$suite->addTest(new PHPUnit_TestSuite('DBLiteContainer'));
+// MDB Container
+$suite->addTest(new PHPUnit_TestSuite('MDBContainer'));
+// MDB2 Container
+$suite->addTest(new PHPUnit_TestSuite('MDB2Container'));
+// POP3 Container
+$suite->addTest(new PHPUnit_TestSuite('POP3Container'));
+
+$result = PHPUnit::run($suite);
+echo $result->toString();
+
+?>
Added: pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/users
===================================================================
--- pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/users (rev 0)
+++ pear/php-auth/branches/upstream/current/Auth-1.6.1/tests/users 2008-04-28 01:36:51 UTC (rev 1023)
@@ -0,0 +1 @@
+
Modified: pear/php-auth/branches/upstream/current/package.xml
===================================================================
--- pear/php-auth/branches/upstream/current/package.xml 2008-04-28 01:09:39 UTC (rev 1022)
+++ pear/php-auth/branches/upstream/current/package.xml 2008-04-28 01:36:51 UTC (rev 1023)
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<package packagerversion="1.6.1" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
+<package packagerversion="1.7.1" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
<name>Auth</name>
<channel>pear.php.net</channel>
<summary>Creating an authentication system.</summary>
@@ -16,7 +16,7 @@
* LDAP servers
* POP3 servers
* IMAP servers
-* vpopmail accounts
+* vpopmail accounts (Using either PECL vpopmail or PEAR Net_Vpopmaild)
* RADIUS
* SAMBA password files
* SOAP (Using either PEAR SOAP package or PHP5 SOAP extension)
@@ -53,10 +53,10 @@
<email>aharvey at php.net</email>
<active>yes</active>
</developer>
- <date>2007-07-02</date>
- <time>08:26:04</time>
+ <date>2008-04-04</date>
+ <time>15:57:23</time>
<version>
- <release>1.5.4</release>
+ <release>1.6.1</release>
<api>1.5.0</api>
</version>
<stability>
@@ -64,76 +64,80 @@
<api>stable</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
- <notes>* Fixed Bug #11499: Redundant parameter in Auth_Container_SOAP5::_validateOptions()
- definition. Thanks to Koles Mihaly for spotting this.</notes>
+ <notes>* Actually included the new NetVPOPMaild container file.
+ *mutter*grumble*stupid package.xml*grumble*mutter*
+* Fix Bug #13578: Parse errors in DB Containers</notes>
<contents>
<dir name="/">
- <file baseinstalldir="" md5sum="d5dadb24a381f9553804292ab4f9a9a3" name="Auth/Anonymous.php" role="php">
+ <file baseinstalldir="" md5sum="7ddc0ffcb8b92481e3167da27f3e2996" name="Auth/Anonymous.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
<file baseinstalldir="" md5sum="3db4bed05ee42a45064360c185babcfc" name="Auth/Auth.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="" md5sum="5bfdf80905a4165f77acaecc051b29d6" name="Auth/Controller.php" role="php">
+ <file baseinstalldir="" md5sum="4cd779a507fd8a196f5c40fdc8ac2321" name="Auth/Controller.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="8a7011bc5fcee3114fef65dd5d7f7bcf" name="Container/Array.php" role="php">
+ <file baseinstalldir="Auth" md5sum="425ad2bfe23c78222e067260bba148c9" name="Container/Array.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="7f025acaa24ad3914e5fb14859719af7" name="Container/DB.php" role="php">
+ <file baseinstalldir="Auth" md5sum="f65dbd589c96909e015adbb5e84c816b" name="Container/DB.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="b05988a276632fed042a1b76ab4d0362" name="Container/DBLite.php" role="php">
+ <file baseinstalldir="Auth" md5sum="c4d18739394aa954b957a3c3b217a6be" name="Container/DBLite.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="5527518bf9cf08acae58d1b403b2ef52" name="Container/File.php" role="php">
+ <file baseinstalldir="Auth" md5sum="ec960928f512703c94b3a5a443699431" name="Container/File.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="b57dc0e5fc5d81bf5acbaf28eeef9113" name="Container/IMAP.php" role="php">
+ <file baseinstalldir="Auth" md5sum="71c4887d6077628a0c8ab2ae23b1dd2b" name="Container/IMAP.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="85ae331e0b57a56406a89ede85779a5e" name="Container/KADM5.php" role="php">
+ <file baseinstalldir="Auth" md5sum="71928f157342e34eaa8a873ed389a502" name="Container/KADM5.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="3cf0804d7822111194fc903995055414" name="Container/LDAP.php" role="php">
+ <file baseinstalldir="Auth" md5sum="51ce4915d7f0b740539703260388f8e7" name="Container/LDAP.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="4969b3e917b5188784808890e0154935" name="Container/MDB.php" role="php">
+ <file baseinstalldir="Auth" md5sum="36c94238dbf7fb795ed454e04667c47b" name="Container/MDB.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="2465e0ffc80c8dfcbc6ad6e918e3871c" name="Container/MDB2.php" role="php">
+ <file baseinstalldir="Auth" md5sum="201ce32581bb1b4071ed8aa5cdf7599b" name="Container/MDB2.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="31971bef4aee44c017f6404dd4d29ec4" name="Container/Multiple.php" role="php">
+ <file baseinstalldir="Auth" md5sum="75d308e264d4cbc2060b5600762d37ff" name="Container/Multiple.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="eeb27cc12acd33036bc361d4863f661a" name="Container/PEAR.php" role="php">
+ <file baseinstalldir="Auth" md5sum="e926c315a6e8d8e9b6a199f16b423bcd" name="Container/PEAR.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="21a87cad1f8ad3ab2d725ca7a56e9d41" name="Container/POP3.php" role="php">
+ <file baseinstalldir="Auth" md5sum="42aa53e04e98ccd3595e102d5ab375c1" name="Container/POP3.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="e87dfe6768ee87d23932246b3dfb8f87" name="Container/RADIUS.php" role="php">
+ <file baseinstalldir="Auth" md5sum="b1335e1986b737436445295cf5f32a4a" name="Container/RADIUS.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="1863e3006f43b362157b507993be15a8" name="Container/SAP.php" role="php">
+ <file baseinstalldir="Auth" md5sum="4728846b74290332eceee0502b17a055" name="Container/SAP.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="32e71953ed17de0858318845b95f8390" name="Container/SMBPasswd.php" role="php">
+ <file baseinstalldir="Auth" md5sum="22b8425b8dee653e415498815eca3986" name="Container/SMBPasswd.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="4b22221f687165c4abfc74ab8692eaf7" name="Container/SOAP.php" role="php">
+ <file baseinstalldir="Auth" md5sum="850962e77d4d2b07eca687a685200c78" name="Container/SOAP.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="39ef97eed47f6f6c14d3a7da9a3cbb14" name="Container/SOAP5.php" role="php">
+ <file baseinstalldir="Auth" md5sum="70c6c480ea673bc1e06aed12c312f869" name="Container/SOAP5.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="5b184743c25b85772fa74fed0cdfbc9b" name="Container/vpopmail.php" role="php">
+ <file baseinstalldir="Auth" md5sum="d3278589849381774ab0057daae4404c" name="Container/vpopmail.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="06bfa8cfc730ae344dddfb674bb62aba" name="Frontend/Html.php" role="php">
+ <file baseinstalldir="Auth" md5sum="a14679c2f26af6708b3de87320c92ccd" name="Container/NetVPOPMaild.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
+ <file baseinstalldir="Auth" md5sum="970cb92d4da66781cfd2aca6d171f3ff" name="Frontend/Html.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
<file baseinstalldir="Auth" md5sum="6d03025f455869185b57b5c138fd1c01" name="Frontend/md5.js" role="php" />
<file baseinstalldir="Auth" md5sum="b60c8b083eb08119d88089db53ee2ede" name="tests/auth_container_db_options.php" role="test" />
<file baseinstalldir="Auth" md5sum="907193304f6f6d0a03321a344d81a8a8" name="tests/auth_container_file_options.php" role="test" />
@@ -155,10 +159,10 @@
<file baseinstalldir="Auth" md5sum="7a5ca7c595123a06d18543b803355158" name="tests/bug8735.phpt" role="test" />
<file baseinstalldir="Auth" md5sum="797b51ba0f58858ab014771aa1b26fd6" name="examples/logging.php" role="doc" />
<file baseinstalldir="Auth" md5sum="c0234bbeeb10e24cdb6f64272e5e9831" name="examples/multi-container.php" role="doc" />
- <file baseinstalldir="" md5sum="5819d31ca7fef8f7349c43dc03d133fc" name="Auth.php" role="php">
+ <file baseinstalldir="" md5sum="289fa024b2d1eda68b7b1b0c9f877493" name="Auth.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
- <file baseinstalldir="Auth" md5sum="e0de203b0ea54c46d3601d55c058273c" name="Container.php" role="php">
+ <file baseinstalldir="Auth" md5sum="b1dc665b8f34b2c0743b8065f0afedbf" name="Container.php" role="php">
<tasks:replace from="@package_version@" to="version" type="package-info" />
</file>
<file baseinstalldir="Auth" md5sum="f5632fbe6d758b2da9af3f54485d0398" name="README.Auth" role="doc" />
@@ -229,6 +233,11 @@
<min>0.9.0</min>
</package>
<package>
+ <name>Net_Vpopmaild</name>
+ <channel>pear.php.net</channel>
+ <min>0.1.0</min>
+ </package>
+ <package>
<name>vpopmail</name>
<channel>pecl.php.net</channel>
<min>0.2</min>
@@ -254,9 +263,51 @@
<phprelease />
<changelog>
<release>
+ <date>2008-04-04</date>
+ <time>10:35:00</time>
+ <version>
+ <release>1.6.0</release>
+ <api>1.5.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.php.net/license">PHP License</license>
+ <notes>* Fixed Bug #12112: Advanced Security Cookie has different settings to
+ session cookie.
+* Implemented Request #13337: New vpopmail container utilising Net_Vpopmaild.
+ Patch supplied by Bill Shupp (shupp)
+* Implemented Request #13418: Karma support for PEAR Container. Patch supplied
+ by Christian Weiske (cweiske).
+* Added correct debug message for when no login has occured instead of session
+ storage not found.
+* Implemented Request #12061: Auto Quote handle database schema changes. ie
+ schema.tableName -> "schema"."tableName"
+* Implemented Request #12087: Ability to select which Advanced Security options
+ are used.
+* Fixed Doc Bug #12156: Correction to doc page for Auth::setSessionName() by
+ Adam Harvey (aharvey)</notes>
+ </release>
+ <release>
<date>2007-07-02</date>
<time>10:35:00</time>
<version>
+ <release>1.5.4</release>
+ <api>1.5.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.php.net/license">PHP License</license>
+ <notes>* Fixed Bug #11499: Redundant parameter in Auth_Container_SOAP5::_validateOptions()
+ definition. Thanks to Koles Mihaly for spotting this.</notes>
+ </release>
+ <release>
+ <date>2007-07-02</date>
+ <time>10:35:00</time>
+ <version>
<release>1.5.3</release>
<api>1.5.0</api>
</version>
More information about the Pkg-php-commits
mailing list