| Total Complexity | 129 | 
| Total Lines | 751 | 
| Duplicated Lines | 0 % | 
| Changes | 0 | ||
Complex classes like SanityTests often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use SanityTests, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 55 | class SanityTests extends CAT { | 
            ||
| 56 | /* in this section set current CAT requirements */  | 
            ||
| 57 | |||
| 58 | /* $php_needversion sets the minumum required php version */  | 
            ||
| 59 | |||
| 60 | // because of bug:  | 
            ||
| 61 | // Fixed bug #74005 (mail.add_x_header causes RFC-breaking lone line feed).  | 
            ||
| 62 | private $php_needversion = '7.2.0';  | 
            ||
| 63 | private $ssp_needversion = ['major' => 1, 'minor' => 15];  | 
            ||
| 64 | |||
| 65 | |||
| 66 | /* List all required NSIS modules below */  | 
            ||
| 67 | private $NSIS_Modules = [  | 
            ||
| 68 | "nsArray.nsh",  | 
            ||
| 69 | "FileFunc.nsh",  | 
            ||
| 70 | "LogicLib.nsh",  | 
            ||
| 71 | "WordFunc.nsh",  | 
            ||
| 72 | "FileFunc.nsh",  | 
            ||
| 73 | "x64.nsh",  | 
            ||
| 74 | ];  | 
            ||
| 75 | |||
| 76 | /* set $profile_option_ct to the number of rows returned by "SELECT * FROM profile_option_dict" */  | 
            ||
| 77 | private $profile_option_ct;  | 
            ||
| 78 | /* set $view_admin_ct to the number of rows returned by "desc view_admin" */  | 
            ||
| 79 | private $view_admin_ct = 8;  | 
            ||
| 80 | |||
| 81 | /* end of config */  | 
            ||
| 82 | public $out;  | 
            ||
| 83 | public $name;  | 
            ||
| 84 | |||
| 85 | /**  | 
            ||
| 86 | * initialise the tests. Includes counting the number of expected rows in the profile_option_dict table.  | 
            ||
| 87 | */  | 
            ||
| 88 |     public function __construct() { | 
            ||
| 106 | }  | 
            ||
| 107 | }  | 
            ||
| 108 | }  | 
            ||
| 109 | }  | 
            ||
| 110 | |||
| 111 | /**  | 
            ||
| 112 | * The single test wrapper  | 
            ||
| 113 | * @param string $test the test name  | 
            ||
| 114 | * @return void  | 
            ||
| 115 | */  | 
            ||
| 116 |     public function test($test) { | 
            ||
| 117 | $this->out[$test] = [];  | 
            ||
| 118 | $this->name = $test;  | 
            ||
| 119 | $m_name = $test . '_test';  | 
            ||
| 120 | $this->test_result[$test] = 0;  | 
            ||
| 121 |         if (!method_exists($this, $m_name)) { | 
            ||
| 122 | $this->testReturn(\core\common\Entity::L_ERROR, "Configuration error, no test configured for <strong>$test</strong>.");  | 
            ||
| 123 | return;  | 
            ||
| 124 | }  | 
            ||
| 125 | $this->$m_name();  | 
            ||
| 126 | }  | 
            ||
| 127 | |||
| 128 | /**  | 
            ||
| 129 | * The multiple tests wrapper  | 
            ||
| 130 | * @param array $Tests the tests array is a simple string array, where each  | 
            ||
| 131 | * entry is a test name. The test names can also be  | 
            ||
| 132 | * given in the format "test=>subtest", which defines a  | 
            ||
| 133 | * conditional execution of the "subtest" if the "test"  | 
            ||
| 134 | * was run earlier and returned a success.  | 
            ||
| 135 | * @return void  | 
            ||
| 136 | */  | 
            ||
| 137 |     public function run_tests($Tests) { | 
            ||
| 148 | }  | 
            ||
| 149 | }  | 
            ||
| 150 | }  | 
            ||
| 151 | |||
| 152 | /**  | 
            ||
| 153 | * enumerates the tests which are defined  | 
            ||
| 154 | *  | 
            ||
| 155 | * @return array  | 
            ||
| 156 | */  | 
            ||
| 157 |     public function get_test_names() { | 
            ||
| 158 | $T = get_class_methods($this);  | 
            ||
| 159 | $out = [];  | 
            ||
| 160 |         foreach ($T as $t) { | 
            ||
| 161 |             if (preg_match('/^(.*)_test$/', $t, $m)) { | 
            ||
| 162 | $out[] = $m[1];  | 
            ||
| 163 | }  | 
            ||
| 164 | }  | 
            ||
| 165 | return $out;  | 
            ||
| 166 | }  | 
            ||
| 167 | |||
| 168 | /**  | 
            ||
| 169 | * This array is used to return the test results.  | 
            ||
| 170 | * As the 'global' entry it returns the maximum return value  | 
            ||
| 171 | * from all tests.  | 
            ||
| 172 | * Individual tests results are teturned as separate entires  | 
            ||
| 173 | * indexed by test names; each value is an array passing "level" and "message"  | 
            ||
| 174 | * from each of the tests.  | 
            ||
| 175 | * $test_result is set by the testReturn method  | 
            ||
| 176 | *  | 
            ||
| 177 | * @var array $test_result  | 
            ||
| 178 | */  | 
            ||
| 179 | public $test_result;  | 
            ||
| 180 | |||
| 181 | /**  | 
            ||
| 182 | * stores the result of a given test in standardised format  | 
            ||
| 183 | *  | 
            ||
| 184 | * @param int $level severity level of the result  | 
            ||
| 185 | * @param string $message verbal description of the result  | 
            ||
| 186 | * @return void  | 
            ||
| 187 | */  | 
            ||
| 188 |     private function testReturn($level, $message) { | 
            ||
| 189 | $this->out[$this->name][] = ['level' => $level, 'message' => $message];  | 
            ||
| 190 | $this->test_result[$this->name] = max($this->test_result[$this->name], $level);  | 
            ||
| 191 | $this->test_result['global'] = max($this->test_result['global'], $level);  | 
            ||
| 192 | }  | 
            ||
| 193 | |||
| 194 | /**  | 
            ||
| 195 | * finds out if a path name is configured as an absolute path or only implicit (e.g. is in $PATH)  | 
            ||
| 196 | * @param string $pathToCheck the path to check  | 
            ||
| 197 | * @return array  | 
            ||
| 198 | */  | 
            ||
| 199 |     private function getExecPath($pathToCheck) { | 
            ||
| 200 | $the_path = "";  | 
            ||
| 201 | $exec_is = "UNDEFINED";  | 
            ||
| 202 |         foreach ([CONFIG, CONFIG_CONFASSISTANT, CONFIG_DIAGNOSTICS] as $config) { | 
            ||
| 203 |             if (!empty($config['PATHS'][$pathToCheck])) { | 
            ||
| 204 | $matchArray = [];  | 
            ||
| 205 |                 preg_match('/([^ ]+) ?/', $config['PATHS'][$pathToCheck], $matchArray); | 
            ||
| 206 | $exe = $matchArray[1];  | 
            ||
| 207 |                 $the_path = exec("which " . $config['PATHS'][$pathToCheck]); | 
            ||
| 208 |                 if ($the_path == $exe) { | 
            ||
| 209 | $exec_is = "EXPLICIT";  | 
            ||
| 210 |                 } else { | 
            ||
| 211 | $exec_is = "IMPLICIT";  | 
            ||
| 212 | }  | 
            ||
| 213 | return(['exec' => $the_path, 'exec_is' => $exec_is]);  | 
            ||
| 214 | }  | 
            ||
| 215 | }  | 
            ||
| 216 | return(['exec' => $the_path, 'exec_is' => $exec_is]);  | 
            ||
| 217 | }  | 
            ||
| 218 | |||
| 219 | /**  | 
            ||
| 220 | * Test for php version  | 
            ||
| 221 | *  | 
            ||
| 222 | * @return void  | 
            ||
| 223 | */  | 
            ||
| 224 |     private function php_test() { | 
            ||
| 225 |         if (version_compare(phpversion(), $this->php_needversion, '>=')) { | 
            ||
| 226 | $this->testReturn(\core\common\Entity::L_OK, "<strong>PHP</strong> is sufficiently recent. You are running " . phpversion() . ".");  | 
            ||
| 227 |         } else { | 
            ||
| 228 | $this->testReturn(\core\common\Entity::L_ERROR, "<strong>PHP</strong> is too old. We need at least $this->php_needversion, but you only have " . phpversion() . ".");  | 
            ||
| 229 | }  | 
            ||
| 230 | }  | 
            ||
| 231 | |||
| 232 | /**  | 
            ||
| 233 | * set for cat_base_url setting  | 
            ||
| 234 | *  | 
            ||
| 235 | * @return void  | 
            ||
| 236 | */  | 
            ||
| 237 |     private function cat_base_url_test() { | 
            ||
| 238 | $rootUrl = substr(CONFIG['PATHS']['cat_base_url'], -1) === '/' ? substr(CONFIG['PATHS']['cat_base_url'], 0, -1) : CONFIG['PATHS']['cat_base_url'];  | 
            ||
| 239 |         preg_match('/(^.*)\/admin\/112365365321.php/', $_SERVER['SCRIPT_NAME'], $m); | 
            ||
| 240 |         if ($rootUrl === $m[1]) { | 
            ||
| 241 | $this->testReturn(\core\common\Entity::L_OK, "<strong>cat_base_url</strong> set correctly");  | 
            ||
| 242 |         } else { | 
            ||
| 243 | $rootFromScript = $m[1] === '' ? '/' : $m[1];  | 
            ||
| 244 | $this->testReturn(\core\common\Entity::L_ERROR, "<strong>cat_base_url</strong> is set to <strong>" . CONFIG['PATHS']['cat_base_url'] . "</strong> and should be <strong>$rootFromScript</strong>");  | 
            ||
| 245 | }  | 
            ||
| 246 | }  | 
            ||
| 247 | |||
| 248 | /**  | 
            ||
| 249 | * test for simpleSAMLphp  | 
            ||
| 250 | *  | 
            ||
| 251 | * @return void  | 
            ||
| 252 | */  | 
            ||
| 253 |     private function ssp_test() { | 
            ||
| 254 |         if (!is_file(CONFIG['AUTHENTICATION']['ssp-path-to-autoloader'])) { | 
            ||
| 255 | $this->testReturn(\core\common\Entity::L_ERROR, "<strong>simpleSAMLphp</strong> not found!");  | 
            ||
| 256 |         } else { | 
            ||
| 257 | include_once CONFIG['AUTHENTICATION']['ssp-path-to-autoloader'];  | 
            ||
| 258 | $SSPconfig = \SimpleSAML_Configuration::getInstance();  | 
            ||
| 259 |             $sspVersion = explode('.', $SSPconfig->getVersion()); | 
            ||
| 260 |             if ((int) $sspVersion[0] >= $this->ssp_needversion['major'] && (int) $sspVersion[1] >= $this->ssp_needversion['minor']) { | 
            ||
| 261 |                 $this->testReturn(\core\common\Entity::L_OK, "<strong>simpleSAMLphp</strong> is sufficently recent. You are running " . implode('.', $sspVersion)); | 
            ||
| 262 |             } else { | 
            ||
| 263 |                 $this->testReturn(\core\common\Entity::L_ERROR, "<strong>simpleSAMLphp</strong> is too old. We need at least " . implode('.', $this->ssp_needversion)); | 
            ||
| 264 | }  | 
            ||
| 265 | }  | 
            ||
| 266 | }  | 
            ||
| 267 | |||
| 268 | /**  | 
            ||
| 269 | * test for security setting  | 
            ||
| 270 | *  | 
            ||
| 271 | * @return void  | 
            ||
| 272 | */  | 
            ||
| 273 |     private function security_test() { | 
            ||
| 274 |         if (in_array("I do not care about security!", CONFIG['SUPERADMINS'])) { | 
            ||
| 275 | $this->testReturn(\core\common\Entity::L_WARN, "You do not care about security. This page should be made accessible to the CAT admin only! See config-master.php: 'SUPERADMINS'!");  | 
            ||
| 276 | }  | 
            ||
| 277 | }  | 
            ||
| 278 | |||
| 279 | /**  | 
            ||
| 280 | * test if zip is available  | 
            ||
| 281 | *  | 
            ||
| 282 | * @return void  | 
            ||
| 283 | */  | 
            ||
| 284 |     private function zip_test() { | 
            ||
| 285 |         if (exec("which zip") != "") { | 
            ||
| 286 | $this->testReturn(\core\common\Entity::L_OK, "<strong>zip</strong> binary found.");  | 
            ||
| 287 |         } else { | 
            ||
| 288 | $this->testReturn(\core\common\Entity::L_ERROR, "<strong>zip</strong> not found in your \$PATH!");  | 
            ||
| 289 | }  | 
            ||
| 290 | }  | 
            ||
| 291 | |||
| 292 | /**  | 
            ||
| 293 | * test if eapol_test is available and recent enough  | 
            ||
| 294 | *  | 
            ||
| 295 | * @return void  | 
            ||
| 296 | */  | 
            ||
| 297 |     private function eapol_test_test() { | 
            ||
| 298 | exec(CONFIG_DIAGNOSTICS['PATHS']['eapol_test'], $out, $retval);  | 
            ||
| 299 |         if ($retval == 255) { | 
            ||
| 300 |             $o = preg_grep('/-o<server cert/', $out); | 
            ||
| 301 |             if (count($o) > 0) { | 
            ||
| 302 | $this->testReturn(\core\common\Entity::L_OK, "<strong>eapol_test</strong> script found.");  | 
            ||
| 303 |             } else { | 
            ||
| 304 | $this->testReturn(\core\common\Entity::L_ERROR, "<strong>eapol_test</strong> found, but is too old!");  | 
            ||
| 305 | }  | 
            ||
| 306 |         } else { | 
            ||
| 307 | $this->testReturn(\core\common\Entity::L_ERROR, "<strong>eapol_test</strong> not found!");  | 
            ||
| 308 | }  | 
            ||
| 309 | }  | 
            ||
| 310 | |||
| 311 | /**  | 
            ||
| 312 | * test if logdir exists and is writable  | 
            ||
| 313 | *  | 
            ||
| 314 | * @return void  | 
            ||
| 315 | */  | 
            ||
| 316 |     private function logdir_test() { | 
            ||
| 317 |         if (fopen(CONFIG['PATHS']['logdir'] . "/debug.log", "a") == FALSE) { | 
            ||
| 318 | $this->testReturn(\core\common\Entity::L_WARN, "Log files in <strong>" . CONFIG['PATHS']['logdir'] . "</strong> are not writable!");  | 
            ||
| 319 |         } else { | 
            ||
| 320 | $this->testReturn(\core\common\Entity::L_OK, "Log directory is writable.");  | 
            ||
| 321 | }  | 
            ||
| 322 | }  | 
            ||
| 323 | |||
| 324 | /**  | 
            ||
| 325 | * test for required PHP modules  | 
            ||
| 326 | *  | 
            ||
| 327 | * @return void  | 
            ||
| 328 | */  | 
            ||
| 329 |     private function phpModules_test() { | 
            ||
| 330 |         if (function_exists('idn_to_ascii')) { | 
            ||
| 331 | $this->testReturn(\core\common\Entity::L_OK, "PHP can handle internationalisation.");  | 
            ||
| 332 |         } else { | 
            ||
| 333 | $this->testReturn(\core\common\Entity::L_ERROR, "PHP can <strong>NOT</strong> handle internationalisation (idn_to_ascii() from php7.0-intl).");  | 
            ||
| 334 | }  | 
            ||
| 335 | |||
| 336 |         if (function_exists('gettext')) { | 
            ||
| 337 | $this->testReturn(\core\common\Entity::L_OK, "PHP extension <strong>GNU Gettext</strong> is installed.");  | 
            ||
| 338 |         } else { | 
            ||
| 339 | $this->testReturn(\core\common\Entity::L_ERROR, "PHP extension <strong>GNU Gettext</strong> not found!");  | 
            ||
| 340 | }  | 
            ||
| 341 | |||
| 342 |         if (function_exists('openssl_sign')) { | 
            ||
| 343 | $this->testReturn(\core\common\Entity::L_OK, "PHP extension <strong>OpenSSL</strong> is installed.");  | 
            ||
| 344 |         } else { | 
            ||
| 345 | $this->testReturn(\core\common\Entity::L_ERROR, "PHP extension <strong>OpenSSL</strong> not found!");  | 
            ||
| 346 | }  | 
            ||
| 347 | |||
| 348 |         if (class_exists('\Imagick')) { | 
            ||
| 349 | $this->testReturn(\core\common\Entity::L_OK, "PHP extension <strong>Imagick</strong> is installed.");  | 
            ||
| 350 |         } else { | 
            ||
| 351 | $this->testReturn(\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>.");  | 
            ||
| 352 | }  | 
            ||
| 353 | |||
| 354 |         if (function_exists('ImageCreate')) { | 
            ||
| 355 | $this->testReturn(\core\common\Entity::L_OK, "PHP extension <strong>GD</strong> is installed.");  | 
            ||
| 356 |         } else { | 
            ||
| 357 | $this->testReturn(\core\common\Entity::L_ERROR, "PHP extension <strong>GD</strong> not found!</a>.");  | 
            ||
| 358 | }  | 
            ||
| 359 | |||
| 360 |         if (function_exists('mysqli_connect')) { | 
            ||
| 361 | $this->testReturn(\core\common\Entity::L_OK, "PHP extension <strong>MySQL</strong> is installed.");  | 
            ||
| 362 |         } else { | 
            ||
| 363 | $this->testReturn(\core\common\Entity::L_ERROR, "PHP extension <strong>MySQL</strong> not found!");  | 
            ||
| 364 | }  | 
            ||
| 365 | }  | 
            ||
| 366 | |||
| 367 | /**  | 
            ||
| 368 | * test if GeoIP is installed correctly  | 
            ||
| 369 | *  | 
            ||
| 370 | * @return void  | 
            ||
| 371 | */  | 
            ||
| 372 |     private function geoip_test() { | 
            ||
| 373 | $host_4 = '145.0.2.50';  | 
            ||
| 374 | $host_6 = '2001:610:188:444::50';  | 
            ||
| 375 |         switch (CONFIG['GEOIP']['version']) { | 
            ||
| 376 | case 0:  | 
            ||
| 377 | $this->testReturn(\core\common\Entity::L_REMARK, "As set in the config, no geolocation service will be used");  | 
            ||
| 378 | break;  | 
            ||
| 379 | case 1:  | 
            ||
| 380 |                 if (!function_exists('geoip_record_by_name')) { | 
            ||
| 381 | $this->testReturn(\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>.");  | 
            ||
| 382 | return;  | 
            ||
| 383 | }  | 
            ||
| 384 | $record = geoip_record_by_name($host_4);  | 
            ||
| 385 |                 if ($record === FALSE) { | 
            ||
| 386 | $this->testReturn(\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.");  | 
            ||
| 387 | return;  | 
            ||
| 388 | }  | 
            ||
| 389 |                 if ($record['city'] != 'Utrecht') { | 
            ||
| 390 | $this->testReturn(\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.");  | 
            ||
| 391 | return;  | 
            ||
| 392 | }  | 
            ||
| 393 | $this->testReturn(\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>.");  | 
            ||
| 394 | break;  | 
            ||
| 395 | case 2:  | 
            ||
| 396 |                 if (!is_file(CONFIG['GEOIP']['geoip2-path-to-autoloader'])) { | 
            ||
| 397 | $this->testReturn(\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>.");  | 
            ||
| 398 | return;  | 
            ||
| 399 | }  | 
            ||
| 400 |                 if (!is_file(CONFIG['GEOIP']['geoip2-path-to-db'])) { | 
            ||
| 401 | $this->testReturn(\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.");  | 
            ||
| 402 | return;  | 
            ||
| 403 | }  | 
            ||
| 404 | include_once CONFIG['GEOIP']['geoip2-path-to-autoloader'];  | 
            ||
| 405 | $reader = new Reader(CONFIG['GEOIP']['geoip2-path-to-db']);  | 
            ||
| 406 |                 try { | 
            ||
| 407 | $record = $reader->city($host_4);  | 
            ||
| 408 |                 } catch (Exception $e) { | 
            ||
| 409 | $this->testReturn(\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.");  | 
            ||
| 410 | return;  | 
            ||
| 411 | }  | 
            ||
| 412 |                 if ($record->city->name != 'Utrecht') { | 
            ||
| 413 | $this->testReturn(\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.");  | 
            ||
| 414 | return;  | 
            ||
| 415 | }  | 
            ||
| 416 |                 try { | 
            ||
| 417 | $record = $reader->city($host_6);  | 
            ||
| 418 |                 } catch (Exception $e) { | 
            ||
| 419 | $this->testReturn(\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.");  | 
            ||
| 420 | return;  | 
            ||
| 421 | }  | 
            ||
| 422 |                 if ($record->city->name != 'Utrecht') { | 
            ||
| 423 | $this->testReturn(\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.");  | 
            ||
| 424 | return;  | 
            ||
| 425 | }  | 
            ||
| 426 | $this->testReturn(\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.");  | 
            ||
| 427 | break;  | 
            ||
| 428 | default:  | 
            ||
| 429 | $this->testReturn(\core\common\Entity::L_ERROR, 'Check CONFIG[\'GEOIP\'][\'version\'], it must be set to either 1 or 2');  | 
            ||
| 430 | break;  | 
            ||
| 431 | }  | 
            ||
| 432 | }  | 
            ||
| 433 | |||
| 434 | /**  | 
            ||
| 435 | * test if openssl is available  | 
            ||
| 436 | *  | 
            ||
| 437 | * @return void  | 
            ||
| 438 | */  | 
            ||
| 439 |     private function openssl_test() { | 
            ||
| 450 | }  | 
            ||
| 451 | }  | 
            ||
| 452 | |||
| 453 | /**  | 
            ||
| 454 | * test if makensis is available  | 
            ||
| 455 | *  | 
            ||
| 456 | * @return void  | 
            ||
| 457 | */  | 
            ||
| 458 |     private function makensis_test() { | 
            ||
| 459 |         if (!is_numeric(CONFIG_CONFASSISTANT['NSIS_VERSION'])) { | 
            ||
| 460 | $this->testReturn(\core\common\Entity::L_ERROR, "NSIS_VERSION needs to be numeric!");  | 
            ||
| 461 | return;  | 
            ||
| 462 | }  | 
            ||
| 463 |         if (CONFIG_CONFASSISTANT['NSIS_VERSION'] < 2) { | 
            ||
| 464 | $this->testReturn(\core\common\Entity::L_ERROR, "NSIS_VERSION needs to be at least 2!");  | 
            ||
| 465 | return;  | 
            ||
| 466 | }  | 
            ||
| 467 |         $A = $this->getExecPath('makensis'); | 
            ||
| 468 |         if ($A['exec'] != "") { | 
            ||
| 469 | $t = exec($A['exec'] . ' -VERSION');  | 
            ||
| 470 |             if ($A['exec_is'] == "EXPLICIT") { | 
            ||
| 471 | $this->testReturn(\core\common\Entity::L_OK, "<strong>makensis $t</strong> was found and is configured explicitly in your config.");  | 
            ||
| 472 |             } else { | 
            ||
| 473 | $this->testReturn(\core\common\Entity::L_WARN, "<strong>makensis $t</strong> was found, but is not configured with an absolute path in your config.");  | 
            ||
| 474 | }  | 
            ||
| 475 | $outputArray = [];  | 
            ||
| 476 | exec($A['exec'] . ' -HELP', $outputArray);  | 
            ||
| 477 |             $t1 = count(preg_grep('/INPUTCHARSET/', $outputArray)); | 
            ||
| 478 |             if ($t1 == 1 && CONFIG_CONFASSISTANT['NSIS_VERSION'] == 2) { | 
            ||
| 479 | $this->testReturn(\core\common\Entity::L_ERROR, "Declared NSIS_VERSION does not seem to match the file pointed to by PATHS['makensis']!");  | 
            ||
| 480 | }  | 
            ||
| 481 |             if ($t1 == 0 && CONFIG_CONFASSISTANT['NSIS_VERSION'] >= 3) { | 
            ||
| 482 | $this->testReturn(\core\common\Entity::L_ERROR, "Declared NSIS_VERSION does not seem to match the file pointed to by PATHS['makensis']!");  | 
            ||
| 483 | }  | 
            ||
| 484 |         } else { | 
            ||
| 485 | $this->testReturn(\core\common\Entity::L_ERROR, "<strong>makensis</strong> was not found on your system!");  | 
            ||
| 486 | }  | 
            ||
| 487 | }  | 
            ||
| 488 | |||
| 489 | /**  | 
            ||
| 490 | * test if all required NSIS modules are available  | 
            ||
| 491 | *  | 
            ||
| 492 | * @return void  | 
            ||
| 493 | */  | 
            ||
| 494 |     private function NSISmodules_test() { | 
            ||
| 495 |         $tmp_dir = $this->createTemporaryDirectory('installer', 0)['dir']; | 
            ||
| 496 |         if (!chdir($tmp_dir)) { | 
            ||
| 497 | $this->loggerInstance->debug(2, "Cannot chdir to $tmp_dir\n");  | 
            ||
| 498 | $this->testReturn(\core\common\Entity::L_ERROR, "NSIS modules test - problem with temporary directory permissions, cannot continue");  | 
            ||
| 499 | return;  | 
            ||
| 500 | }  | 
            ||
| 501 | $exe = 'tt.exe';  | 
            ||
| 502 | $NSIS_Module_status = [];  | 
            ||
| 503 |         foreach ($this->NSIS_Modules as $module) { | 
            ||
| 504 | unset($out);  | 
            ||
| 505 | exec(CONFIG_CONFASSISTANT['PATHS']['makensis'] . " -V1 '-X!include $module' '-XOutFile $exe' '-XSection X' '-XSectionEnd'", $out, $retval);  | 
            ||
| 506 |             if ($retval > 0) { | 
            ||
| 507 | $NSIS_Module_status[$module] = 0;  | 
            ||
| 508 |             } else { | 
            ||
| 509 | $NSIS_Module_status[$module] = 1;  | 
            ||
| 510 | }  | 
            ||
| 511 | }  | 
            ||
| 512 |         if (is_file($exe)) { | 
            ||
| 513 | unlink($exe);  | 
            ||
| 514 | }  | 
            ||
| 515 |         foreach ($NSIS_Module_status as $module => $status) { | 
            ||
| 516 |             if ($status == 1) { | 
            ||
| 517 | $this->testReturn(\core\common\Entity::L_OK, "NSIS module <strong>$module</strong> was found.");  | 
            ||
| 518 |             } else { | 
            ||
| 519 | $this->testReturn(\core\common\Entity::L_ERROR, "NSIS module <strong>$module</strong> was not found or is not working correctly.");  | 
            ||
| 520 | }  | 
            ||
| 521 | }  | 
            ||
| 522 | }  | 
            ||
| 523 | |||
| 524 | /**  | 
            ||
| 525 | * test access to dowloads directories  | 
            ||
| 526 | *  | 
            ||
| 527 | * @return void  | 
            ||
| 528 | */  | 
            ||
| 529 |     private function directories_test() { | 
            ||
| 556 | }  | 
            ||
| 557 | }  | 
            ||
| 558 | |||
| 559 | /**  | 
            ||
| 560 | * test if all required locales are enabled  | 
            ||
| 561 | *  | 
            ||
| 562 | * @return void  | 
            ||
| 563 | */  | 
            ||
| 564 |     private function locales_test() { | 
            ||
| 565 |         $locales = shell_exec("locale -a"); | 
            ||
| 566 | $allthere = "";  | 
            ||
| 567 |         foreach (CONFIG['LANGUAGES'] as $onelanguage) { | 
            ||
| 568 |             if (preg_match("/" . $onelanguage['locale'] . "/", $locales) == 0) { | 
            ||
| 569 | $allthere .= $onelanguage['locale'] . " ";  | 
            ||
| 570 | }  | 
            ||
| 571 | }  | 
            ||
| 572 |         if ($allthere == "") { | 
            ||
| 573 | $this->testReturn(\core\common\Entity::L_OK, "All of your configured locales are available on your system.");  | 
            ||
| 574 |         } else { | 
            ||
| 575 | $this->testReturn(\core\common\Entity::L_WARN, "Some of your configured locales (<strong>$allthere</strong>) are not installed and will not be displayed correctly!");  | 
            ||
| 576 | }  | 
            ||
| 577 | }  | 
            ||
| 578 | |||
| 579 | const DEFAULTS = [  | 
            ||
| 580 | ["SETTING" => CONFIG['APPEARANCE']['from-mail'],  | 
            ||
| 581 | "DEFVALUE" => "[email protected]",  | 
            ||
| 582 | "COMPLAINTSTRING" => "APPEARANCE/from-mail ",  | 
            ||
| 583 | "REQUIRED" => FALSE,],  | 
            ||
| 584 | ["SETTING" => CONFIG['APPEARANCE']['support-contact']['url'],  | 
            ||
| 585 | "DEFVALUE" => "[email protected]?body=Only%20English%20language%20please!",  | 
            ||
| 586 | "COMPLAINTSTRING" => "APPEARANCE/support-contact/url ",  | 
            ||
| 587 | "REQUIRED" => FALSE,],  | 
            ||
| 588 | ["SETTING" => CONFIG['APPEARANCE']['support-contact']['display'],  | 
            ||
| 589 | "DEFVALUE" => "[email protected]",  | 
            ||
| 590 | "COMPLAINTSTRING" => "APPEARANCE/support-contact/display ",  | 
            ||
| 591 | "REQUIRED" => FALSE,],  | 
            ||
| 592 | ["SETTING" => CONFIG['APPEARANCE']['support-contact']['developer-mail'],  | 
            ||
| 593 | "DEFVALUE" => "[email protected]",  | 
            ||
| 594 | "COMPLAINTSTRING" => "APPEARANCE/support-contact/mail ",  | 
            ||
| 595 | "REQUIRED" => FALSE,],  | 
            ||
| 596 | ["SETTING" => CONFIG['APPEARANCE']['abuse-mail'],  | 
            ||
| 597 | "DEFVALUE" => "[email protected]",  | 
            ||
| 598 | "COMPLAINTSTRING" => "APPEARANCE/abuse-mail ",  | 
            ||
| 599 | "REQUIRED" => FALSE,],  | 
            ||
| 600 | ["SETTING" => CONFIG['APPEARANCE']['MOTD'],  | 
            ||
| 601 | "DEFVALUE" => "Release Candidate. All bugs to be shot on sight!",  | 
            ||
| 602 | "COMPLAINTSTRING" => "APPEARANCE/MOTD ",  | 
            ||
| 603 | "REQUIRED" => FALSE,],  | 
            ||
| 604 | ["SETTING" => CONFIG['APPEARANCE']['webcert_CRLDP'],  | 
            ||
| 605 | "DEFVALUE" => ['list', 'of', 'CRL', 'pointers'],  | 
            ||
| 606 | "COMPLAINTSTRING" => "APPEARANCE/webcert_CRLDP ",  | 
            ||
| 607 | "REQUIRED" => TRUE,],  | 
            ||
| 608 | ["SETTING" => CONFIG['APPEARANCE']['webcert_OCSP'],  | 
            ||
| 609 | "DEFVALUE" => ['list', 'of', 'OCSP', 'pointers'],  | 
            ||
| 610 | "COMPLAINTSTRING" => "APPEARANCE/webcert_OCSP ",  | 
            ||
| 611 | "REQUIRED" => TRUE,],  | 
            ||
| 612 | ["SETTING" => CONFIG['DB']['INST']['host'],  | 
            ||
| 613 | "DEFVALUE" => "db.host.example",  | 
            ||
| 614 | "COMPLAINTSTRING" => "DB/INST ",  | 
            ||
| 615 | "REQUIRED" => TRUE,],  | 
            ||
| 616 | ["SETTING" => CONFIG['DB']['INST']['host'],  | 
            ||
| 617 | "DEFVALUE" => "db.host.example",  | 
            ||
| 618 | "COMPLAINTSTRING" => "DB/USER ",  | 
            ||
| 619 | "REQUIRED" => TRUE,],  | 
            ||
| 620 | ["SETTING" => CONFIG['DB']['EXTERNAL']['host'],  | 
            ||
| 621 | "DEFVALUE" => "customerdb.otherhost.example",  | 
            ||
| 622 | "COMPLAINTSTRING" => "DB/EXTERNAL ",  | 
            ||
| 623 | "REQUIRED" => FALSE,],  | 
            ||
| 624 | ];  | 
            ||
| 625 | |||
| 626 | /**  | 
            ||
| 627 | * test if defaults in the config have been replaced with some real values  | 
            ||
| 628 | *  | 
            ||
| 629 | * @return void  | 
            ||
| 630 | */  | 
            ||
| 631 |     private function defaults_test() { | 
            ||
| 632 | $defaultvalues = "";  | 
            ||
| 633 | $missingvalues = "";  | 
            ||
| 634 | // all the checks for equality with a shipped default value  | 
            ||
| 635 |         foreach (SanityTests::DEFAULTS as $oneCheckItem) { | 
            ||
| 636 |             if ($oneCheckItem['REQUIRED'] && !$oneCheckItem['SETTING']) { | 
            ||
| 637 | $missingvalues .= $oneCheckItem["COMPLAINTSTRING"];  | 
            ||
| 638 |             } elseif ($oneCheckItem['SETTING'] == $oneCheckItem["DEFVALUE"]) { | 
            ||
| 639 | $defaultvalues .= $oneCheckItem["COMPLAINTSTRING"];  | 
            ||
| 640 | }  | 
            ||
| 641 | }  | 
            ||
| 642 | // additional checks for defaults, which are not simple equality checks  | 
            ||
| 643 |         if (isset(CONFIG_DIAGNOSTICS['RADIUSTESTS']['UDP-hosts'][0]) && CONFIG_DIAGNOSTICS['RADIUSTESTS']['UDP-hosts'][0]['ip'] == "192.0.2.1") { | 
            ||
| 644 | $defaultvalues .= "RADIUSTESTS/UDP-hosts ";  | 
            ||
| 645 | }  | 
            ||
| 646 | |||
| 647 |         foreach (CONFIG_DIAGNOSTICS['RADIUSTESTS']['TLS-clientcerts'] as $cadata) { | 
            ||
| 648 |             foreach ($cadata['certificates'] as $cert_files) { | 
            ||
| 649 |                 if (file_get_contents(ROOT . "/config/cli-certs/" . $cert_files['public']) === FALSE) { | 
            ||
| 650 | $defaultvalues .= "CERTIFICATE/" . $cert_files['public'] . " ";  | 
            ||
| 651 | }  | 
            ||
| 652 |                 if (file_get_contents(ROOT . "/config/cli-certs/" . $cert_files['private']) === FALSE) { | 
            ||
| 653 | $defaultvalues .= "CERTIFICATE/" . $cert_files['private'] . " ";  | 
            ||
| 654 | }  | 
            ||
| 655 | }  | 
            ||
| 656 | }  | 
            ||
| 657 | |||
| 658 |         if ($defaultvalues != "") { | 
            ||
| 659 | $this->testReturn(\core\common\Entity::L_WARN, "Your configuration in config/config.php contains unchanged default values or links to inexistent files: <strong>$defaultvalues</strong>!");  | 
            ||
| 660 |         } else { | 
            ||
| 661 | $this->testReturn(\core\common\Entity::L_OK, "Your configuration does not contain any unchanged defaults, which is a good sign.");  | 
            ||
| 662 | }  | 
            ||
| 663 | }  | 
            ||
| 664 | |||
| 665 | /**  | 
            ||
| 666 | * test access to databases  | 
            ||
| 667 | *  | 
            ||
| 668 | * @return void  | 
            ||
| 669 | */  | 
            ||
| 670 |     private function databases_test() { | 
            ||
| 718 | }  | 
            ||
| 719 | }  | 
            ||
| 720 | }  | 
            ||
| 721 | |||
| 722 | /**  | 
            ||
| 723 | * test devices.php for the no_cache option  | 
            ||
| 724 | *  | 
            ||
| 725 | * @return void  | 
            ||
| 726 | */  | 
            ||
| 727 |     private function device_cache_test() { | 
            ||
| 762 | }  | 
            ||
| 763 | }  | 
            ||
| 764 | |||
| 765 | /**  | 
            ||
| 766 | * test if mailer works  | 
            ||
| 767 | *  | 
            ||
| 768 | * @return void  | 
            ||
| 769 | */  | 
            ||
| 770 |     private function mailer_test() { | 
            ||
| 771 | if (empty(CONFIG['APPEARANCE']['abuse-mail']) || CONFIG['APPEARANCE']['abuse-mail'] == "[email protected]") {  | 
            ||
| 772 | $this->testReturn(\core\common\Entity::L_ERROR, "Your abuse-mail has not been set, cannot continue with mailer tests.");  | 
            ||
| 773 | return;  | 
            ||
| 774 | }  | 
            ||
| 775 | $mail = new \PHPMailer\PHPMailer\PHPMailer();  | 
            ||
| 776 | $mail->isSMTP();  | 
            ||
| 777 | $mail->Port = 587;  | 
            ||
| 778 | $mail->SMTPAuth = true;  | 
            ||
| 779 | $mail->SMTPSecure = 'tls';  | 
            ||
| 780 | $mail->Host = CONFIG['MAILSETTINGS']['host'];  | 
            ||
| 781 | $mail->Username = CONFIG['MAILSETTINGS']['user'];  | 
            ||
| 782 | $mail->Password = CONFIG['MAILSETTINGS']['pass'];  | 
            ||
| 783 | $mail->SMTPOptions = CONFIG['MAILSETTINGS']['options'];  | 
            ||
| 784 | $mail->WordWrap = 72;  | 
            ||
| 785 | $mail->isHTML(FALSE);  | 
            ||
| 786 | $mail->CharSet = 'UTF-8';  | 
            ||
| 787 | $mail->From = CONFIG['APPEARANCE']['from-mail'];  | 
            ||
| 788 | $mail->FromName = CONFIG['APPEARANCE']['productname'] . " Invitation System";  | 
            ||
| 789 | $mail->addAddress(CONFIG['APPEARANCE']['abuse-mail']);  | 
            ||
| 790 | $mail->Subject = "testing CAT configuration mail";  | 
            ||
| 791 | $mail->Body = "Testing CAT mailing\n";  | 
            ||
| 792 | $sent = $mail->send();  | 
            ||
| 793 |         if ($sent) { | 
            ||
| 794 | $this->testReturn(\core\common\Entity::L_OK, "mailer settings appear to be working, check " . CONFIG['APPEARANCE']['abuse-mail'] . " mailbox if the message was receiced.");  | 
            ||
| 795 |         } else { | 
            ||
| 796 | $this->testReturn(\core\common\Entity::L_ERROR, "mailer settings failed, check the Config::MAILSETTINGS");  | 
            ||
| 797 | }  | 
            ||
| 798 | }  | 
            ||
| 799 | |||
| 800 | /**  | 
            ||
| 801 | * TODO test if RADIUS connections work  | 
            ||
| 802 | *  | 
            ||
| 803 | * @return void  | 
            ||
| 804 | */  | 
            ||
| 805 |     private function UDPhosts_test() { | 
            ||
| 806 | // if(empty)  | 
            ||
| 807 | }  | 
            ||
| 808 | |||
| 810 |