Skip to content

Commit 900fd68

Browse files
Merge pull request #215 from brotskydotcom/issue-214
Allow use of both linux-native and secret-service keystores. Make secret-service be the default in this case.
2 parents 27a7b35 + 88c2ae5 commit 900fd68

File tree

5 files changed

+51
-39
lines changed

5 files changed

+51
-39
lines changed

.github/workflows/ci.yaml

+7-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ name: CI
33
on: [ workflow_dispatch, push, pull_request ]
44

55
jobs:
6-
ci_native:
6+
ci_non_nix:
77
runs-on: ${{ matrix.os }}
88
strategy:
99
matrix:
10-
os: [ ubuntu-latest, macos-latest, windows-latest ]
10+
os: [ macos-latest, windows-latest ]
1111

1212
steps:
1313
- name: Fetch head
@@ -35,17 +35,19 @@ jobs:
3535
run: cargo clippy -- -D warnings
3636

3737
- name: Build and Test
38-
run: cargo test --features=apple-native,windows-native,linux-native --verbose
38+
run: cargo test --features=apple-native,windows-native --verbose
3939

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

43-
ci_secret_service:
43+
ci_nix:
4444
runs-on: ubuntu-latest
4545
strategy:
4646
matrix:
4747
features:
48+
- "linux-native"
4849
- "sync-secret-service"
50+
- "linux-native,sync-secret-service"
4951
- "sync-secret-service,crypto-rust"
5052
- "sync-secret-service,crypto-openssl"
5153
- "async-secret-service,tokio,crypto-rust"

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## Version 3.4.0
2+
- Allow use of both secret-service and keyutils.
3+
14
## Version 3.3.0
25
- Add support for credential-store attributes other than those used by this crate. This allows the creation of credentials that are more compatible with 3rd-party clients, such as the OS-provided GUIs over credentials.
36
- Make the textual descriptions of entries consistently follow the form `user@service` (or `user@service:target` if a target was specified).

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ keywords = ["password", "credential", "keychain", "keyring", "cross-platform"]
66
license = "MIT OR Apache-2.0"
77
name = "keyring"
88
repository = "https://github.com/hwchen/keyring-rs.git"
9-
version = "3.3.0"
9+
version = "3.4.0"
1010
rust-version = "1.75"
1111
edition = "2021"
1212
exclude = [".github/"]
@@ -29,7 +29,7 @@ vendored = ["dbus-secret-service?/vendored", "openssl?/vendored"]
2929
openssl = { version = "0.10.55", optional = true }
3030

3131
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies] # see issue #190
32-
security-framework = { version = "2", optional = true }
32+
security-framework = { version = "3", optional = true }
3333

3434
[target.'cfg(target_os = "linux")'.dependencies]
3535
secret-service = { version = "4", optional = true }

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ This crate provides built-in implementations of the following platform-specific
6161
* _macOS_, _iOS_: The local keychain.
6262
* _Windows_: The Windows Credential Manager.
6363

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. (You cannot enable more than one keystore for a given platform, except when producing docs.)
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.
6565

66-
If you don't enable any credential stores that are supported on a specific target, the _mock_ keystore will be the default on that target. If you enable multiple credential stores for a specific target, you will get a compile error. See the [developer docs](https://docs.rs/keyring/) for details of which features control the inclusion of which credential stores (and which platforms each credential store targets).
66+
If you don't enable any credential stores that are supported on a given platform, or you enable multiple credential stores for some 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 (and which platforms each credential store targets).
6767

6868
### Platform-specific issues
6969

@@ -136,6 +136,7 @@ Thanks to the following for helping make this library better, whether through co
136136
- @ryanavella
137137
- @samuela
138138
- @ShaunSHamilton
139+
- @soywod
139140
- @stankec
140141
- @steveatinfincia
141142
- @Sytten

src/lib.rs

+36-30
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ example, the macOS Keychain credential store is only included if the `"apple-nat
6464
feature is specified (and the crate is built with a macOS target).
6565
6666
If no specified credential store features apply to a given platform,
67+
or multiple credential store features apply to a given platform,
6768
this crate will use the (platform-independent) _mock_ credential store (see below)
68-
on that platform. Specifying multiple credential store features for a given
69-
platform is not supported, and will cause compile-time errors. There are no
69+
on that platform. There are no
7070
default features in this crate: you must specify explicitly which platform-specific
7171
credential stores you intend to use.
7272
@@ -99,6 +99,18 @@ Here are the available credential store features:
9999
installed on the user's machine, specify the `vendored` feature
100100
to statically link them with the built crate.
101101
102+
You cannot specify both the `sync-secret-service` and `async-secret-service` features;
103+
this will produce a compile error. You must pick one or the other if you want to use
104+
the secret service for credential storage.
105+
106+
The Linux platform is the only one for which this crate supplies multiple keystores:
107+
secret-service and keyutils. The secret-service is the more widely used store, because
108+
it provides persistence of credentials beyond reboot (which keyutils does not). However,
109+
because secret-service relies on system UI for unlocking credentials, it often isn't
110+
available on headless Linux installations, so keyutils is provided for those situations.
111+
If you enable both the secret-service store and the keyutils store, the secret-service
112+
store will be used as the default.
113+
102114
## Client-provided Credential Stores
103115
104116
In addition to the platform stores implemented by this crate, clients
@@ -168,31 +180,22 @@ use std::collections::HashMap;
168180
pub mod mock;
169181

170182
//
171-
// no duplicate keystores on any platform
183+
// can't use both sync and async secret service
172184
//
173-
#[cfg(all(
174-
not(doc),
175-
any(
176-
all(feature = "linux-native", feature = "sync-secret-service"),
177-
all(feature = "linux-native", feature = "async-secret-service"),
178-
all(feature = "sync-secret-service", feature = "async-secret-service")
179-
)
180-
))]
181-
compile_error!("You can enable at most one keystore per target architecture");
185+
#[cfg(all(feature = "sync-secret-service", feature = "async-secret-service"))]
186+
compile_error!("This crate cannot use the secret-service both synchronously and asynchronously");
182187

183188
//
184-
// Pick the *nix keystore
189+
// pick the *nix keystore
185190
//
186191

187192
#[cfg(all(target_os = "linux", feature = "linux-native"))]
188193
pub mod keyutils;
194+
// use keyutils as default if secret-service is not available
189195
#[cfg(all(
190196
target_os = "linux",
191197
feature = "linux-native",
192-
not(all(
193-
doc,
194-
any(feature = "sync-secret-service", feature = "async-secret-service")
195-
))
198+
not(any(feature = "sync-secret-service", feature = "async-secret-service"))
196199
))]
197200
pub use keyutils as default;
198201

@@ -201,24 +204,27 @@ pub use keyutils as default;
201204
any(feature = "sync-secret-service", feature = "async-secret-service")
202205
))]
203206
pub mod secret_service;
207+
// use secret-service as default if it's available
204208
#[cfg(all(
205209
any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"),
206-
any(feature = "sync-secret-service", feature = "async-secret-service")
210+
any(feature = "sync-secret-service", feature = "async-secret-service"),
207211
))]
208212
pub use secret_service as default;
209213

210-
#[cfg(all(
211-
target_os = "linux",
212-
not(any(
213-
feature = "linux-native",
214-
feature = "sync-secret-service",
215-
feature = "async-secret-service"
216-
))
217-
))]
218-
pub use mock as default;
219-
#[cfg(all(
220-
any(target_os = "freebsd", target_os = "openbsd"),
221-
not(any(feature = "sync-secret-service", feature = "async-secret-service"))
214+
// fallback to mock if neither keyutils nor secret service is available
215+
#[cfg(any(
216+
all(
217+
target_os = "linux",
218+
not(any(
219+
feature = "linux-native",
220+
feature = "sync-secret-service",
221+
feature = "async-secret-service"
222+
))
223+
),
224+
all(
225+
any(target_os = "freebsd", target_os = "openbsd"),
226+
not(any(feature = "sync-secret-service", feature = "async-secret-service"))
227+
)
222228
))]
223229
pub use mock as default;
224230

0 commit comments

Comments
 (0)