Support ssl for pdo_mysql and mysqli (#1525)

* Support ssl for pdo_mysql and mysqli

* Improve config name for mysql ssl mode, and fix some minor bugs.

* Fix typo

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
This commit is contained in:
沈唁 2023-03-29 14:33:23 +08:00 committed by GitHub
parent 65f5974e17
commit daef17d7eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 11 deletions

View File

@ -924,7 +924,9 @@ function install_step_2_perform()
'dbPassword' => null,
'dbCharset' => 'utf8mb4',
'dbDatabase' => null,
'dbEngine' => 'InnoDB'
'dbEngine' => 'InnoDB',
'dbSslCa' => null,
'dbSslVerify' => 'on',
],
'Pgsql' => [
'dbHost' => 'localhost',
@ -952,7 +954,9 @@ function install_step_2_perform()
'dbEngine' => $request->getServer('TYPECHO_DB_ENGINE'),
'dbPrefix' => $request->getServer('TYPECHO_DB_PREFIX', 'typecho_'),
'dbAdapter' => $request->getServer('TYPECHO_DB_ADAPTER', install_get_current_db_driver()),
'dbNext' => $request->getServer('TYPECHO_DB_NEXT', 'none')
'dbNext' => $request->getServer('TYPECHO_DB_NEXT', 'none'),
'dbSslCa' => $request->getServer('TYPECHO_DB_SSL_CA'),
'dbSslVerify' => $request->getServer('TYPECHO_DB_SSL_VERIFY', 'on'),
];
} else {
$config = $request->from([
@ -967,7 +971,9 @@ function install_step_2_perform()
'dbEngine',
'dbPrefix',
'dbAdapter',
'dbNext'
'dbNext',
'dbSslCa',
'dbSslVerify',
]);
}
@ -1005,6 +1011,8 @@ function install_step_2_perform()
->addRule('dbDatabase', 'required', _t('确认您的配置'))
->addRule('dbEngine', 'required', _t('确认您的配置'))
->addRule('dbEngine', 'enum', _t('确认您的配置'), ['InnoDB', 'MyISAM'])
->addRule('dbSslCa', 'file_exists', _t('确认您的配置'))
->addRule('dbSslVerify', 'enum', _t('确认您的配置'), ['on', 'off'])
->run($config);
break;
case 'Pgsql':
@ -1041,7 +1049,7 @@ function install_step_2_perform()
}
foreach ($configMap[$type] as $key => $value) {
$dbConfig[strtolower(substr($key, 2))] = $config[$key];
$dbConfig[lcfirst(substr($key, 2))] = $config[$key];
}
// intval port number
@ -1049,6 +1057,11 @@ function install_step_2_perform()
$dbConfig['port'] = intval($dbConfig['port']);
}
// bool ssl verify
if (isset($dbConfig['sslVerify'])) {
$dbConfig['sslVerify'] = $dbConfig['sslVerify'] == 'on';
}
if (isset($dbConfig['file']) && preg_match("/^[a-z0-9]+\.[a-z0-9]{2,}$/i", $dbConfig['file'])) {
$dbConfig['file'] = __DIR__ . '/usr/' . $dbConfig['file'];
}
@ -1064,7 +1077,7 @@ function install_step_2_perform()
$installDb->addServer($dbConfig, \Typecho\Db::READ | \Typecho\Db::WRITE);
$installDb->query('SELECT 1=1');
} catch (\Typecho\Db\Adapter\ConnectionException $e) {
install_raise_error(_t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装'));
install_raise_error(_t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装: "%s"', $e->getMessage()));
} catch (\Typecho\Db\Exception $e) {
install_raise_error(_t('安装程序捕捉到以下错误: "%s". 程序被终止, 请检查您的配置信息.', $e->getMessage()));
}

View File

@ -63,4 +63,22 @@
</select>
</li>
</ul>
</details>
<ul class="typecho-option">
<li>
<label class="typecho-label" for="dbSslCa"><?php _e('数据库 SSL 证书'); ?></label>
<input type="text" class="text" name="dbSslCa" id="dbSslCa"/>
<p class="description"><?php _e('如果您的数据库启用了 SSL请填写 CA 证书路径,否则请留空'); ?></p>
</li>
</ul>
<ul class="typecho-option">
<li>
<label class="typecho-label" for="dbSslVerify"><?php _e('启用数据库 SSL 服务端证书验证'); ?></label>
<select name="dbSslVerify" id="dbSslVerify">
<option value="on"><?php _e('启用'); ?></option>
<option value="off"><?php _e('不启用'); ?></option>
</select>
</li>
</ul>
</details>

View File

@ -47,19 +47,30 @@ class Mysqli implements Adapter
*/
public function connect(Config $config): \mysqli
{
$mysqli = mysqli_init();
if ($mysqli) {
if (!empty($config->sslCa)) {
$mysqli->ssl_set(null, null, $config->sslCa, null, null);
if (
$this->dbLink = @mysqli_connect(
if (isset($config->sslVerify)) {
$mysqli->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, $config->sslVerify);
}
}
$mysqli->real_connect(
$config->host,
$config->user,
$config->password,
$config->database,
(empty($config->port) ? null : $config->port)
)
) {
);
$this->dbLink = $mysqli;
if ($config->charset) {
$this->dbLink->query("SET NAMES '{$config->charset}'");
}
return $this->dbLink;
}

View File

@ -51,11 +51,22 @@ class Mysql extends Pdo
*/
public function init(Config $config): \PDO
{
$options = [];
if (!empty($config->sslCa)) {
$options[\PDO::MYSQL_ATTR_SSL_CA] = $config->sslCa;
if (isset($config->sslVerify)) {
// FIXME: https://github.com/php/php-src/issues/8577
$options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = $config->sslVerify;
}
}
$pdo = new \PDO(
!empty($config->dsn)
? $config->dsn : "mysql:dbname={$config->database};host={$config->host};port={$config->port}",
$config->user,
$config->password
$config->password,
$options
);
$pdo->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);