diff --git a/Cargo.toml b/Cargo.toml index c896707..d7c2388 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,40 +6,47 @@ keywords = ["password", "credential", "keychain", "keyring", "cross-platform"] license = "MIT OR Apache-2.0" name = "keyring" repository = "https://github.com/hwchen/keyring-rs.git" -version = "2.1.0" +version = "2.2.0" edition = "2021" exclude = [".github/"] readme = "README.md" [features] -default = ["linux-secret-service"] +default = ["platform-all"] +platform-all = ["platform-linux", "platform-freebsd", "platform-macos", "platform-ios", "platform-windows"] +platform-linux = ["linux-secret-service", "linux-keyutils"] +platform-freebsd = ["linux-secret-service"] +platform-macos = ["security-framework"] +platform-ios = ["security-framework"] +platform-windows = ["winapi", "byteorder"] linux-secret-service = ["linux-secret-service-rt-async-io-crypto-rust"] linux-secret-service-rt-async-io-crypto-rust = ["secret-service/rt-async-io-crypto-rust"] linux-secret-service-rt-tokio-crypto-rust = ["secret-service/rt-tokio-crypto-rust"] linux-secret-service-rt-async-io-crypto-openssl = ["secret-service/rt-async-io-crypto-openssl"] linux-secret-service-rt-tokio-crypto-openssl = ["secret-service/rt-tokio-crypto-openssl"] linux-no-secret-service = ["linux-default-keyutils"] -linux-default-keyutils = [] +linux-default-keyutils = ["linux-keyutils"] + [dependencies] lazy_static = "1" [target.'cfg(target_os = "macos")'.dependencies] -security-framework = "2.6" +security-framework = { version = "2.6", optional = true } [target.'cfg(target_os = "ios")'.dependencies] -security-framework = "2.6" +security-framework = { version = "2.6", optional = true } [target.'cfg(target_os = "linux")'.dependencies] secret-service = { version = "3", optional = true } -linux-keyutils = { version = "0.2", features = ["std"] } +linux-keyutils = { version = "0.2", features = ["std"], optional = true } [target.'cfg(target_os = "freebsd")'.dependencies] secret-service = { version = "3", optional = true } [target.'cfg(target_os = "windows")'.dependencies] -byteorder = "1.2" -winapi = { version = "0.3", features = ["wincred", "winerror", "errhandlingapi", "minwindef"] } +byteorder = { version = "1.2", optional = true } +winapi = { version = "0.3", features = ["wincred", "winerror", "errhandlingapi", "minwindef"], optional = true } [[example]] name = "iostest" diff --git a/README.md b/README.md index 6249ebf..cce6145 100644 --- a/README.md +++ b/README.md @@ -83,15 +83,44 @@ for details. This crate provides secure storage support for Linux (secret-service and kernel keyutils), -iOS (keychain), macOS (keychain), -and Windows (credential manager). +iOS (keychain), macOS (keychain), and +Windows (credential manager). It also builds on FreeBSD (secret-service), and probably works there, but since neither the maintainers nor GitHub do building and testing on FreeBSD, we can't be sure. -Please file issues if you have questions or problems. +The default features of this crate are set up +to build all the available platform support. +So, for example, if you build on macOS, then +keychain support is enabled by loading +other underlying crates that the keychain +credential store requires. + +On Linux, there are two supported platform +credential stores: the secret-service and +the kernel keyutils, and both are built by default. +If you only want to use one or the other, then +you must turn off default features in your +dependency specification and explicitly +specify the feature for the platform support you +want. For example, you might use +```toml +keyring = { version = "2", default_features = false, features = ["linux-secret-service"] } +``` + +If you don't build any of the platform support features, +then you will get the `mock` keystore as your default. + +PLEASE NOTE: As of version 2.2, turning off the default +feature set will turn off platform support on *all* platforms, +not just on Linux (as was the case before). While this +behavior is a breaking change on Mac, Windows, +and FreeBSD, the behavior on those platforms before was +unintended and undefined (suppressing default features did nothing), +so this is considered a bug fix rather than +a semver-breaking change that requires a major version bump. ## Upgrading from v1 @@ -154,6 +183,7 @@ whether through contributing code, discussion, or bug reports! - @stankec - @steveatinfincia - @Sytten +- @VorpalBlade If you should be on this list, but don't find yourself, please contact @brotskydotcom. diff --git a/build-xplat-binaries.sh b/build-xplat-binaries.sh index 1b0ac1d..6d3c8d7 100644 --- a/build-xplat-binaries.sh +++ b/build-xplat-binaries.sh @@ -1,11 +1,24 @@ #!/bin/bash +echo Rustup and Cargo updates... rustup update cargo update -cargo clippy --target x86_64-unknown-linux-musl -cargo clippy --target x86_64-pc-windows-gnu +echo Clippy no default features... +cargo clippy --no-default-features --target aarch64-unknown-linux-musl +cargo clippy --no-default-features --target aarch64-pc-windows-msvc +cargo clippy --no-default-features --target aarch64-apple-darwin +cargo clippy --no-default-features --target aarch64-apple-ios +echo Clippy default features... +cargo clippy --target aarch64-unknown-linux-musl +cargo clippy --target aarch64-pc-windows-msvc cargo clippy --target aarch64-apple-darwin cargo clippy --target aarch64-apple-ios -cargo build --target x86_64-unknown-linux-musl -cargo build --target x86_64-pc-windows-gnu +echo Compile no default features... +cargo build --no-default-features --target aarch64-unknown-linux-musl +cargo build --no-default-features --target aarch64-pc-windows-msvc +cargo build --no-default-features --target aarch64-apple-darwin +cargo build --no-default-features --target aarch64-apple-ios +echo Compile default features... +cargo build --target aarch64-unknown-linux-musl +cargo build --target aarch64-pc-windows-msvc cargo build --target aarch64-apple-darwin cargo build --target aarch64-apple-ios diff --git a/build-xplat-docs.sh b/build-xplat-docs.sh index f0ce2c6..f4940c2 100644 --- a/build-xplat-docs.sh +++ b/build-xplat-docs.sh @@ -1,5 +1,5 @@ #!/bin/bash -cargo doc --no-deps --target x86_64-unknown-linux-musl $OPEN_DOCS -cargo doc --no-deps --target x86_64-pc-windows-gnu $OPEN_DOCS +cargo doc --no-deps --target aarch64-unknown-linux-musl $OPEN_DOCS +cargo doc --no-deps --target aarch64-pc-windows-msvc $OPEN_DOCS cargo doc --no-deps --target aarch64-apple-darwin $OPEN_DOCS cargo doc --no-deps --target aarch64-apple-ios $OPEN_DOCS diff --git a/src/lib.rs b/src/lib.rs index 90a77e0..77209f7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -110,39 +110,64 @@ pub use credential::{Credential, CredentialBuilder}; pub use error::{Error, Result}; // Included keystore implementations and default choice thereof. -// It would be really nice if we could conditionalize multiple declarations, -// but we can't so we have to repeat the conditional on each one. -#[cfg(target_os = "linux")] +pub mod mock; + +#[cfg(all(target_os = "linux", feature = "linux-keyutils"))] pub mod keyutils; -#[cfg(all(target_os = "linux", not(feature = "linux-no-secret-service")))] +#[cfg(all( + target_os = "linux", + feature = "secret-service", + not(feature = "linux-no-secret-service") +))] pub mod secret_service; -#[cfg(all(target_os = "linux", not(feature = "linux-default-keyutils")))] +#[cfg(all( + target_os = "linux", + feature = "secret-service", + not(feature = "linux-default-keyutils") +))] use crate::secret_service as default; -#[cfg(all(target_os = "linux", feature = "linux-default-keyutils"))] +#[cfg(all( + target_os = "linux", + feature = "linux-keyutils", + any(feature = "linux-default-keyutils", not(feature = "secret-service")) +))] use keyutils as default; +#[cfg(all( + target_os = "linux", + not(feature = "secret-service"), + not(feature = "linux-keyutils") +))] +use mock as default; -#[cfg(target_os = "freebsd")] +#[cfg(all(target_os = "freebsd", feature = "secret-service"))] pub mod secret_service; -#[cfg(target_os = "freebsd")] +#[cfg(all(target_os = "freebsd", feature = "secret-service"))] use crate::secret_service as default; +#[cfg(all(target_os = "freebsd", not(feature = "secret-service")))] +use mock as default; -#[cfg(target_os = "windows")] -pub mod windows; -#[cfg(target_os = "windows")] -use windows as default; - -#[cfg(target_os = "macos")] +#[cfg(all(target_os = "macos", feature = "platform-macos"))] pub mod macos; -#[cfg(target_os = "macos")] +#[cfg(all(target_os = "macos", feature = "platform-macos"))] use macos as default; +#[cfg(all(target_os = "macos", not(feature = "platform-macos")))] +use mock as default; -#[cfg(target_os = "ios")] +#[cfg(all(target_os = "windows", feature = "platform-windows"))] +pub mod windows; +#[cfg(all(target_os = "windows", not(feature = "platform-windows")))] +use mock as default; +#[cfg(all(target_os = "windows", feature = "platform-windows"))] +use windows as default; + +#[cfg(all(target_os = "ios", feature = "platform-ios"))] pub mod ios; -#[cfg(target_os = "ios")] +#[cfg(all(target_os = "ios", feature = "platform-ios"))] use ios as default; +#[cfg(all(target_os = "ios", not(feature = "platform-ios")))] +use mock as default; -pub mod mock; #[cfg(not(any( target_os = "linux", target_os = "freebsd",