Refactor code to decouple SSL feature from MySQL PDO

This commit is contained in:
John 2017-08-03 12:53:27 +08:00
parent 2f9bfae1f9
commit a3678c73b9
4 changed files with 56 additions and 30 deletions

View File

@ -25,7 +25,7 @@
* - SS_DATABASE_SSL_KEY: Path to SSL private key file * - SS_DATABASE_SSL_KEY: Path to SSL private key file
* - SS_DATABASE_SSL_CERT: Path to SSL certificate file * - SS_DATABASE_SSL_CERT: Path to SSL certificate file
* - SS_DATABASE_SSL_CA: Path to SSL CA 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. * 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')) if(defined('SS_DATABASE_MEMORY'))
$databaseConfig["memory"] = SS_DATABASE_MEMORY; $databaseConfig["memory"] = SS_DATABASE_MEMORY;
// PDO MySQL SSL parameters // Add ssl parameters to databaseConfig if these are defined
if(defined('SS_DATABASE_CLASS') && SS_DATABASE_CLASS === 'MySQLPDODatabase') { if(
defined('SS_DATABASE_SSL_KEY') &&
defined('SS_DATABASE_SSL_CERT')
) {
// add ssl parameters if these are defined $databaseConfig['ssl_key'] = SS_DATABASE_SSL_KEY;
if( $databaseConfig['ssl_cert'] = SS_DATABASE_SSL_CERT;
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';
}
} }
// 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')) { if(defined('SS_SEND_ALL_EMAILS_TO')) {

View File

@ -37,21 +37,25 @@ class MySQLDatabaseConfigurationHelper implements DatabaseConfigurationHelper {
case 'MySQLPDODatabase': case 'MySQLPDODatabase':
// May throw a PDOException if fails // May throw a PDOException if fails
// Set SSL parameters
$ssl = null; $ssl = null;
$defaultCipher = 'DHE-RSA-AES256-SHA';
if( if(
array_key_exists('ssl_key', $databaseConfig) && array_key_exists('ssl_key', $databaseConfig) &&
array_key_exists('ssl_cert', $databaseConfig) && array_key_exists('ssl_cert', $databaseConfig)) {
array_key_exists('ssl_ca', $databaseConfig) &&
array_key_exists('ssl_cipher', $databaseConfig)) {
$ssl = array( $ssl = array(
PDO::MYSQL_ATTR_SSL_KEY => $databaseConfig['ssl_key'], PDO::MYSQL_ATTR_SSL_KEY => $databaseConfig['ssl_key'],
PDO::MYSQL_ATTR_SSL_CERT => $databaseConfig['ssl_cert'], 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;
} }

View File

@ -132,19 +132,25 @@ if(isset($_REQUEST['db'])) {
"database" => $_REQUEST['db'][$type]['database'], "database" => $_REQUEST['db'][$type]['database'],
); );
// Set SSL parameters if they exist
if( if(
defined('SS_DATABASE_SSL_KEY') && defined('SS_DATABASE_SSL_KEY') &&
defined('SS_DATABASE_SSL_CERT') && defined('SS_DATABASE_SSL_CERT')
defined('SS_DATABASE_SSL_CA')
) { ) {
$databaseConfig['ssl_key'] = SS_DATABASE_SSL_KEY; $databaseConfig['ssl_key'] = SS_DATABASE_SSL_KEY;
$databaseConfig['ssl_cert'] = SS_DATABASE_SSL_CERT; $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 { } else {
// Normal behaviour without the environment // Normal behaviour without the environment

View File

@ -15,6 +15,14 @@ class PDOConnector extends DBConnector {
*/ */
private static $emulate_prepare = false; 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 * The PDO connection instance
* *
@ -160,17 +168,20 @@ class PDOConnector extends DBConnector {
if($parameters['driver'] == 'mysql') { if($parameters['driver'] == 'mysql') {
$options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $charset . ' COLLATE ' . $connCollation; $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( if(
array_key_exists('ssl_key', $parameters) && array_key_exists('ssl_key', $parameters) &&
array_key_exists('ssl_cert', $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_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_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;
} }