source: branches/1.1dev/lib/AuthFile.inc.php

Last change on this file was 708, checked in by anonymous, 4 years ago

Update class constructor method names to construct

File size: 6.4 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 * @inspiration  Horde's Auth class <www.horde.org>
8 * @version 1.0
9 */
10class AuthFile {
11
12    var $_params = array();
13    var $_users = array();
14    var $login_timeout = 21600; // 6 hours
15    var $idle_timeout = 3600; // 1 hour
16
17    /**
18     * Constructs a new htpasswd authentication object.
19     *
20     * @access public
21     *
22     * @param optional array $params  A hash containing parameters.
23     */
24    function __construct($params = array())
25    {
26        $this->_params = $params;
27        setDefault($this->_params['htpasswd_file'], CODE_BASE . '/config/ht_auth');
28        setDefault($this->_params['encryption_type'], 'des');
29
30        if (!empty($this->_params['htpasswd_file'])) {
31            if (false === ($users = @file($this->_params['htpasswd_file']))) {
32                logMsg(sprintf(_("Could not read htpasswd file: %s"), $this->_params['htpasswd_file']), LOG_ERR, __FILE__, __LINE__);
33            }
34            if (is_array($users)) {
35                foreach ($users as $line) {
36                    list($user, $pass) = explode(':', $line, 2);
37                    $this->_users[trim($user)] = trim($pass);
38                }
39            }
40        }
41    }
42
43    /**
44     * Find out if a set of login credentials are valid. Only supports
45     * htpasswd files with DES passwords right now.
46     *
47     * @access private
48     *
49     * @param string $user_id      The user_id to check.
50     * @param array $password      The password to compare to user_id.
51     *
52     * @return boolean  Whether or not the credentials are valid.
53     */
54    function authenticate($user_id, $password)
55    {
56        if (empty($password)) {
57            logMsg(_("No password provided for htpasswd authentication."), LOG_NOTICE, __FILE__, __LINE__);
58            return false;
59        }
60
61        if (empty($this->_users[$user_id])) {
62            logMsg(_("User ID provided does not exist."), LOG_NOTICE, __FILE__, __LINE__);
63            return false;
64        }
65
66        $hash = $this->_encrypt($password, $this->_salt($user_id));
67        if ($hash == $this->_users[$user_id]) {
68            return true;
69        } else {
70            logMsg(_("Provided password hash does not match stored hash."), LOG_NOTICE, __FILE__, __LINE__);
71            return false;
72        }
73    }
74
75    /**
76     * If user passes authentication create authenticated session.
77     *
78     * @access private
79     *
80     * @param string $user_id     The user_id to check.
81     * @param array $password     The password to compare to user_id.
82     *
83     * @return boolean  Whether or not the credentials are valid.
84     */
85    function login($user_id, $password)
86    {
87        $user_id = trim($user_id);
88       
89        $this->clearAuth();
90
91        if ($this->authenticate($user_id, $password)) {
92            $_SESSION['_auth'] = array(
93                'authenticated' => true,
94                'user_id' => $user_id,
95                'user_type' => 'admin',
96                'priv' => 'editor',
97                'login_datetime' => date('Y-m-d H:i:s'),
98                'last_access_datetime' => date('Y-m-d H:i:s'),
99                'remote_addr' => getRemoteAddr()
100            );
101            return true;
102        }
103        return false;
104    }
105
106    /**
107     * Clear any authentication tokens in the current session. A.K.A. logout.
108     *
109     * @access public
110     */
111    function clearAuth()
112    {
113        $_SESSION['_auth'] = array();
114        $_SESSION['_auth']['authenticated'] = false;
115    }
116
117    /**
118     * Test if user has a currently logged-in session.
119     *  - authentication flag set to true
120     *  - user_id not empty
121     *  - total logged-in time is not greater than login_timeout
122     *  - idle time is not greater than idle_timeout
123     *  - remote address is the same as the login remote address.
124     *
125     * @access public
126     */
127    function isLoggedIn()
128    {
129        if (isset($_SESSION['_auth'])) {
130            if (true === $_SESSION['_auth']['authenticated']
131            && !empty($_SESSION['_auth']['user_id'])
132            && strtotime($_SESSION['_auth']['login_datetime']) > time() - $this->login_timeout
133            && strtotime($_SESSION['_auth']['last_access_datetime']) > time() - $this->idle_timeout
134            && $_SESSION['_auth']['remote_addr'] == getRemoteAddr()
135            ) {
136                $_SESSION['_auth']['last_access_datetime'] = date('Y-m-d H:i:s');
137                return true;
138            } else if (true === $_SESSION['_auth']['authenticated']) {
139                raiseMsg(_("Your session has closed. You need to log-in again."), MSG_NOTICE, __FILE__, __LINE__);
140                $this->clearAuth();
141            }
142        }
143        return false;
144    }
145
146    /**
147     * Test if user is of user_type 'admin'.
148     *
149     * @access public
150     */
151    function isAdmin()
152    {
153        if ($_SESSION['_auth']['user_type'] == 'admin') {
154            return true;
155        }
156        return false;
157    }
158
159    /**
160     * Redirect user to login page if they are not logged in.
161     *
162     * @access public
163     */
164    function requireAdminLogin()
165    {
166        if (!$this->isLoggedIn() || !$this->isAdmin()) {
167            setBoomerangURL(absoluteMe());
168            dieURL("$CFG->admin_url/login.php");
169        }
170    }
171
172    /**
173     * Hash a given password according to the configured encryption
174     * type.
175     *
176     * @param string $password  The password to encrypt.
177     * @param string $salt      The salt to use, if needed.
178     *
179     * @return string  The hashed password.
180     */
181    function _encrypt($password, $salt=null)
182    {
183        switch ($this->_params['encryption_type']) {
184        case 'des' :
185            if (isset($salt)) {
186                return crypt($password, $salt);
187            } else {
188                return crypt($password);
189            }
190            break;
191        default : 
192            logMsg('Encryption type not found.', LOG_ERR, __FILE__, __LINE__);
193        }
194
195        return false;
196    }
197
198    /**
199     * Get a salt for $user_id, or generate a new one.
200     *
201     * @return string  The salt.
202     */
203    function _salt($user_id)
204    {
205        switch ($this->_params['encryption_type']) {
206        case 'des':
207            if (!empty($this->_users[$user_id])) {
208                return substr($this->_users[$user_id], 0, 2);
209            }
210            break;
211        default : 
212            logMsg('Encryption type not found.', LOG_ERR, __FILE__, __LINE__);
213        }
214
215        return '';
216    }
217
218}
219?>
Note: See TracBrowser for help on using the repository browser.