Passed
Branch wip_sessions (830972)
by Nils
07:55
created

handleSecurefileConstant()   C

Complexity

Conditions 13
Paths 131

Size

Total Lines 104
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
eloc 52
nc 131
nop 0
dl 0
loc 104
rs 6.3583
c 1
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
2
3
use Hackzilla\PasswordGenerator\Generator\ComputerPasswordGenerator;
4
use Hackzilla\PasswordGenerator\RandomGenerator\Php7RandomGenerator;
5
use Defuse\Crypto\Key;
6
use Defuse\Crypto\Crypto;
7
use Defuse\Crypto\Exception as CryptoException;
8
9
// new SECUREFILE - 3.0.0.23
10
function handleSecurefileConstant()
11
{
12
    if (defined('SECUREFILE') === false || SECUREFILE === 'teampass-seckey.txt' || file_exists(SECUREPATH.'/teampass-seckey.txt') === true) {
13
        // Anonymize the file if needed
14
        if (defined('SECUREFILE') === false) {
15
            define('SECUREFILE', generateRandomKey());
16
        }
17
    
18
        // manage the file itself by renaming it
19
        if (rename(SECUREPATH.'/teampass-seckey.txt', SECUREPATH.'/'.SECUREFILE) === false) {
20
            echo '[{
21
                "error" : "File `'.SECUREPATH.'/teampass-seckey.txt` could not be renamed. Please do it by yourself and click on button Launch.",
22
                "index" : ""
23
            }]';
24
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

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

Loading history...
25
        }
26
27
        // Ensure DB is read as UTF8
28
        if (defined('DB_ENCODING') === false) {
29
            define('DB_ENCODING', "utf8");
30
        }
31
32
        // Now create new file
33
        $file_handled = fopen('../includes/config/settings.php', 'w');
34
        
35
        $settingsTxt = '<?php
36
// DATABASE connexion parameters
37
define("DB_HOST", "' . DB_HOST . '");
38
define("DB_USER", "' . DB_USER . '");
39
define("DB_PASSWD", "' . DB_PASSWD . '");
40
define("DB_NAME", "' . DB_NAME . '");
41
define("DB_PREFIX", "' . DB_PREFIX . '");
42
define("DB_PORT", "' . DB_PORT . '");
43
define("DB_ENCODING", "' . DB_ENCODING . '");';
44
45
if (isset(DB_SSL['key']) === true && empty(DB_SSL['key']) === false) {
46
    $settingsTxt .= '
47
define("DB_SSL", false); // if DB over SSL then comment this line
48
// if DB over SSL then uncomment the following lines
49
//define("DB_SSL", array(
50
//    "key" => "",
51
//    "cert" => "",
52
//    "ca_cert" => "",
53
//    "ca_path" => "",
54
//    "cipher" => ""
55
//));';
56
} else {
57
    $settingsTxt .= '
58
//define("DB_SSL", false); // if DB over SSL then comment this line
59
// if DB over SSL then uncomment the following lines
60
define("DB_SSL", array(
61
    "key" => "'.DB_SSL['key'].'",
62
    "cert" => "'.DB_SSL['cert'].'",
63
    "ca_cert" => ""'.DB_SSL['ca_cert'].',
64
    "ca_path" => "'.DB_SSL['ca_path'].'",
65
    "cipher" => "'.DB_SSL['cipher'].'"
66
));';
67
}
68
69
$settingsTxt .= '
70
define("DB_CONNECT_OPTIONS", array(
71
    MYSQLI_OPT_CONNECT_TIMEOUT => 10
72
));
73
define("SECUREPATH", "' . str_replace('\\', '\\\\', SECUREPATH) . '");
74
define("SECUREFILE", "' . SECUREFILE. '");';
75
76
        if (defined('IKEY') === true) $settingsTxt .= '
77
define("IKEY", "' . IKEY . '");';
78
        else $settingsTxt .= '
79
define("IKEY", "");';
80
        if (defined('SKEY') === true) $settingsTxt .= '
81
define("SKEY", "' . SKEY . '");';
82
        else $settingsTxt .= '
83
define("SKEY", "");';
84
        if (defined('HOST') === true) $settingsTxt .= '
85
define("HOST", "' . HOST . '");';
86
        else $settingsTxt .= '
87
define("HOST", "");';
88
89
90
        $settingsTxt .= '
91
92
if (isset($_SESSION[\'settings\'][\'timezone\']) === true) {
93
    date_default_timezone_set($_SESSION[\'settings\'][\'timezone\']);
94
}
95
';
96
97
        $fileCreation = fwrite(
98
            $file_handled,
99
            utf8_encode($settingsTxt)
100
        );
101
102
        fclose($file_handled);
103
        sleep(3);
104
        if ($fileCreation === false) {
105
            return [
106
                'error' => true,
107
                'message' => 'Setting.php file could not be created in /includes/config/ folder. Please check the path and the rights.',
108
            ];
109
        }
110
111
        return [
112
            'error' => false,
113
            'message' => ''
114
        ];
115
    }
116
}
117
118
/**
119
 * Undocumented function
120
 *
121
 * @param string $message   Message
122
 * @param string $ascii_key Key
123
 * @param string $type      Type
124
 *
125
 * @return array
126
 */
127
function defuseCryption($message, $ascii_key, $type)
128
{
129
    include_once '../includes/config/settings.php';
130
131
    // init
132
    $err = '';
133
    if (empty($ascii_key) === true) {
134
        // new check - 3.0.0.23
135
        $ascii_key = file_get_contents(SECUREPATH.'/'.SECUREFILE);
136
    }
137
    
138
    // convert KEY
139
    $key = Key::loadFromAsciiSafeString($ascii_key);
140
141
    try {
142
        if ($type === 'encrypt') {
143
            $text = Crypto::encrypt($message, $key);
144
        } elseif ($type === 'decrypt') {
145
            $text = Crypto::decrypt($message, $key);
146
        }
147
    } catch (CryptoException\WrongKeyOrModifiedCiphertextException $ex) {
148
        $err = 'an attack! either the wrong key was loaded, or the ciphertext has changed since it was created either corrupted in the database or intentionally modified by someone trying to carry out an attack.';
149
    } catch (CryptoException\BadFormatException $ex) {
150
        $err = $ex;
151
    } catch (CryptoException\EnvironmentIsBrokenException $ex) {
152
        $err = $ex;
153
    } catch (CryptoException\CryptoException $ex) {
154
        $err = $ex;
155
    } catch (CryptoException\IOException $ex) {
156
        $err = $ex;
157
    }
158
159
    return array(
160
        'string' => isset($text) ? $text : '',
161
        'error' => $err,
162
    );
163
}
164
165
166
/**
167
 * Decrypt a defuse string if encrypted
168
 *
169
 * @param string $value Encrypted string
170
 *
171
 * @return string
172
 */
173
function defuse_return_decrypted($value)
174
{
175
    if (substr($value, 0, 3) === "def") {
176
        $value = defuseCryption(
177
            $value,
178
            "",
179
            "decrypt"
180
        )['string'];
181
    }
182
    return $value;
183
}
184
185
/**
186
 * Function permits to get the value from a line
187
 *
188
 * @param string $val A string
189
 *
190
 * @return string
191
 */
192
function getSettingValue($val): string
193
{
194
    $val = trim(strstr($val, "="));
195
    return trim(str_replace('"', '', substr($val, 1, strpos($val, ";") - 1)));
196
}
197
198
/**
199
 * Undocumented function
200
 *
201
 * @param string $dbname     DB
202
 * @param string $column     Column
203
 * @param string $columnAttr Attribute
204
 *
205
 * @return boolean
206
 */
207
function addColumnIfNotExist($dbname, $column, $columnAttr = "VARCHAR(255) NULL")
208
{
209
    global $db_link;
210
    $exists = false;
211
    $columns = mysqli_query($db_link, "show columns from $dbname");
212
    while ($col = mysqli_fetch_assoc($columns)) {
0 ignored issues
show
Bug introduced by
It seems like $columns can also be of type true; however, parameter $result of mysqli_fetch_assoc() does only seem to accept mysqli_result, 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

212
    while ($col = mysqli_fetch_assoc(/** @scrutinizer ignore-type */ $columns)) {
Loading history...
213
        if ((string) $col['Field'] === $column) {
214
            $exists = true;
0 ignored issues
show
Unused Code introduced by
The assignment to $exists is dead and can be removed.
Loading history...
215
            return true;
216
        }
217
    }
218
    if (!$exists && empty($column) === false) {
0 ignored issues
show
introduced by
The condition $exists is always false.
Loading history...
219
        return mysqli_query($db_link, "ALTER TABLE `$dbname` ADD `$column`  $columnAttr");
0 ignored issues
show
Bug Best Practice introduced by
The expression return mysqli_query($db_...lumn.'` '.$columnAttr) also could return the type mysqli_result which is incompatible with the documented return type boolean.
Loading history...
220
    }
221
222
    return false;
223
}
224
225
/**
226
 * Remove column from table if exists
227
 *
228
 * @param string $table      Table
229
 * @param string $column     Column
230
 *
231
 * @return boolean
232
 */
233
function removeColumnIfNotExist($table, $column): bool
234
{
235
    global $db_link;
236
    $exists = false;
237
    $columns = mysqli_query($db_link, "show columns from $table");
238
    while ($col = mysqli_fetch_assoc($columns)) {
0 ignored issues
show
Bug introduced by
It seems like $columns can also be of type true; however, parameter $result of mysqli_fetch_assoc() does only seem to accept mysqli_result, 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

238
    while ($col = mysqli_fetch_assoc(/** @scrutinizer ignore-type */ $columns)) {
Loading history...
239
        if ((string) $col['Field'] === $column) {
240
            $exists = true;
241
        }
242
    }
243
    if ($exists === true) {
244
        return mysqli_query($db_link, "ALTER TABLE `$table` DROP `$column`;");
0 ignored issues
show
Bug Best Practice introduced by
The expression return mysqli_query($db_...` DROP `'.$column.'`;') could return the type mysqli_result which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
245
    }
246
    return false;
247
}
248
249
/**
250
 * Check if an INDEX exist, run the SQL query if not
251
 *
252
 * @param string $table Table
253
 * @param string $index Index
254
 * @param string $sql   SQL
255
 *
256
 * @return array
257
 */
258
function checkIndexExist($table, $index, $sql)
259
{
260
    global $db_link;
261
    $mysqli_result = mysqli_query($db_link, "SHOW INDEX FROM $table WHERE key_name LIKE \"$index\"");
262
    $res = mysqli_fetch_row($mysqli_result);
0 ignored issues
show
Bug introduced by
It seems like $mysqli_result can also be of type true; however, parameter $result of mysqli_fetch_row() does only seem to accept mysqli_result, 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

262
    $res = mysqli_fetch_row(/** @scrutinizer ignore-type */ $mysqli_result);
Loading history...
263
264
    // if index does not exist, then add it
265
    if (!$res) {
266
        $res = mysqli_query(
267
            $db_link,
268
            "ALTER TABLE `$table` ".$sql
269
        );
270
    }
271
272
    return $res;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $res also could return the type mysqli_result|true which is incompatible with the documented return type array.
Loading history...
273
}
274
275
/**
276
 * Check if a table exists in DB
277
 *
278
 * @param string $tablename Table
279
 *
280
 * @return boolean
281
 */
282
function tableExists($tablename)
283
{
284
    global $db_link, $database;
285
286
    $res = mysqli_query(
287
        $db_link,
288
        "SELECT COUNT(*) as count
289
        FROM information_schema.tables
290
        WHERE table_schema = '".$database."'
291
        AND table_name = '$tablename'"
292
    );
293
294
    if ($res > 0) {
295
        return true;
296
    }
297
298
    return false;
299
}
300
301
/**
302
 * Undocumented function
303
 *
304
 * @param string $txt My text
305
 *
306
 * @return string
307
 */
308
function cleanFields($txt)
309
{
310
    $tmp = str_replace(",", ";", trim($txt));
311
    if (empty($tmp)) {
312
        return $tmp;
313
    }
314
    if ($tmp === ";") {
315
        return "";
316
    }
317
    if (strpos($tmp, ';') === 0) {
318
        $tmp = substr($tmp, 1);
319
    }
320
    if (substr($tmp, -1) !== ";") {
321
        $tmp = $tmp.";";
322
    }
323
    return $tmp;
324
}
325
326
/**
327
 * Undocumented function
328
 *
329
 * @return string
330
 */
331
function generateRandomKey()
332
{
333
    $generator = new ComputerPasswordGenerator();
334
335
    $generator->setLength(40);
336
    $generator->setSymbols(false);
337
    $generator->setLowercase(true);
338
    $generator->setUppercase(true);
339
    $generator->setNumbers(true);
340
341
    $key = $generator->generatePasswords();
342
343
    return $key[0];
344
}
345
346
/**
347
 * Undocumented function
348
 *
349
 * @param string $table
350
 * @param string $type
351
 * @param string $label
352
 * @param string $value
353
 * @return void
354
 */
355
function addNewSetting($table, $type, $label, $value): void
356
{
357
    global $db_link;
358
359
    // check if setting already exists
360
    $data = mysqli_fetch_row(mysqli_query($db_link, "SELECT COUNT(*) FROM ".$table." WHERE type = '".$type."' AND intitule = '".$label."'"));
0 ignored issues
show
Bug introduced by
It seems like mysqli_query($db_link, '...le = '' . $label . ''') can also be of type true; however, parameter $result of mysqli_fetch_row() does only seem to accept mysqli_result, 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

360
    $data = mysqli_fetch_row(/** @scrutinizer ignore-type */ mysqli_query($db_link, "SELECT COUNT(*) FROM ".$table." WHERE type = '".$type."' AND intitule = '".$label."'"));
Loading history...
361
    if ((int) $data[0] === 0) {
362
        // add setting
363
        mysqli_query(
364
            $db_link,
365
            "INSERT INTO ".$table."
366
            (`type`, `intitule`, `valeur`)
367
            VALUES ('".$type."', '".$label."', '".$value."')"
368
        );
369
    }
370
}
371
372
/**
373
 * Permits to remove a setting
374
 *
375
 * @param string $table
376
 * @param string $type
377
 * @param string $label
378
 * @return void
379
 */
380
function removeSetting($table, $type, $label): void
381
{
382
    global $db_link;
383
384
    // check if setting already exists
385
    $data = mysqli_fetch_row(mysqli_query($db_link, "SELECT COUNT(*) FROM ".$table." WHERE type = '".$type."' AND intitule = '".$label."'"));
0 ignored issues
show
Bug introduced by
It seems like mysqli_query($db_link, '...le = '' . $label . ''') can also be of type true; however, parameter $result of mysqli_fetch_row() does only seem to accept mysqli_result, 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

385
    $data = mysqli_fetch_row(/** @scrutinizer ignore-type */ mysqli_query($db_link, "SELECT COUNT(*) FROM ".$table." WHERE type = '".$type."' AND intitule = '".$label."'"));
Loading history...
386
    if ((int) $data[0] === 1) {
387
        // delete setting
388
        mysqli_query(
389
            $db_link,
390
            "DELETE FROM ".$table."
391
            WHERE type = '".$type."' AND intitule = '".$label."'"
392
        );
393
    }
394
}
395
396
/**
397
 * Permits to change a column name if exists
398
 *
399
 * @param string $table
400
 * @param string $oldName
401
 * @param string $newName
402
 * @param string $type
403
 * @return void
404
 */
405
function changeColumnName($table, $oldName, $newName, $type): void
406
{
407
    global $db_link;
408
409
    // check if column already exists
410
    $columns = mysqli_query($db_link, "show columns from `" . $table . "`");
411
    while ($col = mysqli_fetch_assoc($columns)) {
0 ignored issues
show
Bug introduced by
It seems like $columns can also be of type true; however, parameter $result of mysqli_fetch_assoc() does only seem to accept mysqli_result, 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

411
    while ($col = mysqli_fetch_assoc(/** @scrutinizer ignore-type */ $columns)) {
Loading history...
412
        if ((string) $col['Field'] === $oldName) {
413
            // change column name
414
            mysqli_query(
415
                $db_link,
416
                "ALTER TABLE ".$table." CHANGE `".$oldName."` `".$newName."` ".$type
417
            );
418
            break;
419
        }
420
    }
421
}
422
423
/**
424
 * Permits to locate the php binary
425
 * 
426
 * @return array
427
 */
428
function findPhpBinary(): array
429
{
430
    $phpPath = '';
431
    
432
    // Essayer de trouver le fichier binaire de PHP dans les chemins de recherche standards
433
    $paths = explode(PATH_SEPARATOR, getenv('PATH'));
434
    foreach ($paths as $path) {
435
        $phpBinary = $path . DIRECTORY_SEPARATOR . 'php';
436
        if (is_executable($phpBinary)) {
437
        $phpPath = $phpBinary;
438
        break;
439
        }
440
    }
441
442
    // Si le fichier binaire de PHP n'a pas été trouvé, on essaie de le chercher via les variables d'environnement
443
    if (!$phpPath && getenv('PHP_BINARY')) {
444
        $phpPath = getenv('PHP_BINARY');
445
    }
446
447
    // Si on n'a toujours pas trouvé le fichier binaire de PHP, on lance une exception
448
    if (!$phpPath) {
449
        return [
450
            'path' => '',
451
            'error' => true,
452
        ];
453
    }
454
455
    return [
456
        'path' => $phpPath,
457
        'error' => false,
458
    ];
459
}
460
461
/**
462
 * delete all files and directories
463
 *
464
 * @param array $folders
465
 * @return void
466
 */
467
function deleteAll(array $folders)
468
{
469
470
    foreach($folders as $folder) {
471
        deleteAllFolder($folder);
472
    }
473
}
474
475
/**
476
 * Delete recursively a folder
477
 *
478
 * @param string $str
479
 * @return void
480
 */
481
function deleteAllFolder(string $str)
482
{
483
    // Check for files 
484
    if (is_file($str)) { 
485
        // If it is file then remove by 
486
        // using unlink function 
487
        @unlink($str); 
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

487
        /** @scrutinizer ignore-unhandled */ @unlink($str); 

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...
488
    } 
489
    // If it is a directory. 
490
    elseif (is_dir($str)) { 
491
        // Get the list of the files in this 
492
        // directory 
493
        $scan = glob(rtrim($str, '/').'/*'); 
494
495
        // Loop through the list of files 
496
        foreach($scan as $index=>$path) { 
497
498
            // Call recursive function 
499
            deleteAllFolder($path); 
500
        } 
501
502
        // Remove the directory itself 
503
        @rmdir($str); 
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rmdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

503
        /** @scrutinizer ignore-unhandled */ @rmdir($str); 

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...
504
    } 
505
}