Code Monkey home page Code Monkey logo

secret-service-rs's Introduction

Secret Service

Secret Service Rust library.

Interfaces with the Linux Secret Service API through dbus.

Documentation

Get Docs!

Basic Usage

secret-service is implemented in pure Rust by default, so it doesn't require any system libraries such as libdbus-1-dev or libdbus-1-3 on Ubuntu.

In Cargo.toml:

When adding the crate, you must select a feature representing your selected runtime and cryptography backend. For example:

[dependencies]
secret-service = { version = "3.0.0", features = ["rt-tokio-crypto-rust"] }

Available feature flags:

  • rt-async-io-crypto-rust: Uses the async-std runtime and pure Rust crytography via RustCrypto.
  • rt-async-io-crypto-openssl: Uses the async-std runtime and OpenSSL as the cryptography provider.
  • rt-tokio-crypto-rust: Uses the tokio runtime and pure Rust cryptography via RustCrypto.
  • rt-tokio-crypto-openssl: Uses the tokio runtime and OpenSSL as the cryptography provider.

Note that the -openssl feature sets require OpenSSL to be available on your system, or the bundled feature of openssl crate must be activated in your cargo dependency tree instead.

In source code (below example is for --bin, not --lib). This example uses tokio as the async runtime.

use secret_service::SecretService;
use secret_service::EncryptionType;
use std::{collections::HashMap, error::Error};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // initialize secret service (dbus connection and encryption session)
    let ss = SecretService::connect(EncryptionType::Dh).await?;

    // get default collection
    let collection = ss.get_default_collection().await?;

    // create new item
    collection.create_item(
        "test_label", // label
        HashMap::from([("test", "test_value")]), // properties
        b"test_secret", // secret
        false, // replace item with same attributes
        "text/plain" // secret content type
    ).await?;

    // search items by properties
    let search_items = ss.search_items(
        HashMap::from([("test", "test_value")])
    ).await?;

    let item = search_items.unlocked.get(0).ok_or("Not found!")?;

    // retrieve secret from item
    let secret = item.get_secret().await?;
    assert_eq!(secret, b"test_secret");

    // delete item (deletes the dbus object, not the struct instance)
    item.delete().await?;
    Ok(())
}

Functionality

  • SecretService: initialize dbus, create plain/encrypted session.
  • Collections: create, delete, search.
  • Items: create, delete, search, get/set secret.

Changelog

See the changelog file

Versioning

This library is feature complete, has stabilized its API for the most part. However, as this crate is almost soley reliable on the zbus crate, we try and match major version releases with theirs to handle breaking changes and move with the wider zbus ecosystem.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

secret-service-rs's People

Contributors

alex avatar bstrie avatar cogitri avatar complexspaces avatar connor4312 avatar cuviper avatar decathorpe avatar hwchen avatar jkhsjdhjs avatar petrochenkov avatar repi avatar reticulis avatar steveatinfincia avatar wgh- avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

secret-service-rs's Issues

Compatibility with musl

It seems that secret-service dynamically links system libraries, which means means you can't use keyring to create statically linked musl binaries:

ldd target/x86_64-unknown-linux-musl/debug/foo
        linux-vdso.so.1 (0x00007ffed8b6c000)
        libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007f9abedeb000)
        libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007f9abeb9e000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9abe7ad000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9abe58e000)
        libsystemd.so.0 => /lib/x86_64-linux-gnu/libsystemd.so.0 (0x00007f9abe30a000)
        /lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007f9abf06c000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f9abe102000)
        liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f9abdedc000)
        liblz4.so.1 => /usr/lib/x86_64-linux-gnu/liblz4.so.1 (0x00007f9abdcc0000)
        libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20 (0x00007f9abd9a5000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9abd7a1000)
        libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007f9abd58c000)

Example main.rs, compiled with cargo build --target x86_64-unknown-linux-musl:

extern crate keyring;

use keyring::Keyring;

fn main() {
    let keyring = Keyring::new("foo", "bar");
    keyring.get_password();
}

It would be great if secret-service/keyring supported static linking.

ZBus 2.0

Currently ZBus 2.0 is still in beta, but it'd probably not be a bad idea to start porting now so we can test the beta release before the final release.

v1.0 checklist

I think that before 1.0, I'd like to resolve the dependencies situation.

  • remove rust-crypto, use RustCrypto.
  • remove dbus, use dbus-bytestream (need to investigate)
  • remove libgmp

I think that this would address most outstanding feature requests (like relying on maintained crypto, static linking).

Investigate adding `dbus` backend and feature flag

There are some users who would prefer to use the dbus crate (and associated C library) over zbus, primarily to avoid Rust async runtime dependencies. In order to integrate this, I propose that method implementations for both the primary async and blocking module are moved into zbus specific implementation modules. After that, a dbus specific module can be added that implements both an async and synchronous backend and the module enabled at compile time will depend on a Cargo flag (defaulting to zbus).

This has been requested a few times before, see the following comments:

Linux compatibility

Hello, I've just been block on a project which use keyring-rs. When I try to use secret-service on my manjaro desktop I get the following error:

Error: Zbus(MethodError("org.freedesktop.DBus.Error.ServiceUnknown", Some("The name org.freedesktop.secrets was not provided by any .service files"), Msg { type: Error, sender: "org.freedesktop.DBus", reply-serial: 2, body: Signature: [
        s (115),
] }))

I have libsecret already installed, so I don't know what are the preprerequisite to have this crate working without troubles. I've tried the example from the home page and I get this error when trying to create a SecretService.

Thanks in advance for your help figuring what is the issue

Allow changing of dbus name?

When trying to run a flatpak'd application, this crate will fail with unable to store token: SecretServiceError(Dbus(D-Bus error: org.freedesktop.DBus.Error.ServiceUnknown (org.freedesktop.DBus.Error.ServiceUnknown))) if the application is not allowed to talk to the host secrets dbus. Flatpak does, however, provide a local dbus portal which stores the keychain on the application side (see https://github.com/flatpak/xdg-desktop-portal/) for more. Would it be possible to allow configuring the dbus name to something other than the default? In this case, it would be org.freedesktop.portal.secrets, or similar.

Cargo audit warnings due to rustsec advisories

Bumping the aes dependency to 0.7 should fix this. Don't know how many code changes this requires.

$ cargo audit
    Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
      Loaded 298 security advisories (from /home/herold/.cargo/advisory-db)
    Updating crates.io index
    Scanning Cargo.lock for vulnerabilities (199 crate dependencies)
     Success No vulnerable packages found

warning: 1 warning found

Crate:  aes-soft
Title:  merged into the `aes` crate
Date:   2021-04-29
URL:    https://rustsec.org/advisories/RUSTSEC-2021-0060
Dependency tree: 
aes-soft 0.6.4
└── aes 0.6.0
    └── secret-service 2.0.1
        └── pika-backup 0.3.0-beta.2

Crate:  aesni
Title:  merged into the `aes` crate
Date:   2021-04-29
URL:    https://rustsec.org/advisories/RUSTSEC-2021-0059
Dependency tree: 
aesni 0.10.0
└── aes 0.6.0
    └── secret-service 2.0.1
        └── pika-backup 0.3.0-beta.2

warning: 1 warning found!

Source on main is at version 3, crates.io is still at version 2.0.2?

@complexspaces I'm finally getting around to the next release of the keyring-rs crate, and I'm trying to figure out which released version of secret-service it should use. I am going to stay with dbus (rather than zbus) because I don't want to force my clients to use an async runtime, so in that sense I could stay with 2.0.2, but then again I'd like to include the unlock improvements of a269ee7 by @jkhsjdhjs, which are only in 3.0. Are you going to release 3.0 to crates.io anytime soon? And will I be able to use feature flags to stay with the dbus interface in 3.0?

cc @Sytten, @landhb

zbus pulls in async-io

A lot of us are using tokio instead. There's a feature flag to build zbus with Tokio internals, but we would need to transitively expose this as a feature on secret-service.

Document crate's public API

We want to enable the missing_docs Clippy lint in CI. However, there are 39 items that are missing documentation.

This issue is for tracking the documentation work required for this.

Failure to unlock a collection

I have got a bug downstream about a crash caused by calling Collection::unlock

Zbus(MethodError("org.freedesktop.DBus.Error.InvalidArgs", Some("Invalid properties"), Msg { type: Error, sender: ":1.11", reply-serial: 4, body: Signature: [
	s (115),
] }))', src/application.rs:290:14

Please fail with KeyringError::NoBackendFound when there is no org.freedesktop.secrets available

When there is no Secret Service implementation available (i.e. connecting to D-Bus was successful, but there is no org.freedesktop.secrets service), the error is KeyringError::SecretServiceError(SsError::Dbus), where the name of the underlying dbus::Error is org.freedesktop.DBus.Error.ServiceUnknown.

In this situation, the keyring call should probably fail with KeyringError::NoBackendFound instead.

Failure to connect to D-Bus (because there is no session bus, and auto-starting it failed) should probably also result in KeyringError::NoBackendFound, but there doesn't appear to be a well-defined error name for that situation. Potential error names include org.freedesktop.DBus.Error.NoServer, org.freedesktop.DBus.Error.FileNotFound, or org.freedesktop.DBus.Error.NotSupported (not an exhaustive list).

Return locked and unlocked items independently in search_items

The current implementation of search_items, which performs a Service.SearchItems call, returns unlocked and locked items in a single vector. This leaves applications using this library no way of determining which items require unlocking and which do not (besides additional dbus calls of course). Since the function retrieves locked and unlocked items independently, I don't see why it shouldn't return them separately as well.

If this proposal is accepted I'd be happy to provide a PR.

See also: hwchen/keyring-rs#84
/cc @brotskydotcom

dbus dependency update

Hello,

Is there any plans to upgrade the dbus dependency to something more recent (current version 0.2.3 was released back in 2016)?
That would help with downstream distribution in, ex., Linux distribution as the packaged dbus crate might not be that old.

Thanks in advance,

Automatically fallback if a `default` Linux keyring is not available?

I recently enabled systemd under WSL and tried our application there. I ran into a problem that credentials were not getting stored correctly, and using gdbus introspect found that there was only a session ('/org/freedesktop/secrets/collection/session') credential collection, and no default collection.

I wondered whether it would be appropriate for this crate to automatically fallback to the session collection (i.e. get_any_collection() from SS) if the default collection doesn't exist.

Publish a new release

Zbus 2.0 didn't end up coming as fast as I personally expected given the speed of the alpha releases (this is not a bad thing, though). However, I think it would be beneficial to publish a new release in order to do a few things for downstream users:

  • Establish the higher MSRV and make it less of a surprise to anyone who updates later on.
  • Remove deprecated dependencies (aesni and aessoft) from downstream user's trees.

This would probably be version 2.1.0, as to avoid breaking anyone with a lower Rust compiler in a SemVer patch release.

@hwchen is this something you have time to look at soon?

Invalid properties when creating collection

Currently when creating a collection this key org.freedesktop.Secret.Item.Label is being used, which I think causes the error. Based on the latest spec for the org.freedesktop.Secret.Service.CreateCollection method it expects a org.freedesktop.Secret.Collection.Label.

running 1 test
test test::should_create_and_delete_collection ... FAILED

failures:

---- test::should_create_and_delete_collection stdout ----
thread 'test::should_create_and_delete_collection' panicked at 'called `Result::unwrap()` on an `Err` value: Zbus(MethodError("org.freedesktop.DBus.Error.InvalidArgs", Some("Invalid properties"), Msg { type: Error, sender: ":1.23", reply-serial: 3, body: Signature: [
	s (115),
] }))', src/lib.rs:359:64
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    test::should_create_and_delete_collection

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 31 filtered out


Allow communication via the secret-service portal

Right now apps using secret-service have to punch a hole through the Flatpak sandbox to allow communication with org.freedesktop.secrets . Secret-service should provide the capability to use the secrets portal so this isn't necessary anymore.

ashpd's SecretProxy can be used for this.

Plan for crypto

There's a couple things I'd like to do to make the crypto side of this lib more robust for the future:

  • remove dependency on unmaintained rust-crypto, hopefully upgrade to ring
  • remove dependency on rand and move to ring for rng.
  • rust-gmp is currently only used for powm. Consider implementing own powm to remove gmp dependency (do some performance comparison first)

The overall idea is to reduce dependencies, and to switch away from unmaintained libraries.

#3

Cryptic error if no keychain exists

Hi,

while debugging a problem with a user we successfully reproduced the following behaviour on a new ubuntu machine:

When trying to get or set a password and no secrets have been set up so far (so no password for the default keychain has been set), the following error gets displayed:

No such interface \'org.freedesktop.DBus.Properties'

Reproduce steps:

  1. Create a new VM using Ubuntu 16.04 LTS
  2. Try setting or getting a password using this library (I use keychain-rs in saml2aws-auto so you could run saml2aws-auto groups add bla --role asdf --prefix asdf, enter gibberish for URL, Username and Password and you'll see the error)
  3. Setup a default keychain by using secret-tool (secret-tool store --label="test" foo bar)
  4. Retry step 2 and it will work now

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.