Resolve ~/.ssh/config aliases and authenticate via ssh-agent - #1
Open
kirisame-meguru wants to merge 1 commit into
Open
Resolve ~/.ssh/config aliases and authenticate via ssh-agent#1kirisame-meguru wants to merge 1 commit into
kirisame-meguru wants to merge 1 commit into
Conversation
russh speaks the protocol only: it reads no client config and never talks to the agent, so both connect tools demanded an explicit host, username and a password or key path. A host that plain `ssh <alias>` reaches with no arguments could not be reached here without restating its whole configuration, and agent-only setups (hardware keys, forwarded agents) could not connect at all. Add src/ssh_config.rs, shared by the server-ops and interactive paths: - lookup() asks the local OpenSSH client for its own answer (`ssh -G <host>`) and reads HostName/User/Port/IdentityFile off it, so Host *and* Match blocks, Includes, wildcards, percent tokens, canonicalization and OpenSSH's built-in defaults behave exactly as they do for ssh itself, with no config parser to keep in sync. No ssh on PATH, or a config ssh refuses to load, degrades to the local account name rather than failing the connect. - authenticate() runs one auth ladder: password, then each identity file that exists on disk, then every identity the agent holds (SSH_AUTH_SOCK, or the OpenSSH named pipe on Windows). RSA keys are signed with the hash the server advertises in server-sig-algs, so they still work against OpenSSH 8.8+. Failures report every method tried and why. ssh_connect now takes `host` alone (username/port/key optional, `useAgent` to opt out); `connect` resolves the same way, using the session name as the alias when no host is given, and keeps precedence explicit args > hosts.toml > ~/.ssh/config. No new dependencies: resolution is a subprocess and the agent client ships with russh. The auth future is boxed with an explicit Send bound: awaiting a generic async fn inside an rmcp #[tool] handler otherwise trips rust#102211.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ssh_connect { "host": "prod-web" }works whereverssh prod-webdoes.src/ssh_config.rs(new), shared byssh_connectandconnect:lookup()— runsssh -G <host>, reads HostName/User/Port/IdentityFile.Host/Match,Include, wildcards, percent tokens, canonicalization and OpenSSH defaults come free. Nosshon PATH → local account name only, connect still proceeds.authenticate()— password → each existing IdentityFile → every ssh-agent identity (SSH_AUTH_SOCK, or\\.\pipe\openssh-ssh-agenton Windows). RSA signed with the hash fromserver-sig-algs(OpenSSH 8.8+). Errors list every method tried and why.API
ssh_connect:username/port/privateKeyPathnow optional;useAgent(default true).connect: same, sessionnameused as alias whenhostis omitted. Precedence: explicit args >hosts.toml>~/.ssh/config.SshAuth.key_path: Option<&Path>→identity_files: Vec<PathBuf>, plususe_agent.Notes
Cargo.toml/Cargo.lockunchanged.src/ssh_config.rs; skip themselves whensshis absent.authenticate()returns a boxedSendfuture — genericasync fnawaited in an rmcp#[tool]handler trips rust#102211.cargo fmtrun: tree isn't rustfmt-clean, kept the diff to the change.