1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-08 03:23:50 +00:00

[PM-14863] Force unlock when keys are cleared / on first unlock and fix account switching behavior (#11994)

* Force unlock when keys are cleared / on first unlock and fix account switching behavior

* Make comment a doc comment

* Pin russh commit

* Cleanup

* Make list messaging explicit

* Add account switching error handling for ssh agent

* Add account switching error handling for ssh agent

* Cleanup
This commit is contained in:
Bernd Schoolmann
2024-12-02 11:55:56 +01:00
committed by GitHub
parent 36750b374e
commit 050417a92e
10 changed files with 125 additions and 35 deletions

View File

@@ -17,9 +17,11 @@ pub mod importer;
pub struct BitwardenDesktopAgent {
keystore: ssh_agent::KeyStore,
cancellation_token: CancellationToken,
show_ui_request_tx: tokio::sync::mpsc::Sender<(u32, String)>,
show_ui_request_tx: tokio::sync::mpsc::Sender<(u32, (String, bool))>,
get_ui_response_rx: Arc<Mutex<tokio::sync::broadcast::Receiver<(u32, bool)>>>,
request_id: Arc<Mutex<u32>>,
/// before first unlock, or after account switching, listing keys should require an unlock to get a list of public keys
needs_unlock: Arc<Mutex<bool>>,
is_running: Arc<tokio::sync::Mutex<bool>>,
}
@@ -33,8 +35,30 @@ impl ssh_agent::Agent for BitwardenDesktopAgent {
let request_id = self.get_request_id().await;
let mut rx_channel = self.get_ui_response_rx.lock().await.resubscribe();
let message = (request_id, (ssh_key.cipher_uuid.clone(), false));
self.show_ui_request_tx
.send((request_id, ssh_key.cipher_uuid.clone()))
.send(message)
.await
.expect("Should send request to ui");
while let Ok((id, response)) = rx_channel.recv().await {
if id == request_id {
return response;
}
}
false
}
async fn can_list(&self) -> bool {
if !*self.needs_unlock.lock().await{
return true;
}
let request_id = self.get_request_id().await;
let mut rx_channel = self.get_ui_response_rx.lock().await.resubscribe();
let message = (request_id, ("".to_string(), true));
self.show_ui_request_tx
.send(message)
.await
.expect("Should send request to ui");
while let Ok((id, response)) = rx_channel.recv().await {
@@ -75,6 +99,8 @@ impl BitwardenDesktopAgent {
let keystore = &mut self.keystore;
keystore.0.write().expect("RwLock is not poisoned").clear();
*self.needs_unlock.blocking_lock() = false;
for (key, name, cipher_id) in new_keys.iter() {
match parse_key_safe(&key) {
Ok(private_key) => {
@@ -119,6 +145,14 @@ impl BitwardenDesktopAgent {
Ok(())
}
pub fn clear_keys(&mut self) -> Result<(), anyhow::Error> {
let keystore = &mut self.keystore;
keystore.0.write().expect("RwLock is not poisoned").clear();
*self.needs_unlock.blocking_lock() = true;
Ok(())
}
async fn get_request_id(&self) -> u32 {
if !*self.is_running.lock().await {
println!("[BitwardenDesktopAgent] Agent is not running, but tried to get request id");

View File

@@ -14,7 +14,7 @@ use super::BitwardenDesktopAgent;
impl BitwardenDesktopAgent {
pub async fn start_server(
auth_request_tx: tokio::sync::mpsc::Sender<(u32, String)>,
auth_request_tx: tokio::sync::mpsc::Sender<(u32, (String, bool))>,
auth_response_rx: Arc<Mutex<tokio::sync::broadcast::Receiver<(u32, bool)>>>,
) -> Result<Self, anyhow::Error> {
let agent = BitwardenDesktopAgent {
@@ -23,6 +23,7 @@ impl BitwardenDesktopAgent {
show_ui_request_tx: auth_request_tx,
get_ui_response_rx: auth_response_rx,
request_id: Arc::new(tokio::sync::Mutex::new(0)),
needs_unlock: Arc::new(tokio::sync::Mutex::new(true)),
is_running: Arc::new(tokio::sync::Mutex::new(false)),
};
let cloned_agent_state = agent.clone();

View File

@@ -12,7 +12,7 @@ use super::BitwardenDesktopAgent;
impl BitwardenDesktopAgent {
pub async fn start_server(
auth_request_tx: tokio::sync::mpsc::Sender<(u32, String)>,
auth_request_tx: tokio::sync::mpsc::Sender<(u32, (String, bool))>,
auth_response_rx: Arc<Mutex<tokio::sync::broadcast::Receiver<(u32, bool)>>>,
) -> Result<Self, anyhow::Error> {
let agent_state = BitwardenDesktopAgent {
@@ -21,6 +21,7 @@ impl BitwardenDesktopAgent {
get_ui_response_rx: auth_response_rx,
cancellation_token: CancellationToken::new(),
request_id: Arc::new(tokio::sync::Mutex::new(0)),
needs_unlock: Arc::new(tokio::sync::Mutex::new(true)),
is_running: Arc::new(tokio::sync::Mutex::new(true)),
};
let stream = named_pipe_listener_stream::NamedPipeServerStream::new(