Skip to content

[P0][security] SSH tunnel stored but never used; no ssh2 dependency; ARCHITECTURE §3.1 SSHTunnel unimplemented #273

Description

@EVWorth

Context

DESIGN_REQUIREMENTS §FR-1.2.1 and ARCHITECTURE §3.1 promise SSH tunnel support (RSA/Ed25519/ECDSA, password or private-key auth, configurable port). The connection dialog exposes the full SSH form, the profile persists the config to SQLite, and the field is documented as a feature. But the backend never reads profile.ssh_config and the ssh2 crate is absent from every Cargo.toml.

Problem

ConnectionManager::connect (src-tauri/crates/mas-core/src/connection/manager.rs) uses only direct MySQL host/port, ignoring profile.ssh_config. A user who fills the SSH tab and clicks Connect connects straight to the raw DB host; if the SSH port differs from the DB port, the connection hits the SSH server on the DB port and fails with a confusing timeout. CoreError::SSH exists but is unreachable. ARCHITECTURE's SSHTunnel sub-component is design-only.

Files

  • src-tauri/crates/mas-core/src/connection/manager.rs:26-135
  • src-tauri/crates/mas-core/Cargo.toml (no ssh2 dep)
  • src-tauri/src/commands/mod.rs (no SSH bridge)
  • src/components/connection/ConnectionDialog.tsx:379-481 (UI form)
  • src-tauri/crates/mas-core/src/connection/store.rs:53-56, 126, 185 (ssh_config persisted)

Repro

  1. Create a profile with SSH host/port filled, DB host/port pointing to a real MySQL.
  2. Save → Connect.
  3. Observe: connection fails or succeeds without an SSH tunnel; logs do not mention SSH.

Expected

Connection opens via the configured SSH tunnel; logs include "Establishing SSH tunnel to <ssh_host>:<ssh_port>"; the MySQL client connects to 127.0.0.1:<local_port>.

Proposed fix

Scope L. Add ssh2 = "..." to mas-core/Cargo.toml. Implement SshTunnel per ARCHITECTURE §3.1: ssh2::Session::connect with password or private_key_path + passphrase, local_port_forward to remote DB. Rewrite ConnectionManager::connect so that when profile.ssh_config.is_some(), host/port are rewritten to 127.0.0.1:local_port and the tunnel is dropped when the pool is dropped. Land the integration test test_connect_with_ssh_tunnel that TESTING_STRATEGY §4 already names.

Acceptance

Connecting to a profile with ssh_config opens a tunnel and reaches MySQL through it. Direct (non-SSH) connections remain unchanged. The connection banner in StatusBar shows a small 🔒 icon.

Needs human verify

Yes (static analysis only — needs manual SSH target to confirm wire behaviour).

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/connectionAudit areaauditTracks a feature-by-feature codebase audit findingkind/doc-driftAudit finding categorykind/securityAudit finding categoryseverity/p0Audit finding severity

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions