Repository navigation
fix(ssh_config): execute ProxyCommand instead of parsing and discarding it #280
Description
Part of the OpenSSH drop-in compatibility epic.
Problem
ProxyCommand is parsed at src/ssh/ssh_config/parser/options/proxy.rs:39, security-validated in src/ssh/ssh_config/security/string_validation.rs, merged by the resolver at src/ssh/ssh_config/resolver.rs:111, and documented as supported in both README.md (lines 1012-1022) and docs/man/bssh.1 (line 1053). It is never executed. The identifier proxy_command does not appear anywhere outside src/ssh/ssh_config/, and unlike ProxyJump, which reaches the jump chain through SshConfig::get_proxy_jump at src/app/initialization.rs:374, there is no accessor for it at all.
The user-visible consequence is a silent security failure: a configuration that says traffic must traverse a bastion or a SOCKS relay connects directly to the target instead, and nothing warns. Documentation that promises the feature makes this worse, because an operator has no reason to check.
It is also the largest single blocker for the regression suite. README.regress describes the suite as "network or proxycommand based tests"; test-exec.sh:888 generates $OBJ/ssh_proxy carrying a proxycommand line, and the majority of connection-level tests run over that config rather than over TCP. proxy-connect fails today with ssh proxyconnect comp=no failed.
Scope
- Execute the resolved
ProxyCommandas a child process and use its stdin and stdout as the transport for the SSH session, instead of opening a socket to the target. - Apply the
%h,%p,%r,%nand related token expansions before execution, and run the command through a shell the way OpenSSH does, since real-world values contain pipes and quoting. - Honor
ProxyCommand noneas an explicit disable. - Define the precedence between
ProxyCommand,ProxyJumpand-Jto match OpenSSH, where the most recently obtained value wins and-Jon the command line overrides both. - Propagate the child's exit and its stderr into bssh's diagnostics so a failing proxy is reported as such rather than as a generic connection error.
- Wire
ProxyUseFdpass, whichREADME.mdalso documents, or reject it as unimplemented. It must not stay in the silently-parsed state that caused this issue.
Acceptance criteria
- A config with
ProxyCommandroutes the session through the child process, verified by a test that would fail if the connection were direct. - Token expansion is covered by tests, including a command containing a pipe.
- A failing or missing proxy command produces a diagnostic naming the command and its exit status.
-
ProxyCommandandProxyJumpprecedence matches OpenSSH. - The regress test
proxy-connectpasses in the harness, and the connection-level tests that run over$OBJ/ssh_proxybecome reachable.
Part of #275
Activity
fix: preserve single-host output bytes (#283) (#291)
fix: execute ProxyCommand transport (#293)
feat: add SSH config runtime foundation (#295) (#302)