diff --git a/setup/ajax.dataloader.php b/setup/ajax.dataloader.php index 9d1b01f08..1cb5a51e1 100644 --- a/setup/ajax.dataloader.php +++ b/setup/ajax.dataloader.php @@ -186,8 +186,7 @@ try catch(Exception $e) { header("HTTP/1.0 500 Internal server error."); - echo "

An error happened while processing the installation:

\n"; - echo '

'.$e."

\n"; + echo "

An error happened while processing the installation

\n"; SetupPage::log_error("An error happened while processing the installation: ".$e); } @@ -195,7 +194,7 @@ if (function_exists('memory_get_peak_usage')) { if ($sOperation == 'file') { - SetupPage::log_info("loading file '$sFileName', peak memory usage. ".memory_get_peak_usage()); + SetupPage::log_info("loading file peak memory usage. ".memory_get_peak_usage()); } else { diff --git a/setup/index.php b/setup/index.php index 890c930e8..487e88cab 100644 --- a/setup/index.php +++ b/setup/index.php @@ -25,6 +25,7 @@ require_once(APPROOT.'/setup/setuppage.class.inc.php'); require_once(APPROOT.'/setup/wizardcontroller.class.inc.php'); require_once(APPROOT.'/setup/wizardsteps.class.inc.php'); +session_start(); clearstatcache(); // Make sure we know what we are doing ! // Set a long (at least 4 minutes) execution time for the setup to avoid timeouts during this phase ini_set('max_execution_time', max(240, ini_get('max_execution_time'))); @@ -33,21 +34,17 @@ ini_set('display_errors', true); ini_set('display_startup_errors', true); date_default_timezone_set('Europe/Paris'); // Just to avoid a warning if the timezone is not set in php.ini -SetupUtils::ExitMaintenanceMode(false); - ///////////////////////////////////////////////////////////////////// // Fake functions to protect the first run of the installer // in case the PHP JSON module is not installed... -if (!function_exists('json_encode')) -{ +if (!function_exists('json_encode')) { function json_encode($value, $options = null) { return '[]'; } } -if (!function_exists('json_decode')) -{ - function json_decode($json, $assoc=null) +if (!function_exists('json_decode')) { + function json_decode($json, $assoc = null) { return array(); } @@ -57,4 +54,13 @@ if (!function_exists('json_decode')) //N°3671 setup context: force $bForceTrustProxy to be persisted in next calls utils::GetAbsoluteUrlAppRoot(true); $oWizard = new WizardController('WizStepWelcome'); -$oWizard->Run(); +//N°3952 +if (SetupUtils::IsSessionSetupTokenValid()) { + // Normal operation + $oWizard->Run(); +} else { + SetupUtils::ExitMaintenanceMode(false); + // Force initializing the setup + $oWizard->Start(); + SetupUtils::CreateSetupToken(); +} diff --git a/setup/setuputils.class.inc.php b/setup/setuputils.class.inc.php index 890e3390a..488b5ffa0 100644 --- a/setup/setuputils.class.inc.php +++ b/setup/setuputils.class.inc.php @@ -2019,6 +2019,7 @@ JS } $sUID = hash('sha256', rand()); file_put_contents(APPROOT.'data/setup/authent', $sUID); + $_SESSION['setup_token'] = $sUID; return $sUID; } @@ -2043,6 +2044,33 @@ JS } } + /** + * Check setup transaction and create a new one if necessary + * + * @return bool + */ + public static function IsSessionSetupTokenValid() + { + if (isset($_SESSION['setup_token'])) { + $sAuth = $_SESSION['setup_token']; + $sTokenFile = APPROOT.'data/setup/authent'; + if (file_exists($sTokenFile) && $sAuth === file_get_contents($sTokenFile)) { + return true; + } + } + + return false; + } + + public static function EraseSetupToken() + { + $sTokenFile = APPROOT.'data/setup/authent'; + if (is_file($sTokenFile)) { + unlink($sTokenFile); + } + unset($_SESSION['setup_token']); + } + private final static function Log($sText) { if (class_exists('SetupPage')) diff --git a/setup/wizardcontroller.class.inc.php b/setup/wizardcontroller.class.inc.php index 18a026ba3..a00c73208 100644 --- a/setup/wizardcontroller.class.inc.php +++ b/setup/wizardcontroller.class.inc.php @@ -105,7 +105,7 @@ class WizardController /** * Starts the wizard by displaying it in its initial state */ - protected function Start() + public function Start() { $sCurrentStepClass = $this->sInitialStepClass; $oStep = new $sCurrentStepClass($this, $this->sInitialState); @@ -121,7 +121,7 @@ class WizardController $sCurrentState = utils::ReadParam('_state', $this->sInitialState); /** @var \WizardStep $oStep */ $oStep = new $sCurrentStepClass($this, $sCurrentState); - if ($oStep->ValidateParams($sCurrentState)) + if ($oStep->ValidateParams()) { $this->PushStep(array('class' => $sCurrentStepClass, 'state' => $sCurrentState)); $aPossibleSteps = $oStep->GetPossibleSteps(); @@ -174,7 +174,7 @@ class WizardController if (!is_writable($sConfigFile)) { SetupUtils::ExitReadOnlyMode(false); // Reset readonly mode in case of problem - + SetupUtils::EraseSetupToken(); $sRelativePath = utils::GetConfigFilePathRelative(); $oP = new SetupPage('Installation Cannot Continue'); $oP->add("

Fatal error

\n"); @@ -182,7 +182,8 @@ class WizardController $oP->p("The wizard cannot modify the configuration file for you. If you want to upgrade ".ITOP_APPLICATION.", make sure that the file '".$sRelativePath."' can be modified by the web server."); $oP->p(''); $oP->output(); - return; + // Prevent token creation + exit; } } } diff --git a/setup/wizardsteps.class.inc.php b/setup/wizardsteps.class.inc.php index 2d96d9eea..e9b40cbef 100644 --- a/setup/wizardsteps.class.inc.php +++ b/setup/wizardsteps.class.inc.php @@ -2208,7 +2208,7 @@ CSS $oPage->add('
Database Parameters