1<?php 2/* 3** Zabbix 4** Copyright (C) 2001-2021 Zabbix SIA 5** 6** This program is free software; you can redistribute it and/or modify 7** it under the terms of the GNU General Public License as published by 8** the Free Software Foundation; either version 2 of the License, or 9** (at your option) any later version. 10** 11** This program is distributed in the hope that it will be useful, 12** but WITHOUT ANY WARRANTY; without even the implied warranty of 13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14** GNU General Public License for more details. 15** 16** You should have received a copy of the GNU General Public License 17** along with this program; if not, write to the Free Software 18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19**/ 20 21 22/** 23 * Setup wizzard form. 24 */ 25class CSetupWizard extends CForm { 26 27 protected $DISABLE_CANCEL_BUTTON = false; 28 29 protected $DISABLE_BACK_BUTTON = false; 30 31 protected $SHOW_RETRY_BUTTON = false; 32 33 protected $STEP_FAILED = false; 34 35 protected $frontend_setup; 36 37 public function __construct() { 38 $this->frontend_setup = new CFrontendSetup(); 39 40 $this->stage = [ 41 0 => [ 42 'title' => _('Welcome'), 43 'fnc' => 'stage0' 44 ], 45 1 => [ 46 'title' => _('Check of pre-requisites'), 47 'fnc' => 'stage1' 48 ], 49 2 => [ 50 'title' => _('Configure DB connection'), 51 'fnc' => 'stage2' 52 ], 53 3 => [ 54 'title' => _('Zabbix server details'), 55 'fnc' => 'stage3' 56 ], 57 4 => [ 58 'title' => _('Pre-installation summary'), 59 'fnc' => 'stage4' 60 ], 61 5 => [ 62 'title' => _('Install'), 63 'fnc' => 'stage5' 64 ] 65 ]; 66 67 $this->eventHandler(); 68 69 parent::__construct('post'); 70 parent::setId('setup-form'); 71 } 72 73 private function getConfig(string $name, $default = null) { 74 return CSession::keyExists($name) ? CSession::getValue($name) : $default; 75 } 76 77 private function setConfig(string $name, $value) { 78 CSession::setValue($name, $value); 79 } 80 81 private function getStep(): int { 82 return $this->getConfig('step', 0); 83 } 84 85 private function doNext(): bool { 86 if (isset($this->stage[$this->getStep() + 1])) { 87 $this->setConfig('step', $this->getStep('step') + 1); 88 89 return true; 90 } 91 92 return false; 93 } 94 95 private function doBack(): bool { 96 if (isset($this->stage[$this->getStep() - 1])) { 97 $this->setConfig('step', $this->getStep('step') - 1); 98 99 return true; 100 } 101 102 return false; 103 } 104 105 protected function bodyToString(bool $destroy = true): string { 106 $step = $this->getStep(); 107 108 $setup_left = (new CDiv()) 109 ->addClass(ZBX_STYLE_SETUP_LEFT) 110 ->addItem((new CDiv(makeLogo(LOGO_TYPE_NORMAL)))->addClass('setup-logo')) 111 ->addItem($this->getList()); 112 113 $setup_right = (new CDiv($this->getStage()))->addClass(ZBX_STYLE_SETUP_RIGHT); 114 115 if (CWebUser::$data && CWebUser::getType() == USER_TYPE_SUPER_ADMIN) { 116 $cancel_button = (new CSubmit('cancel', _('Cancel'))) 117 ->addClass(ZBX_STYLE_BTN_ALT) 118 ->addClass(ZBX_STYLE_FLOAT_LEFT); 119 if ($this->DISABLE_CANCEL_BUTTON) { 120 $cancel_button->setEnabled(false); 121 } 122 } 123 else { 124 $cancel_button = null; 125 } 126 127 if (array_key_exists($step + 1, $this->stage)) { 128 $next_button = new CSubmit('next['.$step.']', _('Next step')); 129 } 130 else { 131 $next_button = new CSubmit($this->SHOW_RETRY_BUTTON ? 'retry' : 'finish', _('Finish')); 132 } 133 134 $back_button = (new CSubmit('back['.$step.']', _('Back'))) 135 ->addClass(ZBX_STYLE_BTN_ALT) 136 ->addClass(ZBX_STYLE_FLOAT_LEFT); 137 138 if ($step == 0 || $this->DISABLE_BACK_BUTTON) { 139 $back_button->setEnabled(false); 140 } 141 142 $setup_footer = (new CDiv([new CDiv([$next_button, $back_button]), $cancel_button])) 143 ->addClass(ZBX_STYLE_SETUP_FOOTER); 144 145 $setup_container = (new CDiv([$setup_left, $setup_right, $setup_footer]))->addClass(ZBX_STYLE_SETUP_CONTAINER); 146 147 return parent::bodyToString($destroy).$setup_container->toString(); 148 } 149 150 private function getList(): CList { 151 $list = new CList(); 152 153 foreach ($this->stage as $id => $data) { 154 $list->addItem($data['title'], ($id <= $this->getStep()) ? ZBX_STYLE_SETUP_LEFT_CURRENT : null); 155 } 156 157 return $list; 158 } 159 160 private function getStage(): array { 161 $function = $this->stage[$this->getStep()]['fnc']; 162 return $this->$function(); 163 } 164 165 private function stage0(): array { 166 preg_match('/^\d+\.\d+/', ZABBIX_VERSION, $version); 167 $setup_title = (new CDiv([new CSpan(_('Welcome to')), 'Zabbix '.$version[0]]))->addClass(ZBX_STYLE_SETUP_TITLE); 168 169 return [(new CDiv($setup_title))->addClass(ZBX_STYLE_SETUP_RIGHT_BODY)]; 170 } 171 172 private function stage1(): array { 173 $table = (new CTable()) 174 ->addClass(ZBX_STYLE_LIST_TABLE) 175 ->setHeader(['', _('Current value'), _('Required'), '']); 176 177 $messages = []; 178 $finalResult = CFrontendSetup::CHECK_OK; 179 180 foreach ($this->frontend_setup->checkRequirements() as $req) { 181 if ($req['result'] == CFrontendSetup::CHECK_OK) { 182 $class = ZBX_STYLE_GREEN; 183 $result = 'OK'; 184 } 185 elseif ($req['result'] == CFrontendSetup::CHECK_WARNING) { 186 $class = ZBX_STYLE_ORANGE; 187 $result = new CSpan(_x('Warning', 'setup')); 188 } 189 else { 190 $class = ZBX_STYLE_RED; 191 $result = new CSpan(_('Fail')); 192 $messages[] = ['type' => 'error', 'message' => $req['error']]; 193 } 194 195 $table->addRow( 196 [ 197 $req['name'], 198 $req['current'], 199 ($req['required'] !== null) ? $req['required'] : '', 200 (new CCol($result))->addClass($class) 201 ] 202 ); 203 204 if ($req['result'] > $finalResult) { 205 $finalResult = $req['result']; 206 } 207 } 208 209 if ($finalResult == CFrontendSetup::CHECK_FATAL) { 210 $message_box = makeMessageBox(ZBX_STYLE_MSG_BAD, $messages, null, false, true); 211 } 212 else { 213 $message_box = null; 214 } 215 216 return [ 217 new CTag('h1', true, _('Check of pre-requisites')), 218 (new CDiv([$message_box, $table]))->addClass(ZBX_STYLE_SETUP_RIGHT_BODY) 219 ]; 220 } 221 222 private function stage2(): array { 223 $DB['TYPE'] = $this->getConfig('DB_TYPE', key(CFrontendSetup::getSupportedDatabases())); 224 225 $table = (new CFormList()) 226 ->addItem([ 227 (new CVar('tls_encryption', 0))->removeId(), 228 (new CVar('verify_certificate', 0))->removeId(), 229 (new CVar('verify_host', 0))->removeId() 230 ]); 231 232 $table->addRow(new CLabel(_('Database type'), 'label-type'), 233 (new CSelect('type')) 234 ->setId('type') 235 ->setFocusableElementId('label-type') 236 ->setValue($DB['TYPE']) 237 ->addOptions(CSelect::createOptionsFromArray(CFrontendSetup::getSupportedDatabases())) 238 ); 239 240 $table->addRow(_('Database host'), 241 (new CTextBox('server', $this->getConfig('DB_SERVER', 'localhost'))) 242 ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH) 243 ); 244 245 $table->addRow(_('Database port'), [ 246 (new CNumericBox('port', $this->getConfig('DB_PORT', '0'), 5, false, false, false)) 247 ->removeAttribute('style') 248 ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH), 249 (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN), 250 (new CSpan(_('0 - use default port')))->addClass(ZBX_STYLE_GREY) 251 ]); 252 253 $table->addRow(_('Database name'), 254 (new CTextBox('database', $this->getConfig('DB_DATABASE', 'zabbix'))) 255 ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH) 256 ); 257 258 $table->addRow(_('Database schema'), 259 (new CTextBox('schema', $this->getConfig('DB_SCHEMA', ''))) 260 ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH), 261 'db_schema_row', 262 ZBX_STYLE_DISPLAY_NONE 263 ); 264 265 $table->addRow(_('User'), 266 (new CTextBox('user', $this->getConfig('DB_USER', 'zabbix')))->setWidth(ZBX_TEXTAREA_SMALL_WIDTH) 267 ); 268 $table->addRow(_('Password'), 269 (new CPassBox('password', $this->getConfig('DB_PASSWORD')))->setWidth(ZBX_TEXTAREA_SMALL_WIDTH) 270 ); 271 272 $table->addRow(_('Database TLS encryption'), [ 273 (new CCheckBox('tls_encryption'))->setChecked($this->getConfig('DB_ENCRYPTION', true)), 274 (new CDiv( 275 _('Connection will not be encrypted because it uses a socket file (on Unix) or shared memory (Windows).') 276 )) 277 ->setId('tls_encryption_hint') 278 ->addClass(ZBX_STYLE_DISPLAY_NONE) 279 ], 280 'db_encryption_row', 281 ZBX_STYLE_DISPLAY_NONE 282 ); 283 284 $table->addRow(_('Verify database certificate'), 285 (new CCheckBox('verify_certificate'))->setChecked($this->getConfig('DB_ENCRYPTION_ADVANCED')), 286 'db_verify_host', 287 ZBX_STYLE_DISPLAY_NONE 288 ); 289 290 $table->addRow((new CLabel(_('Database TLS CA file')))->setAsteriskMark(), 291 (new CTextBox('ca_file', $this->getConfig('DB_CA_FILE')))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH), 292 'db_cafile_row', 293 ZBX_STYLE_DISPLAY_NONE 294 ); 295 296 $table->addRow(_('Database TLS key file'), 297 (new CTextBox('key_file', $this->getConfig('DB_KEY_FILE')))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH), 298 'db_keyfile_row', 299 ZBX_STYLE_DISPLAY_NONE 300 ); 301 302 $table->addRow(_('Database TLS certificate file'), 303 (new CTextBox('cert_file', $this->getConfig('DB_CERT_FILE')))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH), 304 'db_certfile_row', 305 ZBX_STYLE_DISPLAY_NONE 306 ); 307 308 $table->addRow(_('Database host verification'), 309 (new CCheckBox('verify_host'))->setChecked($this->getConfig('DB_VERIFY_HOST')), 310 'db_verify_host_row', 311 ZBX_STYLE_DISPLAY_NONE 312 ); 313 314 $table->addRow(_('Database TLS cipher list'), 315 (new CTextBox('cipher_list', $this->getConfig('DB_CIPHER_LIST')))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH), 316 'db_cipher_row', 317 ZBX_STYLE_DISPLAY_NONE 318 ); 319 320 if ($this->STEP_FAILED) { 321 global $ZBX_MESSAGES; 322 323 $message_box = makeMessageBox(ZBX_STYLE_MSG_BAD, $ZBX_MESSAGES, _('Cannot connect to the database.'), false, 324 true 325 ); 326 } 327 else { 328 $message_box = null; 329 } 330 331 return [ 332 new CTag('h1', true, _('Configure DB connection')), 333 (new CDiv([ 334 new CTag('p', true, _s('Please create database manually, and set the configuration parameters for connection to this database. Press "%1$s" button when done.', _('Next step'))), 335 $message_box, 336 $table 337 ]))->addClass(ZBX_STYLE_SETUP_RIGHT_BODY) 338 ]; 339 } 340 341 private function stage3(): array { 342 $table = new CFormList(); 343 344 $table->addRow(_('Host'), 345 (new CTextBox('zbx_server', $this->getConfig('ZBX_SERVER', 'localhost'))) 346 ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH) 347 ); 348 349 $table->addRow(_('Port'), 350 (new CNumericBox('zbx_server_port', $this->getConfig('ZBX_SERVER_PORT', '10051'), 5, false, false, false)) 351 ->removeAttribute('style') 352 ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH) 353 ); 354 355 $table->addRow('Name', 356 (new CTextBox('zbx_server_name', $this->getConfig('ZBX_SERVER_NAME', ''))) 357 ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH) 358 ); 359 360 return [ 361 new CTag('h1', true, _('Zabbix server details')), 362 (new CDiv([ 363 new CTag('p', true, _('Please enter the host name or host IP address and port number of the Zabbix server, as well as the name of the installation (optional).')), 364 $table 365 ]))->addClass(ZBX_STYLE_SETUP_RIGHT_BODY) 366 ]; 367 } 368 369 private function stage4(): array { 370 $db_type = $this->getConfig('DB_TYPE'); 371 $databases = CFrontendSetup::getSupportedDatabases(); 372 373 $table = new CFormList(); 374 $table->addRow((new CSpan(_('Database type')))->addClass(ZBX_STYLE_GREY), $databases[$db_type]); 375 376 $db_port = ($this->getConfig('DB_PORT') == 0) ? _('default') : $this->getConfig('DB_PORT'); 377 $db_password = preg_replace('/./', '*', $this->getConfig('DB_PASSWORD')); 378 379 $table->addRow((new CSpan(_('Database server')))->addClass(ZBX_STYLE_GREY), $this->getConfig('DB_SERVER')); 380 $table->addRow((new CSpan(_('Database port')))->addClass(ZBX_STYLE_GREY), $db_port); 381 $table->addRow((new CSpan(_('Database name')))->addClass(ZBX_STYLE_GREY), $this->getConfig('DB_DATABASE')); 382 $table->addRow((new CSpan(_('Database user')))->addClass(ZBX_STYLE_GREY), $this->getConfig('DB_USER')); 383 $table->addRow((new CSpan(_('Database password')))->addClass(ZBX_STYLE_GREY), $db_password); 384 if ($db_type === ZBX_DB_POSTGRESQL) { 385 $table->addRow((new CSpan(_('Database schema')))->addClass(ZBX_STYLE_GREY), $this->getConfig('DB_SCHEMA')); 386 } 387 $table->addRow((new CSpan(_('Database TLS encryption')))->addClass(ZBX_STYLE_GREY), 388 $this->getConfig('DB_ENCRYPTION') ? 'true' : 'false' 389 ); 390 if ($this->getConfig('DB_ENCRYPTION_ADVANCED')) { 391 $table->addRow((new CSpan(_('Database TLS CA file')))->addClass(ZBX_STYLE_GREY), 392 $this->getConfig('DB_CA_FILE') 393 ); 394 $table->addRow((new CSpan(_('Database TLS key file')))->addClass(ZBX_STYLE_GREY), 395 $this->getConfig('DB_KEY_FILE') 396 ); 397 $table->addRow((new CSpan(_('Database TLS certificate file')))->addClass(ZBX_STYLE_GREY), 398 $this->getConfig('DB_CERT_FILE') 399 ); 400 $table->addRow((new CSpan(_('Database host verification')))->addClass(ZBX_STYLE_GREY), 401 $this->getConfig('DB_VERIFY_HOST') ? 'true' : 'false' 402 ); 403 if ($db_type === ZBX_DB_MYSQL) { 404 $table->addRow((new CSpan(_('Database TLS cipher list')))->addClass(ZBX_STYLE_GREY), 405 $this->getConfig('DB_CIPHER_LIST') 406 ); 407 } 408 } 409 410 $table->addRow(null, null); 411 412 $table->addRow((new CSpan(_('Zabbix server')))->addClass(ZBX_STYLE_GREY), $this->getConfig('ZBX_SERVER')); 413 $table->addRow((new CSpan(_('Zabbix server port')))->addClass(ZBX_STYLE_GREY), 414 $this->getConfig('ZBX_SERVER_PORT') 415 ); 416 $table->addRow((new CSpan(_('Zabbix server name')))->addClass(ZBX_STYLE_GREY), 417 $this->getConfig('ZBX_SERVER_NAME') 418 ); 419 420 return [ 421 new CTag('h1', true, _('Pre-installation summary')), 422 (new CDiv([ 423 new CTag('p', true, _s('Please check configuration parameters. If all is correct, press "%1$s" button, or "%2$s" button to change configuration parameters.', _('Next step'), _('Back'))), 424 $table 425 ]))->addClass(ZBX_STYLE_SETUP_RIGHT_BODY) 426 ]; 427 } 428 429 private function stage5(): array { 430 /* 431 * Having non-super-admin authenticated at this step means: 432 * - Either the config file has been manually created by the user. 433 * - Or dealing with a spoofed session cookie. 434 * 435 * Since it is not possible to distinguish between the two, it's also impossible to validate the config file 436 * and display any discrepancies with the configuration stored within the session. 437 */ 438 if (CWebUser::$data && CWebUser::getType() < USER_TYPE_SUPER_ADMIN) { 439 CSession::clear(); 440 441 return $this->stageInstalled(); 442 } 443 444 $this->setConfig('ZBX_CONFIG_FILE_CORRECT', true); 445 446 $config_file_name = APP::getInstance()->getRootDir().CConfigFile::CONFIG_FILE_PATH; 447 $config = new CConfigFile($config_file_name); 448 $config->config = [ 449 'DB' => [ 450 'TYPE' => $this->getConfig('DB_TYPE'), 451 'SERVER' => $this->getConfig('DB_SERVER'), 452 'PORT' => $this->getConfig('DB_PORT'), 453 'DATABASE' => $this->getConfig('DB_DATABASE'), 454 'USER' => $this->getConfig('DB_USER'), 455 'PASSWORD' => $this->getConfig('DB_PASSWORD'), 456 'SCHEMA' => $this->getConfig('DB_SCHEMA'), 457 'ENCRYPTION' => $this->getConfig('DB_ENCRYPTION'), 458 'KEY_FILE' => $this->getConfig('DB_KEY_FILE'), 459 'CERT_FILE' => $this->getConfig('DB_CERT_FILE'), 460 'CA_FILE' => $this->getConfig('DB_CA_FILE'), 461 'VERIFY_HOST' => $this->getConfig('DB_VERIFY_HOST'), 462 'CIPHER_LIST' => $this->getConfig('DB_CIPHER_LIST'), 463 'DOUBLE_IEEE754' => $this->getConfig('DB_DOUBLE_IEEE754') 464 ], 465 'ZBX_SERVER' => $this->getConfig('ZBX_SERVER'), 466 'ZBX_SERVER_PORT' => $this->getConfig('ZBX_SERVER_PORT'), 467 'ZBX_SERVER_NAME' => $this->getConfig('ZBX_SERVER_NAME') 468 ]; 469 470 $error = false; 471 472 if (!$config->save()) { 473 $error = true; 474 $messages[] = [ 475 'type' => 'error', 476 'message' => $config->error 477 ]; 478 } 479 480 if ($error) { 481 $this->SHOW_RETRY_BUTTON = true; 482 483 $this->setConfig('ZBX_CONFIG_FILE_CORRECT', false); 484 485 $message_box = makeMessageBox(ZBX_STYLE_MSG_BAD, $messages, _('Cannot create the configuration file.'), 486 false, true 487 ); 488 $message = [ 489 new CTag('p', true, _('Alternatively, you can install it manually:')), 490 new CTag('ol', true, [ 491 new CTag('li', true, new CLink(_('Download the configuration file'), 'setup.php?save_config=1')), 492 new CTag('li', true, _s('Save it as "%1$s"', $config_file_name)) 493 ]) 494 ]; 495 496 return [ 497 new CTag('h1', true, _('Install')), 498 (new CDiv([$message_box, $message]))->addClass(ZBX_STYLE_SETUP_RIGHT_BODY) 499 ]; 500 } 501 502 // Clear session after success install. 503 CSession::clear(); 504 505 return $this->stageInstalled(); 506 } 507 508 private function stageInstalled() { 509 $this->DISABLE_CANCEL_BUTTON = true; 510 $this->DISABLE_BACK_BUTTON = true; 511 512 $message_box = null; 513 $message = [ 514 (new CTag('h1', true, _('Congratulations! You have successfully installed Zabbix frontend.'))) 515 ->addClass(ZBX_STYLE_GREEN), 516 new CTag('p', true, _s('Configuration file "%1$s" created.', ltrim(CConfigFile::CONFIG_FILE_PATH, '/'))) 517 ]; 518 519 return [ 520 new CTag('h1', true, _('Install')), 521 (new CDiv([$message_box, $message]))->addClass(ZBX_STYLE_SETUP_RIGHT_BODY) 522 ]; 523 } 524 525 private function dbConnect() { 526 global $DB; 527 528 if (!$this->getConfig('check_fields_result')) { 529 return false; 530 } 531 532 $DB['TYPE'] = $this->getConfig('DB_TYPE'); 533 if ($DB['TYPE'] === null) { 534 return false; 535 } 536 537 $DB['SERVER'] = $this->getConfig('DB_SERVER', 'localhost'); 538 $DB['PORT'] = $this->getConfig('DB_PORT', '0'); 539 $DB['DATABASE'] = $this->getConfig('DB_DATABASE', 'zabbix'); 540 $DB['USER'] = $this->getConfig('DB_USER', 'root'); 541 $DB['PASSWORD'] = $this->getConfig('DB_PASSWORD', ''); 542 $DB['SCHEMA'] = $this->getConfig('DB_SCHEMA', ''); 543 $DB['ENCRYPTION'] = (bool) $this->getConfig('DB_ENCRYPTION', true); 544 $DB['VERIFY_HOST'] = (bool) $this->getConfig('DB_VERIFY_HOST', true); 545 $DB['KEY_FILE'] = $this->getConfig('DB_KEY_FILE', ''); 546 $DB['CERT_FILE'] = $this->getConfig('DB_CERT_FILE', ''); 547 $DB['CA_FILE'] = $this->getConfig('DB_CA_FILE', ''); 548 $DB['CIPHER_LIST'] = $this->getConfig('DB_CIPHER_LIST', ''); 549 550 $error = ''; 551 552 // Check certificate files exists. 553 if ($DB['ENCRYPTION'] && ($DB['TYPE'] === ZBX_DB_MYSQL || $DB['TYPE'] === ZBX_DB_POSTGRESQL)) { 554 if (($this->getConfig('DB_ENCRYPTION_ADVANCED') || $DB['CA_FILE'] !== '') && !file_exists($DB['CA_FILE'])) { 555 return _s('Incorrect file path for "%1$s": %2$s.', _('Database TLS CA file'), $DB['CA_FILE']); 556 } 557 558 if ($DB['KEY_FILE'] !== '' && !file_exists($DB['KEY_FILE'])) { 559 return _s('Incorrect file path for "%1$s": %2$s.', _('Database TLS key file'), $DB['KEY_FILE']); 560 } 561 562 if ($DB['CERT_FILE'] !== '' && !file_exists($DB['CERT_FILE'])) { 563 return _s('Incorrect file path for "%1$s": %2$s.', _('Database TLS certificate file'), 564 $DB['CERT_FILE'] 565 ); 566 } 567 } 568 569 // During setup set debug to false to avoid displaying unwanted PHP errors in messages. 570 if (DBconnect($error)) { 571 return true; 572 } 573 else { 574 return $error; 575 } 576 } 577 578 private function dbClose(): void { 579 global $DB; 580 581 DBclose(); 582 583 $DB = null; 584 } 585 586 private function checkConnection() { 587 global $DB; 588 589 $result = true; 590 591 if (!zbx_empty($DB['SCHEMA']) && $DB['TYPE'] == ZBX_DB_POSTGRESQL) { 592 $db_schema = DBselect( 593 "SELECT schema_name". 594 " FROM information_schema.schemata". 595 " WHERE schema_name='".pg_escape_string($DB['SCHEMA'])."'" 596 ); 597 $result = DBfetch($db_schema); 598 } 599 600 $db = DB::getDbBackend(); 601 602 if (!$db->checkEncoding()) { 603 error($db->getWarning()); 604 605 return false; 606 } 607 608 return $result; 609 } 610 611 private function eventHandler(): void { 612 /* 613 * Having non-super-admin authenticated at this step means: 614 * - Either the config file has been manually created by the user. 615 * - Or dealing with a spoofed session cookie. 616 * 617 * Since it is not possible to distinguish between the two, skip data validation and prevent stage switching. 618 * Any of either cases is only possible with 5th stage. 619 */ 620 if (CWebUser::$data && CWebUser::getType() < USER_TYPE_SUPER_ADMIN) { 621 return; 622 } 623 624 if (hasRequest('back') && array_key_exists($this->getStep(), getRequest('back'))) { 625 $this->doBack(); 626 } 627 628 if ($this->getStep() == 1) { 629 if (hasRequest('next') && array_key_exists(1, getRequest('next'))) { 630 $finalResult = CFrontendSetup::CHECK_OK; 631 foreach ($this->frontend_setup->checkRequirements() as $req) { 632 if ($req['result'] > $finalResult) { 633 $finalResult = $req['result']; 634 } 635 } 636 637 if ($finalResult == CFrontendSetup::CHECK_FATAL) { 638 $this->STEP_FAILED = true; 639 unset($_REQUEST['next']); 640 } 641 else { 642 $this->doNext(); 643 } 644 } 645 } 646 elseif ($this->getStep() == 2) { 647 $input = [ 648 'DB_TYPE' => getRequest('type', $this->getConfig('DB_TYPE')), 649 'DB_SERVER' => getRequest('server', $this->getConfig('DB_SERVER', 'localhost')), 650 'DB_PORT' => getRequest('port', $this->getConfig('DB_PORT', '0')), 651 'DB_DATABASE' => getRequest('database', $this->getConfig('DB_DATABASE', 'zabbix')), 652 'DB_USER' => getRequest('user', $this->getConfig('DB_USER', 'root')), 653 'DB_PASSWORD' => getRequest('password', $this->getConfig('DB_PASSWORD', '')), 654 'DB_SCHEMA' => getRequest('schema', $this->getConfig('DB_SCHEMA', '')), 655 'DB_ENCRYPTION' => (bool) getRequest('tls_encryption', $this->getConfig('DB_ENCRYPTION', false)), 656 'DB_ENCRYPTION_ADVANCED' => (bool) getRequest('verify_certificate', 657 $this->getConfig('DB_ENCRYPTION_ADVANCED', false) 658 ), 659 'DB_VERIFY_HOST' => (bool) getRequest('verify_host', $this->getConfig('DB_VERIFY_HOST', false)), 660 'DB_KEY_FILE' => getRequest('key_file', $this->getConfig('DB_KEY_FILE', '')), 661 'DB_CERT_FILE' => getRequest('cert_file', $this->getConfig('DB_CERT_FILE', '')), 662 'DB_CA_FILE' => getRequest('ca_file', $this->getConfig('DB_CA_FILE', '')), 663 'DB_CIPHER_LIST' => getRequest('cipher_list', $this->getConfig('DB_CIPHER_LIST', '')) 664 ]; 665 666 if (!$input['DB_ENCRYPTION_ADVANCED']) { 667 $input['DB_KEY_FILE'] = ''; 668 $input['DB_CERT_FILE'] = ''; 669 $input['DB_CA_FILE'] = ''; 670 $input['DB_CIPHER_LIST'] = ''; 671 } 672 else if ($input['DB_TYPE'] === ZBX_DB_MYSQL) { 673 $input['DB_VERIFY_HOST'] = true; 674 } 675 676 if ($input['DB_TYPE'] !== ZBX_DB_POSTGRESQL) { 677 $input['DB_SCHEMA'] = ''; 678 } 679 680 array_map([$this, 'setConfig'], array_keys($input), $input); 681 682 if (hasRequest('next') && array_key_exists(2, getRequest('next'))) { 683 $db_connected = $this->dbConnect(); 684 if ($db_connected === true) { 685 $db_connection_checked = $this->checkConnection(); 686 } 687 else { 688 error($db_connected); 689 $db_connection_checked = false; 690 } 691 692 if ($db_connection_checked) { 693 $this->setConfig('DB_DOUBLE_IEEE754', DB::getDbBackend()->isDoubleIEEE754()); 694 } 695 696 if ($db_connected === true) { 697 $this->dbClose(); 698 } 699 700 if ($db_connection_checked) { 701 $this->doNext(); 702 } 703 else { 704 $this->STEP_FAILED = true; 705 unset($_REQUEST['next']); 706 } 707 } 708 } 709 elseif ($this->getStep() == 3) { 710 $this->setConfig('ZBX_SERVER', getRequest('zbx_server', $this->getConfig('ZBX_SERVER', 'localhost'))); 711 $this->setConfig('ZBX_SERVER_PORT', getRequest('zbx_server_port', $this->getConfig('ZBX_SERVER_PORT', '10051'))); 712 $this->setConfig('ZBX_SERVER_NAME', getRequest('zbx_server_name', $this->getConfig('ZBX_SERVER_NAME', ''))); 713 714 if (hasRequest('next') && array_key_exists(3, getRequest('next'))) { 715 $this->doNext(); 716 } 717 } 718 elseif ($this->getStep() == 4) { 719 if (hasRequest('next') && array_key_exists(4, getRequest('next'))) { 720 $this->doNext(); 721 } 722 } 723 elseif ($this->getStep() == 5) { 724 if (hasRequest('save_config')) { 725 // make zabbix.conf.php downloadable 726 header('Content-Type: application/x-httpd-php'); 727 header('Content-Disposition: attachment; filename="'.basename(CConfigFile::CONFIG_FILE_PATH).'"'); 728 $config = new CConfigFile(APP::getInstance()->getRootDir().CConfigFile::CONFIG_FILE_PATH); 729 $config->config = [ 730 'DB' => [ 731 'TYPE' => $this->getConfig('DB_TYPE'), 732 'SERVER' => $this->getConfig('DB_SERVER'), 733 'PORT' => $this->getConfig('DB_PORT'), 734 'DATABASE' => $this->getConfig('DB_DATABASE'), 735 'USER' => $this->getConfig('DB_USER'), 736 'PASSWORD' => $this->getConfig('DB_PASSWORD'), 737 'SCHEMA' => $this->getConfig('DB_SCHEMA'), 738 'ENCRYPTION' => (bool) $this->getConfig('DB_ENCRYPTION'), 739 'VERIFY_HOST' => (bool) $this->getConfig('DB_VERIFY_HOST'), 740 'KEY_FILE' => $this->getConfig('DB_KEY_FILE'), 741 'CERT_FILE' => $this->getConfig('DB_CERT_FILE'), 742 'CA_FILE' => $this->getConfig('DB_CA_FILE'), 743 'CIPHER_LIST' => $this->getConfig('DB_CIPHER_LIST'), 744 'DOUBLE_IEEE754' => $this->getConfig('DB_DOUBLE_IEEE754') 745 ], 746 'ZBX_SERVER' => $this->getConfig('ZBX_SERVER'), 747 'ZBX_SERVER_PORT' => $this->getConfig('ZBX_SERVER_PORT'), 748 'ZBX_SERVER_NAME' => $this->getConfig('ZBX_SERVER_NAME') 749 ]; 750 die($config->getString()); 751 } 752 } 753 754 if (hasRequest('next') && array_key_exists($this->getStep(), getRequest('next'))) { 755 $this->doNext(); 756 } 757 } 758} 759