You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Summary
- Execute resolved `ProxyCommand` values as managed shell child transports instead of silently opening a direct target socket.
- Match OpenSSH proxy selection semantics across `ProxyCommand`, `ProxyJump`, command-line `-J`, explicit `none`, and effective `%h`/`%k`/`%n` token identities.
- Report bounded proxy stderr and exit status as actionable connection errors, and reject unsupported `ProxyUseFdpass` before spawning a process.
## Implementation
- Add a duplex async transport backed by child stdin/stdout with bounded stderr draining, exit monitoring, deterministic shutdown, and kill-on-drop lifecycle handling.
- Expand `%%`, `%h`, `%k`, `%n`, `%p`, and `%r`, reject malformed or unsupported tokens, and preserve shell pipes and quoting from trusted SSH configuration.
- Preserve the first-obtained SSH configuration semantics introduced by the related proxy and host-key changes, with command-line `-J` taking precedence.
- Silence only the official but unimplemented `SecurityKeyProvider` option while retaining diagnostics for genuinely unknown keywords.
- Preserve raw command exit codes after stdout and stderr and keep draining the SSH channel when the local output receiver closes, fixing integration failures exposed by the real proxy transport.
- Update user and manual documentation to describe the supported behavior and the explicit `ProxyUseFdpass` limitation.
## Security and quality review
- Reviewed shell-boundary validation, token expansion, direct-connection avoidance, child cleanup, stderr memory bounds, failure mapping, host-key alias identity, and early receiver-drop behavior; no unresolved CRITICAL or HIGH findings remain.
- Proxy commands remain an explicitly trusted SSH configuration shell boundary; target-derived tokens retain existing host and username validation, while NUL and newline injection and unsupported expansion tokens are rejected.
## Validation
- `cargo fmt --all -- --check`
- `cargo test --lib proxy` (29 passed)
- `cargo test --lib resolve_effective_jump_hosts` (11 passed)
- `cargo test --lib stream_exit` (2 passed)
- `cargo test --lib nonzero_stream_completion_preserves_remote_status` (1 passed)
- `cargo test --lib closed_output_receiver_is_not_a_command_error` (1 passed)
- `cargo test --test ssh_compat_output_test deprecated_alias_is_silent_and_unknown_keyword_uses_log_file -- --exact` (1 passed)
- `cargo check --lib --tests`
- `cargo clippy --lib --tests -- -D warnings`
- `cargo build --bin bssh`
- `cargo test --bin bssh` (57 passed)
- `TEST_SSH_UNSAFE_PERMISSIONS=1 python3 tests/openssh-regress/run.py --bssh target/debug/bssh --test proxy-connect --jobs 1 --timeout 120` (PASS, 1/1)
Local CI-equivalent note: `cargo test --tests -- --skip integration_test` passed the library tests (1420 passed, 9 ignored, 13 filtered), the bssh binary tests (57 passed), and the subsequent keygen/server and independent test targets until `tests/integration_test.rs`; three unchanged localhost SSH-dependent cases failed in the local harness (`test_localhost_multiple_file_upload`, `test_parallel_execution_with_multiple_nodes`, and `test_download_with_unique_filenames`). The PR's exact-head GitHub checks are the authoritative CI verdict for those environment-dependent cases.
Closes#280
Copy file name to clipboardExpand all lines: README.md
+8-14Lines changed: 8 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -874,11 +874,12 @@ These options control SSH proxy connection behavior:
874
874
875
875
| Option | Description | Example |
876
876
|--------|-------------|---------|
877
-
| **ProxyUseFdpass** | Pass connected file descriptor from ProxyCommand to ssh(1) instead of continuing execution (yes/no, default: no, OpenSSH 6.5+) | `ProxyUseFdpass yes` |
877
+
| **ProxyCommand** | Run a shell command whose stdin/stdout carry the SSH transport; supports `%%`, `%h`, `%k`, `%n`, `%p`, and `%r` | `ProxyCommand nc %h %p` |
878
+
| **ProxyUseFdpass** | Request descriptor passing from ProxyCommand (recognized but not supported by bssh) | `ProxyUseFdpass no` |
878
879
879
-
**ProxyUseFdpass** optimizes ProxyCommand usage by eliminating an unnecessary lingering process and reducing I/O overhead. When enabled, the proxy command passes the established connection file descriptor directly to ssh and exits, rather than remaining active to relay data throughout the session. This is particularly useful with proxy commands like netcat that support file descriptor passing (nc -F).
880
+
**ProxyCommand** uses the user's shell so OpenSSH-style quoting, redirection, and pipelines work. `ProxyCommand none` explicitly selects a direct connection. `ProxyCommand` and `ProxyJump` follow OpenSSH's first-obtained ssh_config rule, while command-line `-J` takes precedence over both.
880
881
881
-
*Note: This option is currently parsed from SSH configuration files for compatibility but is not yet utilized in bssh's SSH client implementation, as proxy connections are not yet supported.*
882
+
*Note: `ProxyUseFdpass yes` is rejected with an actionable error before the command starts. Use a streaming ProxyCommand without `-F`, or set `ProxyUseFdpass no`.*
0 commit comments