Skip to content

fix(ssh): finalize config keyword support invariant - #309

Merged
inureyes merged 3 commits into
mainfrom
feature/issue-281-ssh-config-runtime
Aug 30, 2026
Merged

inureyes merged 3 commits into
mainfrom
feature/issue-281-ssh-config-runtime

Conversation

@inureyes

Copy link
Copy Markdown
Member

Summary

  • Remove the temporary Delegated SSH-config support state and enforce the exact accepted-keyword invariant: 91 spellings = 51 runtime + 40 unimplemented.
  • Share canonical diagnostic deduplication across configuration files, includes, and -o overlays while preserving the first real source location.
  • Accept repeated OpenSSH -t flags and preserve last-option-wins behavior between -t and -T.
  • Escape control characters in SSH-config paths, patterns, unknown keywords, cache errors, include errors, validation errors, and tracing output without changing printable Unicode or the values used for security checks.
  • Distinguish CLI diagnostics as -o option #N rather than ambiguous source lines.

Security review

Independent review reproduced log-line and ANSI injection through control characters in config paths. The final implementation centralizes output-boundary escaping, covers successful parsing and load-error paths, and leaves raw path values intact for validation and policy decisions.

The final re-audit found no CRITICAL, HIGH, or MEDIUM findings.

Validation

  • SSH-config diagnostic output: 12/12
  • Parser: 123/123
  • Include handling: 13/13
  • SSH-config security: 18/18
  • Config cache: 14/14
  • Registry invariant: 3/3
  • CLI TTY precedence: 6/6
  • Authentication, session, transport, forwarding, host-key, source/QoS, and automatic-rekey focused suites: pass
  • cargo check --locked --lib --bins --tests
  • scoped Clippy with -D warnings
  • cargo fmt --check
  • git diff --check

The integrated OpenSSH named run is 14 pass / 3 fail / 2 environmental / 1 skip. The remaining candidate failures require -G from #282 (percent, rekey) and -n from #285 (dynamic-forward). The key-options case now passes after the repeated -t fix.

Tracker status

This PR intentionally references rather than closes #281. The tracker requires the named regress set to pass, so it will remain open until #282 and #285 remove the three known blockers and the integrated set is rerun.

Refs #281

Collapse accepted SSH config keyword support into Runtime or Unimplemented, audit the exact 91-spelling registry, and preserve shared diagnostic provenance and deduplication across config files and -o overlays.

Allow repeated OpenSSH -t flags while retaining boolean runtime consumers and last-option-wins precedence against -T, restoring the key-options regression case.

Validated with focused registry, parser, resolver, diagnostics, CLI, authentication, session, transport, forwarding, host-key, source/QoS, rekey, and OpenSSH named regression tests, plus format, check, and Clippy gates.

Refs #281
SSH config filenames and unknown keywords are untrusted diagnostic fields. Rendering control characters verbatim allowed newline injection and ANSI terminal manipulation in stderr or -E logs.

Escape every Unicode control character at the output boundary while preserving printable Unicode, and model config lines versus -o options explicitly so CLI diagnostics identify `-o option #N`.

Add unit and end-to-end regressions covering control escaping, printable Unicode, malicious newline filenames, ANSI-bearing unknown keywords, single-line log integrity, and ordinary provenance.

Refs #281
SSH config path failures were still rendered through raw Path::display calls across cache loading, include resolution, and path validation. A newline-bearing missing -F path could inject forged -E log lines despite parser warning escaping.

Move control escaping to a crate-visible SSH config diagnostic helper and reuse it at every user-visible path and pattern context in the SSH config and cache modules. The helper returns Cow so ordinary printable UTF-8 remains unchanged and allocation-free.

Add an end-to-end missing-path regression alongside the existing warning-path coverage, and audit remaining raw display calls as test-only fixture construction.

Refs #281
@inureyes inureyes added type:enhancement New feature or request status:review Under review priority:high High priority issue labels Aug 30, 2026
@inureyes
inureyes merged commit 87411e6 into main Aug 30, 2026
5 checks passed
@inureyes
inureyes deleted the feature/issue-281-ssh-config-runtime branch August 30, 2026 10:42
@inureyes inureyes added status:done Completed and removed status:review Under review labels Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority:high High priority issue status:done Completed type:enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(ssh_config): wire the parsed-but-unused ssh_config keywords

1 participant