It’s a really long-read post and I wast sure if it’s better to split it into three parts or put them together. On the one side, there are keyrings, from another — D-Bus, and finally, there is a Secret Service.

Eventually, I decided to keep them here together as I googled all it in the same scope and the are related to each other.

So, in this post we will speak about the next:

what is the keyring at all

at all what is the difference between the Linux keyring and GNOME keyring , and do they relate to each other

and , and do they relate to each other which keyring implementations are

what is the org.freedesktop Secret Service and how it relates to the GNOME keyring

and how it relates to the what is D-Bus , and how we can use it to see how a keyring service is working

, and how we can use it to see how a keyring service is working and a couple of examples with Linux Keyring, GNOME Keyring, KWallet, and KeePass as keyring backends

This post is absolutely not kind of “tutorial” with “HowTo Configure it” but instead — just an overview of the components mentioned above to try to understand what they are and how they can be used.

A real example of how to configure KeePass and maybe GNOME Keyring we will see the following posts.

This post was written by a long-long googling, so here will be a lot of links that were used documents and other materials.

I may confuse something or even understood in a wrong way, so please welcome to the comments, if you’ll see any errors.

The post’s writing process was like this:

Contents

What is the Keyring?

To start what the “keyring” word means at all?

Let’s start with Wikipedia — https://en.wikipedia.org/wiki/Keyring_(cryptography):

In cryptography, a keyring stores known encryption keys (and, in some cases, passwords).

Then, let’s proceed with the GNOME project documentation — https://help.gnome.org/users/seahorse/stable/keyring.html.en:

Much like a keyring in real life allows you to keep certain sets of keys together, a keyring in Passwords and Keys allows you to keep passwords and keys in separate groups.

And even let’s take a look at the MySQL documentation — https://dev.mysql.com/doc/refman/5.7/en/keyring-service.html:

a keyring service that enables internal server components and plugins to securely store sensitive information for later retrieval

Finally, take a look at the keyrings(7) man-page — http://man7.org/linux/man-pages/man7/keyrings.7.html:

The Linux key-management facility is primarily a way for various kernel components to retain or cache security data, authentication keys, encryption keys, and other data in the kernel.

So, the keyring concept — it is some mechanism, or facility, or a concrete application, intended to store some confidential data.

Good, let’s go deeper.

Linux keyring vs gnome-keyring

Useful links used:

Now, let’s speak about the difference between the Linux kernel keyring and the GNOME Keyring: at first, I was confused as I suggested that GNOME Keyring somehow uses kernel’s keyrings facility, but now — it’s just different things.

Let’s go back to the man 7 Linux keyrings:

keyrings — in-kernel key management and retention facility

I.e. Linux keyrings — it’s is kernel’s mechanism providing the ability to store secret information.

Now, let’s read the gnome-keyring documentation:

GNOME Keyring is a collection of components in GNOME that store secrets, passwords, keys, certificates and make them available to applications.

So, GNOME Keyring — is a collection of utilities ( gnome-keyring-daemon , libraries, the seahorse package, etc) to store confidential data. See also GNOME Keyring architecture.

Good documents also can be found here — Tower Floor — Encryption, in particular, see the Caching Passwords document.

Summary

Let’s summarize the key differences between Linux keyrings and GNOME Keyring:

main():

Linux kernel — is a kernel’s facility for “passwords caching” — it stores them in a computer’s memory during an active user’s/system session

gnome-keyring - is persistent storage with keeping data on a hard disk

- is persistent storage with keeping data on a hard disk storing:

Linux keyring — store in RAM, thus passwords are available only during a session, there is no need to store them always

gnome-keyring - creates a file on a disk, usually, in the ~/.local/share/keyrings/

- creates a file on a disk, usually, in the accessing:

Linux keyring — via syscalls from the user space into the kernel space

gnome-keyring - via DBus

- via DBus applications to access:

Linux kernel — keyctl , systemd-ask-password , etc

, , etc gnome-keyring - secret-tool , libraries like python-keyring , seahorse , etc

Keyrings implementations

Beside that, python-keyring mention:

gsheet-keyring — a backend that stores secrets in a Google Sheet. For use with ipython-secrets.

bitwarden-keyring — a backend that stores secrets in the BitWarden password manager.

And this list is not full.

Also, there a bunch of client applications to be used with those keyrings, again the list is not full:

Passwords interception from the gnome-keyting

During googling, found an interesting bug discussion here — https://bugs.launchpad.net/ubuntu/+source/gnome-keyring/+bug/1780365

In short:

a client and a service communicates via D-Bus a client ask for some data from the Secret Service ( gnome-keyring in this case) the service via D-Bus send a confidential data another, “bad”, process listens dbus-messages and intercepts a password

What is the Secret Service?

Another one concept I had to google about: what is the “Secret Service”? How it relates to the GNOME Keyring and to the KWallet?

What is it doing in the Linux and how can I touch it?

Well, let’s go to the documentation again — https://specifications.freedesktop.org/secret-service/latest/ch01.html:

The Secret Service API allows client applications to store secrets securely in a service running in the user’s login session.

Aha, i.e. Secret Service — it’s not some particular service or an application, but it’s a specification, kind of an RFC created by the GNOME and KDE projects to determine how this API must be realized for a client which wants to use GNOME Keyring or KWallet to store their secrets.

Also, the Secret Service API supported not only by the GNOME Keyring and KWallet but also for example by the KeePass and other applications.

IMHO, a bit confusing is the Secret Service name itself — “a hidden service”. If it would be called Secrets Service, i.e. “service of a secrets data” — it would be much more clear.

The Secret Service glossary

In short terms:

secret: a password itself, or any other secret data

item: each such a secret plus its set of attributes makes up an item

collection: a set of such items makes a collection (similar to the keyring or wallet concepts)

collections and items represented by D-Bus objects, each with its unique path

default collection: client applications without special conditions have to save items to the default collection which has to be accessible via the /org/freedesktop/secrets/aliases/default D-Bus path

D-Bus

Oookay…

Not its time to try to recall with is the D-Bus so often mentioned in the previous parts, and how to deal with it.

So, the D-Bus on of the Linux kernel IPC — Inter-Process Communication — mechanisms, allowing for separate processes inside of an operating system to communicate with each other.

Useful links:

And in short about main concepts and terms in D-Bus:

D-Bus in general : it’s a “bus” for IPC, i.e. if in the previous SSH examples (see the SSH: RSA keys, and ssh-agent for SSH keys and their passwords management post) a UNIX socket was used, this time we are using the bus mechanism, see the https://www.kernel.org/doc/html/latest/driver-api/driver-model/bus.html. In its turn, those buses can be

: it’s a “bus” for IPC, i.e. if in the previous SSH examples (see the SSH: RSA keys, and ssh-agent for SSH keys and their passwords management post) a UNIX socket was used, this time we are using the bus mechanism, see the https://www.kernel.org/doc/html/latest/driver-api/driver-model/bus.html. In its turn, those buses can be a session bus

a system bus

private buses

messages : a base communication unit, data transfer similar to the TCP/IP, just in the D-Bus all data of a message is included to the message and not split over TCP-packets

: a base communication unit, data transfer similar to the TCP/IP, just in the D-Bus all data of a message is included to the message and not split over TCP-packets when a message is sent usually it leads to some method to be called to execute some actions by an application providing this method

a message can be sent by an application to itself

namespaces and addresses :

and : as various applications can be placed on the same bus (or “listen to the same bus”) and during that the same application can provide various objects which can accept messages, then need to have some way to address those messages. In D-Bus, such an address consists of an interface name + service + an object name

a namespace example — org.freedesktop.dbus

an address example — unix:tmpdir=/tmp/my-app-name

interface : a set of methods and signals on a particular bus f a particular object. You can think of interfaces as named methods and signals group.

: a set of methods and signals on a particular bus f a particular object. You can think of interfaces as named methods and signals group. most of the interfaces will lead to the concrete construction of a language used for an application, for example, it can be a Java interface or a virtual class in С++

an interface example — org.freedesktop.Introspectable

service : represents a concrete connection of a particular application to a bus

: represents a concrete connection of a particular application to a bus under the service here means a bus name (in the origin — “well-known” Bus names), but keep in mind that the “bus name” here implies a particular connection name but not the bus name

if an application has more then one connection to a bus, or if the application is running in multitype instances — expanded by a PID number, for example, to make it unique

a service example — org.kde.screensaver

objects : the same application can provide access to its multiple objects using paths to separate those objects. Each such a path associated with a service represents a dedicated object, for example /MainInterface or /Documents/Doc1 . Objects allow access to interfaces and the same object can provide such access to multiple interfaces at the same time

: the same application can provide access to its multiple objects using paths to separate those objects. Each such a path associated with a service represents a dedicated object, for example or . Objects allow access to interfaces and the same object can provide such access to multiple interfaces at the same time see the https://dbus.freedesktop.org/doc/dbus-tutorial.html#objects

methods : each object has members of the two types — methods and signals

: each object has members of the two types — methods and signals methods — ate messages sent to an object to trigger some action in an application, who created this object

methods can pass data to an application’s input and can return an output with some values from the application

methods always have a sender and receiver addresses

signals :

: are similar to the methods, but are not tied to any specific destination and can be accepted by any application on the same bus

are generated by an application which exported an interface

D-Bus tools

CLI:

qdbus - watch and send messages via D-Bus

- watch and send messages via D-Bus dbus-monitor - view a bus activity

- view a bus activity dbus-send - send messages via D-Bus

GUI:

qdbusviewer - view objects and messages, is a part of the qt5-tools set

- view objects and messages, is a part of the set d-feet - D-Bus debugger

- D-Bus debugger bustle - D-Bus message analyzer and profiler

For example d-feet , install it:

$ sudo pacman -S d-feet

Run it:

Keyrings examples

And a few examples of how those backends can be used from a Python or CLI utilities.

Linux keyring

As already mentioned, the Linux keyring is a kind of “caching service” in the kernel.

You can use the keyctl utility from the keyutils , and systemd-ask-password .

To read about:

And from the documentation:

Each process subscribes to three keyrings: a thread-specific keyring, a process-specific keyring, and a session-specific keyring.

Let’s see which keyrings are available for my current session:

$ keyctl show @s

Session Keyring

185597501 — alswrv 1000 1000 keyring: _ses

182944921 — alswrv 1000 65534 \_ keyring: _uid.1000

Or for my user:

$ keyctl show @u

Keyring

182944921 — alswrv 1000 65534 keyring: _uid.1000

Also, in the /proc/key-users you can get information about all keyrings and their statistics by each user:

$ cat /proc/key-users

0: 43 42/42 34/1000000 768/25000000

971: 1 1/1 1/200 9/20000

1000: 4 4/4 4/200 46/20000

And keys available for reading by our process (the bash which called the cat ):

$ cat /proc/keys

008f6a74 I — Q — — 1 perm 1f3f0000 1000 65534 keyring _uid_ses.1000: 1

0ae78499 I — Q — — 4 perm 1f3f0000 1000 65534 keyring _uid.1000: empty

0b0ffe3d I — Q — — 225 perm 3f030000 1000 1000 keyring _ses: 1

2a28e4fe I — Q — — 33 perm 3f030000 1000 1000 keyring _ses: 1

A user’s keyrings in the current session:

$ keyctl describe @us

-5: -lswrvalswrv — — — — — — 1000 65534 keyring: _uid_ses.1000

Keys in the current keyring:

$ keyctl list @us

1 key in keyring:

182944921: — alswrv 1000 65534 keyring: _uid.1000

Add a key:

$ keyctl add user example-key example-data @u

546850615

Find it:

$ keyctl request user example-key

546850615

Got its ID and now can read its content using this ID:

$ keyctl print 546850615

example-data

keyctl() syscall

Actually, the keyctl utility just executes the keyctl(2) system call:

$ strace -e keyctl keyctl print 546850615

keyctl(KEYCTL_READ, 546850615, NULL, 0) = 12

keyctl(KEYCTL_READ, 546850615, “example-data”, 12) = 12

example-data

+++ exited with 0 +++

In the first call here — keyctl(KEYCTL_READ, 546850615, NULL, 0) = 12 - we performed the keyctl() syscall with passing the KEYCTL_READ operation and a key ID.

Okay — more or less clear here.

Materials used here:

Let’s go to the keyring storages.

gnome-keyring

Really problematic package, as for me, but still it is most widely used.

Install if not present yet:

$ sudo pacman -S gnome-keyring

Check D-Bus services — look for the org.freedesktop.secrets :

$ dbus-send — session — dest=org.freedesktop.DBus — type=method_call — print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames

…

string “org.freedesktop.secrets”

…

“Aha, here we are” ©

Now we can get the service description by using the org.freedesktop.DBus.Introspectable.Introspect method:

$ dbus-send — session — print-reply — dest=org.freedesktop.DBus /org/freedesktop/secrets org.freedesktop.DBus.Introspectable.Introspect

…

<node>

<interface name=”org.freedesktop.DBus”>

<method name=”Hello”>

<arg direction=”out” type=”s”/>

</method>

<method name=”RequestName”>

<arg direction=”in” type=”s”/>

<arg direction=”in” type=”u”/>

<arg direction=”out” type=”u”/>

</method>

<method name=”ReleaseName”>

<arg direction=”in” type=”s”/>

<arg direction=”out” type=”u”/>

</method>

…

Or with the qdbus , fid the service first:

$ qdbus | grep ‘secrets\|keyring’

org.freedesktop.secrets

org.gnome.keyring

Read the qdbus help:

$ qdbus — help

…

With 0 arguments, qdbus will list the services available on the bus

With just the servicename, qdbus will list the object paths available on the service

With service name and object path, qdbus will list the methods, signals and properties available on the object

And get the full service’s description:

$ qdbus org.freedesktop.secrets /org/freedesktop/secrets

signal void org.freedesktop.DBus.Properties.PropertiesChanged(QString interface_name, QVariantMap changed_properties, QStringList invalidated_properties)

method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)

method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name)

method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)

method QString org.freedesktop.DBus.Introspectable.Introspect()

method QString org.freedesktop.DBus.Peer.GetMachineId()

method void org.freedesktop.DBus.Peer.Ping()

…

D-Bus GetConnectionUnixProcessID

Actually, I want to see who is listening on the another side of the bus. Let’s use the GetConnectionUnixProcessID method for this:

$ qdbus — session org.freedesktop.DBus / org.freedesktop.DBus.GetConnectionUnixProcessID org.freedesktop.secrets

1278791

Here we did:

a call to the org.freedesktop.DBus service

passing the / path

called the org.freedesktop.DBus.GetConnectionUnixProcessID method

method and passing the service org.freedesktop.secrets name to the method to get its PID

Check what is the 1278791 PID:

$ ps xu | grep 1278791

setevoy 1278791 0.0 0.0 383876 8092 ? SLl Dec03 0:00 /usr/bin/gnome-keyring-daemon — start — foreground — components=secrets

Nice.

So, now we are knowing that the Secret Service role is played by the gnome-keyring application. Let's try to add and remove some data using the python-keyring and secret-tool .

python-keyring

Start with the python-keyring .

Install it:

$ sudo pacman -S python-keyring

Check:

>>> import keyring

>>> keyring.set_password(“system”, “username”, “password”)

>>> keyring.get_password(“system”, “username”)

‘password’

In case of errors like (can happen on the first run after installation on Arch Linux, for example):

>>> keyring.set_password(“system”, “username”, “password”)

Traceback (most recent call last):

…

jeepney.wrappers.DBusErrorResponse: [org.freedesktop.DBus.Error.UnknownMethod] (‘No such interface “org.freedesktop.DBus.Properties” on object at path /org/freedesktop/secrets/collection/login’,)

Or:

Traceback (most recent call last):

…

raise PromptDismissedException(‘Prompt dismissed.’)

secretstorage.exceptions.PromptDismissedException: Prompt dismissed.

You need to execute the /etc/X11/xinit/xinitrc.d/50-systemd-user.sh script:

$ . /etc/X11/xinit/xinitrc.d/50-systemd-user.sh

And create a new keyring and set a password for it:

Let’s check the dbus-monitor , to see what's is going on in the D-Bus:

…

method call time=1575542111.465749 sender=:1.576 -> destination=org.freedesktop.secrets serial=7 path=/org/freedesktop/secrets/aliases/default; interface=org.freedesktop.Secret.Collection; member=CreateItem

array [

dict entry(

string “org.freedesktop.Secret.Item.Attributes”

variant array [

dict entry(

string “application”

string “Python keyring library”

)

dict entry(

string “service”

string “system”

)

dict entry(

string “username”

string “username”

)

]

)

dict entry(

string “org.freedesktop.Secret.Item.Label”

variant string “Password for ‘username’ on ‘system’”

)

]

…

struct {

object path “/org/freedesktop/secrets/session/s14”

}

…

signal time=1575542111.476006 sender=:1.220 -> destination=(null destination) serial=689 path=/org/freedesktop/secrets/collection/example_2dkeyring; interface=org.freedesktop.Secret.Collection; member=ItemCreated

object path “/org/freedesktop/secrets/collection/example_2dkeyring/5”

…

Here:

sender=:1.576 — find the 1.576 in the D-Bus services list — it’s our Python ( cmd: python ):

destination=org.freedesktop.secrets

our /usr/bin/gnome-keyring-daemon , already seen in the org.freedesktop.DBus.GetConnectionUnixProcessID output

Check the gnome-keyring storage with the seahorse utility for example:

Okay, “It works!” ©.

secret-tools

Another way can be to use secret-tools utility.

Add a new secret:

$ secret-tool store — label=SecretToolExample username username service secret

Password:

Retrieve it:

$ secret-tool lookup username username service secret

password

Check with the Seahorse in the storage:

KWallet

Install:

$ sudo pacman -S kwallet

Check the D-Bus:

$ qdbus — session org.freedesktop.DBus / org.freedesktop.DBus.GetConnectionUnixProcessID org.freedesktop.secrets

1278791

$ ps aux | grep 1278791

setevoy 1278791 0.0 0.0 384008 8048 ? SLl Dec03 0:00 /usr/bin/gnome-keyring-daemon — start — foreground — components=secrets

Er…

Why not the kwallet , why still the gnome-keyring ?

Try to kill it:

$ kill 1278791

And the service-file is still old:

$ cat /usr/share/dbus-1/services/org.freedesktop.secrets.service

[D-BUS Service]

Name=org.freedesktop.secrets

Exec=/usr/bin/gnome-keyring-daemon — start — foreground — components=secrets

Okay, fully delete the gnome-keyring :

$ sudo pacman -Rsn seahorse

$ sudo pacman -Rsn gnome-keyring

And no service file now:

$ cat /usr/share/dbus-1/services/org.freedesktop.secrets.service

2019/12/05 13:15:03 open /usr/share/dbus-1/services/org.freedesktop.secrets.service: no such file or directory

Reinstall kwallet :

$ sudo pacman -S kwallet

warning: kwallet-5.64.0–1 is up to date — reinstalling

…

No new service file:

$ qdbus — session org.freedesktop.DBus / org.freedesktop.DBus.GetConnectionUnixProcessID org.freedesktop.secrets

Error: org.freedesktop.DBus.Error.NameHasNoOwner

Could not get PID of name ‘org.freedesktop.secrets’: no such name

That’s weird…

Does D-Bus and Secret Service are supported by the KWallet at all?

Reddit says it’s not:

In brief, there is no longer a secret service implementation for KDE that I am aware of

And the ksecretsservice documentation is just full of ToDo's...

It’s a pity. I do like Qt-based KDE applications.

And the more strange is the fact that the Secret Service specification was written by both GNOME and KDE projects together, but it’s supported by the GNOME Keyring only…

Still, we can use KWallet without the Secret Service integration.

Run the KDE’s wallets manager:

$ kwalletmanager5

Create a wallet:

Set its password:

Obviously, now our Python lib will stop working as no Secret Service now is available:

>>> keyring.set_password(“system”, “username”, “password”)

Traceback (most recent call last):

…

raise value

jeepney.wrappers.DBusErrorResponse: [org.freedesktop.DBus.Error.ServiceUnknown] (‘The name org.freedesktop.secrets was not provided by any .service files’,)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

…

raise SecretServiceNotAvailableException(data) from resp

secretstorage.exceptions.SecretServiceNotAvailableException: The name org.freedesktop.secrets was not provided by any .service files

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

…

raise RuntimeError(“Unable to initialize SecretService: %s” % e)

RuntimeError: Unable to initialize SecretService: The name org.freedesktop.secrets was not provided by any .service files

But you can configure a keyring backend and set the kwallet5 directly, googled it here>>>:

>>> kwallet5 = keyring.backends.kwallet.DBusKeyring()

>>> keyring.set_keyring(kwallet5)

>>> keyring.get_keyring()

<keyring.backends.kwallet.DBusKeyring object at 0x7f7efba66fa0>

Add a password:

>>> keyring.set_password(“system”, “username”, “password”)

Check the D-Bus messages:

method call time=1575545736.524015 sender=:1.318 -> destination=:1.269 serial=38 path=/modules/kwalletd5; interface=org.kde.KWallet; member=writePassword

int32 365838442

string “system”

string “username”

string “password”

string “Python keyring library”

And the KWallet:

KeePass

Also, KeePass can act as a keyring backend service using the Secret Storage specification.

If the gnome-keyring is still running - you'll get the "Another secret service is running" error from the KeePass:

Remove the gnome-keyring , and activate Secret Service:

Check the D-Bus activity:

method call time=1575546064.021083 sender=:1.599 -> destination=org.freedesktop.DBus serial=26 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=RequestName

string “org.freedesktop.secrets”

uint32 4

signal time=1575546064.021157 sender=org.freedesktop.DBus -> destination=(null destination) serial=258 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChanged

string “org.freedesktop.secrets”

string “”

string “:1.599”

signal time=1575546064.021212 sender=org.freedesktop.DBus -> destination=:1.599 serial=16 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired

string “org.freedesktop.secrets”

method return time=1575546064.021245 sender=org.freedesktop.DBus -> destination=:1.599 serial=17 reply_serial=26

uint32 1

Check, who is listening to the org.freedesktop.secrets:

$ qdbus — session org.freedesktop.DBus / org.freedesktop.DBus.GetConnectionUnixProcessID org.freedesktop.secrets

4006761

ps aux | grep 4006761

setevoy 4006761 2.0 0.5 475888 89656 tty1 SLl 13:40 0:02 keepassxc

Okay — this is our KeePass.

Add something to the database:

$ secret-tool store — label=SecretToolExample username username service secret

Password:

libsecret-Message: 13:45:13.448: Remote error from secret service: org.freedesktop.DBus.Error.UnknownObject: No such object path ‘/org/freedesktop/secrets/aliases/default’

secret-tool: No such object path ‘/org/freedesktop/secrets/aliases/default’

Er…

Aha, need to configure an internal path in the KeePass database, see this>>> comment.

Add a new group in the database:

Next, go to the Database > Database settings and specify local path to a directory which will be used to store data when acting as a Secret Service storage:

Restart KeePass and check the D-Bus — can see now how the collection was added now:

signal time=1575546948.831195 sender=:1.613 -> destination=(null destination) serial=22 path=/org/freedesktop/secrets; interface=org.freedesktop.Secret.Service; member=CollectionCreated

object path “/org/freedesktop/secrets/collection/Main”

Add a record:

$ secret-tool store — label=SecretToolExample username username service secret

Password:

Check the D-Bus:

…

method call time=1575547056.148892 sender=:1.616 -> destination=org.freedesktop.secrets serial=10 path=/org/freedesktop/secrets/aliases/default; interface=org.freedesktop.Secret.Collection; member=CreateItem

array [

dict entry(

string “org.freedesktop.Secret.Item.Attributes”

variant array [

dict entry(

string “service”

string “secret”

)

dict entry(

string “username”

string “username”

)

]

)

dict entry(

string “org.freedesktop.Secret.Item.Label”

variant string “SecretToolExample”

)

]

…

And the KeePass itself:

That’s all for now.

Useful links

keyrings, Secret Service, etc

D-Bus