Skip to content

Commit 53eda7d

Browse files
Merge pull request #243 from brotskydotcom/v5
First alpha of v4
2 parents ee3f80d + 67567df commit 53eda7d

18 files changed

+238
-1028
lines changed

.github/workflows/ci.yaml

+22-22
Original file line numberDiff line numberDiff line change
@@ -37,37 +37,28 @@ jobs:
3737
- name: Build and Test
3838
env:
3939
RUST_LOG: debug
40-
run: cargo test --features=apple-native,windows-native --verbose
40+
run: cargo test --verbose
4141

4242
- name: Build the CLI release
43-
run: cargo build --release --features=apple-native,windows-native --example keyring-cli
43+
run: cargo build --release --example keyring-cli
4444

4545
ci_nix:
4646
runs-on: ubuntu-latest
4747
strategy:
4848
matrix:
49-
features:
50-
- "linux-native"
51-
- "sync-secret-service"
52-
- "linux-native,sync-secret-service"
53-
- "sync-secret-service,crypto-rust"
54-
- "sync-secret-service,crypto-openssl"
55-
- "async-secret-service,tokio,crypto-rust"
56-
- "async-secret-service,async-io,crypto-rust"
57-
- "async-secret-service,tokio,crypto-openssl"
58-
- "async-secret-service,async-io,crypto-openssl"
59-
- "linux-native-sync-persistent,crypto-rust"
60-
- "linux-native-sync-persistent,crypto-openssl"
61-
- "linux-native-async-persistent,tokio,crypto-rust"
62-
- "linux-native-async-persistent,async-io,crypto-rust"
63-
- "linux-native-async-persistent,tokio,crypto-openssl"
64-
- "linux-native-async-persistent,async-io,crypto-openssl"
49+
features: ['', 'encrypted', 'vendored']
6550

6651
steps:
67-
- name: Install CI dependencies
52+
- name: Install secret service
6853
run: |
6954
sudo apt update -y
70-
sudo apt install -y libdbus-1-dev libssl-dev gnome-keyring
55+
sudo apt install -y gnome-keyring
56+
57+
- name: Install dbus dynamic lib
58+
if: matrix.features != 'vendored'
59+
run: |
60+
sudo apt update -y
61+
sudo apt install -y libdbus-1-dev
7162
7263
- name: Fetch head
7364
uses: actions/checkout@v4
@@ -76,6 +67,7 @@ jobs:
7667
uses: actions-rust-lang/setup-rust-toolchain@v1
7768
with:
7869
toolchain: stable
70+
components: rustfmt, clippy
7971

8072
- name: Cache dependencies
8173
uses: actions/cache@v4
@@ -86,6 +78,14 @@ jobs:
8678
target
8779
key: $test-cache-${{ steps.toolchain.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }}
8880

81+
- name: Format check
82+
if: matrix.features != 'vendored'
83+
run: cargo fmt --all -- --check
84+
85+
- name: Clippy check
86+
if: matrix.features != 'vendored'
87+
run: cargo clippy -- -D warnings
88+
8989
- name: Start gnome-keyring
9090
# run gnome-keyring with 'foobar' as password for the login keyring
9191
# this will create a new login keyring and unlock it
@@ -124,8 +124,8 @@ jobs:
124124
- name: Install rust MSRV
125125
uses: actions-rust-lang/setup-rust-toolchain@v1
126126
with:
127-
toolchain: 1.75
127+
toolchain: 1.85
128128
components: clippy
129129

130130
- name: Clippy check
131-
run: cargo clippy --features=linux-native -- -D warnings
131+
run: cargo clippy --features=vendored -- -D warnings

.github/workflows/doctest.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ jobs:
3232

3333
- name: Build docs
3434
run: |
35-
FEATURES="apple-native, windows-native, linux-native-sync-persistent, crypto-rust"
3635
RUSTDOCFLAGS="--cfg docsrs" \
3736
cargo +nightly doc --no-deps --features "$FEATURES" --target ${{ matrix.target }} -Zbuild-std
3837

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## Version 4.0
2+
- Remove all keystores but apple-native, windows-native, and secret-service.
3+
- Remove use of the async secret-service crate.
4+
- Remove ability to use openssl crypto with secret-service.
5+
- Rework the feature set.
6+
- Rework the way the "default" credential builder is set.
7+
- Move to Rust edition 2024, MSRV 1.85
8+
19
## Version 3.6.2
210
- Have docs.rs build docs for all modules on all platforms (thanks to @unkcpz - see #235).
311
- Switch to `fastrand` for tests (see #237).

Cargo.toml

+19-37
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,42 @@
22
authors = ["Walther Chen <[email protected]>", "Daniel Brotsky <[email protected]>"]
33
description = "Cross-platform library for managing passwords/credentials"
44
homepage = "https://github.com/hwchen/keyring-rs"
5-
keywords = ["password", "credential", "keychain", "keyring", "cross-platform"]
5+
keywords = ["password", "credential", "keychain", "secret-service", "cross-platform"]
66
license = "MIT OR Apache-2.0"
77
name = "keyring"
88
repository = "https://github.com/hwchen/keyring-rs.git"
9-
version = "3.6.2"
10-
rust-version = "1.75"
11-
edition = "2021"
9+
version = "4.0.0-alpha.1"
10+
rust-version = "1.85"
11+
edition = "2024"
1212
exclude = [".github/"]
1313
readme = "README.md"
1414

1515
[features]
16-
linux-native = ["dep:linux-keyutils"]
16+
default = ["apple-native", "secret-service", "windows-native"]
17+
18+
## Use the built-in Keychain Services on macOS and iOS
1719
apple-native = ["dep:security-framework"]
20+
## Use the secret-service on *nix.
21+
secret-service = ["dep:dbus-secret-service"]
22+
## Use the built-in credential store on Windows
1823
windows-native = ["dep:windows-sys", "dep:byteorder"]
1924

20-
linux-native-sync-persistent = ["linux-native", "sync-secret-service"]
21-
linux-native-async-persistent = ["linux-native", "async-secret-service"]
22-
sync-secret-service = ["dep:dbus-secret-service"]
23-
async-secret-service = ["dep:secret-service", "dep:zbus"]
24-
crypto-rust = ["dbus-secret-service?/crypto-rust", "secret-service?/crypto-rust"]
25-
crypto-openssl = ["dbus-secret-service?/crypto-openssl", "secret-service?/crypto-openssl"]
26-
tokio = ["zbus?/tokio"]
27-
async-io = ["zbus?/async-io"]
28-
vendored = ["dbus-secret-service?/vendored", "openssl?/vendored"]
25+
## Link any external required libraries statically
26+
vendored = ["dbus-secret-service?/vendored"]
27+
## Encrypt values when passing them to/from the keystore, if supported.
28+
encrypted = []
2929

3030
[dependencies]
31-
log = "0.4.22"
32-
openssl = { version = "0.10.66", optional = true }
31+
log = "0.4"
3332

34-
[target.'cfg(target_os = "macos")'.dependencies] # see issue #190
33+
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
3534
security-framework = { version = "3", optional = true }
3635

37-
[target.'cfg(target_os = "ios")'.dependencies] # see issue #190
38-
security-framework = { version = "2", optional = true }
39-
40-
[target.'cfg(target_os = "linux")'.dependencies]
41-
secret-service = { version = "4", optional = true }
42-
zbus = { version = "4", optional = true }
43-
linux-keyutils = { version = "0.2", features = ["std"], optional = true }
44-
dbus-secret-service = { version = "4.0.0-rc.2", optional = true }
45-
46-
[target.'cfg(target_os = "freebsd")'.dependencies]
47-
secret-service = { version = "4", optional = true }
48-
zbus = { version = "4", optional = true }
49-
dbus-secret-service = { version = "4.0.1", optional = true }
50-
51-
[target.'cfg(target_os = "openbsd")'.dependencies]
52-
secret-service = { version = "4", optional = true }
53-
zbus = { version = "4", optional = true }
54-
dbus-secret-service = { version = "4.0.0-rc.1", optional = true }
36+
[target.'cfg(any(target_os = "linux",target_os = "freebsd", target_os = "openbsd"))'.dependencies]
37+
dbus-secret-service = { version = "4", features = ["crypto-rust"], optional = true }
5538

5639
[target.'cfg(target_os = "windows")'.dependencies]
57-
byteorder = { version = "1.2", optional = true }
40+
byteorder = { version = "1", optional = true }
5841
windows-sys = { version = "0.59", features = ["Win32_Foundation", "Win32_Security_Credentials"], optional = true }
5942

6043
[[example]]
@@ -79,4 +62,3 @@ whoami = "1.5"
7962
[package.metadata.docs.rs]
8063
default-target = "x86_64-unknown-linux-gnu"
8164
targets = ["x86_64-unknown-linux-gnu", "aarch64-apple-darwin", "aarch64-apple-ios", "x86_64-pc-windows-msvc"]
82-
features = ["apple-native", "windows-native", "linux-native-sync-persistent", "crypto-rust"]

README.md

+17-26
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ A cross-platform library to manage storage and retrieval of passwords (and other
99

1010
## Usage
1111

12-
To use this crate in your project, you must include it in your `Cargo.toml` and specify a feature for each supported credential store you want to use. For example, if you want to use the platform credential stores on Mac and Win, and use the Secret Service (synchronously) on Linux and \*nix platforms, you would add a snippet such as this to your `[dependencies]` section:
12+
To use this crate in your project, include it in your `Cargo.toml` and don't disable the default features:
1313

1414
```toml
15-
keyring = { version = "3", features = ["apple-native", "windows-native", "sync-secret-service"] }
15+
keyring = "4"
1616
```
1717

1818
This will give you access to the `keyring` crate in your code. Now you can use the `Entry::new` function to create a new keyring entry. The `new` function takes a service name and a user's name which together identify the entry.
1919

20-
Passwords (strings) or secrets (binary data) can be added to an entry using its `set_password` or `set_secret` methods, respectively. (These methods create an entry in the underlying credential store.) The password or secret can then be read back using the `get_password` or `get_secret` methods. The underlying credential (with its password/secret data) can then be removed using the `delete_credential` method.
20+
Passwords (strings) or secrets (binary data) can be added to an entry using its `set_password` or `set_secret` methods, respectively. (These methods create an entry in the underlying platform's persistent credential store.) The password or secret can then be read back using the `get_password` or `get_secret` methods. The underlying credential (with its password/secret data) can then be removed using the `delete_credential` method.
2121

2222
```rust
2323
use keyring::{Entry, Result};
@@ -40,9 +40,9 @@ Creating and operating on entries can yield a `keyring::Error` which provides bo
4040

4141
The keychain-rs project contains a sample application (`keyring-cli`) and a sample library (`ios`).
4242

43-
The `keyring-cli` application is a command-line interface to the full functionality of the keyring. Invoke it without arguments to see usage information. It handles binary data input and output using base64 encoding. It can be installed using `cargo install` and used to experiment with library functionality. It can also be used when debugging keyring-based applications to probe the contents of the credential store; just be sure to build it using the same features/credential stores that are used by your application.
43+
The `keyring-cli` application is a command-line interface to the full functionality of the keyring. Invoke it without arguments to see usage information. It handles binary data input and output using base64 encoding. It can be installed using `cargo install` and used to experiment with library functionality. It can also be used when debugging keyring-based applications to probe the contents of the credential store.
4444

45-
The `ios` library is a full exercise of all the iOS functionality; it's meant to be loaded into an iOS test harness such as the one found in [this project](https://github.com/brotskydotcom/rust-on-ios). While the library can be compiled and linked to on macOS as well, doing so doesn't provide any advantages over using the crate directly.
45+
The `ios` library is a full exercise of all the iOS functionality; it's meant to be loaded into an iOS test harness such as the one found in [this project](https://github.com/brotskydotcom/rust-on-ios).
4646

4747
## Client Testing
4848

@@ -56,44 +56,35 @@ This crate allows clients to "bring their own credential store" by providing tra
5656

5757
This crate provides built-in implementations of the following platform-specific credential stores:
5858

59-
* _Linux_: The DBus-based Secret Service, the kernel keyutils, and a combo of the two.
60-
* _FreeBSD_, _OpenBSD_: The DBus-based Secret Service.
61-
* _macOS_, _iOS_: The local keychain.
59+
* _Linux_, _FreeBSD_, _OpenBSD_: The DBus-based Secret Service.
60+
* _macOS_, _iOS_: Keychain Services.
6261
* _Windows_: The Windows Credential Manager.
6362

64-
To enable the stores you want, you use features: there is one feature for each possibly-included credential store. If you specify a feature (e.g., `dbus-secret-service`) _and_ your target platform (e.g., `freebsd`) supports that credential store, it will be included as the default credential store in that build. That way you can have a build command that specifies a single credential store for each of your target platforms, and use that same build command for all targets.
65-
66-
If you don't enable any credential stores that are supported on a given platform, the _mock_ keystore will be the default on that platform. See the [developer docs](https://docs.rs/keyring/) for details of which features control the inclusion of which credential stores.
67-
6863
### Platform-specific issues
6964

7065
Since neither the maintainers nor GitHub do testing on BSD variants, we rely on contributors to support these platforms. Thanks for your help!
7166

7267
If you use the *Secret Service* as your credential store, be aware of the following:
7368

74-
* Access to credential stores via this crate is always *synchronous*; that is, it blocks the thread on which it was invoked. This is true *even if* your feature set specifies using the Zbus-based `secret-service` crate, which offers an async interface, because this crate always uses the blocking interface. If your application is using an async runtime already, and you build with the `async-secret-service` feature in this crate, you should (1) specify the same async runtime you are using as a feature for this crate, and (2) be sure to have a separate thread that is used for all `keyring` calls that access the credential store. Failure to use a separate thread is known to cause deadlocks.
75-
* Because credential store access from this crate is always synchronous, there is really no reason not to use the `sync-secret-service` feature (rather than `async-secret-service`) with this crate, *even if* your code is already using one of the async runtimes. Yes, this feature requires that `libdbus` be installed on your user’s machines, but it is by default in all desktop OS installs that include a Secret Service implementation (such as the Gnome Keyring or the KWallet). If you want to be extra careful, you can use the additional `vendored` feature to this crate to statically link the dbus library with your app so it’s not required on user machines. Just keep in mind that, in the event of an update to `libdbus`, using the `vendored` feature will require a rebuild of your app to get the `libdbus` update to your users.
76-
* Every call to the Secret Service is done via an inter-process call, which takes time (typically tens if not hundreds of milliseconds). If, for some reason, your code is pounding on the Secret Service like a database, you will want to implement a write-through transactional backing cache to protect your users from slowdowns. The `mock` credential store can be adapted for this purpose.
69+
* This implementation requires that `libdbus` be installed on user machines. If you have users whose machines might not have `libdbus` installed, you can specify the `vendored` when building this crate to statically link the dbus library with your app.
70+
* Every call to the Secret Service is done via an inter-process call, which takes time (typically tens if not hundreds of milliseconds).
71+
* By default, this implementation does not encrypt secrets when sending them to or fetching them from the Dbus. If you want them encrypted, you can specify the `encrypted` feature when building this crate.
7772

7873
If you use the *Windows-native credential store*, be careful about multi-threaded access, because the Windows credential store does not guarantee your calls will be serialized in the order they are made. Always access any single credential from just one thread at a time, and if you are doing operations on multiple credentials that require a particular serialization order, perform all those operations from the same thread.
7974

80-
The *macOS and iOS credential stores* do not allow service or user names to be empty, because empty fields are treated as wildcards on lookup. Use some default, non-empty value instead.
81-
82-
## Upgrading from v2
83-
84-
The major functional change between v2 and v3 is the addition of synchronous support for the Secret Service via the [dbus-secret-service crate](https://crates.io/crates/dbus-secret-service). This means that keyring users of the Secret Service no longer need to link with an async runtime. (There are other advantages as well; see [above](#platform-specific-issues) for details.)
75+
The *macOS and iOS credential stores* do not allow service names or usernames to be empty, because empty fields are treated as wildcards on lookup. Use some default, non-empty value instead.
8576

86-
The main API change between v2 and v3 is the addition of support for non-string (i.e., binary) "password" data. To accommodate this, two changes have been made:
77+
## Upgrading from v3
8778

88-
1. There are two new methods on `Entry` objects: `set_secret` and `get_secret`. These are the analogs of `set_password` and `get_password`, but instead of taking or returning strings they take or return binary data (byte arrays/vectors).
79+
There are no functional API changes between v4 and v3; all the changes are in the keystores and how they are specified.
8980

90-
2. The v2 method `delete_password` has been renamed `delete_credential`, both to clarify what's actually being deleted and to emphasize that it doesn't matter whether it's holding a "password" or a "secret".
81+
Version 4 of this crate removes a number of the built-in credential stores that were available in version 3, namely the async secret service and linux keyutils.
9182

92-
Another API change between v2 and v3 is that the notion of a default feature set has gone away: you must now specify explicitly which crate-supported keystores you want included (other than the `mock` keystore, which is always present). So all keyring client developers will need to update their `Cargo.toml` file to use the new features correctly.
83+
Version 4 of this crate also dispenses with the need to explicitly specify which credential store you want to use on each platform. Instead, the default feature set provides a single credential store on each platform. If you would rather bring your own store, and not build this crate's built-in ones, you can simply suppress the default feature set.
9384

94-
All v2 data is fully forward-compatible with v3 data; there have been no changes at all in that respect.
85+
All v2/v3 data is fully forward-compatible with v4 data; there have been no changes at all in that respect.
9586

96-
The MSRV has been moved to 1.75, and all direct dependencies are at their latest stable versions.
87+
The Rust edition of this crate has moved to 2024, and the MSRV has moved to 1.85.
9788

9889
## License
9990

examples/ios.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use keyring::{Entry, Error};
22

3-
#[no_mangle]
3+
#[unsafe(no_mangle)]
44
extern "C" fn test() {
55
test_invalid_parameter();
66
test_empty_keyring();

0 commit comments

Comments
 (0)