Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 91 additions & 72 deletions Cargo.lock

Large diffs are not rendered by default.

52 changes: 26 additions & 26 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,58 +23,58 @@ edition = "2024"
rust-version = "1.97"

[dependencies]
bytes = "1.11.1"
tokio = { version = "1.52.3", features = ["full"] }
# Upstream russh. 0.64 includes the hostkeys-prove support and the post-auth
bytes = "1.12.1"
tokio = { version = "1.54.1", features = ["full"] }
# Upstream russh. 0.64+ includes the hostkeys-prove support and the post-auth
# rekey limit fixes bssh previously carried in an internal fork.
# `client::Handler::check_server_key` receives `PublicKeyOrCertificate`, and
# host certificates are opt-in. bssh leaves `Preferred::host_key_certificates`
# empty, so it never negotiates one; the handler in
# src/ssh/tokio_client/connection.rs refuses certificates because bssh
# verifies no CA signatures.
russh = "0.64.1"
russh = "0.65.0"
# Upstream russh-sftp. bssh's pipelined client transfers live in
# src/ssh/tokio_client/sftp_client.rs and its read-ahead / write-coalescing
# server loop in src/server/sftp_loop.rs, both on russh-sftp's public API.
russh-sftp = "3.0.1"
clap = { version = "4.6.1", features = ["derive", "env"] }
anyhow = "1.0.102"
thiserror = "2.0.18"
clap = { version = "4.6.7", features = ["derive", "env"] }
anyhow = "1.0.104"
thiserror = "2.0.21"
tracing = "0.1.44"
tracing-subscriber = { version = "0.3.23", features = ["env-filter"] }
serde = { version = "1.0.228", features = ["derive"] }
serde = { version = "1.0.229", features = ["derive"] }
serde_yaml = "0.9"
futures = "0.3.32"
async-trait = "0.1.89"
indicatif = "0.18.4"
rpassword = "7.4.0"
futures = "0.3.34"
async-trait = "0.1.92"
indicatif = "0.18.6"
rpassword = "7.5.4"
dirs = "7.0"
chrono = { version = "0.4.44", features = ["serde"] }
glob = "0.3.3"
whoami = "2.1.1"
chrono = { version = "0.4.45", features = ["serde"] }
glob = "0.3.4"
whoami = "2.1.3"
sha1 = "0.11.0"
owo-colors = "4.3.0"
unicode-width = "0.2.2"
owo-colors = "4.4.0"
unicode-width = "0.2.3"
terminal_size = "0.4.4"
zeroize = { version = "1.8.2", features = ["derive"] }
zeroize = { version = "1.9.1", features = ["derive"] }
secrecy = { version = "0.10.3", features = ["serde"] }
rustyline = "19.0.0"
crossterm = "0.29"
ratatui = "0.30"
regex = "1.12.3"
regex = "1.13.1"
signal-hook = "0.4"
nix = { version = "0.31", features = ["fs", "poll", "process", "signal", "term"] }
smallvec = "1.15.1"
smallvec = "1.16.4"
lru = "0.19.0"
uuid = { version = "1.23.1", features = ["v4"] }
tokio-util = "0.7.18"
uuid = { version = "1.29.0", features = ["v4"] }
tokio-util = "0.7.20"
socket2 = { version = "0.6", features = ["all"] }
shell-words = "1.1.1"
base64 = "0.23.1"
hmac = "0.13.0"
hkdf = "0.13.0"
sha2 = "0.11.0"
hickory-resolver = { version = "0.26.1", features = ["dnssec-ring"] }
sha2 = "0.11.1"
hickory-resolver = { version = "0.26.3", features = ["dnssec-ring"] }
libc = "0.2"
# sk-api (FIDO security key) middleware libraries are dlopened in process;
# see src/ssh/security_key for why no ssh-sk-helper style subprocess exists.
Expand All @@ -93,7 +93,7 @@ ipnetwork = "0.21"
bcrypt = "0.19"
argon2 = "0.6"
rand = "0.10"
# Pinned to match russh's ssh-key (0.64.x uses =0.7.0-rc.11) so the workspace
# Pinned to match russh's ssh-key (0.65.x uses =0.7.0-rc.11) so the workspace
# resolves a single ssh-key version instead of 0.6 + 0.7-rc side by side.
ssh-key = { version = "=0.7.0-rc.11", features = ["std"] }
async-compression = { version = "0.4", features = ["tokio", "gzip"] }
Expand Down Expand Up @@ -128,7 +128,7 @@ tempfile = "3.27.0"
mockito = "1.7.2"
tokio-test = "0.4"
serial_test = "4.0.1"
insta = "1.47"
insta = "1.49"
criterion = { version = "0.8", features = ["html_reports"] }
mockall = "0.15.0"

Expand Down
3 changes: 2 additions & 1 deletion docs/architecture/ssh-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
**Tokio Client Module Structure :**
- `tokio_client/connection.rs` - Connection management (293 lines)
- `tokio_client/authentication.rs` - Authentication methods (378 lines)
- `tokio_client/security_key_signer.rs` - russh `Signer` for FIDO `sk-*` identities: resolves `SecurityKeyProvider`, checks the provider before decrypting an `sk-*` key file, calls the provider on a blocking thread (serialized process-wide), prints the touch notice, prompts once for a PIN, and declines a failed signature so authentication continues with the next identity (`authenticate_declinable`)
- `tokio_client/authentication.rs` and `tokio_client/connection.rs` - agent session binding: every agent connection is bound with `session-bind@openssh.com` before use, with the forwarding flag clear for direct authentication and set for relayed forwarded-agent connections; an agent's refusal is not fatal, and a timeout abandons that connection
- `tokio_client/security_key_signer.rs` - russh `Signer` for FIDO `sk-*` identities: resolves `SecurityKeyProvider`, checks the provider before decrypting an `sk-*` key file, calls the provider on a blocking thread (serialized process-wide), prints the touch notice, prompts once for a PIN, and returns signing failures to russh, which abandons the request so authentication continues with the next identity
- `ssh/security_key/` - provider interface (`SecurityKeyProvider` trait, `$VAR` resolution, `internal`/`none` handling), the `sk-api.h` `dlopen` binding (`external.rs`), the `sk-*` signature blob encoder (`signature.rs`), and the built-in provider (`internal/`: `ctaphid.rs` framing and channels over a `HidDevice` trait, `cbor.rs`, `ctap2.rs`, `u2f.rs`, `pin_protocol.rs` for PIN protocols 1 and 2, `device.rs` for one authenticator's `getAssertion`, `select.rs` for `sk_probe`-style device selection, `hidapi_backend.rs` as the only OS-facing file, and `mock.rs` as the scripted test authenticator). The built-in provider exists on Linux and macOS only; elsewhere `internal` fails with a "not available on this platform" error
- `tokio_client/host_key_type.rs` - refuses a server host key or certificate whose type differs from the negotiated host-key algorithm (OpenSSH `kex_verify_host_key`), including `sk-*` types and ECDSA curves
- `tokio_client/channel_manager.rs` - Channel operations (230 lines)
Expand Down
Loading
Loading