diff --git a/Cargo.lock b/Cargo.lock index fc42ae0..1d0912e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -596,11 +596,11 @@ name = "ferrvault-cli" version = "0.1.0" dependencies = [ "anyhow", + "apple-native-keyring-store", "base64", "chrono", "clap", "hostname", - "keyring", "keyring-core", "reqwest", "rpassword", @@ -616,6 +616,8 @@ dependencies = [ "tracing-subscriber", "url", "webpki-roots", + "windows-native-keyring-store", + "zbus-secret-service-keyring-store", "zeroize", ] @@ -1139,18 +1141,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "keyring" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee5140534876dd3450719b506cfbb77397e640910fc39b6e7011c133291e15a" -dependencies = [ - "apple-native-keyring-store", - "keyring-core", - "windows-native-keyring-store", - "zbus-secret-service-keyring-store", -] - [[package]] name = "keyring-core" version = "1.0.0" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index adf91c1..4d4c48b 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -24,7 +24,6 @@ serde_json = "1" anyhow = "1" thiserror = "2" url = "2" -keyring = "4" keyring-core = "1" zeroize = { version = "1", features = ["derive"] } sha2 = "0.11" @@ -35,6 +34,15 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] } hostname = "0.4" rpassword = "7" +[target.'cfg(target_os = "linux")'.dependencies] +zbus-secret-service-keyring-store = { version = "1", features = ["crypto-rust"] } + +[target.'cfg(target_os = "macos")'.dependencies] +apple-native-keyring-store = { version = "1", features = ["keychain"] } + +[target.'cfg(target_os = "windows")'.dependencies] +windows-native-keyring-store = "1" + [dev-dependencies] tempfile = "3" diff --git a/cli/src/storage.rs b/cli/src/storage.rs index f333118..49a8477 100644 --- a/cli/src/storage.rs +++ b/cli/src/storage.rs @@ -11,12 +11,43 @@ const URL_KEY: &str = "api_url"; fn open_entry(key: &str, slot: &str) -> Result { static STORE: OnceLock> = OnceLock::new(); STORE - .get_or_init(|| keyring::use_native_store(true).map_err(|e| e.to_string())) + .get_or_init(set_native_default_store) .as_ref() .map_err(|e| anyhow!("initialising OS keyring — is one installed? ({e})"))?; Entry::new(SERVICE, key).with_context(|| format!("opening OS keyring ({slot} slot)")) } +fn set_native_default_store() -> Result<(), String> { + use std::collections::HashMap; + let config: HashMap<&str, &str> = HashMap::new(); + #[cfg(target_os = "linux")] + { + let store = zbus_secret_service_keyring_store::Store::new_with_configuration(&config) + .map_err(|e| e.to_string())?; + keyring_core::set_default_store(store); + Ok(()) + } + #[cfg(target_os = "macos")] + { + let store = apple_native_keyring_store::keychain::Store::new_with_configuration(&config) + .map_err(|e| e.to_string())?; + keyring_core::set_default_store(store); + Ok(()) + } + #[cfg(target_os = "windows")] + { + let store = windows_native_keyring_store::Store::new_with_configuration(&config) + .map_err(|e| e.to_string())?; + keyring_core::set_default_store(store); + Ok(()) + } + #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] + { + let _ = config; + Err("no OS keyring backend is available on this platform".to_string()) + } +} + pub struct CredentialStore; impl CredentialStore {