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