~ubuntu-desktop/gnome-keyring/ubuntu

« back to all changes in this revision

Viewing changes to debian/patches/0001-Die-if-the-XDG-session-we-were-started-under-goes-aw.patch

  • Committer: Iain Lane
  • Date: 2016-08-18 16:25:04 UTC
  • Revision ID: iain.lane@canonical.com-20160818162504-fenpcwal65d255up
d/p/0001-Die-if-the-XDG-session-we-were-started-under-goes-aw.patch:
Cherry-pick upstream patch to track our login session and exit if that
ends.  This means that gnome-keyring gets cleaned up properly on logout
under dbus-user-session.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
From bade85de0f22b3e3319f2da92634267ba38ab2f3 Mon Sep 17 00:00:00 2001
 
2
From: Iain Lane <iain@orangesquash.org.uk>
 
3
Date: Tue, 19 Jul 2016 17:36:07 +0100
 
4
Subject: [PATCH] Die if the XDG session we were started under goes away
 
5
 
 
6
https://bugzilla.gnome.org/show_bug.cgi?id=768943
 
7
---
 
8
 daemon/gkd-main.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
9
 1 file changed, 158 insertions(+)
 
10
 
 
11
diff --git a/daemon/gkd-main.c b/daemon/gkd-main.c
 
12
index 28758ed..07ee2d0 100644
 
13
--- a/daemon/gkd-main.c
 
14
+++ b/daemon/gkd-main.c
 
15
@@ -128,6 +128,7 @@ static guint timeout_id = 0;
 
16
 static gboolean initialization_completed = FALSE;
 
17
 static GMainLoop *loop = NULL;
 
18
 static int parent_wakeup_fd = -1;
 
19
+static GDBusConnection *system_bus_connection = NULL;
 
20
 
 
21
 static GOptionEntry option_entries[] = {
 
22
        { "start", 's', 0, G_OPTION_ARG_NONE, &run_for_start,
 
23
@@ -835,6 +836,155 @@ on_vanished_quit_loop (GDBusConnection *connection,
 
24
        g_main_loop_quit (user_data);
 
25
 }
 
26
 
 
27
+static void on_logind_session_property_get (GObject *connection,
 
28
+                                           GAsyncResult *res,
 
29
+                                           gpointer user_data G_GNUC_UNUSED)
 
30
+{
 
31
+       GError *error = NULL;
 
32
+       GVariant *result, *resultv;
 
33
+       const gchar *state;
 
34
+       gboolean should_quit;
 
35
+
 
36
+       result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (connection), res, &error);
 
37
+
 
38
+       if (error) {
 
39
+               if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
 
40
+                       g_critical ("%s Couldn't get session state: %s", G_STRLOC, error->message);
 
41
+               g_error_free (error);
 
42
+               return;
 
43
+       }
 
44
+
 
45
+       g_variant_get (result, "(v)", &resultv, NULL);
 
46
+       state = g_variant_get_string (resultv, NULL);
 
47
+
 
48
+       should_quit = g_strcmp0 (state, "closing") == 0;
 
49
+
 
50
+       g_clear_pointer (&result, g_variant_unref);
 
51
+       g_clear_pointer (&resultv, g_variant_unref);
 
52
+
 
53
+       /* yes, the session is closing, so we'll quit now */
 
54
+       if (should_quit)
 
55
+               cleanup_and_exit (0);
 
56
+}
 
57
+
 
58
+static void on_logind_session_properties_changed (GDBusConnection *connection,
 
59
+                                                 const gchar *sender_name G_GNUC_UNUSED,
 
60
+                                                 const gchar *object_path,
 
61
+                                                 const gchar *interface_name G_GNUC_UNUSED,
 
62
+                                                 const gchar *signal_name G_GNUC_UNUSED,
 
63
+                                                 GVariant *parameters,
 
64
+                                                 gpointer user_data G_GNUC_UNUSED)
 
65
+{
 
66
+       const gchar *prop_iface;
 
67
+       gboolean active;
 
68
+       GVariant* changed_properties;
 
69
+
 
70
+       g_variant_get (parameters, "(&s@a{sv}^as)", &prop_iface, &changed_properties, NULL);
 
71
+
 
72
+       if (g_variant_lookup (changed_properties, "Active", "b", &active, NULL)) {
 
73
+               if (!active) {
 
74
+                       /* ok, the session went inactive, let's see if that is because
 
75
+                        * it is closing */
 
76
+                       g_dbus_connection_call (
 
77
+                               connection,
 
78
+                               "org.freedesktop.login1",
 
79
+                               object_path,
 
80
+                               "org.freedesktop.DBus.Properties",
 
81
+                               "Get",
 
82
+                               g_variant_new ("(ss)", prop_iface, "State"),
 
83
+                               G_VARIANT_TYPE ("(v)"),
 
84
+                               G_DBUS_CALL_FLAGS_NONE,
 
85
+                               -1,
 
86
+                               NULL,
 
87
+                               on_logind_session_property_get,
 
88
+                               NULL
 
89
+                       );
 
90
+               }
 
91
+       }
 
92
+
 
93
+       g_variant_unref (changed_properties);
 
94
+}
 
95
+
 
96
+static void
 
97
+on_logind_object_path_get (GObject *connection,
 
98
+                          GAsyncResult *res,
 
99
+                          gpointer user_data G_GNUC_UNUSED)
 
100
+{
 
101
+       GError *error = NULL;
 
102
+       GVariant *result;
 
103
+       const gchar *object_path;
 
104
+       gchar *remote_error;
 
105
+       gboolean is_cancelled, is_name_has_no_owner;
 
106
+
 
107
+       result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (connection), res, &error);
 
108
+
 
109
+       /* If there's an error we always want to quit - but we only tell the
 
110
+        * user about it if something went wrong. Cancelling the operation or
 
111
+        * not having logind available are okay. */
 
112
+       if (error) {
 
113
+               is_cancelled = g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
 
114
+
 
115
+               remote_error = g_dbus_error_get_remote_error (error);
 
116
+               is_name_has_no_owner = g_strcmp0 (remote_error, "org.freedesktop.DBus.Error.NameHasNoOwner") == 0;
 
117
+
 
118
+               if (!is_cancelled && !is_name_has_no_owner)
 
119
+                       g_critical ("%s Couldn't get object path: %s", G_STRLOC, error->message);
 
120
+
 
121
+               g_free (remote_error);
 
122
+               g_error_free (error);
 
123
+               return;
 
124
+       }
 
125
+
 
126
+       /* now we know which object path to look on, watch for
 
127
+        * PropertiesChanged. Note that, per logind's documentation, we only
 
128
+        * get notified for 'Active' changing */
 
129
+       g_variant_get (result, "(&o)", &object_path, NULL);
 
130
+
 
131
+       g_dbus_connection_signal_subscribe (
 
132
+               G_DBUS_CONNECTION (connection),
 
133
+               "org.freedesktop.login1",
 
134
+               "org.freedesktop.DBus.Properties",
 
135
+               "PropertiesChanged",
 
136
+               object_path,
 
137
+               NULL,
 
138
+               G_DBUS_SIGNAL_FLAGS_NONE,
 
139
+               on_logind_session_properties_changed,
 
140
+               NULL,
 
141
+               NULL
 
142
+       );
 
143
+
 
144
+       g_clear_pointer (&result, g_variant_unref);
 
145
+}
 
146
+
 
147
+static void
 
148
+start_watching_logind_for_session_closure ()
 
149
+{
 
150
+       g_return_if_fail (system_bus_connection != NULL);
 
151
+
 
152
+       const gchar *xdg_session_id;
 
153
+
 
154
+       xdg_session_id = g_getenv ("XDG_SESSION_ID");
 
155
+
 
156
+       if (!xdg_session_id)
 
157
+               return;
 
158
+
 
159
+       /* get the right object path */
 
160
+       g_dbus_connection_call (
 
161
+               system_bus_connection,
 
162
+               "org.freedesktop.login1",
 
163
+               "/org/freedesktop/login1",
 
164
+               "org.freedesktop.login1.Manager",
 
165
+               "GetSession",
 
166
+               g_variant_new ("(s)", xdg_session_id, NULL),
 
167
+               G_VARIANT_TYPE ("(o)"),
 
168
+               G_DBUS_CALL_FLAGS_NO_AUTO_START,
 
169
+               -1,
 
170
+               NULL,
 
171
+               on_logind_object_path_get,
 
172
+               NULL
 
173
+       );
 
174
+}
 
175
+
 
176
 int
 
177
 main (int argc, char *argv[])
 
178
 {
 
179
@@ -970,6 +1120,14 @@ main (int argc, char *argv[])
 
180
                if (!gkr_daemon_startup_steps (run_components))
 
181
                        cleanup_and_exit (1);
 
182
        }
 
183
+       
 
184
+       /* if we can get a connection to the system bus, watch it and then kill
 
185
+        * ourselves when our session closes */
 
186
+
 
187
+       system_bus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
 
188
+
 
189
+       if (system_bus_connection)
 
190
+               start_watching_logind_for_session_closure ();
 
191
 
 
192
        signal (SIGPIPE, SIG_IGN);
 
193
 
 
194
-- 
 
195
2.8.1
 
196