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

Base/AlixarController.php (21 issues)

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');
0 ignored issues
show
The function Exception was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

114
                throw /** @scrutinizer ignore-call */ Exception('x');
Loading history...
115
                header("Location: " . $newurl);
0 ignored issues
show
header('Location: ' . $newurl) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
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)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $dolibarr_main_restrict_ip does not exist. Did you maybe mean $dolibarr_main_authentication?
Loading history...
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;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
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
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $dolibarr_nocsrfcheck seems to never exist and therefore empty should always be true.
Loading history...
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;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
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)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $dolibarr_main_authentication seems to never exist and therefore empty should always be true.
Loading history...
226
                    $dolibarr_main_authentication = 'http,dolibarr';
227
                }
228
// Authentication mode: forceuser
229
                if ($dolibarr_main_authentication == 'forceuser' && empty($dolibarr_auto_user)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $dolibarr_auto_user seems to never exist and therefore empty should always be true.
Loading history...
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;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
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
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $dolibarr_main_demo does not exist. Did you maybe mean $dolibarr_main_authentication?
Loading history...
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);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
300
                        $result = $interface->run_triggers('USER_LOGIN_FAILED', Globals::$user, Globals::$user, Globals::$langs, Globals::$conf);
301
                        if ($result < 0) {
302
                            $error++;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $error seems to be never defined.
Loading history...
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;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
417
                }
418
419
                $resultFetchUser = Globals::$user->fetch('', $login, '', 1, ($entitytotest > 0 ? $entitytotest : -1));
420
                var_dump($resultFetchUser);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($resultFetchUser) looks like debug code. Are you sure you do not want to remove it?
Loading history...
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;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
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;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $user seems to be never defined.
Loading history...
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;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
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;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
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;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1035
                }
1036
            }
1037
            return true;
1038
        } else {
1039
            return ($this->testSqlAndScriptInject($var, $type) <= 0);
1040
        }
1041
    }
1042
}
1043