Completed
Push — development ( 6352e5...8bea34 )
by Nils
07:55
created

upgrade_run_2.1.27.php ➔ cleanFields()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 11
nc 6
nop 1
dl 0
loc 17
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * @file          upgrade.ajax.php
4
 * @author        Nils Laumaillé
5
 * @version       2.1.27
6
 * @copyright     (c) 2009-2017 Nils Laumaillé
7
 * @licensing     GNU AFFERO GPL 3.0
8
 * @link          http://www.teampass.net
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
15
/*
16
** Upgrade script for release 2.1.27
17
*/
18
require_once('../sources/SecureHandler.php');
19
session_start();
20
error_reporting(E_ERROR | E_PARSE);
21
$_SESSION['db_encoding'] = "utf8";
22
$_SESSION['CPM'] = 1;
23
24
require_once '../includes/language/english.php';
25
require_once '../includes/config/include.php';
26
require_once '../includes/config/settings.php';
27
require_once '../sources/main.functions.php';
28
29
$_SESSION['settings']['loaded'] = "";
30
31
32
/**
33
 * Function permits to get the value from a line
34
 * @param  string $val [description]
35
 * @return string      [description]
36
 */
37
function getSettingValue($val)
0 ignored issues
show
Best Practice introduced by
The function getSettingValue() has been defined more than once; this definition is ignored, only the first definition in api/functions.php (L149-159) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
38
{
39
    $val = trim(strstr($val, "="));
40
    return trim(str_replace('"', '', substr($val, 1, strpos($val, ";") - 1)));
41
}
42
43
/**
44
 * Function permits to check if a column exists, and if not to add it
45
 * @param string $db         [description]
46
 * @param string $column     [description]
47
 * @param string $columnAttr [description]
48
 */
49 View Code Duplication
function addColumnIfNotExist($db, $column, $columnAttr = "VARCHAR(255) NULL")
0 ignored issues
show
Best Practice introduced by
The function addColumnIfNotExist() has been defined more than once; this definition is ignored, only the first definition in install/upgrade_ajax.php (L65-79) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
50
{
51
    global $dbTmp;
52
    $exists = false;
53
    $columns = mysqli_query($dbTmp, "show columns from $db");
54
    while ($c = mysqli_fetch_assoc($columns)) {
55
        if ($c['Field'] == $column) {
56
            $exists = true;
0 ignored issues
show
Unused Code introduced by
$exists is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
57
            return true;
58
        }
59
    }
60
    if (!$exists) {
61
        return mysqli_query($dbTmp, "ALTER TABLE `$db` ADD `$column`  $columnAttr");
62
    } else {
63
        return false;
64
    }
65
}
66
67 View Code Duplication
function addIndexIfNotExist($table, $index, $sql)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Best Practice introduced by
The function addIndexIfNotExist() has been defined more than once; this definition is ignored, only the first definition in install/upgrade_ajax.php (L81-94) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
68
{
69
    global $dbTmp;
70
71
    $mysqli_result = mysqli_query($dbTmp, "SHOW INDEX FROM $table WHERE key_name LIKE \"$index\"");
72
    $res = mysqli_fetch_row($mysqli_result);
73
74
    // if index does not exist, then add it
75
    if (!$res) {
76
        $res = mysqli_query($dbTmp, "ALTER TABLE `$table` ".$sql);
77
    }
78
79
    return $res;
80
}
81
82 View Code Duplication
function tableExists($tablename)
0 ignored issues
show
Best Practice introduced by
The function tableExists() has been defined more than once; this definition is ignored, only the first definition in install/upgrade_ajax.php (L96-113) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
83
{
84
    global $dbTmp;
85
86
    $res = mysqli_query(
87
        $dbTmp,
88
        "SELECT COUNT(*) as count
89
        FROM information_schema.tables
90
        WHERE table_schema = '".$_SESSION['db_bdd']."'
91
        AND table_name = '$tablename'"
92
    );
93
94
    if ($res > 0) {
95
        return true;
96
    } else {
97
        return false;
98
    }
99
}
100
101
function cleanFields($txt)
102
{
103
    $tmp = str_replace(",", ";", trim($txt));
104
    if (empty($tmp)) {
105
        return $tmp;
106
    }
107
    if ($tmp === ";") {
108
        return "";
109
    }
110
    if (strpos($tmp, ';') === 0) {
111
        $tmp = substr($tmp, 1);
112
    }
113
    if (substr($tmp, -1) !== ";") {
114
        $tmp = $tmp.";";
115
    }
116
    return $tmp;
117
}
118
119
//define pbkdf2 iteration count
120
@define('ITCOUNT', '2072');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
121
122
$return_error = "";
123
124
// do initial upgrade
125
126
//include librairies
127
require_once '../includes/libraries/Tree/NestedTree/NestedTree.php';
128
129
//Build tree
130
$tree = new Tree\NestedTree\NestedTree(
131
    $_SESSION['pre'].'nested_tree',
132
    'id',
133
    'parent_id',
134
    'title'
135
);
136
137
// dataBase
138
$res = "";
139
$dbTmp = mysqli_connect(
140
    $_SESSION['server'],
141
    $_SESSION['user'],
142
    $_SESSION['pass'],
143
    $_SESSION['database'],
144
    $_SESSION['port']
145
);
146
147
// 2.1.27 introduce new encryption protocol with DEFUSE library.
148
// Now evaluate if current instance has already this version
149
$tmp = mysqli_fetch_row(mysqli_query($dbTmp, "SELECT valeur FROM `".$_SESSION['pre']."misc` WHERE type = 'admin' AND intitule = 'teampass_version'"));
150 View Code Duplication
if (count($tmp[0]) === 0 || empty($tmp[0])) {
151
    mysqli_query(
152
        $dbTmp,
153
        "INSERT INTO `".$_SESSION['pre']."misc` (`type`, `intitule`, `valeur`) VALUES ('admin', 'teampass_version', '".$k['version']."')"
154
    );
155
} else {
156
    mysqli_query(
157
        $dbTmp,
158
        "UPDATE `".$_SESSION['pre']."misc`
159
        SET `valeur` = '".$k['version']."'
160
        WHERE intitule = 'teampass_version' AND type = 'admin'"
161
    );
162
}
163
164
// add new admin setting "migration_to_2127"
165
$tmp = mysqli_num_rows(mysqli_query($dbTmp, "SELECT * FROM `".$_SESSION['pre']."misc` WHERE type = 'admin' AND intitule = 'migration_to_2127'"));
166
if ($tmp === "0") {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $tmp (integer) and '0' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
167
    mysqli_query(
168
        $dbTmp,
169
        "INSERT INTO `".$_SESSION['pre']."misc` (`type`, `intitule`, `valeur`) VALUES ('admin', 'migration_to_2127', '0')"
170
    );
171
}
172
173
174
// check if library defuse already on-going here
175
// if yes, then don't execute re-encryption
176 View Code Duplication
if (isset($_SESSION['tp_defuse_installed']) !== true) {
177
    $_SESSION['tp_defuse_installed'] = false;
178
    $columns = mysqli_query($dbTmp, "show columns from ".$_SESSION['pre']."items");
179
    while ($c = mysqli_fetch_assoc($columns)) {
180
        if ($c['Field'] === "encryption_type") {
181
            $_SESSION['tp_defuse_installed'] = true;
182
        }
183
    }
184
}
185
186
// alter table Items
187
mysqli_query($dbTmp, "ALTER TABLE `".$_SESSION['pre']."items` MODIFY pw_len INT(5) NOT NULL DEFAULT '0'");
188
189
// alter table misc to add an index
190
mysqli_query(
191
    $dbTmp,
192
    "ALTER TABLE `".$_SESSION['pre']."misc` ADD `id` INT(12) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`)"
193
);
194
195
// alter table misc to add an index
196
mysqli_query(
197
    $dbTmp,
198
    "ALTER TABLE `".$_SESSION['pre']."log_items` ADD `increment_id` INT(12) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`increment_id`)"
199
);
200
201
// add field agses-usercardid to Users table
202
$res = addColumnIfNotExist(
203
    $_SESSION['pre']."users",
204
    "agses-usercardid",
205
    "VARCHAR(12) NOT NULL DEFAULT '0'"
206
);
207
if ($res === false) {
208
    echo '[{"finish":"1", "msg":"", "error":"An error appears when adding field agses-usercardid to table Users! '.mysqli_error($dbTmp).'!"}]';
209
    mysqli_close($dbTmp);
210
    exit();
211
}
212
213
214
// add field encrypted_data to Categories table
215
$res = addColumnIfNotExist(
216
    $_SESSION['pre']."categories",
217
    "encrypted_data",
218
    "TINYINT(1) NOT NULL DEFAULT '1'"
219
);
220
if ($res === false) {
221
    echo '[{"finish":"1", "msg":"", "error":"An error appears when adding field encrypted_data to table categories! '.mysqli_error($dbTmp).'!"}]';
222
    mysqli_close($dbTmp);
223
    exit();
224
}
225
226
227
// alter table USERS - user_language
228
mysqli_query($dbTmp, "ALTER TABLE `".$_SESSION['pre']."users` MODIFY user_language VARCHAR(50) NOT NULL DEFAULT '0'");
229
230
// alter table USERS - just ensure correct naming of IsAdministratedByRole
231
mysqli_query($dbTmp, "ALTER TABLE `".$_SESSION['pre']."users` CHANGE IsAdministratedByRole isAdministratedByRole tinyint(5) NOT NULL DEFAULT '0'");
232
233
// alter table OTV
234
mysqli_query($dbTmp, "ALTER TABLE `".$_SESSION['pre']."otv` CHANGE originator originator int(12) NOT NULL DEFAULT '0'");
235
236
// do clean of users table
237
$fieldsToUpdate = ['groupes_visibles', 'fonction_id', 'groupes_interdits'];
238
$result = mysqli_query($dbTmp, "SELECT id, groupes_visibles, fonction_id, groupes_interdits FROM `".$_SESSION['pre']."users`");
239
while ($row = mysqli_fetch_assoc($result)) {
240
    // check if field contains , instead of ;
241
    foreach ($fieldsToUpdate as $field) {
242
        $tmp = cleanFields($row[$field]);
243
        if ($tmp !== $row[$field]) {
244
            mysqli_query(
245
                $dbTmp,
246
                "UPDATE `".$_SESSION['pre']."users`
247
                SET `".$field."` = '".$tmp."'
248
                WHERE id = '".$row['id']."'"
249
            );
250
        }
251
    }
252
}
253
mysqli_free_result($result);
254
255
256
// alter table KB_ITEMS
257
mysqli_query($dbTmp, "ALTER TABLE `".$_SESSION['pre']."kb_items` CHANGE `kb_id` `kb_id` INT(12) NOT NULL");
258
mysqli_query($dbTmp, "ALTER TABLE `".$_SESSION['pre']."kb_items` CHANGE `item_id` `item_id` INT(12) NOT NULL");
259
260
261
// add field encrypted_data to CATEGORIES table
262
$res = addColumnIfNotExist(
263
    $_SESSION['pre']."categories",
264
    "encrypted_data",
265
    "TINYINT(1) NOT NULL DEFAULT '1'"
266
);
267
if ($res === false) {
268
    echo '[{"finish":"1", "msg":"", "error":"An error appears when adding field encrypted_data to table CATEGORIES! '.mysqli_error($dbTmp).'!"}]';
269
    mysqli_close($dbTmp);
270
    exit();
271
}
272
273
mysqli_query(
274
    $dbTmp,
275
    "UPDATE `".$_SESSION['pre']."misc`
276
    SET `valeur` = 'maintenance_mode'
277
    WHERE type = 'admin' AND intitule = '".intval($_POST['no_maintenance_mode'])."'"
278
);
279
280
281
// add field encryption_type to ITEMS table
282
$res = addColumnIfNotExist(
283
    $_SESSION['pre']."items",
284
    "encryption_type",
285
    "VARCHAR(20) NOT NULL DEFAULT 'not_set'"
286
);
287
if ($res === false) {
288
    echo '[{"finish":"1", "msg":"", "error":"An error appears when adding field encryption_type to table ITEMS! '.mysqli_error($dbTmp).'!"}]';
289
    mysqli_close($dbTmp);
290
    exit();
291
}
292
293
294
// add field encryption_type to categories_items table
295
$res = addColumnIfNotExist(
296
    $_SESSION['pre']."categories_items",
297
    "encryption_type",
298
    "VARCHAR(20) NOT NULL DEFAULT 'not_set'"
299
);
300
if ($res === false) {
301
    echo '[{"finish":"1", "msg":"", "error":"An error appears when adding field encryption_type to table categories_items! '.mysqli_error($dbTmp).'!"}]';
302
    mysqli_close($dbTmp);
303
    exit();
304
}
305
306
307
// add field encryption_type to LOG_ITEMS table
308
$res = addColumnIfNotExist(
309
    $_SESSION['pre']."log_items",
310
    "encryption_type",
311
    "VARCHAR(20) NOT NULL DEFAULT 'not_set'"
312
);
313
if ($res === false) {
314
    echo '[{"finish":"1", "msg":"", "error":"An error appears when adding field encryption_type to table LOG_ITEMS! '.mysqli_error($dbTmp).'!"}]';
315
    mysqli_close($dbTmp);
316
    exit();
317
}
318
319
320
// add field URL to CACHE table
321
$res = addColumnIfNotExist(
322
    $_SESSION['pre']."cache",
323
    "encryption_type",
324
    "VARCHAR(500) NOT NULL DEFAULT '0'"
325
);
326
if ($res === false) {
327
    echo '[{"finish":"1", "msg":"", "error":"An error appears when adding field URL to table CACHE! '.mysqli_error($dbTmp).'!"}]';
328
    mysqli_close($dbTmp);
329
    exit();
330
}
331
332
333
// add field timestamp to CACHE table
334
$res = addColumnIfNotExist(
335
    $_SESSION['pre']."cache",
336
    "timestamp",
337
    "VARCHAR(50) DEFAULT NULL DEFAULT '0'"
338
);
339
if ($res === false) {
340
    echo '[{"finish":"1", "msg":"", "error":"An error appears when adding field url to table CACHE! '.mysqli_error($dbTmp).'!"}]';
341
    mysqli_close($dbTmp);
342
    exit();
343
}
344
345
346
// add field url to CACHE table
347
$res = addColumnIfNotExist(
348
    $_SESSION['pre']."cache",
349
    "url",
350
    "VARCHAR(500) DEFAULT NULL"
351
);
352
if ($res === false) {
353
    echo '[{"finish":"1", "msg":"", "error":"An error appears when adding field timestamp to table CACHE! '.mysqli_error($dbTmp).'!"}]';
354
    mysqli_close($dbTmp);
355
    exit();
356
}
357
358
//-- generate new DEFUSE key
359
if (!isset($_SESSION['tp_defuse_installed']) || $_SESSION['tp_defuse_installed'] === false) {
360
    $filename = "../includes/config/settings.php";
361
    $settingsFile = file($filename);
362
    while (list($key, $val) = each($settingsFile)) {
363
        if (substr_count($val, 'require_once "') > 0 && substr_count($val, 'sk.php') > 0) {
364
            $_SESSION['sk_file'] = substr($val, 14, strpos($val, '";') - 14);
365
        }
366
    }
367
368
    copy(
369
        SECUREPATH."/teampass-seckey.txt",
370
        SECUREPATH."/teampass-seckey.txt".'.'.date("Y_m_d", mktime(0, 0, 0, date('m'), date('d'), date('y'))).".".time()
371
    );
372
    $_SESSION['tp_defuse_new_key'] = true;
373
    $new_salt = defuse_generate_key();
374
    file_put_contents(
375
        SECUREPATH."/teampass-seckey.txt",
376
        $new_salt
377
    );
378
    $_SESSION['new_salt'] = $new_salt;
379
380
    // update sk.php file
381
    copy(
382
        $_SESSION['sk_file'],
383
        $_SESSION['sk_file'].'.'.date("Y_m_d", mktime(0, 0, 0, date('m'), date('d'), date('y'))).".".time()
384
    );
385
    $data = file($_SESSION['sk_file']); // reads an array of lines
386
    function replace_a_line($data)
387
    {
388
        global $new_salt;
389
        if (stristr($data, "@define('SALT'")) {
390
            return "";
391
        }
392
        return $data;
393
    }
394
    $data = array_map('replace_a_line', $data);
395
    file_put_contents($_SESSION['sk_file'], implode('', $data));
396
397
    //
398
    //
399
    //-- users need to perform re-encryption of their personal pwds
400
    $result = mysqli_query(
401
        $dbTmp,
402
        "SELECT valeur FROM `".$_SESSION['pre']."misc` WHERE type='admin' AND intitule='encryption_type'"
403
    );
404
    $row = mysqli_fetch_assoc($result);
405
    if ($row['valeur'] !== "defuse") {
406
        $result = mysqli_query(
407
            $dbTmp,
408
            "SELECT id FROM `".$_SESSION['pre']."users`"
409
        );
410
        while ($row_user = mysqli_fetch_assoc($result)) {
411
            $result_items = mysqli_query(
412
                $dbTmp,
413
                "SELECT i.id AS item_id
414
                FROM `".$_SESSION['pre']."nested_tree` AS n
415
                INNER JOIN `".$_SESSION['pre']."items` AS i ON (i.id_tree = n.id)
416
                WHERE n.title = ".$row_user['id']
417
            );
418
            if (mysqli_num_rows($result_items) > 0) {
419
                mysqli_query(
420
                    $dbTmp,
421
                    "UPDATE `".$_SESSION['pre']."users`
422
                    SET `upgrade_needed` = '1'
423
                    WHERE id = ".$row_user['id']
424
                );
425
            } else {
426
                mysqli_query(
427
                    $dbTmp,
428
                    "UPDATE `".$_SESSION['pre']."users`
429
                    SET `upgrade_needed` = '0'
430
                    WHERE id = ".$row_user['id']
431
                );
432
            }
433
        }
434
435
        mysqli_query(
436
            $dbTmp,
437
            "UPDATE `".$_SESSION['pre']."misc`
438
            SET `valeur` = 'defuse'
439
            WHERE `type`='admin' AND `initule`='encryption_type'"
440
        );
441
    }
442
} else {
443
    $_SESSION['tp_defuse_new_key'] = false;
444
}
445
//--
446
447
448
// add field encrypted_psk to Users table
449
$res = addColumnIfNotExist(
450
    $_SESSION['pre']."users",
451
    "encrypted_psk",
452
    "TEXT NOT NULL"
453
);
454
if ($res === false) {
455
    echo '[{"finish":"1", "msg":"", "error":"An error appears when adding field encrypted_psk to table Users! '.mysqli_error($dbTmp).'!"}]';
456
    mysqli_close($dbTmp);
457
    exit();
458
}
459
460
461
// add new admin setting "manager_move_item"
462
$tmp = mysqli_num_rows(mysqli_query($dbTmp, "SELECT * FROM `".$_SESSION['pre']."misc` WHERE type = 'admin' AND intitule = 'manager_move_item'"));
463
if ($tmp === "0") {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $tmp (integer) and '0' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
464
    mysqli_query(
465
        $dbTmp,
466
        "INSERT INTO `".$_SESSION['pre']."misc` (`type`, `intitule`, `valeur`) VALUES ('admin', 'manager_move_item', '0')"
467
    );
468
}
469
470
// add new admin setting "create_item_without_password"
471
$tmp = mysqli_num_rows(mysqli_query($dbTmp, "SELECT * FROM `".$_SESSION['pre']."misc` WHERE type = 'admin' AND intitule = 'create_item_without_password'"));
472
if ($tmp === "0") {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $tmp (integer) and '0' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
473
    mysqli_query(
474
        $dbTmp,
475
        "INSERT INTO `".$_SESSION['pre']."misc` (`type`, `intitule`, `valeur`) VALUES ('admin', 'create_item_without_password', '0')"
476
    );
477
}
478
479
// add new admin setting "send_statistics_items"
480
$tmp = mysqli_num_rows(mysqli_query($dbTmp, "SELECT * FROM `".$_SESSION['pre']."misc` WHERE type = 'admin' AND intitule = 'send_statistics_items'"));
481
if ($tmp === "0") {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $tmp (integer) and '0' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
482
    mysqli_query(
483
        $dbTmp,
484
        "INSERT INTO `".$_SESSION['pre']."misc` (`type`, `intitule`, `valeur`) VALUES ('admin', 'send_statistics_items', 'stat_country;stat_users;stat_items;stat_items_shared;stat_folders;stat_folders_shared;stat_admins;stat_managers;stat_ro;stat_mysqlversion;stat_phpversion;stat_teampassversion;stat_languages;stat_kb;stat_suggestion;stat_customfields;stat_api;stat_2fa;stat_agses;stat_duo;stat_ldap;stat_syslog;stat_stricthttps;stat_fav;stat_pf;')"
485
    );
486
}
487
488
// add new admin setting "send_stats_time"
489
$tmp = mysqli_num_rows(mysqli_query($dbTmp, "SELECT * FROM `".$_SESSION['pre']."misc` WHERE type = 'admin' AND intitule = 'send_stats_time'"));
490
if ($tmp === "0") {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $tmp (integer) and '0' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
491
    mysqli_query(
492
        $dbTmp,
493
        "INSERT INTO `".$_SESSION['pre']."misc` (`type`, `intitule`, `valeur`) VALUES ('admin', 'send_stats_time', '".(time() - 2592000)."')"
494
    );
495
}
496
497
// add new admin setting "agses_authentication_enabled"
498
$tmp = mysqli_num_rows(mysqli_query($dbTmp, "SELECT * FROM `".$_SESSION['pre']."misc` WHERE type = 'admin' AND intitule = 'agses_authentication_enabled'"));
499
if ($tmp === "0") {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $tmp (integer) and '0' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
500
    mysqli_query(
501
        $dbTmp,
502
        "INSERT INTO `".$_SESSION['pre']."misc` (`type`, `intitule`, `valeur`) VALUES ('admin', 'agses_authentication_enabled', '0')"
503
    );
504
}
505
506
// add new language "portuges_br"
507
$tmp = mysqli_num_rows(mysqli_query($dbTmp, "SELECT * FROM `".$_SESSION['pre']."languages` WHERE name = 'portuguese_br'"));
508
if ($tmp === "0") {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $tmp (integer) and '0' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
509
    mysqli_query(
510
        $dbTmp,
511
        "INSERT INTO `".$_SESSION['pre']."languages` (`name`, `label`, `code`, `flag`) VALUES ('portuguese_br', 'Portuguese_br', 'pr-bt', 'pr-bt.png')"
512
    );
513
}
514
515
516
// alter table USERS to add a new field "ga_temporary_code"
517
mysqli_query(
518
    $dbTmp,
519
    "ALTER TABLE `".$_SESSION['pre']."users` ADD `ga_temporary_code` VARCHAR(20) NOT NULL DEFAULT 'none' AFTER `ga`;"
520
);
521
// alter table USERS to add a new field "user_ip"
522
mysqli_query(
523
    $dbTmp,
524
    "ALTER TABLE `".$_SESSION['pre']."users` ADD `user_ip` VARCHAR(60) NOT NULL DEFAULT 'none';"
525
);
526
527
528
// alter table EXPORT to add a new fields
529
mysqli_query(
530
    $dbTmp,
531
    "ALTER TABLE `".$_SESSION['pre']."export` ADD `email` VARCHAR(500) NOT NULL DEFAULT 'none';"
532
);
533
mysqli_query(
534
    $dbTmp,
535
    "ALTER TABLE `".$_SESSION['pre']."export` ADD `url` VARCHAR(500) NOT NULL DEFAULT 'none';"
536
);
537
mysqli_query(
538
    $dbTmp,
539
    "ALTER TABLE `".$_SESSION['pre']."export` ADD `kbs` VARCHAR(500) NOT NULL DEFAULT 'none';"
540
);
541
mysqli_query(
542
    $dbTmp,
543
    "ALTER TABLE `".$_SESSION['pre']."export` ADD `tags` VARCHAR(500) NOT NULL DEFAULT 'none';"
544
);
545
546
// alter table MISC
547
mysqli_query(
548
    $dbTmp,
549
    "ALTER TABLE `".$_SESSION['pre']."misc` ADD `id` INT(12) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`);"
550
);
551
mysqli_query(
552
    $dbTmp,
553
    "ALTER TABLE `".$_SESSION['pre']."misc` CHANGE valeur valeur VARCHAR(500) NOT NULL DEFAULT 'none'"
554
);
555
556
// alter table ITEMS_CHANGE
557
mysqli_query(
558
    $dbTmp,
559
    "ALTER TABLE `".$_SESSION['pre']."items_change` CHANGE user_id user_id INT(12) NOT NULL;"
560
);
561
562
// alter table ITEMS
563
mysqli_query(
564
    $dbTmp,
565
    "ALTER TABLE `".$_SESSION['pre']."items` CHANGE auto_update_pwd_next_date auto_update_pwd_next_date VARCHAR(100) NOT NULL DEFAULT '0';"
566
);
567
568
569
// add new admin setting "otv_is_enabled"
570
$tmp = mysqli_num_rows(mysqli_query($dbTmp, "SELECT * FROM `".$_SESSION['pre']."misc` WHERE type = 'admin' AND intitule = 'otv_is_enabled'"));
571
if ($tmp === "0") {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $tmp (integer) and '0' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
572
    mysqli_query(
573
        $dbTmp,
574
        "INSERT INTO `".$_SESSION['pre']."misc` (`type`, `intitule`, `valeur`) VALUES ('admin', 'otv_is_enabled', '0')"
575
    );
576
}
577
578
579
// add new field for items_change
580
mysqli_query(
581
    $dbTmp,
582
    "CREATE TABLE IF NOT EXISTS `".$_SESSION['pre']."items_change` (
583
    `id` int(12) NOT NULL AUTO_INCREMENT,
584
    `item_id` int(12) NOT NULL,
585
    `label` varchar(255) NOT NULL DEFAULT 'none',
586
    `pw` text NOT NULL,
587
    `login` varchar(255) NOT NULL DEFAULT 'none',
588
    `email` varchar(255) NOT NULL DEFAULT 'none',
589
    `url` varchar(255) NOT NULL DEFAULT 'none',
590
    `description` text NOT NULL,
591
    `comment` text NOT NULL,
592
    `folder_id` tinyint(12) NOT NULL,
593
    `user_id` tinyint(12) NOT NULL,
594
    `timestamp` varchar(50) NOT NULL DEFAULT 'none',
595
    PRIMARY KEY (`id`)
596
    ) CHARSET=utf8;"
597
);
598
599
600
601
// File encryption
602
// add field status to FILE table
603
$res = addColumnIfNotExist(
604
    $_SESSION['pre']."files",
605
    "status",
606
    "VARCHAR(50) NOT NULL DEFAULT '0'"
607
);
608
if ($res === false) {
609
    echo '[{"finish":"1", "msg":"", "error":"An error appears when adding field agses-usercardid to table Users! '.mysqli_error($dbTmp).'!"}]';
610
    mysqli_close($dbTmp);
611
    exit();
612
}
613
614
// fill in this new field with the current "encryption-file" status
615
$tmp = mysqli_fetch_row(mysqli_query($dbTmp, "SELECT valeur FROM `".$_SESSION['pre']."misc` WHERE type = 'admin' AND intitule = 'enable_attachment_encryption'"));
616
if (!empty($tmp[0])) {
617
    if ($tmp[0] === "1") {
618
        $status = "encrypted";
619
    } else {
620
        $status = "clear";
621
    }
622
    mysqli_query($dbTmp, "update `".$_SESSION['pre']."files` set status = '".$status."' where 1 = 1");
623
}
624
625
626
// add 2 generic users
627
$tmp = mysqli_num_rows(mysqli_query($dbTmp, "SELECT * FROM `".$_SESSION['pre']."users` WHERE id = '9999991' AND login = 'OTV'"));
628
if ($tmp === "0") {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $tmp (integer) and '0' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
629
    mysqli_query(
630
        $dbTmp,
631
        "INSERT INTO `".$_SESSION['pre']."users` (`id`, `login`, `pw`, `groupes_visibles`, `derniers`, `key_tempo`, `last_pw_change`, `last_pw`, `admin`, `fonction_id`, `groupes_interdits`, `last_connexion`, `gestionnaire`, `email`, `favourites`, `latest_items`, `personal_folder`) VALUES ('9999991', 'OTV', '', '', '', '', '', '', '1', '', '', '', '0', '', '', '', '0')"
632
    );
633
}
634
$tmp = mysqli_num_rows(mysqli_query($dbTmp, "SELECT * FROM `".$_SESSION['pre']."users` WHERE id = '9999991' AND login = 'OTV'"));
635
if ($tmp === "0") {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $tmp (integer) and '0' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
636
    mysqli_query(
637
        $dbTmp,
638
        "INSERT INTO `".$_SESSION['pre']."users` (`id`, `login`, `pw`, `groupes_visibles`, `derniers`, `key_tempo`, `last_pw_change`, `last_pw`, `admin`, `fonction_id`, `groupes_interdits`, `last_connexion`, `gestionnaire`, `email`, `favourites`, `latest_items`, `personal_folder`) VALUES ('9999999', 'API', '', '', '', '', '', '', '1', '', '', '', '0', '', '', '', '0')"
639
    );
640
}
641
642
643
// Update favico to favicon
644
$result = mysqli_query($dbTmp, "SELECT valeur FROM `".$_SESSION['pre']."misc` WHERE intitule = 'cpassman_url' AND type = 'admin'");
645
$rows = mysqli_fetch_assoc($result);
646
mysqli_free_result($result);
647
mysqli_query(
648
    $dbTmp,
649
    "UPDATE `".$_SESSION['pre']."misc`
650
    SET `valeur` = '".$rows['valeur']."/favicon.ico'
651
    WHERE intitule = 'favicon' AND type = 'admin'"
652
);
653
654
655
656
/*
657
* Introduce new CONFIG file
658
*/
659
$tp_config_file = "../includes/config/tp.config.php";
660 View Code Duplication
if (file_exists($tp_config_file)) {
661
    if (!copy($tp_config_file, $tp_config_file.'.'.date("Y_m_d", mktime(0, 0, 0, date('m'), date('d'), date('y'))))) {
662
        echo '[{"error" : "includes/config/tp.config.php file already exists and cannot be renamed. Please do it by yourself and click on button Launch.", "result":"", "index" : "'.$_POST['index'].'", "multiple" : "'.$_POST['multiple'].'"}]';
0 ignored issues
show
Security Cross-Site Scripting introduced by
'[{"error" : "includes/c...OST['multiple'] . '"}]' can contain request data and is used in output context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST
    in install/upgrade_run_2.1.27.php on line 662

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
663
        return false;
664
    } else {
665
        unlink($tp_config_file);
666
    }
667
}
668
$fh = fopen($tp_config_file, 'w');
669
$config_text = "<?php
670
global \$SETTINGS;
671
\$SETTINGS = array (";
672
673
$result = mysqli_query($dbTmp, "SELECT * FROM `".$_SESSION['pre']."misc` WHERE type = 'admin'");
674
while ($row = mysqli_fetch_assoc($result)) {
675
    // append new setting in config file
676
    $config_text .= "
677
    '".$row['intitule']."' => '".$row['valeur']."',";
678
}
679
mysqli_free_result($result);
680
681
// write to config file
682
$result = fwrite(
683
    $fh,
684
    utf8_encode(
685
        substr_replace($config_text, "", -1)."
686
);"
687
    )
688
);
689
fclose($fh);
690
691
// Finished
692
echo '[{"finish":"1" , "next":"", "error":""}]';
693