Enable SSH remotes in native frontends (#117)
This commit is contained in:
@@ -68,10 +68,13 @@ test requires an upstream executable at runtime.
|
||||
|
||||
The executable audit checks project Rust sources for process construction and
|
||||
permits it only in the editor adapter. Every project crate forbids unsafe Rust.
|
||||
Git repository configuration rejects executable helpers and all non-HTTPS,
|
||||
credential-bearing or rewritten remote forms before transport. Error and debug
|
||||
models redact secret bytes; CLI presentation tests assert clipboard, QR, OTP
|
||||
and generated values do not appear on unintended streams.
|
||||
Git repository configuration rejects executable helpers, unsupported schemes,
|
||||
credential-bearing URLs, and rewritten remote forms before transport. The
|
||||
normal CLI build accepts typed HTTPS, `ssh://`, and scp-like remotes. Unknown SSH
|
||||
hosts require an explicit fingerprint confirmation on standard error; encrypted
|
||||
keys use hidden terminal input and no command-line passphrase option. Error and
|
||||
debug models redact secret bytes; CLI presentation tests assert clipboard, QR,
|
||||
OTP, generated values, and SSH passphrases do not appear on unintended streams.
|
||||
|
||||
The activated dependency graph was reviewed with `cargo tree -e features` and
|
||||
`cargo metadata --locked`. Gix default features are disabled and only the
|
||||
|
||||
@@ -95,7 +95,8 @@ Private-key passphrases are stored by fingerprint in the operating-system
|
||||
secret store and never appear in TOML. IronStorage does not read OpenSSH
|
||||
configuration, try additional keys, prompt for passwords or
|
||||
keyboard-interactive authentication, launch an agent, or invoke proxy/helper
|
||||
commands. In builds with the `ssh` feature, the same configuration drives
|
||||
commands. The normal CLI, TUI, and desktop builds enable the storage `ssh`
|
||||
feature, so the same configuration drives
|
||||
branch discovery, clone, fetch, and pull over the embedded upload-pack channel;
|
||||
push and full pull-then-push synchronization use the matching embedded
|
||||
receive-pack channel.
|
||||
@@ -103,7 +104,10 @@ receive-pack channel.
|
||||
The typed endpoint model is always available so an SSH remote remains readable
|
||||
through the Rust API even when the binary was built without SSH. Such a build
|
||||
returns a typed unsupported-transport error before connection or repository
|
||||
mutation. The optional storage `ssh` feature contains `russh` 0.63.1 and Tokio;
|
||||
mutation. The Apple bridge explicitly enables the storage `full` feature set
|
||||
without `ssh`, keeping the iPhone, AutoFill, and Watch dependency graph
|
||||
HTTPS-only until an Apple target opts in. The optional storage `ssh` feature
|
||||
contains `russh` 0.63.1 and Tokio;
|
||||
`russh` default features are disabled and the Ring backend plus RSA key support
|
||||
are selected explicitly.
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ remain native-host smoke checks because CI cannot emulate those OS services.
|
||||
| Authentication expiry | Storage authentication leases own the clock and policy. Passive ticks, rendering, pointer movement, and window events do not renew activity; deterministic tests cover expiry during protected state. |
|
||||
| Dirty documents and conflicts | Every entry/vault/window/Git worktree replacement routes through one Save/Discard/Cancel decision. Failed saves and conflicts keep the complete draft. |
|
||||
| Background and window lifecycle | Generation counters reject stale asynchronous results. Lock cancels Git/clipboard work and clears OTP, QR, URI, entry, and editor state. Close and quit use the same dirty guard. |
|
||||
| Repository and domain ownership | The executable source audit rejects repository/Git construction, process launch, OTP/QR parsing, filesystem writes, unsafe blocks, and non-HTTPS literals in production desktop modules. The folder picker may read only a user-selected QR image; all password-store I/O remains in `crates/storage`. |
|
||||
| Repository and domain ownership | The executable source audit rejects repository/Git construction, process launch, OTP/QR parsing, filesystem writes, unsafe blocks, and insecure HTTP literals in production desktop modules. HTTPS and SSH endpoint parsing, host trust, authentication, and protocol behavior remain in `crates/storage`; desktop only presents typed state and native confirmation or masked-passphrase prompts. The folder picker may read only a user-selected QR image; all password-store I/O remains in `crates/storage`. |
|
||||
|
||||
Run the complete repository gate after the desktop-specific checks:
|
||||
|
||||
|
||||
@@ -60,6 +60,15 @@ commands. SHA-1 host signatures and `ssh-rsa` authentication are excluded.
|
||||
Cancellation interrupts connection and authentication without changing Git,
|
||||
known hosts, or secure storage.
|
||||
|
||||
The standard CLI, TUI, and desktop applications compile this transport and pass
|
||||
their Git actions through storage's typed endpoint selection. They display both
|
||||
SSH URL forms without reparsing them. An unknown key opens an explicit native
|
||||
confirmation showing the host, port, algorithm, and fingerprint; a changed key
|
||||
is a non-bypassable error. Encrypted-key prompts use hidden or masked input and
|
||||
retain a supplied passphrase only after SSH authentication and the requested Git
|
||||
operation succeed. Cancelling either prompt leaves the repository, known hosts,
|
||||
and secure storage unchanged.
|
||||
|
||||
## SSH upload-pack
|
||||
|
||||
With the same feature enabled, branch discovery, clone, fetch, and pull open a
|
||||
@@ -110,3 +119,6 @@ counts, pack checksums, non-fast-forward behavior, and server status. SSH tests
|
||||
use a pure-Rust in-process Russh server and upload-pack fixture to exercise
|
||||
chunked reference and pack streams, end-to-end clone/fetch/pull, command
|
||||
quoting, cancellation, and rollback without an external Git or SSH executable.
|
||||
Frontend tests cover typed transport display, prompt masking and cancellation,
|
||||
retry routing, conflicts, authentication failures, and successful HTTPS
|
||||
regression paths without duplicating protocol logic.
|
||||
|
||||
@@ -49,7 +49,11 @@ caller explicitly selects `SecretCachePolicy::Timed`. Timed policies are capped
|
||||
at 128 entries and 15 minutes, expire lazily, and are always cleared on lock.
|
||||
|
||||
The same unlocked store implements the OpenPGP `SecretProvider`, HTTPS Git
|
||||
`GitCredentialProvider`, and SSH `SshPassphraseProvider`. The CLI uses it for
|
||||
terminal `show` and embedded Git, proving that protected keys and remote
|
||||
authentication are resolved only through opaque references. Tests inject a
|
||||
memory backend and never access a developer or CI user keyring.
|
||||
`GitCredentialProvider`, and SSH `SshPassphraseProvider`. CLI, TUI, and desktop
|
||||
pass one prompted SSH passphrase as zeroizing bytes for one retry. Storage binds
|
||||
that override to the requested key fingerprint, and the authentication handle
|
||||
persists it only after the Git operation succeeds; cancellation, rejection, and
|
||||
other failures never create or replace a record. Prompts are hidden or masked,
|
||||
and secret values are excluded from arguments, history, normal output, debug
|
||||
models, notifications, and the clipboard. Tests inject a memory backend and
|
||||
never access a developer or CI user keyring.
|
||||
|
||||
Reference in New Issue
Block a user