Passed
Push — master ( 32b95a...2c2bb9 )
by Stefan
05:45 queued 29s
created

SanityTests::makensis_test()   D

Complexity

Conditions 9
Paths 11

Size

Total Lines 27
Code Lines 21

Duplication

Lines 11
Ratio 40.74 %

Importance

Changes 0
Metric Value
dl 11
loc 27
c 0
b 0
f 0
rs 4.909
cc 9
eloc 21
nc 11
nop 0
1
<?php
2
/* 
3
 *******************************************************************************
4
 * Copyright 2011-2017 DANTE Ltd. and GÉANT on behalf of the GN3, GN3+, GN4-1 
5
 * and GN4-2 consortia
6
 *
7
 * License: see the web/copyright.php file in the file structure
8
 *******************************************************************************
9
 */
10
11
/**
12
 * 
13
 * 
14
 * This is the definition of the CAT class implementing various configuration
15
 * tests. 
16
 * Each test is implemented as a priviate method which needs to be named "test_name_test".
17
 * The test returns the results by calling the test_return method, this passing the return
18
 * code and the explanatory message. Multiple calls to test_return are allowed.
19
 *
20
 * An individual test can be run by the "test" method which takes the test name as an argument
21
 * multiple tests should be run by the run_all_tests method which takes an array as an argument
22
 * see method descriptions for more information.
23
 * 
24
 * The results of the tests are passed within the $test_result array
25
 *
26
 * Some configuration of this class is required, see further down.
27
 * @author Stefan Winter <[email protected]>
28
 * @author Tomasz Wolniewicz <[email protected]>
29
 *
30
 * @license see LICENSE file in root directory
31
 *
32
 * @package Utilities
33
 */
34
namespace core;
35
use GeoIp2\Database\Reader;
36
use \Exception;
37
38
require_once(dirname(dirname(__FILE__)) . "/config/_config.php");
39
require_once(dirname(dirname(__FILE__)) . "/core/PHPMailer/src/PHPMailer.php");
40
require_once(dirname(dirname(__FILE__)) . "/core/PHPMailer/src/SMTP.php");
41
42
class SanityTests extends CAT {
43
    /* in this section set current CAT requirements */
44
45
    /* $php_needversion sets the minumum required php version */
46
47
    // because of bug:
48
    // Fixed bug #74005 (mail.add_x_header causes RFC-breaking lone line feed).
49
    private $php_needversion = '7.0.17';
50
51
    /* List all required NSIS modules below */
52
    private $NSIS_Modules = [
53
        "nsArray.nsh",
54
        "FileFunc.nsh",
55
        "LogicLib.nsh",
56
        "WordFunc.nsh",
57
        "FileFunc.nsh",
58
        "x64.nsh",
59
    ];
60
61
    /* set $profile_option_ct to the number of rows returned by "SELECT * FROM profile_option_dict" */
62
    private $profile_option_ct = 33;
63
    /* set $view_admin_ct to the number of rows returned by "desc view_admin" */
64
    private $view_admin_ct = 8;
65
66
    /* end of config */
67
    public $out;
68
    public $name;
69
70
    public function __construct() {
71
        parent::__construct();
72
        $this->test_result = [];
73
        $this->test_result['global'] = 0;
74
    }
75
76
    /**
77
     * The single test wrapper
78
     * @param string $test the test name
79
     */
80
    public function test($test) {
81
        $this->out[$test] = [];
82
        $this->name = $test;
83
        $m_name = $test . '_test';
84
        $this->test_result[$test] = 0;
85
        if (!method_exists($this, $m_name)) {
86
            $this->test_return(\core\common\Entity::L_ERROR, "Configuration error, no test configured for <strong>$test</strong>.");
87
            return;
88
        }
89
        $this->$m_name();
90
    }
91
92
    /**
93
     * The multiple tests wrapper
94
     * @param array $Tests the tests array.
95
     *
96
     * The $Tests is a simple string array, where each entry is a test name
97
     * the test names can also be given in the format "test=>subtest", which 
98
     * defines a conditional execution of the "subtest" if the "test" was run earier
99
     * and returned a success.
100
     */
101
    public function run_tests($Tests) {
102
        foreach ($Tests as $testName) {
103
            $matchArray = [];
104
            if (preg_match('/(.+)=>(.+)/', $testName, $matchArray)) {
105
                $tst = $matchArray[1];
106
                $subtst = $matchArray[2];
107
                if ($this->test_result[$tst] < \core\common\Entity::L_ERROR) {
108
                    $this->test($subtst);
109
                }
110
            } else {
111
                $this->test($testName);
112
            }
113
        }
114
    }
115
116
    public function get_test_names() {
117
        $T = get_class_methods($this);
118
        $out = [];
119
        foreach ($T as $t) {
120
            if (preg_match('/^(.*)_test$/', $t, $m)) {
121
                $out[] = $m[1];
122
            }
123
        }
124
        return $out;
125
    }
126
127
    /**
128
     * This array is used to return the test results.
129
     * As the 'global' entry it returns the maximum return value
130
     * from all tests.
131
     * Individual tests results are teturned as separate entires
132
     * indexed by test names; each value is an array passing "level" and "message"
133
     * from each of the tests.
134
     * $test_result is set by the test_return method
135
     *
136
     * @var array $test_result
137
     */
138
    public $test_result;
139
140
    private function test_return($level, $message) {
141
        $this->out[$this->name][] = ['level' => $level, 'message' => $message];
142
        $this->test_result[$this->name] = max($this->test_result[$this->name], $level);
143
        $this->test_result['global'] = max($this->test_result['global'], $level);
144
    }
145
146
    private function get_exec_path($pathToCheck) {
147
        $the_path = "";
148
        $exec_is = "UNDEFINED";
149
        foreach ([CONFIG, CONFIG_CONFASSISTANT, CONFIG_DIAGNOSTICS] as $config) { 
150
            if (!empty($config['PATHS'][$pathToCheck])) {
151
                $matchArray = [];
152
                preg_match('/([^ ]+) ?/', $config['PATHS'][$pathToCheck], $matchArray);
153
                $exe = $matchArray[1];
154
                $the_path = exec("which " . $config['PATHS'][$pathToCheck]);
155
                if ($the_path == $exe) {
156
                    $exec_is = "EXPLICIT";
157
                } else {
158
                    $exec_is = "IMPLICIT";
159
                }
160
                return(['exec' => $the_path, 'exec_is' => $exec_is]);
161
            }
162
        }
163
        return(['exec' => $the_path, 'exec_is' => $exec_is]);
164
    }
165
166
    /**
167
     *  Test for php version
168
     */
169
    private function php_test() {
170
        if (version_compare(phpversion(), $this->php_needversion, '>=')) {
171
            $this->test_return(\core\common\Entity::L_OK, "<strong>PHP</strong> is sufficiently recent. You are running " . phpversion() . ".");
172
        } else {
173
            $this->test_return(\core\common\Entity::L_ERROR, "<strong>PHP</strong> is too old. We need at least $this->php_needversion, but you only have " . phpversion() . ".");
174
        }
175
    }
176
177
    /**
178
     * test for simpleSAMLphp
179
     */
180
    private function ssp_test() {
181
        if (!is_file(CONFIG['AUTHENTICATION']['ssp-path-to-autoloader'])) {
182
            $this->test_return(\core\common\Entity::L_ERROR, "<strong>simpleSAMLphp</strong> not found!");
183
        } else {
184
            $this->test_return(\core\common\Entity::L_OK, "<strong>simpleSAMLphp</strong> autoloader found.");
185
        }
186
    }
187
188
    /**
189
     * test for security setting
190
     */
191
    private function security_test() {
192
        if (in_array("I do not care about security!", CONFIG['SUPERADMINS'])) {
193
            $this->test_return(\core\common\Entity::L_WARN, "You do not care about security. This page should be made accessible to the CAT admin only! See config.php 'Superadmins'!");
194
        }
195
    }
196
197
    /**
198
     * test if zip is available
199
     */
200
    private function zip_test() {
201 View Code Duplication
        if (exec("which zip") != "") {
202
            $this->test_return(\core\common\Entity::L_OK, "<strong>zip</strong> binary found.");
203
        } else {
204
            $this->test_return(\core\common\Entity::L_ERROR, "<strong>zip</strong> not found in your \$PATH!");
205
        }
206
    }
207
208
    /**
209
     * test if eapol_test is availabe and reacent enough
210
     */
211
    private function eapol_test_test() {
212
        exec(CONFIG_DIAGNOSTICS['PATHS']['eapol_test'], $out, $retval);
213
        if ($retval == 255) {
214
            $o = preg_grep('/-o<server cert/', $out);
215 View Code Duplication
            if (count($o) > 0) {
216
                $this->test_return(\core\common\Entity::L_OK, "<strong>eapol_test</strong> script found.");
217
            } else {
218
                $this->test_return(\core\common\Entity::L_ERROR, "<strong>eapol_test</strong> found, but is too old!");
219
            }
220
        } else {
221
            $this->test_return(\core\common\Entity::L_ERROR, "<strong>eapol_test</strong> not found!");
222
        }
223
    }
224
225
    /**
226
     * test if logdir exists and is writable
227
     */
228
    private function logdir_test() {
229
        if (fopen(CONFIG['PATHS']['logdir'] . "/debug.log", "a") == FALSE) {
230
            $this->test_return(\core\common\Entity::L_WARN, "Log files in <strong>" . CONFIG['PATHS']['logdir'] . "</strong> are not writable!");
231
        } else {
232
            $this->test_return(\core\common\Entity::L_OK, "Log directory is writable.");
233
        }
234
    }
235
236
    /**
237
     * test for required PHP modules
238
     */
239
    private function phpModules_test() {
240
        if (function_exists('idn_to_ascii')) {
241
            $this->test_return(\core\common\Entity::L_OK, "PHP can handle internationalisation.");
242
        } else {
243
            $this->test_return(\core\common\Entity::L_ERROR, "PHP can <strong>NOT</strong> handle internationalisation (idn_to_ascii() from php7.0-intl).");
244
        }
245
246
        if (function_exists('gettext')) {
247
            $this->test_return(\core\common\Entity::L_OK, "PHP extension <strong>GNU Gettext</strong> is installed.");
248
        } else {
249
            $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>GNU Gettext</strong> not found!");
250
        }
251
252
        if (function_exists('openssl_sign')) {
253
            $this->test_return(\core\common\Entity::L_OK, "PHP extension <strong>OpenSSL</strong> is installed.");
254
        } else {
255
            $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>OpenSSL</strong> not found!");
256
        }
257
258
        if (class_exists('\Imagick')) {
259
            $this->test_return(\core\common\Entity::L_OK, "PHP extension <strong>Imagick</strong> is installed.");
260
        } else {
261
            $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>Imagick</strong> not found! Get it from your distribution or <a href='http://pecl.php.net/package/imagick'>here</a>.");
262
        }
263
264
        if (function_exists('ImageCreate')) {
265
            $this->test_return(\core\common\Entity::L_OK, "PHP extension <strong>GD</strong> is installed.");
266
        } else {
267
            $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>GD</strong> not found!</a>.");
268
        }
269
270
        if (function_exists('mysqli_connect')) {
271
            $this->test_return(\core\common\Entity::L_OK, "PHP extension <strong>MySQL</strong> is installed.");
272
        } else {
273
            $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>MySQL</strong> not found!");
274
        }
275
    }
276
277
    /**
278
     * test if GeoIP is installed correctly
279
     */
280
    private function geoip_test() {
281
        $host_4 = '145.0.2.50';
282
        $host_6 = '2001:610:188:444::50';
283
        switch (CONFIG['GEOIP']['version']) {
284
            case 0:
285
                $this->test_return(\core\common\Entity::L_REMARK, "As set in the config, no geolocation service will be used");
286
                break;
287
            case 1:
288
                if (!function_exists('geoip_record_by_name')) {
289
                    $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>GeoIP</strong> (legacy) not found! Get it from your distribution or <a href='http://pecl.php.net/package/geoip'>here</a> or better install GeoIP2 from <a href='https://github.com/maxmind/GeoIP2-php'>here</a>.");
290
                    return;
291
                }
292
                $record = geoip_record_by_name($host_4);
293
                if ($record === FALSE) {
294
                    $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>GeoIP</strong> (legacy) found but not working properly, perhaps you need to download the databases. See utils/GeoIP-update.sh in the CAT distribution and use it tu update the GeoIP database regularly.");
295
                    return;
296
                }
297
                if ($record['city'] != 'Utrecht') {
298
                    $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>GeoIP</strong> (legacy) found but not working properly, perhaps you need to download the databases. See utils/GeoIP-update.sh in the CAT distribution and use it tu update the GeoIP database regularly.");
299
                    return;
300
                }
301
                $this->test_return(\core\common\Entity::L_REMARK, "PHP extension <strong>GeoIP</strong> (legacy) is installed and working. See utils/GeoIP-update.sh in the CAT distribution and use it tu update the GeoIP database regularly. We stronly advise to replace the legacy GeoIP with GeoIP2 from <a href='https://github.com/maxmind/GeoIP2-php'>here</a>.");
302
                break;
303
            case 2:
304 View Code Duplication
                if (!is_file(CONFIG['GEOIP']['geoip2-path-to-autoloader'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
305
                    $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>GeoIP2</strong> not found! Get it from <a href='https://github.com/maxmind/GeoIP2-php'>here</a>.");
306
                    return;
307
                }
308 View Code Duplication
                if (!is_file(CONFIG['GEOIP']['geoip2-path-to-db'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
309
                    $this->test_return(\core\common\Entity::L_ERROR, "<strong>GeoIP2 database</strong> not found! See utils/GeoIP-update.sh in the CAT distribution and use it tu update the GeoIP database regularly.");
310
                    return;
311
                }
312
                require_once CONFIG['GEOIP']['geoip2-path-to-autoloader'];
313
                $reader = new Reader(CONFIG['GEOIP']['geoip2-path-to-db']);
314
                try {
315
                    $record = $reader->city($host_4);
316
                } catch (Exception $e) {
317
                    $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>GeoIP2</strong> found but not working properly, perhaps you need to download the databases. See utils/GeoIP-update.sh in the CAT distribution and use it tu update the GeoIP database regularly.");
318
                    return;
319
                }
320
                if ($record->city->name != 'Utrecht') {
321
                    $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>GeoIP2</strong> found but not working properly, perhaps you need to download the databases. See utils/GeoIP-update.sh in the CAT distribution and use it tu update the GeoIP database regularly.");
322
                    return;
323
                }
324
                try {
325
                    $record = $reader->city($host_6);
326
                } catch (Exception $e) {
327
                    $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>GeoIP2</strong> found but not working properly with IPv6, perhaps you need to download the databases. See utils/GeoIP-update.sh in the CAT distribution and use it tu update the GeoIP database regularly.");
328
                    return;
329
                }
330
                if ($record->city->name != 'Utrecht') {
331
                    $this->test_return(\core\common\Entity::L_ERROR, "PHP extension <strong>GeoIP2</strong> found but not working properly with IPv6, perhaps you need to download the databases. See utils/GeoIP-update.sh in the CAT distribution and use it tu update the GeoIP database regularly.");
332
                    return;
333
                }
334
                $this->test_return(\core\common\Entity::L_OK, "PHP extension <strong>GeoIP2</strong> is installed and working. See utils/GeoIP-update.sh in the CAT distribution and use it tu update the GeoIP database regularly.");
335
                break;
336
            default:
337
                $this->test_return(\core\common\Entity::L_ERROR, 'Check CONFIG[\'GEOIP\'][\'version\'], it must be set to either 1 or 2');
338
                break;
339
        }
340
    }
341
342
    /**
343
     * test if openssl is available
344
     */
345
    private function openssl_test() {
346
        $A = $this->get_exec_path('openssl');
347
        if ($A['exec'] != "") {
348
            $t = exec($A['exec'] . ' version');
349 View Code Duplication
            if ($A['exec_is'] == "EXPLICIT") {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
350
                $this->test_return(\core\common\Entity::L_OK, "<strong>$t</strong> was found and is configured explicitly in your config.");
351
            } else {
352
                $this->test_return(\core\common\Entity::L_WARN, "<strong>$t</strong> was found, but is not configured with an absolute path in your config.");
353
            }
354
        } else {
355
            $this->test_return(\core\common\Entity::L_ERROR, "<strong>openssl</strong> was not found on your system!");
356
        }
357
    }
358
359
    /**
360
     * test if makensis is available
361
     */
362
    private function makensis_test() {
363
        if (!is_numeric(CONFIG_CONFASSISTANT['NSIS_VERSION'])) {
364
            $this->test_return(\core\common\Entity::L_ERROR, "NSIS_VERSION needs to be numeric!");
365
            return;
366
        }
367
        if (CONFIG_CONFASSISTANT['NSIS_VERSION'] < 2) {
368
            $this->test_return(\core\common\Entity::L_ERROR, "NSIS_VERSION needs to be at least 2!");
369
            return;
370
        }
371
        $A = $this->get_exec_path('makensis');
372
        if ($A['exec'] != "") {
373
            $t = exec($A['exec'] . ' -VERSION');
374 View Code Duplication
            if ($A['exec_is'] == "EXPLICIT") {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
375
                $this->test_return(\core\common\Entity::L_OK, "<strong>makensis $t</strong> was found and is configured explicitly in your config.");
376
            } else {
377
                $this->test_return(\core\common\Entity::L_WARN, "<strong>makensis $t</strong> was found, but is not configured with an absolute path in your config.");
378
            }
379
            exec($A['exec'] . ' -HELP', $t);
380
            $t1 = count(preg_grep('/INPUTCHARSET/', $t));
381 View Code Duplication
            if ($t1 == 1 && CONFIG_CONFASSISTANT['NSIS_VERSION'] == 2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
382
                $this->test_return(\core\common\Entity::L_ERROR, "Declared NSIS_VERSION does not seem to match the file pointed to by PATHS['makensis']!");
383
            }
384 View Code Duplication
            if ($t1 == 0 && CONFIG_CONFASSISTANT['NSIS_VERSION'] >= 3) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
385
                $this->test_return(\core\common\Entity::L_ERROR, "Declared NSIS_VERSION does not seem to match the file pointed to by PATHS['makensis']!");
386
            }
387
        } else {
388
            $this->test_return(\core\common\Entity::L_ERROR, "<strong>makensis</strong> was not found on your system!");
389
        }
390
    }
391
392
    /**
393
     * test if all required NSIS modules are available
394
     */
395
    private function NSISmodules_test() {
396
        $tmp_dir = $this->createTemporaryDirectory('installer', 0)['dir'];
397
        if (!chdir($tmp_dir)) {
398
            $this->loggerInstance->debug(2, "Cannot chdir to $tmp_dir\n");
399
            $this->test_return(\core\common\Entity::L_ERROR, "NSIS modules test - problem with temporary directory permissions, cannot continue");
400
            return;
401
        }
402
        $exe = 'tt.exe';
403
        $NSIS_Module_status = [];
404
        foreach ($this->NSIS_Modules as $module) {
405
            unset($out);
406
            exec(CONFIG_CONFASSISTANT['PATHS']['makensis'] . " -V1 '-X!include $module' '-XOutFile $exe' '-XSection X' '-XSectionEnd'", $out, $retval);
407
            if ($retval > 0) {
408
                $NSIS_Module_status[$module] = 0;
409
            } else {
410
                $NSIS_Module_status[$module] = 1;
411
            }
412
        }
413
        if (is_file($exe)) {
414
            unlink($exe);
415
        }
416
        foreach ($NSIS_Module_status as $module => $status) {
417
            if ($status == 1) {
418
                $this->test_return(\core\common\Entity::L_OK, "NSIS module <strong>$module</strong> was found.");
419
            } else {
420
                $this->test_return(\core\common\Entity::L_ERROR, "NSIS module <strong>$module</strong> was not found or is not working correctly.");
421
            }
422
        }
423
    }
424
425
    /**
426
     * test access to dowloads directories
427
     */
428
    private function directories_test() {
429
        $Dir1 = $this->createTemporaryDirectory('installer', 0);
430
        $dir1 = $Dir1['dir'];
431
        $base1 = $Dir1['base'];
432
        if ($dir1) {
433
            $this->test_return(\core\common\Entity::L_OK, "Installer cache directory is writable.");
434
            \core\common\Entity::rrmdir($dir1);
435
        } else {
436
            $this->test_return(\core\common\Entity::L_ERROR, "Installer cache directory $base1 does not exist or is not writable!");
437
        }
438
        $Dir2 = $this->createTemporaryDirectory('test', 0);
439
        $dir2 = $Dir2['dir'];
440
        $base2 = $Dir2['base'];
441
        if ($dir2) {
442
            $this->test_return(\core\common\Entity::L_OK, "Test directory is writable.");
443
            \core\common\Entity::rrmdir($dir2);
444
        } else {
445
            $this->test_return(\core\common\Entity::L_ERROR, "Test directory $base2 does not exist or is not writable!");
446
        }
447
        $Dir3 = $this->createTemporaryDirectory('logo', 0);
448
        $dir3 = $Dir3['dir'];
449
        $base3 = $Dir3['base'];
450
        if ($dir3) {
451
            $this->test_return(\core\common\Entity::L_OK, "Logos cache directory is writable.");
452
            \core\common\Entity::rrmdir($dir3);
453
        } else {
454
            $this->test_return(\core\common\Entity::L_ERROR, "Logos cache directory $base3 does not exist or is not writable!");
455
        }
456
    }
457
458
    /**
459
     * test if all required locales are enabled
460
     */
461
    private function locales_test() {
462
        $locales = shell_exec("locale -a");
463
        $allthere = "";
464
        foreach (CONFIG['LANGUAGES'] as $onelanguage) {
465
            if (preg_match("/" . $onelanguage['locale'] . "/", $locales) == 0) {
466
                $allthere .= $onelanguage['locale'] . " ";
467
            }
468
        }
469 View Code Duplication
        if ($allthere == "") {
470
            $this->test_return(\core\common\Entity::L_OK, "All of your configured locales are available on your system.");
471
        } else {
472
            $this->test_return(\core\common\Entity::L_WARN, "Some of your configured locales (<strong>$allthere</strong>) are not installed and will not be displayed correctly!");
473
        }
474
    }
475
476
    /**
477
     * test if defaults in the config have been replaced with some real values
478
     */
479
    private function defaults_test() {
480
        $defaultvalues = "";
481
        $missingvalues = "";
482
        if (CONFIG['APPEARANCE']['from-mail'] == "[email protected]") {
483
            $defaultvalues .= "APPEARANCE/from-mail ";
484
        }
485
        if (CONFIG['APPEARANCE']['support-contact']['url'] == "[email protected]?body=Only%20English%20language%20please!") {
486
            $defaultvalues .= "APPEARANCE/support-contact/url ";
487
        }
488
        if (CONFIG['APPEARANCE']['support-contact']['display'] == "[email protected]") {
489
            $defaultvalues .= "APPEARANCE/support-contact/display ";
490
        }
491
        if (CONFIG['APPEARANCE']['support-contact']['developer-mail'] == "[email protected]") {
492
            $defaultvalues .= "APPEARANCE/support-contact/mail ";
493
        }
494
        if (CONFIG['APPEARANCE']['abuse-mail'] == "[email protected]") {
495
            $defaultvalues .= "APPEARANCE/abuse-mail ";
496
        }
497
        if (CONFIG['APPEARANCE']['MOTD'] == "Release Candidate. All bugs to be shot on sight!") {
498
            $defaultvalues .= "APPEARANCE/MOTD ";
499
        }
500 View Code Duplication
        if (CONFIG['APPEARANCE']['webcert_CRLDP'] == ['list', 'of', 'CRL', 'pointers']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
501
            $defaultvalues .= "APPEARANCE/webcert_CRLDP ";
502
        }
503
        if (empty(CONFIG['APPEARANCE']['webcert_OCSP'])) {
504
            $missingvalues .= "APPEARANCE/webcert_OCSP ";
505 View Code Duplication
        } elseif (CONFIG['APPEARANCE']['webcert_OCSP'] == ['list', 'of', 'OCSP', 'pointers']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
506
            $defaultvalues .= "APPEARANCE/webcert_OCSP ";
507
        }
508
        if (isset(CONFIG_DIAGNOSTICS['RADIUSTESTS']['UDP-hosts'][0]) && CONFIG_DIAGNOSTICS['RADIUSTESTS']['UDP-hosts'][0]['ip'] == "192.0.2.1") {
509
            $defaultvalues .= "RADIUSTESTS/UDP-hosts ";
510
        }
511
        if (CONFIG['DB']['INST']['host'] == "db.host.example") {
512
            $defaultvalues .= "DB/INST ";
513
        }
514
        if (CONFIG['DB']['INST']['host'] == "db.host.example") {
515
            $defaultvalues .= "DB/USER ";
516
        }
517
        if (!empty(CONFIG['DB']['EXTERNAL']) && CONFIG['DB']['EXTERNAL']['host'] == "customerdb.otherhost.example") {
518
            $defaultvalues .= "DB/EXTERNAL ";
519
        }
520
        $files = [];
521
        foreach (CONFIG_DIAGNOSTICS['RADIUSTESTS']['TLS-clientcerts'] as $cadata) {
522
            foreach ($cadata['certificates'] as $cert_files) {
523
                $files[] = $cert_files['public'];
524
                $files[] = $cert_files['private'];
525
            }
526
        }
527
528
        foreach ($files as $file) {
529
            $handle = fopen(ROOT . "/config/cli-certs/" . $file, 'r');
530
            if (!$handle) {
531
                $defaultvalues .= "CERTIFICATE/$file ";
532
            } else {
533
                fclose($handle);
534
            }
535
        }
536 View Code Duplication
        if ($defaultvalues != "") {
537
            $this->test_return(\core\common\Entity::L_WARN, "Your configuration in config/config.php contains unchanged default values or links to inexistent files: <strong>$defaultvalues</strong>!");
538
        } else {
539
            $this->test_return(\core\common\Entity::L_OK, "Your configuration does not contain any unchanged defaults, which is a good sign.");
540
        }
541
    }
542
543
    /**
544
     * test access to databases
545
     */
546
    private function databases_test() {
547
        $databaseName1 = 'INST';
548
        $db1 = mysqli_connect(CONFIG['DB'][$databaseName1]['host'], CONFIG['DB'][$databaseName1]['user'], CONFIG['DB'][$databaseName1]['pass'], CONFIG['DB'][$databaseName1]['db']);
549 View Code Duplication
        if (!$db1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
550
            $this->test_return(\core\common\Entity::L_ERROR, "Connection to the  $databaseName1 database failed");
551
        } else {
552
            $r = mysqli_query($db1, 'select * from profile_option_dict');
553
            if ($r->num_rows == $this->profile_option_ct) {
554
                $this->test_return(\core\common\Entity::L_OK, "The $databaseName1 database appears to be OK.");
555
            } else {
556
                $this->test_return(\core\common\Entity::L_ERROR, "The $databaseName1 database is reacheable but probably not updated to this version of CAT.");
557
            }
558
        }
559
        $databaseName2 = 'USER';
560
        $db2 = mysqli_connect(CONFIG['DB'][$databaseName2]['host'], CONFIG['DB'][$databaseName2]['user'], CONFIG['DB'][$databaseName2]['pass'], CONFIG['DB'][$databaseName2]['db']);
561 View Code Duplication
        if (!$db2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
562
            $this->test_return(\core\common\Entity::L_ERROR, "Connection to the  $databaseName2 database failed");
563
        } else {
564
            $r = mysqli_query($db2, 'desc view_admin');
565
            if ($r->num_rows == $this->view_admin_ct) {
566
                $this->test_return(\core\common\Entity::L_OK, "The $databaseName2 database appears to be OK.");
567
            } else {
568
                $this->test_return(\core\common\Entity::L_ERROR, "The $databaseName2 is reacheable but there is something wrong with the schema");
569
            }
570
        }
571
        $databaseName3 = 'EXTERNAL';
572
        if (!empty(CONFIG['DB'][$databaseName3])) {
573
            $db3 = mysqli_connect(CONFIG['DB'][$databaseName3]['host'], CONFIG['DB'][$databaseName3]['user'], CONFIG['DB'][$databaseName3]['pass'], CONFIG['DB'][$databaseName3]['db']);
574 View Code Duplication
            if (!$db3) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
575
                $this->test_return(\core\common\Entity::L_ERROR, "Connection to the  $databaseName3 database failed");
576
            } else {
577
                $r = mysqli_query($db3, 'desc view_admin');
578
                if ($r->num_rows == $this->view_admin_ct) {
579
                    $this->test_return(\core\common\Entity::L_OK, "The $databaseName3 database appears to be OK.");
580
                } else {
581
                    $this->test_return(\core\common\Entity::L_ERROR, "The $databaseName3 is reacheable but there is something wrong with the schema");
582
                }
583
            }
584
        }
585
    }
586
587
    /**
588
     * test devices.php for the no_cache option
589
     */
590
    private function device_cache_test() {
591
        if ((!empty(\devices\Devices::$Options['no_cache'])) && \devices\Devices::$Options['no_cache']) {
592
            $global_no_cache = 1;
593
        } else {
594
            $global_no_cache = 0;
595
        }
596
597
        if ($global_no_cache == 1) {
598
            $this->test_return(\core\common\Entity::L_WARN, "Devices no_cache global option is set, this is not a good idea in a production setting\n");
599
        }
600
        $Devs = \devices\Devices::listDevices();
601
        $no_cache_dev = '';
602
        $no_cache_dev_count = 0;
603
        if ($global_no_cache) {
604 View Code Duplication
            foreach ($Devs as $dev => $D) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
605
                if (empty($D['options']['no_cache']) || $D['options']['no_cache'] != 0) {
606
                    $no_cache_dev .= $dev . " ";
607
                    $no_cache_dev_count++;
608
                }
609
            }
610
        } else {
611 View Code Duplication
            foreach ($Devs as $dev => $D) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
612
                if (!empty($D['options']['no_cache']) && $D['options']['no_cache'] != 0) {
613
                    $no_cache_dev .= $dev . " ";
614
                    $no_cache_dev_count++;
615
                }
616
            }
617
        }
618
619
620
        if ($no_cache_dev_count > 1) {
621
            $this->test_return(\core\common\Entity::L_WARN, "The following devices will not be cached: $no_cache_dev");
622
        }
623
        if ($no_cache_dev_count == 1) {
624
            $this->test_return(\core\common\Entity::L_WARN, "The following device will not be cached: $no_cache_dev");
625
        }
626
    }
627
628
    /**
629
     * test if mailer works
630
     */
631
    private function mailer_test() {
632
        if (empty(CONFIG['APPEARANCE']['abuse-mail']) || CONFIG['APPEARANCE']['abuse-mail'] == "[email protected]") {
633
            $this->test_return(\core\common\Entity::L_ERROR, "Your abuse-mail has not been set, cannot continue with mailer tests.");
634
            return;
635
        }
636
        $mail = new \PHPMailer\PHPMailer\PHPMailer();
637
        $mail->isSMTP();
638
        $mail->Port = 587;
639
        $mail->SMTPAuth = true;
640
        $mail->SMTPSecure = 'tls';
641
        $mail->Host = CONFIG['MAILSETTINGS']['host'];
642
        $mail->Username = CONFIG['MAILSETTINGS']['user'];
643
        $mail->Password = CONFIG['MAILSETTINGS']['pass'];
644
        $mail->WordWrap = 72;
645
        $mail->isHTML(FALSE);
646
        $mail->CharSet = 'UTF-8';
647
        $mail->From = CONFIG['APPEARANCE']['from-mail'];
648
        $mail->FromName = CONFIG['APPEARANCE']['productname'] . " Invitation System";
649
        $mail->addAddress(CONFIG['APPEARANCE']['abuse-mail']);
650
        $mail->Subject = "testing CAT configuration mail";
651
        $mail->Body = "Testing CAT mailing\n";
652
        $sent = $mail->send();
653
        if ($sent) {
654
            $this->test_return(\core\common\Entity::L_OK, "mailer settings appear to be working, check " . CONFIG['APPEARANCE']['abuse-mail'] . " mailbox if the message was receiced.");
655
        } else {
656
            $this->test_return(\core\common\Entity::L_ERROR, "mailer settings failed, check the Config::MAILSETTINGS");
657
        }
658
    }
659
660
    /**
661
     * TODO test if RADIUS connections work
662
     */
663
    private function UDPhosts_test() {
664
//        if(empty)
665
    }
666
667
}
668