From 34f1d6f0a1642daf1949bb9fb23f44fe58604bd2 Mon Sep 17 00:00:00 2001 From: Guy Sartorelli Date: Thu, 18 May 2023 14:26:23 +1200 Subject: [PATCH] FIX Add back missing SSL support for database connections --- src/Core/CoreKernel.php | 22 +++++++++++++++++++ .../MySQLDatabaseConfigurationHelper.php | 12 +++++----- src/ORM/Connect/MySQLiConnector.php | 15 +++++++------ 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/Core/CoreKernel.php b/src/Core/CoreKernel.php index c16d75999cd..b46a85ce3aa 100644 --- a/src/Core/CoreKernel.php +++ b/src/Core/CoreKernel.php @@ -6,6 +6,7 @@ use SilverStripe\Dev\Install\DatabaseAdapterRegistry; use SilverStripe\ORM\DB; use Exception; +use LogicException; /** * Simple Kernel container @@ -116,6 +117,27 @@ protected function getDatabaseConfig() "password" => Environment::getEnv('SS_DATABASE_PASSWORD') ?: null, ]; + // Only add SSL keys in the array if there is an actual value associated with them + $sslConf = [ + 'ssl_key' => 'SS_DATABASE_SSL_KEY', + 'ssl_cert' => 'SS_DATABASE_SSL_CERT', + 'ssl_ca' => 'SS_DATABASE_SSL_CA', + 'ssl_cipher' => 'SS_DATABASE_SSL_CIPHER', + ]; + foreach ($sslConf as $key => $envVar) { + $envValue = Environment::getEnv($envVar); + if ($envValue) { + $databaseConfig[$key] = $envValue; + } + } + + // Having only the key or cert without the other is bad configuration. + if (isset($databaseConfig['ssl_key']) xor isset($databaseConfig['ssl_cert'])) { + user_error('Database SSL cert and key must both be defined to use SSL in the database.', E_USER_WARNING); + unset($databaseConfig['ssl_key']); + unset($databaseConfig['ssl_cert']); + } + // Set the port if called for $dbPort = Environment::getEnv('SS_DATABASE_PORT'); if ($dbPort) { diff --git a/src/Dev/Install/MySQLDatabaseConfigurationHelper.php b/src/Dev/Install/MySQLDatabaseConfigurationHelper.php index 22552a9b5bc..62cfaec1b5d 100644 --- a/src/Dev/Install/MySQLDatabaseConfigurationHelper.php +++ b/src/Dev/Install/MySQLDatabaseConfigurationHelper.php @@ -35,14 +35,14 @@ protected function createConnection($databaseConfig, &$error) case 'MySQLDatabase': $conn = mysqli_init(); - // Set SSL parameters if they exist. All parameters are required. - if (array_key_exists('ssl_key', $databaseConfig) && - array_key_exists('ssl_cert', $databaseConfig) && - array_key_exists('ssl_ca', $databaseConfig) + // Set SSL parameters if they exist. + // Must have both the SSL cert and key, or the common authority, or preferably all three. + if ((array_key_exists('ssl_key', $databaseConfig) && array_key_exists('ssl_cert', $databaseConfig)) + || array_key_exists('ssl_ca', $databaseConfig) ) { $conn->ssl_set( - $databaseConfig['ssl_key'], - $databaseConfig['ssl_cert'], + $databaseConfig['ssl_key'] ?? null, + $databaseConfig['ssl_cert'] ?? null, $databaseConfig['ssl_ca'], dirname($databaseConfig['ssl_ca']), array_key_exists('ssl_cipher', $databaseConfig) diff --git a/src/ORM/Connect/MySQLiConnector.php b/src/ORM/Connect/MySQLiConnector.php index b4ab7b697fe..20a45d97cce 100644 --- a/src/ORM/Connect/MySQLiConnector.php +++ b/src/ORM/Connect/MySQLiConnector.php @@ -96,14 +96,15 @@ public function connect($parameters, $selectDB = false) ); } - // Set SSL parameters if they exist. All parameters are required. - if (array_key_exists('ssl_key', $parameters ?? []) && - array_key_exists('ssl_cert', $parameters ?? []) && - array_key_exists('ssl_ca', $parameters ?? [])) { + // Set SSL parameters if they exist. + // Must have both the SSL cert and key, or the common authority, or preferably all three. + if ((array_key_exists('ssl_key', $parameters ?? []) && array_key_exists('ssl_cert', $parameters ?? [])) + || array_key_exists('ssl_ca', $parameters ?? []) + ) { $this->dbConn->ssl_set( - $parameters['ssl_key'], - $parameters['ssl_cert'], - $parameters['ssl_ca'], + $parameters['ssl_key'] ?? null, + $parameters['ssl_cert'] ?? null, + $parameters['ssl_ca'] ?? null, dirname($parameters['ssl_ca'] ?? ''), array_key_exists('ssl_cipher', $parameters ?? []) ? $parameters['ssl_cipher']