systemd/gnome-keyring: fix first login bug
Accessing gnome-keyring on first login is broken with systemd, apps relying on a working keyring just hang or show errors. This is a known bug since 2023 [1] with multiple open merge requests to fix the bug [2][3][4]. Both Debian and Fedora have patched their packages to ship a workaround [5][6]. From the available patches I've decided to use the one from Debian [4], because I didn't see [2] being used in another distribution and [3] doesn't seem to be as technically correct according to [7]. I've also tried to reproduce this problem with OpenRC, but it doesn't happen there. Hence not applying the patch to Alpine. [1]: https://gitlab.gnome.org/GNOME/gnome-keyring/-/work_items/137 [2]: https://gitlab.gnome.org/GNOME/gnome-keyring/-/merge_requests/69 [3]: https://gitlab.gnome.org/GNOME/gnome-keyring/-/merge_requests/78 [4]: https://gitlab.gnome.org/GNOME/gnome-keyring/-/merge_requests/99 [5]: https://src.fedoraproject.org/rpms/gnome-keyring/blob/rawhide/f/78.patch [6]: https://salsa.debian.org/gnome-team/gnome-keyring/-/blob/debian/latest/debian/patches/gkd-login-Register-the-login-collection-on-dbus-on-creati.patch [7]: https://gitlab.gnome.org/GNOME/gnome-keyring/-/merge_requests/78#note_2567002 Fixes: #3496 Signed-off-by: Oliver Smith <ollieparanoid@postmarketos.org> Part-of: <https://gitlab.postmarketos.org/postmarketOS/pmaports/-/merge_requests/8587>
This commit is contained in:
parent
9d0b47c505
commit
cb29632344
2 changed files with 239 additions and 2 deletions
|
|
@ -0,0 +1,234 @@
|
|||
From c9c1bbc151d6adb61d18a6a93b3e08a7c5b641d4 Mon Sep 17 00:00:00 2001
|
||||
From: Alessandro Astone <alessandro.astone@canonical.com>
|
||||
Date: Fri, 3 Oct 2025 12:40:07 +0200
|
||||
Subject: [PATCH] gkd-login: Register the login collection on dbus on creation
|
||||
|
||||
The 'login' keyring created on the first user log-in was not properly exposed
|
||||
on the dbus org.freedesktop.secrets service.
|
||||
|
||||
It would be listed in the org.freedesktop.Secret.Service.Collections property
|
||||
as /org/freedesktop/secrets/collection/login, but no object was actually
|
||||
exported at that path.
|
||||
|
||||
Link: https://gitlab.gnome.org/GNOME/gnome-keyring/-/merge_requests/99
|
||||
Closes: https://gitlab.gnome.org/GNOME/gnome-keyring/-/issues/137
|
||||
Closes: https://gitlab.gnome.org/GNOME/gnome-keyring/-/issues/151
|
||||
---
|
||||
daemon/dbus/gkd-secret-service.c | 37 +++++++++++++++++++
|
||||
daemon/login/gkd-login-context.c | 61 ++++++++++++++++++++++++++++++++
|
||||
daemon/login/gkd-login-context.h | 17 +++++++++
|
||||
daemon/login/gkd-login.c | 10 +++++-
|
||||
daemon/login/meson.build | 1 +
|
||||
5 files changed, 125 insertions(+), 1 deletion(-)
|
||||
create mode 100644 daemon/login/gkd-login-context.c
|
||||
create mode 100644 daemon/login/gkd-login-context.h
|
||||
|
||||
diff --git a/daemon/dbus/gkd-secret-service.c b/daemon/dbus/gkd-secret-service.c
|
||||
index 7a445815..0ebdf944 100644
|
||||
--- a/daemon/dbus/gkd-secret-service.c
|
||||
+++ b/daemon/dbus/gkd-secret-service.c
|
||||
@@ -39,6 +39,8 @@
|
||||
#include "gkd-internal-generated.h"
|
||||
#include "gkd-secrets-generated.h"
|
||||
|
||||
+#include "daemon/login/gkd-login-context.h"
|
||||
+
|
||||
#include "egg/egg-error.h"
|
||||
#include "egg/egg-unix-credentials.h"
|
||||
|
||||
@@ -938,6 +940,33 @@ service_name_owner_changed (GDBusConnection *connection,
|
||||
g_hash_table_remove (self->clients, object_name);
|
||||
}
|
||||
|
||||
+static void
|
||||
+on_login_keyring_created (GkdLoginContext *context,
|
||||
+ GckObject *keyring,
|
||||
+ gpointer user_data)
|
||||
+{
|
||||
+ GkdSecretService *self = GKD_SECRET_SERVICE (user_data);
|
||||
+ gsize n_identifier;
|
||||
+ char *identifier;
|
||||
+ char *path;
|
||||
+ GError *error = NULL;
|
||||
+
|
||||
+ g_debug ("intercepted new login keyring, registering on dbus");
|
||||
+
|
||||
+ identifier = gck_object_get_data (keyring, CKA_ID, NULL, &n_identifier, &error);
|
||||
+ if (identifier == NULL) {
|
||||
+ g_warning ("couldn't get login keyring identifier: %s", error->message);
|
||||
+ g_clear_error (&error);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
|
||||
+ gkd_secret_service_emit_collection_created (self, path);
|
||||
+
|
||||
+ g_free (path);
|
||||
+ g_free (identifier);
|
||||
+}
|
||||
+
|
||||
/* -----------------------------------------------------------------------------
|
||||
* OBJECT
|
||||
*/
|
||||
@@ -974,6 +1003,7 @@ gkd_secret_service_constructor (GType type,
|
||||
GError *error = NULL;
|
||||
GckSlot *slot = NULL;
|
||||
guint i;
|
||||
+ GkdLoginContext *login_ctx;
|
||||
|
||||
g_return_val_if_fail (self, NULL);
|
||||
g_return_val_if_fail (self->connection, NULL);
|
||||
@@ -1055,6 +1085,13 @@ gkd_secret_service_constructor (GType type,
|
||||
|
||||
gkd_secret_service_init_collections (self);
|
||||
|
||||
+ login_ctx = gkd_login_context_get_default ();
|
||||
+ g_signal_connect_object (login_ctx,
|
||||
+ "keyring-created",
|
||||
+ G_CALLBACK (on_login_keyring_created),
|
||||
+ self,
|
||||
+ G_CONNECT_DEFAULT);
|
||||
+
|
||||
return G_OBJECT (self);
|
||||
}
|
||||
|
||||
diff --git a/daemon/login/gkd-login-context.c b/daemon/login/gkd-login-context.c
|
||||
new file mode 100644
|
||||
index 00000000..926a2e26
|
||||
--- /dev/null
|
||||
+++ b/daemon/login/gkd-login-context.c
|
||||
@@ -0,0 +1,61 @@
|
||||
+#include "config.h"
|
||||
+#include "gkd-login-context.h"
|
||||
+
|
||||
+struct _GkdLoginContext {
|
||||
+ GObject parent_instance;
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ KEYRING_CREATED,
|
||||
+ LAST_SIGNAL
|
||||
+};
|
||||
+
|
||||
+static guint signals[LAST_SIGNAL] = { 0 };
|
||||
+
|
||||
+G_DEFINE_TYPE (GkdLoginContext, gkd_login_context, G_TYPE_OBJECT)
|
||||
+
|
||||
+static void
|
||||
+gkd_login_context_class_init (GkdLoginContextClass *klass)
|
||||
+{
|
||||
+ /* * keyring-created signal:
|
||||
+ * Emitted when the login keyring is successfully created on disk/in the store.
|
||||
+ * Passes the GckObject representing the keyring so subscribers can use it.
|
||||
+ */
|
||||
+ signals[KEYRING_CREATED] = g_signal_new ("keyring-created",
|
||||
+ GKD_TYPE_LOGIN_CONTEXT,
|
||||
+ G_SIGNAL_RUN_LAST,
|
||||
+ 0,
|
||||
+ NULL, NULL,
|
||||
+ g_cclosure_marshal_VOID__OBJECT,
|
||||
+ G_TYPE_NONE,
|
||||
+ 1, GCK_TYPE_OBJECT);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+gkd_login_context_init (GkdLoginContext *self)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+GkdLoginContext *
|
||||
+gkd_login_context_get_default (void)
|
||||
+{
|
||||
+ static GkdLoginContext *default_login_context = NULL;
|
||||
+
|
||||
+ if (g_once_init_enter_pointer (&default_login_context)) {
|
||||
+ GkdLoginContext *context = g_object_new (GKD_TYPE_LOGIN_CONTEXT, NULL);
|
||||
+
|
||||
+ g_once_init_leave_pointer (&default_login_context, context);
|
||||
+ }
|
||||
+
|
||||
+ return default_login_context;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+gkd_login_context_emit_keyring_created (GkdLoginContext *self,
|
||||
+ GckObject *keyring)
|
||||
+{
|
||||
+ g_return_if_fail (GKD_IS_LOGIN_CONTEXT (self));
|
||||
+ g_return_if_fail (GCK_IS_OBJECT (keyring));
|
||||
+
|
||||
+ g_signal_emit (self, signals[KEYRING_CREATED], 0, keyring);
|
||||
+}
|
||||
diff --git a/daemon/login/gkd-login-context.h b/daemon/login/gkd-login-context.h
|
||||
new file mode 100644
|
||||
index 00000000..a4bee57f
|
||||
--- /dev/null
|
||||
+++ b/daemon/login/gkd-login-context.h
|
||||
@@ -0,0 +1,17 @@
|
||||
+#ifndef GKD_LOGIN_CONTEXT_H
|
||||
+#define GKD_LOGIN_CONTEXT_H
|
||||
+
|
||||
+#include <glib-object.h>
|
||||
+#include <gck/gck.h>
|
||||
+
|
||||
+#define GKD_TYPE_LOGIN_CONTEXT (gkd_login_context_get_type ())
|
||||
+G_DECLARE_FINAL_TYPE (GkdLoginContext, gkd_login_context, GKD, LOGIN_CONTEXT, GObject)
|
||||
+
|
||||
+/* Singleton accessor */
|
||||
+GkdLoginContext * gkd_login_context_get_default (void);
|
||||
+
|
||||
+/* Trigger to be called by gkd-login.c when the keyring is ready */
|
||||
+void gkd_login_context_emit_keyring_created (GkdLoginContext *self,
|
||||
+ GckObject *keyring);
|
||||
+
|
||||
+#endif /* GKD_LOGIN_CONTEXT_H */
|
||||
diff --git a/daemon/login/gkd-login.c b/daemon/login/gkd-login.c
|
||||
index 855f5c3a..9225fdb9 100644
|
||||
--- a/daemon/login/gkd-login.c
|
||||
+++ b/daemon/login/gkd-login.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gkd-login.h"
|
||||
+#include "gkd-login-context.h"
|
||||
|
||||
#include "daemon/gkd-pkcs11.h"
|
||||
|
||||
@@ -149,6 +150,8 @@ static GckObject*
|
||||
create_login_keyring (GckSession *session, GckObject *cred, GError **error)
|
||||
{
|
||||
GckBuilder builder = GCK_BUILDER_INIT;
|
||||
+ GckObject *collection;
|
||||
+ GkdLoginContext *context;
|
||||
|
||||
g_return_val_if_fail (GCK_IS_SESSION (session), NULL);
|
||||
g_return_val_if_fail (GCK_IS_OBJECT (cred), NULL);
|
||||
@@ -161,7 +164,12 @@ create_login_keyring (GckSession *session, GckObject *cred, GError **error)
|
||||
/* TRANSLATORS: This is the display label for the login keyring */
|
||||
gck_builder_add_string (&builder, CKA_LABEL, _("Login"));
|
||||
|
||||
- return gck_session_create_object (session, gck_builder_end (&builder), NULL, error);
|
||||
+ context = gkd_login_context_get_default ();
|
||||
+ collection = gck_session_create_object (session, gck_builder_end (&builder), NULL, error);
|
||||
+ if (collection)
|
||||
+ gkd_login_context_emit_keyring_created (context, collection);
|
||||
+
|
||||
+ return collection;
|
||||
}
|
||||
|
||||
static GckObject*
|
||||
diff --git a/daemon/login/meson.build b/daemon/login/meson.build
|
||||
index e56b6505..63ceb717 100644
|
||||
--- a/daemon/login/meson.build
|
||||
+++ b/daemon/login/meson.build
|
||||
@@ -2,6 +2,7 @@ libgkd_login_sources = files(
|
||||
'gkd-login.c',
|
||||
'gkd-login-interaction.c',
|
||||
'gkd-login-password.c',
|
||||
+ 'gkd-login-context.c',
|
||||
)
|
||||
|
||||
libgkd_login_deps = [
|
||||
--
|
||||
2.54.0
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ maintainer="Newbyte <newbyte@postmarketos.org>"
|
|||
pkgname=gnome-keyring
|
||||
_pkgver=50.0
|
||||
pkgver=9999$_pkgver
|
||||
pkgrel=0
|
||||
pkgrel=1
|
||||
pkgdesc="GNOME keyring"
|
||||
url="https://gitlab.gnome.org/GNOME/gnome-keyring"
|
||||
# armhf: pmb#2618
|
||||
|
|
@ -42,7 +42,9 @@ subpackages="
|
|||
$pkgname-pam
|
||||
$pkgname-systemd
|
||||
"
|
||||
source="https://download.gnome.org/sources/gnome-keyring/${_pkgver%.*}/gnome-keyring-$_pkgver.tar.xz"
|
||||
source="https://download.gnome.org/sources/gnome-keyring/${_pkgver%.*}/gnome-keyring-$_pkgver.tar.xz
|
||||
0001-gkd-login-Register-the-login-collection-on-dbus-on-c.patch
|
||||
"
|
||||
builddir="$srcdir/gnome-keyring-$_pkgver"
|
||||
|
||||
build() {
|
||||
|
|
@ -74,4 +76,5 @@ pam() {
|
|||
|
||||
sha512sums="
|
||||
20786486655c2188d8d0eae129d1c14a61d995d55a2339b166aa914287cf5ddd29b67d6a2fbc9d4b3d73705459cd3d17c696369500e4a0f0d12087aac78a8c15 gnome-keyring-50.0.tar.xz
|
||||
4edf62b7f81623f1f995292a2db5ae7771c9bc819b483f8dd2acd11a8ee03e2661d7d75926e63eb886adf94876d1b414f4ae822e66106a187e6e3c98b4c23ec2 0001-gkd-login-Register-the-login-collection-on-dbus-on-c.patch
|
||||
"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue