aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2023-03-25 18:44:21 -0400
committerJesse Luehrs <doy@tozt.net>2023-03-25 23:14:16 -0400
commit5eab3c4b33f2b0b594993a095eae86f88828827d (patch)
treea2ce6133546bd03a56ad2ae65f1ad0478ab8ee91 /src/bin
parentb659cc500476a7b4b94bc6659d46922be9465b99 (diff)
downloadrbw-5eab3c4b33f2b0b594993a095eae86f88828827d.tar.gz
rbw-5eab3c4b33f2b0b594993a095eae86f88828827d.zip
sync the db every hour, like other bitwarden clients
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/rbw-agent/actions.rs12
-rw-r--r--src/bin/rbw-agent/agent.rs32
-rw-r--r--src/bin/rbw/commands.rs6
3 files changed, 41 insertions, 9 deletions
diff --git a/src/bin/rbw-agent/actions.rs b/src/bin/rbw-agent/actions.rs
index e857a1e..7b5dc58 100644
--- a/src/bin/rbw-agent/actions.rs
+++ b/src/bin/rbw-agent/actions.rs
@@ -130,7 +130,6 @@ pub async fn login(
protected_key,
)) => {
login_success(
- sock,
state,
access_token,
refresh_token,
@@ -166,11 +165,10 @@ pub async fn login(
tty,
&email,
password.clone(),
- provider
+ provider,
)
.await?;
login_success(
- sock,
state,
access_token,
refresh_token,
@@ -307,7 +305,6 @@ async fn two_factor(
}
async fn login_success(
- sock: &mut crate::sock::Sock,
state: std::sync::Arc<tokio::sync::RwLock<crate::agent::State>>,
access_token: String,
refresh_token: String,
@@ -329,7 +326,7 @@ async fn login_success(
db.protected_key = Some(protected_key.to_string());
save_db(&db).await?;
- sync(sock, false).await?;
+ sync(None).await?;
let db = load_db().await?;
let Some(protected_private_key) = db.protected_private_key
@@ -497,8 +494,7 @@ pub async fn check_lock(
}
pub async fn sync(
- sock: &mut crate::sock::Sock,
- ack: bool,
+ sock: Option<&mut crate::sock::Sock>,
) -> anyhow::Result<()> {
let mut db = load_db().await?;
@@ -527,7 +523,7 @@ pub async fn sync(
db.entries = entries;
save_db(&db).await?;
- if ack {
+ if let Some(sock) = sock {
respond_ack(sock).await?;
}
diff --git a/src/bin/rbw-agent/agent.rs b/src/bin/rbw-agent/agent.rs
index 8fa6768..7dcab16 100644
--- a/src/bin/rbw-agent/agent.rs
+++ b/src/bin/rbw-agent/agent.rs
@@ -7,6 +7,8 @@ pub struct State {
Option<std::collections::HashMap<String, rbw::locked::Keys>>,
pub timeout: crate::timeout::Timeout,
pub timeout_duration: std::time::Duration,
+ pub sync_timeout: crate::timeout::Timeout,
+ pub sync_timeout_duration: std::time::Duration,
}
impl State {
@@ -29,10 +31,15 @@ impl State {
self.org_keys = None;
self.timeout.clear();
}
+
+ pub fn set_sync_timeout(&mut self) {
+ self.sync_timeout.set(self.sync_timeout_duration);
+ }
}
pub struct Agent {
timer_r: tokio::sync::mpsc::UnboundedReceiver<()>,
+ sync_timer_r: tokio::sync::mpsc::UnboundedReceiver<()>,
state: std::sync::Arc<tokio::sync::RwLock<State>>,
}
@@ -41,14 +48,23 @@ impl Agent {
let config = rbw::config::Config::load()?;
let timeout_duration =
std::time::Duration::from_secs(config.lock_timeout);
+ let sync_timeout_duration =
+ std::time::Duration::from_secs(config.sync_interval);
let (timeout, timer_r) = crate::timeout::Timeout::new();
+ let (sync_timeout, sync_timer_r) = crate::timeout::Timeout::new();
+ if sync_timeout_duration > std::time::Duration::ZERO {
+ sync_timeout.set(sync_timeout_duration);
+ }
Ok(Self {
timer_r,
+ sync_timer_r,
state: std::sync::Arc::new(tokio::sync::RwLock::new(State {
priv_key: None,
org_keys: None,
timeout,
timeout_duration,
+ sync_timeout,
+ sync_timeout_duration,
})),
})
}
@@ -60,6 +76,7 @@ impl Agent {
enum Event {
Request(std::io::Result<tokio::net::UnixStream>),
Timeout(()),
+ Sync(()),
}
let mut stream = futures_util::stream::select_all([
tokio_stream::wrappers::UnixListenerStream::new(listener)
@@ -70,6 +87,11 @@ impl Agent {
)
.map(Event::Timeout)
.boxed(),
+ tokio_stream::wrappers::UnboundedReceiverStream::new(
+ self.sync_timer_r,
+ )
+ .map(Event::Sync)
+ .boxed(),
]);
while let Some(event) = stream.next().await {
match event {
@@ -94,6 +116,14 @@ impl Agent {
Event::Timeout(()) => {
self.state.write().await.clear();
}
+ Event::Sync(()) => {
+ // this could fail if we aren't logged in, but we don't
+ // care about that
+ tokio::spawn(async move {
+ let _ = crate::actions::sync(None).await;
+ });
+ self.state.write().await.set_sync_timeout();
+ }
}
}
Ok(())
@@ -141,7 +171,7 @@ async fn handle_request(
false
}
rbw::protocol::Action::Sync => {
- crate::actions::sync(sock, true).await?;
+ crate::actions::sync(Some(sock)).await?;
false
}
rbw::protocol::Action::Decrypt {
diff --git a/src/bin/rbw/commands.rs b/src/bin/rbw/commands.rs
index 668cb89..5d51f70 100644
--- a/src/bin/rbw/commands.rs
+++ b/src/bin/rbw/commands.rs
@@ -639,6 +639,12 @@ pub fn config_set(key: &str, value: &str) -> anyhow::Result<()> {
config.lock_timeout = timeout;
}
}
+ "sync_interval" => {
+ let interval = value
+ .parse()
+ .context("failed to parse value for sync_interval")?;
+ config.sync_interval = interval;
+ }
"pinentry" => config.pinentry = value.to_string(),
_ => return Err(anyhow::anyhow!("invalid config key: {}", key)),
}