From 2f9bfae1f9f6bb2d33e3f979601e0abae243a7f6 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 2 Aug 2017 19:29:23 +0800 Subject: [PATCH] NEW Added MySQL SSL PDO Support Modified ConfigureFromEnv.php to parse SS_DATABASE_SSL variables (also added a bit of documentation) Modified PDOConnector.php to implement variables set in ConfigureFromEnv if exists Modified install files MySQLDatabaseConfigurationHelper and install.php5 to accept and implement SS_DATABASE_SSL variables set in _ss_environment.php TODO: Add documentation --- cli-script.php | 8 ++++++ conf/ConfigureFromEnv.php | 27 +++++++++++++++++++ .../MySQLDatabaseConfigurationHelper.php | 21 ++++++++++++++- dev/install/install.php5 | 14 ++++++++++ model/connect/PDOConnector.php | 16 +++++++++++ 5 files changed, 85 insertions(+), 1 deletion(-) diff --git a/cli-script.php b/cli-script.php index 48a87b38d..24e8526a2 100755 --- a/cli-script.php +++ b/cli-script.php @@ -91,6 +91,14 @@ define('SS_DATABASE_SERVER', 'localhost'); define('SS_DATABASE_USERNAME', ''); define('SS_DATABASE_PASSWORD', ''); define('SS_DATABASE_NAME', ''); + +/* SSL support for MySQLPDODatabase */ +/* +define('SS_DATABASE_CLASS', 'MySQLPDODatabase'); +define('SS_DATABASE_SSL_KEY', '/path/to/keyfile'); +define('SS_DATABASE_SSL_CERT', '/path/to/certfile'); +define('SS_DATABASE_SSL_CA', '/path/to/cafile');; +*/ -------------------------------------------------- Once you have done that, run 'composer install' or './framework/sake dev/build' to create diff --git a/conf/ConfigureFromEnv.php b/conf/ConfigureFromEnv.php index 2542150f0..3575f4636 100644 --- a/conf/ConfigureFromEnv.php +++ b/conf/ConfigureFromEnv.php @@ -20,6 +20,14 @@ * - SS_DATABASE_MEMORY: Use in-memory state if possible. Useful for testing, currently only * supported by the SQLite database adapter. * + * SSL Support (for MySQLPDODatabase) + * + * - 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) + * + * * There is one more setting that is intended to be used by people who work on SilverStripe. * - SS_DATABASE_CHOOSE_NAME: Boolean/Int. If set, then the system will choose a default database name for you if * one isn't give in the $database variable. The database name will be "SS_" followed by the name of the folder @@ -116,6 +124,25 @@ if(defined('SS_DATABASE_USERNAME') && defined('SS_DATABASE_PASSWORD')) { // For SQlite3 memory databases (mainly for testing purposes) 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 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_ca'] = SS_DATABASE_SSL_CA; + $databaseConfig['ssl_cipher'] = defined('SS_DATABASE_SSL_CIPHER') ? SS_DATABASE_SSL_CIPHER : 'DHE-RSA-AES256-SHA'; + + } + } + } if(defined('SS_SEND_ALL_EMAILS_TO')) { diff --git a/dev/install/MySQLDatabaseConfigurationHelper.php b/dev/install/MySQLDatabaseConfigurationHelper.php index 5907eb4bb..86f7ff6e5 100644 --- a/dev/install/MySQLDatabaseConfigurationHelper.php +++ b/dev/install/MySQLDatabaseConfigurationHelper.php @@ -36,8 +36,27 @@ class MySQLDatabaseConfigurationHelper implements DatabaseConfigurationHelper { } case 'MySQLPDODatabase': // May throw a PDOException if fails + + $ssl = null; + + 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)) { + + $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'], + ); + + + } + $conn = @new PDO('mysql:host='.$databaseConfig['server'], $databaseConfig['username'], - $databaseConfig['password']); + $databaseConfig['password'], $ssl); if($conn) { $conn->query("SET sql_mode = 'ANSI'"); return $conn; diff --git a/dev/install/install.php5 b/dev/install/install.php5 index 5df46ffbc..c83f4f5d7 100755 --- a/dev/install/install.php5 +++ b/dev/install/install.php5 @@ -132,6 +132,20 @@ if(isset($_REQUEST['db'])) { "database" => $_REQUEST['db'][$type]['database'], ); + 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_ca'] = SS_DATABASE_SSL_CA; + $databaseConfig['ssl_cipher'] = defined('SS_DATABASE_SSL_CIPHER') ? SS_DATABASE_SSL_CIPHER : 'DHE-RSA-AES256-SHA'; + + } + + } else { // Normal behaviour without the environment $databaseConfig = $_REQUEST['db'][$type]; diff --git a/model/connect/PDOConnector.php b/model/connect/PDOConnector.php index 4f8cf21bf..d7e1c00c5 100644 --- a/model/connect/PDOConnector.php +++ b/model/connect/PDOConnector.php @@ -159,6 +159,22 @@ class PDOConnector extends DBConnector { $options = array(); 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 + 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)) { + + $options[PDO::MYSQL_ATTR_SSL_KEY] = $parameters['ssl_key']; + $options[PDO::MYSQL_ATTR_SSL_CERT] =$parameters['ssl_cert']; + $options[PDO::MYSQL_ATTR_SSL_CA] = $parameters['ssl_ca']; + $options[PDO::MYSQL_ATTR_SSL_CIPHER] = $parameters['ssl_cipher']; + + } + + } if(self::is_emulate_prepare()) { $options[PDO::ATTR_EMULATE_PREPARES] = true;