diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 10d9b804cc0..1705e046a3f 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -1407,6 +1407,27 @@ dependencies = [ "syn", ] +[[package]] +name = "env_filter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +dependencies = [ + "log", +] + +[[package]] +name = "env_logger" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "log", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -3690,6 +3711,7 @@ dependencies = [ "ssh-encoding 0.3.0-rc.2", "ssh-key 0.7.0-rc.3", "sysinfo", + "test-log", "tokio", "tokio-util", "tracing", @@ -3780,6 +3802,28 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "test-log" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e33b98a582ea0be1168eba097538ee8dd4bbe0f2b01b22ac92ea30054e5be7b" +dependencies = [ + "env_logger", + "test-log-macros", + "tracing-subscriber", +] + +[[package]] +name = "test-log-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451b374529930d7601b1eef8d32bc79ae870b6079b069401709c2a8bf9e75f36" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "textwrap" version = "0.16.2" diff --git a/apps/desktop/desktop_native/ssh_agent/Cargo.toml b/apps/desktop/desktop_native/ssh_agent/Cargo.toml index b1ddf45b627..1552b0cc3a1 100644 --- a/apps/desktop/desktop_native/ssh_agent/Cargo.toml +++ b/apps/desktop/desktop_native/ssh_agent/Cargo.toml @@ -44,6 +44,7 @@ ssh-key = { version = "=0.7.0-rc.3", features = [ "getrandom", ] } sysinfo = { workspace = true, features = ["windows"] } +test-log = "0.2.18" tokio = { workspace = true, features = ["io-util", "sync", "macros", "net", "full"] } tokio-util = { workspace = true, features = ["codec"] } tracing = { workspace = true } diff --git a/apps/desktop/desktop_native/ssh_agent/examples/integration.rs b/apps/desktop/desktop_native/ssh_agent/tests/integration.rs similarity index 81% rename from apps/desktop/desktop_native/ssh_agent/examples/integration.rs rename to apps/desktop/desktop_native/ssh_agent/tests/integration.rs index 455722293d6..ec416916350 100644 --- a/apps/desktop/desktop_native/ssh_agent/examples/integration.rs +++ b/apps/desktop/desktop_native/ssh_agent/tests/integration.rs @@ -1,7 +1,7 @@ -#![cfg(target_os = "linux")] - +#[cfg(target_os = "linux")] use std::{fs, process::Command, sync::Arc}; +#[cfg(target_os = "linux")] use ssh_agent::{ agent::{ ui_requester::{UiRequestMessage, UiRequester}, @@ -11,26 +11,23 @@ use ssh_agent::{ protocol::types::{KeyPair, PrivateKey}, transport::unix_listener_stream::UnixListenerStream, }; +#[cfg(target_os = "linux")] use tokio::{ sync::{broadcast, mpsc, Mutex}, task, }; +#[cfg(target_os = "linux")] use tracing::info; -#[tokio::main] -async fn main() { +#[cfg(target_os = "linux")] +#[tokio::test] +#[test_log::test] +async fn ssh_agent_auth() { let dir = homedir::my_home().unwrap().unwrap(); let dir = dir.join(".cache"); let dir = dir.join("ssh_agent_integration_test"); let dir = dir.to_string_lossy().into_owned(); - // set up tracing to stdout - tracing_subscriber::fmt() - .with_max_level(tracing::Level::INFO) - .with_thread_ids(true) - .with_thread_names(true) - .init(); - fs::remove_dir_all(&dir).unwrap_or(()); // Prepare test run directory fs::create_dir_all(&dir).unwrap(); @@ -56,6 +53,7 @@ AuthorizedKeysFile {}/authorized_keys .status() .expect("failed to execute process"); }); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; let ui_requester = mock_channels(); let desktop_agent = BitwardenDesktopAgent::new(ui_requester); @@ -63,23 +61,31 @@ AuthorizedKeysFile {}/authorized_keys let dir_clone = dir.clone(); task::spawn(async move { - println!("Starting SSH Agent V2 socket..."); info!(target: "ssh-agent", "Listening on {}", format!("{}/ssh-agent.sock", dir_clone)); UnixListenerStream::listen(format!("{}/ssh-agent.sock", dir_clone), desktop_agent) .await .unwrap(); }); - // run ssh-add -L - Command::new("ssh-add") - .env("SSH_AUTH_SOCK", format!("{}/ssh-agent.sock", dir)) - .args(&["-L"]) - .status() - .expect("failed to execute process"); + tokio::time::sleep(tokio::time::Duration::from_secs(2)).await; - // run ssh - Command::new("ssh") - .env("SSH_AUTH_SOCK", format!("{}/ssh-agent.sock", dir)) + // Test listing keys + let dir_clone = dir.clone(); + let jh1 = std::thread::spawn(move || { + Command::new("ssh-add") + .env("SSH_AUTH_SOCK", format!("{}/ssh-agent.sock", dir_clone)) + .args(&["-L"]) + .status() + .expect("failed to execute process"); + }); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + jh1.join().unwrap(); + + // Test ssh connection + let dir_clone = dir.clone(); + let jh1 = std::thread::spawn(move || { + Command::new("ssh") + .env("SSH_AUTH_SOCK", format!("{}/ssh-agent.sock", dir_clone)) .args(&[ "-o", "StrictHostKeyChecking=no", @@ -93,12 +99,17 @@ AuthorizedKeysFile {}/authorized_keys ]) .status() .expect("failed to execute process"); + }); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + jh1.join().unwrap(); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; // Cleanup fs::remove_dir_all(dir).unwrap(); std::process::exit(0); } +#[cfg(target_os = "linux")] fn make_keys(dir: &str) -> Vec { Command::new("ssh-keygen") .args(&[ @@ -173,6 +184,7 @@ fn make_keys(dir: &str) -> Vec { unlocked_items } +#[cfg(target_os = "linux")] fn mock_channels() -> UiRequester { let (show_ui_request_tx, mut show_ui_request_rx) = mpsc::channel::(10);