Project

General

Profile

1
<?php
2
/**
3
 *
4
 * @category        framework
5
 * @package         backend login
6
 * @author          Ryan Djurovich (2004-2009), WebsiteBaker Project
7
 * @copyright       2009-2012, WebsiteBaker Org. e.V.
8
 * @link			http://www.websitebaker2.org/
9
 * @license         http://www.gnu.org/licenses/gpl.html
10
 * @platform        WebsiteBaker 2.8.x
11
 * @requirements    PHP 5.2.2 and higher
12
 * @version         $Id: class.Login.php 2125 2015-06-17 18:42:26Z darkviper $
13
 * @filesource		$HeadURL: svn://isteam.dynxs.de/wb-archiv/branches/2.8.x/wb/framework/class.Login.php $
14
 * @lastmodified    $Date: 2015-06-17 20:42:26 +0200 (Wed, 17 Jun 2015) $
15
 *
16
 */
17
define('LOGIN_CLASS_LOADED', true);
18

    
19
// Get WB version
20
require_once(ADMIN_PATH.'/interface/version.php');
21

    
22
class Login extends admin {
23

    
24
    const PASS_CHARS = '\w!#$%&*+\-.:=?@\|';
25
    const USER_CHARS = 'a-z0-9&\-.=@_';
26

    
27
    protected $oReg    = null;
28
    protected $oDb     = null;
29
    protected $oTrans  = null;
30
    protected $message = '';
31

    
32
    public function __construct($config_array)
33
    {
34
        $this->oReg   = WbAdaptor::getInstance();
35
        $this->oDb    = $this->oReg->Db;
36
        $this->oTrans = $this->oReg->Trans;
37

    
38
        parent::__construct();
39
    // Get configuration values
40
        while(list($key, $value) = each($config_array)) {
41
            $this->{(strtolower($key))} = $value;
42
        }
43
    // calculate redirect URL
44
        if(!isset($this->redirect_url)) { $this->redirect_url = ''; }
45
        $aServerUrl = $this->mb_parse_url($this->oReg->AppUrl);
46
        $sServerUrl = $_SERVER['SERVER_NAME'];
47
        $sServerScheme =
48
            isset($_SERVER['REQUEST_SCHEME'])
49
            ? $_SERVER['REQUEST_SCHEME']
50
            : isset($aServerUrl['scheme']) ? $aServerUrl['scheme'] : ' http';
51
        $sServerPath = $_SERVER['SCRIPT_NAME'];
52
        // If the url is blank, set it to the default url
53
        $this->url = $this->get_post('url');
54
        if (preg_match('/%0d|%0a|\s/i', $this->url)) {
55
            throw new Exception('Warning: possible intruder detected on login');
56
        }
57
        $aUrl = $this->mb_parse_url( $this->url );
58
        $this->url =
59
            isset($aRedirecthUrl['host']) &&($sServerUrl == $aUrl['host'])
60
            ? $this->url
61
            : $this->oReg->AcpUrl.'start/index.php';
62
        if ($this->redirect_url!='') {
63
            $aRedirecthUrl = $this->mb_parse_url( $this->redirect_url );
64
            $this->redirect_url =
65
                isset($aRedirecthUrl['host']) &&($sServerUrl==$aRedirecthUrl['host'])
66
                ? $this->redirect_url
67
                : $sServerScheme.'://'.$sServerUrl;
68
            $this->url = $this->redirect_url;
69
        }
70
        if(strlen($this->url) < 2) {
71
            $aDefaultUrl = $this->mb_parse_url( $this->default_url );
72
            $this->default_url =
73
                isset($aDefaultUrl['host']) &&($sServerUrl==$aDefaultUrl['host'])
74
                ? $this->default_url
75
                : $sServerScheme.'://'.$sServerUrl;
76
            $this->url = $this->default_url;
77
        }
78
    // get username & password and validate it
79
        $username_fieldname = (string)$this->get_post('username_fieldname');
80
        $username_fieldname = (preg_match('/^_?[a-z][\w]+$/i', $username_fieldname) ? $username_fieldname : 'username');
81
        $sUsername = strtolower(trim((string)$this->get_post($username_fieldname)));
82
        $this->username = (preg_match(
83
            '/^['.self::USER_CHARS.']{'.$this->min_username_len.','.$this->max_username_len.'}$/is',
84
            $sUsername
85
        ) ? $sUsername : '');
86
        $password_fieldname = (string)$this->get_post('password_fieldname');
87
        $password_fieldname = (preg_match('/^_?[a-z][\w]+$/i', $password_fieldname) ? $password_fieldname : 'password');
88

    
89
        if ($this->username) {
90
/** @TODO implement crypting */
91
            $this->password = md5(trim((string)$this->get_post($password_fieldname)));
92
            // Figure out if the "remember me" option has been checked
93
            $this->remember = (@$_POST['remember'] == 'true' ? true : false);
94
        // try to authenticate
95
            $bSuccess = false;
96
            if (!($bSuccess = $this->is_authenticated())) {
97
                if ($this->is_remembered()) {
98
                    $sql = 'SELECT * FROM `'.$this->oDb->TablePrefix.'users` '
99
                         . 'WHERE `user_id`='.$this->get_safe_remember_key();
100
                    if (($oUsers = $this->oDb->doQuery($sql))) {
101
                        if (($aUser = $oUsers->fetchArray())) {
102
                            $this->username = $aUser['username'];
103
                            $this->password = $aUser['password'];
104
                            // Check if the user exists (authenticate them)
105
                            $bSuccess = $this->authenticate();
106
                        }
107
                    }
108
                } else {
109
                    // Check if the user exists (authenticate them)
110
                    $bSuccess = $this->authenticate();
111
                }
112
            }
113
            if ($bSuccess) {
114
                // Authentication successful
115
                $this->send_header($this->url);
116
            } else {
117
                $this->message = $this->oTrans->MESSAGE_LOGIN_AUTHENTICATION_FAILED;
118
                $this->increase_attemps();
119
            }
120
        } else {
121
            $this->display_login();
122
        }
123
    }
124

    
125
    // Authenticate the user (check if they exist in the database)
126
    function authenticate()
127
    {
128
        // Get user information
129
        $loginname = ( preg_match('/^['.self::USER_CHARS.']+$/s',$this->username) ? $this->username : '0');
130
        $aSettings = array();
131
        $aSettings['SYSTEM_PERMISSIONS']   = array();
132
        $aSettings['MODULE_PERMISSIONS']   = array();
133
        $aSettings['TEMPLATE_PERMISSIONS'] = array();
134
        $bRetval = false;
135

    
136
        $sql = 'SELECT * FROM `'.$this->oDb->TablePrefix.'users` '
137
             . 'WHERE `username`=\''.$this->oDb->escapeString($loginname).'\'';
138
        if (($oUser = $this->oDb->doQuery($sql))) {
139
            if (($aUser = $oUser->fetchArray())) {
140
                if (
141
                    $aUser['password'] == $this->password &&
142
                    $aUser['active'] == 1
143
                ) {
144
                // valide authentcation !!
145
                    $user_id                   = $aUser['user_id'];
146
                    $this->user_id             = $user_id;
147
                    $aSettings['USER_ID']      = $user_id;
148
                    $aSettings['GROUP_ID']     = $aUser['group_id'];
149
                    $aSettings['GROUPS_ID']    = $aUser['groups_id'];
150
                    $aSettings['USERNAME']     = $aUser['username'];
151
                    $aSettings['DISPLAY_NAME'] = $aUser['display_name'];
152
                    $aSettings['EMAIL']        = $aUser['email'];
153
                    $aSettings['HOME_FOLDER']  = $aUser['home_folder'];
154
                    // Run remember function if needed
155
                    if($this->remember == true) {
156
                        $this->remember($this->user_id);
157
                    }
158
                    // Set language
159
                    if($aUser['language'] != '') {
160
                        $aSettings['LANGUAGE'] = $aUser['language'];
161
                    }
162
                    // Set timezone
163
                    if($aUser['timezone'] != '-72000') {
164
                        $aSettings['TIMEZONE'] = $aUser['timezone'];
165
                    } else {
166
                        // Set a session var so apps can tell user is using default tz
167
                        $aSettings['USE_DEFAULT_TIMEZONE'] = true;
168
                    }
169
                    // Set date format
170
                    if($aUser['date_format'] != '') {
171
                        $aSettings['DATE_FORMAT'] = $aUser['date_format'];
172
                    } else {
173
                        // Set a session var so apps can tell user is using default date format
174
                        $aSettings['USE_DEFAULT_DATE_FORMAT'] = true;
175
                    }
176
                    // Set time format
177
                    if($aUser['time_format'] != '') {
178
                        $aSettings['TIME_FORMAT'] = $aUser['time_format'];
179
                    } else {
180
                        // Set a session var so apps can tell user is using default time format
181
                        $aSettings['USE_DEFAULT_TIME_FORMAT'] = true;
182
                    }
183
                    // Get group information
184
                    $aSettings['GROUP_NAME'] = array();
185
                    $bOnlyAdminGroup = $this->ami_group_member('1') && (sizeof($aGroupsIds) == 1);
186
                    $sql = 'SELECT * FROM `'.$this->oDb->TablePrefix.'groups` '
187
                         . 'WHERE `group_id` IN (\''.$aUser['groups_id'].',0\') '
188
                         . 'ORDER BY `group_id`';
189
                    if (($oGroups = $this->oDb->doQuery($sql))) {
190
                        while (($aGroup = $oGroups->fetchArray())) {
191
                            $aSettings['GROUP_NAME'][$aGroup['group_id']] = $aGroup['name'];
192
                        // collect system_permissions (additively)
193
                            $aSettings['SYSTEM_PERMISSIONS'] = array_merge(
194
                                $aSettings['SYSTEM_PERMISSIONS'],
195
                                explode(',', $aGroup['system_permissions'])
196
                            );
197
                        // collect module_permission (subtractive)
198
                            if (!sizeof($aSettings['MODULE_PERMISSIONS'])) {
199
                                $aSettings['MODULE_PERMISSIONS'] = explode(',', $aGroup['module_permissions']);
200
                            } else {
201
                                $aSettings['MODULE_PERMISSIONS'] = array_intersect(
202
                                    $aSettings['MODULE_PERMISSIONS'],
203
                                    preg_split('/\s*[,;\|\+]/', $aGroup['module_permissions'], -1, PREG_SPLIT_NO_EMPTY)
204
                                );
205
                            }
206
                        // collect template_permission (subtractive)
207
                            if (!sizeof($aSettings['TEMPLATE_PERMISSIONS'])) {
208
                                $aSettings['TEMPLATE_PERMISSIONS'] = explode(',', $aGroup['template_permissions']);
209
                            } else {
210
                                $aSettings['TEMPLATE_PERMISSIONS'] = array_intersect(
211
                                    $aSettings['TEMPLATE_PERMISSIONS'],
212
                                    preg_split('/\s*[,;\|\+]/', $aGroup['template_permissions'], -1, PREG_SPLIT_NO_EMPTY)
213
                                );
214
                            }
215
                        }
216
                    }
217
                    // Update the users table with current ip and timestamp
218
                    $sRemoteAddress = @$_SERVER['REMOTE_ADDR'] ?: 'unknown';
219
                    $sql = 'UPDATE `'.$this->oDb->TablePrefix.'users` '
220
                         . 'SET `login_when`='.time().', '
221
                         .     '`login_ip`=\''.$sRemoteAddress.'\' '
222
                         . 'WHERE `user_id`=\''.$user_id.'\'';
223
                    $this->oDb->doQuery($sql);
224
                    $bRetval = true;
225
                }
226
            }
227
        }
228
        // merge settings into $_SESSION and overwrite older one values
229
        $_SESSION = array_merge($_SESSION, $aSettings);
230
        // Return if the user exists or not
231
        return $bRetval;
232
    }
233

    
234
    // Increase the count for login attemps
235
    function increase_attemps()
236
    {
237
        $_SESSION['ATTEMPS'] = (isset($_SESSION['ATTEMPS']) ? $_SESSION['ATTEMPS']++ : 0);
238
        $this->display_login();
239
    }
240

    
241
    // Function to set a "remembering" cookie for the user - removed
242
    function remember($user_id)
243
    {
244
        return true;
245
    }
246

    
247
    // Function to check if a user has been remembered - removed
248
    function is_remembered()
249
    {
250
        return false;
251
    }
252

    
253
    // Display the login screen
254
    function display_login()
255
    {
256
        // If attemps more than allowed, warn the user
257
        if($this->get_session('ATTEMPS') > $this->max_attemps) {
258
            $this->warn();
259
        }
260
        // Show the login form
261
        if($this->frontend != true) {
262
            $template = new Template(dirname($this->correct_theme_source($this->template_file)));
263
            $template->set_file('page', $this->template_file);
264
            $template->set_block('page', 'mainBlock', 'main');
265
            $template->set_var('DISPLAY_REMEMBER_ME', ($this->remember_me_option ? '' : 'display: none;'));
266
            $template->set_var($this->oTrans->getLangArray());
267
            $template->set_var(
268
                array(
269
                    'TITLE_LOGOUT'           => $this->oTrans->MENU_LOGIN,
270
                    'TITLE_VIEW'             => $this->oTrans->TEXT_WEBSITE,
271
                    'SECTION_NAME'           => $this->oTrans->MENU_LOGIN,
272
                    'SECTION_LOGIN'          => $this->oTrans->MENU_LOGIN,
273
                    'ACTION_URL'             => $this->login_url,
274
                    'URL'                    => $this->default_url,
275
                    'ATTEMPS'                => $this->get_session('ATTEMPS'),
276
                    'USERNAME'               => $this->username,
277
                    'USERNAME_FIELDNAME'     => $this->username_fieldname,
278
                    'PASSWORD_FIELDNAME'     => $this->password_fieldname,
279
                    'MESSAGE'                => $this->message,
280
                    'WEBSITE_TITLE'          => $this->oReg->WebsiteTitle,
281
                    'INTERFACE_DIR_URL'      => $this->oReg->AcpUrl.'interface',
282
                    'MAX_USERNAME_LEN'       => $this->max_username_len,
283
                    'MAX_PASSWORD_LEN'       => $this->max_password_len,
284
                    'ADMIN_URL'              => $this->oReg->AcpUrl,
285
                    'WB_URL'                 => $this->oReg->AppUrl,
286
                    'URL_VIEW'               => $this->oReg->AppUrl,
287
                    'THEME_URL'              => $this->oReg->ThemeUrl,
288
                    'VERSION'                => $this->oReg->Version,
289
                    'SP'                     => (isset($this->oReg->Sp) ? $this->oReg->Sp : ''),
290
                    'REVISION'               => $this->oReg->Revision,
291
                    'LANGUAGE'               => strtolower($this->oReg->Language),
292
                    'FORGOTTEN_DETAILS_APP'  => $this->forgotten_details_app,
293
                    'PAGES_DIRECTORY'        => $this->oReg->PagesDir,
294
                    'LOGIN_DISPLAY_HIDDEN'   => !$this->is_authenticated() ? 'hidden' : '',
295
                    'LOGIN_DISPLAY_NONE'     => !$this->is_authenticated() ? 'none' : '',
296
                    'LOGIN_LINK'             => $_SERVER['SCRIPT_NAME'],
297
                    'LOGIN_ICON'             => 'login',
298
                    'START_ICON'             => 'blank',
299
                    'URL_HELP'               => 'http://wiki.websitebaker.org/',
300
                )
301
            );
302
            $template->set_var('CHARSET', (isset($this->oReg->DefaultCharset) ? $this->oReg->DefaultCharset : 'utf-8'));
303
            $template->parse('main', 'mainBlock', false);
304
            $template->pparse('output', 'page');
305
        }
306
    }
307
    // sanities the REMEMBER_KEY cookie to avoid SQL injection
308
    function get_safe_remember_key()
309
    {
310
        $iMatches = 0;
311
        if (isset($_COOKIE['REMEMBER_KEY'])) {
312
            $sRetval = preg_replace(
313
                '/^([0-9]{11})_([0-9a-f]{11})$/i',
314
                '\1\2',
315
                $_COOKIE['REMEMBER_KEY'], -1, $iMatches
316
            );
317
        }
318
        return ($iMatches ? $sRetval : '');
319
    }
320
    // Warn user that they have had to many login attemps
321
    function warn()
322
    {
323
        $this->send_header($this->warning_url);
324
        exit;
325
    }
326

    
327
}
(24-24/38)