From 34382598d91daf31981902422ebe77de65377aa4 Mon Sep 17 00:00:00 2001 From: Dhanuka Warusadura Date: Sun, 29 Sep 2024 16:58:42 +0200 Subject: [PATCH] wip: watch peer connections Signed-off-by: Dhanuka Warusadura --- Cargo.lock | 1 + server/Cargo.toml | 1 + server/src/daemon/service.rs | 2 ++ server/src/daemon/service_manager.rs | 53 +++++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 1c313dee8..6eb04e42f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1079,6 +1079,7 @@ version = "0.3.0" dependencies = [ "base64", "clap", + "futures-util", "oo7", "rpassword", "serde", diff --git a/server/Cargo.toml b/server/Cargo.toml index e23b98cc6..f54bd545b 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -11,6 +11,7 @@ version.workspace = true [dependencies] base64 = "0.22.1" clap = { version = "4.4.6", features = [ "cargo", "derive" ] } +futures-util = "0.3.30" oo7 = { workspace = true, features = ["unstable"] } rpassword = "7.2.0" serde.workspace = true diff --git a/server/src/daemon/service.rs b/server/src/daemon/service.rs index 4d2ded134..e2e70241f 100644 --- a/server/src/daemon/service.rs +++ b/server/src/daemon/service.rs @@ -440,6 +440,8 @@ impl Service { // loading login.keyring into the objects tree Service::init_collections(&object_server, self).await; + ServiceManager::watch_peer_connections(&cnx).await?; + Ok(()) } diff --git a/server/src/daemon/service_manager.rs b/server/src/daemon/service_manager.rs index 1d6c5f6e2..54ad139d8 100644 --- a/server/src/daemon/service_manager.rs +++ b/server/src/daemon/service_manager.rs @@ -1,14 +1,20 @@ use std::{collections::HashMap, sync::RwLock}; -use zbus::zvariant::{ObjectPath, OwnedObjectPath}; +use futures_util::stream::StreamExt; +use zbus::{ + zvariant::{ObjectPath, OwnedObjectPath}, + Connection, MatchRule, MessageStream, +}; use super::{collection::Collection, session::Session}; +use crate::daemon; #[derive(Debug, Default)] pub struct ServiceManager { sessions: HashMap, collections: HashMap, collections_to_unlock: Vec, + peers: HashMap, unlock_request_sender: RwLock, unlock_prompt_path: RwLock, prompts_counter: RwLock, @@ -70,6 +76,18 @@ impl ServiceManager { *self.unlock_prompt_path.write().unwrap() = path.into(); } + pub fn peer(&self, peer: String) -> Option { + self.peers.get(&peer).cloned() + } + + pub fn insert_peer(&mut self, peer: String, path: ObjectPath<'_>) { + self.peers.insert(peer, path.into()); + } + + pub fn remove_peer(&mut self, peer: String) { + self.peers.remove(&peer); + } + pub fn prompts_counter(&self) -> i32 { *self.prompts_counter.read().unwrap() } @@ -102,4 +120,37 @@ impl ServiceManager { pub fn set_prompt_dismissed(&mut self, dismissed: bool) { self.prompt_dismissed = dismissed; } + + pub async fn watch_peer_connections(connection: &Connection) -> daemon::Result<()> { + // monitor client disconnects + + let rule = MatchRule::builder() + .msg_type(zbus::message::Type::Signal) + .sender("org.freedesktop.DBus")? + .interface("org.freedesktop.DBus")? + .member("NameOwnerChanged")? + .add_arg("org.gnome.seahorse.Application")? + .build(); + + let mut stream = MessageStream::for_match_rule(rule, connection, Some(1)).await?; + + while let Some(Ok(message)) = stream.next().await { + let Ok((_, old_owner, new_owner)) = + message.body().deserialize::<(String, String, String)>() + else { + continue; + }; + if new_owner == "" { + // a peer is disconnecting, remove session info + // https://github.com/GNOME/gnome-keyring/blob/4132075144c7bb21b897570dd53b005ac38250aa/daemon/dbus/gkd-secret-service.c#L936 + tracing::info!("A peer is disconnected."); + // todo: clean up + println!("------------------ {old_owner}"); + } else { + tracing::info!("A peer connected."); + } + } + + Ok(()) + } }