From a3678c73b9061583633a477c34cb9202bf906e28 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 3 Aug 2017 12:53:27 +0800 Subject: [PATCH] Refactor code to decouple SSL feature from MySQL PDO --- conf/ConfigureFromEnv.php | 35 +++++++++++-------- .../MySQLDatabaseConfigurationHelper.php | 14 +++++--- dev/install/install.php5 | 14 +++++--- model/connect/PDOConnector.php | 23 ++++++++---- 4 files changed, 56 insertions(+), 30 deletions(-) diff --git a/conf/ConfigureFromEnv.php b/conf/ConfigureFromEnv.php index 3575f4636..cf86b1a5a 100644 --- a/conf/ConfigureFromEnv.php +++ b/conf/ConfigureFromEnv.php @@ -25,7 +25,7 @@ * - SS_DATABASE_SSL_KEY: Path to SSL private key file * - SS_DATABASE_SSL_CERT: Path to SSL certificate file * - SS_DATABASE_SSL_CA: Path to SSL CA file - * - SS_DATABASE_SSL_CIPHER: Alternative cipher (defaults to DHE-RSA-AES256-SHA) + * - SS_DATABASE_SSL_CIPHER: Override default cipher (defaults are set per database connector) * * * There is one more setting that is intended to be used by people who work on SilverStripe. @@ -125,24 +125,29 @@ if(defined('SS_DATABASE_USERNAME') && defined('SS_DATABASE_PASSWORD')) { if(defined('SS_DATABASE_MEMORY')) $databaseConfig["memory"] = SS_DATABASE_MEMORY; - // PDO MySQL SSL parameters - if(defined('SS_DATABASE_CLASS') && SS_DATABASE_CLASS === 'MySQLPDODatabase') { + // Add ssl parameters to databaseConfig if these are defined + if( + defined('SS_DATABASE_SSL_KEY') && + defined('SS_DATABASE_SSL_CERT') + ) { - // add ssl parameters if these are defined - if( - defined('SS_DATABASE_SSL_KEY') && - defined('SS_DATABASE_SSL_CERT') && - defined('SS_DATABASE_SSL_CA') - ) { + $databaseConfig['ssl_key'] = SS_DATABASE_SSL_KEY; + $databaseConfig['ssl_cert'] = SS_DATABASE_SSL_CERT; - $databaseConfig['ssl_key'] = SS_DATABASE_SSL_KEY; - $databaseConfig['ssl_cert'] = SS_DATABASE_SSL_CERT; - $databaseConfig['ssl_ca'] = SS_DATABASE_SSL_CA; - $databaseConfig['ssl_cipher'] = defined('SS_DATABASE_SSL_CIPHER') ? SS_DATABASE_SSL_CIPHER : 'DHE-RSA-AES256-SHA'; - - } } + // Some databases do not require a CA so this is optional + if(defined('SS_DATABASE_SSL_CA')) { + $databaseConfig['ssl_ca'] = SS_DATABASE_SSL_CA; + } + + // Cipher defaults should be set per connector + if(defined('SS_DATABASE_SSL_CIPHER')) { + $databaseConfig['ssl_cipher'] = SS_DATABASE_SSL_CIPHER; + } + + + } if(defined('SS_SEND_ALL_EMAILS_TO')) { diff --git a/dev/install/MySQLDatabaseConfigurationHelper.php b/dev/install/MySQLDatabaseConfigurationHelper.php index 86f7ff6e5..8815fcc03 100644 --- a/dev/install/MySQLDatabaseConfigurationHelper.php +++ b/dev/install/MySQLDatabaseConfigurationHelper.php @@ -37,21 +37,25 @@ class MySQLDatabaseConfigurationHelper implements DatabaseConfigurationHelper { case 'MySQLPDODatabase': // May throw a PDOException if fails + // Set SSL parameters $ssl = null; + $defaultCipher = 'DHE-RSA-AES256-SHA'; if( array_key_exists('ssl_key', $databaseConfig) && - array_key_exists('ssl_cert', $databaseConfig) && - array_key_exists('ssl_ca', $databaseConfig) && - array_key_exists('ssl_cipher', $databaseConfig)) { + array_key_exists('ssl_cert', $databaseConfig)) { $ssl = array( PDO::MYSQL_ATTR_SSL_KEY => $databaseConfig['ssl_key'], PDO::MYSQL_ATTR_SSL_CERT => $databaseConfig['ssl_cert'], - PDO::MYSQL_ATTR_SSL_CA => $databaseConfig['ssl_ca'], - PDO::MYSQL_ATTR_SSL_CIPHER => $databaseConfig['ssl_cipher'], ); + if(array_key_exists('ssl_ca', $databaseConfig)) { + $ssl[PDO::MYSQL_ATTR_SSL_CA] = $databaseConfig['ssl_ca']; + } + + // use default cipher if not provided + $ssl[PDO::MYSQL_ATTR_SSL_CA] = array_key_exists('ssl_ca', $databaseConfig) ? $databaseConfig['ssl_ca'] : $defaultCipher; } diff --git a/dev/install/install.php5 b/dev/install/install.php5 index c83f4f5d7..795383727 100755 --- a/dev/install/install.php5 +++ b/dev/install/install.php5 @@ -132,19 +132,25 @@ if(isset($_REQUEST['db'])) { "database" => $_REQUEST['db'][$type]['database'], ); + // Set SSL parameters if they exist if( defined('SS_DATABASE_SSL_KEY') && - defined('SS_DATABASE_SSL_CERT') && - defined('SS_DATABASE_SSL_CA') + defined('SS_DATABASE_SSL_CERT') ) { $databaseConfig['ssl_key'] = SS_DATABASE_SSL_KEY; $databaseConfig['ssl_cert'] = SS_DATABASE_SSL_CERT; - $databaseConfig['ssl_ca'] = SS_DATABASE_SSL_CA; - $databaseConfig['ssl_cipher'] = defined('SS_DATABASE_SSL_CIPHER') ? SS_DATABASE_SSL_CIPHER : 'DHE-RSA-AES256-SHA'; } + if(defined('SS_DATABASE_SSL_CA')) { + $databaseConfig['ssl_ca'] = SS_DATABASE_SSL_CA; + } + + if(defined('SS_DATABASE_SSL_CIPHER')) { + $databaseConfig['ssl_cipher'] = SS_DATABASE_SSL_CIPHER; + } + } else { // Normal behaviour without the environment diff --git a/model/connect/PDOConnector.php b/model/connect/PDOConnector.php index d7e1c00c5..fd5b6d3b8 100644 --- a/model/connect/PDOConnector.php +++ b/model/connect/PDOConnector.php @@ -15,6 +15,14 @@ class PDOConnector extends DBConnector { */ private static $emulate_prepare = false; + /** + * Default strong SSL cipher to be used + * + * @config + * @var boolean + */ + private static $ssl_cipher_default = 'DHE-RSA-AES256-SHA'; + /** * The PDO connection instance * @@ -160,17 +168,20 @@ class PDOConnector extends DBConnector { if($parameters['driver'] == 'mysql') { $options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $charset . ' COLLATE ' . $connCollation; - // Set SSL options from mysite/_config.php if they exist + // Set SSL options if they are defined if( array_key_exists('ssl_key', $parameters) && - array_key_exists('ssl_cert', $parameters) && - array_key_exists('ssl_ca', $parameters) && - array_key_exists('ssl_cipher', $parameters)) { + array_key_exists('ssl_cert', $parameters)) { $options[PDO::MYSQL_ATTR_SSL_KEY] = $parameters['ssl_key']; - $options[PDO::MYSQL_ATTR_SSL_CERT] =$parameters['ssl_cert']; + $options[PDO::MYSQL_ATTR_SSL_CERT] = $parameters['ssl_cert']; + + if(array_key_exists('ssl_ca', $parameters)) { $options[PDO::MYSQL_ATTR_SSL_CA] = $parameters['ssl_ca']; - $options[PDO::MYSQL_ATTR_SSL_CIPHER] = $parameters['ssl_cipher']; + } + + // use default cipher if not provided + $options[PDO::MYSQL_ATTR_SSL_CIPHER] = $parameters['ssl_cipher'] ?: $this->config()->ssl_cipher_default; }