Skip to content

Commit a817311

Browse files
bnymnnmalevanec
authored andcommitted
Enable Magento 2 to connect MySQL through SSL.
1 parent 9cc293e commit a817311

File tree

13 files changed

+368
-13
lines changed

13 files changed

+368
-13
lines changed

lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php

+25-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class ConfigOptionsListConstants
2121
const CONFIG_PATH_CRYPT_KEY = 'crypt/key';
2222
const CONFIG_PATH_SESSION_SAVE = 'session/save';
2323
const CONFIG_PATH_RESOURCE_DEFAULT_SETUP = 'resource/default_setup/connection';
24+
const CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS = 'db/connection/default/driver_options';
2425
const CONFIG_PATH_DB_CONNECTION_DEFAULT = 'db/connection/default';
2526
const CONFIG_PATH_DB_CONNECTIONS = 'db/connection';
2627
const CONFIG_PATH_DB_PREFIX = 'db/table_prefix';
@@ -64,6 +65,10 @@ class ConfigOptionsListConstants
6465
const INPUT_KEY_DB_MODEL = 'db-model';
6566
const INPUT_KEY_DB_INIT_STATEMENTS = 'db-init-statements';
6667
const INPUT_KEY_DB_ENGINE = 'db-engine';
68+
const INPUT_KEY_DB_SSL_KEY = 'db-ssl-key';
69+
const INPUT_KEY_DB_SSL_CERT = 'db-ssl-cert';
70+
const INPUT_KEY_DB_SSL_CA = 'db-ssl-ca';
71+
const INPUT_KEY_DB_SSL_VERIFY = 'db-ssl-verify';
6772
const INPUT_KEY_RESOURCE = 'resource';
6873
const INPUT_KEY_SKIP_DB_VALIDATION = 'skip-db-validation';
6974
const INPUT_KEY_CACHE_HOSTS = 'http-cache-hosts';
@@ -75,7 +80,11 @@ class ConfigOptionsListConstants
7580
const KEY_CACHE_FRONTEND = 'cache/frontend';
7681
const CONFIG_PATH_BACKEND_OPTIONS = 'backend_options';
7782

78-
/** @deprecated */
83+
/**
84+
* @deprecated
85+
*
86+
* Definition format constant.
87+
*/
7988
const INPUT_KEY_DEFINITION_FORMAT = 'definition-format';
8089

8190
/**#@+
@@ -104,6 +113,21 @@ class ConfigOptionsListConstants
104113
const KEY_MODEL = 'model';
105114
const KEY_INIT_STATEMENTS = 'initStatements';
106115
const KEY_ACTIVE = 'active';
116+
const KEY_DRIVER_OPTIONS = 'driver_options';
117+
/**#@-*/
118+
119+
/**#@+
120+
* Array keys for database driver options configurations
121+
*/
122+
const KEY_MYSQL_SSL_KEY = \PDO::MYSQL_ATTR_SSL_KEY;
123+
const KEY_MYSQL_SSL_CERT = \PDO::MYSQL_ATTR_SSL_CERT;
124+
const KEY_MYSQL_SSL_CA = \PDO::MYSQL_ATTR_SSL_CA;
125+
126+
/**
127+
* Constant \PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT cannot be used as it was introduced in PHP 7.1.4
128+
* and Magento 2 is currently supporting PHP 7.1.3.
129+
*/
130+
const KEY_MYSQL_SSL_VERIFY = 1014;
107131
/**#@-*/
108132

109133
/**

setup/src/Magento/Setup/Controller/DatabaseCheck.php

+35-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace Magento\Setup\Controller;
77

8+
use Magento\Framework\Config\ConfigOptionsListConstants;
89
use Magento\Setup\Validator\DbValidator;
910
use Zend\Json\Json;
1011
use Zend\Mvc\Controller\AbstractActionController;
@@ -40,12 +41,45 @@ public function indexAction()
4041
try {
4142
$params = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY);
4243
$password = isset($params['password']) ? $params['password'] : '';
43-
$this->dbValidator->checkDatabaseConnection($params['name'], $params['host'], $params['user'], $password);
44+
$driverOptions = [];
45+
if ($this->isDriverOptionsGiven($params)) {
46+
if (empty($params['driverOptionsSslVerify'])) {
47+
$params['driverOptionsSslVerify'] = 0;
48+
}
49+
$driverOptions = [
50+
ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY => $params['driverOptionsSslKey'],
51+
ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT => $params['driverOptionsSslCert'],
52+
ConfigOptionsListConstants::KEY_MYSQL_SSL_CA => $params['driverOptionsSslCa'],
53+
ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY => (int) $params['driverOptionsSslVerify'],
54+
];
55+
}
56+
$this->dbValidator->checkDatabaseConnectionWithDriverOptions(
57+
$params['name'],
58+
$params['host'],
59+
$params['user'],
60+
$password,
61+
$driverOptions
62+
);
4463
$tablePrefix = isset($params['tablePrefix']) ? $params['tablePrefix'] : '';
4564
$this->dbValidator->checkDatabaseTablePrefix($tablePrefix);
4665
return new JsonModel(['success' => true]);
4766
} catch (\Exception $e) {
4867
return new JsonModel(['success' => false, 'error' => $e->getMessage()]);
4968
}
5069
}
70+
71+
/**
72+
* Is Driver Options Given
73+
*
74+
* @param array $params
75+
* @return bool
76+
*/
77+
private function isDriverOptionsGiven($params)
78+
{
79+
return !(
80+
empty($params['driverOptionsSslKey']) ||
81+
empty($params['driverOptionsSslCert']) ||
82+
empty($params['driverOptionsSslCa'])
83+
);
84+
}
5185
}

setup/src/Magento/Setup/Model/ConfigGenerator.php

+14-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
use Magento\Framework\Config\ConfigOptionsListConstants;
1515
use Magento\Framework\App\State;
1616
use Magento\Framework\Math\Random;
17+
use Magento\Setup\Model\ConfigOptionsList\DriverOptions;
1718

1819
/**
1920
* Creates deployment config data based on user input array
2021
*
21-
* This class introduced to break down {@see Magento\Setup\Model\ConfigOptionsList::createConfig}
22+
* This class introduced to break down {@see \Magento\Setup\Model\ConfigOptionsList::createConfig}
2223
*/
2324
class ConfigGenerator
2425
{
@@ -62,24 +63,32 @@ class ConfigGenerator
6263
*/
6364
private $cryptKeyGenerator;
6465

66+
/**
67+
* @var DriverOptions
68+
*/
69+
private $driverOptions;
70+
6571
/**
6672
* Constructor
6773
*
6874
* @param Random $random Deprecated since 100.2.0
6975
* @param DeploymentConfig $deploymentConfig
7076
* @param ConfigDataFactory|null $configDataFactory
7177
* @param CryptKeyGeneratorInterface|null $cryptKeyGenerator
78+
* @param DriverOptions|null $driverOptions
7279
*/
7380
public function __construct(
7481
Random $random,
7582
DeploymentConfig $deploymentConfig,
7683
ConfigDataFactory $configDataFactory = null,
77-
CryptKeyGeneratorInterface $cryptKeyGenerator = null
84+
CryptKeyGeneratorInterface $cryptKeyGenerator = null,
85+
DriverOptions $driverOptions = null
7886
) {
7987
$this->random = $random;
8088
$this->deploymentConfig = $deploymentConfig;
8189
$this->configDataFactory = $configDataFactory ?? ObjectManager::getInstance()->get(ConfigDataFactory::class);
8290
$this->cryptKeyGenerator = $cryptKeyGenerator ?? ObjectManager::getInstance()->get(CryptKeyGenerator::class);
91+
$this->driverOptions = $driverOptions ?? ObjectManager::getInstance()->get(DriverOptions::class);
8392
}
8493

8594
/**
@@ -181,6 +190,9 @@ public function createDbConfig(array $data)
181190
$configData->set($dbConnectionPrefix . ConfigOptionsListConstants::KEY_ACTIVE, '1');
182191
}
183192

193+
$driverOptions = $this->driverOptions->getDriverOptions($data);
194+
$configData->set($dbConnectionPrefix . ConfigOptionsListConstants::KEY_DRIVER_OPTIONS, $driverOptions);
195+
184196
return $configData;
185197
}
186198

setup/src/Magento/Setup/Model/ConfigOptionsList.php

+44-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Magento\Framework\Setup\ConfigOptionsListInterface;
1313
use Magento\Framework\Setup\Option\FlagConfigOption;
1414
use Magento\Framework\Setup\Option\TextConfigOption;
15+
use Magento\Setup\Model\ConfigOptionsList\DriverOptions;
1516
use Magento\Setup\Validator\DbValidator;
1617

1718
/**
@@ -53,17 +54,24 @@ class ConfigOptionsList implements ConfigOptionsListInterface
5354
\Magento\Setup\Model\ConfigOptionsList\Lock::class,
5455
];
5556

57+
/**
58+
* @var DriverOptions
59+
*/
60+
private $driverOptions;
61+
5662
/**
5763
* Constructor
5864
*
5965
* @param ConfigGenerator $configGenerator
6066
* @param DbValidator $dbValidator
6167
* @param KeyValidator|null $encryptionKeyValidator
68+
* @param DriverOptions|null $driverOptions
6269
*/
6370
public function __construct(
6471
ConfigGenerator $configGenerator,
6572
DbValidator $dbValidator,
66-
KeyValidator $encryptionKeyValidator = null
73+
KeyValidator $encryptionKeyValidator = null,
74+
DriverOptions $driverOptions = null
6775
) {
6876
$this->configGenerator = $configGenerator;
6977
$this->dbValidator = $dbValidator;
@@ -72,6 +80,7 @@ public function __construct(
7280
$this->configOptionsCollection[] = $objectManager->get($className);
7381
}
7482
$this->encryptionKeyValidator = $encryptionKeyValidator ?: $objectManager->get(KeyValidator::class);
83+
$this->driverOptions = $driverOptions ?? $objectManager->get(DriverOptions::class);
7584
}
7685

7786
/**
@@ -162,6 +171,36 @@ public function getOptions()
162171
ConfigOptionsListConstants::CONFIG_PATH_CACHE_HOSTS,
163172
'http Cache hosts'
164173
),
174+
new TextConfigOption(
175+
ConfigOptionsListConstants::INPUT_KEY_DB_SSL_KEY,
176+
TextConfigOption::FRONTEND_WIZARD_TEXT,
177+
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS .
178+
'/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY,
179+
'Full path of client key file in order to establish db connection through SSL',
180+
null
181+
),
182+
new TextConfigOption(
183+
ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CERT,
184+
TextConfigOption::FRONTEND_WIZARD_TEXT,
185+
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS .
186+
'/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT,
187+
'Full path of client certificate file in order to establish db connection through SSL',
188+
null
189+
),
190+
new TextConfigOption(
191+
ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CA,
192+
TextConfigOption::FRONTEND_WIZARD_TEXT,
193+
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS .
194+
'/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_CA,
195+
'Full path of server certificate file in order to establish db connection through SSL',
196+
null
197+
),
198+
new FlagConfigOption(
199+
ConfigOptionsListConstants::INPUT_KEY_DB_SSL_VERIFY,
200+
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS .
201+
'/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY,
202+
'Verify server certification'
203+
),
165204
];
166205

167206
foreach ($this->configOptionsCollection as $configOptionsList) {
@@ -349,12 +388,14 @@ private function validateDbSettings(array $options, DeploymentConfig $deployment
349388
) {
350389
try {
351390
$options = $this->getDbSettings($options, $deploymentConfig);
391+
$driverOptions = $this->driverOptions->getDriverOptions($options);
352392

353-
$this->dbValidator->checkDatabaseConnection(
393+
$this->dbValidator->checkDatabaseConnectionWithDriverOptions(
354394
$options[ConfigOptionsListConstants::INPUT_KEY_DB_NAME],
355395
$options[ConfigOptionsListConstants::INPUT_KEY_DB_HOST],
356396
$options[ConfigOptionsListConstants::INPUT_KEY_DB_USER],
357-
$options[ConfigOptionsListConstants::INPUT_KEY_DB_PASSWORD]
397+
$options[ConfigOptionsListConstants::INPUT_KEY_DB_PASSWORD],
398+
$driverOptions
358399
);
359400
} catch (\Exception $exception) {
360401
$errors[] = $exception->getMessage();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Setup\Model\ConfigOptionsList;
9+
10+
use Magento\Framework\Config\ConfigOptionsListConstants;
11+
12+
/**
13+
* Mysql driver options.
14+
*/
15+
class DriverOptions
16+
{
17+
/**
18+
* Get mysql driver options.
19+
*
20+
* @param array $options
21+
* @return array
22+
*/
23+
public function getDriverOptions(array $options): array
24+
{
25+
$driverOptionKeys = [
26+
ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_KEY,
27+
ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CERT,
28+
ConfigOptionsListConstants::KEY_MYSQL_SSL_CA => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CA,
29+
ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_VERIFY
30+
];
31+
$driverOptions = [];
32+
foreach ($driverOptionKeys as $configKey => $driverOptionKey) {
33+
if ($this->optionExists($options, $driverOptionKey)) {
34+
$driverOptions[$configKey] = $options[$driverOptionKey];
35+
}
36+
}
37+
return $driverOptions;
38+
}
39+
40+
/**
41+
* Verify if option exists.
42+
*
43+
* @param array $options
44+
* @param string $driverOptionKey
45+
* @return bool
46+
*/
47+
private function optionExists($options, $driverOptionKey): bool
48+
{
49+
return $options[$driverOptionKey] === false || !empty($options[$driverOptionKey]);
50+
}
51+
}

setup/src/Magento/Setup/Model/Installer.php

+28-2
Original file line numberDiff line numberDiff line change
@@ -1375,7 +1375,32 @@ private function deleteDeploymentConfig()
13751375
*/
13761376
private function assertDbAccessible()
13771377
{
1378-
$this->dbValidator->checkDatabaseConnection(
1378+
$driverOptionKeys = [
1379+
ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY =>
1380+
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . '/' .
1381+
ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY,
1382+
1383+
ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT =>
1384+
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . '/' .
1385+
ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT,
1386+
1387+
ConfigOptionsListConstants::KEY_MYSQL_SSL_CA =>
1388+
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . '/' .
1389+
ConfigOptionsListConstants::KEY_MYSQL_SSL_CA,
1390+
1391+
ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY =>
1392+
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . '/' .
1393+
ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY
1394+
];
1395+
$driverOptions = [];
1396+
foreach ($driverOptionKeys as $driverOptionKey => $driverOptionConfig) {
1397+
$config = $this->deploymentConfig->get($driverOptionConfig);
1398+
if ($config !== null) {
1399+
$driverOptions[$driverOptionKey] = $config;
1400+
}
1401+
}
1402+
1403+
$this->dbValidator->checkDatabaseConnectionWithDriverOptions(
13791404
$this->deploymentConfig->get(
13801405
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT .
13811406
'/' . ConfigOptionsListConstants::KEY_NAME
@@ -1391,7 +1416,8 @@ private function assertDbAccessible()
13911416
$this->deploymentConfig->get(
13921417
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT .
13931418
'/' . ConfigOptionsListConstants::KEY_PASSWORD
1394-
)
1419+
),
1420+
$driverOptions
13951421
);
13961422
$prefix = $this->deploymentConfig->get(
13971423
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT .

setup/src/Magento/Setup/Model/RequestDataConverter.php

+8
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ private function convertDeploymentConfigForm(array $source)
5151
isset($source['db']['tablePrefix']) ? $source['db']['tablePrefix'] : '';
5252
$result[BackendConfigOptionsList::INPUT_KEY_BACKEND_FRONTNAME] = isset($source['config']['address']['admin'])
5353
? $source['config']['address']['admin'] : '';
54+
$result[SetupConfigOptionsList::INPUT_KEY_DB_SSL_KEY] = isset($source['db']['driverOptionsSslKey'])
55+
? $source['db']['driverOptionsSslKey'] : '';
56+
$result[SetupConfigOptionsList::INPUT_KEY_DB_SSL_CERT] = isset($source['db']['driverOptionsSslCert'])
57+
? $source['db']['driverOptionsSslCert'] : '';
58+
$result[SetupConfigOptionsList::INPUT_KEY_DB_SSL_CA] = isset($source['db']['driverOptionsSslCa'])
59+
? $source['db']['driverOptionsSslCa'] : '';
60+
$result[SetupConfigOptionsList::INPUT_KEY_DB_SSL_VERIFY] = isset($source['db']['driverOptionsSslVerify'])
61+
? $source['db']['driverOptionsSslVerify'] : '';
5462
$result[SetupConfigOptionsList::INPUT_KEY_ENCRYPTION_KEY] = isset($source['config']['encrypt']['key'])
5563
? $source['config']['encrypt']['key'] : null;
5664
$result[SetupConfigOptionsList::INPUT_KEY_SESSION_SAVE] = isset($source['config']['sessionSave']['type'])

0 commit comments

Comments
 (0)