From 0ed04a6c00423cc5eeffef19558d7598e96fd82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Wed, 30 Mar 2022 22:13:54 -0300 Subject: [PATCH 01/14] Remove `trigger_error` calls from `HomeController` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurício Meneghini Fauth (cherry picked from commit c5611531c03a5c9dfe13510e7fc5b901daa77039) Signed-off-by: Maurício Meneghini Fauth --- .../classes/Controllers/HomeController.php | 103 +++++++++--------- templates/home/index.twig | 13 ++- 2 files changed, 66 insertions(+), 50 deletions(-) diff --git a/libraries/classes/Controllers/HomeController.php b/libraries/classes/Controllers/HomeController.php index 322ed3702e..998cc3b4ce 100644 --- a/libraries/classes/Controllers/HomeController.php +++ b/libraries/classes/Controllers/HomeController.php @@ -30,10 +30,7 @@ use function ini_get; use function mb_strlen; use function preg_match; use function sprintf; -use function trigger_error; -use const E_USER_NOTICE; -use const E_USER_WARNING; use const PHP_VERSION; use const SODIUM_CRYPTO_SECRETBOX_KEYBYTES; @@ -48,6 +45,12 @@ class HomeController extends AbstractController /** @var DatabaseInterface */ private $dbi; + /** + * @var array> + * @psalm-var list + */ + private $errors = []; + public function __construct( ResponseRenderer $response, Template $template, @@ -241,6 +244,7 @@ class HomeController extends AbstractController 'config_storage_message' => $configStorageMessage ?? '', 'has_theme_manager' => $cfg['ThemeManager'], 'themes' => $this->themeManager->getThemesArray(), + 'errors' => $this->errors, ]); } @@ -256,16 +260,16 @@ class HomeController extends AbstractController */ $gc_time = (int) ini_get('session.gc_maxlifetime'); if ($gc_time < $cfg['LoginCookieValidity']) { - trigger_error( - __( + $this->errors[] = [ + 'message' => __( 'Your PHP parameter [a@https://www.php.net/manual/en/session.' . 'configuration.php#ini.session.gc-maxlifetime@_blank]session.' . 'gc_maxlifetime[/a] is lower than cookie validity configured ' . 'in phpMyAdmin, because of this, your login might expire sooner ' . 'than configured in phpMyAdmin.' ), - E_USER_WARNING - ); + 'severity' => 'warning', + ]; } } @@ -273,14 +277,14 @@ class HomeController extends AbstractController * Check whether LoginCookieValidity is limited by LoginCookieStore. */ if ($cfg['LoginCookieStore'] != 0 && $cfg['LoginCookieStore'] < $cfg['LoginCookieValidity']) { - trigger_error( - __( + $this->errors[] = [ + 'message' => __( 'Login cookie store is lower than cookie validity configured in ' . 'phpMyAdmin, because of this, your login will expire sooner than ' . 'configured in phpMyAdmin.' ), - E_USER_WARNING - ); + 'severity' => 'warning', + ]; } /** @@ -292,15 +296,15 @@ class HomeController extends AbstractController && $cfg['Server']['controluser'] === 'pma' && $cfg['Server']['controlpass'] === 'pmapass' ) { - trigger_error( - __( + $this->errors[] = [ + 'message' => __( 'Your server is running with default values for the ' . 'controluser and password (controlpass) and is open to ' . 'intrusion; you really should fix this security weakness' . ' by changing the password for controluser \'pma\'.' ), - E_USER_WARNING - ); + 'severity' => 'warning', + ]; } /** @@ -308,23 +312,23 @@ class HomeController extends AbstractController */ if (! empty($_SESSION['encryption_key'])) { if (empty($cfg['blowfish_secret'])) { - trigger_error( - __( + $this->errors[] = [ + 'message' => __( 'The configuration file now needs a secret passphrase (blowfish_secret).' ), - E_USER_WARNING - ); + 'severity' => 'warning', + ]; } elseif (mb_strlen($cfg['blowfish_secret'], '8bit') !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) { - trigger_error( - sprintf( + $this->errors[] = [ + 'message' => sprintf( __( 'The secret passphrase in configuration (blowfish_secret) is not the correct length.' . ' It should be %d bytes long.' ), SODIUM_CRYPTO_SECRETBOX_KEYBYTES ), - E_USER_WARNING - ); + 'severity' => 'warning', + ]; } } @@ -333,16 +337,16 @@ class HomeController extends AbstractController * production environment. */ if (@file_exists(ROOT_PATH . 'config')) { - trigger_error( - __( + $this->errors[] = [ + 'message' => __( 'Directory [code]config[/code], which is used by the setup script, ' . 'still exists in your phpMyAdmin directory. It is strongly ' . 'recommended to remove it once phpMyAdmin has been configured. ' . 'Otherwise the security of your server may be compromised by ' . 'unauthorized people downloading your configuration.' ), - E_USER_WARNING - ); + 'severity' => 'warning', + ]; } /** @@ -353,22 +357,22 @@ class HomeController extends AbstractController && ini_get('suhosin.request.max_value_length') && ini_get('suhosin.simulation') == '0' ) { - trigger_error( - sprintf( + $this->errors[] = [ + 'message' => sprintf( __( 'Server running with Suhosin. Please refer to %sdocumentation%s for possible issues.' ), '[doc@faq1-38]', '[/doc]' ), - E_USER_WARNING - ); + 'severity' => 'warning', + ]; } /* Missing template cache */ if ($this->config->getTempDir('twig') === null) { - trigger_error( - sprintf( + $this->errors[] = [ + 'message' => sprintf( __( 'The $cfg[\'TempDir\'] (%s) is not accessible. ' . 'phpMyAdmin is not able to cache templates and will ' . @@ -376,8 +380,8 @@ class HomeController extends AbstractController ), $this->config->get('TempDir') ), - E_USER_WARNING - ); + 'severity' => 'warning', + ]; } $this->checkLanguageStats(); @@ -410,12 +414,12 @@ class HomeController extends AbstractController return; } - trigger_error( - 'You are using an incomplete translation, please help to make it ' - . 'better by [a@https://www.phpmyadmin.net/translate/' - . '@_blank]contributing[/a].', - E_USER_NOTICE - ); + $this->errors[] = [ + 'message' => 'You are using an incomplete translation, please help to make it ' + . 'better by [a@https://www.phpmyadmin.net/translate/' + . '@_blank]contributing[/a].', + 'severity' => 'notice', + ]; } private function checkPhpExtensionsRequirements(): void @@ -425,15 +429,15 @@ class HomeController extends AbstractController * to tell user something might be broken without it, see bug #1063149. */ if (! extension_loaded('mbstring')) { - trigger_error( - __( + $this->errors[] = [ + 'message' => __( 'The mbstring PHP extension was not found and you seem to be using' . ' a multibyte charset. Without the mbstring extension phpMyAdmin' . ' is unable to split strings correctly and it may result in' . ' unexpected results.' ), - E_USER_WARNING - ); + 'severity' => 'warning', + ]; } /** @@ -443,12 +447,13 @@ class HomeController extends AbstractController return; } - trigger_error( - __( + $this->errors[] = [ + 'message' => __( 'The curl extension was not found and allow_url_fopen is ' . 'disabled. Due to this some features such as error reporting ' . 'or version check are disabled.' - ) - ); + ), + 'severity' => 'notice', + ]; } } diff --git a/templates/home/index.twig b/templates/home/index.twig index 72b70a242b..9e089f840c 100644 --- a/templates/home/index.twig +++ b/templates/home/index.twig @@ -9,7 +9,7 @@
{{ sync_favorite_tables|raw }}
-
+
{% if has_server %} {% if is_demo %} @@ -273,6 +273,17 @@
+ + {% for error in errors %} + + {% endfor %}
From 5d4884d294ca9b1f069fcacada98f6697f464274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Thu, 15 Sep 2022 13:04:22 -0300 Subject: [PATCH 02/14] Update setup page to generate better blowfish_secret keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of generating a printable string, it generates a binary string and converts it to an hexadecimal string. Signed-off-by: Maurício Meneghini Fauth --- .../classes/Config/ServerConfigChecks.php | 71 +++++------------- libraries/classes/Setup/ConfigGenerator.php | 26 +++++++ phpstan-baseline.neon | 5 ++ psalm-baseline.xml | 29 +++----- .../classes/Config/ServerConfigChecksTest.php | 74 ++++++++++++++++--- test/classes/Setup/ConfigGeneratorTest.php | 30 ++++++++ 6 files changed, 153 insertions(+), 82 deletions(-) diff --git a/libraries/classes/Config/ServerConfigChecks.php b/libraries/classes/Config/ServerConfigChecks.php index 4a8283c742..3420091e94 100644 --- a/libraries/classes/Config/ServerConfigChecks.php +++ b/libraries/classes/Config/ServerConfigChecks.php @@ -11,17 +11,17 @@ use PhpMyAdmin\Core; use PhpMyAdmin\Sanitize; use PhpMyAdmin\Setup\Index as SetupIndex; use PhpMyAdmin\Url; -use PhpMyAdmin\Util; use function __; -use function count; use function function_exists; use function htmlspecialchars; -use function implode; use function ini_get; -use function preg_match; +use function is_string; +use function mb_strlen; +use function sodium_crypto_secretbox_keygen; use function sprintf; -use function strlen; + +use const SODIUM_CRYPTO_SECRETBOX_KEYBYTES; /** * Performs various compatibility, security and consistency checks on current config @@ -247,9 +247,12 @@ class ServerConfigChecks $cookieAuthServer, $blowfishSecretSet ): array { - if ($cookieAuthServer && $blowfishSecret === null) { + if ( + $cookieAuthServer + && (! is_string($blowfishSecret) || mb_strlen($blowfishSecret, '8bit') !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) + ) { $blowfishSecretSet = true; - $this->cfg->set('blowfish_secret', Util::generateRandom(32)); + $this->cfg->set('blowfish_secret', sodium_crypto_secretbox_keygen()); } return [ @@ -345,55 +348,21 @@ class ServerConfigChecks ): void { // $cfg['blowfish_secret'] // it's required for 'cookie' authentication - if (! $cookieAuthUsed) { - return; - } - - if ($blowfishSecretSet) { - // 'cookie' auth used, blowfish_secret was generated - SetupIndex::messagesSet( - 'notice', - 'blowfish_secret_created', - Descriptions::get('blowfish_secret'), - Sanitize::sanitizeMessage(__( - 'You didn\'t have blowfish secret set and have enabled ' - . '[kbd]cookie[/kbd] authentication, so a key was automatically ' - . 'generated for you. It is used to encrypt cookies; you don\'t need to ' - . 'remember it.' - )) - ); - - return; - } - - $blowfishWarnings = []; - // check length - if (strlen($blowfishSecret) < 32) { - // too short key - $blowfishWarnings[] = __('Key is too short, it should have at least 32 characters.'); - } - - // check used characters - $hasDigits = (bool) preg_match('/\d/', $blowfishSecret); - $hasChars = (bool) preg_match('/\S/', $blowfishSecret); - $hasNonword = (bool) preg_match('/\W/', $blowfishSecret); - if (! $hasDigits || ! $hasChars || ! $hasNonword) { - $blowfishWarnings[] = Sanitize::sanitizeMessage( - __( - 'Key should contain letters, numbers [em]and[/em] special characters.' - ) - ); - } - - if (empty($blowfishWarnings)) { + if (! $cookieAuthUsed || ! $blowfishSecretSet) { return; } + // 'cookie' auth used, blowfish_secret was generated SetupIndex::messagesSet( - 'error', - 'blowfish_warnings' . count($blowfishWarnings), + 'notice', + 'blowfish_secret_created', Descriptions::get('blowfish_secret'), - implode('
', $blowfishWarnings) + Sanitize::sanitizeMessage(__( + 'You didn\'t have blowfish secret set and have enabled ' + . '[kbd]cookie[/kbd] authentication, so a key was automatically ' + . 'generated for you. It is used to encrypt cookies; you don\'t need to ' + . 'remember it.' + )) ); } diff --git a/libraries/classes/Setup/ConfigGenerator.php b/libraries/classes/Setup/ConfigGenerator.php index d252636efa..af5d94a637 100644 --- a/libraries/classes/Setup/ConfigGenerator.php +++ b/libraries/classes/Setup/ConfigGenerator.php @@ -15,12 +15,18 @@ use function count; use function gmdate; use function implode; use function is_array; +use function is_string; +use function mb_strlen; use function preg_replace; +use function sodium_bin2hex; +use function sodium_crypto_secretbox_keygen; +use function sprintf; use function str_contains; use function strtr; use function var_export; use const DATE_RFC1123; +use const SODIUM_CRYPTO_SECRETBOX_KEYBYTES; /** * Config file generation class @@ -94,6 +100,12 @@ class ConfigGenerator */ private static function getVarExport($var_name, $var_value, $crlf) { + if ($var_name === 'blowfish_secret') { + $secret = self::getBlowfishSecretKey($var_value); + + return sprintf('$cfg[\'blowfish_secret\'] = \sodium_hex2bin(\'%s\');%s', sodium_bin2hex($secret), $crlf); + } + if (! is_array($var_value) || empty($var_value)) { return "\$cfg['" . $var_name . "'] = " . var_export($var_value, true) . ';' . $crlf; @@ -199,4 +211,18 @@ class ConfigGenerator return $ret; } + + /** + * @param mixed $key + * + * @psalm-return non-empty-string + */ + private static function getBlowfishSecretKey($key): string + { + if (is_string($key) && mb_strlen($key, '8bit') === SODIUM_CRYPTO_SECRETBOX_KEYBYTES) { + return $key; + } + + return sodium_crypto_secretbox_keygen(); + } } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1c03b2ea93..c3fd561717 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -7790,6 +7790,11 @@ parameters: count: 1 path: libraries/classes/Setup/ConfigGenerator.php + - + message: "#^Method PhpMyAdmin\\\\Setup\\\\ConfigGenerator\\:\\:getBlowfishSecretKey\\(\\) should return non\\-empty\\-string but returns string\\.$#" + count: 2 + path: libraries/classes/Setup/ConfigGenerator.php + - message: "#^Method PhpMyAdmin\\\\Setup\\\\ConfigGenerator\\:\\:getServerPart\\(\\) has parameter \\$servers with no value type specified in iterable type array\\.$#" count: 1 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index fdfa268435..be2ba27d96 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -12573,6 +12573,10 @@ + + $key + sodium_crypto_secretbox_keygen() + $conf['Servers'] @@ -12590,6 +12594,9 @@ $v $v + + non-empty-string + self::getServerPart($cf, $crlf, $conf['Servers']) @@ -14280,40 +14287,24 @@ - - $_SESSION['messages'] + $_SESSION['messages']['error'] - $_SESSION['messages']['error'] - $_SESSION['messages']['notice'] $_SESSION['messages']['notice'] - + $_SESSION['messages']['error'] - $_SESSION['messages']['error'] - $_SESSION['messages']['notice'] $_SESSION['messages']['notice'] - - $_SESSION[$this->sessionID]['AllowArbitraryServer'] + $_SESSION[$this->sessionID]['AllowArbitraryServer'] $_SESSION[$this->sessionID]['BZipDump'] - $_SESSION[$this->sessionID]['BZipDump'] - $_SESSION[$this->sessionID]['GZipDump'] $_SESSION[$this->sessionID]['GZipDump'] $_SESSION[$this->sessionID]['LoginCookieStore'] - $_SESSION[$this->sessionID]['LoginCookieStore'] - $_SESSION[$this->sessionID]['LoginCookieValidity'] $_SESSION[$this->sessionID]['LoginCookieValidity'] $_SESSION[$this->sessionID]['SaveDir'] - $_SESSION[$this->sessionID]['SaveDir'] - $_SESSION[$this->sessionID]['Servers'] - $_SESSION[$this->sessionID]['Servers'] $_SESSION[$this->sessionID]['Servers'] $_SESSION[$this->sessionID]['TempDir'] - $_SESSION[$this->sessionID]['TempDir'] $_SESSION[$this->sessionID]['ZipDump'] - $_SESSION[$this->sessionID]['ZipDump'] - $_SESSION[$this->sessionID]['blowfish_secret'] $_SESSION[$this->sessionID] diff --git a/test/classes/Config/ServerConfigChecksTest.php b/test/classes/Config/ServerConfigChecksTest.php index 9e64d14e60..2d26e221b5 100644 --- a/test/classes/Config/ServerConfigChecksTest.php +++ b/test/classes/Config/ServerConfigChecksTest.php @@ -11,6 +11,10 @@ use ReflectionException; use ReflectionProperty; use function array_keys; +use function mb_strlen; +use function str_repeat; + +use const SODIUM_CRYPTO_SECRETBOX_KEYBYTES; /** * @covers \PhpMyAdmin\Config\ServerConfigChecks @@ -100,8 +104,10 @@ class ServerConfigChecksTest extends AbstractTestCase ); } - public function testBlowfishCreate(): void + public function testBlowfish(): void { + $_SESSION[$this->sessionID] = []; + $_SESSION[$this->sessionID]['blowfish_secret'] = null; $_SESSION[$this->sessionID]['Servers'] = [ '1' => [ 'host' => 'localhost', @@ -110,7 +116,6 @@ class ServerConfigChecksTest extends AbstractTestCase 'AllowRoot' => false, ], ]; - $_SESSION[$this->sessionID]['AllowArbitraryServer'] = false; $_SESSION[$this->sessionID]['LoginCookieValidity'] = -1; $_SESSION[$this->sessionID]['LoginCookieStore'] = 0; @@ -123,28 +128,73 @@ class ServerConfigChecksTest extends AbstractTestCase $configChecker = new ServerConfigChecks($GLOBALS['ConfigFile']); $configChecker->performConfigChecks(); - $this->assertEquals( - ['blowfish_secret_created'], - array_keys($_SESSION['messages']['notice']) - ); - - $this->assertArrayNotHasKey('error', $_SESSION['messages']); + /** + * @var mixed $secret + * @psalm-suppress TypeDoesNotContainType + */ + $secret = $_SESSION[$this->sessionID]['blowfish_secret'] ?? ''; + $this->assertIsString($secret); + $this->assertSame(SODIUM_CRYPTO_SECRETBOX_KEYBYTES, mb_strlen($secret, '8bit')); + $messages = $_SESSION['messages'] ?? null; + $this->assertIsArray($messages); + $this->assertArrayHasKey('notice', $messages); + $this->assertIsArray($messages['notice']); + $this->assertArrayHasKey('blowfish_secret_created', $messages['notice']); + $this->assertArrayNotHasKey('error', $messages); } - public function testBlowfish(): void + public function testBlowfishWithInvalidSecret(): void { - $_SESSION[$this->sessionID]['blowfish_secret'] = 'sec'; - + $_SESSION[$this->sessionID] = []; + $_SESSION[$this->sessionID]['blowfish_secret'] = str_repeat('a', SODIUM_CRYPTO_SECRETBOX_KEYBYTES + 1); $_SESSION[$this->sessionID]['Servers'] = [ '1' => [ 'host' => 'localhost', + 'ssl' => true, 'auth_type' => 'cookie', + 'AllowRoot' => false, ], ]; $configChecker = new ServerConfigChecks($GLOBALS['ConfigFile']); $configChecker->performConfigChecks(); - $this->assertArrayHasKey('blowfish_warnings2', $_SESSION['messages']['error']); + /** + * @var mixed $secret + * @psalm-suppress TypeDoesNotContainType + */ + $secret = $_SESSION[$this->sessionID]['blowfish_secret'] ?? ''; + $this->assertIsString($secret); + $this->assertSame(SODIUM_CRYPTO_SECRETBOX_KEYBYTES, mb_strlen($secret, '8bit')); + $messages = $_SESSION['messages'] ?? null; + $this->assertIsArray($messages); + $this->assertArrayHasKey('notice', $messages); + $this->assertIsArray($messages['notice']); + $this->assertArrayHasKey('blowfish_secret_created', $messages['notice']); + $this->assertArrayNotHasKey('error', $messages); + } + + public function testBlowfishWithValidSecret(): void + { + $_SESSION[$this->sessionID] = []; + $_SESSION[$this->sessionID]['blowfish_secret'] = str_repeat('a', SODIUM_CRYPTO_SECRETBOX_KEYBYTES); + $_SESSION[$this->sessionID]['Servers'] = ['1' => ['host' => 'localhost', 'auth_type' => 'cookie']]; + + $configChecker = new ServerConfigChecks($GLOBALS['ConfigFile']); + $configChecker->performConfigChecks(); + + /** + * @var mixed $secret + * @psalm-suppress TypeDoesNotContainType + */ + $secret = $_SESSION[$this->sessionID]['blowfish_secret'] ?? ''; + $this->assertIsString($secret); + $this->assertSame(SODIUM_CRYPTO_SECRETBOX_KEYBYTES, mb_strlen($secret, '8bit')); + $messages = $_SESSION['messages'] ?? null; + $this->assertIsArray($messages); + $this->assertArrayHasKey('notice', $messages); + $this->assertIsArray($messages['notice']); + $this->assertArrayNotHasKey('blowfish_secret_created', $messages['notice']); + $this->assertArrayNotHasKey('error', $messages); } } diff --git a/test/classes/Setup/ConfigGeneratorTest.php b/test/classes/Setup/ConfigGeneratorTest.php index 7aaaa10ec0..985feb404d 100644 --- a/test/classes/Setup/ConfigGeneratorTest.php +++ b/test/classes/Setup/ConfigGeneratorTest.php @@ -10,6 +10,13 @@ use PhpMyAdmin\Tests\AbstractTestCase; use PhpMyAdmin\Version; use ReflectionClass; +use function explode; +use function hex2bin; +use function mb_strlen; +use function str_repeat; + +use const SODIUM_CRYPTO_SECRETBOX_KEYBYTES; + /** * @covers \PhpMyAdmin\Setup\ConfigGenerator */ @@ -115,6 +122,29 @@ class ConfigGeneratorTest extends AbstractTestCase ); } + public function testGetVarExportForBlowfishSecret(): void + { + $reflection = new ReflectionClass(ConfigGenerator::class); + $method = $reflection->getMethod('getVarExport'); + $method->setAccessible(true); + + $this->assertEquals( + '$cfg[\'blowfish_secret\'] = \sodium_hex2bin(\'' + . '6161616161616161616161616161616161616161616161616161616161616161\');' . "\n", + $method->invoke(null, 'blowfish_secret', str_repeat('a', SODIUM_CRYPTO_SECRETBOX_KEYBYTES), "\n") + ); + + /** @var string $actual */ + $actual = $method->invoke(null, 'blowfish_secret', 'invalid secret', "\n"); + $this->assertStringStartsWith('$cfg[\'blowfish_secret\'] = \sodium_hex2bin(\'', $actual); + $this->assertStringEndsWith('\');' . "\n", $actual); + $pieces = explode('\'', $actual); + $this->assertCount(5, $pieces); + $binaryString = hex2bin($pieces[3]); + $this->assertIsString($binaryString); + $this->assertSame(SODIUM_CRYPTO_SECRETBOX_KEYBYTES, mb_strlen($binaryString, '8bit')); + } + /** * Test for ConfigGenerator::isZeroBasedArray */ From 700db7e72b2aba5649832e73496743cdfc257fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Thu, 15 Sep 2022 15:28:35 -0300 Subject: [PATCH 03/14] Update the docs to reflect the blowfish_secret changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurício Meneghini Fauth --- ChangeLog | 1 + config.sample.inc.php | 4 ++-- doc/config.rst | 34 ++++++++++++++++++++------- doc/glossary.rst | 5 ++++ doc/setup.rst | 4 ++-- libraries/classes/Config/Settings.php | 7 +++--- libraries/config.default.php | 7 +++--- 7 files changed, 42 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 46def253e4..d4bc5e966e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,7 @@ phpMyAdmin - ChangeLog - issue Fix PHP warning on GIS visualization when there is only one GIS column - issue #17728 Some select HTML tags will now have the correct UI style - issue #17734 PHP deprecations will only be shown when in a development environment +- issue #17369 Fix server error when blowfish_secret is not exactly 32 bytes long 5.2.0 (2022-05-10) - issue #16521 Upgrade Bootstrap to version 5 diff --git a/config.sample.inc.php b/config.sample.inc.php index 34b6a9dabf..5ba637c759 100644 --- a/config.sample.inc.php +++ b/config.sample.inc.php @@ -10,8 +10,8 @@ declare(strict_types=1); /** - * This is needed for cookie based authentication to encrypt password in - * cookie. Needs to be 32 chars long. + * This is needed for cookie based authentication to encrypt the cookie. + * Needs to be a 32-bytes long string of random bytes. */ $cfg['blowfish_secret'] = ''; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */ diff --git a/doc/config.rst b/doc/config.rst index 5594823827..95cd0aa841 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -1896,13 +1896,23 @@ Cookie authentication options :type: string :default: ``''`` - The "cookie" auth\_type uses AES algorithm to encrypt the password. If you - are using the "cookie" auth\_type, enter here a random passphrase of your - choice. It will be used internally by the AES algorithm: you won’t be - prompted for this passphrase. + The "cookie" auth\_type uses the :term:`Sodium` extension to encrypt the cookies (see :term:`Cookie`). If you are + using the "cookie" auth\_type, enter here a generated string of random bytes to be used as an encryption key. It + will be used internally by the :term:`Sodium` extension: you won't be prompted for this encryption key. - The secret should be 32 characters long. Using shorter will lead to weaker security - of encrypted cookies, using longer will cause no harm. + Since a binary string is usually not printable, it can be converted into a hexadecimal representation (using a + function like `sodium_bin2hex `_) and then used in the configuration file. For + example: + + .. code-block:: php + + // The string is a hexadecimal representation of a 32-bytes long string of random bytes. + $cfg['blowfish_secret'] = sodium_hex2bin('f16ce59f45714194371b48fe362072dc3b019da7861558cd4ad29e4d6fb13851'); + + .. warning:: + + The encryption key must be 32 bytes long. If it has a different length of bytes, a new key will be automatically + generated for you. However it will only last for the duration of the session. .. note:: @@ -1910,11 +1920,19 @@ Cookie authentication options Blowfish algorithm was originally used to do the encryption. .. versionchanged:: 3.1.0 + Since version 3.1.0 phpMyAdmin can generate this on the fly, but it makes a bit weaker security as this generated secret is stored in session and furthermore it makes impossible to recall user name from cookie. + .. versionchanged:: 5.2.0 + + Since version 5.2.0, phpMyAdmin uses the + `sodium\_crypto\_secretbox `_ and + `sodium\_crypto\_secretbox\_open `_ PHP functions to encrypt + and decrypt cookies, respectively. + .. config:option:: $cfg['CookieSameSite'] :type: string @@ -3809,8 +3827,8 @@ following example shows two of them: .. code-block:: php + Sodium + The Sodium PHP extension. + + .. seealso:: `PHP manual for Sodium extension `_ + Storage Engines MySQL can use several different formats for storing data on disk, these are called storage engines or table types. phpMyAdmin allows a user to diff --git a/doc/setup.rst b/doc/setup.rst index c2b7b78928..1f2563edfc 100644 --- a/doc/setup.rst +++ b/doc/setup.rst @@ -587,8 +587,8 @@ simple configuration may look like this: .. code-block:: xml+php Date: Thu, 15 Sep 2022 18:41:32 -0300 Subject: [PATCH 04/14] Document how to generate a string of random bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurício Meneghini Fauth --- config.sample.inc.php | 2 +- doc/config.rst | 4 ++++ doc/faq.rst | 31 +++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/config.sample.inc.php b/config.sample.inc.php index 5ba637c759..2fca0b5bc4 100644 --- a/config.sample.inc.php +++ b/config.sample.inc.php @@ -11,7 +11,7 @@ declare(strict_types=1); /** * This is needed for cookie based authentication to encrypt the cookie. - * Needs to be a 32-bytes long string of random bytes. + * Needs to be a 32-bytes long string of random bytes. See FAQ 2.10. */ $cfg['blowfish_secret'] = ''; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */ diff --git a/doc/config.rst b/doc/config.rst index 95cd0aa841..11f5b1d893 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -1888,6 +1888,8 @@ Generic settings A secret key used to encrypt/decrypt the URL query string. Should be 32 bytes long. + .. seealso:: :ref:`faq2_10` + Cookie authentication options ----------------------------- @@ -1933,6 +1935,8 @@ Cookie authentication options `sodium\_crypto\_secretbox\_open `_ PHP functions to encrypt and decrypt cookies, respectively. + .. seealso:: :ref:`faq2_10` + .. config:option:: $cfg['CookieSameSite'] :type: string diff --git a/doc/faq.rst b/doc/faq.rst index 866a920dab..ff1e928f0d 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -867,6 +867,37 @@ If using PHP 5.4.0 or higher, you must set starting from phpMyAdmin version 4.0.4, session-based upload progress has been temporarily deactivated due to its problematic behavior. +.. _faq2_10: + +2.10 How to generate a string of random bytes +--------------------------------------------- + +One way to generate a string of random bytes suitable for cryptographic use is using the +`random_bytes `_ :term:`PHP` function. Since this function returns a binary string, +the returned value should be converted to printable format before being able to copy it. + +For example, the :config:option:`$cfg['blowfish_secret']` configuration directive requires a 32-bytes long string. The +following command can be used to generate a hexadecimal representation of this string. + +.. code-block:: sh + + php -r 'echo bin2hex(random_bytes(32)) . PHP_EOL;' + +The above example will output something similar to: + +.. code-block:: sh + + f16ce59f45714194371b48fe362072dc3b019da7861558cd4ad29e4d6fb13851 + +And then this hexadecimal value can be used in the configuration file. + +.. code-block:: php + + $cfg['blowfish_secret'] = sodium_hex2bin('f16ce59f45714194371b48fe362072dc3b019da7861558cd4ad29e4d6fb13851'); + +The `sodium_hex2bin `_ is used here to convert the hexadecimal value back to the +binary format. + .. _faqlimitations: Known limitations From 5d9142674d09379a9e4394779c1e624dd2d6ece5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Fri, 23 Sep 2022 14:32:30 -0300 Subject: [PATCH 05/14] Allow longer cookie encryption keys to be used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurício Meneghini Fauth --- doc/config.rst | 5 +++-- libraries/classes/Controllers/HomeController.php | 14 +++++++++----- .../classes/Plugins/Auth/AuthenticationCookie.php | 13 ++++++++++++- psalm-baseline.xml | 4 +--- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/doc/config.rst b/doc/config.rst index 11f5b1d893..27d9500311 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -1913,8 +1913,9 @@ Cookie authentication options .. warning:: - The encryption key must be 32 bytes long. If it has a different length of bytes, a new key will be automatically - generated for you. However it will only last for the duration of the session. + The encryption key must be 32 bytes long. If it is longer than the length of bytes, only the first 32 bytes will + be used, and if it is shorter, a new temporary key will be automatically generated for you. However, this + temporary key will only last for the duration of the session. .. note:: diff --git a/libraries/classes/Controllers/HomeController.php b/libraries/classes/Controllers/HomeController.php index 998cc3b4ce..39235fdc06 100644 --- a/libraries/classes/Controllers/HomeController.php +++ b/libraries/classes/Controllers/HomeController.php @@ -311,19 +311,23 @@ class HomeController extends AbstractController * Check if user does not have defined blowfish secret and it is being used. */ if (! empty($_SESSION['encryption_key'])) { - if (empty($cfg['blowfish_secret'])) { + $encryptionKeyLength = mb_strlen($cfg['blowfish_secret'], '8bit'); + if ($encryptionKeyLength < SODIUM_CRYPTO_SECRETBOX_KEYBYTES) { $this->errors[] = [ 'message' => __( - 'The configuration file now needs a secret passphrase (blowfish_secret).' + 'The configuration file needs a valid key for cookie encryption.' + . ' A temporary key was automatically generated for you.' + . ' Please refer to the [doc@cfg_blowfish_secret]documentation[/doc].' ), 'severity' => 'warning', ]; - } elseif (mb_strlen($cfg['blowfish_secret'], '8bit') !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) { + } elseif ($encryptionKeyLength > SODIUM_CRYPTO_SECRETBOX_KEYBYTES) { $this->errors[] = [ 'message' => sprintf( __( - 'The secret passphrase in configuration (blowfish_secret) is not the correct length.' - . ' It should be %d bytes long.' + 'The cookie encryption key in the configuration file is longer than necessary.' + . ' It should only be %d bytes long.' + . ' Please refer to the [doc@cfg_blowfish_secret]documentation[/doc].' ), SODIUM_CRYPTO_SECRETBOX_KEYBYTES ), diff --git a/libraries/classes/Plugins/Auth/AuthenticationCookie.php b/libraries/classes/Plugins/Auth/AuthenticationCookie.php index 33faf56b34..e083ddf19a 100644 --- a/libraries/classes/Plugins/Auth/AuthenticationCookie.php +++ b/libraries/classes/Plugins/Auth/AuthenticationCookie.php @@ -597,11 +597,21 @@ class AuthenticationCookie extends AuthenticationPlugin */ private function getEncryptionSecret(): string { + /** @var mixed $key */ $key = $GLOBALS['cfg']['blowfish_secret'] ?? null; - if (is_string($key) && mb_strlen($key, '8bit') === SODIUM_CRYPTO_SECRETBOX_KEYBYTES) { + if (! is_string($key)) { + return $this->getSessionEncryptionSecret(); + } + + $length = mb_strlen($key, '8bit'); + if ($length === SODIUM_CRYPTO_SECRETBOX_KEYBYTES) { return $key; } + if ($length > SODIUM_CRYPTO_SECRETBOX_KEYBYTES) { + return mb_substr($key, 0, SODIUM_CRYPTO_SECRETBOX_KEYBYTES, '8bit'); + } + return $this->getSessionEncryptionSecret(); } @@ -610,6 +620,7 @@ class AuthenticationCookie extends AuthenticationPlugin */ private function getSessionEncryptionSecret(): string { + /** @var mixed $key */ $key = $_SESSION['encryption_key'] ?? null; if (is_string($key) && mb_strlen($key, '8bit') === SODIUM_CRYPTO_SECRETBOX_KEYBYTES) { return $key; diff --git a/psalm-baseline.xml b/psalm-baseline.xml index be2ba27d96..874757e842 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -9042,14 +9042,12 @@ $_SESSION['browser_access_time'][$key] - + $GLOBALS['pma_auth_server'] $_form_params['route'] $captchaSiteVerifyURL $captchaSiteVerifyURL $key - $key - $key $password $serverCookie $serverCookie From 243b9da2fb0797f7ca26288800c203783bb34713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Mon, 26 Sep 2022 17:55:36 -0300 Subject: [PATCH 06/14] Add a note that sodium_bin2hex is not required for blowfish_secret MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurício Meneghini Fauth --- doc/config.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/config.rst b/doc/config.rst index 27d9500311..20366d140d 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -1911,6 +1911,15 @@ Cookie authentication options // The string is a hexadecimal representation of a 32-bytes long string of random bytes. $cfg['blowfish_secret'] = sodium_hex2bin('f16ce59f45714194371b48fe362072dc3b019da7861558cd4ad29e4d6fb13851'); + Using a binary string is recommended. However, if all 32 bytes of the string are visible + characters, then a function like `sodium_bin2hex `_ is not required. For + example: + + .. code-block:: php + + // A string of 32 characters. + $cfg['blowfish_secret'] = 'JOFw435365IScA&Q!cDugr!lSfuAz*OW'; + .. warning:: The encryption key must be 32 bytes long. If it is longer than the length of bytes, only the first 32 bytes will From 35a959af25531df044b9a0203ceeda423ae1d598 Mon Sep 17 00:00:00 2001 From: Giovanni Vella Date: Tue, 27 Sep 2022 08:45:35 +0000 Subject: [PATCH 07/14] Translated using Weblate (Italian) Currently translated at 99.8% (3413 of 3418 strings) [ci skip] Translation: phpMyAdmin/5.2 Translate-URL: https://hosted.weblate.org/projects/phpmyadmin/5-2/it/ Signed-off-by: Giovanni Vella --- po/it.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/po/it.po b/po/it.po index bd34d86a21..80642edc32 100644 --- a/po/it.po +++ b/po/it.po @@ -4,8 +4,8 @@ msgstr "" "Project-Id-Version: phpMyAdmin 5.2.0-dev\n" "Report-Msgid-Bugs-To: translators@phpmyadmin.net\n" "POT-Creation-Date: 2022-04-21 15:54-0300\n" -"PO-Revision-Date: 2022-03-21 17:56+0000\n" -"Last-Translator: Lorenzo Asolan \n" +"PO-Revision-Date: 2022-09-28 09:18+0000\n" +"Last-Translator: Giovanni Vella \n" "Language-Team: Italian \n" "Language: it\n" @@ -13,7 +13,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.12-dev\n" +"X-Generator: Weblate 4.14.1\n" #: libraries/advisory_rules_generic.php:9 msgid "Uptime below one day" @@ -16226,7 +16226,7 @@ msgstr "Agosto" #: templates/javascript/variables.twig:28 msgid "September" -msgstr "Setttembre" +msgstr "Settembre" #: templates/javascript/variables.twig:29 msgid "October" From a267ba3dde2488a59d75f433509c1cdfb0fe4f10 Mon Sep 17 00:00:00 2001 From: William Desportes Date: Wed, 7 Sep 2022 18:55:04 +0200 Subject: [PATCH 08/14] Add comments to the release script Signed-off-by: William Desportes --- scripts/create-release.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/create-release.sh b/scripts/create-release.sh index 42fb559a0d..ab640b06ad 100755 --- a/scripts/create-release.sh +++ b/scripts/create-release.sh @@ -468,15 +468,18 @@ do PACKAGES_VERSIONS="$PACKAGES_VERSIONS $PACKAGES:$PKG_VERSION" done -echo "Installing composer packages '$PACKAGES_VERSIONS'" +echo "* Installing composer packages '$PACKAGES_VERSIONS'" composer require --no-interaction --optimize-autoloader --update-no-dev $PACKAGES_VERSIONS +echo "* Running a security checkup" security_checkup +echo "* Cleaning up vendor folders" mv composer.json.backup composer.json cleanup_composer_vendors +echo "* Running a security checkup" security_checkup if [ $do_tag -eq 1 ] ; then echo "* Commiting composer.lock" From eac7356f4c81cc2e6c83c233b4574cfa04553736 Mon Sep 17 00:00:00 2001 From: William Desportes Date: Wed, 7 Sep 2022 19:00:05 +0200 Subject: [PATCH 09/14] Remove rm "-f" argument as it hides errors on the release script Signed-off-by: William Desportes --- scripts/create-release.sh | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/scripts/create-release.sh b/scripts/create-release.sh index ab640b06ad..f6de36b088 100755 --- a/scripts/create-release.sh +++ b/scripts/create-release.sh @@ -262,7 +262,7 @@ restore_vendor_folder() { echo 'No backup to restore' exit 1; fi - rm -rf ./vendor + rm -r ./vendor mv "${TEMP_FOLDER}/vendor" ./vendor rmdir "${TEMP_FOLDER}" } @@ -284,7 +284,7 @@ delete_phpunit_sandbox() { echo 'No phpunit sandbox to delete' exit 1; fi - rm -rf "${TEMP_PHPUNIT_FOLDER}" + rm -r "${TEMP_PHPUNIT_FOLDER}" } security_checkup() { @@ -425,16 +425,16 @@ fi echo "* Removing unneeded files" # Remove developer information -rm -rf .github CODE_OF_CONDUCT.md DCO +rm -r .github CODE_OF_CONDUCT.md DCO # Testsuite setup -rm -f .scrutinizer.yml .weblate codecov.yml +rm .scrutinizer.yml .weblate codecov.yml # Remove Doctum config file -rm -f test/doctum-config.php +rm test/doctum-config.php # Remove readme for github -rm -f README.rst +rm README.rst if [ -f ./scripts/console ]; then # Update the vendors to have the dev vendors @@ -494,8 +494,8 @@ fi # Remove git metadata rm .git -find . -name .gitignore -print0 | xargs -0 -r rm -f -find . -name .gitattributes -print0 | xargs -0 -r rm -f +find . -name .gitignore -print0 | xargs -0 -r rm +find . -name .gitattributes -print0 | xargs -0 -r rm if [ $do_test -eq 1 ] ; then # Move the folder out and install dev vendors @@ -508,7 +508,7 @@ if [ $do_test -eq 1 ] ; then test_ret=$? if [ $do_ci -eq 1 ] ; then cd ../.. - rm -rf $workdir + rm -r $workdir git worktree prune if [ "$branch" = "ci" ] ; then git branch -D ci @@ -523,7 +523,7 @@ if [ $do_test -eq 1 ] ; then # Generate an normal autoload (this is just a security, because normally the vendor folder will be restored) composer dump-autoload # Remove libs installed for testing - rm -rf build + rm -r build delete_phpunit_sandbox restore_vendor_folder fi @@ -546,27 +546,27 @@ for kit in $KITS ; do if [ $kit != source ] ; then echo "* Removing source files" # Testsuite - rm -rf test/ + rm -r test/ # Template test files rm -r templates/test/ rm phpunit.xml.* build.xml - rm -f .editorconfig .browserslistrc .eslintignore .jshintrc .eslintrc.json .stylelintrc.json psalm.xml psalm-baseline.xml phpstan.neon.dist phpstan-baseline.neon phpcs.xml.dist jest.config.js infection.json.dist + rm .editorconfig .browserslistrc .eslintignore .jshintrc .eslintrc.json .stylelintrc.json psalm.xml psalm-baseline.xml phpstan.neon.dist phpstan-baseline.neon phpcs.xml.dist jest.config.js infection.json.dist # Gettext po files - rm -rf po/ + rm -r po # Documentation source code mv doc/html htmldoc - rm -rf doc + rm -r doc mkdir doc mv htmldoc doc/html rm doc/html/.buildinfo doc/html/objects.inv - rm -rf node_modules + rm -r node_modules # Remove bin files for non source version # https://github.com/phpmyadmin/phpmyadmin/issues/16033 - rm -rf vendor/bin + rm -r vendor/bin fi # Remove developer scripts - rm -rf scripts + rm -r scripts # Remove possible tmp folder rm -rf tmp @@ -607,11 +607,11 @@ for kit in $KITS ; do # Cleanup rm -f $name.tar # Remove directory with current dist set - rm -rf $name + rm -r $name done # Cleanup -rm -rf phpMyAdmin-${version} +rm -r phpMyAdmin-${version} git worktree prune # Signing of files with default GPG key @@ -660,7 +660,7 @@ if [ $do_tag -eq 1 ] ; then git rm --force composer.lock git commit -s -m "Removing composer.lock" cd ../.. - rm -rf $workdir + rm -r $workdir git worktree prune fi From 9477d1d748e53e532f5bb295ab5b0331a5379c28 Mon Sep 17 00:00:00 2001 From: William Desportes Date: Wed, 7 Sep 2022 19:17:49 +0200 Subject: [PATCH 10/14] Fixup removing 'po' folder in the english kit Signed-off-by: William Desportes --- scripts/create-release.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/create-release.sh b/scripts/create-release.sh index f6de36b088..f9eff01de5 100755 --- a/scripts/create-release.sh +++ b/scripts/create-release.sh @@ -551,8 +551,8 @@ for kit in $KITS ; do rm -r templates/test/ rm phpunit.xml.* build.xml rm .editorconfig .browserslistrc .eslintignore .jshintrc .eslintrc.json .stylelintrc.json psalm.xml psalm-baseline.xml phpstan.neon.dist phpstan-baseline.neon phpcs.xml.dist jest.config.js infection.json.dist - # Gettext po files - rm -r po + # Gettext po files (if they where not removed by ./scripts/lang-cleanup.sh) + rm -rf po # Documentation source code mv doc/html htmldoc rm -r doc From 4e08ffdc77504fce66a70e54651ca3448ff098dc Mon Sep 17 00:00:00 2001 From: William Desportes Date: Wed, 7 Sep 2022 19:18:57 +0200 Subject: [PATCH 11/14] Add a comment when building a kit starts on the release script Signed-off-by: William Desportes --- scripts/create-release.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/create-release.sh b/scripts/create-release.sh index f9eff01de5..14222674db 100755 --- a/scripts/create-release.sh +++ b/scripts/create-release.sh @@ -534,6 +534,7 @@ cd .. # Prepare all kits for kit in $KITS ; do + echo "* Building kit: $kit" # Copy all files name=phpMyAdmin-$version-$kit cp -r phpMyAdmin-$version $name From 8331b15243096bc1f286a8c20771482fbd20ec4d Mon Sep 17 00:00:00 2001 From: William Desportes Date: Wed, 28 Sep 2022 23:47:45 +0200 Subject: [PATCH 12/14] Fix #17736 - Add utf8mb3 as an alias of utf8 on the charset description page Signed-off-by: William Desportes --- libraries/classes/Charsets/Collation.php | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/classes/Charsets/Collation.php b/libraries/classes/Charsets/Collation.php index 5215fe561f..74215bd0a9 100644 --- a/libraries/classes/Charsets/Collation.php +++ b/libraries/classes/Charsets/Collation.php @@ -344,6 +344,7 @@ final class Collation // Fall through to other unicode case 'ucs2': case 'utf8': + case 'utf8mb3': case 'utf16': case 'utf16le': case 'utf16be': From a4d273f5cfad5083ceaee14cdc2ddf8c923fe5de Mon Sep 17 00:00:00 2001 From: William Desportes Date: Wed, 28 Sep 2022 23:50:11 +0200 Subject: [PATCH 13/14] Add a ChangeLog entry for #17736 Signed-off-by: William Desportes --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index d4bc5e966e..7f7166168f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -35,6 +35,7 @@ phpMyAdmin - ChangeLog - issue #17728 Some select HTML tags will now have the correct UI style - issue #17734 PHP deprecations will only be shown when in a development environment - issue #17369 Fix server error when blowfish_secret is not exactly 32 bytes long +- issue #17736 Add utf8mb3 as an alias of utf8 on the charset description page 5.2.0 (2022-05-10) - issue #16521 Upgrade Bootstrap to version 5 From add68b47e314fb74c6e6c11bafbbed6ed8c74344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Thu, 29 Sep 2022 00:17:47 -0300 Subject: [PATCH 14/14] Update po files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ci skip] Signed-off-by: Maurício Meneghini Fauth --- po/af.po | 414 +++++++++++++++++----------------- po/am.po | 414 +++++++++++++++++----------------- po/ar.po | 445 +++++++++++++++++++----------------- po/ar_LY.po | 414 +++++++++++++++++----------------- po/az.po | 455 +++++++++++++++++++------------------ po/be.po | 420 +++++++++++++++++----------------- po/be@latin.po | 421 +++++++++++++++++----------------- po/ber.po | 414 +++++++++++++++++----------------- po/bg.po | 446 +++++++++++++++++++----------------- po/bn.po | 434 ++++++++++++++++++----------------- po/br.po | 414 +++++++++++++++++----------------- po/brx.po | 414 +++++++++++++++++----------------- po/bs.po | 424 +++++++++++++++++----------------- po/ca.po | 448 +++++++++++++++++++----------------- po/ckb.po | 420 +++++++++++++++++----------------- po/cs.po | 453 +++++++++++++++++++------------------ po/cy.po | 414 +++++++++++++++++----------------- po/da.po | 444 +++++++++++++++++++----------------- po/de.po | 451 +++++++++++++++++++----------------- po/el.po | 452 +++++++++++++++++++------------------ po/en_GB.po | 460 +++++++++++++++++++------------------ po/enm.po | 414 +++++++++++++++++----------------- po/eo.po | 414 +++++++++++++++++----------------- po/es.po | 440 +++++++++++++++++++----------------- po/et.po | 436 ++++++++++++++++++----------------- po/eu.po | 422 +++++++++++++++++----------------- po/fa.po | 414 +++++++++++++++++----------------- po/fi.po | 444 +++++++++++++++++++----------------- po/fil.po | 442 +++++++++++++++++++----------------- po/fr.po | 440 +++++++++++++++++++----------------- po/fy.po | 414 +++++++++++++++++----------------- po/gl.po | 434 ++++++++++++++++++----------------- po/gu.po | 414 +++++++++++++++++----------------- po/he.po | 436 ++++++++++++++++++----------------- po/hi.po | 443 +++++++++++++++++++----------------- po/hr.po | 437 ++++++++++++++++++----------------- po/hu.po | 450 +++++++++++++++++++----------------- po/hy.po | 435 ++++++++++++++++++----------------- po/ia.po | 450 +++++++++++++++++++----------------- po/id.po | 459 +++++++++++++++++++------------------ po/ig.po | 414 +++++++++++++++++----------------- po/it.po | 440 +++++++++++++++++++----------------- po/ja.po | 438 ++++++++++++++++++----------------- po/ka.po | 428 ++++++++++++++++++----------------- po/kab.po | 416 +++++++++++++++++----------------- po/kk.po | 442 +++++++++++++++++++----------------- po/km.po | 414 +++++++++++++++++----------------- po/kn.po | 414 +++++++++++++++++----------------- po/ko.po | 472 ++++++++++++++++++++------------------ po/ksh.po | 414 +++++++++++++++++----------------- po/ku.po | 414 +++++++++++++++++----------------- po/ky.po | 414 +++++++++++++++++----------------- po/li.po | 414 +++++++++++++++++----------------- po/lt.po | 438 ++++++++++++++++++----------------- po/lv.po | 424 +++++++++++++++++----------------- po/mk.po | 428 ++++++++++++++++++----------------- po/ml.po | 414 +++++++++++++++++----------------- po/mn.po | 424 +++++++++++++++++----------------- po/ms.po | 414 +++++++++++++++++----------------- po/my.po | 414 +++++++++++++++++----------------- po/nb.po | 448 +++++++++++++++++++----------------- po/ne.po | 414 +++++++++++++++++----------------- po/nl.po | 444 +++++++++++++++++++----------------- po/nn.po | 414 +++++++++++++++++----------------- po/pa.po | 414 +++++++++++++++++----------------- po/phpmyadmin.pot | 421 +++++++++++++++++----------------- po/pl.po | 564 ++++++++++++++++++++++++---------------------- po/pt.po | 447 +++++++++++++++++++----------------- po/pt_BR.po | 447 +++++++++++++++++++----------------- po/rcf.po | 418 +++++++++++++++++----------------- po/ro.po | 441 +++++++++++++++++++----------------- po/ru.po | 452 ++++++++++++++++++++----------------- po/si.po | 434 ++++++++++++++++++----------------- po/sk.po | 446 +++++++++++++++++++----------------- po/sl.po | 442 +++++++++++++++++++----------------- po/sq.po | 451 +++++++++++++++++++----------------- po/sr.po | 424 +++++++++++++++++----------------- po/sr@latin.po | 424 +++++++++++++++++----------------- po/sv.po | 445 +++++++++++++++++++----------------- po/ta.po | 436 ++++++++++++++++++----------------- po/te.po | 414 +++++++++++++++++----------------- po/th.po | 436 ++++++++++++++++++----------------- po/tk.po | 414 +++++++++++++++++----------------- po/tr.po | 438 ++++++++++++++++++----------------- po/tt.po | 414 +++++++++++++++++----------------- po/tzm.po | 414 +++++++++++++++++----------------- po/ug.po | 414 +++++++++++++++++----------------- po/uk.po | 489 +++++++++++++++++++++------------------- po/ur.po | 424 +++++++++++++++++----------------- po/uz.po | 437 ++++++++++++++++++----------------- po/uz@latin.po | 438 ++++++++++++++++++----------------- po/vi.po | 446 +++++++++++++++++++----------------- po/vls.po | 414 +++++++++++++++++----------------- po/zh_CN.po | 442 +++++++++++++++++++----------------- po/zh_TW.po | 434 ++++++++++++++++++----------------- 95 files changed, 21324 insertions(+), 19769 deletions(-) diff --git a/po/af.po b/po/af.po index f2d0292e5d..a435ec5b39 100644 --- a/po/af.po +++ b/po/af.po @@ -1,9 +1,9 @@ # msgid "" msgstr "" -"Project-Id-Version: phpMyAdmin 5.2.0-dev\n" +"Project-Id-Version: phpMyAdmin 5.2.1-dev\n" "Report-Msgid-Bugs-To: translators@phpmyadmin.net\n" -"POT-Creation-Date: 2022-04-21 15:54-0300\n" +"POT-Creation-Date: 2022-09-29 00:17-0300\n" "PO-Revision-Date: 2022-02-17 10:34+0000\n" "Last-Translator: Maurício Meneghini Fauth \n" "Language-Team: Afrikaans must be the name of and only of a primary key!" msgstr "" "\"PRIMARY\" moet die naam wees van die primere sleutel, en slegs van die primere sleutel!" -#: templates/table/index_form.twig:34 +#: templates/table/index_form.twig:37 #, fuzzy #| msgid "Index name:" msgid "Index choice:" msgstr "Indeks naam :" -#: templates/table/index_form.twig:54 +#: templates/table/index_form.twig:57 #, fuzzy msgid "Advanced options" msgstr "Aksie" -#: templates/table/index_form.twig:64 +#: templates/table/index_form.twig:67 msgid "Key block size:" msgstr "" -#: templates/table/index_form.twig:81 +#: templates/table/index_form.twig:84 msgid "Index type:" msgstr "Indeks tipe :" -#: templates/table/index_form.twig:98 +#: templates/table/index_form.twig:101 #, fuzzy #| msgid "User" msgid "Parser:" msgstr "Gebruiker" -#: templates/table/index_form.twig:114 +#: templates/table/index_form.twig:117 #, fuzzy msgid "Comment:" msgstr "Kommentaar" -#: templates/table/index_form.twig:159 templates/table/index_form.twig:196 +#: templates/table/index_form.twig:162 templates/table/index_form.twig:199 msgid "Drag to reorder" msgstr "" diff --git a/po/am.po b/po/am.po index 27a3d70285..c40a5c7964 100644 --- a/po/am.po +++ b/po/am.po @@ -5,9 +5,9 @@ # msgid "" msgstr "" -"Project-Id-Version: phpMyAdmin 5.2.0-dev\n" +"Project-Id-Version: phpMyAdmin 5.2.1-dev\n" "Report-Msgid-Bugs-To: translators@phpmyadmin.net\n" -"POT-Creation-Date: 2022-04-21 15:54-0300\n" +"POT-Creation-Date: 2022-09-29 00:17-0300\n" "PO-Revision-Date: 2022-02-17 10:35+0000\n" "Last-Translator: Maurício Meneghini Fauth \n" "Language-Team: Amharic be the name of and only of a primary key!" msgstr "" -#: templates/table/index_form.twig:34 +#: templates/table/index_form.twig:37 msgid "Index choice:" msgstr "" -#: templates/table/index_form.twig:54 +#: templates/table/index_form.twig:57 msgid "Advanced options" msgstr "" -#: templates/table/index_form.twig:64 +#: templates/table/index_form.twig:67 msgid "Key block size:" msgstr "" -#: templates/table/index_form.twig:81 +#: templates/table/index_form.twig:84 msgid "Index type:" msgstr "" -#: templates/table/index_form.twig:98 +#: templates/table/index_form.twig:101 msgid "Parser:" msgstr "" -#: templates/table/index_form.twig:114 +#: templates/table/index_form.twig:117 msgid "Comment:" msgstr "" -#: templates/table/index_form.twig:159 templates/table/index_form.twig:196 +#: templates/table/index_form.twig:162 templates/table/index_form.twig:199 msgid "Drag to reorder" msgstr "" diff --git a/po/ar.po b/po/ar.po index da70779942..2799601a62 100644 --- a/po/ar.po +++ b/po/ar.po @@ -1,9 +1,9 @@ # msgid "" msgstr "" -"Project-Id-Version: phpMyAdmin 5.2.0-dev\n" +"Project-Id-Version: phpMyAdmin 5.2.1-dev\n" "Report-Msgid-Bugs-To: translators@phpmyadmin.net\n" -"POT-Creation-Date: 2022-04-21 15:54-0300\n" +"POT-Creation-Date: 2022-09-29 00:17-0300\n" "PO-Revision-Date: 2022-05-21 00:27+0000\n" "Last-Translator: Maurício Meneghini Fauth \n" "Language-Team: Arabic