From b1f85ec0328621c0f74b11b4278de353fed531db Mon Sep 17 00:00:00 2001 From: brandonkelly Date: Mon, 3 Aug 2026 10:50:33 -0700 Subject: [PATCH 1/5] Pull in the default SSL config settings --- src/db/mysql/Schema.php | 70 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/src/db/mysql/Schema.php b/src/db/mysql/Schema.php index f923de08e3b..aaf986d9b6d 100644 --- a/src/db/mysql/Schema.php +++ b/src/db/mysql/Schema.php @@ -477,14 +477,25 @@ 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]) || + isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CERT]) || + isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_KEY]) + ) { + 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]; + } + } 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, ''); @@ -495,6 +506,49 @@ 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 = ''; + foreach (preg_split('/\s+/', $shellCommand->getOutput()) as $token) { + if (!str_starts_with($token, '--') || !str_contains($token, '=')) { + continue; + } + [$key, $value] = explode('=', substr($token, 2), 2); + if (isset($directives[$key])) { + $contents .= PHP_EOL . $directives[$key] . '=' . $value; + } + } + + return $contents; + } + /** * Returns the row format for the given table, if known. * From fcc390f1ad711121a374162a14e0cc238c89cdd0 Mon Sep 17 00:00:00 2001 From: brandonkelly Date: Mon, 3 Aug 2026 10:53:14 -0700 Subject: [PATCH 2/5] Check for PDO::MYSQL_ATTR_SSL_CAPATH and MYSQL_ATTR_SSL_CIPHER --- src/db/mysql/Schema.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/db/mysql/Schema.php b/src/db/mysql/Schema.php index aaf986d9b6d..1f4419eee82 100644 --- a/src/db/mysql/Schema.php +++ b/src/db/mysql/Schema.php @@ -479,18 +479,26 @@ private function _createDumpConfigFile(): string // Certificates if ( isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CA]) || + 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]) + isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_KEY]) || + 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 (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 (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 From a9922dc3d79e8a7d52d08578dffa870898e2c62c Mon Sep 17 00:00:00 2001 From: Brandon Kelly Date: Mon, 3 Aug 2026 11:17:15 -0700 Subject: [PATCH 3/5] Make sure the attributes exist Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/db/mysql/Schema.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/db/mysql/Schema.php b/src/db/mysql/Schema.php index 1f4419eee82..42155eecaec 100644 --- a/src/db/mysql/Schema.php +++ b/src/db/mysql/Schema.php @@ -479,15 +479,15 @@ private function _createDumpConfigFile(): string // Certificates if ( isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CA]) || - isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CAPATH]) || + (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]) || - isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CIPHER]) + (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 (isset($this->db->attributes[PDO::MYSQL_ATTR_SSL_CAPATH])) { + 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])) { @@ -496,7 +496,7 @@ private function _createDumpConfigFile(): string 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_CIPHER])) { + 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 { From 74b3915cd4bedd1ec306ded740bb35111ec75cbc Mon Sep 17 00:00:00 2001 From: Brandon Kelly Date: Mon, 3 Aug 2026 11:18:07 -0700 Subject: [PATCH 4/5] Fix Windows compatibility Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/db/mysql/Schema.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/db/mysql/Schema.php b/src/db/mysql/Schema.php index 42155eecaec..989f98a8cd3 100644 --- a/src/db/mysql/Schema.php +++ b/src/db/mysql/Schema.php @@ -544,11 +544,13 @@ private function _sslDefaultsFromConfigFiles(): string ]; $contents = ''; - foreach (preg_split('/\s+/', $shellCommand->getOutput()) as $token) { - if (!str_starts_with($token, '--') || !str_contains($token, '=')) { + $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])) { $contents .= PHP_EOL . $directives[$key] . '=' . $value; } From 4005938f128e16e7aa77aea76b622507f450839d Mon Sep 17 00:00:00 2001 From: brandonkelly Date: Mon, 3 Aug 2026 13:20:12 -0700 Subject: [PATCH 5/5] Ignore redacted values --- src/db/mysql/Schema.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/mysql/Schema.php b/src/db/mysql/Schema.php index 989f98a8cd3..29ba24ec881 100644 --- a/src/db/mysql/Schema.php +++ b/src/db/mysql/Schema.php @@ -551,7 +551,7 @@ private function _sslDefaultsFromConfigFiles(): string } [$key, $value] = explode('=', substr($token, 2), 2); $value = trim($value, "\"'"); - if (isset($directives[$key])) { + if (isset($directives[$key]) && !preg_match('/^\**$/', $value)) { $contents .= PHP_EOL . $directives[$key] . '=' . $value; } }