Skip to content

Commit

Permalink
[PM-14988] Use peercred / GetNamedPipeClientProcessId to gather info …
Browse files Browse the repository at this point in the history
…about process connecting to ssh agent (#12065)

* Fix double prompt when unlocking by ssh request

* Add peercred for unix

* Enable apple-app-store feature

* Add generic parameter

* Update

* Add procinfo for windows

* Show connecting app in ui

* Use struct instead of tuple

* Use atomics instead of mutex

* Fix windows build

* Use is_running function

* Cleanup named pipe listener

* Cleanups

* Cargo fmt

* Replace "" with none

* Rebuild index.d.ts

* Fix is running check
  • Loading branch information
quexten authored Dec 11, 2024
1 parent 7abdc7a commit e8d8a81
Show file tree
Hide file tree
Showing 19 changed files with 410 additions and 105 deletions.
71 changes: 70 additions & 1 deletion apps/desktop/desktop_native/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion apps/desktop/desktop_native/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ ssh-key = { version = "=0.6.7", default-features = false, features = [
"rsa",
"getrandom",
] }
bitwarden-russh = { git = "https://github.com/bitwarden/bitwarden-russh.git", rev = "b4e7f2fedbe3df8c35545feb000176d3e7b2bc32" }
bitwarden-russh = { git = "https://github.com/bitwarden/bitwarden-russh.git", rev = "23b50e3bbe6d56ef19ab0e98e8bb1462cb6d77ae" }
tokio = { version = "=1.41.1", features = ["io-util", "sync", "macros", "net"] }
tokio-stream = { version = "=0.1.15", features = ["net"] }
tokio-util = { version = "=0.7.12", features = ["codec"] }
Expand All @@ -59,6 +59,7 @@ 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 = ["windows"] }

[target.'cfg(windows)'.dependencies]
widestring = { version = "=1.1.0", optional = true }
Expand All @@ -72,6 +73,7 @@ windows = { version = "=0.58.0", features = [
"Win32_System_WinRT",
"Win32_UI_Input_KeyboardAndMouse",
"Win32_UI_WindowsAndMessaging",
"Win32_System_Pipes",
], optional = true }

[target.'cfg(windows)'.dev-dependencies]
Expand Down
19 changes: 14 additions & 5 deletions apps/desktop/desktop_native/core/src/biometric/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,12 +310,16 @@ mod tests {
os_key_part_b64: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=".to_owned(),
client_key_part_b64: Some("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=".to_owned()),
};
crate::password::set_password(test, test, secret).await.unwrap();
crate::password::set_password(test, test, secret)
.await
.unwrap();
let result =
<Biometric as BiometricTrait>::get_biometric_secret(test, test, Some(key_material))
.await
.unwrap();
crate::password::delete_password("test", "test").await.unwrap();
crate::password::delete_password("test", "test")
.await
.unwrap();
assert_eq!(result, secret);
}

Expand All @@ -328,19 +332,24 @@ mod tests {
os_key_part_b64: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=".to_owned(),
client_key_part_b64: Some("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=".to_owned()),
};
crate::password::set_password(test, test, &secret.to_string()).await.unwrap();
crate::password::set_password(test, test, &secret.to_string())
.await
.unwrap();

let result =
<Biometric as BiometricTrait>::get_biometric_secret(test, test, Some(key_material))
.await
.unwrap();
crate::password::delete_password("test", "test").await.unwrap();
crate::password::delete_password("test", "test")
.await
.unwrap();
assert_eq!(result, "secret");
}

#[tokio::test]
async fn set_biometric_secret_requires_key() {
let result = <Biometric as BiometricTrait>::set_biometric_secret("", "", "", None, "").await;
let result =
<Biometric as BiometricTrait>::set_biometric_secret("", "", "", None, "").await;
assert!(result.is_err());
assert_eq!(
result.unwrap_err().to_string(),
Expand Down
12 changes: 9 additions & 3 deletions apps/desktop/desktop_native/core/src/password/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,18 @@ mod tests {

#[tokio::test]
async fn test() {
set_password("BitwardenTest", "BitwardenTest", "Random").await.unwrap();
set_password("BitwardenTest", "BitwardenTest", "Random")
.await
.unwrap();
assert_eq!(
"Random",
get_password("BitwardenTest", "BitwardenTest").await.unwrap()
get_password("BitwardenTest", "BitwardenTest")
.await
.unwrap()
);
delete_password("BitwardenTest", "BitwardenTest").await.unwrap();
delete_password("BitwardenTest", "BitwardenTest")
.await
.unwrap();

// Ensure password is deleted
match get_password("BitwardenTest", "BitwardenTest").await {
Expand Down
48 changes: 28 additions & 20 deletions apps/desktop/desktop_native/core/src/password/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ use std::collections::HashMap;
pub async fn get_password(service: &str, account: &str) -> Result<String> {
match get_password_new(service, account).await {
Ok(res) => Ok(res),
Err(_) => {
get_password_legacy(service, account).await
}
Err(_) => get_password_legacy(service, account).await,
}
}

Expand All @@ -20,8 +18,8 @@ async fn get_password_new(service: &str, account: &str) -> Result<String> {
Some(res) => {
let secret = res.secret().await?;
Ok(String::from_utf8(secret.to_vec())?)
},
None => Err(anyhow!("no result"))
}
None => Err(anyhow!("no result")),
}
}

Expand All @@ -37,20 +35,30 @@ async fn get_password_legacy(service: &str, account: &str) -> Result<String> {
match res {
Some(res) => {
let secret = res.secret().await?;
println!("deleting legacy secret service entry {} {}", service, account);
println!(
"deleting legacy secret service entry {} {}",
service, account
);
keyring.delete(&attributes).await?;
let secret_string = String::from_utf8(secret.to_vec())?;
set_password(service, account, &secret_string).await?;
Ok(secret_string)
},
None => Err(anyhow!("no result"))
}
None => Err(anyhow!("no result")),
}
}

pub async fn set_password(service: &str, account: &str, password: &str) -> Result<()> {
let keyring = oo7::Keyring::new().await?;
let attributes = HashMap::from([("service", service), ("account", account)]);
keyring.create_item("org.freedesktop.Secret.Generic", &attributes, password, true).await?;
keyring
.create_item(
"org.freedesktop.Secret.Generic",
&attributes,
password,
true,
)
.await?;
Ok(())
}

Expand All @@ -74,33 +82,33 @@ mod tests {

#[tokio::test]
async fn test() {
set_password("BitwardenTest", "BitwardenTest", "Random").await.unwrap();
set_password("BitwardenTest", "BitwardenTest", "Random")
.await
.unwrap();
assert_eq!(
"Random",
get_password("BitwardenTest", "BitwardenTest").await.unwrap()
get_password("BitwardenTest", "BitwardenTest")
.await
.unwrap()
);
delete_password("BitwardenTest", "BitwardenTest").await.unwrap();
delete_password("BitwardenTest", "BitwardenTest")
.await
.unwrap();

// Ensure password is deleted
match get_password("BitwardenTest", "BitwardenTest").await {
Ok(_) => {
panic!("Got a result")
}
Err(e) => assert_eq!(
"no result",
e.to_string()
),
Err(e) => assert_eq!("no result", e.to_string()),
}
}

#[tokio::test]
async fn test_error_no_password() {
match get_password("Unknown", "Unknown").await {
Ok(_) => panic!("Got a result"),
Err(e) => assert_eq!(
"no result",
e.to_string()
),
Err(e) => assert_eq!("no result", e.to_string()),
}
}
}
12 changes: 9 additions & 3 deletions apps/desktop/desktop_native/core/src/password/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,18 @@ mod tests {

#[tokio::test]
async fn test() {
set_password("BitwardenTest", "BitwardenTest", "Random").await.unwrap();
set_password("BitwardenTest", "BitwardenTest", "Random")
.await
.unwrap();
assert_eq!(
"Random",
get_password("BitwardenTest", "BitwardenTest").await.unwrap()
get_password("BitwardenTest", "BitwardenTest")
.await
.unwrap()
);
delete_password("BitwardenTest", "BitwardenTest").await.unwrap();
delete_password("BitwardenTest", "BitwardenTest")
.await
.unwrap();

// Ensure password is deleted
match get_password("BitwardenTest", "BitwardenTest").await {
Expand Down
Loading

0 comments on commit e8d8a81

Please sign in to comment.