fix: asking for reprompt - #356
Closed
soraxas wants to merge 274 commits into
Closed
Conversation
…EntryData and rename structures around
Display logic has been transferred inside db, but it's temporary as it needs to be decoupled too.
…tr> instead of FromStr
written with AI, verified and fixed by OI (Organic Intelligence)
…id downcasting errors
exchange_refresh_token and exchange_refresh_token_async were calling
json_with_path() directly on the response without first checking the
HTTP status. A 4xx from the identity server (e.g. {"error":"invalid_grant"})
was therefore parsed as ConnectRefreshTokenRes, failing with a cryptic
"missing field `access_token`" JSON error instead of surfacing the actual
HTTP status.
Bitwarden (and Vaultwarden) rotate the refresh token on every exchange: alongside the new access_token, the server returns a new refresh_token and immediately invalidates the old one. ConnectRefreshTokenRes only captured access_token, so the stored refresh token became stale after the first refresh cycle. The next sync would attempt to use the already-rotated token and receive HTTP 400 invalid_grant, surfacing as "api request returned error: 400". Fix: capture refresh_token in ConnectRefreshTokenRes, thread it back through with_exchange_refresh_token_async (return type expands from (Option<String>, T) to (Option<String>, Option<String>, T)), and persist it in Db via a new update_refresh_token method. All six public action functions (sync, add, edit, remove, list_folders, create_folder) and their callers in both the agent and the rbw binary are updated. Also adds body logging to client::sync() on non-2xx responses so future failures surface the server's error body alongside the status code.
Signed-off-by: Tin Lai <tin@tinyiu.com>
Folder names are encrypted with the local user vault key, even for organization entries. Passing the entry context sent org/item keys to the agent, which caused invalid MAC failures during list/search for entries in folders.
There was a problem hiding this comment.
Pull request overview
This PR is a broad refactor of rbw that modernizes the agent/client architecture (moving more logic into the daemon and making components async), updates crypto/session handling, and introduces optional SSH-signature confirmation via pinentry.
Changes:
- Refactors the agent into a new async
agentmodule with cached DB state, deadline-based lock/sync timers, and broadcast-based notifications. - Reworks pinentry and locked-memory handling (new
LockedVec), and threads new crypto/session parameter structs through login/unlock flows. - Adds optional
confirm_sshbehavior for SSH-agent signing plus Nix flake/devshell support and various cleanup/formatting updates.
Reviewed changes
Copilot reviewed 41 out of 44 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/search.rs |
Adds a shared Needle type with parsing/display for search/find inputs. |
src/pwgen.rs |
Formatting-only simplifications in password generation. |
src/protocol.rs |
Fixes protocol version calculation; refactors environment variable handling/types. |
src/pinentry.rs |
Major rewrite of pinentry interaction: streaming parser, percent decode helpers, and new confirm flow. |
src/locked.rs |
Replaces the old locked vector type with LockedVec based on a fixed-size locked buffer. |
src/lib.rs |
Exposes the new search module. |
src/json.rs |
Simplifies JSON-with-path helpers; async path now relies on From<reqwest::Error>. |
src/identity.rs |
Switches identity derivation to use CryptoParameters and LockedVec. |
src/error.rs |
Adds new error variants and From conversions (I/O, UTF-8, reqwest). |
src/edit.rs |
Refactors editor invocation; improves error propagation and reduces allocations. |
src/dirs.rs |
Makes directory/file helpers fallible (Result<PathBuf>) instead of panicking. |
src/config.rs |
Adds confirm_ssh config knob; updates load/save paths to new dirs results. |
src/cipherstring.rs |
Updates locked decrypt return types and cleans up symmetric/asymmetric handling. |
src/bin/rbw/sock.rs |
Updates socket path retrieval for new fallible dirs APIs. |
src/bin/rbw/main.rs |
Makes client CLI async; refactors command wiring and completion generation. |
src/bin/rbw/actions.rs |
Simplifies client/agent request sending; adjusts log-path handling for fallible dirs. |
src/bin/rbw-agent/sock.rs |
Updates agent socket binding to use fallible dirs APIs. |
src/bin/rbw-agent/notifications.rs |
Replaces per-subscriber channel list with tokio::sync::broadcast and adds disconnect signaling. |
src/bin/rbw-agent/main.rs |
Replaces old agent/state/timeout modules with the new agent implementation and signal handling. |
src/bin/rbw-agent/debugger.rs |
Formatting-only adjustments to tracing/core-dump error messages. |
src/bin/rbw-agent/daemon.rs |
Updates pid/log file paths for new fallible dirs APIs. |
src/bin/rbw-agent/agent/ssh_agent.rs |
Reworks SSH agent integration to call into new Agent and adds optional confirmation. |
src/bin/rbw-agent/agent/mod.rs |
New central async Agent implementation (state, deadlines, notifications, request routing). |
src/bin/rbw-agent/agent/actions.rs |
New agent action handlers (login/unlock/sync/crypto/reprompt/ssh-key lookup). |
src/bin/rbw-agent/timeout.rs |
Removed (replaced by deadline-based logic in the new agent). |
src/bin/rbw-agent/state.rs |
Removed (state moved into the new agent internals). |
src/bin/rbw-agent/agent.rs |
Removed (replaced by src/bin/rbw-agent/agent/mod.rs). |
src/bin/rbw-agent/actions.rs |
Removed (replaced by src/bin/rbw-agent/agent/actions.rs). |
src/base64.rs |
Minor formatting cleanup. |
src/api/mod.rs |
New API models/enums and sync/login parsing logic (replacing older API layer). |
src/api/client.rs |
New async HTTP client implementation (reqwest/axum-based SSO callback flow). |
src/actions.rs |
Reworks public actions layer around new async API client and new session/crypto structs. |
shell.nix |
Adds a Nix dev shell definition for Rust tooling and pinentry. |
flake.nix |
Adds flake wiring (currently exposes a placeholder default package). |
flake.lock |
Locks nixpkgs input. |
README.md |
Documents fork status and the new confirm_ssh option. |
CHANGELOG.md |
Records the refactor, new options, and dependency removals. |
Cargo.toml |
Bumps version, adjusts deps/features (e.g., removes arrayvec/is-terminal/tokio-stream). |
Cargo.lock |
Updates lockfile for dependency changes. |
.rustfmt.toml |
Updates rustfmt settings (newline style). |
.github/workflows/tests.yaml |
Minor formatting tweak. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+218
to
+222
| pinentry.command("CONFIRM").await?; | ||
|
|
||
| pinentry.wait().await?; | ||
|
|
||
| Ok(true) |
Comment on lines
+32
to
+33
| // NOTE: This panics if the line is > 4096 bytes | ||
| v.push(b); |
Comment on lines
146
to
150
| self.env_vars | ||
| .iter() | ||
| .map(|(var, val)| (var.0.clone(), val.0.clone())) | ||
| .filter(|(var, _)| (*ENVIRONMENT_VARIABLES_OS).contains(var)) | ||
| .map(|(var, val)| (var.0.as_os_str(), val.0.as_os_str())) | ||
| .filter(|(var, _)| (ENVIRONMENT_VARIABLES_OS).contains(&var.to_os_string())) | ||
| .collect() |
Comment on lines
+192
to
+196
| pinentry.command("SETTITLE rbw").await?; | ||
| pinentry.command(&format!("SETPROMPT {prompt}")).await?; | ||
| pinentry.command(&format!("SETDESC {desc}")).await?; | ||
|
|
||
| if let Some(err) = err { |
Comment on lines
+8
to
+17
| outputs = | ||
| { self, nixpkgs }: | ||
| { | ||
|
|
||
| packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hello; | ||
|
|
||
| packages.x86_64-linux.default = self.packages.x86_64-linux.hello; | ||
| devShells.x86_64-linux.default = import ./shell.nix { pkgs = nixpkgs.legacyPackages.x86_64-linux; }; | ||
|
|
||
| }; |
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.
No description provided.