Skip to content

fix(plugins): honor SSL config in Oracle and Cassandra, real 2-pass prefer for MySQL/MariaDB#1310

Merged
datlechin merged 13 commits into
mainfrom
refactor/ssl-all-drivers
May 18, 2026
Merged

fix(plugins): honor SSL config in Oracle and Cassandra, real 2-pass prefer for MySQL/MariaDB#1310
datlechin merged 13 commits into
mainfrom
refactor/ssl-all-drivers

Conversation

@datlechin
Copy link
Copy Markdown
Member

Stacks on top of #1309 (per-engine default SSL mode). Merge that first.

Summary

3 driver fixes that close silent SSL gaps and finish the SSL story started in #1309:

  • Oracle: SSL pane was completely ignored. The OraclePluginDriver never passed sslConfig into OracleNIO.OracleConnection.Configuration, so every Oracle connection was plain TCP regardless of what the user picked. Wired through NIOSSL with TLSConfiguration.makeClientConfiguration(), mapping Required → no verify, Verify CA → CA only, Verify Identity → full verification.
  • Cassandra: Same class of silent SSL bug, worse. The plugin read SSL mode from additionalFields["sslMode"], but that field was never declared in additionalConnectionFields and never written by the form. Result: every Cassandra connection was plain TCP regardless of SSL pane. Switched to reading config.ssl directly. Removed the orphan sslCaCertPath custom field (standard SSL pane now handles it). Migration: existing additionalFields["sslCaCertPath"] is copied into sslConfig.caCertificatePath on load.
  • MySQL/MariaDB: .preferred was cosmetic in PR fix(connection-form): default SSL mode to preferred for libpq and FreeTDS engines (#1298) #1309 because bundled libmariadb has only MYSQL_OPT_SSL_ENFORCE (binary) — .disabled and .preferred mapped identically. Implemented 2-pass connect: try ENFORCE=1 first, on SSL-only error codes {CR_SSL_CONNECTION_ERROR=2026, CR_SERVER_HANDSHAKE_ERR=2012, ER_HANDSHAKE_ERROR=1043} retry with ENFORCE=0. Re-enabled MySQL/MariaDB defaultSSLMode = .preferred in metadata so Cloud SQL / Azure MySQL works out of the box.

Out of scope (separate follow-up)

  • Cross-plugin SSL standardization (SSLMappingProtocol, SSLHandshakeError, conform Mongo/Redis/ClickHouse to unified pattern) — architectural debt, separate PR with PluginKit ABI surface
  • Form save-time validation (.verifyCa requires CA path, etc.) — UX polish
  • Per-engine SSL tooltip explaining default — UX polish

ClickHouse .verifyIdentity was investigated and confirmed NOT a bug: returns nil delegate intentionally, URLSession default HTTPS trust evaluation already validates cert chain + hostname.

Architecture notes

  • Oracle: buildTLS() helper in OracleConnectionWrapper. Logs warning for .preferred since OracleNIO has no opportunistic TLS (only .disable or .require(NIOSSLContext)). Default stays .disabled for Oracle.
  • Cassandra: backward-compatible read of legacy sslCaCertPath in ConnectionStorage.toConnection() — copies to sslConfig.caCertificatePath if empty. Drops on next save (form no longer writes that key).
  • MySQL: attemptConnect(enforceSSL:) extracted from connect(). 2-pass only fires for .preferred; .required/.verifyCa/.verifyIdentity keep single-pass with strict enforce. SSL-only retry codes are conservative (excludes timeouts, auth fails, network errors).

Test plan

  • Build with xcodebuild (NIOSSL import in Oracle plugin compiles)
  • Oracle: connect to Oracle Autonomous Database via TCPS with Required mode — should succeed (was failing before)
  • Oracle: connect to Oracle XE local with Disabled mode — should still work
  • Oracle: connect to Oracle Autonomous Database with Verify Identity + wrong CA — should fail with cert chain error
  • Cassandra: connect to AstraDB / DataStax with Required mode — should succeed (was failing before)
  • Cassandra: connect to local Cassandra without SSL — should still work
  • Cassandra: existing connection that previously set sslCaCertPath via the custom field — CA path should appear in standard SSL pane after upgrade
  • MySQL: connect to Cloud SQL with Preferred mode — should succeed via 2-pass (try TLS, succeed)
  • MySQL: connect to local Docker MySQL (no TLS) with Preferred mode — should succeed via 2-pass (try TLS, fall back to plain)
  • MySQL: connect with wrong password and Preferred mode — should fail immediately, not retry (auth error 1045 not in retry set)
  • MySQL: connect to Cloud SQL with Required mode — should succeed with enforce=1, no retry
  • Run xcodebuild test -only-testing:TableProTests/DatabaseTypeTests — MySQL/MariaDB tests now expect .preferred

Base automatically changed from fix/postgres-rds-ssl-default-1298 to main May 18, 2026 04:11
@datlechin datlechin force-pushed the refactor/ssl-all-drivers branch from b755fac to ed5c8a1 Compare May 18, 2026 04:11
@datlechin datlechin force-pushed the refactor/ssl-all-drivers branch from 397e777 to e593ed4 Compare May 18, 2026 04:28
@datlechin datlechin merged commit ded6909 into main May 18, 2026
2 checks passed
@datlechin datlechin deleted the refactor/ssl-all-drivers branch May 18, 2026 04:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant