diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index e0c1271599e79e37d1792d098882f78495eb6b27..03f66bb97721606a1d5a42decfec3e01b501ad44 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -491,7 +491,7 @@ function drupal_valid_http_host($host) { */ function drupal_settings_initialize() { // Export these settings.php variables to the global namespace. - global $base_url, $databases, $cookie_domain, $drupal_hash_salt, $config_directories, $config; + global $base_url, $databases, $cookie_domain, $config_directories, $config; $settings = array(); $config = array(); @@ -1662,10 +1662,13 @@ function drupal_get_user_timezone() { * A salt based on information in settings.php, not in the database. */ function drupal_get_hash_salt() { - global $drupal_hash_salt, $databases; - // If the $drupal_hash_salt variable is empty, a hash of the serialized - // database credentials is used as a fallback salt. - return empty($drupal_hash_salt) ? hash('sha256', serialize($databases)) : $drupal_hash_salt; + $hash_salt = settings()->get('hash_salt'); + // This should never happen, as it breaks user logins and many other services. + // Therefore, explicitly notify the user (developer) by throwing an exception. + if (empty($hash_salt)) { + throw new \RuntimeException('Missing $settings[\'hash_salt\'] in settings.php.'); + } + return $hash_salt; } /** diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 68fc46e69e8b2f7f19de12dff1fda95220ecbfe4..928694d9a906a5e449ed49d98c326b1830e3130f 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -1255,17 +1255,14 @@ function install_settings_form_submit($form, &$form_state) { 'value' => $database, 'required' => TRUE, ); - $settings['drupal_hash_salt'] = (object) array( + $settings['settings']['hash_salt'] = (object) array( 'value' => Crypt::randomStringHashed(55), 'required' => TRUE, ); - // Remember the profile which was used. - $settings['settings'] = array( - 'install_profile' => (object) array( - 'value' => $install_state['parameters']['profile'], - 'required' => TRUE, - ), + $settings['settings']['install_profile'] = (object) array( + 'value' => $install_state['parameters']['profile'], + 'required' => TRUE, ); drupal_rewrite_settings($settings); diff --git a/core/includes/install.inc b/core/includes/install.inc index fefa9312415f4ccdfeb509a5ec7b73ee5df9e834..c7f5937941056445f33d508e6289c52e37218c9f 100644 --- a/core/includes/install.inc +++ b/core/includes/install.inc @@ -7,6 +7,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse; use Drupal\Component\Utility\Crypt; +use Drupal\Component\Utility\Settings; use Drupal\Core\Database\Database; use Drupal\Core\DrupalKernel; @@ -199,8 +200,14 @@ function drupal_rewrite_settings($settings = array(), $settings_file = NULL) { } // Build list of setting names and insert the values into the global namespace. $variable_names = array(); + $settings_settings = array(); foreach ($settings as $setting => $data) { - _drupal_rewrite_settings_global($GLOBALS[$setting], $data); + if ($setting != 'settings') { + _drupal_rewrite_settings_global($GLOBALS[$setting], $data); + } + else { + _drupal_rewrite_settings_global($settings_settings, $data); + } $variable_names['$'. $setting] = $setting; } $contents = file_get_contents(DRUPAL_ROOT . '/' . $settings_file); @@ -307,6 +314,14 @@ function drupal_rewrite_settings($settings = array(), $settings_file = NULL) { if (file_put_contents(DRUPAL_ROOT . '/' . $settings_file, $buffer) === FALSE) { throw new Exception(t('Failed to modify %settings. Verify the file permissions.', array('%settings' => $settings_file))); } + else { + // In case any $settings variables were written, import them into the + // Settings singleton. + if (!empty($settings_settings)) { + $old_settings = settings()->getAll(); + new Settings($settings_settings + $old_settings); + } + } } else { throw new Exception(t('Failed to open %settings. Verify the file permissions.', array('%settings' => $settings_file))); diff --git a/core/rebuild.php b/core/rebuild.php index 9ddf054857f4460cef6ee793ae037af599517502..81d9f5570f29736dc779fb19aeb14329e6ea47fe 100644 --- a/core/rebuild.php +++ b/core/rebuild.php @@ -24,7 +24,7 @@ if (settings()->get('rebuild_access', FALSE) || (isset($_GET['token'], $_GET['timestamp']) && ((REQUEST_TIME - $_GET['timestamp']) < 300) && - ($_GET['token'] === Crypt::hmacBase64($_GET['timestamp'], $GLOBALS['drupal_hash_salt'])) + ($_GET['token'] === Crypt::hmacBase64($_GET['timestamp'], settings()->get('hash_salt'))) )) { drupal_rebuild(); diff --git a/core/scripts/rebuild_token_calculator.sh b/core/scripts/rebuild_token_calculator.sh index 9b948b48ed12568c12e086d6ab31fe4e2473c828..a75c9b68608568d0b03b9f88334380384a7324d8 100755 --- a/core/scripts/rebuild_token_calculator.sh +++ b/core/scripts/rebuild_token_calculator.sh @@ -19,6 +19,6 @@ } $timestamp = time(); -$token = Crypt::hmacBase64($timestamp, $drupal_hash_salt); +$token = Crypt::hmacBase64($timestamp, settings()->get('hash_salt')); print "timestamp=$timestamp&token=$token\n"; diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index 5642dc5c82a51e583cf2c83f324d69bbdd1e7fee..ad2c404f1334d79b9b7e1f02d90b080ea8e77885 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -213,25 +213,6 @@ */ $databases = array(); -/** - * Salt for one-time login links and cancel links, form tokens, etc. - * - * This variable will be set to a random value by the installer. All one-time - * login links will be invalidated if the value is changed. Note that if your - * site is deployed on a cluster of web servers, you must ensure that this - * variable has the same value on each server. If this variable is empty, a hash - * of the serialized database credentials will be used as a fallback salt. - * - * For enhanced security, you may set this variable to a value using the - * contents of a file outside your docroot that is never saved together - * with any backups of your Drupal files and database. - * - * Example: - * $drupal_hash_salt = file_get_contents('/home/example/salt.txt'); - * - */ -$drupal_hash_salt = ''; - /** * Location of the site configuration files. * @@ -262,6 +243,25 @@ * @see \Drupal\Component\Utility\Settings::get() */ +/** + * Salt for one-time login links, cancel links, form tokens, etc. + * + * This variable will be set to a random value by the installer. All one-time + * login links will be invalidated if the value is changed. Note that if your + * site is deployed on a cluster of web servers, you must ensure that this + * variable has the same value on each server. + * + * For enhanced security, you may set this variable to a value using the + * contents of a file outside your docroot that is never saved together + * with any backups of your Drupal files and database. + * + * Example: + * @code + * $settings['hash_salt'] = file_get_contents('/home/example/salt.txt'); + * @endcode + */ +$settings['hash_salt'] = ''; + /** * Access control for update.php script. *