source: trunk/lib/Auth_File.inc.php @ 67

Last change on this file since 67 was 67, checked in by scdev, 18 years ago

Fixed authenticate method in Auth_File

File size: 7.5 KB
Line 
1<?php
2/**
3 * The Auth_File:: class provides a htpasswd file implementation for
4 * authentication.
5 *
6 * @author  Quinn Comendant <quinn@strangecode.com>
7 * @version 1.1
8 */
9
10// Available encryption types for class Auth_SQL.
11define('AUTH_ENCRYPT_MD5', 'md5');
12define('AUTH_ENCRYPT_CRYPT', 'crypt');
13define('AUTH_ENCRYPT_SHA1', 'sha1');
14define('AUTH_ENCRYPT_PLAINTEXT', 'plaintext');
15
16class Auth_File {
17
18    var $_params = array(
19        'encryption_type' => AUTH_ENCRYPT_CRYPT,
20        'htpasswd_file' => null,
21        'login_timeout' => 21600, // 6 hours.
22        'idle_timeout' => 3600, // 1 hour.
23        'login_url' => '/login.php',
24    );
25    var $_users = array();
26
27    /**
28     * Constructs a new htpasswd authentication object.
29     *
30     * @access public
31     *
32     * @param optional array $params  A hash containing parameters.
33     */
34    function Auth_File($params = array())
35    {
36        $this->_params = array_merge($this->_params, $params);
37
38        if (!empty($this->_params['htpasswd_file'])) {
39            if (false === ($users = file($this->_params['htpasswd_file']))) {
40                App::logMsg(sprintf(_("Could not read htpasswd file: %s"), $this->_params['htpasswd_file']), LOG_ERR, __FILE__, __LINE__);
41            }
42            if (is_array($users)) {
43                foreach ($users as $line) {
44                    list($user, $pass) = explode(':', $line, 2);
45                    $this->_users[trim($user)] = trim($pass);
46                }
47            }
48        }
49    }
50
51    /**
52     * Set the params of an auth object.
53     *
54     * @param  array $params   Array of parameter keys and value to set.
55     * @return bool true on success, false on failure
56     */
57    function setParam($params)
58    {
59        if (isset($params) && is_array($params)) {
60            // Merge new parameters with old overriding only those passed.
61            $this->_params = array_merge($this->_params, $params);
62        }
63    }
64
65    /**
66     * Return the value of a parameter, if it exists.
67     *
68     * @access public
69     * @param string $param        Which parameter to return.
70     * @return mixed               Configured parameter value.
71     */
72    function getParam($param)
73    {
74        if (isset($this->_params[$param])) {
75            return $this->_params[$param];
76        } else {
77            App::logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
78            return null;
79        }
80    }
81
82    /**
83     * Clear any authentication tokens in the current session. A.K.A. logout.
84     *
85     * @access public
86     */
87    function clearAuth()
88    {
89        $_SESSION['_auth_file'] = array('authenticated' => false);
90    }
91
92    /**
93     * Find out if a set of login credentials are valid. Only supports
94     * htpasswd files with DES passwords right now.
95     *
96     * @access public
97     *
98     * @param string $username      The username to check.
99     * @param array $password      The password to compare to username.
100     *
101     * @return boolean  Whether or not the credentials are valid.
102     */
103    function authenticate($username, $password)
104    {
105        if ('' == trim($password)) {
106            App::logMsg(_("No password provided for htpasswd authentication."), LOG_INFO, __FILE__, __LINE__);
107            return false;
108        }
109
110        if (!isset($this->_users[$username])) {
111            App::logMsg(_("User ID provided does not exist."), LOG_INFO, __FILE__, __LINE__);
112            return false;
113        }
114
115        if ($this->_encrypt($password, $this->_users[$username]) == $this->_users[$username]) {
116            return true;
117        } else {
118            App::logMsg(sprintf('Authentication failed for user %s', $username), LOG_INFO, __FILE__, __LINE__);
119            return false;
120        }
121    }
122
123    /**
124     * If user passes authentication create authenticated session.
125     *
126     * @access public
127     *
128     * @param string $username     The username to check.
129     * @param array $password     The password to compare to username.
130     *
131     * @return boolean  Whether or not the credentials are valid.
132     */
133    function login($username, $password)
134    {
135        $username = strtolower(trim($username));
136
137        $this->clearAuth();
138
139        if ($this->authenticate($username, $password)) {
140            $_SESSION['_auth_file'] = array(
141                'authenticated' => true,
142                'username' => $username,
143                'login_datetime' => date('Y-m-d H:i:s'),
144                'last_access_datetime' => date('Y-m-d H:i:s'),
145                'remote_addr' => getRemoteAddr()
146            );
147            return true;
148        }
149        return false;
150    }
151
152    /**
153     * Test if user has a currently logged-in session.
154     *  - authentication flag set to true
155     *  - username not empty
156     *  - total logged-in time is not greater than login_timeout
157     *  - idle time is not greater than idle_timeout
158     *  - remote address is the same as the login remote address.
159     *
160     * @access public
161     */
162    function isLoggedIn()
163    {
164        if (isset($_SESSION['_auth_file'])) {
165            if (true === $_SESSION['_auth_file']['authenticated']
166            && !empty($_SESSION['_auth_file']['username'])
167            && strtotime($_SESSION['_auth_file']['login_datetime']) > time() - $this->_params['login_timeout']
168            && strtotime($_SESSION['_auth_file']['last_access_datetime']) > time() - $this->_params['idle_timeout']
169            && $_SESSION['_auth_file']['remote_addr'] == getRemoteAddr()
170            ) {
171                $_SESSION['_auth_file']['last_access_datetime'] = date('Y-m-d H:i:s');
172                return true;
173            } else if (true === $_SESSION['_auth_file']['authenticated']) {
174                App::raiseMsg(_("Your session has closed. You need to log-in again."), MSG_NOTICE, __FILE__, __LINE__);
175                $this->clearAuth();
176                return false;
177            }
178        }
179        return false;
180    }
181
182    /**
183     * Redirect user to login page if they are not logged in.
184     *
185     * @param string $message The text description of a message to raise.
186     * @param int    $type    The type of message: MSG_NOTICE,
187     *                        MSG_SUCCESS, MSG_WARNING, or MSG_ERR.
188     * @param string $file    __FILE__.
189     * @param string $line    __LINE__.
190     * @access public
191     */
192    function requireLogin($message='', $type=MSG_NOTICE, $file=null, $line=null)
193    {
194        if (!$this->isLoggedIn()) {
195            // Display message for requiring login.
196            App::raiseMsg($message, $type, $file, $line);
197
198            // Login scripts must have the same 'login' tag for boomerangURL verification/manipulation.
199            App::setBoomerangURL(absoluteMe(), 'login');
200            App::dieURL($this->_params['login_url']);
201        }
202    }
203
204    /**
205     * Hash a given password according to the configured encryption
206     * type.
207     *
208     * @param string $password              The password to encrypt.
209     * @param string $encrypted_password    The currently encrypted password to use as salt, if needed.
210     *
211     * @return string  The hashed password.
212     */
213    function _encrypt($password, $encrypted_password=null)
214    {
215        switch ($this->_params['encryption_type']) {
216        case AUTH_ENCRYPT_PLAINTEXT :
217            return $password;
218            break;
219
220        case AUTH_ENCRYPT_SHA1 :
221            return sha1($password);
222            break;
223
224        case AUTH_ENCRYPT_MD5 :
225            return md5($password);
226            break;
227
228        case AUTH_ENCRYPT_CRYPT :
229        default :
230            return crypt($password, $encrypted_password);
231            break;
232        }
233    }
234
235} // end class
236?>
Note: See TracBrowser for help on using the repository browser.