After installing Nextcloud (see the Nextcloud: running in Docker Compose on Debian with Let’s Encrypt SSL post), on the next day its client ton my Arch Linux asked for authentication.
But after I entered my credentials, it returned me the following error:
_ Reading from keychain failed with error: ‘The name org.freedesktop.secrets was not provided by any .service files’ _
One of the first search results in Google was this>>> discussion where the first comment says:
Could be an upstream issue of the qtkeychain dependency frankosterfeld/qtkeychain#99, but I don’t have any KDE setup to test/debug this. Any help here is welcome.
Okay – we have a starting point now, let’s try to go deeper to investigate why this error happens.
What is the qtkeychain
at all?
From its README on the Github:
QtKeychain is a Qt API to store passwords and other secret data securely.
I.e. this package intended to provide an API interface for Qt-based applications to be used to retrieve confidential information from an operating system.
But QtKeychain itself doesn’t store those credentials, instead – it translates those requests to some backend-storage, and this is described in the following lines in the same README::
- Mac OS X: Passwords are stored in the OS X Keychain.
- Linux/Unix: If running, GNOME Keyring is used, otherwise qtkeychain tries to use KWallet (via D-Bus), if available.
I.e. on a Linux qtkeychain
will try to call GNOME Keyring or KWallet via D-Bus.
Now, using this tip – the D-Bus – let’s grab the qtkeychain
source code to see how this is happening at all.
Download its repository and use the grep
util with the dbus string:
[setevoy@setevoy-arch-work /tmp/qtkeychain] [master*] $ grep -r dbus .
./qt5keychain.pri: QT += dbus
./org.kde.KWallet.xml:<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
./keychain_unix.cpp: /* The secret service dbus api, accessible through libsecret, is supposed
keychain_unix.cpp
– well, self-explanatory file name, looks like what we are looking for.
Open it and look for the dbus word again – will see the detectKeyringBackend()
– again self-explanatory name:
static KeyringBackend detectKeyringBackend()
{
/* The secret service dbus api, accessible through libsecret, is supposed
* to unify password services.
*
* Unfortunately at the time of Kubuntu 18.04 the secret service backend
* in KDE is gnome-keyring-daemon - using it has several complications:
* - the default collection isn't opened on session start, so users need
* to manually unlock it when the first application uses it
* - it's separate from the kwallet5 keyring, so switching to it means the
* existing keyring data can't be accessed anymore
*
* Thus we still prefer kwallet backends on KDE even if libsecret is
* available.
*/
switch (detectDesktopEnvironment()) {
case DesktopEnv_Kde4:
return Backend_Kwallet4;
case DesktopEnv_Plasma5:
if (isKwallet5Available()) {
return Backend_Kwallet5;
}
if (LibSecretKeyring::isAvailable()) {
return Backend_LibSecretKeyring;
}
if (GnomeKeyring::isAvailable()) {
return Backend_GnomeKeyring;
}
// During startup the keychain backend might just not have started yet
return Backend_Kwallet5;
case DesktopEnv_Gnome:
case DesktopEnv_Unity:
case DesktopEnv_Xfce:
case DesktopEnv_Other:
default:
if (LibSecretKeyring::isAvailable()) {
return Backend_LibSecretKeyring;
}
if (GnomeKeyring::isAvailable()) {
return Backend_GnomeKeyring;
}
if (isKwallet5Available()) {
return Backend_Kwallet5;
}
...
}
There is also an interesting comment about kwallet
vs gnome-keyring
in the beginning, but for now, skip it.
So, then a backend initialization will be performed:
...
static KeyringBackend getKeyringBackend()
{
static KeyringBackend backend = detectKeyringBackend();
return backend;
}
...
And then – an attempt to get some password:
...
void ReadPasswordJobPrivate::scheduledStart() {
switch ( getKeyringBackend() ) {
case Backend_LibSecretKeyring: {
if ( !LibSecretKeyring::findPassword(key, q->service(), this) ) {
q->emitFinishedWithError( OtherError, tr("Unknown error") );
}
} break;
case Backend_GnomeKeyring:
this->mode = JobPrivate::Text;
if ( !GnomeKeyring::find_network_password( key.toUtf8().constData(),
q->service().toUtf8().constData(),
"plaintext",
reinterpret_cast<GnomeKeyring::OperationGetStringCallback>( &JobPrivate::gnomeKeyring_readCb ),
this, 0 ) )
q->emitFinishedWithError( OtherError, tr("Unknown error") );
break;
case Backend_Kwallet4:
kwalletReadPasswordScheduledStartImpl("org.kde.kwalletd", "/modules/kwalletd", this);
break;
case Backend_Kwallet5:
kwalletReadPasswordScheduledStartImpl("org.kde.kwalletd5", "/modules/kwalletd5", this);
break;
}
}
...
In our case, the next condition will be applied will be used:
...
case Backend_LibSecretKeyring: {
if ( !LibSecretKeyring::findPassword(key, q->service(), this) ) {
...
We can go deeper in the code, but now we got the main – the qtkeychain
will issue a call to the libsecret
.
We can deeper into the libsecret
‘s code, but not this time. Let’s just find where libsecret
will perform a call to the D-Bus using D-Bus API.
In the libsecret
‘s repository grep
by the dbus will rerun a lot of files – filet the search results with the -v
:
[setevoy@setevoy-arch-work /tmp/libsecret] [master*] $ grep -r "/org/freedesktop/secrets" . | grep -v "test\|.py"
./tool/secret-tool.c:#define SECRET_ALIAS_PREFIX "/org/freedesktop/secrets/aliases/"
./libsecret/secret-util.c: return g_strdup_printf ("/org/freedesktop/secrets/aliases/%s", collection);
./libsecret/secret-private.h:#define SECRET_ALIAS_PREFIX "/org/freedesktop/secrets/aliases/"
./libsecret/secret-private.h:#define SECRET_SERVICE_PATH "/org/freedesktop/secrets"
./tool/secret-tool.c:#define SECRET_ALIAS_PREFIX "/org/freedesktop/secrets/aliases/"
– “Alright, These Guys”!” (с)
So, what is going on here?
- I have Arch Linux with Openbox Window Manager, but without a Desktop Environment
- thus, in the
qtkeychain
‘sdetectKeyringBackend()
function the next condition will be applied:
...
case DesktopEnv_Other:
default:
if (LibSecretKeyring::isAvailable()) {
return Backend_LibSecretKeyring;
}
...
-
qtkeychain
will issue a call to thelibsecret
, which in its turn will try to call the D-Bus’sorg.freedesktop.secrets
, can not find it and returns theSECRET_ERROR_NO_SUCH_OBJECT
error
But why it can not be found?
Check the D-Bus service files in the /usr/share/dbus-1/services/
directory:
$ ls -l /usr/share/dbus-1/services/
total 196
...
-rw-r--r-- 1 root root 107 Sep 10 21:53 org.a11y.Bus.service
-rw-r--r-- 1 root root 95 Oct 31 12:09 org.bluez.obex.service
-rw-r--r-- 1 root root 116 Oct 9 12:26 org.freedesktop.ColorHelper.service
-rw-r--r-- 1 root root 104 Oct 27 16:08 org.freedesktop.Telepathy.AccountManager.service
-rw-r--r-- 1 root root 194 Nov 5 12:19 org.freedesktop.Telepathy.Client.KTp.Approver.service
-rw-r--r-- 1 root root 91 Nov 5 12:21 org.freedesktop.Telepathy.Client.KTp.CallUi.service
-rw-r--r-- 1 root root 106 Nov 5 12:20 org.freedesktop.Telepathy.Client.KTp.ConfAuthObserver.service
-rw-r--r-- 1 root root 117 Nov 5 12:26 org.freedesktop.Telepathy.Client.KTp.FileTransferHandler.service
-rw-r--r-- 1 root root 217 Nov 5 12:27 org.freedesktop.Telepathy.Client.KTp.KdedIntegrationModule.service
-rw-r--r-- 1 root root 88 Nov 12 10:26 org.freedesktop.Telepathy.Client.KTp.Proxy.service
-rw-r--r-- 1 root root 101 Nov 5 12:20 org.freedesktop.Telepathy.Client.KTp.SASLHandler.service
-rw-r--r-- 1 root root 91 Nov 5 12:29 org.freedesktop.Telepathy.Client.KTp.TextUi.service
-rw-r--r-- 1 root root 100 Nov 5 12:20 org.freedesktop.Telepathy.Client.KTp.TLSHandler.service
-rw-r--r-- 1 root root 102 Nov 10 2018 org.freedesktop.Telepathy.Client.Logger.service
-rw-r--r-- 1 root root 84 Sep 12 2018 org.freedesktop.Telepathy.Client.Vinagre.service
-rw-r--r-- 1 root root 95 Nov 10 2018 org.freedesktop.Telepathy.Logger.service
-rw-r--r-- 1 root root 188 Oct 27 16:08 org.freedesktop.Telepathy.MissionControl5.service
-rw-r--r-- 1 root root 60 Oct 27 2018 org.gnome.GConf.service
...
And recall the error text – – The name org.freedesktop.secrets was not provided by any .service files’: we can not see the org.freedesktop.secrets.service
file in the directory above.
The solution
First, check if the qtkeychain
installed:
[setevoy@setevoy-arch-work ~] $ pacman -Qi | grep qtkeychain
Optional For : chromium qtkeychain
Optional For : git qtkeychain
Depends On : qtkeychain qt5-webkit hicolor-icon-theme xdg-utils
Required By : appstream-qt...
Name : qtkeychain
URL : https://github.com/frankosterfeld/qtkeychain
Yes. Actually, it is set as the dependency for the nextcloud-client
, thus pacman
installed it together with the client.
Now, what we need is just to install some package which will provide us the org.freedesktop.secrets
service.
Install the gnome-keyring
:
[setevoy@setevoy-arch-work /tmp/qtkeychain] [master*] $ sudo pacman -S gnome-keyring
Check D-Bus services again:
[setevoy@setevoy-arch-work /tmp/qtkeychain] [master*] $ ls -l /usr/share/dbus-1/services/ | grep secret
-rw-r--r-- 1 root root 122 Oct 29 11:38 org.freedesktop.secrets.service
And check the service’s file content:
[setevoy@setevoy-arch-work /tmp/qtkeychain] [master*] $ 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
Repeat log in to the Nextcloud.
Done.
P.S. There is a good story about Chrome/Chromium and how they are working with backend storages, I’ll add another post about it.
Useful links
- GNOME/Keyring
- Python bindings to Freedesktop.org Secret Service API
- Specifications/ secret-storage-spec
- Using the DBUS C API
- libsecret
- Understanding D-Bus
- dbus-monitor — debug probe to print message bus messages
- How to modify a dbus service’s “Exec” line without losing the changes in case of upgrade
Top comments (0)