Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 72 additions & 8 deletions src/db/mysql/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -477,14 +477,33 @@ private function _createDumpConfigFile(): string
}

// Certificates
if (isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CA])) {
$contents .= PHP_EOL . 'ssl_ca=' . $this->db->attributes[PDO::MYSQL_ATTR_SSL_CA];
}
if (isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CERT])) {
$contents .= PHP_EOL . 'ssl_cert=' . $this->db->attributes[PDO::MYSQL_ATTR_SSL_CERT];
}
if (isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_KEY])) {
$contents .= PHP_EOL . 'ssl_key=' . $this->db->attributes[PDO::MYSQL_ATTR_SSL_KEY];
if (
isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CA]) ||
(defined('PDO::MYSQL_ATTR_SSL_CAPATH') && isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CAPATH])) ||
isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CERT]) ||
isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_KEY]) ||
(defined('PDO::MYSQL_ATTR_SSL_CIPHER') && isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CIPHER]))
) {
if (isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CA])) {
$contents .= PHP_EOL . 'ssl_ca=' . $this->db->attributes[PDO::MYSQL_ATTR_SSL_CA];
}
if (defined('PDO::MYSQL_ATTR_SSL_CAPATH') && isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CAPATH])) {
$contents .= PHP_EOL . 'ssl_capath=' . $this->db->attributes[PDO::MYSQL_ATTR_SSL_CAPATH];
}
if (isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CERT])) {
$contents .= PHP_EOL . 'ssl_cert=' . $this->db->attributes[PDO::MYSQL_ATTR_SSL_CERT];
}
if (isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_KEY])) {
$contents .= PHP_EOL . 'ssl_key=' . $this->db->attributes[PDO::MYSQL_ATTR_SSL_KEY];
}
if (defined('PDO::MYSQL_ATTR_SSL_CIPHER') && isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CIPHER])) {
$contents .= PHP_EOL . 'ssl_cipher=' . $this->db->attributes[PDO::MYSQL_ATTR_SSL_CIPHER];
}
} else {
// The db connection wasn't explicitly configured with SSL attributes, but the normal
// my.cnf file chain (which --defaults-file causes mysqldump/mysql to ignore) might
// still specify them, so carry those over.
$contents .= $this->_sslDefaultsFromConfigFiles();
}

FileHelper::writeToFile($this->tempMyCnfPath, '');
Expand All @@ -495,6 +514,51 @@ private function _createDumpConfigFile(): string
return $this->tempMyCnfPath;
}

/**
* Returns `ssl_*` my.cnf directives based on whatever the normal MySQL config file chain
* (e.g. `/etc/my.cnf`, `~/.my.cnf`) would otherwise provide, since those files are ignored
* once `--defaults-file` is passed to `mysqldump`/`mysql`.
*
* @return string
*/
private function _sslDefaultsFromConfigFiles(): string
{
$shellCommand = (new ShellCommand('mysql'))->addArg('--print-defaults');

// If we don't have proc_open, maybe we've got exec
if (!function_exists('proc_open') && function_exists('exec')) {
$shellCommand->useExec = true;
}

if (!$shellCommand->execute()) {
return '';
}

$directives = [
'ssl-ca' => 'ssl_ca',
'ssl-capath' => 'ssl_capath',
'ssl-cert' => 'ssl_cert',
'ssl-key' => 'ssl_key',
'ssl-cipher' => 'ssl_cipher',
'ssl-mode' => 'ssl_mode',
];

$contents = '';
$output = trim($shellCommand->getOutput());
foreach (str_getcsv($output, ' ') as $token) {
if ($token === '' || !str_starts_with($token, '--') || !str_contains($token, '=')) {
continue;
}
[$key, $value] = explode('=', substr($token, 2), 2);
$value = trim($value, "\"'");
if (isset($directives[$key]) && !preg_match('/^\**$/', $value)) {
$contents .= PHP_EOL . $directives[$key] . '=' . $value;
}
}
Comment thread
Copilot marked this conversation as resolved.

return $contents;
}

/**
* Returns the row format for the given table, if known.
*
Expand Down
Loading