Passed
Push — master ( 65bdac...4e88da )
by Alxarafe
32:38
created

Base/AlixarController.php (2 issues)

Checks if used types are correctly prefixed.

Bug Major
1
<?php
2
/* Copyright (C) 2019       Alxarafe                    <[email protected]>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
 */
17
namespace Alixar\Base;
18
19
use Alxarafe\Helpers\Debug;
20
use Alixar\Helpers\Globals;
21
use Alixar\Helpers\DolUtils;
22
use Alixar\Helpers\Security;
23
use Alixar\Helpers\Security2;
24
use Alixar\Helpers\DateLib;
25
use Alixar\Base\Interfaces;
26
use Alixar\Base\MenuManager;
27
28
/**
29
 * This class contains the methods and attributes common to all Alixar controllers
30
 *
31
 * @author Alxarafe
32
 */
33
class AlixarController extends \Alxarafe\Base\Controller
34
{
35
36
    public $authmode;
37
    public $dol_authmode;
38
39
    function __construct()
40
    {
41
        parent::__construct();
42
43
        $this->checkRequires();
44
45
        // Include the conf.php and functions.lib.php
46
        // require_once DOL_BASE_PATH . '/filefunc.inc.php';
47
        Globals::initGlobals();
48
49
        // Init session. Name of session is specific to Dolibarr instance.
50
        // Note: the function dol_getprefix may have been redefined to return a different key to manage another area to protect.
51
        $prefix = DolUtils::dol_getprefix('');
52
53
        $sessionname = 'DOLSESSID_' . $prefix;
54
        $sessiontimeout = 'DOLSESSTIMEOUT_' . $prefix;
55
        if (!empty($_COOKIE[$sessiontimeout])) {
56
            ini_set('session.gc_maxlifetime', $_COOKIE[$sessiontimeout]);
57
        }
58
        session_name($sessionname);
59
        session_set_cookie_params(0, '/', null, false, true);   // Add tag httponly on session cookie (same as setting session.cookie_httponly into php.ini). Must be called before the session_start.
60
        // This create lock, released when session_write_close() or end of page.
61
        // We need this lock as long as we read/write $_SESSION ['vars']. We can remove lock when finished.
62
        if (!defined('NOSESSION')) {
63
            session_start();
64
            /* if (ini_get('register_globals'))    // Deprecated in 5.3 and removed in 5.4. To solve bug in using $_SESSION
65
              {
66
              foreach ($_SESSION as $key=>$value)
67
              {
68
              if (isset($GLOBALS[$key])) unset($GLOBALS[$key]);
69
              }
70
              } */
71
        }
72
73
// Init the 5 global objects, this include will make the new and set properties for: Globals::$conf, $db, Globals::$langs, Globals::$user, $mysoc
74
        //require_once 'master.inc.php';
75
// Activate end of page function
76
        //register_shutdown_function('dol_shutdown');
77
// Detection browser
78
        if (isset($_SERVER["HTTP_USER_AGENT"])) {
79
            $tmp = DolUtils::getBrowserInfo($_SERVER["HTTP_USER_AGENT"]);
80
            Globals::$conf->browser->name = $tmp['browsername'];
81
            Globals::$conf->browser->os = $tmp['browseros'];
82
            Globals::$conf->browser->version = $tmp['browserversion'];
83
            Globals::$conf->browser->layout = $tmp['layout'];     // 'classic', 'phone', 'tablet'
84
//var_dump(Globals::$conf->browser);
85
86
            if (Globals::$conf->browser->layout == 'phone') {
87
                Globals::$conf->dol_no_mouse_hover = 1;
88
            }
89
            if (Globals::$conf->browser->layout == 'phone') {
90
                Globals::$conf->global->MAIN_TESTMENUHIDER = 1;
91
            }
92
        }
93
94
// Force HTTPS if required (Globals::$conf->file->main_force_https is 0/1 or https dolibarr root url)
95
// $_SERVER["HTTPS"] is 'on' when link is https, otherwise $_SERVER["HTTPS"] is empty or 'off'
96
        if (!empty(Globals::$conf->file->main_force_https) && (empty($_SERVER["HTTPS"]) || $_SERVER["HTTPS"] != 'on')) {
97
            $newurl = '';
98
            if (is_numeric(Globals::$conf->file->main_force_https)) {
99
                if (Globals::$conf->file->main_force_https == '1' && !empty($_SERVER["SCRIPT_URI"])) { // If SCRIPT_URI supported by server
100
                    if (preg_match('/^http:/i', $_SERVER["SCRIPT_URI"]) && !preg_match('/^https:/i', $_SERVER["SCRIPT_URI"])) { // If link is http
101
                        $newurl = preg_replace('/^http:/i', 'https:', $_SERVER["SCRIPT_URI"]);
102
                    }
103
                } else { // Check HTTPS environment variable (Apache/mod_ssl only)
104
                    $newurl = preg_replace('/^http:/i', 'https:', DOL_MAIN_URL_ROOT) . $_SERVER["REQUEST_URI"];
105
                }
106
            } else {
107
// Check HTTPS environment variable (Apache/mod_ssl only)
108
                $newurl = Globals::$conf->file->main_force_https . $_SERVER["REQUEST_URI"];
109
            }
110
// Start redirect
111
            if ($newurl) {
112
                DolUtils::dol_syslog("main.inc: dolibarr_main_force_https is on, we make a redirect to " . $newurl);
113
                echo $newurl;
114
                throw Exception('x');
115
                header("Location: " . $newurl);
116
                exit;
117
            } else {
118
                DolUtils::dol_syslog("main.inc: dolibarr_main_force_https is on but we failed to forge new https url so no redirect is done", LOG_WARNING);
119
            }
120
        }
121
122
        if (!defined('NOLOGIN') && !defined('NOIPCHECK') && !empty($dolibarr_main_restrict_ip)) {
123
            $listofip = explode(',', $dolibarr_main_restrict_ip);
124
            $found = false;
125
            foreach ($listofip as $ip) {
126
                $ip = trim($ip);
127
                if ($ip == $_SERVER['REMOTE_ADDR']) {
128
                    $found = true;
129
                    break;
130
                }
131
            }
132
            if (!$found) {
133
                print 'Access refused by IP protection';
134
                exit;
135
            }
136
        }
137
138
// Loading of additional presentation includes
139
        if (!defined('NOREQUIREHTML')) {
140
            require_once DOL_BASE_PATH . '/core/class/html.form.class.php';     // Need 660ko memory (800ko in 2.2)
141
        }
142
        if (!defined('NOREQUIREAJAX') && Globals::$conf->use_javascript_ajax) {
143
            require_once DOL_BASE_PATH . '/core/lib/ajax.lib.php'; // Need 22ko memory
144
        }
145
// If install or upgrade process not done or not completely finished, we call the install page.
146
        if (!empty(Globals::$conf->global->MAIN_NOT_INSTALLED) || !empty(Globals::$conf->global->MAIN_NOT_UPGRADED)) {
147
            DolUtils::dol_syslog("main.inc: A previous install or upgrade was not complete. Redirect to install page.", LOG_WARNING);
148
            throw Exception('x');
149
            header("Location: " . DOL_BASE_URI . "/install/index.php");
150
            exit;
151
        }
152
// If an upgrade process is required, we call the install page.
153
        if ((!empty(Globals::$conf->global->MAIN_VERSION_LAST_UPGRADE) && (Globals::$conf->global->MAIN_VERSION_LAST_UPGRADE != DOL_VERSION)) || (empty(Globals::$conf->global->MAIN_VERSION_LAST_UPGRADE) && !empty(Globals::$conf->global->MAIN_VERSION_LAST_INSTALL) && (Globals::$conf->global->MAIN_VERSION_LAST_INSTALL != DOL_VERSION))) {
154
            $versiontocompare = empty(Globals::$conf->global->MAIN_VERSION_LAST_UPGRADE) ? Globals::$conf->global->MAIN_VERSION_LAST_INSTALL : Globals::$conf->global->MAIN_VERSION_LAST_UPGRADE;
155
            require_once DOL_BASE_PATH . '/core/lib/admin.lib.php';
156
            $dolibarrversionlastupgrade = preg_split('/[.-]/', $versiontocompare);
157
            $dolibarrversionprogram = preg_split('/[.-]/', DOL_VERSION);
158
            $rescomp = versioncompare($dolibarrversionprogram, $dolibarrversionlastupgrade);
159
            if ($rescomp > 0) {   // Programs have a version higher than database. We did not add "&& $rescomp < 3" because we want upgrade process for build upgrades
160
                DolUtils::dol_syslog("main.inc: database version " . $versiontocompare . " is lower than programs version " . DOL_VERSION . ". Redirect to install page.", LOG_WARNING);
161
                throw Exception('x');
162
                header("Location: " . DOL_BASE_URI . "/install/index.php");
163
                exit;
164
            }
165
        }
166
167
// Creation of a token against CSRF vulnerabilities
168
        if (!defined('NOTOKENRENEWAL')) {
169
// roulement des jetons car cree a chaque appel
170
            if (isset($_SESSION['newtoken'])) {
171
                $_SESSION['token'] = $_SESSION['newtoken'];
172
            }
173
174
// Save in $_SESSION['newtoken'] what will be next token. Into forms, we will add param token = $_SESSION['newtoken']
175
            $token = Security::dol_hash(uniqid(mt_rand(), true)); // Generates a hash of a random number
176
            $_SESSION['newtoken'] = $token;
177
        }
178
        if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && !empty(Globals::$conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN)) || defined('CSRFCHECK_WITH_TOKEN')) { // Check validity of token, only if option MAIN_SECURITY_CSRF_WITH_TOKEN enabled or if constant CSRFCHECK_WITH_TOKEN is set
179
            if ($_SERVER['REQUEST_METHOD'] == 'POST' && !DolUtils::GETPOST('token', 'alpha')) { // Note, offender can still send request by GET
180
                print "Access refused by CSRF protection in main.inc.php. Token not provided.\n";
181
                print "If you access your server behind a proxy using url rewriting, you might check that all HTTP header is propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file).\n";
182
                die;
183
            }
184
            if ($_SERVER['REQUEST_METHOD'] === 'POST') {  // This test must be after loading $_SESSION['token'].
185
                if (DolUtils::GETPOST('token', 'alpha') != $_SESSION['token']) {
186
                    DolUtils::dol_syslog("Invalid token in " . $_SERVER['HTTP_REFERER'] . ", action=" . DolUtils::GETPOST('action', 'aZ09') . ", _POST['token']=" . DolUtils::GETPOST('token', 'alpha') . ", _SESSION['token']=" . $_SESSION['token'], LOG_WARNING);
187
//print 'Unset POST by CSRF protection in main.inc.php.';	// Do not output anything because this create problems when using the BACK button on browsers.
188
                    unset($_POST);
189
                }
190
            }
191
        }
192
193
// Disable modules (this must be after session_start and after conf has been loaded)
194
        if (DolUtils::GETPOST('disablemodules', 'alpha')) {
195
            $_SESSION["disablemodules"] = DolUtils::GETPOST('disablemodules', 'alpha');
196
        }
197
        if (!empty($_SESSION["disablemodules"])) {
198
            $disabled_modules = explode(',', $_SESSION["disablemodules"]);
199
            foreach ($disabled_modules as $module) {
200
                if ($module) {
201
                    if (empty(Globals::$conf->$module)) {
202
                        Globals::$conf->$module = new stdClass();
0 ignored issues
show
The type Alixar\Base\stdClass was not found. Did you mean stdClass? If so, make sure to prefix the type with \.
Loading history...
203
                    }
204
                    Globals::$conf->$module->enabled = false;
205
                    if ($module == 'fournisseur') {  // Special case
206
                        Globals::$conf->supplier_order->enabled = 0;
207
                        Globals::$conf->supplier_invoice->enabled = 0;
208
                    }
209
                }
210
            }
211
        }
212
213
        /*
214
         * Phase authentication / login
215
         */
216
        $login = '';
217
        if (!defined('NOLOGIN')) {
218
// $authmode lists the different means of identification to be tested in order of preference.
219
// Example: 'http', 'dolibarr', 'ldap', 'http,forceuser', '...'
220
221
            if (defined('MAIN_AUTHENTICATION_MODE')) {
222
                $dolibarr_main_authentication = constant('MAIN_AUTHENTICATION_MODE');
223
            } else {
224
// Authentication mode
225
                if (empty($dolibarr_main_authentication)) {
226
                    $dolibarr_main_authentication = 'http,dolibarr';
227
                }
228
// Authentication mode: forceuser
229
                if ($dolibarr_main_authentication == 'forceuser' && empty($dolibarr_auto_user)) {
230
                    $dolibarr_auto_user = 'auto';
231
                }
232
            }
233
// Set authmode
234
            $this->authmode = explode(',', $dolibarr_main_authentication);
235
236
// No authentication mode
237
            if (!count($this->authmode)) {
238
                Globals::$langs->load('main');
239
                dol_print_error('', Globals::$langs->trans("ErrorConfigParameterNotDefined", 'dolibarr_main_authentication'));
240
                exit;
241
            }
242
243
// If login request was already post, we retrieve login from the session
244
// Call module if not realized that his request.
245
// At the end of this phase, the variable $login is defined.
246
            $resultFetchUser = '';
247
            $test = true;
248
            if (!isset($_SESSION["dol_login"])) {
249
// It is not already authenticated and it requests the login / password
250
                //include_once DOL_BASE_PATH . '/core/lib/security2.lib.php';
251
252
                $dol_dst_observed = DolUtils::GETPOST("dst_observed", 'int', 3);
253
                $dol_dst_first = DolUtils::GETPOST("dst_first", 'int', 3);
254
                $dol_dst_second = DolUtils::GETPOST("dst_second", 'int', 3);
255
                $dol_screenwidth = DolUtils::GETPOST("screenwidth", 'int', 3);
256
                $dol_screenheight = DolUtils::GETPOST("screenheight", 'int', 3);
257
                $dol_hide_topmenu = DolUtils::GETPOST('dol_hide_topmenu', 'int', 3);
258
                $dol_hide_leftmenu = DolUtils::GETPOST('dol_hide_leftmenu', 'int', 3);
259
                $dol_optimize_smallscreen = DolUtils::GETPOST('dol_optimize_smallscreen', 'int', 3);
260
                $dol_no_mouse_hover = DolUtils::GETPOST('dol_no_mouse_hover', 'int', 3);
261
                $dol_use_jmobile = DolUtils::GETPOST('dol_use_jmobile', 'int', 3);
262
//dol_syslog("POST key=".join(array_keys($_POST),',').' value='.join($_POST,','));
263
// If in demo mode, we check we go to home page through the public/demo/index.php page
264
                if (!empty($dolibarr_main_demo) && $_SERVER['PHP_SELF'] == DOL_BASE_URI . '/index.php') {  // We ask index page
265
                    if (empty($_SERVER['HTTP_REFERER']) || !preg_match('/public/', $_SERVER['HTTP_REFERER'])) {
266
                        DolUtils::dol_syslog("Call index page from another url than demo page (call is done from page " . $_SERVER['HTTP_REFERER'] . ")");
267
                        $url = '';
268
                        $url .= ($url ? '&' : '') . ($dol_hide_topmenu ? 'dol_hide_topmenu=' . $dol_hide_topmenu : '');
269
                        $url .= ($url ? '&' : '') . ($dol_hide_leftmenu ? 'dol_hide_leftmenu=' . $dol_hide_leftmenu : '');
270
                        $url .= ($url ? '&' : '') . ($dol_optimize_smallscreen ? 'dol_optimize_smallscreen=' . $dol_optimize_smallscreen : '');
271
                        $url .= ($url ? '&' : '') . ($dol_no_mouse_hover ? 'dol_no_mouse_hover=' . $dol_no_mouse_hover : '');
272
                        $url .= ($url ? '&' : '') . ($dol_use_jmobile ? 'dol_use_jmobile=' . $dol_use_jmobile : '');
273
                        $url = DOL_BASE_URI . '/public/demo/index.php' . ($url ? '?' . $url : '');
274
                        echo $url;
275
                        throw Exception('x');
276
                        header("Location: " . $url);
277
                        exit;
278
                    }
279
                }
280
281
// Verification security graphic code
282
                if (DolUtils::GETPOST("username", "alpha", 2) && !empty(Globals::$conf->global->MAIN_SECURITY_ENABLECAPTCHA)) {
283
                    $sessionkey = 'dol_antispam_value';
284
                    $ok = (array_key_exists($sessionkey, $_SESSION) === true && (strtolower($_SESSION[$sessionkey]) == strtolower($_POST['code'])));
285
286
// Check code
287
                    if (!$ok) {
288
                        DolUtils::dol_syslog('Bad value for code, connexion refused');
289
// Load translation files required by page
290
                        Globals::$langs->loadLangs(array('main', 'errors'));
291
292
                        $_SESSION["dol_loginmesg"] = Globals::$langs->trans("ErrorBadValueForCode");
293
                        $test = false;
294
295
// Call trigger for the "security events" log
296
                        Globals::$user->trigger_mesg = 'ErrorBadValueForCode - login=' . DolUtils::GETPOST("username", "alpha", 2);
297
// Call of triggers
298
                        //include_once DOL_BASE_PATH . '/core/class/interfaces.class.php';
299
                        $interface = new Interfaces($db);
300
                        $result = $interface->run_triggers('USER_LOGIN_FAILED', Globals::$user, Globals::$user, Globals::$langs, Globals::$conf);
301
                        if ($result < 0) {
302
                            $error++;
303
                        }
304
// End Call of triggers
305
// Hooks on failed login
306
                        $action = '';
307
                        Globals::$hookManager->initHooks(array('login'));
308
                        $parameters = array('dol_authmode' => $this->dol_authmode, 'dol_loginmesg' => $_SESSION["dol_loginmesg"]);
309
                        $reshook = Globals::$hookManager->executeHooks('afterLoginFailed', $parameters, Globals::$user, $action);    // Note that $action and $object may have been modified by some hooks
310
                        if ($reshook < 0)
311
                            $error++;
312
313
// Note: exit is done later
314
                    }
315
                }
316
317
                $allowedmethodtopostusername = 2;
318
                if (defined('MAIN_AUTHENTICATION_POST_METHOD')) {
319
                    $allowedmethodtopostusername = constant('MAIN_AUTHENTICATION_POST_METHOD');
320
                }
321
                $usertotest = (!empty($_COOKIE['login_dolibarr']) ? $_COOKIE['login_dolibarr'] : DolUtils::GETPOST("username", "alpha", $allowedmethodtopostusername));
322
                $passwordtotest = DolUtils::GETPOST('password', 'none', $allowedmethodtopostusername);
323
                $entitytotest = (DolUtils::GETPOST('entity', 'int') ? DolUtils::GETPOST('entity', 'int') : (!empty(Globals::$conf->entity) ? Globals::$conf->entity : 1));
324
325
// Define if we received data to test the login.
326
                $goontestloop = false;
327
                if (isset($_SERVER["REMOTE_USER"]) && in_array('http', $this->authmode)) {
328
                    $goontestloop = true;
329
                }
330
                if ($dolibarr_main_authentication == 'forceuser' && !empty($dolibarr_auto_user)) {
331
                    $goontestloop = true;
332
                }
333
                if (DolUtils::GETPOST("username", "alpha", $allowedmethodtopostusername) || !empty($_COOKIE['login_dolibarr']) || DolUtils::GETPOST('openid_mode', 'alpha', 1)) {
334
                    $goontestloop = true;
335
                }
336
337
                if (!is_object(Globals::$langs)) { // This can occurs when calling page with NOREQUIRETRAN defined, however we need langs for error messages.
338
                    // include_once DOL_BASE_PATH . '/core/class/translate.class.php';
339
                    Globals::$langs = new Translate("", Globals::$conf);
0 ignored issues
show
The type Alixar\Base\Translate was not found. Did you mean Translate? If so, make sure to prefix the type with \.
Loading history...
340
                    $langcode = (DolUtils::GETPOST('lang', 'aZ09', 1) ? DolUtils::GETPOST('lang', 'aZ09', 1) : (empty(Globals::$conf->global->MAIN_LANG_DEFAULT) ? 'auto' : Globals::$conf->global->MAIN_LANG_DEFAULT));
341
                    if (defined('MAIN_LANG_DEFAULT')) {
342
                        $langcode = constant('MAIN_LANG_DEFAULT');
343
                    }
344
                    Globals::$langs->setDefaultLang($langcode);
345
                }
346
347
// Validation of login/pass/entity
348
// If ok, the variable login will be returned
349
// If error, we will put error message in session under the name dol_loginmesg
350
                if ($test && $goontestloop) {
351
                    $login = Security2::checkLoginPassEntity($usertotest, $passwordtotest, $entitytotest, $this->authmode);
352
                    if ($login) {
353
                        $this->dol_authmode = Globals::$conf->authmode; // This properties is defined only when logged, to say what mode was successfully used
354
                        $dol_tz = $_POST["tz"];
355
                        $dol_tz_string = $_POST["tz_string"];
356
                        $dol_tz_string = preg_replace('/\s*\(.+\)$/', '', $dol_tz_string);
357
                        $dol_tz_string = preg_replace('/,/', '/', $dol_tz_string);
358
                        $dol_tz_string = preg_replace('/\s/', '_', $dol_tz_string);
359
                        $dol_dst = 0;
360
                        if (isset($_POST["dst_first"]) && isset($_POST["dst_second"])) {
361
                            // include_once DOL_BASE_PATH . '/core/lib/date.lib.php';
362
                            $datenow = DolUtils::dol_now();
363
                            $datefirst = DateLib::dol_stringtotime($_POST["dst_first"]);
364
                            $datesecond = DateLib::dol_stringtotime($_POST["dst_second"]);
365
                            if ($datenow >= $datefirst && $datenow < $datesecond) {
366
                                $dol_dst = 1;
367
                            }
368
                        }
369
//print $datefirst.'-'.$datesecond.'-'.$datenow.'-'.$dol_tz.'-'.$dol_tzstring.'-'.$dol_dst; exit;
370
                    }
371
372
                    if (!$login) {
373
                        DolUtils::dol_syslog('Bad password, connexion refused', LOG_DEBUG);
374
// Load translation files required by page
375
                        Globals::$langs->loadLangs(array('main', 'errors'));
376
377
// Bad password. No authmode has found a good password.
378
// We set a generic message if not defined inside function checkLoginPassEntity or subfunctions
379
                        if (empty($_SESSION["dol_loginmesg"])) {
380
                            $_SESSION["dol_loginmesg"] = Globals::$langs->trans("ErrorBadLoginPassword");
381
                        }
382
383
                        // Call trigger for the "security events" log
384
                        Globals::$user->trigger_mesg = Globals::$langs->trans("ErrorBadLoginPassword") . ' - login=' . DolUtils::GETPOST("username", "alpha", 2);
385
386
                        // Call of triggers
387
                        //include_once DOL_BASE_PATH . '/core/class/interfaces.class.php';
388
                        $interface = new Interfaces();
389
                        $result = $interface->run_triggers('USER_LOGIN_FAILED', Globals::$user, Globals::$user, Globals::$langs, Globals::$conf, DolUtils::GETPOST("username", "alpha", 2));
390
                        if ($result < 0) {
391
                            $error++;
392
                        }
393
// End Call of triggers
394
// Hooks on failed login
395
                        $action = '';
396
                        Globals::$hookManager->initHooks(array('login'));
397
                        $parameters = array('dol_authmode' => $this->dol_authmode, 'dol_loginmesg' => $_SESSION["dol_loginmesg"]);
398
                        $reshook = Globals::$hookManager->executeHooks('afterLoginFailed', $parameters, Globals::$user, $action);    // Note that $action and $object may have been modified by some hooks
399
                        if ($reshook < 0) {
400
                            $error++;
401
                        }
402
403
                    // Note: exit is done in next chapter
404
                    }
405
                }
406
407
                // End test login / passwords
408
                if (!$login || (in_array('ldap', $this->authmode) && empty($passwordtotest))) { // With LDAP we refused empty password because some LDAP are "opened" for anonymous access so connexion is a success.
409
                // No data to test login, so we show the login page
410
                    DolUtils::dol_syslog("--- Access to " . $_SERVER["PHP_SELF"] . " showing the login form and exit");
411
                    if (defined('NOREDIRECTBYMAINTOLOGIN')) {
412
                        return 'ERROR_NOT_LOGGED';
413
                    } else {
414
                        Security2::dol_loginfunction($this);
415
                    }
416
                    exit;
417
                }
418
419
                $resultFetchUser = Globals::$user->fetch('', $login, '', 1, ($entitytotest > 0 ? $entitytotest : -1));
420
                var_dump($resultFetchUser);
421
                if ($resultFetchUser <= 0) {
422
                    DolUtils::dol_syslog('User not found, connexion refused');
423
                    session_destroy();
424
                    session_name($sessionname);
425
                    session_set_cookie_params(0, '/', null, false, true);   // Add tag httponly on session cookie
426
                    session_start();    // Fixing the bug of register_globals here is useless since session is empty
427
428
                    if ($resultFetchUser == 0) {
429
// Load translation files required by page
430
                        Globals::$langs->loadLangs(array('main', 'errors'));
431
432
                        $_SESSION["dol_loginmesg"] = Globals::$langs->trans("ErrorCantLoadUserFromDolibarrDatabase", $login);
433
434
                        Globals::$user->trigger_mesg = 'ErrorCantLoadUserFromDolibarrDatabase - login=' . $login;
435
                    }
436
                    if ($resultFetchUser < 0) {
437
                        $_SESSION["dol_loginmesg"] = Globals::$user->error;
438
439
                        Globals::$user->trigger_mesg = Globals::$user->error;
440
                    }
441
442
// Call triggers for the "security events" log
443
                    //include_once DOL_BASE_PATH . '/core/class/interfaces.class.php';
444
                    $interface = new Interfaces();
445
                    $result = $interface->run_triggers('USER_LOGIN_FAILED', Globals::$user, Globals::$user, Globals::$langs, Globals::$conf);
446
                    if ($result < 0) {
447
                        $error++;
448
                    }
449
// End call triggers
450
// Hooks on failed login
451
                    $action = '';
452
                    Globals::$hookManager->initHooks(array('login'));
453
                    $parameters = array('dol_authmode' => $this->dol_authmode, 'dol_loginmesg' => $_SESSION["dol_loginmesg"]);
454
                    $reshook = Globals::$hookManager->executeHooks('afterLoginFailed', $parameters, Globals::$user, $action);    // Note that $action and $object may have been modified by some hooks
455
                    if ($reshook < 0) {
456
                        $error++;
457
                    }
458
459
                    $paramsurl = array();
460
                    if (DolUtils::GETPOST('textbrowser', 'int')) {
461
                        $paramsurl[] = 'textbrowser=' . DolUtils::GETPOST('textbrowser', 'int');
462
                    }
463
                    if (DolUtils::GETPOST('nojs', 'int')) {
464
                        $paramsurl[] = 'nojs=' . DolUtils::GETPOST('nojs', 'int');
465
                    }
466
                    if (DolUtils::GETPOST('lang', 'aZ09')) {
467
                        $paramsurl[] = 'lang=' . DolUtils::GETPOST('lang', 'aZ09');
468
                    }
469
                    echo 'Location: ' . DOL_BASE_URI . '/index.php' . (count($paramsurl) ? '?' . implode('&', $paramsurl) : '');
470
                    throw Exception('x');
471
                    header('Location: ' . DOL_BASE_URI . '/index.php' . (count($paramsurl) ? '?' . implode('&', $paramsurl) : ''));
472
                    exit;
473
                }
474
            } else {
475
// We are already into an authenticated session
476
                $login = $_SESSION["dol_login"];
477
                $entity = $_SESSION["dol_entity"];
478
                DolUtils::dol_syslog("- This is an already logged session. _SESSION['dol_login']=" . $login . " _SESSION['dol_entity']=" . $entity, LOG_DEBUG);
479
480
                $resultFetchUser = Globals::$user->fetch('', $login, '', 1, ($entity > 0 ? $entity : -1));
481
                if ($resultFetchUser <= 0) {
482
// Account has been removed after login
483
                    DolUtils::dol_syslog("Can't load user even if session logged. _SESSION['dol_login']=" . $login, LOG_WARNING);
484
                    session_destroy();
485
                    session_name($sessionname);
486
                    session_set_cookie_params(0, '/', null, false, true);   // Add tag httponly on session cookie
487
                    session_start();    // Fixing the bug of register_globals here is useless since session is empty
488
489
                    if ($resultFetchUser == 0) {
490
// Load translation files required by page
491
                        Globals::$langs->loadLangs(array('main', 'errors'));
492
493
                        $_SESSION["dol_loginmesg"] = Globals::$langs->trans("ErrorCantLoadUserFromDolibarrDatabase", $login);
494
495
                        Globals::$user->trigger_mesg = 'ErrorCantLoadUserFromDolibarrDatabase - login=' . $login;
496
                    }
497
                    if ($resultFetchUser < 0) {
498
                        $_SESSION["dol_loginmesg"] = Globals::$user->error;
499
500
                        Globals::$user->trigger_mesg = Globals::$user->error;
501
                    }
502
503
// Call triggers for the "security events" log
504
                    //include_once DOL_BASE_PATH . '/core/class/interfaces.class.php';
505
                    $interface = new Interfaces($db);
506
                    $result = $interface->run_triggers('USER_LOGIN_FAILED', Globals::$user, Globals::$user, Globals::$langs, Globals::$conf);
507
                    if ($result < 0) {
508
                        $error++;
509
                    }
510
// End call triggers
511
// Hooks on failed login
512
                    $action = '';
513
                    Globals::$hookManager->initHooks(array('login'));
514
                    $parameters = array('dol_authmode' => $this->dol_authmode, 'dol_loginmesg' => $_SESSION["dol_loginmesg"]);
515
                    $reshook = Globals::$hookManager->executeHooks('afterLoginFailed', $parameters, Globals::$user, $action);    // Note that $action and $object may have been modified by some hooks
516
                    if ($reshook < 0) {
517
                        $error++;
518
                    }
519
520
                    $paramsurl = array();
521
                    if (DolUtils::GETPOST('textbrowser', 'int')) {
522
                        $paramsurl[] = 'textbrowser=' . DolUtils::GETPOST('textbrowser', 'int');
523
                    }
524
                    if (DolUtils::GETPOST('nojs', 'int')) {
525
                        $paramsurl[] = 'nojs=' . DolUtils::GETPOST('nojs', 'int');
526
                    }
527
                    if (DolUtils::GETPOST('lang', 'aZ09')) {
528
                        $paramsurl[] = 'lang=' . DolUtils::GETPOST('lang', 'aZ09');
529
                    }
530
                    echo 'Location: ' . DOL_BASE_URI . '/index.php' . (count($paramsurl) ? '?' . implode('&', $paramsurl) : '');
531
                    throw Exception('x');
532
                    header('Location: ' . DOL_BASE_URI . '/index.php' . (count($paramsurl) ? '?' . implode('&', $paramsurl) : ''));
533
                    exit;
534
                } else {
535
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
536
                    Globals::$hookManager->initHooks(array('main'));
537
538
// Code for search criteria persistence.
539
                    if (!empty($_GET['save_lastsearch_values'])) {    // We must use $_GET here
540
                        $relativepathstring = preg_replace('/\?.*$/', '', $_SERVER["HTTP_REFERER"]);
541
                        $relativepathstring = preg_replace('/^https?:\/\/[^\/]*/', '', $relativepathstring);     // Get full path except host server
542
// Clean $relativepathstring
543
                        if (constant('DOL_BASE_URI')) {
544
                            $relativepathstring = preg_replace('/^' . preg_quote(constant('DOL_BASE_URI'), '/') . '/', '', $relativepathstring);
545
                        }
546
                        $relativepathstring = preg_replace('/^\//', '', $relativepathstring);
547
                        $relativepathstring = preg_replace('/^custom\//', '', $relativepathstring);
548
//var_dump($relativepathstring);
549
// We click on a link that leave a page we have to save search criteria, contextpage, limit and page. We save them from tmp to no tmp
550
                        if (!empty($_SESSION['lastsearch_values_tmp_' . $relativepathstring])) {
551
                            $_SESSION['lastsearch_values_' . $relativepathstring] = $_SESSION['lastsearch_values_tmp_' . $relativepathstring];
552
                            unset($_SESSION['lastsearch_values_tmp_' . $relativepathstring]);
553
                        }
554
                        if (!empty($_SESSION['lastsearch_contextpage_tmp_' . $relativepathstring])) {
555
                            $_SESSION['lastsearch_contextpage_' . $relativepathstring] = $_SESSION['lastsearch_contextpage_tmp_' . $relativepathstring];
556
                            unset($_SESSION['lastsearch_contextpage_tmp_' . $relativepathstring]);
557
                        }
558
                        if (!empty($_SESSION['lastsearch_page_tmp_' . $relativepathstring]) && $_SESSION['lastsearch_page_tmp_' . $relativepathstring] > 1) {
559
                            $_SESSION['lastsearch_page_' . $relativepathstring] = $_SESSION['lastsearch_page_tmp_' . $relativepathstring];
560
                            unset($_SESSION['lastsearch_page_tmp_' . $relativepathstring]);
561
                        }
562
                        if (!empty($_SESSION['lastsearch_limit_tmp_' . $relativepathstring]) && $_SESSION['lastsearch_limit_tmp_' . $relativepathstring] != Globals::$conf->liste_limit) {
563
                            $_SESSION['lastsearch_limit_' . $relativepathstring] = $_SESSION['lastsearch_limit_tmp_' . $relativepathstring];
564
                            unset($_SESSION['lastsearch_limit_tmp_' . $relativepathstring]);
565
                        }
566
                    }
567
568
                    $action = '';
569
                    $reshook = Globals::$hookManager->executeHooks('updateSession', array(), Globals::$user, $action);
570
                    if ($reshook < 0) {
571
                        setEventMessages(Globals::$hookManager->error, Globals::$hookManager->errors, 'errors');
572
                    }
573
                }
574
            }
575
576
// Is it a new session that has started ?
577
// If we are here, this means authentication was successfull.
578
            if (!isset($_SESSION["dol_login"])) {
579
// New session for this login has started.
580
                $error = 0;
581
582
// Store value into session (values always stored)
583
                $_SESSION["dol_login"] = Globals::$user->login;
584
                $_SESSION["dol_authmode"] = isset($this->dol_authmode) ? $this->dol_authmode : '';
585
                $_SESSION["dol_tz"] = isset($dol_tz) ? $dol_tz : '';
586
                $_SESSION["dol_tz_string"] = isset($dol_tz_string) ? $dol_tz_string : '';
587
                $_SESSION["dol_dst"] = isset($dol_dst) ? $dol_dst : '';
588
                $_SESSION["dol_dst_observed"] = isset($dol_dst_observed) ? $dol_dst_observed : '';
589
                $_SESSION["dol_dst_first"] = isset($dol_dst_first) ? $dol_dst_first : '';
590
                $_SESSION["dol_dst_second"] = isset($dol_dst_second) ? $dol_dst_second : '';
591
                $_SESSION["dol_screenwidth"] = isset($dol_screenwidth) ? $dol_screenwidth : '';
592
                $_SESSION["dol_screenheight"] = isset($dol_screenheight) ? $dol_screenheight : '';
593
                $_SESSION["dol_company"] = Globals::$conf->global->MAIN_INFO_SOCIETE_NOM;
594
                $_SESSION["dol_entity"] = Globals::$conf->entity;
595
// Store value into session (values stored only if defined)
596
                if (!empty($dol_hide_topmenu)) {
597
                    $_SESSION['dol_hide_topmenu'] = $dol_hide_topmenu;
598
                }
599
                if (!empty($dol_hide_leftmenu)) {
600
                    $_SESSION['dol_hide_leftmenu'] = $dol_hide_leftmenu;
601
                }
602
                if (!empty($dol_optimize_smallscreen)) {
603
                    $_SESSION['dol_optimize_smallscreen'] = $dol_optimize_smallscreen;
604
                }
605
                if (!empty($dol_no_mouse_hover)) {
606
                    $_SESSION['dol_no_mouse_hover'] = $dol_no_mouse_hover;
607
                }
608
                if (!empty($dol_use_jmobile)) {
609
                    $_SESSION['dol_use_jmobile'] = $dol_use_jmobile;
610
                }
611
612
                DolUtils::dol_syslog("This is a new started user session. _SESSION['dol_login']=" . $_SESSION["dol_login"] . " Session id=" . session_id());
613
614
                $db->begin();
615
616
                Globals::$user->update_last_login_date();
617
618
                $loginfo = 'TZ=' . $_SESSION["dol_tz"] . ';TZString=' . $_SESSION["dol_tz_string"] . ';Screen=' . $_SESSION["dol_screenwidth"] . 'x' . $_SESSION["dol_screenheight"];
619
620
// Call triggers for the "security events" log
621
                Globals::$user->trigger_mesg = $loginfo;
622
// Call triggers
623
                //include_once DOL_BASE_PATH . '/core/class/interfaces.class.php';
624
                $interface = new Interfaces($db);
625
                $result = $interface->run_triggers('USER_LOGIN', Globals::$user, Globals::$user, Globals::$langs, Globals::$conf);
626
                if ($result < 0) {
627
                    $error++;
628
                }
629
// End call triggers
630
// Hooks on successfull login
631
                $action = '';
632
                Globals::$hookManager->initHooks(array('login'));
633
                $parameters = array('dol_authmode' => $this->dol_authmode, 'dol_loginfo' => $loginfo);
634
                $reshook = Globals::$hookManager->executeHooks('afterLogin', $parameters, Globals::$user, $action);    // Note that $action and $object may have been modified by some hooks
635
                if ($reshook < 0) {
636
                    $error++;
637
                }
638
639
                if ($error) {
640
                    $db->rollback();
641
                    session_destroy();
642
                    dol_print_error($db, 'Error in some triggers USER_LOGIN or in some hooks afterLogin');
643
                    exit;
644
                } else {
645
                    $db->commit();
646
                }
647
648
// Change landing page if defined.
649
                $landingpage = (empty(Globals::$user->conf->MAIN_LANDING_PAGE) ? (empty(Globals::$conf->global->MAIN_LANDING_PAGE) ? '' : Globals::$conf->global->MAIN_LANDING_PAGE) : Globals::$user->conf->MAIN_LANDING_PAGE);
650
                if (!empty($landingpage)) {    // Example: /index.php
651
                    $newpath = dol_buildpath($landingpage, 1);
652
                    if ($_SERVER["PHP_SELF"] != $newpath) {   // not already on landing page (avoid infinite loop)
653
                        echo $newpath;
654
                        throw Exception('x');
655
                        header('Location: ' . $newpath);
656
                        exit;
657
                    }
658
                }
659
            }
660
661
662
// If user admin, we force the rights-based modules
663
            if (Globals::$user->admin) {
664
                Globals::$user->rights->user->user->lire = 1;
665
                Globals::$user->rights->user->user->creer = 1;
666
                Globals::$user->rights->user->user->password = 1;
667
                Globals::$user->rights->user->user->supprimer = 1;
668
                Globals::$user->rights->user->self->creer = 1;
669
                Globals::$user->rights->user->self->password = 1;
670
            }
671
672
            /*
673
             * Overwrite some configs globals (try to avoid this and have code to use instead Globals::$user->conf->xxx)
674
             */
675
676
// Set liste_limit
677
            if (isset(Globals::$user->conf->MAIN_SIZE_LISTE_LIMIT)) {
678
                Globals::$conf->liste_limit = Globals::$user->conf->MAIN_SIZE_LISTE_LIMIT; // Can be 0
679
            }
680
            if (isset(Globals::$user->conf->PRODUIT_LIMIT_SIZE)) {
681
                Globals::$conf->product->limit_size = Globals::$user->conf->PRODUIT_LIMIT_SIZE; // Can be 0
682
// Replace conf->css by personalized value if theme not forced
683
            }
684
            if (empty(Globals::$conf->global->MAIN_FORCETHEME) && !empty(Globals::$user->conf->MAIN_THEME)) {
685
                Globals::$conf->theme = Globals::$user->conf->MAIN_THEME;
686
// Globals::$conf->css = "/theme/" . Globals::$conf->theme . "/style.css.php";
687
                Globals::$conf->css = '?controller=theme/' . Globals::$conf->theme . '&method=style.css';
688
            }
689
        }
690
691
// Case forcing style from url
692
        if (DolUtils::GETPOST('theme', 'alpha')) {
693
            Globals::$conf->theme = DolUtils::GETPOST('theme', 'alpha', 1);
694
// Globals::$conf->css = "/theme/" . Globals::$conf->theme . "/style.css.php";
695
            Globals::$conf->css = '?controller=theme/' . Globals::$conf->theme . '&method=style.css';
696
        }
697
698
699
// Set javascript option
700
        if (!DolUtils::GETPOST('nojs', 'int')) {   // If javascript was not disabled on URL
701
            if (!empty(Globals::$user->conf->MAIN_DISABLE_JAVASCRIPT)) {
702
                Globals::$conf->use_javascript_ajax = !$user->conf->MAIN_DISABLE_JAVASCRIPT;
703
            }
704
        } else {
705
            Globals::$conf->use_javascript_ajax = 0;
706
        }
707
// Set MAIN_OPTIMIZEFORTEXTBROWSER
708
        if (DolUtils::GETPOST('textbrowser', 'int') || (!empty(Globals::$conf->browser->name) && Globals::$conf->browser->name == 'lynxlinks') || !empty(Globals::$user->conf->MAIN_OPTIMIZEFORTEXTBROWSER)) {   // If we must enable text browser
709
            Globals::$conf->global->MAIN_OPTIMIZEFORTEXTBROWSER = 1;
710
        } elseif (!empty(Globals::$user->conf->MAIN_OPTIMIZEFORTEXTBROWSER)) {
711
            Globals::$conf->global->MAIN_OPTIMIZEFORTEXTBROWSER = Globals::$user->conf->MAIN_OPTIMIZEFORTEXTBROWSER;
712
        }
713
714
// Set terminal output option according to conf->browser.
715
        if (DolUtils::GETPOST('dol_hide_leftmenu', 'int') || !empty($_SESSION['dol_hide_leftmenu'])) {
716
            Globals::$conf->dol_hide_leftmenu = 1;
717
        }
718
        if (DolUtils::GETPOST('dol_hide_topmenu', 'int') || !empty($_SESSION['dol_hide_topmenu'])) {
719
            Globals::$conf->dol_hide_topmenu = 1;
720
        }
721
        if (DolUtils::GETPOST('dol_optimize_smallscreen', 'int') || !empty($_SESSION['dol_optimize_smallscreen'])) {
722
            Globals::$conf->dol_optimize_smallscreen = 1;
723
        }
724
        if (DolUtils::GETPOST('dol_no_mouse_hover', 'int') || !empty($_SESSION['dol_no_mouse_hover'])) {
725
            Globals::$conf->dol_no_mouse_hover = 1;
726
        }
727
        if (DolUtils::GETPOST('dol_use_jmobile', 'int') || !empty($_SESSION['dol_use_jmobile'])) {
728
            Globals::$conf->dol_use_jmobile = 1;
729
        }
730
        if (!empty(Globals::$conf->browser->layout) && Globals::$conf->browser->layout != 'classic') {
731
            Globals::$conf->dol_no_mouse_hover = 1;
732
        }
733
        if ((!empty(Globals::$conf->browser->layout) && Globals::$conf->browser->layout == 'phone') || (!empty($_SESSION['dol_screenwidth']) && $_SESSION['dol_screenwidth'] < 400) || (!empty($_SESSION['dol_screenheight']) && $_SESSION['dol_screenheight'] < 400)
734
        ) {
735
            Globals::$conf->dol_optimize_smallscreen = 1;
736
        }
737
// If we force to use jmobile, then we reenable javascript
738
        if (!empty(Globals::$conf->dol_use_jmobile)) {
739
            Globals::$conf->use_javascript_ajax = 1;
740
        }
741
// Replace themes bugged with jmobile with eldy
742
        if (!empty(Globals::$conf->dol_use_jmobile) && in_array(Globals::$conf->theme, array('bureau2crea', 'cameleo', 'amarok'))) {
743
            Globals::$conf->theme = 'eldy';
744
// Globals::$conf->css = "/theme/" . Globals::$conf->theme . "/style.css.php";
745
            Globals::$conf->css = '?controller=theme/' . Globals::$conf->theme . '&method=style.css';
746
        }
747
748
        if (!defined('NOREQUIRETRAN')) {
749
            if (!DolUtils::GETPOST('lang', 'aZ09')) { // If language was not forced on URL
750
// If user has chosen its own language
751
                if (!empty(Globals::$user->conf->MAIN_LANG_DEFAULT)) {
752
// If different than current language
753
//print ">>>".Globals::$langs->getDefaultLang()."-".$user->conf->MAIN_LANG_DEFAULT;
754
                    if (Globals::$langs->getDefaultLang() != Globals::$user->conf->MAIN_LANG_DEFAULT) {
755
                        Globals::$langs->setDefaultLang(Globals::$user->conf->MAIN_LANG_DEFAULT);
756
                    }
757
                }
758
            }
759
        }
760
761
        if (!defined('NOLOGIN')) {
762
// If the login is not recovered, it is identified with an account that does not exist.
763
// Hacking attempt?
764
            if (!Globals::$user->login) {
765
                accessforbidden();
766
            }
767
768
// Check if user is active
769
            if (Globals::$user->statut < 1) {
770
// If not active, we refuse the user
771
                Globals::$langs->load("other");
772
                DolUtils::dol_syslog("Authentification ko as login is disabled");
773
                accessforbidden(Globals::$langs->trans("ErrorLoginDisabled"));
774
                exit;
775
            }
776
777
// Load permissions
778
            Globals::$user->getrights();
779
        }
780
781
782
        DolUtils::dol_syslog("--- Access to " . $_SERVER["PHP_SELF"] . ' - action=' . DolUtils::GETPOST('action', 'az09') . ', massaction=' . DolUtils::GETPOST('massaction', 'az09'));
783
//Another call for easy debugg
784
//dol_syslog("Access to ".$_SERVER["PHP_SELF"].' GET='.join(',',array_keys($_GET)).'->'.join(',',$_GET).' POST:'.join(',',array_keys($_POST)).'->'.join(',',$_POST));
785
// Load main languages files
786
        if (!defined('NOREQUIRETRAN')) {
787
// Load translation files required by page
788
            Globals::$langs->loadLangs(array('main', 'dict'));
789
        }
790
791
// Define some constants used for style of arrays
792
        $bc = array(0 => 'class="impair"', 1 => 'class="pair"');
793
        $bcdd = array(0 => 'class="drag drop oddeven"', 1 => 'class="drag drop oddeven"');
794
        $bcnd = array(0 => 'class="nodrag nodrop nohover"', 1 => 'class="nodrag nodrop nohoverpair"');  // Used for tr to add new lines
795
        $bctag = array(0 => 'class="impair tagtr"', 1 => 'class="pair tagtr"');
796
797
// Define messages variables
798
        $mesg = '';
799
        $warning = '';
800
        $error = 0;
801
// deprecated, see setEventMessages() and dol_htmloutput_events()
802
        $mesgs = array();
803
        $warnings = array();
804
        $errors = array();
805
806
// Constants used to defined number of lines in textarea
807
        if (empty(Globals::$conf->browser->firefox)) {
808
            define('ROWS_1', 1);
809
            define('ROWS_2', 2);
810
            define('ROWS_3', 3);
811
            define('ROWS_4', 4);
812
            define('ROWS_5', 5);
813
            define('ROWS_6', 6);
814
            define('ROWS_7', 7);
815
            define('ROWS_8', 8);
816
            define('ROWS_9', 9);
817
        } else {
818
            define('ROWS_1', 0);
819
            define('ROWS_2', 1);
820
            define('ROWS_3', 2);
821
            define('ROWS_4', 3);
822
            define('ROWS_5', 4);
823
            define('ROWS_6', 5);
824
            define('ROWS_7', 6);
825
            define('ROWS_8', 7);
826
            define('ROWS_9', 8);
827
        }
828
829
        $heightforframes = 50;
830
831
// Init menu manager
832
        if (!defined('NOREQUIREMENU')) {
833
            if (empty(Globals::$user->societe_id)) {    // If internal user or not defined
834
                Globals::$conf->standard_menu = (empty(Globals::$conf->global->MAIN_MENU_STANDARD_FORCED) ? (empty(Globals::$conf->global->MAIN_MENU_STANDARD) ? 'eldy_menu.php' : Globals::$conf->global->MAIN_MENU_STANDARD) : Globals::$conf->global->MAIN_MENU_STANDARD_FORCED);
835
            } else {                        // If external user
836
                Globals::$conf->standard_menu = (empty(Globals::$conf->global->MAIN_MENUFRONT_STANDARD_FORCED) ? (empty(Globals::$conf->global->MAIN_MENUFRONT_STANDARD) ? 'eldy_menu.php' : Globals::$conf->global->MAIN_MENUFRONT_STANDARD) : Globals::$conf->global->MAIN_MENUFRONT_STANDARD_FORCED);
837
            }
838
839
// Load the menu manager (only if not already done)
840
            $file_menu = Globals::$conf->standard_menu;
841
            if (DolUtils::GETPOST('menu', 'alpha')) {
842
                $file_menu = DolUtils::GETPOST('menu', 'alpha');     // example: menu=eldy_menu.php
843
            }
844
            if (!class_exists('MenuManager')) {
845
                $menufound = 0;
846
                $dirmenus = array_merge(array("/core/menus/"), (array) Globals::$conf->modules_parts['menus']);
847
                foreach ($dirmenus as $dirmenu) {
848
                    // $menufound = dol_include_once($dirmenu . "standard/" . $file_menu);
849
                    if (class_exists('MenuManager')) {
850
                        break;
851
                    }
852
                }
853
                if (!class_exists('MenuManager')) { // If failed to include, we try with standard eldy_menu.php
854
                    DolUtils::dol_syslog("You define a menu manager '" . $file_menu . "' that can not be loaded.", LOG_WARNING);
855
                    $file_menu = 'eldy_menu.php';
856
                    // include_once DOL_DOCUMENT_ROOT . "/core/menus/standard/" . $file_menu;
857
                }
858
            }
859
            $menumanager = new MenuManager(empty(Globals::$user->societe_id) ? 0 : 1);
860
            $menumanager->loadMenu();
861
        }
862
    }
863
864
    function checkRequires()
865
    {
866
        /**
867
         * $_GET = array_map('stripslashes_deep', $_GET);
868
         * $_POST = array_map('stripslashes_deep', $_POST);
869
         * $_FILES = array_map('stripslashes_deep', $_FILES);
870
         * // $_COOKIE  = array_map('stripslashes_deep', $_COOKIE); // Useless because a cookie should never be outputed on screen nor used into sql
871
         * @set_magic_quotes_runtime(0);
872
         */
873
        // Check consistency of NOREQUIREXXX DEFINES
874
        if ((defined('NOREQUIREDB') || defined('NOREQUIRETRAN')) && !defined('NOREQUIREMENU')) {
875
            print 'If define NOREQUIREDB or NOREQUIRETRAN are set, you must also set NOREQUIREMENU or not set them';
876
            exit;
877
        }
878
879
        // Sanity check on URL
880
        if (!empty($_SERVER["PHP_SELF"])) {
881
            $morevaltochecklikepost = array($_SERVER["PHP_SELF"]);
882
            $this->analyseVarsForSqlAndScriptsInjection($morevaltochecklikepost, 2);
883
        }
884
885
        // Sanity check on GET parameters
886
        if (!defined('NOSCANGETFORINJECTION') && !empty($_SERVER["QUERY_STRING"])) {
887
            $morevaltochecklikeget = array($_SERVER["QUERY_STRING"]);
888
            $this->analyseVarsForSqlAndScriptsInjection($morevaltochecklikeget, 1);
889
        }
890
891
        // Sanity check on POST
892
        if (!defined('NOSCANPOSTFORINJECTION')) {
893
            $this->analyseVarsForSqlAndScriptsInjection($_POST, 0);
894
        }
895
896
        // This is to make Dolibarr working with Plesk
897
        if (!empty($_SERVER['DOCUMENT_ROOT']) && substr($_SERVER['DOCUMENT_ROOT'], -6) !== 'htdocs') {
898
            set_include_path($_SERVER['DOCUMENT_ROOT'] . '/htdocs');
899
        }
900
901
        // If there is a POST parameter to tell to save automatically some POST parameters into cookies, we do it.
902
        // This is used for example by form of boxes to save personalization of some options.
903
        // DOL_AUTOSET_COOKIE=cookiename:val1,val2 and  cookiename_val1=aaa cookiename_val2=bbb will set cookie_name with value json_encode(array('val1'=> , ))
904
        if (!empty($_POST["DOL_AUTOSET_COOKIE"])) {
905
            $tmpautoset = explode(':', $_POST["DOL_AUTOSET_COOKIE"], 2);
906
            $tmplist = explode(',', $tmpautoset[1]);
907
            $cookiearrayvalue = array();
908
            foreach ($tmplist as $tmpkey) {
909
                $postkey = $tmpautoset[0] . '_' . $tmpkey;
910
//var_dump('tmpkey='.$tmpkey.' postkey='.$postkey.' value='.$_POST[$postkey]);
911
                if (!empty($_POST[$postkey])) {
912
                    $cookiearrayvalue[$tmpkey] = $_POST[$postkey];
913
                }
914
            }
915
            $cookiename = $tmpautoset[0];
916
            $cookievalue = json_encode($cookiearrayvalue);
917
//var_dump('setcookie cookiename='.$cookiename.' cookievalue='.$cookievalue);
918
            setcookie($cookiename, empty($cookievalue) ? '' : $cookievalue, empty($cookievalue) ? 0 : (time() + (86400 * 354)), '/', null, false, true); // keep cookie 1 year and add tag httponly
919
            if (empty($cookievalue)) {
920
                unset($_COOKIE[$cookiename]);
921
            }
922
        }
923
    }
924
925
    /**
926
     * DEPRECATED?
927
     *
928
     * Forcing parameter setting magic_quotes_gpc and cleaning parameters
929
     * (Otherwise he would have for each position, condition
930
     * Reading stripslashes variable according to state get_magic_quotes_gpc).
931
     * Off mode recommended (just do $db->escape for insert / update).
932
     */
933
    function stripslashes_deep($value)
934
    {
935
        return (is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value));
936
    }
937
938
    /**
939
     * Security: SQL Injection and XSS Injection (scripts) protection (Filters on GET, POST, PHP_SELF).
940
     *
941
     * @param       string      $val        Value
942
     * @param       string      $type       1=GET, 0=POST, 2=PHP_SELF, 3=GET without sql reserved keywords (the less tolerant test)
943
     * @return      int                     >0 if there is an injection, 0 if none
944
     * @deprecated                          use $this->testSqlAndScriptInject
945
     * @see $this->testSqlAndScriptInject($val, $type)
946
     */
947
    function test_sql_and_script_inject($val, $type)
948
    {
949
// phpcs:enable
950
        return $this->testSqlAndScriptInject($val, $type);
951
    }
952
953
    /**
954
     * Security: SQL Injection and XSS Injection (scripts) protection (Filters on GET, POST, PHP_SELF).
955
     *
956
     * @param		string		$val		Value
957
     * @param		string		$type		1=GET, 0=POST, 2=PHP_SELF, 3=GET without sql reserved keywords (the less tolerant test)
958
     * @return		int						>0 if there is an injection, 0 if none
959
     */
960
    function testSqlAndScriptInject($val, $type)
961
    {
962
        $inj = 0;
963
// For SQL Injection (only GET are used to be included into bad escaped SQL requests)
964
        if ($type == 1 || $type == 3) {
965
            $inj += preg_match('/delete\s+from/i', $val);
966
            $inj += preg_match('/create\s+table/i', $val);
967
            $inj += preg_match('/insert\s+into/i', $val);
968
            $inj += preg_match('/select\s+from/i', $val);
969
            $inj += preg_match('/into\s+(outfile|dumpfile)/i', $val);
970
            $inj += preg_match('/user\s*\(/i', $val);      // avoid to use function user() that return current database login
971
            $inj += preg_match('/information_schema/i', $val);    // avoid to use request that read information_schema database
972
        }
973
        if ($type == 3) {
974
            $inj += preg_match('/select|update|delete|replace|group\s+by|concat|count|from/i', $val);
975
        }
976
        if ($type != 2) { // Not common key strings, so we can check them both on GET and POST
977
            $inj += preg_match('/updatexml\(/i', $val);
978
            $inj += preg_match('/update.+set.+=/i', $val);
979
            $inj += preg_match('/union.+select/i', $val);
980
            $inj += preg_match('/(\.\.%2f)+/i', $val);
981
        }
982
// For XSS Injection done by adding javascript with script
983
// This is all cases a browser consider text is javascript:
984
// When it found '<script', 'javascript:', '<style', 'onload\s=' on body tag, '="&' on a tag size with old browsers
985
// All examples on page: http://ha.ckers.org/xss.html#XSScalc
986
// More on https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
987
        $inj += preg_match('/<script/i', $val);
988
        $inj += preg_match('/<iframe/i', $val);
989
        $inj += preg_match('/<audio/i', $val);
990
        $inj += preg_match('/Set\.constructor/i', $val); // ECMA script 6
991
        if (!defined('NOSTYLECHECK')) {
992
            $inj += preg_match('/<style/i', $val);
993
        }
994
        $inj += preg_match('/base[\s]+href/si', $val);
995
        $inj += preg_match('/<.*onmouse/si', $val);       // onmousexxx can be set on img or any html tag like <img title='...' onmouseover=alert(1)>
996
        $inj += preg_match('/onerror\s*=/i', $val);       // onerror can be set on img or any html tag like <img title='...' onerror = alert(1)>
997
        $inj += preg_match('/onfocus\s*=/i', $val);       // onfocus can be set on input text html tag like <input type='text' value='...' onfocus = alert(1)>
998
        $inj += preg_match('/onload\s*=/i', $val);        // onload can be set on svg tag <svg/onload=alert(1)> or other tag like body <body onload=alert(1)>
999
        $inj += preg_match('/onloadstart\s*=/i', $val);   // onload can be set on audio tag <audio onloadstart=alert(1)>
1000
        $inj += preg_match('/onclick\s*=/i', $val);       // onclick can be set on img text html tag like <img onclick = alert(1)>
1001
        $inj += preg_match('/onscroll\s*=/i', $val);      // onscroll can be on textarea
1002
//$inj += preg_match('/on[A-Z][a-z]+\*=/', $val);   // To lock event handlers onAbort(), ...
1003
        $inj += preg_match('/&#58;|&#0000058|&#x3A/i', $val);  // refused string ':' encoded (no reason to have it encoded) to lock 'javascript:...'
1004
//if ($type == 1)
1005
//{
1006
        $inj += preg_match('/javascript:/i', $val);
1007
        $inj += preg_match('/vbscript:/i', $val);
1008
//}
1009
// For XSS Injection done by adding javascript closing html tags like with onmousemove, etc... (closing a src or href tag with not cleaned param)
1010
        if ($type == 1) {
1011
            $inj += preg_match('/"/i', $val);  // We refused " in GET parameters value
1012
        }
1013
        if ($type == 2) {
1014
            $inj += preg_match('/[;"]/', $val);  // PHP_SELF is a file system path. It can contains spaces.
1015
        }
1016
        return $inj;
1017
    }
1018
1019
    /**
1020
     * Return true if security check on parameters are OK, false otherwise.
1021
     *
1022
     * @param		string			$var		Variable name
1023
     * @param		string			$type		1=GET, 0=POST, 2=PHP_SELF
1024
     * @return		boolean|null				true if there is no injection. Stop code if injection found.
1025
     */
1026
    function analyseVarsForSqlAndScriptsInjection(&$var, $type)
1027
    {
1028
        if (is_array($var)) {
1029
            foreach ($var as $key => $value) { // Warning, $key may also be used for attacks
1030
                if ($this->analyseVarsForSqlAndScriptsInjection($key, $type) && $this->analyseVarsForSqlAndScriptsInjection($value, $type)) {
1031
//$var[$key] = $value;	// This is useless
1032
                } else {
1033
                    print 'Access refused by SQL/Script injection protection in main.inc.php (type=' . htmlentities($type) . ' key=' . htmlentities($key) . ' value=' . htmlentities($value) . ' page=' . htmlentities($_SERVER["REQUEST_URI"]) . ')';
1034
                    exit;
1035
                }
1036
            }
1037
            return true;
1038
        } else {
1039
            return ($this->testSqlAndScriptInject($var, $type) <= 0);
1040
        }
1041
    }
1042
}
1043