diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 1cf2344c3e7..6059b3cefdf 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -313,7 +313,7 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitwarden-russh" version = "0.1.0" -source = "git+https://github.com/bitwarden/bitwarden-russh.git?branch=km/pm-10098/clean-russh-implementation#86ff1bf2f4620a3ae5684adee31abdbee33c6f07" +source = "git+https://github.com/bitwarden/bitwarden-russh.git?branch=km/allow_additional_data#28e28c57f258d897ff963c1b1e4c191f4f4fa42c" dependencies = [ "anyhow", "byteorder", diff --git a/apps/desktop/desktop_native/core/Cargo.toml b/apps/desktop/desktop_native/core/Cargo.toml index 9a5b47b8a06..72bddf1262f 100644 --- a/apps/desktop/desktop_native/core/Cargo.toml +++ b/apps/desktop/desktop_native/core/Cargo.toml @@ -10,22 +10,22 @@ default = ["sys"] manual_test = [] sys = [ - "dep:widestring", - "dep:windows", - "dep:core-foundation", - "dep:security-framework", - "dep:security-framework-sys", - "dep:gio", - "dep:libsecret", - "dep:zbus", - "dep:zbus_polkit", + "dep:widestring", + "dep:windows", + "dep:core-foundation", + "dep:security-framework", + "dep:security-framework-sys", + "dep:gio", + "dep:libsecret", + "dep:zbus", + "dep:zbus_polkit", ] [dependencies] aes = "=0.8.4" anyhow = "=1.0.93" arboard = { version = "=3.4.1", default-features = false, features = [ - "wayland-data-control", + "wayland-data-control", ] } async-stream = "0.3.5" base64 = "=0.22.1" @@ -50,7 +50,7 @@ ssh-key = { version = "0.6.6", default-features = false, features = [ "rsa", "getrandom", ] } -bitwarden-russh = { git = "https://github.com/bitwarden/bitwarden-russh.git", branch = "km/pm-10098/clean-russh-implementation" } +bitwarden-russh = { git = "https://github.com/bitwarden/bitwarden-russh.git", branch = "km/allow_additional_data" } tokio = { version = "=1.40.0", features = ["io-util", "sync", "macros", "net"] } tokio-stream = { version = "=0.1.15", features = ["net"] } tokio-util = "=0.7.12" @@ -60,20 +60,20 @@ rand_chacha = "=0.3.1" pkcs8 = { version = "=0.10.2", features = ["alloc", "encryption", "pem"] } rsa = "=0.9.6" ed25519 = { version = "=2.2.3", features = ["pkcs8"] } -sysinfo = { version = "0.32.0", features = ["apple-app-store"] } +sysinfo = { version = "0.32.0", features = ["windows"] } [target.'cfg(windows)'.dependencies] widestring = { version = "=1.1.0", optional = true } windows = { version = "=0.57.0", features = [ - "Foundation", - "Security_Credentials_UI", - "Security_Cryptography", - "Storage_Streams", - "Win32_Foundation", - "Win32_Security_Credentials", - "Win32_System_WinRT", - "Win32_UI_Input_KeyboardAndMouse", - "Win32_UI_WindowsAndMessaging", + "Foundation", + "Security_Credentials_UI", + "Security_Cryptography", + "Storage_Streams", + "Win32_Foundation", + "Win32_Security_Credentials", + "Win32_System_WinRT", + "Win32_UI_Input_KeyboardAndMouse", + "Win32_UI_WindowsAndMessaging", ], optional = true } [target.'cfg(windows)'.dev-dependencies] diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs b/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs index 608d81a9496..b826cb0d512 100644 --- a/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs +++ b/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs @@ -13,7 +13,7 @@ mod platform_ssh_agent; pub mod generator; pub mod importer; mod peercred_unix_listener_stream; - +pub mod peerinfo; #[derive(Clone)] pub struct BitwardenDesktopAgent { keystore: ssh_agent::KeyStore, @@ -31,8 +31,8 @@ impl BitwardenDesktopAgent { } } -impl ssh_agent::Agent for BitwardenDesktopAgent { - async fn confirm(&self, ssh_key: Key) -> bool { +impl ssh_agent::Agent for BitwardenDesktopAgent { + async fn confirm(&self, ssh_key: Key, _info: &peerinfo::models::PeerInfo) -> bool { let request_id = self.get_request_id().await; let mut rx_channel = self.get_ui_response_rx.lock().await.resubscribe(); @@ -47,6 +47,10 @@ impl ssh_agent::Agent for BitwardenDesktopAgent { } false } + + fn can_list(&self, _connection_info: &peerinfo::models::PeerInfo) -> impl std::future::Future + Send { + async { true } + } } impl BitwardenDesktopAgent { diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/named_pipe_listener_stream.rs b/apps/desktop/desktop_native/core/src/ssh_agent/named_pipe_listener_stream.rs index 69399ae7530..917d8dd2ecf 100644 --- a/apps/desktop/desktop_native/core/src/ssh_agent/named_pipe_listener_stream.rs +++ b/apps/desktop/desktop_native/core/src/ssh_agent/named_pipe_listener_stream.rs @@ -27,6 +27,7 @@ impl NamedPipeServerStream { PIPE_NAME ); let mut listener = ServerOptions::new().create(PIPE_NAME).unwrap(); + loop { println!("[SSH Agent Native Module] Waiting for connection"); select! { diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/peercred_unix_listener_stream.rs b/apps/desktop/desktop_native/core/src/ssh_agent/peercred_unix_listener_stream.rs index ca11b0a286a..c17eab62fc9 100644 --- a/apps/desktop/desktop_native/core/src/ssh_agent/peercred_unix_listener_stream.rs +++ b/apps/desktop/desktop_native/core/src/ssh_agent/peercred_unix_listener_stream.rs @@ -2,9 +2,11 @@ use futures::Stream; use std::io; use std::pin::Pin; use std::task::{Context, Poll}; -use sysinfo::{Pid, System}; use tokio::net::{UnixListener, UnixStream}; +use super::peerinfo; +use super::peerinfo::models::PeerInfo; + #[derive(Debug)] pub struct PeercredUnixListenerStream { inner: UnixListener, @@ -14,31 +16,49 @@ impl PeercredUnixListenerStream { pub fn new(listener: UnixListener) -> Self { Self { inner: listener } } - - pub fn into_inner(self) -> UnixListener { - self.inner - } } impl Stream for PeercredUnixListenerStream { - type Item = io::Result; + type Item = io::Result<(UnixStream, PeerInfo)>; fn poll_next( self: Pin<&mut Self>, cx: &mut Context<'_>, - ) -> Poll>> { + ) -> Poll>> { match self.inner.poll_accept(cx) { Poll::Ready(Ok((stream, _))) => { - println!("{:?}", stream.peer_cred()); - println!("{:?}", stream.peer_cred().unwrap().pid()); - let peer = stream.peer_cred().unwrap(); - let s = System::new_all(); - if let Some(process) = s.process(Pid::from_u32(peer.pid().unwrap() as u32)) { - println!("name {:?}", process.name()); - println!("cmd {:?}", process.cmd()); + let pid = match stream.peer_cred() { + Ok(peer) => match peer.pid() { + Some(pid) => pid, + None => { + return Poll::Ready(Some(Err(io::Error::new( + io::ErrorKind::Other, + "Failed to get peer PID", + )))); + } + }, + Err(err) => { + return Poll::Ready(Some(Err(io::Error::new( + io::ErrorKind::Other, + format!("Failed to get peer credentials: {}", err), + )))); + } + }; + let peer_info = peerinfo::gather::get_peer_info(pid as u32); + match peer_info { + Ok(info) => { + println!("name {:?}", info.process_name()); + println!("uid {:?}", info.uid()); + Poll::Ready(Some(Ok((stream, info)))) + } + Err(err) => { + println!("Failed to get peer info: {}", err); + Poll::Ready(Some(Err(io::Error::new( + io::ErrorKind::Other, + format!("Failed to get peer info: {}", err), + )))) + } } - - Poll::Ready(Some(Ok(stream))) } Poll::Ready(Err(err)) => Poll::Ready(Some(Err(err))), Poll::Pending => Poll::Pending, diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/gather.rs b/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/gather.rs new file mode 100644 index 00000000000..699203d613d --- /dev/null +++ b/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/gather.rs @@ -0,0 +1,23 @@ +use sysinfo::{Pid, System}; + +use super::models::PeerInfo; + +pub fn get_peer_info(peer_pid: u32) -> Result { + let s = System::new_all(); + if let Some(process) = s.process(Pid::from_u32(peer_pid)) { + let peer_process_name = match process.name().to_str() { + Some(name) => name.to_string(), + None => { + return Err("Failed to get process name".to_string()); + } + }; + + return Ok(PeerInfo::new( + peer_pid, + process.pid().as_u32(), + peer_process_name, + )); + } + + Err("Failed to get process".to_string()) +} diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/mod.rs b/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/mod.rs new file mode 100644 index 00000000000..fb12aa66e09 --- /dev/null +++ b/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/mod.rs @@ -0,0 +1,2 @@ +pub mod gather; +pub mod models; diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/models.rs b/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/models.rs new file mode 100644 index 00000000000..823d912883e --- /dev/null +++ b/apps/desktop/desktop_native/core/src/ssh_agent/peerinfo/models.rs @@ -0,0 +1,32 @@ +/** +* Peerinfo represents the information of a peer process connecting over a socket. +* This can be later extended to include more information (icon, app name) for the corresponding application. +*/ +#[derive(Debug)] +pub struct PeerInfo { + uid: u32, + pid: u32, + process_name: String, +} + +impl PeerInfo { + pub fn new(uid: u32, pid: u32, process_name: String) -> Self { + Self { + uid, + pid, + process_name, + } + } + + pub fn uid(&self) -> u32 { + self.uid + } + + pub fn pid(&self) -> u32 { + self.pid + } + + pub fn process_name(&self) -> &str { + &self.process_name + } +} diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/unix.rs b/apps/desktop/desktop_native/core/src/ssh_agent/unix.rs index 68d647d04d3..7a512712153 100644 --- a/apps/desktop/desktop_native/core/src/ssh_agent/unix.rs +++ b/apps/desktop/desktop_native/core/src/ssh_agent/unix.rs @@ -12,7 +12,7 @@ use crate::ssh_agent::peercred_unix_listener_stream::PeercredUnixListenerStream; use super::BitwardenDesktopAgent; -impl BitwardenDesktopAgent { +impl BitwardenDesktopAgent{ pub async fn start_server( auth_request_tx: tokio::sync::mpsc::Sender<(u32, String)>, auth_response_rx: Arc>>,