diff --git a/core/lib/Drupal/Component/Utility/Crypt.php b/core/lib/Drupal/Component/Utility/Crypt.php index 6ebdc4aac8..583544eb01 100644 --- a/core/lib/Drupal/Component/Utility/Crypt.php +++ b/core/lib/Drupal/Component/Utility/Crypt.php @@ -154,18 +154,22 @@ public static function hashEquals($known_string, $user_string) { } /** - * Returns a URL-safe, base64 encoded string of highly randomized bytes. + * Returns a base64-encoded string of highly randomized bytes. * - * @param $count + * @param int $count * The number of random bytes to fetch and base64 encode. * + * @param array|string $replace + * Optional. An array or string to pass to str_replace(). This value will + * replace "+", "/", and "=". Defaults to URL-safe characters. + * * @return string * The base64 encoded result will have a length of up to 4 * $count. * * @see \Drupal\Component\Utility\Crypt::randomBytes() */ - public static function randomBytesBase64($count = 32) { - return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode(static::randomBytes($count))); + public static function randomBytesBase64($count = 32, $replace = ['-', '_']) { + return str_replace(['+', '/', '='], $replace, base64_encode(static::randomBytes($count))); } } diff --git a/core/lib/Drupal/Core/Session/SessionManager.php b/core/lib/Drupal/Core/Session/SessionManager.php index d0ba7769f2..2ef206be64 100644 --- a/core/lib/Drupal/Core/Session/SessionManager.php +++ b/core/lib/Drupal/Core/Session/SessionManager.php @@ -138,16 +138,16 @@ public function start() { } if (empty($result)) { - // Randomly generate a session identifier for this request. This is - // necessary because \Drupal\Core\TempStore\SharedTempStoreFactory::get() - // wants to know the future session ID of a lazily started session in - // advance. + // Randomly generate a valid PHP session identifier for this request. This + // is necessary because + // \Drupal\Core\TempStore\SharedTempStoreFactory::get() wants to know the + // future session ID of a lazily started session in advance. // // @todo: With current versions of PHP there is little reason to generate // the session id from within application code. Consider using the // default php session id instead of generating a custom one: // https://www.drupal.org/node/2238561 - $this->setId(Crypt::randomBytesBase64()); + $this->setId(Crypt::randomBytesBase64(32, [',', '-'])); // Initialize the session global and attach the Symfony session bags. $_SESSION = []; @@ -245,7 +245,8 @@ public function regenerate($destroy = FALSE, $lifetime = NULL) { // Ensure the session is reloaded correctly. $this->startedLazy = TRUE; } - session_id(Crypt::randomBytesBase64()); + // Generate a valid PHP session identifier. + session_id(Crypt::randomBytesBase64(32, [',', '-'])); $this->getMetadataBag()->clearCsrfTokenSeed(); diff --git a/core/modules/file/file.install b/core/modules/file/file.install index 74ad63b954..77856c281f 100644 --- a/core/modules/file/file.install +++ b/core/modules/file/file.install @@ -70,60 +70,81 @@ function file_requirements($phase) { // Check the server's ability to indicate upload progress. if ($phase == 'runtime') { $description = NULL; - $severity = REQUIREMENT_INFO; + $severity = NULL; $implementation = file_progress_implementation(); - $server_software = \Drupal::request()->server->get('SERVER_SOFTWARE'); - - // Test the web server identity. - if (preg_match("/Nginx/i", $server_software)) { - $is_nginx = TRUE; - $is_apache = FALSE; - $fastcgi = FALSE; - } - elseif (preg_match("/Apache/i", $server_software)) { - $is_nginx = FALSE; - $is_apache = TRUE; - $fastcgi = strpos($server_software, 'mod_fastcgi') !== FALSE || strpos($server_software, 'mod_fcgi') !== FALSE; - } - else { - $is_nginx = FALSE; - $is_apache = FALSE; - $fastcgi = FALSE; - } - - if (!$is_apache && !$is_nginx) { - $value = t('Not enabled'); - $description = t('Your server is not capable of displaying file upload progress. File upload progress requires an Apache server running PHP with mod_php or Nginx with PHP-FPM.'); - } - elseif ($fastcgi) { - $value = t('Not enabled'); - $description = t('Your server is not capable of displaying file upload progress. File upload progress requires PHP be run with mod_php or PHP-FPM and not as FastCGI.'); - } - elseif (!$implementation) { - $value = t('Not enabled'); - $description = t('Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the PECL uploadprogress library.'); - } - elseif ($implementation == 'apc') { - $value = t('Enabled (APC RFC1867)'); - $description = t('Your server is capable of displaying file upload progress using APC RFC1867. Note that only one upload at a time is supported. It is recommended to use the PECL uploadprogress library if possible.'); - } - elseif ($implementation == 'uploadprogress') { - $value = t('Enabled (PECL uploadprogress)'); - } - elseif ($implementation == 'session') { + if ($implementation == 'session') { $value = t('Enabled (PHP session upload progress)'); $session_manager = \Drupal::service('session_manager'); if (!method_exists($session_manager, 'getPHPSessionName') || $session_manager->getPHPSessionName() != session_name()) { - $description = t('The PHP session name must be set to %session_name before Drupal starts in order to store file upload progress. It is currently set to %php_session_name.', [ - ':url' => 'http://php.net/manual/en/session.configuration.php#ini.session.name', - '%session_name' => session_name(), - '%php_session_name' => $session_manager->getPHPSessionName(), - ]); + $description = [ + ['#markup' => t('The PHP session name must be set to %session_name before Drupal starts in order to store file upload progress. It is currently set to %php_session_name.', [ + ':url' => 'http://php.net/manual/en/session.configuration.php#ini.session.name', + '%session_name' => session_name(), + '%php_session_name' => $session_manager->getPHPSessionName(), + ])], + ]; + // Tell users how to configure the PHP session name, if we can. + if (substr(PHP_SAPI, 0, 6) == 'apache') { + // Settings can be configured in a .htaccess file if PHP is running as + // an Apache module. + $description[] = ['#prefix' => ' ', '#markup' => t('Add php_value session.name @session_name to the PHP @php-version settings of the .htaccess file in your Drupal root folder.', [ + '@session_name' => session_name(), + '@php-version' => PHP_MAJOR_VERSION, + ])]; + } + elseif (substr(PHP_SAPI, 0, 3) == 'cgi') { + // PHP running as CGI cannot get settings from .htaccess files, but + // since 5.3.0 it supports .user.ini files. + $description[] = ['#prefix' => ' ', '#markup' => t('Add session.name=@session_name to a .user.ini file in your Drupal root folder.', [ + '@session_name' => session_name(), + ':url' => 'http://php.net/manual/en/configuration.file.per-user.php', + ])]; + } } if (method_exists($session_manager, 'getPHPSessionName') && $session_manager->getPHPSessionName() != session_name()) { $severity = REQUIREMENT_WARNING; } } + else { + $server_software = \Drupal::request()->server->get('SERVER_SOFTWARE'); + + // Test the web server identity. + if (preg_match("/Nginx/i", $server_software)) { + $is_nginx = TRUE; + $is_apache = FALSE; + $fastcgi = FALSE; + } + elseif (preg_match("/Apache/i", $server_software)) { + $is_nginx = FALSE; + $is_apache = TRUE; + $fastcgi = strpos($server_software, 'mod_fastcgi') !== FALSE || strpos($server_software, 'mod_fcgi') !== FALSE; + } + else { + $is_nginx = FALSE; + $is_apache = FALSE; + $fastcgi = FALSE; + } + + if (!$is_apache && !$is_nginx) { + $value = t('Not enabled'); + $description = t('Your server is not capable of displaying file upload progress. File upload progress requires an Apache server running PHP with mod_php or Nginx with PHP-FPM.'); + } + elseif ($fastcgi) { + $value = t('Not enabled'); + $description = t('Your server is not capable of displaying file upload progress. File upload progress requires PHP be run with mod_php or PHP-FPM and not as FastCGI.'); + } + elseif (!$implementation) { + $value = t('Not enabled'); + $description = t('Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the PECL uploadprogress library.'); + } + elseif ($implementation == 'apc') { + $value = t('Enabled (APC RFC1867)'); + $description = t('Your server is capable of displaying file upload progress using APC RFC1867. Note that only one upload at a time is supported. It is recommended to use the PECL uploadprogress library if possible.'); + } + elseif ($implementation == 'uploadprogress') { + $value = t('Enabled (PECL uploadprogress)'); + } + } $requirements['file_progress'] = [ 'title' => t('Upload progress'), 'value' => $value,