Line data Source code
1 : /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 : /* gkd-dbus-secrets.c - dbus secret service
3 :
4 : Copyright (C) 2009, Stefan Walter
5 :
6 : The Gnome Keyring Library is free software; you can redistribute it and/or
7 : modify it under the terms of the GNU Library General Public License as
8 : published by the Free Software Foundation; either version 2 of the
9 : License, or (at your option) any later version.
10 :
11 : The Gnome Keyring Library is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Library General Public License for more details.
15 :
16 : You should have received a copy of the GNU Library General Public
17 : License along with the Gnome Library; see the file COPYING.LIB. If not,
18 : <http://www.gnu.org/licenses/>.
19 :
20 : Author: Stef Walter <stef@memberwebs.com>
21 : */
22 :
23 : #include "config.h"
24 :
25 : #include "gkd-dbus.h"
26 : #include "gkd-dbus-private.h"
27 : #include "gkd-secret-service.h"
28 :
29 : #include "daemon/gkd-pkcs11.h"
30 :
31 : #include "egg/egg-cleanup.h"
32 : #include "egg/egg-error.h"
33 :
34 : #include <gck/gck.h>
35 :
36 : static GDBusConnection *dbus_conn = NULL;
37 : static GkdSecretService *secrets_service = NULL;
38 :
39 : static GckSlot*
40 25 : calculate_secrets_slot (void)
41 : {
42 25 : GckSlot *slot = NULL;
43 : GckModule *module;
44 : GList *modules;
45 25 : GError *err = NULL;
46 : CK_FUNCTION_LIST_PTR funcs;
47 :
48 : /* TODO: Should we be handling just one module here? */
49 25 : funcs = gkd_pkcs11_get_functions ();
50 25 : g_return_val_if_fail (funcs != NULL, NULL);
51 :
52 25 : module = gck_module_new (funcs);
53 25 : g_return_val_if_fail (module, NULL);
54 :
55 25 : modules = g_list_prepend (NULL, module);
56 25 : slot = gck_modules_token_for_uri (modules, "pkcs11:token=Secret%20Store", &err);
57 25 : if (!slot && err) {
58 0 : g_warning ("couldn't find secret store: %s", egg_error_message (err));
59 0 : g_clear_error (&err);
60 : }
61 :
62 25 : gck_list_unref_free (modules);
63 25 : return slot;
64 : }
65 :
66 : gboolean
67 25 : gkd_dbus_secrets_startup (void)
68 : {
69 25 : const gchar *service = NULL;
70 25 : unsigned int flags = 0;
71 : GckSlot *slot;
72 25 : GError *error = NULL;
73 : GVariant *request_variant;
74 : guint res;
75 :
76 25 : g_return_val_if_fail (dbus_conn, FALSE);
77 25 : g_return_val_if_fail (!secrets_service, FALSE);
78 :
79 : #ifdef WITH_DEBUG
80 25 : service = g_getenv ("GNOME_KEYRING_TEST_SERVICE");
81 25 : if (service && service[0])
82 16 : flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | G_BUS_NAME_OWNER_FLAGS_REPLACE;
83 : else
84 : #endif
85 9 : service = SECRET_SERVICE;
86 :
87 : /* Figure out which slot to use */
88 25 : slot = calculate_secrets_slot ();
89 25 : g_return_val_if_fail (slot, FALSE);
90 25 : secrets_service = g_object_new (GKD_SECRET_TYPE_SERVICE,
91 : "connection", dbus_conn, "pkcs11-slot", slot, NULL);
92 25 : g_object_unref (slot);
93 :
94 : /* Try and grab our name */
95 25 : request_variant = g_dbus_connection_call_sync (dbus_conn,
96 : "org.freedesktop.DBus", /* bus name */
97 : "/org/freedesktop/DBus", /* object path */
98 : "org.freedesktop.DBus", /* interface name */
99 : "RequestName", /* method name */
100 : g_variant_new ("(su)",
101 : service,
102 : flags),
103 : G_VARIANT_TYPE ("(u)"),
104 : G_DBUS_CALL_FLAGS_NONE,
105 : -1, NULL, &error);
106 :
107 25 : if (error != NULL) {
108 0 : g_message ("couldn't request name '%s' on session bus: %s",
109 : service, error->message);
110 0 : g_error_free (error);
111 : } else {
112 25 : g_variant_get (request_variant, "(u)", &res);
113 25 : g_variant_unref (request_variant);
114 :
115 25 : switch (res) {
116 : /* We acquired the service name */
117 25 : case 1: /* DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER */
118 : /* We already acquired the service name. */
119 : case 4: /* DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER */
120 25 : break;
121 : /* Another daemon is running */
122 0 : case 2: /* DBUS_REQUEST_NAME_REPLY_IN_QUEUE */
123 : case 3: /* DBUS_REQUEST_NAME_REPLY_EXISTS */
124 0 : g_message ("another secret service is running");
125 0 : break;
126 0 : default:
127 0 : g_clear_object (&secrets_service);
128 0 : g_return_val_if_reached (FALSE);
129 : break;
130 : };
131 : }
132 :
133 25 : return TRUE;
134 : }
135 :
136 : static void
137 27 : cleanup_dbus_conn (gpointer unused)
138 : {
139 27 : g_assert (dbus_conn);
140 27 : g_clear_object (&dbus_conn);
141 27 : }
142 :
143 : void
144 27 : gkd_dbus_secrets_init (GDBusConnection *conn)
145 : {
146 27 : dbus_conn = g_object_ref (conn);
147 27 : egg_cleanup_register (cleanup_dbus_conn, NULL);
148 27 : }
149 :
150 : void
151 27 : gkd_dbus_secrets_cleanup (GDBusConnection *conn)
152 : {
153 27 : if (secrets_service) {
154 25 : g_object_run_dispose (G_OBJECT (secrets_service));
155 25 : g_object_unref (secrets_service);
156 25 : secrets_service = NULL;
157 : }
158 27 : }
|