Passed
Branch development (e0e718)
by Nils
04:45
created

mainQuery()   F

Complexity

Conditions 160
Paths 230

Size

Total Lines 1298
Code Lines 757

Duplication

Lines 0
Ratio 0 %

Importance

Changes 12
Bugs 0 Features 0
Metric Value
cc 160
eloc 757
nc 230
nop 0
dl 0
loc 1298
rs 3.6
c 12
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 63 and the first side effect is on line 16.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 *
4
 * @file          main.queries.php
5
 * @author        Nils Laumaillé
6
 * @version       2.1.27
7
 * @copyright     (c) 2009-2017 Nils Laumaillé
8
 * @licensing     GNU GPL-3.0
9
 * @link          http://www.teampass.net
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 */
15
16
$debugLdap = 0; //Can be used in order to debug LDAP authentication
17
18
require_once 'SecureHandler.php';
19
session_start();
20
if (!isset($_SESSION['CPM']) || $_SESSION['CPM'] != 1) {
21
    $_SESSION['error']['code'] = "1004"; //Hacking attempt
22
    include '../error.php';
23
    exit();
24
}
25
26
// Load config
27
if (file_exists('../includes/config/tp.config.php')) {
28
    require_once '../includes/config/tp.config.php';
29
} elseif (file_exists('./includes/config/tp.config.php')) {
30
    require_once './includes/config/tp.config.php';
31
} else {
32
    throw new Exception("Error file '/includes/config/tp.config.php' not exists", 1);
33
}
34
35
/* do checks */
36
require_once $SETTINGS['cpassman_dir'].'/includes/config/include.php';
37
require_once $SETTINGS['cpassman_dir'].'/sources/checks.php';
38
$post_type = filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING);
39
if (isset($post_type) && ($post_type === "ga_generate_qr"
40
    || $post_type === "send_pw_by_email" || $post_type === "generate_new_password")
41
) {
42
    // continue
43
    mainQuery();
44
} elseif (isset($_SESSION['user_id']) && !checkUser($_SESSION['user_id'], $_SESSION['key'], "home")) {
45
    $_SESSION['error']['code'] = ERR_NOT_ALLOWED; //not allowed page
46
    include $SETTINGS['cpassman_dir'].'/error.php';
47
    exit();
48
} elseif ((isset($_SESSION['user_id']) && isset($_SESSION['key'])) ||
49
    (isset($post_type) && $post_type === "change_user_language"
50
        && null !== filter_input(INPUT_POST, 'data', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES))
51
) {
52
    // continue
53
    mainQuery();
54
} else {
55
    $_SESSION['error']['code'] = ERR_NOT_ALLOWED; //not allowed page
56
    include $SETTINGS['cpassman_dir'].'/error.php';
57
    exit();
58
}
59
60
/*
61
** Executes expected queries
62
*/
63
function mainQuery()
64
{
65
    global $server, $user, $pass, $database, $port, $encoding, $pre, $LANG;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
66
    global $SETTINGS, $SETTINGS_EXT;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
67
68
    include $SETTINGS['cpassman_dir'].'/includes/config/settings.php';
69
    header("Content-type: text/html; charset=utf-8");
70
    header("Cache-Control: no-cache, must-revalidate");
71
    error_reporting(E_ERROR);
72
    require_once $SETTINGS['cpassman_dir'].'/sources/main.functions.php';
73
    require_once $SETTINGS['cpassman_dir'].'/sources/SplClassLoader.php';
74
75
    // connect to the server
76
    require_once $SETTINGS['cpassman_dir'].'/includes/libraries/Database/Meekrodb/db.class.php';
77
    $pass = defuse_return_decrypted($pass);
78
    DB::$host = $server;
79
    DB::$user = $user;
80
    DB::$password = $pass;
81
    DB::$dbName = $database;
82
    DB::$port = $port;
83
    DB::$encoding = $encoding;
84
    DB::$error_handler = true;
85
    $link = mysqli_connect($server, $user, $pass, $database, $port);
86
    $link->set_charset($encoding);
87
88
    // User's language loading
89
    require_once $SETTINGS['cpassman_dir'].'/includes/language/'.$_SESSION['user_language'].'.php';
90
    // Manage type of action asked
91
    switch (filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING)) {
92
        case "change_pw":
93
            // decrypt and retreive data in JSON format
94
            $dataReceived = prepareExchangedData(
95
                filter_input(INPUT_POST, 'data', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES),
96
                "decode"
97
            );
98
99
            // load passwordLib library
100
            $pwdlib = new SplClassLoader('PasswordLib', '../includes/libraries');
101
            $pwdlib->register();
102
            $pwdlib = new PasswordLib\PasswordLib();
103
104
            // Prepare variables
105
            $newPw = $pwdlib->createPasswordHash(htmlspecialchars_decode($dataReceived['new_pw']));
106
107
            // User has decided to change is PW
108
            if (null !== filter_input(INPUT_POST, 'change_pw_origine', FILTER_SANITIZE_STRING)
109
                && filter_input(INPUT_POST, 'change_pw_origine', FILTER_SANITIZE_STRING) === "user_change"
110
                && $_SESSION['user_admin'] !== "1"
111
            ) {
112
                // check if expected security level is reached
113
                $data_roles = DB::queryfirstrow("SELECT fonction_id FROM ".prefix_table("users")." WHERE id = %i", $_SESSION['user_id']);
114
115
                // check if badly written
116
                $data_roles['fonction_id'] = array_filter(explode(',', str_replace(';', ',', $data_roles['fonction_id'])));
117
                if ($data_roles['fonction_id'][0] === "") {
118
                    $data_roles['fonction_id'] = implode(';', $data_roles['fonction_id']);
119
                    DB::update(
120
                        prefix_table("users"),
121
                        array(
122
                            'fonction_id' => $data_roles['fonction_id']
123
                            ),
124
                        "id = %i",
125
                        $_SESSION['user_id']
126
                    );
127
                }
128
129
                $data = DB::query(
130
                    "SELECT complexity
131
                    FROM ".prefix_table("roles_title")."
132
                    WHERE id IN (".implode(',', $data_roles['fonction_id']).")
133
                    ORDER BY complexity DESC"
134
                );
135
                if (intval(filter_input(INPUT_POST, 'complexity', FILTER_SANITIZE_NUMBER_INT)) < intval($data[0]['complexity'])) {
136
                    echo '[ { "error" : "complexity_level_not_reached" } ]';
137
                    break;
138
                }
139
140
                // Get a string with the old pw array
141
                $lastPw = explode(';', $_SESSION['last_pw']);
142
                // if size is bigger then clean the array
143
                if (sizeof($lastPw) > $SETTINGS['number_of_used_pw']
144
                        && $SETTINGS['number_of_used_pw'] > 0
145
                ) {
146
                    for ($x_counter = 0; $x_counter < $SETTINGS['number_of_used_pw']; $x_counter++) {
147
                        unset($lastPw[$x_counter]);
148
                    }
149
                    // reinit SESSION
150
                    $_SESSION['last_pw'] = implode(';', $lastPw);
151
                    // specific case where admin setting "number_of_used_pw"
152
                } elseif ($SETTINGS['number_of_used_pw'] == 0) {
153
                    $_SESSION['last_pw'] = "";
154
                    $lastPw = array();
155
                }
156
157
                // check if new pw is different that old ones
158
                if (in_array($newPw, $lastPw)) {
159
                    echo '[ { "error" : "already_used" } ]';
160
                    break;
161
                }
162
163
                // update old pw with new pw
164
                if (sizeof($lastPw) == ($SETTINGS['number_of_used_pw'] + 1)) {
165
                    unset($lastPw[0]);
166
                } else {
167
                    array_push($lastPw, $newPw);
168
                }
169
                // create a list of last pw based on the table
170
                $oldPw = "";
171
                foreach ($lastPw as $elem) {
172
                    if (!empty($elem)) {
173
                        if (empty($oldPw)) {
174
                            $oldPw = $elem;
175
                        } else {
176
                            $oldPw .= ";".$elem;
177
                        }
178
                    }
179
                }
180
181
                // update sessions
182
                $_SESSION['last_pw'] = $oldPw;
183
                $_SESSION['last_pw_change'] = mktime(0, 0, 0, date('m'), date('d'), date('y'));
0 ignored issues
show
Bug introduced by
date('m') of type string is incompatible with the type integer expected by parameter $month of mktime(). ( Ignorable by Annotation )

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

183
                $_SESSION['last_pw_change'] = mktime(0, 0, 0, /** @scrutinizer ignore-type */ date('m'), date('d'), date('y'));
Loading history...
Bug introduced by
date('d') of type string is incompatible with the type integer expected by parameter $day of mktime(). ( Ignorable by Annotation )

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

183
                $_SESSION['last_pw_change'] = mktime(0, 0, 0, date('m'), /** @scrutinizer ignore-type */ date('d'), date('y'));
Loading history...
Bug introduced by
date('y') of type string is incompatible with the type integer expected by parameter $year of mktime(). ( Ignorable by Annotation )

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

183
                $_SESSION['last_pw_change'] = mktime(0, 0, 0, date('m'), date('d'), /** @scrutinizer ignore-type */ date('y'));
Loading history...
184
                $_SESSION['validite_pw'] = true;
185
186
                // BEfore updating, check that the pwd is correct
187
                if ($pwdlib->verifyPasswordHash(htmlspecialchars_decode($dataReceived['new_pw']), $newPw) === true) {
188
                    // update DB
189
                    DB::update(
190
                        prefix_table("users"),
191
                        array(
192
                            'pw' => $newPw,
193
                            'last_pw_change' => mktime(0, 0, 0, date('m'), date('d'), date('y')),
194
                            'last_pw' => $oldPw
195
                            ),
196
                        "id = %i",
197
                        $_SESSION['user_id']
198
                    );
199
                    // update LOG
200
                    logEvents('user_mngt', 'at_user_pwd_changed', $_SESSION['user_id'], $_SESSION['login'], $_SESSION['user_id']);
201
                    echo '[ { "error" : "none" } ]';
202
                } else {
203
                     echo '[ { "error" : "pwd_hash_not_correct" } ]';
204
                }
205
                break;
206
207
            // ADMIN has decided to change the USER's PW
208
            } elseif (null !== filter_input(INPUT_POST, 'change_pw_origine', FILTER_SANITIZE_STRING)
209
                && ((filter_input(INPUT_POST, 'change_pw_origine', FILTER_SANITIZE_STRING) === "admin_change"
210
                    || filter_input(INPUT_POST, 'change_pw_origine', FILTER_SANITIZE_STRING) === "user_change"
211
                    ) && ($_SESSION['user_admin'] === "1"|| $_SESSION['user_manager'] === "1"
212
                    || $_SESSION['user_can_manage_all_users'] === "1")
213
                )
214
            ) {
215
                // check if user is admin / Manager
216
                $userInfo = DB::queryFirstRow(
217
                    "SELECT admin, gestionnaire
218
                    FROM ".prefix_table("users")."
219
                    WHERE id = %i",
220
                    $_SESSION['user_id']
221
                );
222
                if ($userInfo['admin'] != 1 && $userInfo['gestionnaire'] != 1) {
223
                    echo '[ { "error" : "not_admin_or_manager" } ]';
224
                    break;
225
                }
226
227
                // BEfore updating, check that the pwd is correct
228
                if ($pwdlib->verifyPasswordHash(htmlspecialchars_decode($dataReceived['new_pw']), $newPw) === true) {
229
                    // adapt
230
                    if (filter_input(INPUT_POST, 'change_pw_origine', FILTER_SANITIZE_STRING) === "user_change") {
231
                        $dataReceived['user_id'] = $_SESSION['user_id'];
232
                    }
233
234
                    // update DB
235
                    DB::update(
236
                        prefix_table("users"),
237
                        array(
238
                            'pw' => $newPw,
239
                            'last_pw_change' => mktime(0, 0, 0, date('m'), date('d'), date('y'))
240
                            ),
241
                        "id = %i",
242
                        $dataReceived['user_id']
243
                    );
244
245
                    // update LOG
246
                    logEvents('user_mngt', 'at_user_pwd_changed', $_SESSION['user_id'], $_SESSION['login'], $dataReceived['user_id']);
247
248
                    //Send email to user
249
                    if (filter_input(INPUT_POST, 'change_pw_origine', FILTER_SANITIZE_STRING) !== "admin_change") {
250
                        $row = DB::queryFirstRow(
251
                            "SELECT email FROM ".prefix_table("users")."
252
                            WHERE id = %i",
253
                            $dataReceived['user_id']
254
                        );
255
                        if (!empty($row['email']) && isset($SETTINGS['enable_email_notification_on_user_pw_change']) && $SETTINGS['enable_email_notification_on_user_pw_change'] == 1) {
256
                            sendEmail(
257
                                $LANG['forgot_pw_email_subject'],
258
                                $LANG['forgot_pw_email_body']." ".htmlspecialchars_decode($dataReceived['new_pw']),
259
                                $row[0],
260
                                $LANG['forgot_pw_email_altbody_1']." ".htmlspecialchars_decode($dataReceived['new_pw'])
261
                            );
262
                        }
263
                    }
264
265
                    echo '[ { "error" : "none" } ]';
266
                } else {
267
                    echo '[ { "error" : "pwd_hash_not_correct" } ]';
268
                }
269
                break;
270
271
                // ADMIN first login
272
            } elseif (null !== filter_input(INPUT_POST, 'change_pw_origine', FILTER_SANITIZE_STRING)
273
                && filter_input(INPUT_POST, 'change_pw_origine', FILTER_SANITIZE_STRING) == "first_change"
274
            ) {
275
                // update DB
276
                DB::update(
277
                    prefix_table("users"),
278
                    array(
279
                        'pw' => $newPw,
280
                        'last_pw_change' => mktime(0, 0, 0, date('m'), date('d'), date('y'))
281
                        ),
282
                    "id = %i",
283
                    $_SESSION['user_id']
284
                );
285
286
                // update sessions
287
                $_SESSION['last_pw'] = "";
288
                $_SESSION['last_pw_change'] = mktime(0, 0, 0, date('m'), date('d'), date('y'));
289
                $_SESSION['validite_pw'] = true;
290
291
                // update LOG
292
                logEvents('user_mngt', 'at_user_initial_pwd_changed', $_SESSION['user_id'], $_SESSION['login'], $_SESSION['user_id']);
293
294
                echo '[ { "error" : "none" } ]';
295
                break;
296
            } else {
297
                // DEFAULT case
298
                echo '[ { "error" : "nothing_to_do" } ]';
299
            }
300
            break;
301
        /**
302
         * This will generate the QR Google Authenticator
303
         */
304
        case "ga_generate_qr":
305
            // is this allowed by setting
306
            if ((isset($SETTINGS['ga_reset_by_user']) === false || $SETTINGS['ga_reset_by_user'] !== "1")
307
                && (null === filter_input(INPUT_POST, 'demand_origin', FILTER_SANITIZE_STRING)
308
                    || filter_input(INPUT_POST, 'demand_origin', FILTER_SANITIZE_STRING) !== "users_management_list")
309
            ) {
310
                // User cannot ask for a new code
311
                echo '[{"error" : "not_allowed"}]';
312
                break;
313
            }
314
315
            // Check if user exists
316
            if (null === filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT)
317
                || empty(filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT)) === true
318
            ) {
319
                // decrypt and retreive data in JSON format
320
                $dataReceived = prepareExchangedData(
321
                    filter_input(INPUT_POST, 'data', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES),
322
                    "decode"
323
                );
324
                // Prepare variables
325
                $login = htmlspecialchars_decode($dataReceived['login']);
326
327
                // Get data about user
328
                $data = DB::queryfirstrow(
329
                    "SELECT id, email
330
                    FROM ".prefix_table("users")."
331
                    WHERE login = %s",
332
                    $login
333
                );
334
            } else {
335
                $data = DB::queryfirstrow(
336
                    "SELECT id, login, email
337
                    FROM ".prefix_table("users")."
338
                    WHERE id = %i",
339
                    filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT)
340
                );
341
            }
342
            $counter = DB::count();
343
            if ($counter == 0) {
344
                // not a registered user !
345
                echo '[{"error" : "no_user"}]';
346
            } else {
347
                if (empty($data['email'])) {
348
                    echo '[{"error" : "no_email"}]';
349
                } else {
350
                    // generate new GA user code
351
                    include_once($SETTINGS['cpassman_dir']."/includes/libraries/Authentication/TwoFactorAuth/TwoFactorAuth.php");
352
                    $tfa = new Authentication\TwoFactorAuth\TwoFactorAuth($SETTINGS['ga_website_name']);
353
                    $gaSecretKey = $tfa->createSecret();
354
                    $gaTemporaryCode = GenerateCryptKey(12);
355
356
                    // save the code
357
                    DB::update(
358
                        prefix_table("users"),
359
                        array(
360
                            'ga' => $gaSecretKey,
361
                            'ga_temporary_code' => $gaTemporaryCode
362
                            ),
363
                        "id = %i",
364
                        $data['id']
365
                    );
366
367
                    // send mail?
368
                    if (null !== filter_input(INPUT_POST, 'send_email', FILTER_SANITIZE_STRING)
369
                        && filter_input(INPUT_POST, 'send_email', FILTER_SANITIZE_STRING) === "1"
370
                    ) {
371
                        sendEmail(
372
                            $LANG['email_ga_subject'],
373
                            str_replace(
374
                                "#2FACode#",
375
                                $gaTemporaryCode,
376
                                $LANG['email_ga_text']
377
                            ),
378
                            $data['email']
379
                        );
380
                    }
381
382
                    // send back
383
                    echo '[{ "error" : "0" , "email" : "'.$data['email'].'" , "msg" : "'.str_replace("#email#", "<b>".$data['email']."</b>", addslashes($LANG['admin_email_result_ok'])).'"}]';
384
                }
385
            }
386
            break;
387
        /**
388
         * Increase the session time of User
389
         */
390
        case "increase_session_time":
391
            // check if session is not already expired.
392
            if ($_SESSION['fin_session'] > time()) {
393
                // Calculate end of session
394
                $_SESSION['fin_session'] = (integer) ($_SESSION['fin_session'] + filter_input(INPUT_POST, 'duration', FILTER_SANITIZE_NUMBER_INT));
395
                // Update table
396
                DB::update(
397
                    prefix_table("users"),
398
                    array(
399
                        'session_end' => $_SESSION['fin_session']
400
                    ),
401
                    "id = %i",
402
                    $_SESSION['user_id']
403
                );
404
                // Return data
405
                echo '[{"new_value":"'.$_SESSION['fin_session'].'"}]';
406
            } else {
407
                echo '[{"new_value":"expired"}]';
408
            }
409
            break;
410
        /**
411
         * Hide maintenance message
412
         */
413
        case "hide_maintenance":
414
            $_SESSION['hide_maintenance'] = 1;
415
            break;
416
        /**
417
         * Used in order to send the password to the user by email
418
         */
419
        case "send_pw_by_email":
420
            // generate key
421
            $key = GenerateCryptKey(50);
422
423
            // Prepare post variables
424
            $post_email = mysqli_escape_string($link, stripslashes(filter_input(INPUT_POST, 'email', FILTER_SANITIZE_STRING)));
425
            $post_login = mysqli_escape_string($link, filter_input(INPUT_POST, 'login', FILTER_SANITIZE_STRING));
426
427
            // Get account and pw associated to email
428
            DB::query(
429
                "SELECT * FROM ".prefix_table("users")." WHERE email = %s",
430
                $post_email
431
            );
432
            $counter = DB::count();
433
            if ($counter != 0) {
434
                $data = DB::query(
435
                    "SELECT login,pw FROM ".prefix_table("users")." WHERE email = %s",
436
                    $post_email
437
                );
438
                $textMail = $LANG['forgot_pw_email_body_1']." <a href=\"".
439
                    $SETTINGS['cpassman_url']."/index.php?action=password_recovery&key=".$key.
440
                    "&login=".$post_login."\">".$SETTINGS['cpassman_url'].
441
                    "/index.php?action=password_recovery&key=".$key."&login=".$post_login."</a>.<br><br>".$LANG['thku'];
442
                $textMailAlt = $LANG['forgot_pw_email_altbody_1']." ".$LANG['at_login']." : ".$post_login." - ".
443
                    $LANG['index_password']." : ".md5($data['pw']);
444
445
                // Check if email has already a key in DB
446
                DB::query(
447
                    "SELECT * FROM ".prefix_table("misc")." WHERE intitule = %s AND type = %s",
448
                    $post_login,
449
                    "password_recovery"
450
                );
451
                $counter = DB::count();
452
                if ($counter != 0) {
453
                    DB::update(
454
                        prefix_table("misc"),
455
                        array(
456
                            'valeur' => $key
457
                        ),
458
                        "type = %s and intitule = %s",
459
                        "password_recovery",
460
                        $post_login
461
                    );
462
                } else {
463
                    // store in DB the password recovery informations
464
                    DB::insert(
465
                        prefix_table("misc"),
466
                        array(
467
                            'type' => 'password_recovery',
468
                            'intitule' => $post_login,
469
                            'valeur' => $key
470
                        )
471
                    );
472
                }
473
474
                echo '[{'.sendEmail($LANG['forgot_pw_email_subject'], $textMail, $post_email, $textMailAlt).'}]';
475
            } else {
476
                // no one has this email ... alert
477
                echo '[{"error":"error_email" , "message":"'.$LANG['forgot_my_pw_error_email_not_exist'].'"}]';
478
            }
479
            break;
480
481
        // Send to user his new pw if key is conform
482
        case "generate_new_password":
483
            // decrypt and retreive data in JSON format
484
            $dataReceived = prepareExchangedData(
485
                filter_input(INPUT_POST, 'data', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES),
486
                "decode"
487
            );
488
489
            // Prepare variables
490
            $login = htmlspecialchars_decode($dataReceived['login']);
491
            $key = htmlspecialchars_decode($dataReceived['key']);
492
493
            // check if key is okay
494
            $data = DB::queryFirstRow(
495
                "SELECT valeur FROM ".prefix_table("misc")." WHERE intitule = %s AND type = %s",
496
                mysqli_escape_string($link, $login),
497
                "password_recovery"
498
            );
499
            if ($key == $data['valeur']) {
500
                // load passwordLib library
501
                $pwdlib = new SplClassLoader('PasswordLib', '../includes/libraries');
502
                $pwdlib->register();
503
                $pwdlib = new PasswordLib\PasswordLib();
504
505
                // generate key
506
                $newPwNotCrypted = $pwdlib->getRandomToken(10);
507
508
                // Prepare variables
509
                $newPw = $pwdlib->createPasswordHash(($newPwNotCrypted));
510
511
                // update DB
512
                DB::update(
513
                    prefix_table("users"),
514
                    array(
515
                        'pw' => $newPw
516
                        ),
517
                    "login = %s",
518
                    mysqli_escape_string($link, $login)
519
                );
520
                // Delete recovery in DB
521
                DB::delete(
522
                    prefix_table("misc"),
523
                    "type = %s AND intitule = %s AND valeur = %s",
524
                    "password_recovery",
525
                    mysqli_escape_string($link, $login),
526
                    $key
527
                );
528
                // Get email
529
                $dataUser = DB::queryFirstRow(
530
                    "SELECT email FROM ".prefix_table("users")." WHERE login = %s",
531
                    mysqli_escape_string($link, $login)
532
                );
533
534
                $_SESSION['validite_pw'] = false;
535
                // send to user
536
                $ret = json_decode(
537
                    sendEmail(
538
                        $LANG['forgot_pw_email_subject_confirm'],
539
                        $LANG['forgot_pw_email_body']." ".$newPwNotCrypted,
540
                        $dataUser['email'],
541
                        strip_tags($LANG['forgot_pw_email_body'])." ".$newPwNotCrypted
542
                    )
543
                );
544
                // send email
545
                if (empty($ret['error'])) {
546
                    echo 'done';
547
                } else {
548
                    echo $ret['message'];
549
                }
550
            }
551
            break;
552
        /**
553
         * Store the personal saltkey
554
         */
555
        case "store_personal_saltkey":
556
            if (filter_input(INPUT_POST, 'key', FILTER_SANITIZE_STRING) !== $_SESSION['key']) {
557
                echo '[ { "error" : "key_not_conform" , "status" : "nok" } ]';
558
                break;
559
            }
560
561
            $dataReceived = prepareExchangedData(
562
                filter_input(INPUT_POST, 'data', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES),
563
                "decode"
564
            );
565
            $filter_score = filter_var($dataReceived['score'], FILTER_SANITIZE_NUMBER_INT);
566
            $filter_psk = filter_var($dataReceived['psk'], FILTER_SANITIZE_STRING);
567
568
            // manage store
569
            if ($filter_psk !== "") {
570
                // store in session the cleartext for psk
571
                $_SESSION['user_settings']['clear_psk'] = $filter_psk;
572
573
                // check if encrypted_psk is in database. If not, add it
574
                if (!isset($_SESSION['user_settings']['encrypted_psk']) || (isset($_SESSION['user_settings']['encrypted_psk']) && empty($_SESSION['user_settings']['encrypted_psk']))) {
575
                    // Check if security level is reach (if enabled)
576
                    if (isset($SETTINGS['personal_saltkey_security_level']) === true) {
577
                        // Did we received the pass score
578
                        if (empty($filter_score) === false) {
579
                            if (intval($SETTINGS['personal_saltkey_security_level']) > $filter_score) {
580
                                echo '[ { "error" : "security_level_not_reached" , "status" : "" } ]';
581
                                break;
582
                            }
583
                        }
584
                    }
585
                    // generate it based upon clear psk
586
                    $_SESSION['user_settings']['encrypted_psk'] = defuse_generate_personal_key($filter_psk);
587
588
                    // store it in DB
589
                    DB::update(
590
                        prefix_table("users"),
591
                        array(
592
                            'encrypted_psk' => $_SESSION['user_settings']['encrypted_psk']
593
                            ),
594
                        "id = %i",
595
                        $_SESSION['user_id']
596
                    );
597
                }
598
599
                // check if psk is correct.
600
                $user_key_encoded = defuse_validate_personal_key(
601
                    $filter_psk,
602
                    $_SESSION['user_settings']['encrypted_psk']
603
                );
604
605
                if (strpos($user_key_encoded, "Error ") !== false) {
606
                    echo '[ { "error" : "psk_not_correct" , "status" : "" } ]';
607
                    break;
608
                } else {
609
                    // Check if security level is reach (if enabled)
610
                    if (isset($SETTINGS['personal_saltkey_security_level']) === true) {
611
                        // Did we received the pass score
612
                        if (empty($filter_score) === false) {
613
                            if (intval($SETTINGS['personal_saltkey_security_level']) > $filter_score) {
614
                                echo '[ { "error" : "" , "status" : "security_level_not_reached_but_psk_correct" } ]';
615
                                break;
616
                            }
617
                        }
618
                    }
619
                    // Store PSK
620
                    $_SESSION['user_settings']['session_psk'] = $user_key_encoded;
621
                    setcookie(
622
                        "TeamPass_PFSK_".md5($_SESSION['user_id']),
623
                        encrypt($filter_psk, ""),
0 ignored issues
show
Bug introduced by
It seems like encrypt($filter_psk, '') can also be of type false; however, parameter $value of setcookie() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

623
                        /** @scrutinizer ignore-type */ encrypt($filter_psk, ""),
Loading history...
624
                        (!isset($SETTINGS['personal_saltkey_cookie_duration']) || $SETTINGS['personal_saltkey_cookie_duration'] == 0) ? time() + 60 * 60 * 24 : time() + 60 * 60 * 24 * $SETTINGS['personal_saltkey_cookie_duration'],
625
                        '/'
626
                    );
627
                }
628
            } else {
629
                echo '[ { "error" : "psk_is_empty" , "status" : "" } ]';
630
                break;
631
            }
632
633
            echo '[ { "error" : "" , "status" : "ok" } ]';
634
635
            break;
636
        /**
637
         * Change the personal saltkey
638
         */
639
        case "change_personal_saltkey":
640
            if (filter_input(INPUT_POST, 'key', FILTER_SANITIZE_STRING) !== $_SESSION['key']) {
641
                echo '[{"error" : "something_wrong"}]';
642
                break;
643
            }
644
645
            //init
646
            $list = "";
647
            $number = 0;
648
649
            //decrypt and retreive data in JSON format
650
            $dataReceived = prepareExchangedData(
651
                filter_input(INPUT_POST, 'data_to_share', FILTER_SANITIZE_STRING),
652
                "decode"
653
            );
654
655
            //Prepare variables
656
            $newPersonalSaltkey = htmlspecialchars_decode($dataReceived['sk']);
657
            $oldPersonalSaltkey = htmlspecialchars_decode($dataReceived['old_sk']);
658
659
            // check old psk
660
            $user_key_encoded = defuse_validate_personal_key(
661
                $oldPersonalSaltkey,
662
                $_SESSION['user_settings']['encrypted_psk']
663
            );
664
            if (strpos($user_key_encoded, "Error ") !== false) {
665
                echo prepareExchangedData(
666
                    array(
667
                        "list" => $list,
668
                        "error" => $user_key_encoded,
669
                        "nb_total" => $number
670
                    ),
671
                    "encode"
672
                );
673
                break;
674
            } else {
675
                // Store PSK
676
                $_SESSION['user_settings']['encrypted_oldpsk'] = $user_key_encoded;
677
            }
678
679
            // generate the new encrypted psk based upon clear psk
680
            $_SESSION['user_settings']['encrypted_psk'] = defuse_generate_personal_key($newPersonalSaltkey);
681
682
            // store it in DB
683
            DB::update(
684
                prefix_table("users"),
685
                array(
686
                    'encrypted_psk' => $_SESSION['user_settings']['encrypted_psk']
687
                    ),
688
                "id = %i",
689
                $_SESSION['user_id']
690
            );
691
692
            $user_key_encoded = defuse_validate_personal_key(
693
                $newPersonalSaltkey,
694
                $_SESSION['user_settings']['encrypted_psk']
695
            );
696
            $_SESSION['user_settings']['session_psk'] = $user_key_encoded;
697
698
            // Change encryption
699
            // Build list of items to be re-encrypted
700
            $rows = DB::query(
701
                "SELECT i.id as id, i.pw as pw
702
                FROM ".prefix_table("items")." as i
703
                INNER JOIN ".prefix_table("log_items")." as l ON (i.id=l.id_item)
704
                WHERE i.perso = %i AND l.id_user= %i AND l.action = %s",
705
                "1",
706
                $_SESSION['user_id'],
707
                "at_creation"
708
            );
709
            $number = DB::count();
710
            foreach ($rows as $record) {
711
                if (!empty($record['pw'])) {
712
                    if (empty($list)) {
713
                        $list = $record['id'];
714
                    } else {
715
                        $list .= ",".$record['id'];
716
                    }
717
                }
718
            }
719
720
            // change salt
721
            setcookie(
722
                "TeamPass_PFSK_".md5($_SESSION['user_id']),
723
                encrypt($newPersonalSaltkey, ""),
724
                time() + 60 * 60 * 24 * $SETTINGS['personal_saltkey_cookie_duration'],
725
                '/'
726
            );
727
728
            echo prepareExchangedData(
729
                array(
730
                    "list" => $list,
731
                    "error" => "no",
732
                    "nb_total" => $number
733
                ),
734
                "encode"
735
            );
736
            break;
737
        /**
738
         * Reset the personal saltkey
739
         */
740
        case "reset_personal_saltkey":
741
            if (filter_input(INPUT_POST, 'key', FILTER_SANITIZE_STRING) !== $_SESSION['key']) {
742
                echo '[{"error" : "something_wrong"}]';
743
                break;
744
            }
745
746
            if (!empty($_SESSION['user_id'])) {
747
                // delete all previous items of this user
748
                $rows = DB::query(
749
                    "SELECT i.id as id
750
                    FROM ".prefix_table("items")." as i
751
                    INNER JOIN ".prefix_table("log_items")." as l ON (i.id=l.id_item)
752
                    WHERE i.perso = %i AND l.id_user= %i AND l.action = %s",
753
                    "1",
754
                    $_SESSION['user_id'],
755
                    "at_creation"
756
                );
757
                foreach ($rows as $record) {
758
                    // delete in ITEMS table
759
                    DB::delete(prefix_table("items"), "id = %i", $record['id']);
760
                    // delete in LOGS table
761
                    DB::delete(prefix_table("log_items"), "id_item = %i", $record['id']);
762
                    // delete from CACHE table
763
                    updateCacheTable("delete_value", $record['id']);
764
                }
765
766
                // remove from DB
767
                DB::update(
768
                    prefix_table("users"),
769
                    array(
770
                        'encrypted_psk' => ""
771
                        ),
772
                    "id = %i",
773
                    $_SESSION['user_id']
774
                );
775
776
                $_SESSION['user_settings']['session_psk'] = "";
777
            }
778
            break;
779
        /**
780
         * Change the user's language
781
         */
782
        case "change_user_language":
783
            if (!empty($_SESSION['user_id'])) {
784
                // decrypt and retreive data in JSON format
785
                $dataReceived = prepareExchangedData(
786
                    filter_input(INPUT_POST, 'data', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES),
787
                    "decode"
788
                );
789
                // Prepare variables
790
                $language = $dataReceived['lang'];
791
                // update DB
792
                DB::update(
793
                    prefix_table("users"),
794
                    array(
795
                        'user_language' => $language
796
                        ),
797
                    "id = %i",
798
                    $_SESSION['user_id']
799
                );
800
                $_SESSION['user_language'] = $language;
801
                echo "done";
802
            } else {
803
                $_SESSION['user_language'] = "";
804
                echo "done";
805
            }
806
            break;
807
        /**
808
         * Send emails not sent
809
         */
810
        case "send_waiting_emails":
811
            if (filter_input(INPUT_POST, 'key', FILTER_SANITIZE_STRING) !== $_SESSION['key']) {
812
                echo '[ { "error" : "key_not_conform" } ]';
813
                break;
814
            }
815
816
            if (isset($SETTINGS['enable_send_email_on_user_login'])
817
                && $SETTINGS['enable_send_email_on_user_login'] === "1"
818
            ) {
819
                $row = DB::queryFirstRow(
820
                    "SELECT valeur FROM ".prefix_table("misc")." WHERE type = %s AND intitule = %s",
821
                    "cron",
822
                    "sending_emails"
823
                );
824
                if ((time() - $row['valeur']) >= 300 || $row['valeur'] == 0) {
825
                    $rows = DB::query("SELECT * FROM ".prefix_table("emails")." WHERE status != %s", "sent");
826
                    foreach ($rows as $record) {
827
                        // Send email
828
                        $ret = sendEmail(
829
                            $record['subject'],
830
                            $record['body'],
831
                            $record['receivers']
832
                        );
833
834
                        if (strpos($ret, "error_mail_not_send") !== false) {
835
                            $status = "not_sent";
836
                        } else {
837
                            $status = "sent";
838
                        }
839
840
                        // update item_id in files table
841
                        DB::update(
842
                            prefix_table("emails"),
843
                            array(
844
                                'status' => $status
845
                                ),
846
                            "timestamp = %s",
847
                            $record['timestamp']
848
                        );
849
                    }
850
                }
851
                // update cron time
852
                DB::update(
853
                    prefix_table("misc"),
854
                    array(
855
                        'valeur' => time()
856
                        ),
857
                    "intitule = %s AND type = %s",
858
                    "sending_emails",
859
                    "cron"
860
                );
861
            }
862
            break;
863
864
        /**
865
         * Store error
866
         */
867
        case "store_error":
868
            if (!empty($_SESSION['user_id'])) {
869
                // update DB
870
                logEvents(
871
                    'error',
872
                    urldecode(filter_input(INPUT_POST, 'error', FILTER_SANITIZE_STRING)),
873
                    $_SESSION['user_id'],
874
                    $_SESSION['login']
875
                );
876
            }
877
            break;
878
879
        /**
880
         * Generate a password generic
881
         */
882
        case "generate_a_password":
883
            if (filter_input(INPUT_POST, 'size', FILTER_SANITIZE_NUMBER_INT) > $SETTINGS['pwd_maximum_length']) {
884
                echo prepareExchangedData(
885
                    array(
886
                        "error_msg" => "Password length is too long!",
887
                        "error" => "true"
888
                    ),
889
                    "encode"
890
                );
891
                break;
892
            }
893
894
            $generator = new SplClassLoader('PasswordGenerator\Generator', '../includes/libraries');
895
            $generator->register();
896
            $generator = new PasswordGenerator\Generator\ComputerPasswordGenerator();
897
898
            // Is PHP7 being used?
899
            if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
900
                $php7generator = new SplClassLoader('PasswordGenerator\RandomGenerator', '../includes/libraries');
901
                $php7generator->register();
902
                $generator->setRandomGenerator(new PasswordGenerator\RandomGenerator\Php7RandomGenerator());
903
            }
904
905
            $generator->setLength((int) filter_input(INPUT_POST, 'size', FILTER_SANITIZE_NUMBER_INT));
906
907
            if (null !== filter_input(INPUT_POST, 'secure_pwd', FILTER_SANITIZE_STRING)
908
                && filter_input(INPUT_POST, 'secure_pwd', FILTER_SANITIZE_STRING) === "true"
909
            ) {
910
                $generator->setSymbols(true);
911
                $generator->setLowercase(true);
912
                $generator->setUppercase(true);
913
                $generator->setNumbers(true);
914
            } else {
915
                $generator->setLowercase((filter_input(INPUT_POST, 'lowercase', FILTER_SANITIZE_STRING) === "true") ? true : false);
916
                $generator->setUppercase((filter_input(INPUT_POST, 'capitalize', FILTER_SANITIZE_STRING) === "true") ? true : false);
917
                $generator->setNumbers((filter_input(INPUT_POST, 'numerals', FILTER_SANITIZE_STRING) === "true") ? true : false);
918
                $generator->setSymbols((filter_input(INPUT_POST, 'symbols', FILTER_SANITIZE_STRING) === "true") ? true : false);
919
            }
920
921
            echo prepareExchangedData(
922
                array(
923
                    "key" => $generator->generatePasswords(),
924
                    "error" => ""
925
                ),
926
                "encode"
927
            );
928
            break;
929
        /**
930
         * Check if user exists and send back if psk is set
931
         */
932
        case "check_login_exists":
933
            $data = DB::query(
934
                "SELECT login, psk FROM ".prefix_table("users")."
935
                WHERE login = %i",
936
                mysqli_escape_string($link, stripslashes(filter_input(INPUT_POST, 'userId', FILTER_SANITIZE_NUMBER_INT)))
937
            );
938
            if (empty($data['login'])) {
939
                $userOk = false;
940
            } else {
941
                $userOk = true;
942
            }
943
            if (isset($SETTINGS['psk_authentication']) && $SETTINGS['psk_authentication'] == 1
944
                && !empty($data['psk'])
945
            ) {
946
                $pskSet = true;
947
            } else {
948
                $pskSet = false;
949
            }
950
951
            echo '[{"login" : "'.$userOk.'", "psk":"'.$pskSet.'"}]';
952
            break;
953
        /**
954
         * Make statistics on item
955
         */
956
        case "item_stat":
957
            if (null !== filter_input(INPUT_POST, 'scope', FILTER_SANITIZE_STRING)
958
                && filter_input(INPUT_POST, 'scope', FILTER_SANITIZE_STRING) === "item"
959
            ) {
960
                $data = DB::queryfirstrow(
961
                    "SELECT view FROM ".prefix_table("statistics")." WHERE scope = %s AND item_id = %i",
962
                    'item',
963
                    filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT)
964
                );
965
                $counter = DB::count();
966
                if ($counter == 0) {
967
                    DB::insert(
968
                        prefix_table("statistics"),
969
                        array(
970
                            'scope' => 'item',
971
                            'view' => '1',
972
                            'item_id' => filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT)
973
                        )
974
                    );
975
                } else {
976
                    DB::update(
977
                        prefix_table("statistics"),
978
                        array(
979
                            'scope' => 'item',
980
                            'view' => $data['view'] + 1
981
                        ),
982
                        "item_id = %i",
983
                        filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT)
984
                    );
985
                }
986
            }
987
988
            break;
989
        /**
990
         * Refresh list of last items seen
991
         */
992
        case "refresh_list_items_seen":
993
            if (filter_input(INPUT_POST, 'key', FILTER_SANITIZE_STRING) !== $_SESSION['key']) {
994
                echo '[ { "error" : "key_not_conform" } ]';
995
                break;
996
            }
997
998
            // get list of last items seen
999
            $x_counter = 1;
1000
            $arrTmp = array();
1001
            $arr_html = array();
1002
            $rows = DB::query(
1003
                "SELECT i.id AS id, i.label AS label, i.id_tree AS id_tree, l.date
1004
                FROM ".prefix_table("log_items")." AS l
1005
                RIGHT JOIN ".prefix_table("items")." AS i ON (l.id_item = i.id)
1006
                WHERE l.action = %s AND l.id_user = %i
1007
                ORDER BY l.date DESC
1008
                LIMIT 0, 100",
1009
                "at_shown",
1010
                $_SESSION['user_id']
1011
            );
1012
            if (DB::count() > 0) {
1013
                foreach ($rows as $record) {
1014
                    if (!in_array($record['id'], $arrTmp)) {
1015
                        array_push(
1016
                            $arr_html,
1017
                            array(
1018
                                "id" => $record['id'],
1019
                                "label" => htmlspecialchars(stripslashes(htmlspecialchars_decode($record['label'], ENT_QUOTES)), ENT_QUOTES),
1020
                                "tree_id" => $record['id_tree']
1021
                            )
1022
                        );
1023
                        $x_counter++;
1024
                        array_push($arrTmp, $record['id']);
1025
                        if ($x_counter >= 10) {
1026
                            break;
1027
                        }
1028
                    }
1029
                }
1030
            }
1031
1032
            // get wainting suggestions
1033
            $nb_suggestions_waiting = 0;
1034
            if (isset($SETTINGS['enable_suggestion']) && $SETTINGS['enable_suggestion'] == 1
1035
                && ($_SESSION['user_admin'] == 1 || $_SESSION['user_manager'] == 1)
1036
            ) {
1037
                DB::query("SELECT * FROM ".prefix_table("suggestion"));
1038
                $nb_suggestions_waiting = DB::count();
1039
            }
1040
1041
            echo json_encode(
1042
                array(
1043
                    "error" => "",
1044
                    "existing_suggestions" => $nb_suggestions_waiting,
1045
                    "html_json" => $arr_html
1046
                ),
1047
                JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP
1048
            );
1049
            break;
1050
1051
        /**
1052
         * Generates a KEY with CRYPT
1053
         */
1054
        case "generate_new_key":
1055
            // load passwordLib library
1056
            $pwdlib = new SplClassLoader('PasswordLib', '../includes/libraries');
1057
            $pwdlib->register();
1058
            $pwdlib = new PasswordLib\PasswordLib();
1059
            // generate key
1060
            $key = $pwdlib->getRandomToken(filter_input(INPUT_POST, 'size', FILTER_SANITIZE_NUMBER_INT));
1061
            echo '[{"key" : "'.htmlentities($key, ENT_QUOTES).'"}]';
1062
            break;
1063
1064
        /**
1065
         * Generates a TOKEN with CRYPT
1066
         */
1067
        case "save_token":
1068
            $token = GenerateCryptKey(
1069
                null !== filter_input(INPUT_POST, 'size', FILTER_SANITIZE_NUMBER_INT) ? filter_input(INPUT_POST, 'size', FILTER_SANITIZE_NUMBER_INT) : 20,
1070
                null !== filter_input(INPUT_POST, 'secure', FILTER_SANITIZE_BOOLEAN) ? filter_input(INPUT_POST, 'secure', FILTER_SANITIZE_BOOLEAN) : false,
0 ignored issues
show
Bug introduced by
The constant FILTER_SANITIZE_BOOLEAN was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1071
                null !== filter_input(INPUT_POST, 'numeric', FILTER_SANITIZE_BOOLEAN) ? filter_input(INPUT_POST, 'numeric', FILTER_SANITIZE_BOOLEAN) : false,
1072
                null !== filter_input(INPUT_POST, 'capital', FILTER_SANITIZE_BOOLEAN) ? filter_input(INPUT_POST, 'capital', FILTER_SANITIZE_BOOLEAN) : false,
1073
                null !== filter_input(INPUT_POST, 'symbols', FILTER_SANITIZE_BOOLEAN) ? filter_input(INPUT_POST, 'symbols', FILTER_SANITIZE_BOOLEAN) : false
1074
            );
1075
1076
            // store in DB
1077
            DB::insert(
1078
                prefix_table("tokens"),
1079
                array(
1080
                    'user_id' => $_SESSION['user_id'],
1081
                    'token' => $token,
1082
                    'reason' => filter_input(INPUT_POST, 'reason', FILTER_SANITIZE_STRING),
1083
                    'creation_timestamp' => time(),
1084
                    'end_timestamp' => time() + filter_input(INPUT_POST, 'duration', FILTER_SANITIZE_NUMBER_INT)    // in secs
1085
                )
1086
            );
1087
1088
            echo '[{"token" : "'.$token.'"}]';
1089
            break;
1090
1091
        /**
1092
         * Create list of timezones
1093
         */
1094
        case "generate_timezones_list":
1095
            $array = array();
1096
            foreach (timezone_identifiers_list() as $zone) {
1097
                $array[$zone] = $zone;
1098
            }
1099
1100
            echo json_encode($array);
1101
            break;
1102
1103
        /**
1104
         * Check if suggestions are existing
1105
         */
1106
        case "is_existings_suggestions":
1107
            if (filter_input(INPUT_POST, 'key', FILTER_SANITIZE_STRING) !== $_SESSION['key']) {
1108
                echo '[ { "error" : "key_not_conform" } ]';
1109
                break;
1110
            }
1111
1112
            if ($_SESSION['user_manager'] === "1" || $_SESSION['is_admin'] === "1") {
1113
                $count = 0;
1114
                DB::query("SELECT * FROM ".$pre."items_change");
1115
                $count += DB::count();
1116
                DB::query("SELECT * FROM ".$pre."suggestion");
1117
                $count += DB::count();
1118
1119
                echo '[ { "error" : "" , "count" : "'.$count.'" , "show_sug_in_menu" : "0"} ]';
1120
            } elseif (isset($_SESSION['nb_item_change_proposals']) && $_SESSION['nb_item_change_proposals'] > 0) {
1121
                echo '[ { "error" : "" , "count" : "'.$_SESSION['nb_item_change_proposals'].'" , "show_sug_in_menu" : "1"} ]';
1122
            } else {
1123
                echo '[ { "error" : "" , "count" : "" , "show_sug_in_menu" : "0"} ]';
1124
            }
1125
1126
            break;
1127
1128
        /**
1129
         * Check if suggestions are existing
1130
         */
1131
        case "sending_statistics":
1132
            if (filter_input(INPUT_POST, 'key', FILTER_SANITIZE_STRING) !== $_SESSION['key']) {
1133
                echo '[ { "error" : "key_not_conform" } ]';
1134
                break;
1135
            }
1136
1137
            if (isset($SETTINGS['send_statistics_items']) && isset($SETTINGS['send_stats']) && isset($SETTINGS['send_stats_time'])
1138
                && $SETTINGS['send_stats'] === "1"
1139
                && ($SETTINGS['send_stats_time'] + $SETTINGS_EXT['one_day_seconds']) > time()
1140
            ) {
1141
                // get statistics data
1142
                $stats_data = getStatisticsData();
1143
1144
1145
                // get statistics items to share
1146
                $statsToSend = [];
1147
                $statsToSend['ip'] = $_SERVER['SERVER_ADDR'];
1148
                $statsToSend['timestamp'] = time();
1149
                foreach (array_filter(explode(";", $SETTINGS['send_statistics_items'])) as $data) {
1150
                    if ($data === "stat_languages") {
1151
                        $tmp = "";
1152
                        foreach ($stats_data[$data] as $key => $value) {
1153
                            if (empty($tmp)) {
1154
                                $tmp = $key."-".$value;
1155
                            } else {
1156
                                $tmp .= ",".$key."-".$value;
1157
                            }
1158
                        }
1159
                        $statsToSend[$data] = $tmp;
1160
                    } elseif ($data === "stat_country") {
1161
                        $tmp = "";
1162
                        foreach ($stats_data[$data] as $key => $value) {
1163
                            if (empty($tmp)) {
1164
                                $tmp = $key."-".$value;
1165
                            } else {
1166
                                $tmp .= ",".$key."-".$value;
1167
                            }
1168
                        }
1169
                        $statsToSend[$data] = $tmp;
1170
                    } else {
1171
                        $statsToSend[$data] = $stats_data[$data];
1172
                    }
1173
                }
1174
1175
                // connect to Teampass Statistics database
1176
                db::debugmode(true);
1177
                $link2 = new MeekroDB(
1178
                    "sql11.freemysqlhosting.net",
1179
                    "sql11197223",
1180
                    "3QzpXYQ9dZ",
1181
                    "sql11197223",
1182
                    "3306",
1183
                    "utf8"
1184
                );
1185
1186
                $link2->insert(
1187
                    "statistics",
1188
                    $statsToSend
1189
                );
1190
1191
                // update table misc with current timestamp
1192
                DB::update(
1193
                    prefix_table("misc"),
1194
                    array(
1195
                        'valeur' => time()
1196
                        ),
1197
                    "type = %s AND intitule = %s",
1198
                    'admin',
1199
                    'send_stats_time'
1200
                );
1201
1202
1203
                //permits to test only once by session
1204
                $_SESSION['temporary']['send_stats_done'] = true;
1205
                $SETTINGS['send_stats_time'] = time();
1206
1207
                // save change in config file
1208
                handleConfigFile("update", 'send_stats_time', $SETTINGS['send_stats_time']);
1209
1210
                echo '[ { "error" : "" , "done" : "1"} ]';
1211
            } else {
1212
                echo '[ { "error" : "" , "done" : "0"} ]';
1213
            }
1214
1215
            break;
1216
1217
        /**
1218
         * delete a file
1219
         */
1220
        case "file_deletion":
1221
            if (filter_input(INPUT_POST, 'key', FILTER_SANITIZE_STRING) !== $_SESSION['key']) {
1222
                echo '[ { "error" : "key_not_conform" } ]';
1223
                break;
1224
            }
1225
1226
            fileDelete(filter_input(INPUT_POST, 'filename', FILTER_SANITIZE_STRING));
1227
1228
            break;
1229
1230
        /**
1231
         * Generate BUG report
1232
         */
1233
        case "generate_bug_report":
1234
            if (filter_input(INPUT_POST, 'key', FILTER_SANITIZE_STRING) !== $_SESSION['key']) {
1235
                echo '[ { "error" : "key_not_conform" } ]';
1236
                break;
1237
            }
1238
1239
            // Read config file
1240
            $tmp = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $tmp is dead and can be removed.
Loading history...
1241
            $list_of_options = '';
1242
            $url_found = '';
1243
            $anonym_url = '';
1244
            $tp_config_file = "../includes/config/tp.config.php";
1245
            $data = file($tp_config_file);
1246
            foreach ($data as $line) {
1247
                if (substr($line, 0, 4) === '    ') {
1248
                    // Remove extra spaces
1249
                    $line = str_replace('    ', '', $line);
1250
1251
                    // Identify url to anonymize it
1252
                    if (strpos($line, 'cpassman_url') > 0 && empty($url_found) === true) {
1253
                        $url_found = substr($line, 19, strlen($line) - 22);//echo $url_found." ; ";
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1254
                        $tmp = parse_url($url_found);
1255
                        $anonym_url = $tmp['scheme'] . '://<anonym_url>' . $tmp['path'];
1256
                        $line = "'cpassman_url' => '" . $anonym_url . "\n";
1257
                    }
1258
1259
                    // Anonymize all urls
1260
                    if (empty($anonym_url) === false) {
1261
                        $line = str_replace($url_found, $anonym_url, $line);
1262
                    }
1263
1264
                    // Clear bck_script_passkey
1265
                    if (strpos($line, 'bck_script_passkey') > 0) {
1266
                        $line = "'bck_script_passkey' => '<removed>'\n";
1267
                    }
1268
1269
                    // Complete line to display
1270
                    $list_of_options .= $line;
1271
                }
1272
            }
1273
1274
            // Get error
1275
            $err = error_get_last();
1276
1277
            // Get 10 latest errors in Teampass
1278
            $teampass_errors = '';
1279
            $rows = DB::query(
1280
                "SELECT label, date AS error_date
1281
                FROM ".prefix_table("log_system")."
1282
                WHERE `type` LIKE 'error'
1283
                ORDER BY `date` DESC
1284
                LIMIT 0, 10"
1285
            );
1286
            if (DB::count() > 0) {
1287
                foreach ($rows as $record) {
1288
                    if (empty($teampass_errors) === true) {
1289
                        $teampass_errors = ' * '.date($SETTINGS['date_format'].' '.$SETTINGS['time_format'], $record['error_date']).' - '.$record['label'];
1290
                    } else {
1291
                        $teampass_errors .= '
1292
 * '.date($SETTINGS['date_format'].' '.$SETTINGS['time_format'], $record['error_date']).' - '.$record['label'];
1293
                    }
1294
                }
1295
            }
1296
1297
            // Now prepare text
1298
            $txt = "### Steps to reproduce
1299
1.
1300
2.
1301
3.
1302
1303
### Expected behaviour
1304
Tell us what should happen
1305
1306
1307
### Actual behaviour
1308
Tell us what happens instead
1309
1310
### Server configuration
1311
**Operating system**: ".php_uname()."
1312
1313
**Web server:** ".$_SERVER['SERVER_SOFTWARE']."
1314
1315
**Database:** ".mysqli_get_server_info($link)."
1316
1317
**PHP version:** ".PHP_VERSION."
1318
1319
**Teampass version:** ".$SETTINGS_EXT['version_full']."
1320
1321
**Teampass configuration file:**
1322
```
1323
" . $list_of_options . "
1324
```
1325
1326
**Updated from an older Teampass or fresh install:**
1327
1328
### Client configuration
1329
1330
**Browser:** ".filter_input(INPUT_POST, 'browser_name', FILTER_SANITIZE_STRING)." - ".filter_input(INPUT_POST, 'browser_version', FILTER_SANITIZE_STRING)."
1331
1332
**Operating system:** ".filter_input(INPUT_POST, 'os', FILTER_SANITIZE_STRING)." - ".filter_input(INPUT_POST, 'os_archi', FILTER_SANITIZE_STRING)."bits
1333
1334
### Logs
1335
1336
#### Web server error log
1337
```
1338
" . $err['message']." - ".$err['file']." (".$err['line'] .")
1339
```
1340
1341
#### Teampass 10 last system errors
1342
```
1343
" . $teampass_errors ."
1344
```
1345
1346
#### Log from the web-browser developer console (CTRL + SHIFT + i)
1347
```
1348
Insert the log here and especially the answer of the query that failed.
1349
```
1350
";
1351
1352
            echo prepareExchangedData(
1353
                array(
1354
                    "html" => $txt,
1355
                    "error" => ""
1356
                ),
1357
                "encode"
1358
            );
1359
1360
            break;
1361
    }
1362
}
1363