1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* gnome-keyring.c - library for talking to the keyring daemon.
3
4 Copyright (C) 2003 Red Hat, Inc
5 Copyright (C) 2007 Stefan Walter
6
7 The Gnome Keyring Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 The Gnome Keyring Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public
18 License along with the Gnome Library; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
21
22 Author: Alexander Larsson <alexl@redhat.com>
23 Author: Stef Walter <stef@memberwebs.com>
24 */
25
26 #include "config.h"
27
28 #define DEBUG_FLAG GKR_DEBUG_OPERATION
29 #include "gkr-callback.h"
30 #include "gkr-debug.h"
31 #include "gkr-misc.h"
32 #include "gkr-operation.h"
33 #include "gkr-session.h"
34 #include "gnome-keyring.h"
35 #include "gnome-keyring-private.h"
36
37 #include "egg/egg-dbus.h"
38 #include "egg/egg-secure-memory.h"
39
40 #include <dbus/dbus.h>
41
42 #include <glib/gi18n-lib.h>
43
44 #include <time.h>
45 #include <unistd.h>
46 #include <errno.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <sys/types.h>
50 #include <sys/socket.h>
51 #include <sys/uio.h>
52 #include <stdarg.h>
53
54 EGG_SECURE_DECLARE (libgnome_keyring);
55
56 typedef gboolean (*DecodeCallback) (DBusMessageIter *, gpointer);
57
58 typedef gboolean (*DecodeDictCallback) (const gchar *, DBusMessageIter *, gpointer);
59
60 typedef gboolean (*DecodePathCallback) (const char *, gpointer);
61
62 /**
63 * SECTION:gnome-keyring-generic-callbacks
64 * @title: Callbacks
65 * @short_description: Different callbacks for retrieving async results
66 *
67 * <warning>All of these APIs are deprecated. Use
68 * <ulink href="http://developer.gnome.org/libsecret/stable/">libsecret</ulink>
69 * instead.</warning>
70 */
71
72 static DBusMessage*
prepare_property_get(const gchar * path,const gchar * interface,const gchar * name)73 prepare_property_get (const gchar *path, const gchar *interface, const gchar *name)
74 {
75 DBusMessage *req;
76
77 g_assert (path);
78 g_assert (name);
79
80 if (!interface)
81 interface = "";
82
83 req = dbus_message_new_method_call (gkr_service_name, path,
84 DBUS_INTERFACE_PROPERTIES, "Get");
85 dbus_message_append_args (req, DBUS_TYPE_STRING, &interface,
86 DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
87
88 return req;
89 }
90
91 static DBusMessage*
prepare_property_getall(const gchar * path,const gchar * interface)92 prepare_property_getall (const gchar *path, const gchar *interface)
93 {
94 DBusMessage *req;
95
96 g_assert (path);
97
98 if (!interface)
99 interface = "";
100
101 req = dbus_message_new_method_call (gkr_service_name, path,
102 DBUS_INTERFACE_PROPERTIES, "GetAll");
103 dbus_message_append_args (req, DBUS_TYPE_STRING, &interface, DBUS_TYPE_INVALID);
104
105 return req;
106 }
107
108 static DBusMessage*
prepare_get_secret(GkrSession * session,const char * path)109 prepare_get_secret (GkrSession *session, const char *path)
110 {
111 DBusMessage *req;
112 const gchar *spath;
113
114 g_assert (session);
115 g_assert (path);
116
117 req = dbus_message_new_method_call (gkr_service_name, path,
118 ITEM_INTERFACE, "GetSecret");
119
120 spath = gkr_session_get_path (session);
121 dbus_message_append_args (req, DBUS_TYPE_OBJECT_PATH, &spath, DBUS_TYPE_INVALID);
122
123 return req;
124 }
125
126 static DBusMessage*
prepare_get_secrets(GkrSession * session,char ** paths,int n_paths)127 prepare_get_secrets (GkrSession *session, char **paths, int n_paths)
128 {
129 DBusMessage *req;
130 const char *spath;
131
132 g_assert (session);
133
134 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
135 SERVICE_INTERFACE, "GetSecrets");
136
137 spath = gkr_session_get_path (session);
138 dbus_message_append_args (req, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, n_paths,
139 DBUS_TYPE_OBJECT_PATH, &spath, DBUS_TYPE_INVALID);
140
141 return req;
142 }
143
144 static DBusMessage*
prepare_xlock(const char * action,char ** objects,int n_objects)145 prepare_xlock (const char *action, char **objects, int n_objects)
146 {
147 DBusMessage *req;
148
149 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
150 SERVICE_INTERFACE, action);
151
152 dbus_message_append_args (req, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objects, n_objects,
153 DBUS_TYPE_INVALID);
154
155 return req;
156 }
157
158 static GnomeKeyringResult
decode_invalid_response(DBusMessage * reply)159 decode_invalid_response (DBusMessage *reply)
160 {
161 g_assert (reply);
162 g_message ("call to daemon returned an invalid response: %s.%s()",
163 dbus_message_get_interface (reply),
164 dbus_message_get_member (reply));
165 return GNOME_KEYRING_RESULT_IO_ERROR;
166 }
167
168 static GnomeKeyringResult
decode_property_variant_array(DBusMessage * reply,DecodeCallback callback,gpointer user_data)169 decode_property_variant_array (DBusMessage *reply, DecodeCallback callback,
170 gpointer user_data)
171 {
172 DBusMessageIter iter, variant, array;
173 int type;
174
175 g_assert (reply);
176 g_assert (callback);
177
178 if (!dbus_message_has_signature (reply, "v"))
179 return decode_invalid_response (reply);
180
181 /* Iter to the variant */
182 if (!dbus_message_iter_init (reply, &iter))
183 g_return_val_if_reached (BROKEN);
184 g_return_val_if_fail (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_VARIANT, BROKEN);
185 dbus_message_iter_recurse (&iter, &variant);
186
187 /* Iter to the array */
188 if (dbus_message_iter_get_arg_type (&variant) != DBUS_TYPE_ARRAY)
189 return decode_invalid_response (reply);
190 dbus_message_iter_recurse (&variant, &array);
191
192 /* Each item in the array */
193 for (;;) {
194 type = dbus_message_iter_get_arg_type (&array);
195 if (type == DBUS_TYPE_INVALID)
196 break;
197 if (!(callback) (&array, user_data))
198 return decode_invalid_response (reply);
199
200 dbus_message_iter_next (&array);
201 }
202
203 return GNOME_KEYRING_RESULT_OK;
204 }
205
206 static GnomeKeyringResult
decode_property_dict(DBusMessage * reply,DecodeDictCallback callback,gpointer user_data)207 decode_property_dict (DBusMessage *reply, DecodeDictCallback callback,
208 gpointer user_data)
209 {
210 DBusMessageIter iter, variant, array, dict;
211 const char *property;
212 int type;
213
214 g_assert (reply);
215 g_assert (callback);
216
217 if (!dbus_message_has_signature (reply, "a{sv}"))
218 return decode_invalid_response (reply);
219
220 /* Iter to the array */
221 if (!dbus_message_iter_init (reply, &iter))
222 g_return_val_if_reached (BROKEN);
223 g_return_val_if_fail (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY, BROKEN);
224 dbus_message_iter_recurse (&iter, &array);
225
226 /* Each dict entry in the array */
227 for (;;) {
228 type = dbus_message_iter_get_arg_type (&array);
229 if (type == DBUS_TYPE_INVALID)
230 break;
231 g_return_val_if_fail (type == DBUS_TYPE_DICT_ENTRY, BROKEN);
232
233 dbus_message_iter_recurse (&array, &dict);
234
235 /* The property type */
236 g_return_val_if_fail (dbus_message_iter_get_arg_type (&dict) == DBUS_TYPE_STRING, BROKEN);
237 dbus_message_iter_get_basic (&dict, &property);
238 g_return_val_if_fail (property, BROKEN);
239
240 /* The variant value */
241 if (!dbus_message_iter_next (&dict))
242 g_return_val_if_reached (BROKEN);
243 g_return_val_if_fail (dbus_message_iter_get_arg_type (&dict) == DBUS_TYPE_VARIANT, BROKEN);
244 dbus_message_iter_recurse (&dict, &variant);
245
246 if (!(callback) (property, &variant, user_data))
247 return decode_invalid_response (reply);
248
249 dbus_message_iter_next (&array);
250 }
251
252 return GNOME_KEYRING_RESULT_OK;
253 }
254
255 static gboolean
decode_get_attributes_foreach(DBusMessageIter * iter,gpointer user_data)256 decode_get_attributes_foreach (DBusMessageIter *iter, gpointer user_data)
257 {
258 GHashTable *table = user_data;
259 DBusMessageIter dict;
260 const char *name;
261 const char *value;
262
263 if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_DICT_ENTRY)
264 return FALSE;
265
266 dbus_message_iter_recurse (iter, &dict);
267 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_STRING)
268 return FALSE;
269 dbus_message_iter_get_basic (&dict, &name);
270
271 dbus_message_iter_next (&dict);
272 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_STRING)
273 return FALSE;
274 dbus_message_iter_get_basic (&dict, &value);
275
276 /* These strings will last as long as the message, so no need to dup */
277 g_return_val_if_fail (name && value, FALSE);
278 g_hash_table_insert (table, (char*)name, (char*)value);
279 return TRUE;
280 }
281
282 static GnomeKeyringResult
decode_get_attributes(DBusMessage * reply,GnomeKeyringAttributeList * attrs)283 decode_get_attributes (DBusMessage *reply, GnomeKeyringAttributeList *attrs)
284 {
285 GnomeKeyringResult res;
286 GHashTableIter iter;
287 GHashTable *table;
288 const char *name;
289 const char *value;
290 guint32 number;
291 gchar *check, *end;
292 gboolean is_uint32;
293
294 g_assert (reply);
295
296 table = g_hash_table_new (g_str_hash, g_str_equal);
297 res = decode_property_variant_array (reply, decode_get_attributes_foreach, table);
298 if (res == GNOME_KEYRING_RESULT_OK) {
299 g_hash_table_iter_init (&iter, table);
300 while (g_hash_table_iter_next (&iter, (gpointer*)&name, (gpointer*)&value)) {
301 g_assert (name && value);
302
303 /* Hide these gnome-keyring internal attributes */
304 if (g_str_has_prefix (name, "gkr:"))
305 continue;
306
307 /*
308 * Figure out the attribute type. In the secrets service
309 * all attributes have string values. The daemon will
310 * set a special compat attribute to indicate to us
311 * whether this was a uint32
312 */
313 check = g_strdup_printf ("gkr:compat:uint32:%s", name);
314 is_uint32 = g_hash_table_lookup (table, check) != NULL;
315 g_free (check);
316
317 if (is_uint32) {
318 number = strtoul (value, &end, 10);
319 if (end && end[0] == '\0')
320 gnome_keyring_attribute_list_append_uint32 (attrs, name, number);
321 else
322 is_uint32 = FALSE;
323 }
324
325 if (!is_uint32)
326 gnome_keyring_attribute_list_append_string (attrs, name, value);
327 }
328 }
329
330 g_hash_table_destroy (table);
331 return res;
332 }
333
334 static gboolean
decode_xlock_reply(DBusMessage * reply,const char ** prompt,DecodePathCallback callback,gpointer user_data)335 decode_xlock_reply (DBusMessage *reply, const char **prompt,
336 DecodePathCallback callback, gpointer user_data)
337 {
338 DBusMessageIter iter, array;
339 const char *path;
340
341 g_assert (reply);
342 g_assert (prompt);
343 g_assert (callback);
344
345 if (!dbus_message_has_signature (reply, "aoo"))
346 return FALSE;
347
348 if (!dbus_message_iter_init (reply, &iter))
349 g_return_val_if_reached (FALSE);
350 dbus_message_iter_recurse (&iter, &array);
351 if (!dbus_message_iter_next (&iter) ||
352 dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_OBJECT_PATH)
353 g_return_val_if_reached (FALSE);
354 dbus_message_iter_get_basic (&iter, prompt);
355 g_return_val_if_fail (prompt, FALSE);
356
357 while (dbus_message_iter_get_arg_type (&array) == DBUS_TYPE_OBJECT_PATH) {
358 path = NULL;
359 dbus_message_iter_get_basic (&array, &path);
360 g_return_val_if_fail (path, FALSE);
361
362 if (!(callback) (path, user_data))
363 break;
364 if (!dbus_message_iter_next (&array))
365 break;
366 }
367
368 return TRUE;
369 }
370
371 static gboolean
decode_xlock_completed(DBusMessage * reply,gboolean * dismissed,DecodePathCallback callback,gpointer user_data)372 decode_xlock_completed (DBusMessage *reply, gboolean *dismissed,
373 DecodePathCallback callback, gpointer user_data)
374 {
375 DBusMessageIter variant, iter, array;
376 dbus_bool_t bval;
377 const char *path;
378 char *signature;
379 gboolean equal;
380
381 g_assert (reply);
382 g_assert (dismissed);
383 g_assert (callback);
384
385 if (!dbus_message_has_signature (reply, "bv"))
386 return FALSE;
387
388 if (!dbus_message_iter_init (reply, &iter))
389 g_return_val_if_reached (FALSE);
390 dbus_message_iter_get_basic (&iter, &bval);
391 *dismissed = bval;
392
393 /* Prompt was dismissed */
394 if (bval == TRUE)
395 return TRUE;
396
397 /* Dig out the variant */
398 if (!dbus_message_iter_next (&iter))
399 g_return_val_if_reached (FALSE);
400 dbus_message_iter_recurse (&iter, &variant);
401
402 signature = dbus_message_iter_get_signature (&variant);
403 equal = g_str_equal (signature, "ao");
404 dbus_free (signature);
405 if (!equal)
406 return FALSE;
407
408 g_return_val_if_fail (dbus_message_iter_get_arg_type (&variant) == DBUS_TYPE_ARRAY, FALSE);
409 g_return_val_if_fail (dbus_message_iter_get_element_type (&variant) == DBUS_TYPE_OBJECT_PATH, FALSE);
410
411 dbus_message_iter_recurse (&variant, &array);
412
413 while (dbus_message_iter_get_arg_type (&array) == DBUS_TYPE_OBJECT_PATH) {
414 path = NULL;
415 dbus_message_iter_get_basic (&array, &path);
416 g_return_val_if_fail (path, FALSE);
417
418 if (!(callback) (path, user_data))
419 break;
420 if (!dbus_message_iter_next (&array))
421 break;
422 }
423
424 return TRUE;
425 }
426
427 static void
encode_attribute_list(DBusMessageIter * iter,GnomeKeyringAttributeList * attrs)428 encode_attribute_list (DBusMessageIter *iter, GnomeKeyringAttributeList *attrs)
429 {
430 DBusMessageIter dict, array;
431 GnomeKeyringAttribute *attr;
432 const gchar *string;
433 gchar *value;
434 guint i;
435
436 dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{ss}", &array);
437
438 for (i = 0; attrs && i < attrs->len; ++i) {
439 attr = &gnome_keyring_attribute_list_index (attrs, i);
440 dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
441
442 /* Add in the attribute type */
443 string = attr->name ? attr->name : "";
444 dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &string);
445
446 /* String values */
447 if (attr->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
448 string = attr->value.string ? attr->value.string : "";
449 dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &string);
450
451 /* Integer values */
452 } else if (attr->type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) {
453 value = g_strdup_printf ("%u", attr->value.integer);
454 dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &value);
455 g_free (value);
456
457 } else {
458 g_warning ("received invalid attribute type");
459 return;
460 }
461
462 dbus_message_iter_close_container (&array, &dict);
463
464 /* Integer values get another compatibility marker */
465 if (attr->type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) {
466 dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
467
468 value = g_strdup_printf ("gkr:compat:uint32:%s", attr->name);
469 dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &value);
470 g_free (value);
471 string = "";
472 dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &string);
473
474 dbus_message_iter_close_container (&array, &dict);
475 }
476 }
477
478 dbus_message_iter_close_container (iter, &array);
479 }
480
481 /**
482 * SECTION:gnome-keyring-misc
483 * @title: Miscellaneous Functions
484 * @short_description: Miscellaneous functions.
485 *
486 * All of these APIs are deprecated. Use
487 * <ulink href="http://developer.gnome.org/libsecret/stable/">libsecret</ulink>
488 * instead.
489 **/
490
491 /**
492 * gnome_keyring_is_available:
493 *
494 * Check whether you can communicate with a gnome-keyring-daemon.
495 *
496 * Return value: %FALSE if you can't communicate with the daemon (so you
497 * can't load and save passwords).
498 *
499 * Deprecated: Not needed when using libsecret. The gnome-keyring daemon is
500 * automatically started as needed.
501 **/
502 gboolean
gnome_keyring_is_available(void)503 gnome_keyring_is_available (void)
504 {
505 GkrOperation *op;
506 DBusMessage *req;
507
508 gkr_init ();
509
510 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
511 DBUS_INTERFACE_PEER, "Ping");
512
513 op = gkr_operation_new (gkr_callback_empty, GKR_CALLBACK_RES, NULL, NULL);
514 gkr_operation_request (op, req);
515 dbus_message_unref (req);
516 return gkr_operation_block_and_unref (op) == GNOME_KEYRING_RESULT_OK;
517 }
518
519 /**
520 * gnome_keyring_cancel_request:
521 * @request: The request returned from the asynchronous call function.
522 *
523 * Cancel an asynchronous request.
524 *
525 * If a callback was registered when making the asynchronous request, that callback
526 * function will be called with a result of %GNOME_KEYRING_RESULT_CANCELLED
527 *
528 * Deprecated: When using libsecret, use #GCancellable to cancel asynchronous
529 * requests.
530 **/
531 void
gnome_keyring_cancel_request(gpointer request)532 gnome_keyring_cancel_request (gpointer request)
533 {
534 GkrOperation *op = request;
535
536 gkr_init ();
537
538 g_return_if_fail (request);
539 gkr_operation_complete_later (op, GNOME_KEYRING_RESULT_CANCELLED);
540 }
541
542 /**
543 * SECTION:gnome-keyring-keyrings
544 * @title: Keyrings
545 * @short_description: Listing and managing keyrings
546 *
547 * <warning>All of these APIs are deprecated. Use
548 * <ulink href="http://developer.gnome.org/libsecret/stable/">libsecret</ulink>
549 * instead.</warning>
550 *
551 * <code>gnome-keyring-daemon</code> manages multiple keyrings. Each keyring can
552 * store one or more items containing secrets.
553 *
554 * One of the keyrings is the default keyring, which can in many cases be used
555 * by specifying %NULL for a keyring name.
556 *
557 * Each keyring can be in a locked or unlocked state. A password must be
558 * specified, either by the user or the calling application, to unlock the
559 * keyring.
560 */
561
562 static GkrOperation*
set_default_keyring_start(const gchar * keyring,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)563 set_default_keyring_start (const gchar *keyring, GnomeKeyringOperationDoneCallback callback,
564 gpointer data, GDestroyNotify destroy_data)
565 {
566 DBusMessage *req;
567 const char *string;
568 GkrOperation *op;
569 gchar *path;
570
571 g_return_val_if_fail (keyring, NULL);
572 g_return_val_if_fail (callback, NULL);
573
574 path = gkr_encode_keyring_name (keyring);
575 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
576 SERVICE_INTERFACE, "SetAlias");
577
578 string = "default";
579 dbus_message_append_args (req, DBUS_TYPE_STRING, &string,
580 DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
581
582 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
583 gkr_operation_set_keyring_hint (op);
584 gkr_operation_request (op, req);
585 dbus_message_unref (req);
586 g_free (path);
587
588 return op;
589 }
590
591 /**
592 * gnome_keyring_set_default_keyring: (skip)
593 * @keyring: The keyring to make default
594 * @callback: A callback which will be called when the request completes or fails.
595 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
596 * @callback.
597 * @destroy_data: A function to free @data when it's no longer needed.
598 *
599 * Change the default keyring.
600 *
601 * For a synchronous version of this function see gnome_keyring_set_default_keyring_sync().
602 *
603 * Return value: (transfer none): The asynchronous request, which can be passed
604 * to gnome_keyring_cancel_request().
605 *
606 * Deprecated: Use secret_service_set_alias() instead.
607 **/
608 gpointer
gnome_keyring_set_default_keyring(const gchar * keyring,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)609 gnome_keyring_set_default_keyring (const gchar *keyring,
610 GnomeKeyringOperationDoneCallback callback,
611 gpointer data,
612 GDestroyNotify destroy_data)
613 {
614 GkrOperation *op;
615
616 gkr_init ();
617
618 op = set_default_keyring_start (keyring, callback, data, destroy_data);
619 return gkr_operation_pending_and_unref (op);
620 }
621
622 /**
623 * gnome_keyring_set_default_keyring_sync:
624 * @keyring: The keyring to make default
625 *
626 * Change the default keyring.
627 *
628 * For an asynchronous version of this function see gnome_keyring_set_default_keyring().
629 *
630 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
631 * an error result otherwise.
632 *
633 * Deprecated: Use secret_service_set_alias_sync() instead.
634 **/
635 GnomeKeyringResult
gnome_keyring_set_default_keyring_sync(const char * keyring)636 gnome_keyring_set_default_keyring_sync (const char *keyring)
637 {
638 GkrOperation *op;
639
640 g_return_val_if_fail (keyring, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
641
642 gkr_init ();
643
644 op = set_default_keyring_start (keyring, gkr_callback_empty, NULL, NULL);
645 return gkr_operation_block_and_unref (op);
646 }
647
648 static void
get_default_keyring_sync(GnomeKeyringResult res,const gchar * name,gpointer user_data)649 get_default_keyring_sync (GnomeKeyringResult res, const gchar *name, gpointer user_data)
650 {
651 gchar **result = user_data;
652 *result = (gchar*)name;
653 }
654
655 static void
get_default_keyring_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)656 get_default_keyring_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
657 {
658 GkrCallback *cb;
659 const char *path;
660 gchar *name;
661
662 if (gkr_operation_handle_errors (op, reply))
663 return;
664
665 if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_OBJECT_PATH, &path,
666 DBUS_TYPE_INVALID)) {
667 gkr_operation_complete (op, decode_invalid_response (reply));
668 return;
669 }
670
671 if (g_str_equal (path, "/")) {
672 name = NULL;
673 } else {
674 name = gkr_decode_keyring_name (path);
675 if (name == NULL) {
676 gkr_operation_complete (op, decode_invalid_response (reply));
677 return;
678 }
679 }
680
681 cb = gkr_operation_pop (op);
682 gkr_callback_invoke_ok_string (cb, name);
683 if (cb->callback != get_default_keyring_sync)
684 g_free (name);
685 }
686
687 static GkrOperation*
get_default_keyring_start(GnomeKeyringOperationGetStringCallback callback,gpointer data,GDestroyNotify destroy_data)688 get_default_keyring_start (GnomeKeyringOperationGetStringCallback callback,
689 gpointer data, GDestroyNotify destroy_data)
690 {
691 DBusMessage *req;
692 const char *string;
693 GkrOperation *op;
694
695 g_return_val_if_fail (callback, NULL);
696
697 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
698 SERVICE_INTERFACE, "ReadAlias");
699
700 string = "default";
701 dbus_message_append_args (req, DBUS_TYPE_STRING, &string, DBUS_TYPE_INVALID);
702
703 op = gkr_operation_new (callback, GKR_CALLBACK_RES_STRING, data, destroy_data);
704 gkr_operation_push (op, get_default_keyring_reply, GKR_CALLBACK_OP_MSG, NULL, NULL);
705 gkr_operation_request (op, req);
706 dbus_message_unref (req);
707
708 return op;
709 }
710
711 /**
712 * gnome_keyring_get_default_keyring: (skip)
713 * @callback: A callback which will be called when the request completes or fails.
714 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
715 * @callback.
716 * @destroy_data: A function to free @data when it's no longer needed.
717 *
718 * Get the default keyring name, which will be passed to the @callback. If no
719 * default keyring exists, then %NULL will be passed to the @callback. The
720 * string will be freed after @callback returns.
721 *
722 * For a synchronous version of this function see gnome_keyring_get_default_keyring_sync().
723 *
724 * Return value: (transfer none): The asynchronous request, which can be passed
725 * to gnome_keyring_cancel_request().
726 *
727 * Deprecated: Use secret_collection_for_alias() instead.
728 **/
729 gpointer
gnome_keyring_get_default_keyring(GnomeKeyringOperationGetStringCallback callback,gpointer data,GDestroyNotify destroy_data)730 gnome_keyring_get_default_keyring (GnomeKeyringOperationGetStringCallback callback,
731 gpointer data,
732 GDestroyNotify destroy_data)
733 {
734 GkrOperation *op;
735
736 gkr_init ();
737
738 op = get_default_keyring_start (callback, data, destroy_data);
739 return gkr_operation_pending_and_unref (op);
740 }
741
742 /**
743 * gnome_keyring_get_default_keyring_sync:
744 * @keyring: (out): Location for the default keyring name to be returned.
745 *
746 * Get the default keyring name.
747 *
748 * The string returned in @keyring must be freed with g_free().
749 *
750 * For an asynchronous version of this function see gnome_keyring_get_default_keyring().
751 *
752 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
753 * an error result otherwise.
754 *
755 * Deprecated: Use secret_collection_for_alias_sync() instead.
756 **/
757 GnomeKeyringResult
gnome_keyring_get_default_keyring_sync(char ** keyring)758 gnome_keyring_get_default_keyring_sync (char **keyring)
759 {
760 GkrOperation *op;
761
762 g_return_val_if_fail (keyring, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
763
764 gkr_init ();
765
766 op = get_default_keyring_start (get_default_keyring_sync, keyring, NULL);
767 return gkr_operation_block_and_unref (op);
768 }
769
770 static void
list_keyring_names_sync(GnomeKeyringResult res,GList * names,gpointer user_data)771 list_keyring_names_sync (GnomeKeyringResult res, GList *names, gpointer user_data)
772 {
773 GList **result = user_data;
774 *result = names;
775 }
776
777 static gboolean
list_keyring_names_foreach(DBusMessageIter * iter,gpointer user_data)778 list_keyring_names_foreach (DBusMessageIter *iter, gpointer user_data)
779 {
780 GList **names = user_data;
781 const char *path;
782 gchar *name;
783
784 if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_OBJECT_PATH)
785 return FALSE;
786
787 /* The object path, gets converted into a name */
788 dbus_message_iter_get_basic (iter, &path);
789 name = gkr_decode_keyring_name (path);
790 if (name != NULL)
791 *names = g_list_prepend (*names, name);
792
793 return TRUE;
794 }
795
796 static void
list_keyring_names_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)797 list_keyring_names_reply (GkrOperation *op, DBusMessage *reply,
798 gpointer user_data)
799 {
800 GnomeKeyringResult res;
801 GList *names = NULL;
802 GkrCallback *cb;
803
804 if (gkr_operation_handle_errors (op, reply))
805 return;
806
807 res = decode_property_variant_array (reply, list_keyring_names_foreach, &names);
808 if (res == GNOME_KEYRING_RESULT_OK) {
809 cb = gkr_operation_pop (op);
810 gkr_callback_invoke_ok_list (cb, names);
811 if (cb->callback == list_keyring_names_sync)
812 names = NULL;
813 } else {
814 gkr_operation_complete (op, res);
815 }
816
817 gnome_keyring_string_list_free (names);
818 }
819
820 static GkrOperation*
list_keyring_names_start(GnomeKeyringOperationGetListCallback callback,gpointer data,GDestroyNotify destroy_data)821 list_keyring_names_start (GnomeKeyringOperationGetListCallback callback,
822 gpointer data, GDestroyNotify destroy_data)
823 {
824 GkrOperation *op;
825 DBusMessage *req;
826
827 g_return_val_if_fail (callback, NULL);
828
829 req = prepare_property_get (SERVICE_PATH, SERVICE_INTERFACE, "Collections");
830
831 op = gkr_operation_new (callback, GKR_CALLBACK_RES_LIST, data, destroy_data);
832 gkr_operation_push (op, list_keyring_names_reply, GKR_CALLBACK_OP_MSG, NULL, NULL);
833 gkr_operation_request (op, req);
834 dbus_message_unref (req);
835 return op;
836 }
837
838 /**
839 * gnome_keyring_list_keyring_names: (skip)
840 * @callback: A callback which will be called when the request completes or fails.
841 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
842 * @callback.
843 * @destroy_data: A function to free @data when it's no longer needed.
844 *
845 * Get a list of keyring names.
846 *
847 * A %GList of null terminated strings will be passed to
848 * the @callback. If no keyrings exist then an empty list will be passed to the
849 * @callback. The list is freed after @callback returns.
850 *
851 * For a synchronous version of this function see gnome_keyring_list_keyring_names_sync().
852 *
853 * Return value: (transfer none): The asynchronous request, which can be passed
854 * to gnome_keyring_cancel_request().
855 *
856 * Deprecated: Use secret_service_get_collections() instead.
857 **/
858 gpointer
gnome_keyring_list_keyring_names(GnomeKeyringOperationGetListCallback callback,gpointer data,GDestroyNotify destroy_data)859 gnome_keyring_list_keyring_names (GnomeKeyringOperationGetListCallback callback,
860 gpointer data,
861 GDestroyNotify destroy_data)
862 {
863 GkrOperation *op;
864
865 gkr_init ();
866
867 op = list_keyring_names_start (callback, data, destroy_data);
868 return gkr_operation_pending_and_unref (op);
869 }
870
871 /**
872 * gnome_keyring_list_keyring_names_sync:
873 * @keyrings: (out) (element-type utf8): Location for a %GList of keyring names to be returned.
874 *
875 * Get a list of keyring names.
876 *
877 * The list returned in in @keyrings must be freed using
878 * gnome_keyring_string_list_free().
879 *
880 * For an asynchronous version of this function see gnome_keyring_list_keyring_names().
881 *
882 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
883 * an error result otherwise.
884 *
885 * Deprecated: Use secret_service_get_collections() instead.
886 **/
887 GnomeKeyringResult
gnome_keyring_list_keyring_names_sync(GList ** keyrings)888 gnome_keyring_list_keyring_names_sync (GList **keyrings)
889 {
890 GkrOperation *op;
891
892 g_return_val_if_fail (keyrings, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
893
894 gkr_init ();
895
896 op = list_keyring_names_start (list_keyring_names_sync, keyrings, NULL);
897 return gkr_operation_block_and_unref (op);
898 }
899
900 static GkrOperation*
lock_all_start(GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)901 lock_all_start (GnomeKeyringOperationDoneCallback callback,
902 gpointer data, GDestroyNotify destroy_data)
903 {
904 DBusMessage *req;
905 GkrOperation *op;
906
907 g_return_val_if_fail (callback, NULL);
908
909 gkr_debug ("Calling o.f.S.Service.LockService");
910
911 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
912 SERVICE_INTERFACE, "LockService");
913
914 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
915 gkr_operation_request (op, req);
916 dbus_message_unref (req);
917
918 return op;
919 }
920
921 /**
922 * gnome_keyring_lock_all: (skip)
923 * @callback: A callback which will be called when the request completes or fails.
924 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
925 * @callback.
926 * @destroy_data: A function to free @data when it's no longer needed.
927 *
928 * Lock all the keyrings, so that their contents may not be accessed without
929 * first unlocking them with a password.
930 *
931 * For a synchronous version of this function see gnome_keyring_lock_all_sync().
932 *
933 * Return value: (transfer none): The asynchronous request, which can be passed
934 * to gnome_keyring_cancel_request().
935 *
936 * Deprecated: Use libsecret instead.
937 **/
938 gpointer
gnome_keyring_lock_all(GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)939 gnome_keyring_lock_all (GnomeKeyringOperationDoneCallback callback,
940 gpointer data,
941 GDestroyNotify destroy_data)
942 {
943 GkrOperation *op;
944
945 gkr_init ();
946
947 op = lock_all_start (callback, data, destroy_data);
948 return gkr_operation_pending_and_unref (op);
949 }
950
951 /**
952 * gnome_keyring_lock_all_sync:
953 *
954 * Lock all the keyrings, so that their contents may not eb accessed without
955 * first unlocking them with a password.
956 *
957 * For an asynchronous version of this function see gnome_keyring_lock_all().
958 *
959 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
960 * an error result otherwise.
961 *
962 * Deprecated: Use libsecret instead.
963 **/
964 GnomeKeyringResult
gnome_keyring_lock_all_sync(void)965 gnome_keyring_lock_all_sync (void)
966 {
967 GkrOperation *op;
968
969 gkr_init ();
970
971 op = lock_all_start (gkr_callback_empty, NULL, NULL);
972 return gkr_operation_block_and_unref (op);
973 }
974
975 typedef struct _create_keyring_args {
976 gchar *keyring_name;
977 gchar *password;
978 } create_keyring_args;
979
980 static void
create_keyring_free(gpointer data)981 create_keyring_free (gpointer data)
982 {
983 create_keyring_args *args = data;
984 g_free (args->keyring_name);
985 egg_secure_strfree (args->password);
986 g_slice_free (create_keyring_args, args);
987 }
988
989 static void
create_keyring_encode_properties(DBusMessageIter * iter,const gchar * keyring_name)990 create_keyring_encode_properties (DBusMessageIter *iter, const gchar *keyring_name)
991 {
992 DBusMessageIter array, dict, variant;
993 const gchar *label = COLLECTION_INTERFACE ".Label";
994
995 dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{sv}", &array);
996 dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
997 dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &label);
998 dbus_message_iter_open_container (&dict, DBUS_TYPE_VARIANT, "s", &variant);
999 dbus_message_iter_append_basic (&variant, DBUS_TYPE_STRING, &keyring_name);
1000 dbus_message_iter_close_container (&dict, &variant);
1001 dbus_message_iter_close_container (&array, &dict);
1002 dbus_message_iter_close_container (iter, &array);
1003 }
1004
1005 static void
create_keyring_password_reply(GkrOperation * op,GkrSession * session,gpointer user_data)1006 create_keyring_password_reply (GkrOperation *op, GkrSession *session, gpointer user_data)
1007 {
1008 create_keyring_args *args = user_data;
1009 DBusMessageIter iter;
1010 DBusMessage *req;
1011
1012 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
1013 "org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface",
1014 "CreateWithMasterPassword");
1015
1016 dbus_message_iter_init_append (req, &iter);
1017 create_keyring_encode_properties (&iter, args->keyring_name);
1018 if (!gkr_session_encode_secret (session, &iter, args->password)) {
1019 gkr_operation_complete (op, GNOME_KEYRING_RESULT_IO_ERROR);
1020 dbus_message_unref (req);
1021 return;
1022 }
1023
1024 gkr_operation_request (op, req);
1025 dbus_message_unref (req);
1026 }
1027
1028 static void
create_keyring_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)1029 create_keyring_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
1030 {
1031 const char *collection;
1032 const char *prompt;
1033
1034 if (gkr_operation_handle_errors (op, reply))
1035 return;
1036
1037 /* Parse the response */
1038 if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_OBJECT_PATH, &collection,
1039 DBUS_TYPE_OBJECT_PATH, &prompt, DBUS_TYPE_INVALID)) {
1040 g_warning ("bad response to CreateCollection from service");
1041 gkr_callback_invoke_res (gkr_operation_pop (op), GNOME_KEYRING_RESULT_IO_ERROR);
1042 return;
1043 }
1044
1045 /* No prompt, we're done */
1046 g_return_if_fail (prompt);
1047 if (g_str_equal (prompt, "/"))
1048 gkr_operation_complete (op, GNOME_KEYRING_RESULT_OK);
1049
1050 /* A prompt, display it, default handling for response */
1051 else
1052 gkr_operation_prompt (op, prompt);
1053 }
1054
1055 static void
create_keyring_check_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)1056 create_keyring_check_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
1057 {
1058 create_keyring_args *args = user_data;
1059 DBusMessageIter iter;
1060 DBusMessage *req;
1061 const gchar *alias = "";
1062
1063 /* If no such object, then no such keyring exists and we're good to go. */
1064 if (!dbus_message_is_error (reply, ERROR_NO_SUCH_OBJECT) &&
1065 !dbus_message_is_error (reply, DBUS_ERROR_UNKNOWN_METHOD)) {
1066 /* Success means 'already exists' */
1067 if (!gkr_operation_handle_errors (op, reply))
1068 gkr_operation_complete (op, GNOME_KEYRING_RESULT_ALREADY_EXISTS);
1069 return;
1070 }
1071
1072 /* With a password requires a session, so get on that */
1073 if (args->password) {
1074 gkr_operation_push (op, create_keyring_password_reply, GKR_CALLBACK_OP_SESSION, args, NULL);
1075 gkr_session_negotiate (op);
1076
1077 /* Otherwiswe just create the collection */
1078 } else {
1079 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
1080 SERVICE_INTERFACE, "CreateCollection");
1081 dbus_message_iter_init_append (req, &iter);
1082 create_keyring_encode_properties (&iter, args->keyring_name);
1083 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &alias);
1084 gkr_operation_push (op, create_keyring_reply, GKR_CALLBACK_OP_MSG, NULL, NULL);
1085 gkr_operation_request (op, req);
1086 dbus_message_unref (req);
1087 }
1088 }
1089
1090 static GkrOperation*
create_keyring_start(const char * keyring_name,const char * password,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)1091 create_keyring_start (const char *keyring_name, const char *password,
1092 GnomeKeyringOperationDoneCallback callback,
1093 gpointer data, GDestroyNotify destroy_data)
1094 {
1095 create_keyring_args *args;
1096 DBusMessage *req;
1097 GkrOperation *op;
1098 gchar *path;
1099
1100 g_return_val_if_fail (callback, NULL);
1101
1102 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
1103
1104 args = g_slice_new0 (create_keyring_args);
1105 args->keyring_name = g_strdup (keyring_name);
1106 args->password = egg_secure_strdup (password);
1107
1108 /*
1109 * The secrets API has a significantly different model with creating of
1110 * keyrings, where we never get an 'already exists' error. However this
1111 * breaks certain strange uses of gnome_keyring_create ().
1112 *
1113 * So we simulate 'already exists' in a fairly good, but 'racy' manner.
1114 */
1115
1116 path = gkr_encode_keyring_name (keyring_name);
1117 req = prepare_property_get (path, COLLECTION_INTERFACE, "Label");
1118 gkr_operation_push (op, create_keyring_check_reply, GKR_CALLBACK_OP_MSG,
1119 args, create_keyring_free);
1120 gkr_operation_request (op, req);
1121 dbus_message_unref (req);
1122 g_free (path);
1123
1124 return op;
1125 }
1126
1127 /**
1128 * gnome_keyring_create: (skip)
1129 * @keyring_name: The new keyring name. Must not be %NULL.
1130 * @password: (allow-none): The password for the new keyring. If %NULL user
1131 * will be prompted.
1132 * @callback: A callback which will be called when the request completes or fails.
1133 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
1134 * @callback.
1135 * @destroy_data: A function to free @data when it's no longer needed.
1136 *
1137 * Create a new keyring with the specified name. In most cases %NULL will be
1138 * passed as the @password, which will prompt the user to enter a password
1139 * of their choice.
1140 *
1141 * For a synchronous version of this function see gnome_keyring_create_sync().
1142 *
1143 * Return value: (transfer none): The asynchronous request, which can be passed
1144 * to gnome_keyring_cancel_request().
1145 *
1146 * Deprecated: Use secret_collection_create() instead.
1147 **/
1148 gpointer
gnome_keyring_create(const char * keyring_name,const char * password,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)1149 gnome_keyring_create (const char *keyring_name,
1150 const char *password,
1151 GnomeKeyringOperationDoneCallback callback,
1152 gpointer data,
1153 GDestroyNotify destroy_data)
1154 {
1155 GkrOperation *op;
1156
1157 gkr_init ();
1158
1159 op = create_keyring_start (keyring_name, password, callback, data, destroy_data);
1160 return gkr_operation_pending_and_unref (op);
1161 }
1162
1163 /**
1164 * gnome_keyring_create_sync:
1165 * @keyring_name: The new keyring name. Must not be %NULL
1166 * @password: (allow-none): The password for the new keyring. If %NULL user
1167 * will be prompted.
1168 *
1169 * Create a new keyring with the specified name. In most cases %NULL will be
1170 * passed in as the @password, which will prompt the user to enter a password
1171 * of their choice.
1172 *
1173 * For an asynchronous version of this function see gnome_keyring_create().
1174 *
1175 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
1176 * an error result otherwise.
1177 *
1178 * Deprecated: Use secret_collection_create_sync() instead.
1179 **/
1180 GnomeKeyringResult
gnome_keyring_create_sync(const char * keyring_name,const char * password)1181 gnome_keyring_create_sync (const char *keyring_name,
1182 const char *password)
1183 {
1184 GkrOperation *op;
1185
1186 gkr_init ();
1187
1188 op = create_keyring_start (keyring_name, password, gkr_callback_empty, NULL, NULL);
1189 return gkr_operation_block_and_unref (op);
1190 }
1191
1192 typedef struct _xlock_check_args {
1193 const gchar *path;
1194 gboolean matched;
1195 } xlock_check_args;
1196
1197 static gboolean
xlock_check_path(const char * path,gpointer user_data)1198 xlock_check_path (const char *path, gpointer user_data)
1199 {
1200 xlock_check_args *args = user_data;
1201 g_assert (path);
1202 g_assert (args->path);
1203 args->matched = g_str_equal (path, args->path);
1204 return !args->matched;
1205 }
1206
1207 static void
xlock_2_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)1208 xlock_2_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
1209 {
1210 xlock_check_args args = { user_data, FALSE };
1211 gboolean dismissed;
1212
1213 if (gkr_operation_handle_errors (op, reply))
1214 return;
1215
1216 if (!decode_xlock_completed (reply, &dismissed, xlock_check_path, &args)) {
1217 gkr_operation_complete (op, decode_invalid_response (reply));
1218 return;
1219 }
1220
1221 if (dismissed || !args.matched) {
1222 gkr_debug ("xlock prompt dismissed");
1223 gkr_operation_complete (op, GNOME_KEYRING_RESULT_DENIED);
1224 } else {
1225 gkr_debug ("xlock prompt completed");
1226 gkr_operation_complete (op, GNOME_KEYRING_RESULT_OK);
1227 }
1228 }
1229
1230 static void
xlock_1_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)1231 xlock_1_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
1232 {
1233 xlock_check_args args = { user_data, FALSE };
1234 const char *prompt;
1235
1236 if (gkr_operation_handle_errors (op, reply))
1237 return;
1238
1239 if (!decode_xlock_reply (reply, &prompt, xlock_check_path, &args)) {
1240 gkr_debug ("invalid response to xlock");
1241 gkr_operation_complete (op, decode_invalid_response (reply));
1242 return;
1243 }
1244
1245 if (args.matched) {
1246 gkr_debug ("xlocked without prompt");
1247 gkr_callback_invoke_res (gkr_operation_pop (op), GNOME_KEYRING_RESULT_OK);
1248 return;
1249 }
1250
1251 /* Is there a prompt needed? */
1252 if (!g_str_equal (prompt, "/")) {
1253 gkr_debug ("prompting for xlock");
1254 gkr_operation_push (op, xlock_2_reply, GKR_CALLBACK_OP_MSG, user_data, NULL);
1255 gkr_operation_prompt (op, prompt);
1256
1257 /* No prompt, and no opportunity to */
1258 } else {
1259 gkr_debug ("couldn't unlock the keyring, and no prompt");
1260 gkr_callback_invoke_res (gkr_operation_pop (op), GNOME_KEYRING_RESULT_NO_SUCH_KEYRING);
1261 }
1262 }
1263
1264 static GkrOperation*
xlock_async(const gchar * method,const gchar * keyring,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)1265 xlock_async (const gchar *method, const gchar *keyring,
1266 GnomeKeyringOperationDoneCallback callback,
1267 gpointer data, GDestroyNotify destroy_data)
1268 {
1269 DBusMessage *req;
1270 GkrOperation *op;
1271 gchar *path;
1272
1273 path = gkr_encode_keyring_name (keyring);
1274
1275 gkr_debug ("xlock operation without password, probable prompt %s", path);
1276 req = prepare_xlock (method, &path, 1);
1277
1278 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
1279 gkr_operation_push (op, xlock_1_reply, GKR_CALLBACK_OP_MSG, path, g_free);
1280 gkr_operation_request (op, req);
1281
1282 dbus_message_unref (req);
1283 return op;
1284 }
1285
1286 typedef struct _unlock_password_args {
1287 gchar *keyring_name;
1288 gchar *password;
1289 } unlock_password_args;
1290
1291 static void
unlock_password_free(gpointer data)1292 unlock_password_free (gpointer data)
1293 {
1294 unlock_password_args *args = data;
1295 g_free (args->keyring_name);
1296 egg_secure_strfree (args->password);
1297 g_slice_free (unlock_password_args, args);
1298 }
1299
1300 static void
unlock_password_reply(GkrOperation * op,GkrSession * session,gpointer user_data)1301 unlock_password_reply (GkrOperation *op, GkrSession *session, gpointer user_data)
1302 {
1303 unlock_password_args *args = user_data;
1304 DBusMessageIter iter;
1305 DBusMessage *req;
1306 gchar *path;
1307
1308 gkr_debug ("have session, unlocking with password");
1309
1310 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
1311 "org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface",
1312 "UnlockWithMasterPassword");
1313
1314 dbus_message_iter_init_append (req, &iter);
1315 path = gkr_encode_keyring_name (args->keyring_name);
1316 dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH, &path);
1317 g_free (path);
1318 if (!gkr_session_encode_secret (session, &iter, args->password)) {
1319 gkr_operation_complete (op, GNOME_KEYRING_RESULT_IO_ERROR);
1320 dbus_message_unref (req);
1321 return;
1322 }
1323
1324 gkr_operation_request (op, req);
1325 dbus_message_unref (req);
1326 }
1327
1328 static GkrOperation*
unlock_keyring_start(const char * keyring,const char * password,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)1329 unlock_keyring_start (const char *keyring, const char *password,
1330 GnomeKeyringOperationDoneCallback callback,
1331 gpointer data, GDestroyNotify destroy_data)
1332 {
1333 unlock_password_args *args;
1334 GkrOperation *op;
1335
1336 g_return_val_if_fail (callback, NULL);
1337
1338 /* Null password, standard operation */
1339 if (password == NULL)
1340 return xlock_async ("Unlock", keyring, callback, data, destroy_data);
1341
1342 g_return_val_if_fail (callback, NULL);
1343 gkr_debug ("unlocking with password");
1344
1345 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
1346
1347 args = g_slice_new0 (unlock_password_args);
1348 args->keyring_name = g_strdup (keyring);
1349 args->password = egg_secure_strdup (password);
1350 gkr_operation_push (op, unlock_password_reply, GKR_CALLBACK_OP_SESSION,
1351 args, unlock_password_free);
1352 gkr_operation_set_keyring_hint (op);
1353 gkr_session_negotiate (op);
1354
1355 return op;
1356 }
1357
1358 /**
1359 * gnome_keyring_unlock: (skip)
1360 * @keyring: (allow-none): The name of the keyring to unlock, or %NULL for the
1361 * default keyring.
1362 * @password: (allow-none): The password to unlock the keyring with, or %NULL
1363 * to prompt the user.
1364 * @callback: A callback which will be called when the request completes or fails.
1365 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
1366 * @callback.
1367 * @destroy_data: A function to free @data when it's no longer needed.
1368 *
1369 * Unlock a @keyring, so that its contents may be accessed. In most cases %NULL
1370 * will be passed as the @password, which will prompt the user to enter the
1371 * correct password.
1372 *
1373 * Most keyring operations involving items require that you first unlock the
1374 * keyring. One exception is gnome_keyring_find_items() and related functions.
1375 *
1376 * For a synchronous version of this function see gnome_keyring_unlock_sync().
1377 *
1378 * Return value: (transfer none): The asynchronous request, which can be passed
1379 * to gnome_keyring_cancel_request().
1380 *
1381 * Deprecated: Use secret_service_unlock() instead.
1382 **/
1383 gpointer
gnome_keyring_unlock(const char * keyring,const char * password,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)1384 gnome_keyring_unlock (const char *keyring,
1385 const char *password,
1386 GnomeKeyringOperationDoneCallback callback,
1387 gpointer data,
1388 GDestroyNotify destroy_data)
1389 {
1390 GkrOperation *op;
1391
1392 gkr_init ();
1393
1394 op = unlock_keyring_start (keyring, password, callback, data, destroy_data);
1395 return gkr_operation_pending_and_unref (op);
1396 }
1397
1398 /**
1399 * gnome_keyring_unlock_sync:
1400 * @keyring: (allow-none): The name of the keyring to unlock, or %NULL for the
1401 * default keyring.
1402 * @password: (allow-none): The password to unlock the keyring with, or %NULL
1403 * to prompt the user.
1404 *
1405 * Unlock a @keyring, so that its contents may be accessed. In most cases %NULL
1406 * will be passed in as the @password, which will prompt the user to enter the
1407 * correct password.
1408 *
1409 * Most keyring opretaions involving items require that yo ufirst unlock the
1410 * keyring. One exception is gnome_keyring_find_items_sync() and related functions.
1411 *
1412 * For an asynchronous version of this function see gnome_keyring_unlock().
1413 *
1414 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
1415 * an error result otherwise.
1416 *
1417 * Deprecated: Use secret_service_unlock_sync() instead.
1418 **/
1419 GnomeKeyringResult
gnome_keyring_unlock_sync(const char * keyring,const char * password)1420 gnome_keyring_unlock_sync (const char *keyring,
1421 const char *password)
1422 {
1423 GkrOperation *op;
1424
1425 gkr_init ();
1426
1427 op = unlock_keyring_start (keyring, password, gkr_callback_empty, NULL, NULL);
1428 return gkr_operation_block_and_unref (op);
1429 }
1430
1431 static GkrOperation*
lock_keyring_start(const char * keyring,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)1432 lock_keyring_start (const char *keyring, GnomeKeyringOperationDoneCallback callback,
1433 gpointer data, GDestroyNotify destroy_data)
1434 {
1435 g_return_val_if_fail (callback, NULL);
1436 return xlock_async ("Lock", keyring, callback, data, destroy_data);
1437 }
1438
1439 /**
1440 * gnome_keyring_lock: (skip)
1441 * @keyring: (allow-none): The name of the keyring to lock, or %NULL for the
1442 * default keyring.
1443 * @callback: A callback which will be called when the request completes or fails.
1444 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
1445 * @callback.
1446 * @destroy_data: A function to free @data when it's no longer needed.
1447 *
1448 * Lock a @keyring, so that its contents may not be accessed without first
1449 * supplying a password.
1450 *
1451 * Most keyring operations involving items require that you first unlock the
1452 * keyring. One exception is gnome_keyring_find_items() and related functions.
1453 *
1454 * For a synchronous version of this function see gnome_keyring_lock_sync().
1455 *
1456 * Return value: (transfer none): The asynchronous request, which can be passed
1457 * to gnome_keyring_cancel_request().
1458 *
1459 * Deprecated: Use secret_service_lock() instead.
1460 **/
1461 gpointer
gnome_keyring_lock(const char * keyring,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)1462 gnome_keyring_lock (const char *keyring,
1463 GnomeKeyringOperationDoneCallback callback,
1464 gpointer data,
1465 GDestroyNotify destroy_data)
1466 {
1467 GkrOperation* op;
1468
1469 gkr_init ();
1470
1471 op = lock_keyring_start (keyring, callback, data, destroy_data);
1472 return gkr_operation_pending_and_unref (op);
1473 }
1474
1475 /**
1476 * gnome_keyring_lock_sync:
1477 * @keyring: (allow-none): The name of the keyring to lock, or %NULL for the
1478 * default keyring.
1479 *
1480 * Lock a @keyring, so that its contents may not be accessed without first
1481 * supplying a password.
1482 *
1483 * Most keyring opretaions involving items require that you first unlock the
1484 * keyring. One exception is gnome_keyring_find_items_sync() and related functions.
1485 *
1486 * For an asynchronous version of this function see gnome_keyring_lock().
1487 *
1488 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
1489 * an error result otherwise.
1490 *
1491 * Deprecated: Use secret_service_lock_sync() instead.
1492 **/
1493 GnomeKeyringResult
gnome_keyring_lock_sync(const char * keyring)1494 gnome_keyring_lock_sync (const char *keyring)
1495 {
1496 GkrOperation *op;
1497
1498 gkr_init ();
1499
1500 op = lock_keyring_start (keyring, gkr_callback_empty, NULL, NULL);
1501 return gkr_operation_block_and_unref (op);
1502 }
1503
1504 static GkrOperation*
delete_keyring_start(const char * keyring,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)1505 delete_keyring_start (const char *keyring, GnomeKeyringOperationDoneCallback callback,
1506 gpointer data, GDestroyNotify destroy_data)
1507 {
1508 DBusMessage *req;
1509 GkrOperation *op;
1510 gchar *path;
1511
1512 g_return_val_if_fail (callback, NULL);
1513
1514 path = gkr_encode_keyring_name (keyring);
1515 req = dbus_message_new_method_call (gkr_service_name, path,
1516 COLLECTION_INTERFACE, "Delete");
1517
1518 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
1519 gkr_operation_request (op, req);
1520 dbus_message_unref (req);
1521 g_free (path);
1522
1523 return op;
1524 }
1525
1526 /**
1527 * gnome_keyring_delete: (skip)
1528 * @keyring: The name of the keyring to delete. Cannot be %NULL.
1529 * @callback: A callback which will be called when the request completes or fails.
1530 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
1531 * @callback.
1532 * @destroy_data: A function to free @data when it's no longer needed.
1533 *
1534 * Delete @keyring. Once a keyring is deleted there is no mechanism for
1535 * recovery of its contents.
1536 *
1537 * For a synchronous version of this function see gnome_keyring_delete_sync().
1538 *
1539 * Return value: (transfer none): The asynchronous request, which can be passed
1540 * to gnome_keyring_cancel_request().
1541 *
1542 * Deprecated: Use secret_collection_delete() instead.
1543 **/
1544 gpointer
gnome_keyring_delete(const char * keyring,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)1545 gnome_keyring_delete (const char *keyring,
1546 GnomeKeyringOperationDoneCallback callback,
1547 gpointer data,
1548 GDestroyNotify destroy_data)
1549 {
1550 GkrOperation *op;
1551
1552 gkr_init ();
1553
1554 op = delete_keyring_start (keyring, callback, data, destroy_data);
1555 return gkr_operation_pending_and_unref (op);
1556 }
1557
1558 /**
1559 * gnome_keyring_delete_sync:
1560 * @keyring: The name of the keyring to delete. Cannot be %NULL
1561 *
1562 * Delete @keyring. Once a keyring is deleted there is no mechanism for
1563 * recovery of its contents.
1564 *
1565 * For an asynchronous version of this function see gnome_keyring_delete().
1566 *
1567 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
1568 * an error result otherwise.
1569 *
1570 * Deprecated: Use secret_collection_delete_sync() instead.
1571 **/
1572 GnomeKeyringResult
gnome_keyring_delete_sync(const char * keyring)1573 gnome_keyring_delete_sync (const char *keyring)
1574 {
1575 GkrOperation *op;
1576
1577 gkr_init ();
1578
1579 op = delete_keyring_start (keyring, gkr_callback_empty, NULL, NULL);
1580 return gkr_operation_block_and_unref (op);
1581 }
1582
1583 typedef struct _change_password_args {
1584 gchar *keyring_name;
1585 gchar *password;
1586 gchar *original;
1587 } change_password_args;
1588
1589 static void
change_password_free(gpointer data)1590 change_password_free (gpointer data)
1591 {
1592 change_password_args *args = data;
1593 g_free (args->keyring_name);
1594 egg_secure_strfree (args->password);
1595 egg_secure_strfree (args->original);
1596 g_slice_free (change_password_args, args);
1597 }
1598
1599 static void
change_password_reply(GkrOperation * op,GkrSession * session,gpointer user_data)1600 change_password_reply (GkrOperation *op, GkrSession *session, gpointer user_data)
1601 {
1602 change_password_args *args = user_data;
1603 DBusMessageIter iter;
1604 DBusMessage *req;
1605 gchar *path;
1606
1607 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
1608 "org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface",
1609 "ChangeWithMasterPassword");
1610
1611 dbus_message_iter_init_append (req, &iter);
1612 path = gkr_encode_keyring_name (args->keyring_name);
1613 dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH, &path);
1614 g_free (path);
1615 if (!gkr_session_encode_secret (session, &iter, args->original) ||
1616 !gkr_session_encode_secret (session, &iter, args->password)) {
1617 gkr_operation_complete (op, GNOME_KEYRING_RESULT_IO_ERROR);
1618 dbus_message_unref (req);
1619 return;
1620 }
1621
1622 gkr_operation_request (op, req);
1623 dbus_message_unref (req);
1624 }
1625
1626
1627 static void
change_2_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)1628 change_2_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
1629 {
1630 DBusMessageIter iter;
1631 dbus_bool_t dismissed;
1632
1633 if (gkr_operation_handle_errors (op, reply))
1634 return;
1635
1636 if (!dbus_message_has_signature (reply, "bv")) {
1637 gkr_operation_complete (op, decode_invalid_response (reply));
1638 return;
1639 }
1640
1641 if (!dbus_message_iter_init (reply, &iter))
1642 g_return_if_reached ();
1643 dbus_message_iter_get_basic (&iter, &dismissed);
1644
1645 if (dismissed)
1646 gkr_operation_complete (op, GNOME_KEYRING_RESULT_DENIED);
1647 else
1648 gkr_operation_complete (op, GNOME_KEYRING_RESULT_OK);
1649 }
1650
1651 static void
change_1_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)1652 change_1_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
1653 {
1654 const char *prompt;
1655
1656 if (gkr_operation_handle_errors (op, reply))
1657 return;
1658
1659 if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_OBJECT_PATH, &prompt, DBUS_TYPE_INVALID)) {
1660 gkr_operation_complete (op, decode_invalid_response (reply));
1661 return;
1662 }
1663
1664 /* Is there a prompt needed? */
1665 if (!g_str_equal (prompt, "/")) {
1666 gkr_operation_push (op, change_2_reply, GKR_CALLBACK_OP_MSG, user_data, NULL);
1667 gkr_operation_prompt (op, prompt);
1668
1669 /* Somehow, no prompt was necessary */
1670 } else {
1671 gkr_operation_complete (op, GNOME_KEYRING_RESULT_OK);
1672 }
1673 }
1674
1675 static GkrOperation*
change_password_start(const char * keyring,const char * original,const char * password,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)1676 change_password_start (const char *keyring, const char *original, const char *password,
1677 GnomeKeyringOperationDoneCallback callback, gpointer data,
1678 GDestroyNotify destroy_data)
1679 {
1680 change_password_args *args;
1681 DBusMessage *req;
1682 GkrOperation *op;
1683 gchar *path;
1684
1685 g_return_val_if_fail (callback, NULL);
1686
1687 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
1688
1689 /* With and without password are completely different */
1690
1691 if (password || original) {
1692 args = g_slice_new0 (change_password_args);
1693 args->keyring_name = g_strdup (keyring);
1694 args->password = egg_secure_strdup (password);
1695 args->original = egg_secure_strdup (original);
1696 gkr_operation_push (op, change_password_reply, GKR_CALLBACK_OP_SESSION,
1697 args, change_password_free);
1698 gkr_session_negotiate (op);
1699
1700 } else {
1701 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
1702 SERVICE_INTERFACE, "ChangeLock");
1703 path = gkr_encode_keyring_name (keyring);
1704 dbus_message_append_args (req, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
1705 gkr_operation_push (op, change_1_reply, GKR_CALLBACK_OP_MSG, path, g_free);
1706 gkr_operation_request (op, req);
1707 dbus_message_unref (req);
1708 }
1709
1710 return op;
1711 }
1712
1713 /**
1714 * gnome_keyring_change_password: (skip)
1715 * @keyring: The name of the keyring to change the password for. Cannot be %NULL.
1716 * @original: (allow-none): The old keyring password, or %NULL to prompt the
1717 * user for it.
1718 * @password: (allow-none): The new keyring password, or %NULL to prompt the
1719 * user for it.
1720 * @callback: A callback which will be called when the request completes or fails.
1721 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
1722 * @callback.
1723 * @destroy_data: A function to free @data when it's no longer needed.
1724 *
1725 * Change the password for a @keyring. In most cases you would specify %NULL for
1726 * both the @original and @password arguments and allow the user to type the
1727 * correct passwords.
1728 *
1729 * For a synchronous version of this function see gnome_keyring_change_password_sync().
1730 *
1731 * Return value: (transfer none): The asynchronous request, which can be passed
1732 * to gnome_keyring_cancel_request().
1733 *
1734 * Deprecated: Not used with libsecret.
1735 **/
1736 gpointer
gnome_keyring_change_password(const char * keyring,const char * original,const char * password,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)1737 gnome_keyring_change_password (const char *keyring,
1738 const char *original,
1739 const char *password,
1740 GnomeKeyringOperationDoneCallback callback,
1741 gpointer data,
1742 GDestroyNotify destroy_data)
1743 {
1744 GkrOperation *op;
1745
1746 gkr_init ();
1747
1748 op = change_password_start (keyring, original, password, callback, data, destroy_data);
1749 return gkr_operation_pending_and_unref (op);
1750 }
1751
1752
1753 /**
1754 * gnome_keyring_change_password_sync:
1755 * @keyring: The name of the keyring to change the password for. Cannot be %NULL
1756 * @original: (allow-none): The old keyring password, or %NULL to prompt the
1757 * user for it.
1758 * @password: (allow-none): The new keyring password, or %NULL to prompt the
1759 * user for it.
1760 *
1761 * Change the password for @keyring. In most cases you would specify %NULL for
1762 * both the @original and @password arguments and allow the user to type the
1763 * correct passwords.
1764 *
1765 * For an asynchronous version of this function see gnome_keyring_change_password().
1766 *
1767 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
1768 * an error result otherwise.
1769 *
1770 * Deprecated: Not used with libsecret.
1771 **/
1772 GnomeKeyringResult
gnome_keyring_change_password_sync(const char * keyring_name,const char * original,const char * password)1773 gnome_keyring_change_password_sync (const char *keyring_name,
1774 const char *original, const char *password)
1775 {
1776 GkrOperation *op;
1777
1778 gkr_init ();
1779
1780 op = change_password_start (keyring_name, original, password, gkr_callback_empty, NULL, NULL);
1781 return gkr_operation_block_and_unref (op);
1782 }
1783
1784 static gboolean
decode_time_from_iter(DBusMessageIter * iter,time_t * tval)1785 decode_time_from_iter (DBusMessageIter *iter,
1786 time_t *tval)
1787 {
1788 dbus_int64_t i64val;
1789 dbus_uint64_t ui64val;
1790
1791 if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_INT64) {
1792 dbus_message_iter_get_basic (iter, &i64val);
1793 *tval = (time_t)i64val;
1794 } else if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UINT64) {
1795 dbus_message_iter_get_basic (iter, &ui64val);
1796 *tval = (time_t)ui64val;
1797 } else {
1798 return FALSE;
1799 }
1800
1801 return TRUE;
1802 }
1803
1804 static gboolean
get_keyring_info_foreach(const gchar * property,DBusMessageIter * iter,gpointer user_data)1805 get_keyring_info_foreach (const gchar *property, DBusMessageIter *iter, gpointer user_data)
1806 {
1807 GnomeKeyringInfo *info = user_data;
1808 dbus_bool_t bval;
1809
1810 if (g_str_equal (property, "Locked")) {
1811 if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_BOOLEAN)
1812 return FALSE;
1813 dbus_message_iter_get_basic (iter, &bval);
1814 info->is_locked = (bval == TRUE);
1815
1816 } else if (g_str_equal (property, "Created")) {
1817 if (!decode_time_from_iter (iter, &info->ctime)) {
1818 gkr_debug ("invalid Created property type: %s",
1819 dbus_message_iter_get_signature (iter));
1820 return FALSE;
1821 }
1822
1823 } else if (g_str_equal (property, "Modified")) {
1824 if (!decode_time_from_iter (iter, &info->mtime)) {
1825 gkr_debug ("invalid Modified property type: %s",
1826 dbus_message_iter_get_signature (iter));
1827 return FALSE;
1828 }
1829 }
1830
1831 return TRUE;
1832 }
1833
1834 static void
get_keyring_info_sync(GnomeKeyringResult res,GnomeKeyringInfo * info,gpointer user_data)1835 get_keyring_info_sync (GnomeKeyringResult res, GnomeKeyringInfo *info, gpointer user_data)
1836 {
1837 GnomeKeyringInfo **result = user_data;
1838 *result = info;
1839 }
1840
1841 static void
get_keyring_info_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)1842 get_keyring_info_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
1843 {
1844 GnomeKeyringResult res;
1845 GnomeKeyringInfo *info;
1846 GkrCallback *cb;
1847
1848 if (gkr_operation_handle_errors (op, reply))
1849 return;
1850
1851 info = g_new0 (GnomeKeyringInfo, 1);
1852 res = decode_property_dict (reply, get_keyring_info_foreach, info);
1853 if (res == GNOME_KEYRING_RESULT_OK) {
1854 cb = gkr_operation_pop (op);
1855 gkr_callback_invoke_ok_keyring_info (cb, info);
1856 if (cb->callback == get_keyring_info_sync)
1857 info = NULL;
1858 } else {
1859 gkr_operation_complete (op, res);
1860 }
1861
1862 gnome_keyring_info_free (info);
1863 }
1864
1865 static GkrOperation*
get_keyring_info_start(const char * keyring,GnomeKeyringOperationGetKeyringInfoCallback callback,gpointer data,GDestroyNotify destroy_data)1866 get_keyring_info_start (const char *keyring, GnomeKeyringOperationGetKeyringInfoCallback callback,
1867 gpointer data, GDestroyNotify destroy_data)
1868 {
1869 DBusMessage *req;
1870 GkrOperation *op;
1871 gchar *path;
1872
1873 g_return_val_if_fail (callback, NULL);
1874
1875 path = gkr_encode_keyring_name (keyring);
1876
1877 gkr_debug ("getting info for keyring: %s", path);
1878 req = prepare_property_getall (path, COLLECTION_INTERFACE);
1879
1880 op = gkr_operation_new (callback, GKR_CALLBACK_RES_KEYRING_INFO, data, destroy_data);
1881 gkr_operation_push (op, get_keyring_info_reply, GKR_CALLBACK_OP_MSG, NULL, NULL);
1882 gkr_operation_request (op, req);
1883 dbus_message_unref (req);
1884 g_free (path);
1885
1886 return op;
1887 }
1888
1889 /**
1890 * gnome_keyring_get_info: (skip)
1891 * @keyring: (allow-none): The name of the keyring, or %NULL for the default
1892 * keyring.
1893 * @callback: A callback which will be called when the request completes or fails.
1894 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
1895 * @callback.
1896 * @destroy_data: A function to free @data when it's no longer needed.
1897 *
1898 * Get information about the @keyring. The resulting #GnomeKeyringInfo structure
1899 * will be passed to @callback. The structure is freed after @callback returns.
1900 *
1901 * For a synchronous version of this function see gnome_keyring_get_info_sync().
1902 *
1903 * Return value: (transfer none): The asynchronous request, which can be passed
1904 * to gnome_keyring_cancel_request().
1905 *
1906 * Deprecated: Use #SecretCollection objects instead.
1907 **/
1908 gpointer
gnome_keyring_get_info(const char * keyring,GnomeKeyringOperationGetKeyringInfoCallback callback,gpointer data,GDestroyNotify destroy_data)1909 gnome_keyring_get_info (const char *keyring,
1910 GnomeKeyringOperationGetKeyringInfoCallback callback,
1911 gpointer data,
1912 GDestroyNotify destroy_data)
1913 {
1914 GkrOperation *op;
1915
1916 gkr_init ();
1917
1918 op = get_keyring_info_start (keyring, callback, data, destroy_data);
1919 return gkr_operation_pending_and_unref (op);
1920 }
1921
1922 /**
1923 * gnome_keyring_get_info_sync:
1924 * @keyring: (allow-none): The name of the keyring, or %NULL for the default
1925 * keyring.
1926 * @info: (out): Location for the information about the keyring to be returned.
1927 *
1928 * Get information about @keyring.
1929 *
1930 * The #GnomeKeyringInfo structure returned in @info must be freed with
1931 * gnome_keyring_info_free().
1932 *
1933 * For an asynchronous version of this function see gnome_keyring_get_info().
1934 *
1935 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
1936 * an error result otherwise.
1937 *
1938 * Deprecated: Use #SecretCollection objects instead.
1939 **/
1940 GnomeKeyringResult
gnome_keyring_get_info_sync(const char * keyring,GnomeKeyringInfo ** info)1941 gnome_keyring_get_info_sync (const char *keyring,
1942 GnomeKeyringInfo **info)
1943 {
1944 GkrOperation *op;
1945
1946 g_return_val_if_fail (info, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
1947
1948 gkr_init ();
1949
1950 op = get_keyring_info_start (keyring, get_keyring_info_sync, info, NULL);
1951 return gkr_operation_block_and_unref (op);
1952 }
1953
1954 static GkrOperation*
set_keyring_info_start(const char * keyring,GnomeKeyringInfo * info,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)1955 set_keyring_info_start (const char *keyring, GnomeKeyringInfo *info,
1956 GnomeKeyringOperationDoneCallback callback,
1957 gpointer data, GDestroyNotify destroy_data)
1958 {
1959 GkrOperation *op;
1960 gchar *path;
1961
1962 g_return_val_if_fail (info, NULL);
1963 g_return_val_if_fail (callback, NULL);
1964
1965 path = gkr_encode_keyring_name (keyring);
1966
1967 /*
1968 * TODO: Currently nothing to do. lock_on_idle and lock_timeout are not
1969 * implemented in the DBus API. They were never used by the old
1970 * gnome-keyring-daemon either.
1971 */
1972
1973 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
1974 gkr_operation_complete_later (op, GNOME_KEYRING_RESULT_OK);
1975
1976 g_free (path);
1977 return op;
1978 }
1979
1980 /**
1981 * gnome_keyring_set_info: (skip)
1982 * @keyring: (allow-none): The name of the keyring, or %NULL for the default
1983 * keyring.
1984 * @info: A structure containing flags and info for the keyring.
1985 * @callback: A callback which will be called when the request completes or fails.
1986 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
1987 * @callback.
1988 * @destroy_data: A function to free @data when it's no longer needed.
1989 *
1990 * Set flags and info for the @keyring. The only fields in @info that are used
1991 * are lock_on_idle and lock_timeout.
1992 *
1993 * For a synchronous version of this function see gnome_keyring_set_info_sync().
1994 *
1995 * Return value: (transfer none): The asynchronous request, which can be passed
1996 * to gnome_keyring_cancel_request().
1997 *
1998 * Deprecated: Use #SecretCollection objects instead.
1999 **/
2000 gpointer
gnome_keyring_set_info(const char * keyring,GnomeKeyringInfo * info,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)2001 gnome_keyring_set_info (const char *keyring,
2002 GnomeKeyringInfo *info,
2003 GnomeKeyringOperationDoneCallback callback,
2004 gpointer data,
2005 GDestroyNotify destroy_data)
2006 {
2007 GkrOperation *op;
2008
2009 gkr_init ();
2010
2011 op = set_keyring_info_start (keyring, info, callback, data, destroy_data);
2012 return gkr_operation_pending_and_unref (op);
2013 }
2014
2015 /**
2016 * gnome_keyring_set_info_sync:
2017 * @keyring: (allow-none): The name of the keyring, or %NULL for the default
2018 * keyring.
2019 * @info: A structure containing flags and info for the keyring.
2020 *
2021 * Set flags and info for @keyring. The only fields in @info that are used
2022 * are lock_on_idle and lock_timeout.
2023 *
2024 * For an asynchronous version of this function see gnome_keyring_set_info().
2025 *
2026 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
2027 * an error result otherwise.
2028 *
2029 * Deprecated: Use #SecretCollection objects instead.
2030 **/
2031 GnomeKeyringResult
gnome_keyring_set_info_sync(const char * keyring,GnomeKeyringInfo * info)2032 gnome_keyring_set_info_sync (const char *keyring,
2033 GnomeKeyringInfo *info)
2034 {
2035 gchar *path;
2036
2037 g_return_val_if_fail (info, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
2038
2039 gkr_init ();
2040
2041 path = gkr_encode_keyring_name (keyring);
2042
2043 /*
2044 * TODO: Currently nothing to do. lock_on_idle and lock_timeout are not
2045 * implemented in the DBus API. They were never used by the old
2046 * gnome-keyring-daemon either.
2047 */
2048
2049 g_free (path);
2050 return GNOME_KEYRING_RESULT_OK;
2051 }
2052
2053 static void
list_item_ids_sync(GnomeKeyringResult res,GList * ids,gpointer user_data)2054 list_item_ids_sync (GnomeKeyringResult res, GList *ids, gpointer user_data)
2055 {
2056 GList **result = user_data;
2057 *result = ids;
2058 }
2059
2060 static gboolean
list_item_ids_foreach(DBusMessageIter * iter,gpointer data)2061 list_item_ids_foreach (DBusMessageIter *iter, gpointer data)
2062 {
2063 GList **ids = data;
2064 const char *path;
2065 guint32 id;
2066
2067 if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_OBJECT_PATH)
2068 return FALSE;
2069
2070 /* The object path, gets converted into a name */
2071 dbus_message_iter_get_basic (iter, &path);
2072 if (gkr_decode_item_id (path, &id))
2073 *ids = g_list_prepend (*ids, GUINT_TO_POINTER (id));
2074 else
2075 g_message ("unsupported item. identifier is not an integer: %s", path);
2076
2077 return TRUE;
2078 }
2079
2080 static void
list_item_ids_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)2081 list_item_ids_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
2082 {
2083 GnomeKeyringResult res;
2084 GList *ids = NULL;
2085 GkrCallback *cb;
2086
2087 if (gkr_operation_handle_errors (op, reply))
2088 return;
2089
2090 res = decode_property_variant_array (reply, list_item_ids_foreach, &ids);
2091 if (res == GNOME_KEYRING_RESULT_OK) {
2092 cb = gkr_operation_pop (op);
2093 gkr_callback_invoke_ok_list (cb, ids);
2094 if (cb->callback == list_item_ids_sync)
2095 ids = NULL;
2096 } else {
2097 gkr_operation_complete (op, res);
2098 }
2099
2100 g_list_free (ids);
2101 }
2102
2103 static GkrOperation*
list_item_ids_start(const char * keyring,GnomeKeyringOperationGetListCallback callback,gpointer data,GDestroyNotify destroy_data)2104 list_item_ids_start (const char *keyring, GnomeKeyringOperationGetListCallback callback,
2105 gpointer data, GDestroyNotify destroy_data)
2106 {
2107 DBusMessage *req;
2108 GkrOperation *op;
2109 gchar *path;
2110
2111 g_return_val_if_fail (callback, NULL);
2112
2113 path = gkr_encode_keyring_name (keyring);
2114 req = prepare_property_get (path, COLLECTION_INTERFACE, "Items");
2115
2116 op = gkr_operation_new (callback, GKR_CALLBACK_RES_LIST, data, destroy_data);
2117 gkr_operation_push (op, list_item_ids_reply, GKR_CALLBACK_OP_MSG, NULL, NULL);
2118 gkr_operation_request (op, req);
2119
2120 dbus_message_unref (req);
2121 g_free (path);
2122
2123 return op;
2124 }
2125
2126 /**
2127 * gnome_keyring_list_item_ids: (skip)
2128 * @keyring: (allow-none): The name of the keyring, or %NULL for the default
2129 * keyring.
2130 * @callback: A callback which will be called when the request completes or fails.
2131 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
2132 * @callback.
2133 * @destroy_data: A function to free @data when it's no longer needed.
2134 *
2135 * Get a list of all the ids for items in @keyring. These are passed in a %GList
2136 * to the @callback. Use GPOINTER_TO_UINT() on the list to access the integer ids.
2137 * The list is freed after @callback returns.
2138 *
2139 * All items that are not flagged as %GNOME_KEYRING_ITEM_APPLICATION_SECRET are
2140 * included in the list. This includes items that the calling application may not
2141 * (yet) have access to.
2142 *
2143 * For a synchronous version of this function see gnome_keyring_list_item_ids_sync().
2144 *
2145 * Return value: (transfer none): The asynchronous request, which can be passed
2146 * to gnome_keyring_cancel_request().
2147 *
2148 * Deprecated: Use secret_collection_get_items() instead.
2149 **/
2150 gpointer
gnome_keyring_list_item_ids(const char * keyring,GnomeKeyringOperationGetListCallback callback,gpointer data,GDestroyNotify destroy_data)2151 gnome_keyring_list_item_ids (const char *keyring,
2152 GnomeKeyringOperationGetListCallback callback,
2153 gpointer data,
2154 GDestroyNotify destroy_data)
2155 {
2156 GkrOperation *op;
2157
2158 gkr_init ();
2159
2160 op = list_item_ids_start (keyring, callback, data, destroy_data);
2161 return gkr_operation_pending_and_unref (op);
2162 }
2163
2164 /**
2165 * gnome_keyring_list_item_ids_sync:
2166 * @keyring: (allow-none): The name of the keyring, or %NULL for the default
2167 * keyring.
2168 * @ids: (out) (element-type guint): The location to store a %GList of item ids
2169 * (ie: unsigned integers).
2170 *
2171 * Get a list of all the ids for items in @keyring.
2172 *
2173 * Use GPOINTER_TO_UINT() on the list to access the integer ids. The list
2174 * should be freed with g_list_free().
2175 *
2176 * For an asynchronous version of this function see gnome_keyring_list_item_ids().
2177 *
2178 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
2179 * an error result otherwise.
2180 *
2181 * Deprecated: Use secret_collection_get_items() instead.
2182 **/
2183 GnomeKeyringResult
gnome_keyring_list_item_ids_sync(const char * keyring,GList ** ids)2184 gnome_keyring_list_item_ids_sync (const char *keyring,
2185 GList **ids)
2186 {
2187 GkrOperation *op;
2188
2189 g_return_val_if_fail (ids, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
2190
2191 gkr_init ();
2192
2193 op = list_item_ids_start (keyring, list_item_ids_sync, ids, NULL);
2194 return gkr_operation_block_and_unref (op);
2195 }
2196
2197 /**
2198 * SECTION:gnome-keyring-daemon
2199 * @title: Daemon Management Functions
2200 * @short_description: Functions used by session to run the Gnome Keyring Daemon.
2201 *
2202 * <warning>All of these APIs are deprecated. Use
2203 * <ulink href="http://developer.gnome.org/libsecret/stable/">libsecret</ulink>
2204 * instead.</warning>
2205 *
2206 * These functions are not used by most applications using Gnome Keyring.
2207 **/
2208
2209 /**
2210 * gnome_keyring_daemon_set_display_sync:
2211 * @display: Deprecated
2212 *
2213 * Deprecated: No longer supported, always fails.
2214 *
2215 * Return value: GNOME_KEYRING_RESULT_DENIED
2216 **/
2217 GnomeKeyringResult
gnome_keyring_daemon_set_display_sync(const char * display)2218 gnome_keyring_daemon_set_display_sync (const char *display)
2219 {
2220 g_return_val_if_fail (display, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
2221 return GNOME_KEYRING_RESULT_DENIED;
2222 }
2223
2224 /**
2225 * gnome_keyring_daemon_prepare_environment_sync:
2226 *
2227 * Deprecated: No longer supported, call is ignored.
2228 *
2229 * Return value: GNOME_KEYRING_RESULT_OK
2230 **/
2231 GnomeKeyringResult
gnome_keyring_daemon_prepare_environment_sync(void)2232 gnome_keyring_daemon_prepare_environment_sync (void)
2233 {
2234 return GNOME_KEYRING_RESULT_OK;
2235 }
2236
2237 /**
2238 * SECTION:gnome-keyring-find
2239 * @title: Search Functionality
2240 * @short_description: Find Keyring Items
2241 *
2242 * <warning>All of these APIs are deprecated. Use
2243 * <ulink href="http://developer.gnome.org/libsecret/stable/">libsecret</ulink>
2244 * instead.</warning>
2245 *
2246 * A find operation searches through all keyrings for items that match the
2247 * attributes. The user may have been prompted to unlock necessary keyrings, and
2248 * user will have been prompted for access to the items if needed.
2249 *
2250 * A find operation may return multiple or zero results.
2251 **/
2252
2253 typedef struct _find_items_args {
2254 GList *found;
2255 GList *queued;
2256 GkrSession *session;
2257 GPtrArray *paths;
2258 } find_items_args;
2259
2260 static void
find_items_free(gpointer data)2261 find_items_free (gpointer data)
2262 {
2263 find_items_args *args = data;
2264 guint i;
2265
2266 gnome_keyring_found_list_free (args->queued);
2267 gnome_keyring_found_list_free (args->found);
2268 gkr_session_unref (args->session);
2269 for (i = 0; i < args->paths->len; ++i)
2270 g_free (g_ptr_array_index (args->paths, i));
2271 g_ptr_array_free (args->paths, TRUE);
2272
2273 g_slice_free (find_items_args, args);
2274 }
2275
2276 static void
find_items_sync(GnomeKeyringResult res,GList * found,gpointer user_data)2277 find_items_sync (GnomeKeyringResult res, GList *found, gpointer user_data)
2278 {
2279 GList **result = user_data;
2280 *result = found;
2281 }
2282
2283 static gboolean
find_items_queue(const char * path,gpointer user_data)2284 find_items_queue (const char *path, gpointer user_data)
2285 {
2286 find_items_args *args = user_data;
2287 g_ptr_array_add (args->paths, g_strdup (path));
2288 return TRUE;
2289 }
2290
2291 static gboolean
find_items_decode_secrets(DBusMessageIter * iter,find_items_args * args)2292 find_items_decode_secrets (DBusMessageIter *iter, find_items_args *args)
2293 {
2294 DBusMessageIter array, dict;
2295 GnomeKeyringFound *found;
2296 const char *path;
2297 gchar *keyring;
2298 gchar *secret;
2299 guint32 item_id;
2300 int type;
2301
2302 if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_ARRAY ||
2303 dbus_message_iter_get_element_type (iter) != DBUS_TYPE_DICT_ENTRY)
2304 return FALSE;
2305
2306 dbus_message_iter_recurse (iter, &array);
2307
2308 for (;;) {
2309 type = dbus_message_iter_get_arg_type (&array);
2310 if (type == DBUS_TYPE_INVALID)
2311 break;
2312 else if (type != DBUS_TYPE_DICT_ENTRY)
2313 return FALSE;
2314 dbus_message_iter_recurse (&array, &dict);
2315 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_OBJECT_PATH)
2316 return FALSE;
2317
2318 /* The item path */
2319 dbus_message_iter_get_basic (&dict, &path);
2320 if (!dbus_message_iter_next (&dict))
2321 return FALSE;
2322
2323 keyring = gkr_decode_keyring_item_id (path, &item_id);
2324 if (keyring == NULL)
2325 return FALSE;
2326
2327 /* The secret */
2328 if (!gkr_session_decode_secret (args->session, &dict, &secret)) {
2329 g_free (keyring);
2330 return FALSE;
2331 }
2332
2333 found = g_new0 (GnomeKeyringFound, 1);
2334 found->item_id = item_id;
2335 found->keyring = keyring;
2336 found->secret = secret;
2337 args->queued = g_list_prepend (args->queued, found);
2338
2339 dbus_message_iter_next (&array);
2340 }
2341
2342 return TRUE;
2343 }
2344
2345 static void
find_items_6_reply(GkrOperation * op,DBusMessage * reply,gpointer data)2346 find_items_6_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
2347 {
2348 GnomeKeyringFound *found;
2349 find_items_args *args = data;
2350 GnomeKeyringResult res;
2351 DBusMessage *req;
2352 gchar *path;
2353 GkrCallback *cb;
2354
2355 if (reply != NULL) {
2356
2357 /* At this point we have a response to GetProperty("Attributes") */
2358
2359 if (gkr_operation_handle_errors (op, reply))
2360 return;
2361
2362 found = args->queued->data;
2363 args->queued = g_list_remove (args->queued, args->queued->data);
2364 args->found = g_list_prepend (args->found, found);
2365
2366 found->attributes = gnome_keyring_attribute_list_new ();
2367 res = decode_get_attributes (reply, found->attributes);
2368 if (res != GNOME_KEYRING_RESULT_OK) {
2369 gkr_operation_complete (op, res);
2370 return;
2371 }
2372 }
2373
2374 /* Do we have any more items? */
2375 if (!args->queued) {
2376 if (args->found) {
2377 /* Back to the original order returned from daemon */
2378 args->found = g_list_reverse (args->found);
2379
2380 cb = gkr_operation_pop (op);
2381 gkr_callback_invoke_ok_list (cb, args->found);
2382 if (cb->callback == find_items_sync)
2383 args->found = NULL;
2384 } else {
2385 gkr_operation_complete (op, GNOME_KEYRING_RESULT_NO_MATCH);
2386 }
2387 return;
2388 }
2389
2390 /* Next item in the queue */
2391 found = args->queued->data;
2392 g_assert (found);
2393
2394 /* Request the next set of attributes */
2395 path = gkr_encode_keyring_item_id (found->keyring, found->item_id);
2396 req = prepare_property_get (path, ITEM_INTERFACE, "Attributes");
2397 g_free (path);
2398
2399 gkr_operation_push (op, find_items_6_reply, GKR_CALLBACK_OP_MSG, args, NULL);
2400 gkr_operation_request (op, req);
2401 dbus_message_unref (req);
2402 }
2403
2404 static void
find_items_5_reply(GkrOperation * op,DBusMessage * reply,gpointer data)2405 find_items_5_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
2406 {
2407 find_items_args *args = data;
2408 DBusMessageIter iter;
2409
2410 /* At this point we got back all the secrets */
2411
2412 if (gkr_operation_handle_errors (op, reply))
2413 return;
2414
2415 /* Decode the unlocked secrets received */
2416 if (!dbus_message_iter_init (reply, &iter))
2417 g_return_if_reached ();
2418 if (!find_items_decode_secrets (&iter, args)) {
2419 gkr_operation_complete (op, decode_invalid_response (reply));
2420 return;
2421 }
2422
2423 /* Start retrieving attributes */
2424 find_items_6_reply (op, NULL, args);
2425 }
2426
2427 static void
find_items_4_reply(GkrOperation * op,GkrSession * session,gpointer data)2428 find_items_4_reply (GkrOperation *op, GkrSession *session, gpointer data)
2429 {
2430 find_items_args *args = data;
2431 DBusMessage *req;
2432 char **paths;
2433 int n_paths;
2434
2435 /* At this point we have a session, and can get secrets */
2436
2437 g_assert (!args->session);
2438 args->session = gkr_session_ref (session);
2439
2440 paths = (char**)args->paths->pdata;
2441 n_paths = args->paths->len;
2442
2443 /* Retrieve any unlocked secrets */
2444 req = prepare_get_secrets (session, paths, n_paths);
2445
2446 gkr_operation_push (op, find_items_5_reply, GKR_CALLBACK_OP_MSG, args, NULL);
2447 gkr_operation_request (op, req);
2448 dbus_message_unref (req);
2449 }
2450
2451 static void
find_items_3_reply(GkrOperation * op,DBusMessage * reply,gpointer data)2452 find_items_3_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
2453 {
2454 find_items_args *args = data;
2455 gboolean dismissed;
2456
2457 /* At this point Prompt has Completed, and should contain a list of unlocked items */
2458
2459 if (gkr_operation_handle_errors (op, reply))
2460 return;
2461
2462 if (!decode_xlock_completed (reply, &dismissed, find_items_queue, args)) {
2463 gkr_operation_complete (op, decode_invalid_response (reply));
2464 return;
2465 }
2466
2467 /* Well we're going to be transferring secrets, so need a session */
2468 gkr_operation_push (op, find_items_4_reply, GKR_CALLBACK_OP_SESSION, args, NULL);
2469 gkr_session_negotiate (op);
2470 }
2471
2472 static void
find_items_2_reply(GkrOperation * op,DBusMessage * reply,gpointer data)2473 find_items_2_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
2474 {
2475 find_items_args *args = data;
2476 const char *prompt;
2477 char **unlocked;
2478 int n_unlocked, i;
2479
2480 /* At this point Unlock has returned a list of unlocked items, plus prompt? */
2481
2482 if (gkr_operation_handle_errors (op, reply))
2483 return;
2484
2485 if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &unlocked, &n_unlocked,
2486 DBUS_TYPE_OBJECT_PATH, &prompt, DBUS_TYPE_INVALID)) {
2487 gkr_operation_complete (op, decode_invalid_response (reply));
2488 return;
2489 }
2490
2491 /* These are ready to retrieve */
2492 for (i = 0; i < n_unlocked; ++i)
2493 g_ptr_array_add (args->paths, g_strdup (unlocked[i]));
2494
2495 /* Do we have a prompt to display? */
2496 if (prompt && !g_str_equal (prompt, "/")) {
2497 gkr_operation_push (op, find_items_3_reply, GKR_CALLBACK_OP_MSG, args, NULL);
2498 gkr_operation_prompt (op, prompt);
2499
2500 /* Well we're going to be transferring secrets, so need a session */
2501 } else {
2502 gkr_operation_push (op, find_items_4_reply, GKR_CALLBACK_OP_SESSION, args, NULL);
2503 gkr_session_negotiate (op);
2504 }
2505
2506 dbus_free_string_array (unlocked);
2507 }
2508
2509 static void
find_items_1_reply(GkrOperation * op,DBusMessage * reply,gpointer data)2510 find_items_1_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
2511 {
2512 find_items_args *args = data;
2513 char **unlocked, **locked;
2514 int n_unlocked, n_locked, i;
2515 DBusMessage *req;
2516
2517 /* At this point SearchItems has returned two lists of locked/unlocked items */
2518
2519 if (gkr_operation_handle_errors (op, reply))
2520 return;
2521
2522 if (!dbus_message_get_args (reply, NULL,
2523 DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &unlocked, &n_unlocked,
2524 DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &locked, &n_locked,
2525 DBUS_TYPE_INVALID)) {
2526 gkr_operation_complete (op, decode_invalid_response (reply));
2527 return;
2528 }
2529
2530 /* Did we find anything? */
2531 if (!n_unlocked && !n_locked) {
2532 gkr_operation_complete (op, GNOME_KEYRING_RESULT_NO_MATCH);
2533 dbus_free_string_array (locked);
2534 dbus_free_string_array (unlocked);
2535 return;
2536 }
2537
2538 /* These are ready to retrieve */
2539 for (i = 0; i < n_unlocked; ++i)
2540 g_ptr_array_add (args->paths, g_strdup (unlocked[i]));
2541
2542 /* Do we have any to unlock? */
2543 if (n_locked) {
2544 req = prepare_xlock ("Unlock", locked, n_locked);
2545 gkr_operation_push (op, find_items_2_reply, GKR_CALLBACK_OP_MSG, args, NULL);
2546 gkr_operation_request (op, req);
2547
2548 /* Well we're going to be transferring secrets, so need a session */
2549 } else {
2550 gkr_operation_push (op, find_items_4_reply, GKR_CALLBACK_OP_SESSION, args, NULL);
2551 gkr_session_negotiate (op);
2552 }
2553
2554 dbus_free_string_array (locked);
2555 dbus_free_string_array (unlocked);
2556 }
2557
2558 static GkrOperation*
find_items_start(GnomeKeyringItemType type,GnomeKeyringAttributeList * attributes,GnomeKeyringOperationGetListCallback callback,gpointer data,GDestroyNotify destroy_data)2559 find_items_start (GnomeKeyringItemType type, GnomeKeyringAttributeList *attributes,
2560 GnomeKeyringOperationGetListCallback callback,
2561 gpointer data, GDestroyNotify destroy_data)
2562 {
2563 DBusMessageIter iter;
2564 find_items_args *args;
2565 DBusMessage *req;
2566 GkrOperation *op;
2567
2568 g_return_val_if_fail (attributes, NULL);
2569 g_return_val_if_fail (callback, NULL);
2570
2571 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
2572 SERVICE_INTERFACE, "SearchItems");
2573
2574 /* Encode the attribute list */
2575 dbus_message_iter_init_append (req, &iter);
2576 encode_attribute_list (&iter, attributes);
2577
2578 args = g_slice_new0 (find_items_args);
2579 args->paths = g_ptr_array_new ();
2580
2581 op = gkr_operation_new (callback, GKR_CALLBACK_RES_LIST, data, destroy_data);
2582 gkr_operation_push (op, find_items_1_reply, GKR_CALLBACK_OP_MSG, args, find_items_free);
2583 gkr_operation_request (op, req);
2584
2585 dbus_message_unref (req);
2586
2587 return op;
2588 }
2589
2590 /**
2591 * gnome_keyring_find_items: (skip)
2592 * @type: The type of items to find.
2593 * @attributes: A list of attributes to search for. This cannot be an empty list.
2594 * @callback: A callback which will be called when the request completes or fails.
2595 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
2596 * @callback.
2597 * @destroy_data: A function to free @data when it's no longer needed.
2598 *
2599 * Searches through all keyrings for items that match the @attributes. The matches
2600 * are for exact equality.
2601 *
2602 * A %GList of GnomeKeyringFound structures are passed to the @callback. The
2603 * list and structures are freed after the callback returns.
2604 *
2605 * The user may have been prompted to unlock necessary keyrings, and user will
2606 * have been prompted for access to the items if needed.
2607 *
2608 * For a synchronous version of this function see gnome_keyring_find_items_sync().
2609 *
2610 * Return value: (transfer none): The asynchronous request, which can be passed
2611 * to gnome_keyring_cancel_request().
2612 *
2613 * Deprecated: Use secret_password_lookup() or secret_service_search() instead.
2614 **/
2615 gpointer
gnome_keyring_find_items(GnomeKeyringItemType type,GnomeKeyringAttributeList * attributes,GnomeKeyringOperationGetListCallback callback,gpointer data,GDestroyNotify destroy_data)2616 gnome_keyring_find_items (GnomeKeyringItemType type,
2617 GnomeKeyringAttributeList *attributes,
2618 GnomeKeyringOperationGetListCallback callback,
2619 gpointer data,
2620 GDestroyNotify destroy_data)
2621 {
2622 GkrOperation *op;
2623
2624 gkr_init ();
2625
2626 op = find_items_start (type, attributes, callback, data, destroy_data);
2627 return gkr_operation_pending_and_unref (op);
2628 }
2629
2630 static GnomeKeyringAttributeList *
make_attribute_list_va(va_list args)2631 make_attribute_list_va (va_list args)
2632 {
2633 GnomeKeyringAttributeList *attributes;
2634 GnomeKeyringAttribute attribute;
2635 char *str;
2636 guint32 val;
2637
2638 attributes = g_array_new (FALSE, FALSE, sizeof (GnomeKeyringAttribute));
2639
2640 while ((attribute.name = va_arg (args, char *)) != NULL) {
2641 attribute.type = va_arg (args, GnomeKeyringAttributeType);
2642
2643 switch (attribute.type) {
2644 case GNOME_KEYRING_ATTRIBUTE_TYPE_STRING:
2645 str = va_arg (args, char *);
2646 attribute.value.string = str;
2647 g_array_append_val (attributes, attribute);
2648 break;
2649 case GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32:
2650 val = va_arg (args, guint32);
2651 attribute.value.integer = val;
2652 g_array_append_val (attributes, attribute);
2653 break;
2654 default:
2655 g_array_free (attributes, TRUE);
2656 return NULL;
2657 }
2658 }
2659 return attributes;
2660 }
2661
2662 /**
2663 * gnome_keyring_find_itemsv: (skip)
2664 * @type: The type of items to find.
2665 * @callback: A callback which will be called when the request completes or fails.
2666 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
2667 * @callback.
2668 * @destroy_data: A function to free @data when it's no longer needed.
2669 * @...: Attribute name, followed by the attribute type, and string or 32-bit unsigned int value. Terminated with %NULL.
2670 *
2671 * Searches through all keyrings for items that match the specified attributes.
2672 * The matches are for exact equality.
2673 *
2674 * The variable argument list should contain a) The attribute name as a null
2675 * terminated string, followed by b) The attribute type, either
2676 * %GNOME_KEYRING_ATTRIBUTE_TYPE_STRING or %GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32
2677 * and then the c) attribute value, either a character string, or 32-bit
2678 * unsigned int. The list should be terminated with a NULL.
2679 *
2680 * A %GList of GnomeKeyringFound structures are passed to the @callback. The
2681 * list and structures are freed after the callback returns.
2682 *
2683 * The user may have been prompted to unlock necessary keyrings, and user will
2684 * have been prompted for access to the items if needed.
2685 *
2686 * For a synchronous version of this function see gnome_keyring_find_itemsv_sync().
2687 *
2688 * Return value: (transfer none): The asynchronous request, which can be passed
2689 * to gnome_keyring_cancel_request().
2690 *
2691 * Deprecated: Use secret_password_lookup() or secret_service_search() instead.
2692 **/
2693 gpointer
gnome_keyring_find_itemsv(GnomeKeyringItemType type,GnomeKeyringOperationGetListCallback callback,gpointer data,GDestroyNotify destroy_data,...)2694 gnome_keyring_find_itemsv (GnomeKeyringItemType type,
2695 GnomeKeyringOperationGetListCallback callback,
2696 gpointer data,
2697 GDestroyNotify destroy_data,
2698 ...)
2699 {
2700 GnomeKeyringAttributeList *attributes;
2701 va_list args;
2702 gpointer ret;
2703
2704 gkr_init ();
2705
2706 va_start (args, destroy_data);
2707 attributes = make_attribute_list_va (args);
2708 va_end (args);
2709
2710 ret = gnome_keyring_find_items (type, attributes, callback, data, destroy_data);
2711 g_array_free (attributes, TRUE);
2712 return ret;
2713 }
2714
2715 /**
2716 * gnome_keyring_find_items_sync:
2717 * @type: The type of items to find.
2718 * @attributes: A list of attributes to search for. This cannot be an empty list.
2719 * @found: (out) (element-type GnomeKeyringFound): The location to return a
2720 * list of #GnomeKeyringFound pointers.
2721 *
2722 * Searches through all keyrings for items that match the @attributes and @type.
2723 * The matches are for exact equality.
2724 *
2725 * A %GList of GnomeKeyringFound structures is returned in @found. The list may
2726 * have zero items if nothing matched the criteria. The list should be freed
2727 * using gnome_keyring_found_list_free().
2728 *
2729 * The user may have been prompted to unlock necessary keyrings, and user will
2730 * have been prompted for access to the items if needed.
2731 *
2732 * For an asynchronous version of this function see gnome_keyring_find_items().
2733 *
2734 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
2735 * an error result otherwise.
2736 *
2737 * Deprecated: Use secret_password_lookup_sync() or secret_service_search_sync() instead.
2738 **/
2739 GnomeKeyringResult
gnome_keyring_find_items_sync(GnomeKeyringItemType type,GnomeKeyringAttributeList * attributes,GList ** found)2740 gnome_keyring_find_items_sync (GnomeKeyringItemType type,
2741 GnomeKeyringAttributeList *attributes,
2742 GList **found)
2743 {
2744 GkrOperation *op;
2745
2746 gkr_init ();
2747
2748 op = find_items_start (type, attributes, find_items_sync, found, NULL);
2749 return gkr_operation_block_and_unref (op);
2750 }
2751
2752 /**
2753 * gnome_keyring_find_itemsv_sync: (skip)
2754 * @type: The type of items to find.
2755 * @found: (out) (element-type GnomeKeyringFound): The location to return a
2756 * list of #GnomeKeyringFound pointers.
2757 * @...: Attribute name, followed by the attribute type, and string or 32-bit unsigned int value. Terminated with %NULL.
2758 *
2759 * Searches through all keyrings for items that match the @attributes and @type.
2760 * The matches are for exact equality.
2761 *
2762 * The variable argument list should contain a) The attribute name as a null
2763 * terminated string, followed by b) The attribute type, either
2764 * %GNOME_KEYRING_ATTRIBUTE_TYPE_STRING or %GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32
2765 * and then the c) attribute value, either a character string, or 32-bit
2766 * unsigned int. The list should be terminated with a %NULL.
2767 *
2768 * A %GList of GnomeKeyringFound structures is returned in @found. The list may
2769 * have zero items if nothing matched the criteria. The list should be freed
2770 * using gnome_keyring_found_list_free().
2771 *
2772 * The user may have been prompted to unlock necessary keyrings, and user will
2773 * have been prompted for access to the items if needed.
2774 *
2775 * For an asynchronous version of this function see gnome_keyring_find_items().
2776 *
2777 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
2778 * an error result otherwise.
2779 *
2780 * Deprecated: Use secret_password_lookup_sync() or secret_service_search_sync() instead.
2781 **/
2782 GnomeKeyringResult
gnome_keyring_find_itemsv_sync(GnomeKeyringItemType type,GList ** found,...)2783 gnome_keyring_find_itemsv_sync (GnomeKeyringItemType type,
2784 GList **found,
2785 ...)
2786 {
2787 GnomeKeyringAttributeList *attributes;
2788 va_list args;
2789 GnomeKeyringResult ret;
2790
2791 g_return_val_if_fail (found, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
2792
2793 gkr_init ();
2794
2795 va_start (args, found);
2796 attributes = make_attribute_list_va (args);
2797 va_end (args);
2798
2799 ret = gnome_keyring_find_items_sync (type, attributes, found);
2800 g_array_free (attributes, TRUE);
2801 return ret;
2802 }
2803
2804 /**
2805 * SECTION:gnome-keyring-items
2806 * @title: Keyring Items
2807 * @short_description: Keyring items each hold a secret and a number of attributes.
2808 *
2809 * <warning>All of these APIs are deprecated. Use
2810 * <ulink href="http://developer.gnome.org/libsecret/stable/">libsecret</ulink>
2811 * instead.</warning>
2812 *
2813 * A keyring contains multiple items. Each item has a secret, attributes and access
2814 * information associated with it.
2815 *
2816 * An item is identified by an unsigned integer unique to the keyring in which it
2817 * exists. An item's name is for displaying to the user. Each item has a single secret,
2818 * which is a null-terminated string. This secret is stored in non-pageable memory, and
2819 * encrypted on disk. All of this information is exposed via #GnomeKeyringItemInfo
2820 * pointers.
2821 *
2822 * Attributes allow various other pieces of information to be associated with an item.
2823 * These can also be used to search for relevant items. Attributes are accessed with
2824 * #GnomeKeyringAttribute structures and built into lists using #GnomeKeyringAttributeList.
2825 *
2826 * Attributes are not stored in a secret or encrypted manner by gnome-keyring. Do
2827 * not store sensitive information in attributes.
2828 **/
2829
2830 typedef struct _item_create_args {
2831 DBusMessage *request;
2832 DBusMessageIter iter;
2833 gboolean is_default;
2834 gboolean update_if_exists;
2835 gchar *secret;
2836 } item_create_args;
2837
2838 static void
item_create_free(gpointer data)2839 item_create_free (gpointer data)
2840 {
2841 item_create_args *args = data;
2842 dbus_message_unref (args->request);
2843 egg_secure_strfree (args->secret);
2844 g_slice_free (item_create_args, args);
2845 }
2846
2847 static void
item_create_sync(GnomeKeyringResult res,guint32 item_id,gpointer data)2848 item_create_sync (GnomeKeyringResult res, guint32 item_id, gpointer data)
2849 {
2850 guint32 *result = data;
2851 *result = item_id;
2852 }
2853
2854 static const gchar *
item_type_to_string(GnomeKeyringItemType item_type)2855 item_type_to_string (GnomeKeyringItemType item_type)
2856 {
2857 switch (item_type) {
2858 case GNOME_KEYRING_ITEM_GENERIC_SECRET:
2859 return "org.freedesktop.Secret.Generic";
2860 case GNOME_KEYRING_ITEM_NETWORK_PASSWORD:
2861 return "org.gnome.keyring.NetworkPassword";
2862 case GNOME_KEYRING_ITEM_NOTE:
2863 return "org.gnome.keyring.Note";
2864 case GNOME_KEYRING_ITEM_CHAINED_KEYRING_PASSWORD:
2865 return "org.gnome.keyring.ChainedKeyring";
2866 case GNOME_KEYRING_ITEM_ENCRYPTION_KEY_PASSWORD:
2867 return "org.gnome.keyring.EncryptionKey";
2868 case GNOME_KEYRING_ITEM_PK_STORAGE:
2869 return "org.gnome.keyring.PkStorage";
2870 default:
2871 return "org.freedesktop.Secret.Generic";
2872 }
2873 }
2874
2875 static DBusMessage*
item_create_prepare(const gchar * path,GnomeKeyringItemType type,const gchar * label,GnomeKeyringAttributeList * attrs,DBusMessageIter * iter)2876 item_create_prepare (const gchar *path, GnomeKeyringItemType type, const gchar *label,
2877 GnomeKeyringAttributeList *attrs, DBusMessageIter *iter)
2878 {
2879 DBusMessageIter array, variant, dict;
2880 DBusMessage *req;
2881 const char *string;
2882 const gchar *type_string;
2883
2884 req = dbus_message_new_method_call (gkr_service_name, path,
2885 COLLECTION_INTERFACE, "CreateItem");
2886
2887 dbus_message_iter_init_append (req, iter);
2888 dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{sv}", &array);
2889
2890 /* Set the label */
2891 string = ITEM_INTERFACE ".Label";
2892 dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
2893 dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &string);
2894 dbus_message_iter_open_container (&dict, DBUS_TYPE_VARIANT, "s", &variant);
2895 dbus_message_iter_append_basic (&variant, DBUS_TYPE_STRING, &label);
2896 dbus_message_iter_close_container (&dict, &variant);
2897 dbus_message_iter_close_container (&array, &dict);
2898
2899 /* Set the attributes */
2900 string = ITEM_INTERFACE ".Attributes";
2901 dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
2902 dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &string);
2903 dbus_message_iter_open_container (&dict, DBUS_TYPE_VARIANT, "a{ss}", &variant);
2904 encode_attribute_list (&variant, attrs);
2905 dbus_message_iter_close_container (&dict, &variant);
2906 dbus_message_iter_close_container (&array, &dict);
2907
2908 /* Set the item type */
2909 string = ITEM_INTERFACE ".Type";
2910 type_string = item_type_to_string (type);
2911 dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
2912 dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &string);
2913 dbus_message_iter_open_container (&dict, DBUS_TYPE_VARIANT, "s", &variant);
2914 dbus_message_iter_append_basic (&variant, DBUS_TYPE_STRING, &type_string);
2915 dbus_message_iter_close_container (&dict, &variant);
2916 dbus_message_iter_close_container (&array, &dict);
2917
2918 dbus_message_iter_close_container (iter, &array);
2919 return req;
2920 }
2921
2922 static void
item_create_3_created_reply(GkrOperation * op,DBusMessage * reply,gpointer data)2923 item_create_3_created_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
2924 {
2925 /* Called after trying to create item */
2926
2927 const char *path;
2928 const char *prompt;
2929 guint32 id;
2930
2931 if (gkr_operation_handle_errors (op, reply))
2932 return;
2933
2934 if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_OBJECT_PATH, &path,
2935 DBUS_TYPE_OBJECT_PATH, &prompt, DBUS_TYPE_INVALID)) {
2936 gkr_operation_complete (op, decode_invalid_response (reply));
2937 return;
2938 }
2939
2940 if (!gkr_decode_item_id (path, &id)) {
2941 gkr_debug ("couldn't decode item item path %s", path);
2942 gkr_operation_complete (op, GNOME_KEYRING_RESULT_IO_ERROR);
2943 return;
2944 }
2945
2946 gkr_debug ("new item id %u for path %s", (guint)id, path);
2947 gkr_callback_invoke_ok_uint (gkr_operation_pop (op), id);
2948 }
2949
2950 static void
item_create_2_session_reply(GkrOperation * op,GkrSession * session,gpointer data)2951 item_create_2_session_reply (GkrOperation *op, GkrSession *session, gpointer data)
2952 {
2953 /* Called after we have a session, start creating item */
2954
2955 item_create_args *args = data;
2956 dbus_bool_t replace;
2957
2958 gkr_debug ("have session, encoding secret");
2959
2960 if (!gkr_session_encode_secret (session, &args->iter, args->secret)) {
2961 gkr_operation_complete (op, BROKEN);
2962 g_return_if_reached ();
2963 }
2964
2965 replace = args->update_if_exists;
2966 dbus_message_iter_append_basic (&args->iter, DBUS_TYPE_BOOLEAN, &replace);
2967
2968 gkr_debug ("creating item");
2969
2970 gkr_operation_push (op, item_create_3_created_reply, GKR_CALLBACK_OP_MSG, NULL, NULL);
2971 gkr_operation_set_keyring_hint (op);
2972 gkr_operation_request (op, args->request);
2973 }
2974
2975 static void
item_create_2_session_request(GkrOperation * op,gpointer data)2976 item_create_2_session_request (GkrOperation *op, gpointer data)
2977 {
2978 /* Called to get us a valid session */
2979
2980 gkr_debug ("requesting session");
2981
2982 gkr_operation_push (op, item_create_2_session_reply, GKR_CALLBACK_OP_SESSION, data, NULL);
2983 gkr_session_negotiate (op);
2984 }
2985
2986 static void
item_create_1_create_prompt_reply(GkrOperation * op,DBusMessage * reply,gpointer data)2987 item_create_1_create_prompt_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
2988 {
2989 /* Called after prompting to create default collection for item */
2990
2991 DBusMessageIter iter, variant;
2992 const char *path;
2993 char *signature;
2994 gboolean equal;
2995
2996 if (gkr_operation_handle_errors (op, reply))
2997 return;
2998
2999 if (!dbus_message_has_signature (reply, "bv")) {
3000 gkr_operation_complete (op, decode_invalid_response (reply));
3001 return;
3002 }
3003
3004 /* Skip over dismissed, already parsed */
3005 if (!dbus_message_iter_init (reply, &iter) ||
3006 !dbus_message_iter_next (&iter))
3007 g_return_if_reached ();
3008
3009 /* Dig out the variant */
3010 dbus_message_iter_recurse (&iter, &variant);
3011
3012 signature = dbus_message_iter_get_signature (&variant);
3013 equal = g_str_equal (signature, "o");
3014 dbus_free (signature);
3015 if (!equal) {
3016 gkr_operation_complete (op, decode_invalid_response (reply));
3017 return;
3018 }
3019
3020 g_return_if_fail (dbus_message_iter_get_arg_type (&variant) == DBUS_TYPE_OBJECT_PATH);
3021 dbus_message_iter_get_basic (&variant, &path);
3022
3023 gkr_debug ("created default keyring: %s", path);
3024
3025 /* Start the session */
3026 item_create_2_session_request (op, data);
3027 }
3028
3029 static void
item_create_1_collection_reply(GkrOperation * op,DBusMessage * reply,gpointer data)3030 item_create_1_collection_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
3031 {
3032 /* Called after trying to create default collection to create item in */
3033
3034 const char *collection;
3035 const char *prompt;
3036
3037 if (gkr_operation_handle_errors (op, reply))
3038 return;
3039
3040 /* Parse the response */
3041 if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_OBJECT_PATH, &collection,
3042 DBUS_TYPE_OBJECT_PATH, &prompt, DBUS_TYPE_INVALID)) {
3043 g_warning ("bad response to CreateCollection from service");
3044 gkr_callback_invoke_res (gkr_operation_pop (op), GNOME_KEYRING_RESULT_IO_ERROR);
3045 return;
3046 }
3047
3048 /* No prompt, set keyring as default */
3049 g_return_if_fail (prompt);
3050 if (g_str_equal (prompt, "/")) {
3051 gkr_debug ("created default keyring: %s", collection);
3052 item_create_2_session_request (op, data);
3053
3054 /* A prompt, display it get the response */
3055 } else {
3056 gkr_debug ("prompting to create default keyring: %s", prompt);
3057 gkr_operation_push (op, item_create_1_create_prompt_reply, GKR_CALLBACK_OP_MSG, data, NULL);
3058 gkr_operation_prompt (op, prompt);
3059 }
3060 }
3061
3062 static gboolean
item_create_check_unlock(const char * path,gpointer user_data)3063 item_create_check_unlock (const char *path, gpointer user_data)
3064 {
3065 gboolean *unlocked = user_data;
3066 *unlocked = TRUE;
3067 return FALSE;
3068 }
3069
3070 static void
item_create_1_unlock_prompt_reply(GkrOperation * op,DBusMessage * reply,gpointer data)3071 item_create_1_unlock_prompt_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
3072 {
3073 /* Called after unlocking the collection we're going to create item in */
3074 gboolean dismissed = FALSE;
3075 gboolean unlocked = FALSE;
3076
3077 if (!decode_xlock_completed (reply, &dismissed, item_create_check_unlock, &unlocked)) {
3078 gkr_operation_complete (op, decode_invalid_response (reply));
3079 return;
3080 }
3081
3082 if (dismissed || !unlocked) {
3083 gkr_debug ("unlock prompt dismissed or not unlocked");
3084 gkr_operation_complete (op, GNOME_KEYRING_RESULT_DENIED);
3085 return;
3086 }
3087
3088 gkr_debug ("keyring unlocked");
3089
3090 /* Now that its unlocked, we need a session to transfer the secret */
3091 item_create_2_session_request (op, data);
3092 }
3093
3094 static void
item_create_1_unlock_reply(GkrOperation * op,DBusMessage * reply,gpointer data)3095 item_create_1_unlock_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
3096 {
3097 /* Called after trying to unlock keyring we're going to create item in */
3098
3099 item_create_args *args = data;
3100 DBusMessageIter iter;
3101 DBusMessage *req;
3102 gboolean unlocked = FALSE;
3103 const char *prompt;
3104 const char *alias = "default";
3105
3106 if (gkr_operation_handle_errors (op, reply))
3107 return;
3108
3109 if (!decode_xlock_reply (reply, &prompt, item_create_check_unlock, &unlocked)) {
3110 gkr_operation_complete (op, decode_invalid_response (reply));
3111 return;
3112 }
3113
3114 /* Prompt to unlock the collection */
3115 if (!g_str_equal (prompt, "/")) {
3116 gkr_debug ("prompting to unlock the keyring: %s", prompt);
3117 gkr_operation_push (op, item_create_1_unlock_prompt_reply, GKR_CALLBACK_OP_MSG, args, NULL);
3118 gkr_operation_prompt (op, prompt);
3119
3120 /* No such keyring, no prompt, and not unlocked */
3121 } else if (!unlocked) {
3122
3123 /* Caller asked for default keyring, and there is no such keyring. Create */
3124 if (args->is_default) {
3125 gkr_debug ("no such default keyring, creating");
3126 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
3127 SERVICE_INTERFACE, "CreateCollection");
3128 dbus_message_iter_init_append (req, &iter);
3129 /* TRANSLATORS: This is the name of an automatically created default keyring. */
3130 create_keyring_encode_properties (&iter, _("Default"));
3131 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &alias);
3132 gkr_operation_push (op, item_create_1_collection_reply, GKR_CALLBACK_OP_MSG, args, NULL);
3133 gkr_operation_request (op, req);
3134 dbus_message_unref (req);
3135
3136 /* No such keyring, error */
3137 } else {
3138 gkr_debug ("no such keyring");
3139 gkr_operation_complete (op, GNOME_KEYRING_RESULT_NO_SUCH_KEYRING);
3140 }
3141
3142 /* Successfully unlocked, or not locked. We need a session to transfer the secret */
3143 } else {
3144 gkr_debug ("unlocked keyring");
3145 item_create_2_session_request (op, args);
3146 }
3147 }
3148
3149 static GkrOperation*
item_create_start(const char * keyring,GnomeKeyringItemType type,const char * display_name,GnomeKeyringAttributeList * attributes,const char * secret,gboolean update_if_exists,GnomeKeyringOperationGetIntCallback callback,gpointer data,GDestroyNotify destroy_data)3150 item_create_start (const char *keyring, GnomeKeyringItemType type, const char *display_name,
3151 GnomeKeyringAttributeList *attributes, const char *secret,
3152 gboolean update_if_exists, GnomeKeyringOperationGetIntCallback callback,
3153 gpointer data, GDestroyNotify destroy_data)
3154 {
3155 item_create_args *args;
3156 DBusMessage *req;
3157 GkrOperation *op;
3158 gchar *path;
3159
3160 if (!display_name) {
3161 gkr_debug ("creating item with blank label");
3162 display_name = "";
3163 }
3164
3165 args = g_slice_new0 (item_create_args);
3166 args->update_if_exists = update_if_exists;
3167 args->secret = egg_secure_strdup (secret);
3168 args->is_default = (keyring == NULL);
3169
3170 path = gkr_encode_keyring_name (keyring);
3171 args->request = item_create_prepare (path, type, display_name, attributes, &args->iter);
3172 g_return_val_if_fail (args->request, NULL);
3173
3174 /* First unlock the keyring */
3175 gkr_debug ("unlocking the keyring: %s", path);
3176 req = prepare_xlock ("Unlock", &path, 1);
3177 g_free (path);
3178
3179 op = gkr_operation_new (callback, GKR_CALLBACK_RES_UINT, data, destroy_data);
3180 gkr_operation_push (op, item_create_1_unlock_reply, GKR_CALLBACK_OP_MSG, args, item_create_free);
3181 gkr_operation_set_keyring_hint (op);
3182 gkr_operation_request (op, req);
3183 dbus_message_unref (req);
3184
3185 return op;
3186 }
3187
3188 /**
3189 * gnome_keyring_item_create: (skip)
3190 * @keyring: (allow-none): The name of the keyring in which to create the item,
3191 * or %NULL for the default keyring.
3192 * @type: The item type.
3193 * @display_name: The name of the item. This will be displayed to the user where necessary.
3194 * @attributes: A (possibly empty) list of attributes to store with the item.
3195 * @secret: The password or secret of the item.
3196 * @update_if_exists: If true, then another item matching the type, and attributes
3197 * will be updated instead of creating a new item.
3198 * @callback: A callback which will be called when the request completes or fails.
3199 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
3200 * @callback.
3201 * @destroy_data: A function to free @data when it's no longer needed.
3202 *
3203 * Create a new item in a keyring.
3204 *
3205 * The @secret must be a null terminated string. It should be allocated using secure
3206 * memory whenever possible. See gnome_keyring_memory_strdup()
3207 *
3208 * The user may have been prompted to unlock necessary keyrings. If %NULL is
3209 * specified as the @keyring and no default keyring exists, the user will be
3210 * prompted to create a new keyring.
3211 *
3212 * When @update_if_exists is set to %TRUE, the user may be prompted for access
3213 * to the previously existing item.
3214 *
3215 * Whether a new item is created or not, id of the item will be passed to
3216 * the @callback.
3217 *
3218 * For a synchronous version of this function see gnome_keyring_item_create_sync().
3219 *
3220 * Return value: (transfer none): The asynchronous request, which can be passed
3221 * to gnome_keyring_cancel_request().
3222 *
3223 * Deprecated: Use secret_password_store() or secret_item_create() instead.
3224 **/
3225 gpointer
gnome_keyring_item_create(const char * keyring,GnomeKeyringItemType type,const char * display_name,GnomeKeyringAttributeList * attributes,const char * secret,gboolean update_if_exists,GnomeKeyringOperationGetIntCallback callback,gpointer data,GDestroyNotify destroy_data)3226 gnome_keyring_item_create (const char *keyring,
3227 GnomeKeyringItemType type,
3228 const char *display_name,
3229 GnomeKeyringAttributeList *attributes,
3230 const char *secret,
3231 gboolean update_if_exists,
3232 GnomeKeyringOperationGetIntCallback callback,
3233 gpointer data,
3234 GDestroyNotify destroy_data)
3235 {
3236 GkrOperation *op;
3237
3238 gkr_init ();
3239
3240 op = item_create_start (keyring, type, display_name, attributes, secret,
3241 update_if_exists, callback, data, destroy_data);
3242 return gkr_operation_pending_and_unref (op);
3243 }
3244
3245 /**
3246 * gnome_keyring_item_create_sync:
3247 * @keyring: (allow-none): The name of the keyring in which to create the item,
3248 * or %NULL for the default keyring.
3249 * @type: The item type.
3250 * @display_name: The name of the item. This will be displayed to the user where necessary.
3251 * @attributes: A (possibly empty) list of attributes to store with the item.
3252 * @secret: The password or secret of the item.
3253 * @update_if_exists: If true, then another item matching the type, and attributes
3254 * will be updated instead of creating a new item.
3255 * @item_id: (out): return location for the id of the created/updated keyring item.
3256 *
3257 * Create a new item in a keyring.
3258 *
3259 * The @secret must be a null terminated string. It should be allocated using secure
3260 * memory whenever possible. See gnome_keyring_memory_strdup()
3261 *
3262 * The user may have been prompted to unlock necessary keyrings. If %NULL is
3263 * specified as the @keyring and no default keyring exists, the user will be
3264 * prompted to create a new keyring.
3265 *
3266 * When @update_if_exists is set to %TRUE, the user may be prompted for access
3267 * to the previously existing item.
3268 *
3269 * For an asynchronous version of this function see gnome_keyring_item_create().
3270 *
3271 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
3272 * an error result otherwise.
3273 *
3274 * Deprecated: Use secret_password_store_sync() or secret_item_create_sync() instead.
3275 */
3276 GnomeKeyringResult
gnome_keyring_item_create_sync(const char * keyring,GnomeKeyringItemType type,const char * display_name,GnomeKeyringAttributeList * attributes,const char * secret,gboolean update_if_exists,guint32 * item_id)3277 gnome_keyring_item_create_sync (const char *keyring,
3278 GnomeKeyringItemType type,
3279 const char *display_name,
3280 GnomeKeyringAttributeList *attributes,
3281 const char *secret,
3282 gboolean update_if_exists,
3283 guint32 *item_id)
3284 {
3285 GkrOperation *op;
3286
3287 gkr_init ();
3288
3289 op = item_create_start (keyring, type, display_name, attributes, secret,
3290 update_if_exists, item_create_sync, item_id, NULL);
3291 return gkr_operation_block_and_unref (op);
3292 }
3293
3294 static GkrOperation*
item_delete_start(const char * keyring,guint32 id,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)3295 item_delete_start (const char *keyring, guint32 id, GnomeKeyringOperationDoneCallback callback,
3296 gpointer data, GDestroyNotify destroy_data)
3297 {
3298 DBusMessage *req;
3299 GkrOperation *op;
3300 gchar *path;
3301
3302 path = gkr_encode_keyring_item_id (keyring, id);
3303 req = dbus_message_new_method_call (gkr_service_name, path,
3304 ITEM_INTERFACE, "Delete");
3305
3306 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
3307 gkr_operation_request (op, req);
3308 dbus_message_unref (req);
3309
3310 return op;
3311 }
3312
3313 /**
3314 * gnome_keyring_item_delete: (skip)
3315 * @keyring: (allow-none): The name of the keyring from which to delete the
3316 * item, or %NULL for the default keyring.
3317 * @id: The id of the item
3318 * @callback: A callback which will be called when the request completes or fails.
3319 * @data: (allow-none): A pointer to arbitrary data that will be passed to the @callback.
3320 * @destroy_data: A function to free @data when it's no longer needed.
3321 *
3322 * Delete an item in a keyring.
3323 *
3324 * The user may be prompted if the calling application doesn't have necessary
3325 * access to delete the item.
3326 *
3327 * For an asynchronous version of this function see gnome_keyring_delete().
3328 *
3329 * Return value: (transfer none): The asynchronous request, which can be passed
3330 * to gnome_keyring_cancel_request().
3331 *
3332 * Deprecated: Use secret_password_clear() or secret_item_delete() instead.
3333 **/
3334 gpointer
gnome_keyring_item_delete(const char * keyring,guint32 id,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)3335 gnome_keyring_item_delete (const char *keyring,
3336 guint32 id,
3337 GnomeKeyringOperationDoneCallback callback,
3338 gpointer data,
3339 GDestroyNotify destroy_data)
3340 {
3341 GkrOperation *op;
3342
3343 gkr_init ();
3344
3345 op = item_delete_start (keyring, id, callback, data, destroy_data);
3346 return gkr_operation_pending_and_unref (op);
3347 }
3348
3349 /**
3350 * gnome_keyring_item_delete_sync:
3351 * @keyring: (allow-none): The name of the keyring from which to delete the
3352 * item, or %NULL for the default keyring.
3353 * @id: The id of the item
3354 *
3355 * Delete an item in a keyring.
3356 *
3357 * The user may be prompted if the calling application doesn't have necessary
3358 * access to delete the item.
3359 *
3360 * For an asynchronous version of this function see gnome_keyring_item_delete().
3361 *
3362 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
3363 * an error result otherwise.
3364 *
3365 * Deprecated: Use secret_password_clear_sync() or secret_item_delete_sync() instead.
3366 **/
3367 GnomeKeyringResult
gnome_keyring_item_delete_sync(const char * keyring,guint32 id)3368 gnome_keyring_item_delete_sync (const char *keyring,
3369 guint32 id)
3370 {
3371 GkrOperation *op;
3372
3373 gkr_init ();
3374
3375 op = item_delete_start (keyring, id, gkr_callback_empty, NULL, NULL);
3376 return gkr_operation_block_and_unref (op);
3377 }
3378
3379 /**
3380 * gnome_keyring_item_get_info: (skip)
3381 * @keyring: (allow-none): The name of the keyring in which the item exists, or
3382 * %NULL for the default keyring.
3383 * @id: The id of the item
3384 * @callback: A callback which will be called when the request completes or fails.
3385 * @data: (allow-none): A pointer to arbitrary data that will be passed to the @callback.
3386 * @destroy_data: A function to free @data when it's no longer needed.
3387 *
3388 * Get information about an item and its secret.
3389 *
3390 * The user may be prompted if the calling application doesn't have necessary
3391 * access to read the item with its secret.
3392 *
3393 * A #GnomeKeyringItemInfo structure will be passed to the @callback. This structure
3394 * will be freed after @callback returns.
3395 *
3396 * For a synchronous version of this function see gnome_keyring_item_get_info_sync().
3397 *
3398 * Return value: (transfer none): The asynchronous request, which can be passed
3399 * to gnome_keyring_cancel_request().
3400 *
3401 * Deprecated: Use #SecretItem objects instead.
3402 **/
3403 gpointer
gnome_keyring_item_get_info(const char * keyring,guint32 id,GnomeKeyringOperationGetItemInfoCallback callback,gpointer data,GDestroyNotify destroy_data)3404 gnome_keyring_item_get_info (const char *keyring,
3405 guint32 id,
3406 GnomeKeyringOperationGetItemInfoCallback callback,
3407 gpointer data,
3408 GDestroyNotify destroy_data)
3409 {
3410 gkr_init ();
3411
3412 return gnome_keyring_item_get_info_full (keyring, id, GNOME_KEYRING_ITEM_INFO_ALL,
3413 callback, data, destroy_data);
3414 }
3415
3416 /**
3417 * gnome_keyring_item_get_info_sync:
3418 * @keyring: (allow-none): The name of the keyring in which the item exists, or
3419 * %NULL for the default keyring.
3420 * @id: The id of the item
3421 * @info: (out): The location to return a #GnomeKeyringItemInfo pointer.
3422 *
3423 * Get information about an item and its secret.
3424 *
3425 * The user may be prompted if the calling application doesn't have necessary
3426 * access to read the item with its secret.
3427 *
3428 * A #GnomeKeyringItemInfo structure will be returned in @info. This must be
3429 * freed using gnome_keyring_item_info_free().
3430 *
3431 * For an asynchronous version of this function see gnome_keyring_item_get_info().
3432 *
3433 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
3434 * an error result otherwise.
3435 *
3436 * Deprecated: Use #SecretItem objects instead.
3437 **/
3438 GnomeKeyringResult
gnome_keyring_item_get_info_sync(const char * keyring,guint32 id,GnomeKeyringItemInfo ** info)3439 gnome_keyring_item_get_info_sync (const char *keyring,
3440 guint32 id,
3441 GnomeKeyringItemInfo **info)
3442 {
3443 gkr_init ();
3444
3445 return gnome_keyring_item_get_info_full_sync (keyring, id, GNOME_KEYRING_ITEM_INFO_ALL, info);
3446 }
3447
3448 static gboolean
item_get_info_foreach(const gchar * property,DBusMessageIter * iter,gpointer user_data)3449 item_get_info_foreach (const gchar *property, DBusMessageIter *iter, gpointer user_data)
3450 {
3451 GnomeKeyringItemInfo *info = user_data;
3452 const char *sval;
3453
3454 if (g_str_equal (property, "Label")) {
3455 if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_STRING)
3456 return FALSE;
3457 dbus_message_iter_get_basic (iter, &sval);
3458 info->display_name = g_strdup (sval);
3459
3460 } else if (g_str_equal (property, "Created")) {
3461 if (!decode_time_from_iter (iter, &info->ctime)) {
3462 gkr_debug ("invalid Created property type: %s",
3463 dbus_message_iter_get_signature (iter));
3464 return FALSE;
3465 }
3466 } else if (g_str_equal (property, "Modified")) {
3467 if (!decode_time_from_iter (iter, &info->mtime)) {
3468 gkr_debug ("invalid Modified property type: %s",
3469 dbus_message_iter_get_signature (iter));
3470 return FALSE;
3471 }
3472 } else if (g_str_equal (property, "Type")) {
3473 if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_STRING)
3474 return FALSE;
3475 dbus_message_iter_get_basic (iter, &sval);
3476 g_return_val_if_fail (sval, FALSE);
3477 if (g_str_equal (sval, "org.freedesktop.Secret.Generic"))
3478 info->type = GNOME_KEYRING_ITEM_GENERIC_SECRET;
3479 else if (g_str_equal (sval, "org.gnome.keyring.NetworkPassword"))
3480 info->type = GNOME_KEYRING_ITEM_NETWORK_PASSWORD;
3481 else if (g_str_equal (sval, "org.gnome.keyring.Note"))
3482 info->type = GNOME_KEYRING_ITEM_NOTE;
3483 else if (g_str_equal (sval, "org.gnome.keyring.ChainedKeyring"))
3484 info->type = GNOME_KEYRING_ITEM_CHAINED_KEYRING_PASSWORD;
3485 else if (g_str_equal (sval, "org.gnome.keyring.EncryptionKey"))
3486 info->type = GNOME_KEYRING_ITEM_ENCRYPTION_KEY_PASSWORD;
3487 else if (g_str_equal (sval, "org.gnome.keyring.PkStorage"))
3488 info->type = GNOME_KEYRING_ITEM_PK_STORAGE;
3489 else
3490 info->type = GNOME_KEYRING_ITEM_GENERIC_SECRET;
3491 }
3492
3493 return TRUE;
3494 }
3495
3496 typedef struct _item_get_info_args {
3497 gchar *path;
3498 guint32 flags;
3499 GkrSession *session;
3500 GnomeKeyringItemInfo *info;
3501 } item_get_info_args;
3502
3503 static void
item_get_info_free(gpointer data)3504 item_get_info_free (gpointer data)
3505 {
3506 item_get_info_args *args = data;
3507 g_assert (data);
3508 g_free (args->path);
3509 if (args->session)
3510 gkr_session_unref (args->session);
3511 gnome_keyring_item_info_free (args->info);
3512 g_slice_free (item_get_info_args, args);
3513 }
3514
3515 static void
item_get_info_sync(GnomeKeyringResult res,GnomeKeyringItemInfo * info,gpointer user_data)3516 item_get_info_sync (GnomeKeyringResult res, GnomeKeyringItemInfo *info, gpointer user_data)
3517 {
3518 GnomeKeyringItemInfo **result = user_data;
3519 *result = info;
3520 }
3521
3522 static void
item_get_info_3_reply(GkrOperation * op,DBusMessage * reply,gpointer data)3523 item_get_info_3_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
3524 {
3525 item_get_info_args *args = data;
3526 DBusMessageIter iter;
3527 GkrCallback *cb;
3528
3529 if (gkr_operation_handle_errors (op, reply))
3530 return;
3531
3532 if (!dbus_message_iter_init (reply, &iter))
3533 g_return_if_reached ();
3534
3535 g_assert (args->info);
3536 g_assert (args->session);
3537 g_assert (!args->info->secret);
3538
3539 if (gkr_session_decode_secret (args->session, &iter, &args->info->secret)) {
3540 cb = gkr_operation_pop (op);
3541 gkr_callback_invoke_ok_item_info (cb, args->info);
3542 if (cb->callback == item_get_info_sync)
3543 args->info = NULL;
3544 } else {
3545 gkr_operation_complete (op, GNOME_KEYRING_RESULT_IO_ERROR);
3546 }
3547 }
3548
3549 static void
item_get_info_2_reply(GkrOperation * op,GkrSession * session,gpointer data)3550 item_get_info_2_reply (GkrOperation *op, GkrSession *session, gpointer data)
3551 {
3552 item_get_info_args *args = data;
3553 const char *path;
3554 DBusMessage *req;
3555
3556 g_assert (!args->session);
3557 args->session = gkr_session_ref (session);
3558
3559 req = dbus_message_new_method_call (gkr_service_name, args->path, ITEM_INTERFACE, "GetSecret");
3560 path = gkr_session_get_path (session);
3561 dbus_message_append_args (req, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
3562
3563 gkr_operation_push (op, item_get_info_3_reply, GKR_CALLBACK_OP_MSG, args, NULL);
3564 gkr_operation_request (op, req);
3565 dbus_message_unref (req);
3566 }
3567
3568 static void
item_get_info_1_reply(GkrOperation * op,DBusMessage * reply,gpointer data)3569 item_get_info_1_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
3570 {
3571 item_get_info_args *args = data;
3572 GnomeKeyringResult res;
3573 GkrCallback *cb;
3574
3575 if (gkr_operation_handle_errors (op, reply))
3576 return;
3577
3578 g_assert (args->info);
3579 res = decode_property_dict (reply, item_get_info_foreach, args->info);
3580 if (res != GNOME_KEYRING_RESULT_OK) {
3581 gkr_operation_complete (op, res);
3582 return;
3583 }
3584
3585 /* Need to request the secret as well? */
3586 if (args->flags & GNOME_KEYRING_ITEM_INFO_SECRET) {
3587 gkr_operation_push (op, item_get_info_2_reply, GKR_CALLBACK_OP_SESSION, args, NULL);
3588 gkr_session_negotiate (op);
3589
3590 /* No secret needed, all done */
3591 } else {
3592 cb = gkr_operation_pop (op);
3593 gkr_callback_invoke_ok_item_info (cb, args->info);
3594 if (cb->callback == item_get_info_sync)
3595 args->info = NULL;
3596 }
3597 }
3598
3599 static GkrOperation*
item_get_info_start(const char * keyring,guint32 id,guint32 flags,GnomeKeyringOperationGetItemInfoCallback callback,gpointer data,GDestroyNotify destroy_data)3600 item_get_info_start (const char *keyring, guint32 id, guint32 flags,
3601 GnomeKeyringOperationGetItemInfoCallback callback,
3602 gpointer data, GDestroyNotify destroy_data)
3603 {
3604 item_get_info_args *args;
3605 DBusMessage *req;
3606 GkrOperation *op;
3607
3608 args = g_slice_new0 (item_get_info_args);
3609 args->info = g_new0 (GnomeKeyringItemInfo, 1);
3610 args->flags = flags;
3611
3612 args->path = gkr_encode_keyring_item_id (keyring, id);
3613 req = prepare_property_getall (args->path, ITEM_INTERFACE);
3614
3615 op = gkr_operation_new (callback, GKR_CALLBACK_RES_ITEM_INFO, data, destroy_data);
3616 gkr_operation_push (op, item_get_info_1_reply, GKR_CALLBACK_OP_MSG, args, item_get_info_free);
3617 gkr_operation_request (op, req);
3618
3619 dbus_message_unref (req);
3620 return op;
3621 }
3622
3623 /**
3624 * gnome_keyring_item_get_info_full: (skip)
3625 * @keyring: (allow-none): The name of the keyring in which the item exists, or
3626 * %NULL for the default keyring.
3627 * @id: The id of the item
3628 * @flags: The parts of the item to retrieve.
3629 * @callback: A callback which will be called when the request completes or fails.
3630 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
3631 * @callback.
3632 * @destroy_data: A function to free @data when it's no longer needed.
3633 *
3634 * Get information about an item, optionally retrieving its secret.
3635 *
3636 * If @flags includes %GNOME_KEYRING_ITEM_INFO_SECRET then the user may be
3637 * prompted if the calling application doesn't have necessary access to read
3638 * the item with its secret.
3639 *
3640 * A #GnomeKeyringItemInfo pointer will be passed to the @callback. Certain fields
3641 * of this structure may be %NULL or zero if they were not specified in @flags. This
3642 * structure will be freed after @callback returns.
3643 *
3644 * For a synchronous version of this function see gnome_keyring_item_get_info_full_sync().
3645 *
3646 * Return value: (transfer none): The asynchronous request, which can be passed
3647 * to gnome_keyring_cancel_request().
3648 *
3649 * Deprecated: Use #SecretItem objects instead.
3650 **/
3651 gpointer
gnome_keyring_item_get_info_full(const char * keyring,guint32 id,guint32 flags,GnomeKeyringOperationGetItemInfoCallback callback,gpointer data,GDestroyNotify destroy_data)3652 gnome_keyring_item_get_info_full (const char *keyring,
3653 guint32 id,
3654 guint32 flags,
3655 GnomeKeyringOperationGetItemInfoCallback callback,
3656 gpointer data,
3657 GDestroyNotify destroy_data)
3658 {
3659 GkrOperation *op;
3660
3661 gkr_init ();
3662
3663 op = item_get_info_start (keyring, id, flags, callback, data, destroy_data);
3664 return gkr_operation_pending_and_unref (op);
3665 }
3666
3667 /**
3668 * gnome_keyring_item_get_info_full_sync:
3669 * @keyring: (allow-none): The name of the keyring in which the item exists, or
3670 * %NULL for the default keyring.
3671 * @id: The id of the item
3672 * @flags: The parts of the item to retrieve.
3673 * @info: (out): The location to return a #GnomeKeyringItemInfo pointer.
3674 *
3675 * Get information about an item, optionally retrieving its secret.
3676 *
3677 * If @flags includes %GNOME_KEYRING_ITEM_INFO_SECRET then the user may be
3678 * prompted if the calling application doesn't have necessary access to read
3679 * the item with its secret.
3680 *
3681 * A #GnomeKeyringItemInfo structure will be returned in @info. Certain fields
3682 * of this structure may be %NULL or zero if they were not specified in @flags.
3683 * This must be freed using gnome_keyring_item_info_free().
3684 *
3685 * For an asynchronous version of this function see gnome_keyring_item_get_info_full().
3686 *
3687 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
3688 * an error result otherwise.
3689 *
3690 * Deprecated: Use #SecretItem objects instead.
3691 **/
3692 GnomeKeyringResult
gnome_keyring_item_get_info_full_sync(const char * keyring,guint32 id,guint32 flags,GnomeKeyringItemInfo ** info)3693 gnome_keyring_item_get_info_full_sync (const char *keyring,
3694 guint32 id,
3695 guint32 flags,
3696 GnomeKeyringItemInfo **info)
3697 {
3698 GkrOperation *op;
3699
3700 gkr_init ();
3701
3702 op = item_get_info_start (keyring, id, flags, item_get_info_sync, info, NULL);
3703 return gkr_operation_block_and_unref (op);
3704 }
3705
3706 typedef struct _item_set_info_args {
3707 gchar *path;
3708 GkrSession *session;
3709 GnomeKeyringItemInfo *info;
3710 } item_set_info_args;
3711
3712 static void
item_set_info_free(gpointer data)3713 item_set_info_free (gpointer data)
3714 {
3715 item_set_info_args *args = data;
3716 g_assert (data);
3717 g_free (args->path);
3718 if (args->session)
3719 gkr_session_unref (args->session);
3720 gnome_keyring_item_info_free (args->info);
3721 g_slice_free (item_set_info_args, args);
3722 }
3723
3724 static void
item_set_info_3_reply(GkrOperation * op,GkrSession * session,gpointer user_data)3725 item_set_info_3_reply (GkrOperation *op, GkrSession *session, gpointer user_data)
3726 {
3727 item_set_info_args *args = user_data;
3728 DBusMessageIter iter;
3729 DBusMessage *req;
3730
3731 g_assert (args);
3732 g_assert (args->info);
3733 g_assert (args->info->secret);
3734
3735 /* Sending a secret */
3736 req = dbus_message_new_method_call (gkr_service_name, args->path,
3737 ITEM_INTERFACE, "SetSecret");
3738
3739 dbus_message_iter_init_append (req, &iter);
3740 if (!gkr_session_encode_secret (session, &iter, args->info->secret)) {
3741 dbus_message_unref (req);
3742 gkr_operation_complete (op, GNOME_KEYRING_RESULT_IO_ERROR);
3743 return;
3744 }
3745
3746 /* Calls the final result handler directly */
3747 gkr_operation_request (op, req);
3748 dbus_message_unref (req);
3749 }
3750
3751 static void
item_set_info_2_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)3752 item_set_info_2_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
3753 {
3754 item_set_info_args *args = user_data;
3755
3756 if (gkr_operation_handle_errors (op, reply))
3757 return;
3758
3759 /* Need a session to send a secret */
3760 if (args->info->secret) {
3761 gkr_operation_push (op, item_set_info_3_reply, GKR_CALLBACK_OP_SESSION, args, NULL);
3762 gkr_session_negotiate (op);
3763
3764 /* No secret? all done */
3765 } else {
3766 gkr_operation_complete (op, GNOME_KEYRING_RESULT_OK);
3767 }
3768 }
3769
3770 static void
item_set_info_1_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)3771 item_set_info_1_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
3772 {
3773 item_set_info_args *args = user_data;
3774 DBusMessageIter iter, variant;
3775 DBusMessage *req;
3776 const char *string;
3777
3778 if (gkr_operation_handle_errors (op, reply))
3779 return;
3780
3781 /* Next set the type */
3782 req = dbus_message_new_method_call (gkr_service_name, args->path,
3783 DBUS_INTERFACE_PROPERTIES, "Set");
3784
3785 dbus_message_iter_init_append (req, &iter);
3786 string = ITEM_INTERFACE;
3787 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &string);
3788 string = "Type";
3789 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &string);
3790 dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "s", &variant);
3791
3792 string = item_type_to_string (args->info->type);
3793 dbus_message_iter_append_basic (&variant, DBUS_TYPE_STRING, &string);
3794 dbus_message_iter_close_container (&iter, &variant);
3795
3796 gkr_operation_push (op, item_set_info_2_reply, GKR_CALLBACK_OP_MSG, args, NULL);
3797 gkr_operation_request (op, req);
3798 }
3799
3800 static GkrOperation*
item_set_info_start(const char * keyring,guint32 id,GnomeKeyringItemInfo * info,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)3801 item_set_info_start (const char *keyring, guint32 id, GnomeKeyringItemInfo *info,
3802 GnomeKeyringOperationDoneCallback callback,
3803 gpointer data, GDestroyNotify destroy_data)
3804 {
3805 item_set_info_args *args;
3806 DBusMessageIter iter, variant;
3807 DBusMessage *req;
3808 GkrOperation *op;
3809 const char *string;
3810
3811 args = g_slice_new0 (item_set_info_args);
3812 args->info = gnome_keyring_item_info_copy (info);
3813 args->path = gkr_encode_keyring_item_id (keyring, id);
3814
3815 /* First set the label */
3816 req = dbus_message_new_method_call (gkr_service_name, args->path,
3817 DBUS_INTERFACE_PROPERTIES, "Set");
3818
3819 dbus_message_iter_init_append (req, &iter);
3820 string = ITEM_INTERFACE;
3821 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &string);
3822 string = "Label";
3823 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &string);
3824 dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "s", &variant);
3825 string = args->info->display_name ? args->info->display_name : "";
3826 dbus_message_iter_append_basic (&variant, DBUS_TYPE_STRING, &string);
3827 dbus_message_iter_close_container (&iter, &variant);
3828
3829 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
3830 gkr_operation_push (op, item_set_info_1_reply, GKR_CALLBACK_OP_MSG, args, item_set_info_free);
3831 gkr_operation_request (op, req);
3832 dbus_message_unref (req);
3833
3834 return op;
3835 }
3836
3837 /**
3838 * gnome_keyring_item_set_info: (skip)
3839 * @keyring: (allow-none): The name of the keyring in which the item exists, or
3840 * %NULL for the default keyring.
3841 * @id: The id of the item
3842 * @info: The item info to save into the item.
3843 * @callback: A callback which will be called when the request completes or fails.
3844 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
3845 * @callback.
3846 * @destroy_data: A function to free @data when it's no longer needed.
3847 *
3848 * Set information on an item, like its display name, secret etc...
3849 *
3850 * Only the fields in the @info pointer that are non-null or non-zero will be
3851 * set on the item.
3852 *
3853 * For a synchronous version of this function see gnome_keyring_item_set_info_sync().
3854 *
3855 * Return value: (transfer none): The asynchronous request, which can be passed
3856 * to gnome_keyring_cancel_request().
3857 *
3858 * Deprecated: Use #SecretItem objects instead.
3859 **/
3860 gpointer
gnome_keyring_item_set_info(const char * keyring,guint32 id,GnomeKeyringItemInfo * info,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)3861 gnome_keyring_item_set_info (const char *keyring,
3862 guint32 id,
3863 GnomeKeyringItemInfo *info,
3864 GnomeKeyringOperationDoneCallback callback,
3865 gpointer data,
3866 GDestroyNotify destroy_data)
3867 {
3868 GkrOperation *op;
3869
3870 gkr_init ();
3871
3872 op = item_set_info_start (keyring, id, info, callback, data, destroy_data);
3873 return gkr_operation_pending_and_unref (op);
3874 }
3875
3876 /**
3877 * gnome_keyring_item_set_info_sync:
3878 * @keyring: (allow-none): The name of the keyring in which the item exists, or
3879 * %NULL for the default keyring.
3880 * @id: The id of the item
3881 * @info: The item info to save into the item.
3882 *
3883 * Set information on an item, like its display name, secret etc...
3884 *
3885 * Only the fields in the @info pointer that are non-null or non-zero will be
3886 * set on the item.
3887 *
3888 * For an asynchronous version of this function see gnome_keyring_item_set_info().
3889 *
3890 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
3891 * an error result otherwise.
3892 *
3893 * Deprecated: Use #SecretItem objects instead.
3894 **/
3895 GnomeKeyringResult
gnome_keyring_item_set_info_sync(const char * keyring,guint32 id,GnomeKeyringItemInfo * info)3896 gnome_keyring_item_set_info_sync (const char *keyring,
3897 guint32 id,
3898 GnomeKeyringItemInfo *info)
3899 {
3900 GkrOperation *op;
3901
3902 gkr_init ();
3903
3904 op = item_set_info_start (keyring, id, info, gkr_callback_empty, NULL, NULL);
3905 return gkr_operation_block_and_unref (op);
3906 }
3907
3908 static void
item_get_attributes_sync(GnomeKeyringResult res,GnomeKeyringAttributeList * attrs,gpointer user_data)3909 item_get_attributes_sync (GnomeKeyringResult res, GnomeKeyringAttributeList *attrs, gpointer user_data)
3910 {
3911 GnomeKeyringAttributeList **result = user_data;
3912 *result = attrs;
3913 }
3914
3915 static void
item_get_attributes_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)3916 item_get_attributes_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
3917 {
3918 GnomeKeyringResult res;
3919 GnomeKeyringAttributeList *attrs;
3920 GkrCallback *cb;
3921
3922 if (gkr_operation_handle_errors (op, reply))
3923 return;
3924
3925 attrs = gnome_keyring_attribute_list_new ();
3926 res = decode_get_attributes (reply, attrs);
3927 if (res == GNOME_KEYRING_RESULT_OK) {
3928 cb = gkr_operation_pop (op);
3929 gkr_callback_invoke_ok_attributes (cb, attrs);
3930 if (cb->callback == item_get_attributes_sync)
3931 attrs = NULL;
3932 } else {
3933 gkr_operation_complete (op, res);
3934 }
3935
3936 gnome_keyring_attribute_list_free (attrs);
3937 }
3938
3939 static GkrOperation*
item_get_attributes_start(const char * keyring,guint32 id,GnomeKeyringOperationGetAttributesCallback callback,gpointer data,GDestroyNotify destroy_data)3940 item_get_attributes_start (const char *keyring, guint32 id,
3941 GnomeKeyringOperationGetAttributesCallback callback,
3942 gpointer data, GDestroyNotify destroy_data)
3943 {
3944 DBusMessage *req;
3945 GkrOperation *op;
3946 gchar *path;
3947
3948 path = gkr_encode_keyring_item_id (keyring, id);
3949 req = prepare_property_get (path, ITEM_INTERFACE, "Attributes");
3950
3951 op = gkr_operation_new (callback, GKR_CALLBACK_RES_ATTRIBUTES, data, destroy_data);
3952 gkr_operation_push (op, item_get_attributes_reply, GKR_CALLBACK_OP_MSG, NULL, NULL);
3953 gkr_operation_request (op, req);
3954 dbus_message_unref (req);
3955 g_free (path);
3956
3957 return op;
3958 }
3959
3960 /**
3961 * gnome_keyring_item_get_attributes: (skip)
3962 * @keyring: (allow-none): The name of the keyring in which the item exists, or
3963 * %NULL for the default keyring.
3964 * @id: The id of the item
3965 * @callback: A callback which will be called when the request completes or fails.
3966 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
3967 * @callback.
3968 * @destroy_data: A function to free @data when it's no longer needed.
3969 *
3970 * Get all the attributes for an item.
3971 *
3972 * A #GnomeKeyringAttributeList will be passed to the @callback. This list will
3973 * be freed after @callback returns.
3974 *
3975 * For a synchronous version of this function see gnome_keyring_item_get_attributes_sync().
3976 *
3977 * Return value: (transfer none): The asynchronous request, which can be passed
3978 * to gnome_keyring_cancel_request().
3979 *
3980 * Deprecated: Use secret_item_get_attributes() instead.
3981 **/
3982 gpointer
gnome_keyring_item_get_attributes(const char * keyring,guint32 id,GnomeKeyringOperationGetAttributesCallback callback,gpointer data,GDestroyNotify destroy_data)3983 gnome_keyring_item_get_attributes (const char *keyring,
3984 guint32 id,
3985 GnomeKeyringOperationGetAttributesCallback callback,
3986 gpointer data,
3987 GDestroyNotify destroy_data)
3988 {
3989 GkrOperation *op;
3990
3991 gkr_init ();
3992
3993 op = item_get_attributes_start (keyring, id, callback, data, destroy_data);
3994 return gkr_operation_pending_and_unref (op);
3995 }
3996
3997 /*FIXME: @attributes is (out), but GI scanner crashes on this */
3998
3999 /**
4000 * gnome_keyring_item_get_attributes_sync:
4001 * @keyring: (allow-none): The name of the keyring in which the item exists, or
4002 * %NULL for the default keyring.
4003 * @id: The id of the item
4004 * @attributes: The location to return a pointer to the attribute list.
4005 *
4006 * Get all attributes for an item.
4007 *
4008 * A #GnomeKeyringAttributeList will be returned in @attributes. This should be
4009 * freed using gnome_keyring_attribute_list_free().
4010 *
4011 * For an asynchronous version of this function see gnome_keyring_item_get_attributes().
4012 *
4013 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
4014 * an error result otherwise.
4015 *
4016 * Deprecated: Use secret_item_get_attributes() instead.
4017 **/
4018 GnomeKeyringResult
gnome_keyring_item_get_attributes_sync(const char * keyring,guint32 id,GnomeKeyringAttributeList ** attributes)4019 gnome_keyring_item_get_attributes_sync (const char *keyring,
4020 guint32 id,
4021 GnomeKeyringAttributeList **attributes)
4022 {
4023 GkrOperation *op;
4024
4025 gkr_init ();
4026
4027 op = item_get_attributes_start (keyring, id, item_get_attributes_sync, attributes, NULL);
4028 return gkr_operation_block_and_unref (op);
4029 }
4030
4031 static DBusMessage*
item_set_attributes_prepare(const gchar * path,GnomeKeyringAttributeList * attrs)4032 item_set_attributes_prepare (const gchar *path, GnomeKeyringAttributeList *attrs)
4033 {
4034 DBusMessageIter iter, variant;
4035 DBusMessage *req;
4036 const gchar *string;
4037
4038 req = dbus_message_new_method_call (gkr_service_name, path,
4039 DBUS_INTERFACE_PROPERTIES, "Set");
4040
4041 dbus_message_iter_init_append (req, &iter);
4042 string = ITEM_INTERFACE;
4043 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &string);
4044 string = "Attributes";
4045 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &string);
4046 dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "a{ss}", &variant);
4047 encode_attribute_list (&variant, attrs);
4048 dbus_message_iter_close_container (&iter, &variant);
4049
4050 return req;
4051 }
4052
4053 static GkrOperation*
item_set_attributes_start(const char * keyring,guint32 id,GnomeKeyringAttributeList * attributes,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)4054 item_set_attributes_start (const char *keyring, guint32 id, GnomeKeyringAttributeList *attributes,
4055 GnomeKeyringOperationDoneCallback callback,
4056 gpointer data, GDestroyNotify destroy_data)
4057 {
4058 DBusMessage *req;
4059 GkrOperation *op;
4060 gchar *string;
4061 gchar *path;
4062
4063 path = gkr_encode_keyring_item_id (keyring, id);
4064
4065 if (gkr_debugging) {
4066 string = gkr_attributes_print (attributes);
4067 gkr_debug ("setting item %s attributes: %s", path, string);
4068 g_free (string);
4069 }
4070
4071 /* Setup the attributes */
4072 req = item_set_attributes_prepare (path, attributes);
4073
4074 g_free (path);
4075
4076 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
4077 gkr_operation_request (op, req);
4078 dbus_message_unref (req);
4079
4080 return op;
4081 }
4082
4083 /**
4084 * gnome_keyring_item_set_attributes: (skip)
4085 * @keyring: (allow-none): The name of the keyring in which the item exists, or
4086 * %NULL for the default keyring.
4087 * @id: The id of the item
4088 * @attributes: The full list of attributes to set on the item.
4089 * @callback: A callback which will be called when the request completes or fails.
4090 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
4091 * @callback.
4092 * @destroy_data: A function to free @data when it's no longer needed.
4093 *
4094 * Set all the attributes for an item. This will replace any previous attributes
4095 * set on the item.
4096 *
4097 * For a synchronous version of this function see gnome_keyring_item_set_attributes_sync().
4098 *
4099 * Return value: (transfer none): The asynchronous request, which can be passed
4100 * to gnome_keyring_cancel_request().
4101 *
4102 * Deprecated: Use secret_item_set_attributes() instead.
4103 **/
4104 gpointer
gnome_keyring_item_set_attributes(const char * keyring,guint32 id,GnomeKeyringAttributeList * attributes,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)4105 gnome_keyring_item_set_attributes (const char *keyring,
4106 guint32 id,
4107 GnomeKeyringAttributeList *attributes,
4108 GnomeKeyringOperationDoneCallback callback,
4109 gpointer data,
4110 GDestroyNotify destroy_data)
4111 {
4112 GkrOperation *op;
4113
4114 gkr_init ();
4115
4116 op = item_set_attributes_start (keyring, id, attributes, callback, data, destroy_data);
4117 return gkr_operation_pending_and_unref (op);
4118 }
4119
4120 /**
4121 * gnome_keyring_item_set_attributes_sync:
4122 * @keyring: (allow-none): The name of the keyring in which the item exists, or
4123 * %NULL for the default keyring.
4124 * @id: The id of the item
4125 * @attributes: The full list of attributes to set on the item.
4126 *
4127 * Set all the attributes for an item. This will replace any previous attributes
4128 * set on the item.
4129 *
4130 * For an asynchronous version of this function see gnome_keyring_item_set_attributes().
4131 *
4132 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
4133 * an error result otherwise.
4134 *
4135 * Deprecated: Use secret_item_set_attributes_sync() instead.
4136 **/
4137 GnomeKeyringResult
gnome_keyring_item_set_attributes_sync(const char * keyring,guint32 id,GnomeKeyringAttributeList * attributes)4138 gnome_keyring_item_set_attributes_sync (const char *keyring,
4139 guint32 id,
4140 GnomeKeyringAttributeList *attributes)
4141 {
4142 GkrOperation *op;
4143
4144 gkr_init ();
4145
4146 op = item_set_attributes_start (keyring, id, attributes, gkr_callback_empty, NULL, NULL);
4147 return gkr_operation_block_and_unref (op);
4148 }
4149
4150 static void
item_get_acl_reply(GnomeKeyringResult res,gpointer user_data)4151 item_get_acl_reply (GnomeKeyringResult res, gpointer user_data)
4152 {
4153 GkrCallback *cb = user_data;
4154 gkr_callback_invoke_ok_list (cb, NULL);
4155 }
4156
4157 /**
4158 * gnome_keyring_item_get_acl: (skip)
4159 * @keyring: (allow-none): The name of the keyring in which the item exists, or
4160 * %NULL for the default keyring.
4161 * @id: The id of the item
4162 * @callback: A callback which will be called when the request completes or fails.
4163 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
4164 * @callback.
4165 * @destroy_data: A function to free @data when it's no longer needed.
4166 *
4167 * Return value: (transfer none): The asynchronous request, which can be passed
4168 * to gnome_keyring_cancel_request().
4169 *
4170 * Deprecated: Never returns any ACL values.
4171 */
4172 gpointer
gnome_keyring_item_get_acl(const char * keyring,guint32 id,GnomeKeyringOperationGetListCallback callback,gpointer data,GDestroyNotify destroy_data)4173 gnome_keyring_item_get_acl (const char *keyring,
4174 guint32 id,
4175 GnomeKeyringOperationGetListCallback callback,
4176 gpointer data,
4177 GDestroyNotify destroy_data)
4178 {
4179 GkrOperation *op;
4180 GkrCallback *cb;
4181
4182 gkr_init ();
4183
4184 cb = gkr_callback_new (NULL, callback, GKR_CALLBACK_RES_LIST, data, destroy_data);
4185 op = gkr_operation_new (item_get_acl_reply, GKR_CALLBACK_RES, cb, gkr_callback_free);
4186 gkr_operation_complete_later (op, GNOME_KEYRING_RESULT_OK);
4187 return gkr_operation_pending_and_unref (op);
4188 }
4189
4190 /**
4191 * gnome_keyring_item_get_acl_sync:
4192 * @keyring: (allow-none): The name of the keyring in which the item exists, or
4193 * %NULL for the default keyring.
4194 * @id: The id of the item
4195 * @acl: (out) (element-type GnomeKeyringAccessControl): The location to return
4196 * a pointer to the access control list.
4197 *
4198 * Return value: Always %GNOME_KEYRING_RESULT_OK.
4199 *
4200 * Deprecated: Never returns any acls.
4201 **/
4202 GnomeKeyringResult
gnome_keyring_item_get_acl_sync(const char * keyring,guint32 id,GList ** acl)4203 gnome_keyring_item_get_acl_sync (const char *keyring,
4204 guint32 id,
4205 GList **acl)
4206 {
4207 g_return_val_if_fail (acl, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
4208 *acl = NULL;
4209 return GNOME_KEYRING_RESULT_OK;
4210 }
4211
4212 /**
4213 * gnome_keyring_item_set_acl: (skip)
4214 * @keyring: (allow-none): The name of the keyring in which the item exists, or
4215 * %NULL for the default keyring.
4216 * @id: The id of the item
4217 * @acl: (element-type GnomeKeyringAccessControl): The access control list to
4218 * set on the item.
4219 * @callback: A callback which will be called when the request completes or fails.
4220 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
4221 * @callback.
4222 * @destroy_data: A function to free @data when it's no longer needed.
4223 *
4224 * Return value: (transfer none): The asynchronous request, which can be passed
4225 * to gnome_keyring_cancel_request().
4226 *
4227 * Deprecated: This function no longer has any effect.
4228 **/
4229 gpointer
gnome_keyring_item_set_acl(const char * keyring,guint32 id,GList * acl,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)4230 gnome_keyring_item_set_acl (const char *keyring,
4231 guint32 id,
4232 GList *acl,
4233 GnomeKeyringOperationDoneCallback callback,
4234 gpointer data,
4235 GDestroyNotify destroy_data)
4236 {
4237 GkrOperation *op;
4238
4239 gkr_init ();
4240
4241 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
4242 gkr_operation_complete_later (op, GNOME_KEYRING_RESULT_OK);
4243 return gkr_operation_pending_and_unref (op);
4244 }
4245
4246 /**
4247 * gnome_keyring_item_set_acl_sync:
4248 * @keyring: (allow-none): The name of the keyring in which the item exists, or
4249 * %NULL for the default keyring.
4250 * @id: The id of the item
4251 * @acl: (element-type GnomeKeyringAccessControl): The access control list to
4252 * set on the item.
4253 *
4254 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
4255 * an error result otherwise.
4256 *
4257 * Deprecated: This function no longer has any effect.
4258 **/
4259 GnomeKeyringResult
gnome_keyring_item_set_acl_sync(const char * keyring,guint32 id,GList * acl)4260 gnome_keyring_item_set_acl_sync (const char *keyring,
4261 guint32 id,
4262 GList *acl)
4263 {
4264 return GNOME_KEYRING_RESULT_OK;
4265 }
4266
4267 /**
4268 * gnome_keyring_item_grant_access_rights: (skip)
4269 * @keyring: (allow-none): The keyring name, or %NULL for the default keyring.
4270 * @display_name: The display name for the application, as returned by g_get_application_name().
4271 * @full_path: The full filepath to the application.
4272 * @id: The id of the item to grant access to.
4273 * @rights: The type of rights to grant.
4274 * @callback: Callback which is called when the operation completes
4275 * @data: (allow-none): Data to be passed to callback
4276 * @destroy_data: Function to be called when data is no longer needed.
4277 *
4278 * Return value: (transfer none): The asynchronous request, which can be passed
4279 * to gnome_keyring_cancel_request().
4280 *
4281 * Since: 2.20
4282 *
4283 * Deprecated: This function no longer has any effect.
4284 */
4285 gpointer
gnome_keyring_item_grant_access_rights(const gchar * keyring,const gchar * display_name,const gchar * full_path,const guint32 id,const GnomeKeyringAccessType rights,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)4286 gnome_keyring_item_grant_access_rights (const gchar *keyring,
4287 const gchar *display_name,
4288 const gchar *full_path,
4289 const guint32 id,
4290 const GnomeKeyringAccessType rights,
4291 GnomeKeyringOperationDoneCallback callback,
4292 gpointer data,
4293 GDestroyNotify destroy_data)
4294 {
4295 GkrOperation *op;
4296
4297 gkr_init ();
4298
4299 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
4300 gkr_operation_complete_later (op, GNOME_KEYRING_RESULT_OK);
4301 return gkr_operation_pending_and_unref (op);
4302 }
4303
4304 /**
4305 * gnome_keyring_item_grant_access_rights_sync:
4306 * @keyring: (allow-none): The keyring name, or %NULL for the default keyring.
4307 * @display_name: The display name for the application, as returned by g_get_application_name().
4308 * @full_path: The full filepath to the application.
4309 * @id: The id of the item to grant access to.
4310 * @rights: The type of rights to grant.
4311 *
4312 * Will grant the application access rights to the item, provided
4313 * callee has write access to said item.
4314 *
4315 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
4316 * an error result otherwise.
4317 *
4318 * Deprecated: This function no longer has any effect.
4319 */
4320 GnomeKeyringResult
gnome_keyring_item_grant_access_rights_sync(const char * keyring,const char * display_name,const char * full_path,const guint32 id,const GnomeKeyringAccessType rights)4321 gnome_keyring_item_grant_access_rights_sync (const char *keyring,
4322 const char *display_name,
4323 const char *full_path,
4324 const guint32 id,
4325 const GnomeKeyringAccessType rights)
4326 {
4327 return GNOME_KEYRING_RESULT_OK;
4328 }
4329
4330 /* ------------------------------------------------------------------------------
4331 * NETWORK PASSWORD APIS
4332 */
4333
4334 /**
4335 * SECTION:gnome-keyring-network
4336 * @title: Network Passwords
4337 * @short_description: Saving of network passwords.
4338 *
4339 * <warning>All of these APIs are deprecated. Use
4340 * <ulink href="http://developer.gnome.org/libsecret/stable/">libsecret</ulink>
4341 * instead.</warning>
4342 *
4343 * Networks passwords are a simple way of saving passwords associated with a
4344 * certain user/server/protocol and other fields.
4345 *
4346 * Attributes are not stored in a secret or encrypted manner by gnome-keyring. Do
4347 * not store sensitive information in attributes.
4348 **/
4349
4350 /**
4351 * gnome_keyring_network_password_free:
4352 * @data: (allow-none): A #GnomeKeyringNetworkPasswordData pointer.
4353 *
4354 * Free a network password data pointer. If %NULL is passed in,
4355 * nothing happens.
4356 *
4357 * Deprecated: Not used with libsecret.
4358 **/
4359 void
gnome_keyring_network_password_free(GnomeKeyringNetworkPasswordData * data)4360 gnome_keyring_network_password_free (GnomeKeyringNetworkPasswordData *data)
4361 {
4362 if (!data)
4363 return;
4364
4365 g_free (data->keyring);
4366 g_free (data->protocol);
4367 g_free (data->server);
4368 g_free (data->object);
4369 g_free (data->authtype);
4370 g_free (data->user);
4371 g_free (data->domain);
4372 gnome_keyring_free_password (data->password);
4373
4374 g_free (data);
4375 }
4376
4377 /**
4378 * gnome_keyring_network_password_list_free:
4379 * @list: (element-type GnomeKeyringNetworkPasswordData): A list of
4380 * #GnomeKeyringNetworkPasswordData pointers.
4381 *
4382 * Free a list of network password data.
4383 *
4384 * Deprecated: Not used with libsecret.
4385 **/
4386 void
gnome_keyring_network_password_list_free(GList * list)4387 gnome_keyring_network_password_list_free (GList *list)
4388 {
4389 g_list_foreach (list, (GFunc)gnome_keyring_network_password_free, NULL);
4390 g_list_free (list);
4391 }
4392
4393 static void
find_network_password_sync(GnomeKeyringResult res,GList * list,gpointer user_data)4394 find_network_password_sync (GnomeKeyringResult res, GList *list, gpointer user_data)
4395 {
4396 GList **result = user_data;
4397 *result = list;
4398 }
4399
4400 static void
find_network_password_filter(GnomeKeyringResult res,GList * found_list,gpointer user_data)4401 find_network_password_filter (GnomeKeyringResult res, GList *found_list, gpointer user_data)
4402 {
4403 GkrCallback *cb = user_data;
4404 GnomeKeyringNetworkPasswordData *data;
4405 GnomeKeyringFound *found;
4406 GList *result, *l;
4407 int i;
4408
4409 if (res != GNOME_KEYRING_RESULT_OK) {
4410 gkr_callback_invoke_res (cb, res);
4411 return;
4412 }
4413
4414 result = NULL;
4415 for (l = found_list; l != NULL; l = l->next) {
4416 found = l->data;
4417
4418 data = g_new0 (GnomeKeyringNetworkPasswordData, 1);
4419
4420 result = g_list_prepend (result, data);
4421
4422 data->keyring = g_strdup (found->keyring);
4423 data->item_id = found->item_id;
4424 data->password = found->secret;
4425 found->secret = NULL;
4426
4427 for (i = 0; i < found->attributes->len; i++) {
4428 GnomeKeyringAttribute *attribute = &(g_array_index (found->attributes, GnomeKeyringAttribute, i));
4429 if (strcmp (attribute->name, "user") == 0 &&
4430 attribute->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
4431 data->user = g_strdup (attribute->value.string);
4432 } else if (strcmp (attribute->name, "domain") == 0 &&
4433 attribute->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
4434 data->domain = g_strdup (attribute->value.string);
4435 } else if (strcmp (attribute->name, "server") == 0 &&
4436 attribute->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
4437 data->server = g_strdup (attribute->value.string);
4438 } else if (strcmp (attribute->name, "object") == 0 &&
4439 attribute->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
4440 data->object = g_strdup (attribute->value.string);
4441 } else if (strcmp (attribute->name, "protocol") == 0 &&
4442 attribute->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
4443 data->protocol = g_strdup (attribute->value.string);
4444 } else if (strcmp (attribute->name, "authtype") == 0 &&
4445 attribute->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
4446 data->authtype = g_strdup (attribute->value.string);
4447 } else if (strcmp (attribute->name, "port") == 0 &&
4448 attribute->type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) {
4449 data->port = attribute->value.integer;
4450 }
4451 }
4452 }
4453
4454 result = g_list_reverse (result);
4455 gkr_callback_invoke_ok_list (cb, result);
4456 if (cb->callback != find_network_password_sync)
4457 gnome_keyring_network_password_list_free (result);
4458 }
4459
4460 static GnomeKeyringAttributeList *
make_attribute_list_for_network_password(const char * user,const char * domain,const char * server,const char * object,const char * protocol,const char * authtype,guint32 port)4461 make_attribute_list_for_network_password (const char *user,
4462 const char *domain,
4463 const char *server,
4464 const char *object,
4465 const char *protocol,
4466 const char *authtype,
4467 guint32 port)
4468 {
4469 GnomeKeyringAttributeList *attributes;
4470
4471 attributes = g_array_new (FALSE, FALSE, sizeof (GnomeKeyringAttribute));
4472
4473 if (user != NULL)
4474 gnome_keyring_attribute_list_append_string (attributes, "user", user);
4475 if (domain != NULL)
4476 gnome_keyring_attribute_list_append_string (attributes, "domain", domain);
4477 if (server != NULL)
4478 gnome_keyring_attribute_list_append_string (attributes, "server", server);
4479 if (object != NULL)
4480 gnome_keyring_attribute_list_append_string (attributes, "object", object);
4481 if (protocol != NULL)
4482 gnome_keyring_attribute_list_append_string (attributes, "protocol", protocol);
4483 if (authtype != NULL)
4484 gnome_keyring_attribute_list_append_string (attributes, "authtype", authtype);
4485 if (port != 0)
4486 gnome_keyring_attribute_list_append_uint32 (attributes, "port", port);
4487 return attributes;
4488 }
4489
4490 static GkrOperation*
find_network_password_start(const char * user,const char * domain,const char * server,const char * object,const char * protocol,const char * authtype,guint32 port,GnomeKeyringOperationGetListCallback callback,gpointer user_data,GDestroyNotify destroy_data)4491 find_network_password_start (const char *user, const char *domain, const char *server,
4492 const char *object, const char *protocol, const char *authtype,
4493 guint32 port, GnomeKeyringOperationGetListCallback callback,
4494 gpointer user_data, GDestroyNotify destroy_data)
4495 {
4496 GnomeKeyringAttributeList *attributes;
4497 GkrOperation *op;
4498 GkrCallback *cb;
4499
4500 attributes = make_attribute_list_for_network_password (user, domain, server, object,
4501 protocol, authtype, port);
4502
4503 cb = gkr_callback_new (NULL, callback, GKR_CALLBACK_RES_LIST, user_data, destroy_data);
4504 op = find_items_start (GNOME_KEYRING_ITEM_NETWORK_PASSWORD, attributes,
4505 find_network_password_filter, cb, gkr_callback_free);
4506 gnome_keyring_attribute_list_free (attributes);
4507
4508 return op;
4509 }
4510
4511 /**
4512 * gnome_keyring_find_network_password: (skip)
4513 * @user: (allow-none): The user name or %NULL for any user.
4514 * @domain: (allow-none): The domain name or %NULL for any domain.
4515 * @server: (allow-none): The server or %NULL for any server.
4516 * @object: (allow-none): The remote object or %NULL for any object.
4517 * @protocol: (allow-none): The network protocol or %NULL for any protocol.
4518 * @authtype: (allow-none): The authentication type or %NULL for any type.
4519 * @port: The network port or zero for any port.
4520 * @callback: Callback which is called when the operation completes
4521 * @data: (allow-none): Data to be passed to callback
4522 * @destroy_data: Function to be called when data is no longer needed.
4523 *
4524 * Find a previously stored network password. Searches all keyrings.
4525 *
4526 * A %GList of #GnomeKeyringNetworkPasswordData structures are passed to the
4527 * @callback. The list and structures are freed after the callback returns.
4528 *
4529 * The user may have been prompted to unlock necessary keyrings, and user will
4530 * have been prompted for access to the items if needed.
4531 *
4532 * Network passwords are items with the item type %GNOME_KEYRING_ITEM_NETWORK_PASSWORD
4533 *
4534 * Return value: (transfer none): The asynchronous request, which can be passed
4535 * to gnome_keyring_cancel_request().
4536 *
4537 * Deprecated: Use secret_password_lookup() with %SECRET_SCHEMA_COMPAT_NETWORK.
4538 **/
4539 gpointer
gnome_keyring_find_network_password(const char * user,const char * domain,const char * server,const char * object,const char * protocol,const char * authtype,guint32 port,GnomeKeyringOperationGetListCallback callback,gpointer user_data,GDestroyNotify destroy_data)4540 gnome_keyring_find_network_password (const char *user,
4541 const char *domain,
4542 const char *server,
4543 const char *object,
4544 const char *protocol,
4545 const char *authtype,
4546 guint32 port,
4547 GnomeKeyringOperationGetListCallback callback,
4548 gpointer user_data,
4549 GDestroyNotify destroy_data)
4550 {
4551 GkrOperation *op;
4552
4553 gkr_init ();
4554
4555 op = find_network_password_start (user, domain, server, object, protocol,
4556 authtype, port, callback, user_data, destroy_data);
4557 return gkr_operation_pending_and_unref (op);
4558 }
4559
4560 /**
4561 * gnome_keyring_find_network_password_sync:
4562 * @user: (allow-none): The user name or %NULL.
4563 * @domain: (allow-none): The domain name or %NULL.
4564 * @server: (allow-none): The server or %NULL.
4565 * @object: (allow-none): The remote object or %NULL.
4566 * @protocol: (allow-none): The network protocol or %NULL.
4567 * @authtype: (allow-none): The authentication type or %NULL.
4568 * @port: The network port or zero.
4569 * @results: (out) (element-type GnomeKeyringNetworkPasswordData): A location
4570 * to return a %GList of #GnomeKeyringNetworkPasswordData pointers.
4571 *
4572 * Find a previously stored network password. Searches all keyrings.
4573 *
4574 * A %GList of #GnomeKeyringNetworkPasswordData structures are returned in the
4575 * @out_list argument. The list should be freed with gnome_keyring_network_password_list_free()
4576 *
4577 * The user may have been prompted to unlock necessary keyrings, and user will
4578 * have been prompted for access to the items if needed.
4579 *
4580 * Network passwords are items with the item type %GNOME_KEYRING_ITEM_NETWORK_PASSWORD
4581 *
4582 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
4583 * an error result otherwise.
4584 *
4585 * Deprecated: Use secret_password_lookup_sync() with %SECRET_SCHEMA_COMPAT_NETWORK.
4586 **/
4587 GnomeKeyringResult
gnome_keyring_find_network_password_sync(const char * user,const char * domain,const char * server,const char * object,const char * protocol,const char * authtype,guint32 port,GList ** results)4588 gnome_keyring_find_network_password_sync (const char *user,
4589 const char *domain,
4590 const char *server,
4591 const char *object,
4592 const char *protocol,
4593 const char *authtype,
4594 guint32 port,
4595 GList **results)
4596 {
4597 GkrOperation *op;
4598
4599 gkr_init ();
4600
4601 op = find_network_password_start (user, domain, server, object, protocol,
4602 authtype, port, find_network_password_sync, results, NULL);
4603 return gkr_operation_block_and_unref (op);
4604 }
4605
4606 static char *
set_network_password_display_name(const char * user,const char * server,const char * object,guint32 port)4607 set_network_password_display_name (const char *user,
4608 const char *server,
4609 const char *object,
4610 guint32 port)
4611 {
4612 GString *s;
4613 char *name;
4614
4615 if (server != NULL) {
4616 s = g_string_new (NULL);
4617 if (user != NULL) {
4618 g_string_append_printf (s, "%s@", user);
4619 }
4620 g_string_append (s, server);
4621 if (port != 0)
4622 g_string_append_printf (s, ":%d", port);
4623 if (object != NULL)
4624 g_string_append_printf (s, "/%s", object);
4625 name = g_string_free (s, FALSE);
4626 } else {
4627 name = g_strdup ("network password");
4628 }
4629 return name;
4630 }
4631
4632 static void
set_network_password_sync(GnomeKeyringResult res,guint32 item_id,gpointer user_data)4633 set_network_password_sync (GnomeKeyringResult res, guint32 item_id, gpointer user_data)
4634 {
4635 guint32 *result = user_data;
4636 *result = item_id;
4637 }
4638
4639 static GkrOperation*
set_network_password_start(const char * keyring,const char * user,const char * domain,const char * server,const char * object,const char * protocol,const char * authtype,guint32 port,const char * password,GnomeKeyringOperationGetIntCallback callback,gpointer data,GDestroyNotify destroy_data)4640 set_network_password_start (const char *keyring, const char *user, const char *domain,
4641 const char *server, const char *object, const char *protocol,
4642 const char *authtype, guint32 port, const char *password,
4643 GnomeKeyringOperationGetIntCallback callback,
4644 gpointer data, GDestroyNotify destroy_data)
4645 {
4646 GnomeKeyringAttributeList *attributes;
4647 GkrOperation *op;
4648 char *name;
4649
4650 name = set_network_password_display_name (user, server, object, port);
4651
4652 attributes = make_attribute_list_for_network_password (user, domain, server, object,
4653 protocol, authtype, port);
4654
4655 op = item_create_start (keyring, GNOME_KEYRING_ITEM_NETWORK_PASSWORD, name, attributes,
4656 password, TRUE, callback, data, destroy_data);
4657
4658 gnome_keyring_attribute_list_free (attributes);
4659 g_free (name);
4660
4661 return op;
4662 }
4663
4664 /**
4665 * gnome_keyring_set_network_password: (skip)
4666 * @keyring: (allow-none): The keyring to store the password in, or %NULL for
4667 * the default keyring.
4668 * @user: (allow-none): The user name or %NULL.
4669 * @domain: (allow-none): The domain name or %NULL.
4670 * @server: (allow-none): The server or %NULL.
4671 * @object: (allow-none): The remote object or %NULL.
4672 * @protocol: (allow-none): The network protocol or %NULL.
4673 * @authtype: (allow-none): The authentication type or %NULL.
4674 * @port: The network port or zero.
4675 * @password: The password to store, must not be %NULL.
4676 * @callback: Callback which is called when the operation completes
4677 * @data: (allow-none): Data to be passed to callback
4678 * @destroy_data: Function to be called when data is no longer needed.
4679 *
4680 * Store a network password.
4681 *
4682 * If an item already exists for with this network info (ie: user, server etc...)
4683 * then it will be updated.
4684 *
4685 * Whether a new item is created or not, id of the item will be passed to
4686 * the @callback.
4687 *
4688 * Network passwords are items with the item type %GNOME_KEYRING_ITEM_NETWORK_PASSWORD
4689 *
4690 * Return value: (transfer none): The asynchronous request, which can be passed
4691 * to gnome_keyring_cancel_request().
4692 *
4693 * Deprecated: Use secret_password_store() with %SECRET_SCHEMA_COMPAT_NETWORK.
4694 **/
4695 gpointer
gnome_keyring_set_network_password(const char * keyring,const char * user,const char * domain,const char * server,const char * object,const char * protocol,const char * authtype,guint32 port,const char * password,GnomeKeyringOperationGetIntCallback callback,gpointer data,GDestroyNotify destroy_data)4696 gnome_keyring_set_network_password (const char *keyring,
4697 const char *user,
4698 const char *domain,
4699 const char *server,
4700 const char *object,
4701 const char *protocol,
4702 const char *authtype,
4703 guint32 port,
4704 const char *password,
4705 GnomeKeyringOperationGetIntCallback callback,
4706 gpointer data,
4707 GDestroyNotify destroy_data)
4708 {
4709 GkrOperation *op;
4710
4711 gkr_init ();
4712
4713 op = set_network_password_start (keyring, user, domain, server, object, protocol,
4714 authtype, port, password, callback, data, destroy_data);
4715 return gkr_operation_pending_and_unref (op);
4716 }
4717
4718 /**
4719 * gnome_keyring_set_network_password_sync:
4720 * @keyring: (allow-none): The keyring to store the password in, or %NULL for
4721 * the default keyring.
4722 * @user: (allow-none): The user name or %NULL.
4723 * @domain: (allow-none): The domain name or %NULL.
4724 * @server: (allow-none): The server or %NULL.
4725 * @object: (allow-none): The remote object or %NULL.
4726 * @protocol: (allow-none): The network protocol or %NULL.
4727 * @authtype: (allow-none): The authentication type or %NULL.
4728 * @port: The network port or zero.
4729 * @password: The password to store, must not be %NULL.
4730 * @item_id: (out): A location to store the resulting item's id.
4731 *
4732 * Store a network password.
4733 *
4734 * If an item already exists for with this network info (ie: user, server etc...)
4735 * then it will be updated.
4736 *
4737 * The created or updated item id will be returned in @item_id.
4738 *
4739 * Network passwords are items with the item type %GNOME_KEYRING_ITEM_NETWORK_PASSWORD
4740 *
4741 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
4742 * an error result otherwise.
4743 *
4744 * Deprecated: Use secret_password_store_sync() with %SECRET_SCHEMA_COMPAT_NETWORK.
4745 **/
4746 GnomeKeyringResult
gnome_keyring_set_network_password_sync(const char * keyring,const char * user,const char * domain,const char * server,const char * object,const char * protocol,const char * authtype,guint32 port,const char * password,guint32 * item_id)4747 gnome_keyring_set_network_password_sync (const char *keyring,
4748 const char *user,
4749 const char *domain,
4750 const char *server,
4751 const char *object,
4752 const char *protocol,
4753 const char *authtype,
4754 guint32 port,
4755 const char *password,
4756 guint32 *item_id)
4757 {
4758 GkrOperation *op;
4759
4760 gkr_init ();
4761
4762 op = set_network_password_start (keyring, user, domain, server, object, protocol,
4763 authtype, port, password, set_network_password_sync, item_id, NULL);
4764 return gkr_operation_block_and_unref (op);
4765 }
4766
4767 /* ------------------------------------------------------------------------------
4768 * SIMPLE PASSWORD APIS
4769 */
4770
4771 /**
4772 * SECTION:gnome-keyring-password
4773 * @title: Simple Password Storage
4774 * @short_description: Store and lookup passwords with a set of attributes.
4775 *
4776 * <warning>All of these APIs are deprecated. Use
4777 * <ulink href="http://developer.gnome.org/libsecret/stable/">libsecret</ulink>
4778 * instead.</warning>
4779 *
4780 * This is a simple API for storing passwords and retrieving passwords in the keyring.
4781 *
4782 * Each password is associated with a set of attributes. Attribute values can be either
4783 * strings or unsigned integers.
4784 *
4785 * The names and types of allowed attributes for a given password are defined with a
4786 * schema. Certain schemas are predefined such as %GNOME_KEYRING_NETWORK_PASSWORD.
4787 * Additional schemas can be defined via the %GnomeKeyringPasswordSchema structure.
4788 *
4789 * Attributes are not stored in a secret or encrypted manner by gnome-keyring. Do
4790 * not store sensitive information in attributes.
4791 *
4792 * Each function accepts a variable list of attributes names and their values.
4793 * Include a %NULL to terminate the list of attributes.
4794 *
4795 * <example>
4796 * <title>Passing attributes to the functions</title>
4797 * <programlisting>
4798 * res = gnome_keyring_delete_password_sync (GNOME_KEYRING_NETWORK_PASSWORD,
4799 * "user", "me", // A string attribute
4800 * "server, "example.gnome.org",
4801 * "port", "8080", // An integer attribute
4802 * NULL);
4803 * </programlisting></example>
4804 **/
4805
4806 /**
4807 * GnomeKeyringPasswordSchema:
4808 * @item_type: The item type for this schema.
4809 * @attributes: (type GnomeKeyringPasswordSchemaAttribute) (array fixed-size=32): list of attributes
4810 *
4811 * Describes a password schema. Often you'll want to use a predefined schema such
4812 * as %GNOME_KEYRING_NETWORK_PASSWORD.
4813 *
4814 * <para>
4815 * The last attribute name in a schema must be %NULL.
4816 *
4817 * <programlisting>
4818 * GnomeKeyringPasswordSchema my_schema = {
4819 * GNOME_KEYRING_ITEM_GENERIC_SECRET,
4820 * {
4821 * { "string-attr", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
4822 * { "uint-attr", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 },
4823 * { NULL, 0 }
4824 * }
4825 * };
4826 * </programlisting>
4827 * </para>
4828 **/
4829
4830 /**
4831 * GnomeKeyringPasswordSchemaAttribute:
4832 * @name: the attribute name
4833 * @type: the attribute data type
4834 *
4835 * One attribute of a #GnomeKeyringPasswordSchema.
4836 */
4837
4838 static const GnomeKeyringPasswordSchema network_password_schema = {
4839 GNOME_KEYRING_ITEM_NETWORK_PASSWORD,
4840 {
4841 { "user", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
4842 { "domain", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
4843 { "object", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
4844 { "protocol", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
4845 { "port", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 },
4846 { "server", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
4847 { "NULL", 0 },
4848 }
4849 };
4850
4851 /**
4852 * GNOME_KEYRING_NETWORK_PASSWORD:
4853 *
4854 * <para>
4855 * A predefined schema for network paswsords. It contains the following attributes:
4856 * </para>
4857 * <itemizedlist>
4858 * <listitem>user: A string for the user login.</listitem>
4859 * <listitem>server: The server being connected to.</listitem>
4860 * <listitem>protocol: The protocol used to access the server, such as 'http' or 'smb'</listitem>
4861 * <listitem>domain: A realm or domain, such as a Windows login domain.</listitem>
4862 * <listitem>port: The network port to used to connect to the server.</listitem>
4863 * </itemizedlist>
4864 **/
4865
4866 /* Declared in gnome-keyring.h */
4867 const GnomeKeyringPasswordSchema *GNOME_KEYRING_NETWORK_PASSWORD = &network_password_schema;
4868
4869 /**
4870 * GNOME_KEYRING_DEFAULT:
4871 *
4872 * <para>
4873 * The default keyring.
4874 * </para>
4875 **/
4876
4877 /**
4878 * GNOME_KEYRING_SESSION:
4879 *
4880 * <para>
4881 * A keyring only stored in memory.
4882 * </para>
4883 **/
4884
4885 static GnomeKeyringAttributeList*
schema_attribute_list_va(const GnomeKeyringPasswordSchema * schema,va_list args)4886 schema_attribute_list_va (const GnomeKeyringPasswordSchema *schema, va_list args)
4887 {
4888 GnomeKeyringAttributeList *attributes;
4889 GnomeKeyringAttributeType type;
4890 GnomeKeyringAttribute attribute;
4891 gboolean type_found;
4892 char *str;
4893 guint32 i, val;
4894
4895 attributes = g_array_new (FALSE, FALSE, sizeof (GnomeKeyringAttribute));
4896
4897 while ((attribute.name = va_arg (args, char *)) != NULL) {
4898
4899 type_found = FALSE;
4900 for (i = 0; i < G_N_ELEMENTS (schema->attributes); ++i) {
4901 if (!schema->attributes[i].name)
4902 break;
4903 if (strcmp (schema->attributes[i].name, attribute.name) == 0) {
4904 type_found = TRUE;
4905 type = schema->attributes[i].type;
4906 break;
4907 }
4908 }
4909
4910 if (!type_found) {
4911 g_warning ("The password attribute '%s' was not found in the password schema.", attribute.name);
4912 g_array_free (attributes, TRUE);
4913 return NULL;
4914 }
4915
4916 attribute.type = type;
4917 switch (type) {
4918 case GNOME_KEYRING_ATTRIBUTE_TYPE_STRING:
4919 str = va_arg (args, char *);
4920 attribute.value.string = str;
4921 g_array_append_val (attributes, attribute);
4922 break;
4923 case GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32:
4924 val = va_arg (args, guint32);
4925 attribute.value.integer = val;
4926 g_array_append_val (attributes, attribute);
4927 break;
4928 default:
4929 g_warning ("The password attribute '%s' has an invalid type in the password schema.", attribute.name);
4930 g_array_free (attributes, TRUE);
4931 return NULL;
4932 }
4933 }
4934
4935 return attributes;
4936 }
4937
4938 static void
store_password_filter(GnomeKeyringResult res,guint32 item_id,gpointer user_data)4939 store_password_filter (GnomeKeyringResult res, guint32 item_id, gpointer user_data)
4940 {
4941 GkrCallback *cb = user_data;
4942 gkr_callback_invoke_res (cb, res);
4943 }
4944
4945 /**
4946 * gnome_keyring_store_password: (skip)
4947 * @schema: The password schema.
4948 * @keyring: (allow-none): The keyring to store the password in. Specify %NULL
4949 * for the default keyring. Use %GNOME_KEYRING_SESSION to store the
4950 * password in memory only.
4951 * @display_name: A human readable description of what the password is for.
4952 * @password: The password to store.
4953 * @callback: A callback which will be called when the request completes or fails.
4954 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
4955 * @callback.
4956 * @destroy_data: A function to free @data when it's no longer needed.
4957 * @...: The variable argument list should contain pairs of a) The attribute name as a null
4958 * terminated string, followed by b) attribute value, either a character string,
4959 * or 32-bit unsigned int, as defined in the password @schema. The list of attribtues
4960 * should be terminated with a %NULL.
4961 *
4962 * Store a password associated with a given set of attributes.
4963 *
4964 * Attributes which identify this password must be passed as additional
4965 * arguments. Attributes passed must be defined in the schema.
4966 *
4967 * If a password exists in the keyring that already has all the same arguments,
4968 * then the password will be updated.
4969 *
4970 * Another more complex way to create a keyring item is using gnome_keyring_item_create().
4971 *
4972 * Return value: (transfer none): The asynchronous request, which can be passed
4973 * to gnome_keyring_cancel_request().
4974 *
4975 * Since: 2.22
4976 *
4977 * Deprecated: Use secret_password_store() instead.
4978 **/
4979 gpointer
gnome_keyring_store_password(const GnomeKeyringPasswordSchema * schema,const gchar * keyring,const gchar * display_name,const gchar * password,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data,...)4980 gnome_keyring_store_password (const GnomeKeyringPasswordSchema* schema, const gchar *keyring,
4981 const gchar *display_name, const gchar *password,
4982 GnomeKeyringOperationDoneCallback callback,
4983 gpointer data, GDestroyNotify destroy_data, ...)
4984 {
4985 GnomeKeyringAttributeList *attributes;
4986 GkrOperation *op;
4987 GkrCallback *cb;
4988 va_list args;
4989
4990 gkr_init ();
4991
4992 va_start (args, destroy_data);
4993 attributes = schema_attribute_list_va (schema, args);
4994 va_end (args);
4995
4996 cb = gkr_callback_new (NULL, callback, GKR_CALLBACK_RES, data, destroy_data);
4997 op = gnome_keyring_item_create (keyring, schema->item_type, display_name, attributes,
4998 password, TRUE, store_password_filter, cb, gkr_callback_free);
4999
5000 g_array_free (attributes, TRUE);
5001 return op;
5002 }
5003
5004 /**
5005 * gnome_keyring_store_password_sync: (skip)
5006 * @schema: The password schema.
5007 * @keyring: (allow-none): The keyring to store the password in. Specify %NULL
5008 * for the default keyring. Use %GNOME_KEYRING_SESSION to store the
5009 * password in memory only.
5010 * @display_name: A human readable description of what the password is for.
5011 * @password: The password to store.
5012 * @...: The variable argument list should contain pairs of a) The attribute name as a null
5013 * terminated string, followed by b) attribute value, either a character string,
5014 * or 32-bit unsigned int, as defined in the password @schema. The list of attribtues
5015 * should be terminated with a %NULL.
5016 *
5017 * Store a password associated with a given set of attributes.
5018 *
5019 * Attributes which identify this password must be passed as additional
5020 * arguments. Attributes passed must be defined in the schema.
5021 *
5022 * This function may block for an unspecified period. If your application must
5023 * remain responsive to the user, then use gnome_keyring_store_password().
5024 *
5025 * If a password exists in the keyring that already has all the same arguments,
5026 * then the password will be updated.
5027 *
5028 * Another more complex way to create a keyring item is using
5029 * gnome_keyring_item_create_sync().
5030 *
5031 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
5032 * an error result otherwise.
5033 *
5034 * Since: 2.22
5035 *
5036 * Deprecated: Use secret_password_store_sync() instead.
5037 **/
5038 GnomeKeyringResult
gnome_keyring_store_password_sync(const GnomeKeyringPasswordSchema * schema,const gchar * keyring,const gchar * display_name,const gchar * password,...)5039 gnome_keyring_store_password_sync (const GnomeKeyringPasswordSchema* schema, const gchar *keyring,
5040 const gchar *display_name, const gchar *password, ...)
5041 {
5042 GnomeKeyringAttributeList *attributes;
5043 GnomeKeyringResult res;
5044 guint32 item_id;
5045 va_list args;
5046
5047 g_return_val_if_fail (schema, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
5048
5049 gkr_init ();
5050
5051 va_start (args, password);
5052 attributes = schema_attribute_list_va (schema, args);
5053 va_end (args);
5054
5055 if (!attributes || !attributes->len)
5056 return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
5057
5058 res = gnome_keyring_item_create_sync (keyring, schema->item_type, display_name,
5059 attributes, password, TRUE, &item_id);
5060
5061 g_array_free (attributes, TRUE);
5062 return res;
5063 }
5064
5065 static gboolean
find_unlocked_first(const char * path,gpointer user_data)5066 find_unlocked_first (const char *path, gpointer user_data)
5067 {
5068 const char **result = user_data;
5069 *result = path;
5070 return FALSE;
5071 }
5072
5073 static void
find_unlocked_3_reply(GkrOperation * op,DBusMessage * reply,gpointer data)5074 find_unlocked_3_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
5075 {
5076 gboolean dismissed;
5077 const char *item = NULL;
5078
5079 /* At this point Prompt has Completed, and should contain a list of unlocked items */
5080
5081 if (gkr_operation_handle_errors (op, reply))
5082 return;
5083
5084 if (!decode_xlock_completed (reply, &dismissed, find_unlocked_first, &item)) {
5085 gkr_operation_complete (op, decode_invalid_response (reply));
5086 return;
5087 }
5088
5089 gkr_callback_invoke_op_string (gkr_operation_pop (op), item);
5090 }
5091
5092 static void
find_unlocked_2_reply(GkrOperation * op,DBusMessage * reply,gpointer data)5093 find_unlocked_2_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
5094 {
5095 const char *prompt;
5096 const char *item = NULL;
5097
5098 /* At this point Unlock has returned a list of unlocked items, plus prompt? */
5099
5100 if (gkr_operation_handle_errors (op, reply))
5101 return;
5102
5103 if (!decode_xlock_reply (reply, &prompt, find_unlocked_first, &item)) {
5104 gkr_operation_complete (op, decode_invalid_response (reply));
5105 return;
5106 }
5107
5108 /* Need to show prompt to find an unlocked item */
5109 if (!item && !g_str_equal (prompt, "/")) {
5110 gkr_operation_push (op, find_unlocked_3_reply, GKR_CALLBACK_OP_MSG, NULL, NULL);
5111 gkr_operation_prompt (op, prompt);
5112 return;
5113 }
5114
5115 gkr_callback_invoke_op_string (gkr_operation_pop (op), item);
5116 }
5117
5118 static void
find_unlocked_1_reply(GkrOperation * op,DBusMessage * reply,gpointer data)5119 find_unlocked_1_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
5120 {
5121 char **unlocked, **locked;
5122 int n_unlocked, n_locked;
5123 DBusMessage *req;
5124
5125 /* At this point SearchItems has returned two lists of locked/unlocked items */
5126
5127 if (gkr_operation_handle_errors (op, reply))
5128 return;
5129
5130 if (!dbus_message_get_args (reply, NULL,
5131 DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &unlocked, &n_unlocked,
5132 DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &locked, &n_locked,
5133 DBUS_TYPE_INVALID)) {
5134 gkr_operation_complete (op, decode_invalid_response (reply));
5135 return;
5136 }
5137
5138 /* Do we have an unlocked item? */
5139 if (n_unlocked) {
5140 gkr_callback_invoke_op_string (gkr_operation_pop (op), unlocked[0]);
5141
5142 /* Do we have any to unlock? */
5143 } else if (n_locked) {
5144 req = prepare_xlock ("Unlock", locked, n_locked);
5145 gkr_operation_push (op, find_unlocked_2_reply, GKR_CALLBACK_OP_MSG, NULL, NULL);
5146 gkr_operation_request (op, req);
5147
5148 /* No passwords at all, complete */
5149 } else {
5150 gkr_callback_invoke_op_string (gkr_operation_pop (op), NULL);
5151 }
5152
5153 dbus_free_string_array (locked);
5154 dbus_free_string_array (unlocked);
5155 }
5156
5157 static void
find_unlocked(GkrOperation * op,GnomeKeyringAttributeList * attributes)5158 find_unlocked (GkrOperation *op, GnomeKeyringAttributeList *attributes)
5159 {
5160 DBusMessageIter iter;
5161 DBusMessage *req;
5162
5163 req = dbus_message_new_method_call (gkr_service_name, SERVICE_PATH,
5164 SERVICE_INTERFACE, "SearchItems");
5165
5166 /* Encode the attribute list */
5167 dbus_message_iter_init_append (req, &iter);
5168 encode_attribute_list (&iter, attributes);
5169
5170 gkr_operation_push (op, find_unlocked_1_reply, GKR_CALLBACK_OP_MSG, NULL, NULL);
5171 gkr_operation_request (op, req);
5172 dbus_message_unref (req);
5173 }
5174
5175 static void
find_password_sync(GnomeKeyringResult res,const gchar * secret,gpointer user_data)5176 find_password_sync (GnomeKeyringResult res, const gchar *secret, gpointer user_data)
5177 {
5178 gchar **result = user_data;
5179 *result = (gchar*)secret;
5180 }
5181
5182 static void
find_password_3_reply(GkrOperation * op,DBusMessage * reply,gpointer user_data)5183 find_password_3_reply (GkrOperation *op, DBusMessage *reply, gpointer user_data)
5184 {
5185 GkrSession *session = user_data;
5186 DBusMessageIter iter;
5187 GkrCallback *cb;
5188 gchar *secret;
5189
5190 if (gkr_operation_handle_errors (op, reply))
5191 return;
5192
5193 if (!dbus_message_iter_init (reply, &iter) ||
5194 !gkr_session_decode_secret (session, &iter, &secret)) {
5195 gkr_operation_complete (op, decode_invalid_response (reply));
5196 return;
5197 }
5198
5199 cb = gkr_operation_pop (op);
5200 gkr_callback_invoke_ok_string (cb, secret);
5201 if (cb->callback != find_password_sync)
5202 egg_secure_strfree (secret);
5203 }
5204
5205 static void
find_password_2_reply(GkrOperation * op,GkrSession * session,gpointer user_data)5206 find_password_2_reply (GkrOperation *op, GkrSession *session, gpointer user_data)
5207 {
5208 gchar *path = user_data;
5209 DBusMessage *req;
5210
5211 req = prepare_get_secret (session, path);
5212
5213 gkr_operation_push (op, find_password_3_reply, GKR_CALLBACK_OP_MSG,
5214 gkr_session_ref (session), gkr_session_unref);
5215 gkr_operation_request (op, req);
5216 dbus_message_unref (req);
5217 }
5218
5219 static void
find_password_1_reply(GkrOperation * op,const char * path,gpointer user_data)5220 find_password_1_reply (GkrOperation *op, const char *path, gpointer user_data)
5221 {
5222 GkrCallback *cb;
5223
5224 /* All done, complete the operation here */
5225 if (path == NULL) {
5226 cb = gkr_operation_pop (op);
5227 gkr_callback_invoke_res (cb, GNOME_KEYRING_RESULT_NO_MATCH);
5228
5229 /* We need a session to get the secret for this item */
5230 } else {
5231 gkr_operation_push (op, find_password_2_reply, GKR_CALLBACK_OP_SESSION,
5232 g_strdup (path), g_free);
5233 gkr_session_negotiate (op);
5234 }
5235 }
5236
5237 static GkrOperation*
find_password_va_start(const GnomeKeyringPasswordSchema * schema,va_list va,GnomeKeyringOperationGetStringCallback callback,gpointer data,GDestroyNotify destroy_data)5238 find_password_va_start (const GnomeKeyringPasswordSchema* schema, va_list va,
5239 GnomeKeyringOperationGetStringCallback callback,
5240 gpointer data, GDestroyNotify destroy_data)
5241 {
5242 GnomeKeyringAttributeList *attributes;
5243 GkrOperation *op;
5244
5245 g_assert (schema);
5246 g_assert (callback);
5247
5248 attributes = schema_attribute_list_va (schema, va);
5249
5250 op = gkr_operation_new (callback, GKR_CALLBACK_RES_STRING, data, destroy_data);
5251
5252 if (attributes == NULL || attributes->len == 0) {
5253 gkr_operation_complete_later (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
5254
5255 } else {
5256 gkr_operation_push (op, find_password_1_reply, GKR_CALLBACK_OP_STRING, NULL, NULL);
5257 find_unlocked (op, attributes);
5258 }
5259
5260 g_array_free (attributes, TRUE);
5261 return op;
5262 }
5263
5264 /**
5265 * gnome_keyring_find_password: (skip)
5266 * @schema: The password schema.
5267 * @callback: A callback which will be called when the request completes or fails.
5268 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
5269 * @callback.
5270 * @destroy_data: A function to free @data when it's no longer needed.
5271 * @...: The variable argument list should contain pairs of a) The attribute name as a null
5272 * terminated string, followed by b) attribute value, either a character string,
5273 * or 32-bit unsigned int, as defined in the password @schema. The list of attribtues
5274 * should be terminated with a %NULL.
5275 *
5276 * Find a password that matches a given set of attributes.
5277 *
5278 * Attributes which identify this password must be passed as additional
5279 * arguments. Attributes passed must be defined in the schema.
5280 *
5281 * The string that is passed to @callback is automatically freed when the
5282 * function returns.
5283 *
5284 * Another more complex way to find items in the keyrings is using
5285 * gnome_keyring_find_items().
5286 *
5287 * Return value: (transfer none): The asynchronous request, which can be passed
5288 * to gnome_keyring_cancel_request().
5289 *
5290 * Since: 2.22
5291 *
5292 * Deprecated: Use secret_password_lookup() instead.
5293 **/
5294 gpointer
gnome_keyring_find_password(const GnomeKeyringPasswordSchema * schema,GnomeKeyringOperationGetStringCallback callback,gpointer data,GDestroyNotify destroy_data,...)5295 gnome_keyring_find_password (const GnomeKeyringPasswordSchema* schema,
5296 GnomeKeyringOperationGetStringCallback callback,
5297 gpointer data, GDestroyNotify destroy_data, ...)
5298 {
5299 GkrOperation *op;
5300 va_list va;
5301
5302 g_return_val_if_fail (schema, NULL);
5303 g_return_val_if_fail (callback, NULL);
5304
5305 gkr_init ();
5306
5307 va_start (va, destroy_data);
5308 op = find_password_va_start (schema, va, callback, data, destroy_data);
5309 va_end (va);
5310
5311 return gkr_operation_pending_and_unref (op);
5312 }
5313
5314 /**
5315 * GnomeKeyringFound:
5316 * @keyring: The keyring the item was found in.
5317 * @item_id: The identifier for the item.
5318 * @attributes: The item's attributes.
5319 * @secret: The item's secret.
5320 *
5321 * A found structure returned by a found operation. Use gnome_keyring_found_list_free()
5322 * to free a list of these structures.
5323 *
5324 * Deprecated: Not used with libsecret.
5325 */
5326
5327 /**
5328 * gnome_keyring_find_password_sync: (skip)
5329 * @schema: The password schema.
5330 * @password: (out): An address to store password that was found. The password
5331 * must be freed with gnome_keyring_free_password().
5332 * @...: The variable argument list should contain pairs of a) The attribute name as a null
5333 * terminated string, followed by b) attribute value, either a character string,
5334 * or 32-bit unsigned int, as defined in the password @schema. The list of attribtues
5335 * should be terminated with a %NULL.
5336 *
5337 * Find a password that matches a given set of attributes.
5338 *
5339 * Attributes which identify this password must be passed as additional
5340 * arguments. Attributes passed must be defined in the schema.
5341 *
5342 * This function may block for an unspecified period. If your application must
5343 * remain responsive to the user, then use gnome_keyring_find_password().
5344 *
5345 * Another more complex way to find items in the keyrings is using
5346 * gnome_keyring_find_items_sync().
5347 *
5348 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
5349 * an error result otherwise.
5350 *
5351 * Since: 2.22
5352 *
5353 * Deprecated: Use secret_password_lookup_sync() instead.
5354 **/
5355 GnomeKeyringResult
gnome_keyring_find_password_sync(const GnomeKeyringPasswordSchema * schema,gchar ** password,...)5356 gnome_keyring_find_password_sync (const GnomeKeyringPasswordSchema* schema,
5357 gchar **password, ...)
5358 {
5359 GkrOperation *op;
5360 va_list va;
5361
5362 g_return_val_if_fail (schema, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
5363 g_return_val_if_fail (password, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
5364
5365 gkr_init ();
5366
5367 va_start (va, password);
5368 op = find_password_va_start (schema, va, find_password_sync, password, NULL);
5369 va_end (va);
5370
5371 return gkr_operation_block_and_unref (op);
5372 }
5373
5374 static void
delete_password_reply(GkrOperation * op,const char * path,gpointer user_data)5375 delete_password_reply (GkrOperation *op, const char *path, gpointer user_data)
5376 {
5377 DBusMessage *req;
5378
5379 if (path == NULL) {
5380 gkr_operation_complete (op, GNOME_KEYRING_RESULT_NO_MATCH);
5381 } else {
5382 req = dbus_message_new_method_call (gkr_service_name, path,
5383 ITEM_INTERFACE, "Delete");
5384 gkr_operation_request (op, req);
5385 dbus_message_unref (req);
5386 }
5387 }
5388
5389 static GkrOperation*
delete_password_va_start(const GnomeKeyringPasswordSchema * schema,va_list va,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data)5390 delete_password_va_start (const GnomeKeyringPasswordSchema* schema, va_list va,
5391 GnomeKeyringOperationDoneCallback callback,
5392 gpointer data, GDestroyNotify destroy_data)
5393 {
5394 GnomeKeyringAttributeList *attributes;
5395 GkrOperation *op;
5396
5397 g_assert (schema);
5398 g_assert (callback);
5399
5400 attributes = schema_attribute_list_va (schema, va);
5401
5402 op = gkr_operation_new (callback, GKR_CALLBACK_RES, data, destroy_data);
5403
5404 if (!attributes || !attributes->len) {
5405 gkr_operation_complete_later (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
5406
5407 } else {
5408 gkr_operation_push (op, delete_password_reply, GKR_CALLBACK_OP_STRING, NULL, NULL);
5409 find_unlocked (op, attributes);
5410 }
5411
5412 return op;
5413 }
5414
5415 /**
5416 * gnome_keyring_delete_password: (skip)
5417 * @schema: The password schema.
5418 * @callback: A callback which will be called when the request completes or fails.
5419 * @data: (allow-none): A pointer to arbitrary data that will be passed to the
5420 * @callback.
5421 * @destroy_data: A function to free @data when it's no longer needed.
5422 * @...: The variable argument list should contain pairs of a) The attribute name as a null
5423 * terminated string, followed by b) attribute value, either a character string,
5424 * or 32-bit unsigned int, as defined in the password @schema. The list of attribtues
5425 * should be terminated with a %NULL.
5426 *
5427 * Delete a password that matches a given set of attributes.
5428 *
5429 * Attributes which identify this password must be passed as additional
5430 * arguments. Attributes passed must be defined in the schema.
5431 *
5432 * Another more complex way to find items in the keyrings is using
5433 * gnome_keyring_item_delete().
5434 *
5435 * Return value: (transfer none): The asynchronous request, which can be passed
5436 * to gnome_keyring_cancel_request().
5437 *
5438 * Since: 2.22
5439 *
5440 * Deprecated: Use secret_password_clear() instead.
5441 **/
5442 gpointer
gnome_keyring_delete_password(const GnomeKeyringPasswordSchema * schema,GnomeKeyringOperationDoneCallback callback,gpointer data,GDestroyNotify destroy_data,...)5443 gnome_keyring_delete_password (const GnomeKeyringPasswordSchema* schema,
5444 GnomeKeyringOperationDoneCallback callback,
5445 gpointer data, GDestroyNotify destroy_data, ...)
5446 {
5447 GkrOperation *op;
5448 va_list va;
5449
5450 g_return_val_if_fail (schema, NULL);
5451 g_return_val_if_fail (callback, NULL);
5452
5453 gkr_init ();
5454
5455 va_start (va, destroy_data);
5456 op = delete_password_va_start (schema, va, callback, data, destroy_data);
5457 va_end (va);
5458
5459 return gkr_operation_pending_and_unref (op);
5460 }
5461
5462 /**
5463 * gnome_keyring_delete_password_sync: (skip)
5464 * @schema: The password schema.
5465 * @...: The variable argument list should contain pairs of a) The attribute name as a null
5466 * terminated string, followed by b) attribute value, either a character string,
5467 * or 32-bit unsigned int, as defined in the password @schema. The list of attribtues
5468 * should be terminated with a %NULL.
5469 *
5470 * Delete a password that matches a given set of attributes.
5471 *
5472 * Attributes which identify this password must be passed as additional
5473 * arguments. Attributes passed must be defined in the schema.
5474 *
5475 * This function may block for an unspecified period. If your application must
5476 * remain responsive to the user, then use gnome_keyring_delete_password().
5477 *
5478 * Another more complex way to find items in the keyrings is using
5479 * gnome_keyring_item_delete_sync().
5480 *
5481 * Return value: %GNOME_KEYRING_RESULT_OK if the operation was succcessful or
5482 * an error result otherwise.
5483 *
5484 * Since: 2.22
5485 *
5486 * Deprecated: Use secret_password_clear_sync() instead.
5487 **/
5488 GnomeKeyringResult
gnome_keyring_delete_password_sync(const GnomeKeyringPasswordSchema * schema,...)5489 gnome_keyring_delete_password_sync (const GnomeKeyringPasswordSchema* schema, ...)
5490 {
5491 GkrOperation *op;
5492 va_list va;
5493
5494 g_return_val_if_fail (schema, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
5495
5496 gkr_init ();
5497
5498 va_start (va, schema);
5499 op = delete_password_va_start (schema, va, gkr_callback_empty, NULL, NULL);
5500 va_end (va);
5501
5502 return gkr_operation_block_and_unref (op);
5503 }
5504