1 /* libsecret - GLib wrapper for Secret Service
3 * Copyright 2011 Collabora Ltd.
4 * Copyright 2012 Red Hat Inc.
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 2.1 of the licence or (at
9 * your option) any later version.
11 * See the included COPYING file for more information.
13 * Author: Stef Walter <stefw@gnome.org>
18 #include "secret-collection.h"
19 #include "secret-dbus-generated.h"
20 #include "secret-item.h"
21 #include "secret-paths.h"
22 #include "secret-private.h"
23 #include "secret-service.h"
24 #include "secret-types.h"
25 #include "secret-value.h"
27 #include <glib/gi18n-lib.h>
31 * @SECRET_SEARCH_NONE: no flags
32 * @SECRET_SEARCH_ALL: all the items matching the search will be returned, instead of just the first one
33 * @SECRET_SEARCH_UNLOCK: unlock locked items while searching
34 * @SECRET_SEARCH_LOAD_SECRETS: while searching load secrets for items that are not locked
36 * Various flags to be used with secret_service_search() and secret_service_search_sync().
40 SecretService *service;
41 GCancellable *cancellable;
46 SecretSearchFlags flags;
51 search_closure_free (gpointer data)
53 SearchClosure *closure = data;
54 g_object_unref (closure->service);
55 g_clear_object (&closure->cancellable);
56 g_hash_table_unref (closure->items);
57 g_variant_unref (closure->attributes);
58 g_strfreev (closure->unlocked);
59 g_strfreev (closure->locked);
60 g_slice_free (SearchClosure, closure);
64 search_closure_take_item (SearchClosure *closure,
67 const gchar *path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (item));
68 g_hash_table_insert (closure->items, (gpointer)path, item);
72 search_closure_build_items (SearchClosure *closure,
75 GList *results = NULL;
79 for (i = 0; paths[i]; i++) {
80 item = g_hash_table_lookup (closure->items, paths[i]);
82 results = g_list_prepend (results, g_object_ref (item));
85 return g_list_reverse (results);
89 on_search_secrets (GObject *source,
93 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
95 /* Note that we ignore any unlock failure */
96 secret_item_load_secrets_finish (result, NULL);
98 g_simple_async_result_complete (async);
99 g_object_unref (async);
103 on_search_unlocked (GObject *source,
104 GAsyncResult *result,
107 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
108 SearchClosure *search = g_simple_async_result_get_op_res_gpointer (async);
111 /* Note that we ignore any unlock failure */
112 secret_service_unlock_finish (search->service, result, NULL, NULL);
114 /* If loading secrets ... locked items automatically ignored */
115 if (search->flags & SECRET_SEARCH_LOAD_SECRETS) {
116 items = g_hash_table_get_values (search->items);
117 secret_item_load_secrets (items, search->cancellable,
118 on_search_secrets, g_object_ref (async));
121 /* No additional options, just complete */
123 g_simple_async_result_complete (async);
126 g_object_unref (async);
130 secret_search_unlock_load_or_complete (GSimpleAsyncResult *async,
131 SearchClosure *search)
135 /* If unlocking then unlock all the locked items */
136 if (search->flags & SECRET_SEARCH_UNLOCK) {
137 items = search_closure_build_items (search, search->locked);
138 secret_service_unlock (search->service, items, search->cancellable,
139 on_search_unlocked, g_object_ref (async));
140 g_list_free_full (items, g_object_unref);
142 /* If loading secrets ... locked items automatically ignored */
143 } else if (search->flags & SECRET_SEARCH_LOAD_SECRETS) {
144 items = g_hash_table_get_values (search->items);
145 secret_item_load_secrets (items, search->cancellable,
146 on_search_secrets, g_object_ref (async));
149 /* No additional options, just complete */
151 g_simple_async_result_complete (async);
156 on_search_loaded (GObject *source,
157 GAsyncResult *result,
160 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
161 SearchClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
162 GError *error = NULL;
167 item = secret_item_new_for_dbus_path_finish (result, &error);
169 g_simple_async_result_take_error (res, error);
172 search_closure_take_item (closure, item);
174 /* We're done loading, lets go to the next step */
175 if (closure->loading == 0)
176 secret_search_unlock_load_or_complete (res, closure);
178 g_object_unref (res);
182 search_load_item_async (SecretService *self,
183 GSimpleAsyncResult *res,
184 SearchClosure *closure,
189 item = _secret_service_find_item_instance (self, path);
191 secret_item_new_for_dbus_path (self, path, SECRET_ITEM_NONE, closure->cancellable,
192 on_search_loaded, g_object_ref (res));
195 search_closure_take_item (closure, item);
200 on_search_paths (GObject *source,
201 GAsyncResult *result,
204 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
205 SearchClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
206 SecretService *self = closure->service;
207 GError *error = NULL;
212 secret_service_search_for_dbus_paths_finish (self, result, &closure->unlocked,
213 &closure->locked, &error);
216 if (closure->flags & SECRET_SEARCH_ALL)
220 for (i = 0; count < want && closure->unlocked[i] != NULL; i++, count++)
221 search_load_item_async (self, res, closure, closure->unlocked[i]);
222 for (i = 0; count < want && closure->locked[i] != NULL; i++, count++)
223 search_load_item_async (self, res, closure, closure->locked[i]);
225 /* No items loading, complete operation now */
226 if (closure->loading == 0)
227 secret_search_unlock_load_or_complete (res, closure);
230 g_simple_async_result_take_error (res, error);
231 g_simple_async_result_complete (res);
234 g_object_unref (res);
238 on_search_service (GObject *source,
239 GAsyncResult *result,
242 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
243 SearchClosure *search = g_simple_async_result_get_op_res_gpointer (async);
244 GError *error = NULL;
246 search->service = secret_service_get_finish (result, &error);
248 _secret_service_search_for_paths_variant (search->service, search->attributes,
249 search->cancellable, on_search_paths,
250 g_object_ref (async));
253 g_simple_async_result_take_error (async, error);
254 g_simple_async_result_complete (async);
257 g_object_unref (async);
261 * secret_service_search:
262 * @service: (allow-none): the secret service
263 * @schema: (allow-none): the schema for the attributes
264 * @attributes: (element-type utf8 utf8): search for items matching these attributes
265 * @flags: search option flags
266 * @cancellable: optional cancellation object
267 * @callback: called when the operation completes
268 * @user_data: data to pass to the callback
270 * Search for items matching the @attributes. All collections are searched.
271 * The @attributes should be a table of string keys and string values.
273 * If @service is NULL, then secret_service_get() will be called to get
274 * the default #SecretService proxy.
276 * If %SECRET_SEARCH_ALL is set in @flags, then all the items matching the
277 * search will be returned. Otherwise only the first item will be returned.
278 * This is almost always the unlocked item that was most recently stored.
280 * If %SECRET_SEARCH_UNLOCK is set in @flags, then items will be unlocked
281 * if necessary. In either case, locked and unlocked items will match the
282 * search and be returned. If the unlock fails, the search does not fail.
284 * If %SECRET_SEARCH_LOAD_SECRETS is set in @flags, then the items will have
285 * their secret values loaded and available via secret_item_get_secret().
287 * This function returns immediately and completes asynchronously.
290 secret_service_search (SecretService *service,
291 const SecretSchema *schema,
292 GHashTable *attributes,
293 SecretSearchFlags flags,
294 GCancellable *cancellable,
295 GAsyncReadyCallback callback,
298 GSimpleAsyncResult *res;
299 SearchClosure *closure;
300 const gchar *schema_name = NULL;
302 g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service));
303 g_return_if_fail (attributes != NULL);
304 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
306 /* Warnings raised already */
307 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
310 if (schema != NULL && !(schema->flags & SECRET_SCHEMA_DONT_MATCH_NAME))
311 schema_name = schema->name;
313 res = g_simple_async_result_new (G_OBJECT (service), callback, user_data,
314 secret_service_search);
315 closure = g_slice_new0 (SearchClosure);
316 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
317 closure->items = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
318 closure->flags = flags;
319 closure->attributes = _secret_attributes_to_variant (attributes, schema_name);
320 g_variant_ref_sink (closure->attributes);
321 g_simple_async_result_set_op_res_gpointer (res, closure, search_closure_free);
324 closure->service = g_object_ref (service);
325 _secret_service_search_for_paths_variant (closure->service, closure->attributes,
326 closure->cancellable, on_search_paths,
330 secret_service_get (SECRET_SERVICE_NONE, cancellable,
331 on_search_service, g_object_ref (res));
334 g_object_unref (res);
338 * secret_service_search_finish:
339 * @service: (allow-none): the secret service
340 * @result: asynchronous result passed to callback
341 * @error: location to place error on failure
343 * Complete asynchronous operation to search for items.
345 * Returns: (transfer full) (element-type Secret.Item):
346 * a list of items that matched the search
349 secret_service_search_finish (SecretService *service,
350 GAsyncResult *result,
353 GSimpleAsyncResult *res;
354 SearchClosure *closure;
357 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), NULL);
358 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
359 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service),
360 secret_service_search), NULL);
362 res = G_SIMPLE_ASYNC_RESULT (result);
364 if (_secret_util_propagate_error (res, error))
367 closure = g_simple_async_result_get_op_res_gpointer (res);
368 if (closure->unlocked)
369 items = search_closure_build_items (closure, closure->unlocked);
371 items = g_list_concat (items, search_closure_build_items (closure, closure->locked));
376 service_load_items_sync (SecretService *service,
377 GCancellable *cancellable,
387 for (i = 0; *have < want && paths[i] != NULL; i++) {
388 item = _secret_service_find_item_instance (service, paths[i]);
390 item = secret_item_new_for_dbus_path_sync (service, paths[i], SECRET_ITEM_NONE,
396 *items = g_list_prepend (*items, item);
405 * secret_service_search_sync:
406 * @service: (allow-none): the secret service
407 * @schema: (allow-none): the schema for the attributes
408 * @attributes: (element-type utf8 utf8): search for items matching these attributes
409 * @flags: search option flags
410 * @cancellable: optional cancellation object
411 * @error: location to place error on failure
413 * Search for items matching the @attributes. All collections are searched.
414 * The @attributes should be a table of string keys and string values.
416 * If @service is NULL, then secret_service_get_sync() will be called to get
417 * the default #SecretService proxy.
419 * If %SECRET_SEARCH_ALL is set in @flags, then all the items matching the
420 * search will be returned. Otherwise only the first item will be returned.
421 * This is almost always the unlocked item that was most recently stored.
423 * If %SECRET_SEARCH_UNLOCK is set in @flags, then items will be unlocked
424 * if necessary. In either case, locked and unlocked items will match the
425 * search and be returned. If the unlock fails, the search does not fail.
427 * If %SECRET_SEARCH_LOAD_SECRETS is set in @flags, then the items' secret
428 * values will be loaded for any unlocked items. Loaded item secret values
429 * are available via secret_item_get_secret(). If the load of a secret values
432 * This function may block indefinetely. Use the asynchronous version
433 * in user interface threads.
435 * Returns: (transfer full) (element-type Secret.Item):
436 * a list of items that matched the search
439 secret_service_search_sync (SecretService *service,
440 const SecretSchema *schema,
441 GHashTable *attributes,
442 SecretSearchFlags flags,
443 GCancellable *cancellable,
446 gchar **unlocked_paths = NULL;
447 gchar **locked_paths = NULL;
449 GList *locked = NULL;
450 GList *unlocked = NULL;
455 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), NULL);
456 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
457 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
459 /* Warnings raised already */
460 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
463 if (service == NULL) {
464 service = secret_service_get_sync (SECRET_SERVICE_NONE, cancellable, error);
468 g_object_ref (service);
471 if (!secret_service_search_for_dbus_paths_sync (service, schema, attributes, cancellable,
472 &unlocked_paths, &locked_paths, error)) {
473 g_object_unref (service);
480 if (flags & SECRET_SEARCH_ALL)
484 /* Remember, we're adding to the list backwards */
486 if (unlocked_paths) {
487 ret = service_load_items_sync (service, cancellable, unlocked_paths,
488 &unlocked, want, &have, error);
491 if (ret && locked_paths) {
492 ret = service_load_items_sync (service, cancellable, locked_paths,
493 &locked, want, &have, error);
496 g_strfreev (unlocked_paths);
497 g_strfreev (locked_paths);
500 g_list_free_full (unlocked, g_object_unref);
501 g_list_free_full (locked, g_object_unref);
502 g_object_unref (service);
506 /* The lists are backwards at this point ... */
507 items = g_list_concat (items, g_list_copy (locked));
508 items = g_list_concat (items, g_list_copy (unlocked));
509 items = g_list_reverse (items);
511 if (flags & SECRET_SEARCH_UNLOCK)
512 secret_service_unlock_sync (service, locked, cancellable, NULL, NULL);
514 if (flags & SECRET_SEARCH_LOAD_SECRETS)
515 secret_item_load_secrets_sync (items, NULL, NULL);
517 g_list_free (locked);
518 g_list_free (unlocked);
519 g_object_unref (service);
524 _secret_service_decode_get_secrets_first (SecretService *self,
527 SecretSession *session;
528 SecretValue *value = NULL;
533 g_variant_get (out, "(a{o(oayays)})", &iter);
534 while (g_variant_iter_next (iter, "{&o@(oayays)}", &path, &variant)) {
535 session = _secret_service_get_session (self);
536 value = _secret_session_decode_secret (session, variant);
537 g_variant_unref (variant);
540 g_variant_iter_free (iter);
545 _secret_service_decode_get_secrets_all (SecretService *self,
548 SecretSession *session;
555 session = _secret_service_get_session (self);
556 values = g_hash_table_new_full (g_str_hash, g_str_equal,
557 g_free, secret_value_unref);
558 g_variant_get (out, "(a{o(oayays)})", &iter);
559 while (g_variant_iter_loop (iter, "{o@(oayays)}", &path, &variant)) {
560 value = _secret_session_decode_secret (session, variant);
562 g_hash_table_insert (values, g_strdup (path), value);
564 g_variant_iter_free (iter);
569 GCancellable *cancellable;
578 xlock_closure_free (gpointer data)
580 XlockClosure *closure = data;
581 if (closure->cancellable)
582 g_object_unref (closure->cancellable);
583 g_ptr_array_free (closure->paths, TRUE);
584 g_strfreev (closure->xlocked);
585 g_hash_table_unref (closure->objects);
586 g_slice_free (XlockClosure, closure);
590 on_xlock_paths (GObject *source,
591 GAsyncResult *result,
594 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
595 XlockClosure *xlock = g_simple_async_result_get_op_res_gpointer (async);
598 GError *error = NULL;
601 xlock->count = _secret_service_xlock_paths_finish (SECRET_SERVICE (source), result,
602 &xlock->xlocked, &error);
606 * After a lock or unlock we want the Locked property to immediately
607 * reflect the new state, and not have to wait for a PropertiesChanged
608 * signal to be processed later.
611 lockval = g_variant_ref_sink (g_variant_new_boolean (xlock->locking));
612 for (i = 0; xlock->xlocked[i] != NULL; i++) {
613 object = g_hash_table_lookup (xlock->objects, xlock->xlocked[i]);
615 g_dbus_proxy_set_cached_property (object, "Locked", lockval);
617 g_variant_unref (lockval);
620 g_simple_async_result_take_error (async, error);
623 g_simple_async_result_complete (async);
624 g_object_unref (async);
628 on_xlock_service (GObject *source,
629 GAsyncResult *result,
632 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
633 XlockClosure *xlock = g_simple_async_result_get_op_res_gpointer (async);
634 GError *error = NULL;
635 SecretService *service;
637 service = secret_service_get_finish (result, &error);
639 _secret_service_xlock_paths_async (service, xlock->locking ? "Lock" : "Unlock",
640 (const gchar **)xlock->paths->pdata,
641 xlock->cancellable, on_xlock_paths,
642 g_object_ref (async));
643 g_object_unref (service);
646 g_simple_async_result_take_error (async, error);
647 g_simple_async_result_complete (async);
650 g_object_unref (async);
654 service_xlock_async (SecretService *service,
657 GCancellable *cancellable,
658 GAsyncReadyCallback callback,
661 GSimpleAsyncResult *async;
666 async = g_simple_async_result_new (G_OBJECT (service), callback, user_data,
667 service_xlock_async);
668 xlock = g_slice_new0 (XlockClosure);
669 xlock->objects = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
670 xlock->locking = locking;
671 xlock->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
672 xlock->paths = g_ptr_array_new ();
674 for (l = objects; l != NULL; l = g_list_next (l)) {
675 path = g_dbus_proxy_get_object_path (l->data);
676 g_ptr_array_add (xlock->paths, (gpointer)path);
677 g_hash_table_insert (xlock->objects, g_strdup (path), g_object_ref (l->data));
679 g_ptr_array_add (xlock->paths, NULL);
681 g_simple_async_result_set_op_res_gpointer (async, xlock, xlock_closure_free);
683 if (service == NULL) {
684 secret_service_get (SECRET_SERVICE_NONE, cancellable,
685 on_xlock_service, g_object_ref (async));
687 _secret_service_xlock_paths_async (service, xlock->locking ? "Lock" : "Unlock",
688 (const gchar **)xlock->paths->pdata,
689 xlock->cancellable, on_xlock_paths,
690 g_object_ref (async));
693 g_object_unref (async);
697 service_xlock_finish (SecretService *service,
698 GAsyncResult *result,
702 GSimpleAsyncResult *async;
707 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service),
708 service_xlock_async), -1);
710 async = G_SIMPLE_ASYNC_RESULT (result);
711 if (_secret_util_propagate_error (async, error))
714 xlock = g_simple_async_result_get_op_res_gpointer (async);
717 for (i = 0; xlock->xlocked[i] != NULL; i++) {
718 object = g_hash_table_lookup (xlock->objects, xlock->xlocked[i]);
720 *xlocked = g_list_prepend (*xlocked, g_object_ref (object));
728 * secret_service_lock:
729 * @service: (allow-none): the secret service
730 * @objects: (element-type Gio.DBusProxy): the items or collections to lock
731 * @cancellable: optional cancellation object
732 * @callback: called when the operation completes
733 * @user_data: data to pass to the callback
735 * Lock items or collections in the secret service.
737 * The secret service may not be able to lock items individually, and may
738 * lock an entire collection instead.
740 * If @service is NULL, then secret_service_get() will be called to get
741 * the default #SecretService proxy.
743 * This method returns immediately and completes asynchronously. The secret
744 * service may prompt the user. secret_service_prompt() will be used to handle
745 * any prompts that show up.
748 secret_service_lock (SecretService *service,
750 GCancellable *cancellable,
751 GAsyncReadyCallback callback,
754 g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service));
755 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
757 service_xlock_async (service, TRUE, objects, cancellable, callback, user_data);
761 * secret_service_lock_finish:
762 * @service: (allow-none): the secret service
763 * @result: asynchronous result passed to the callback
764 * @locked: (out) (element-type Gio.DBusProxy) (transfer full) (allow-none):
765 * location to place list of items or collections that were locked
766 * @error: location to place an error on failure
768 * Complete asynchronous operation to lock items or collections in the secret
771 * The secret service may not be able to lock items individually, and may
772 * lock an entire collection instead.
774 * Returns: the number of items or collections that were locked
777 secret_service_lock_finish (SecretService *service,
778 GAsyncResult *result,
782 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), -1);
783 g_return_val_if_fail (error == NULL || *error == NULL, -1);
785 return service_xlock_finish (service, result, locked, error);
789 * secret_service_lock_sync:
790 * @service: (allow-none): the secret service
791 * @objects: (element-type Gio.DBusProxy): the items or collections to lock
792 * @cancellable: optional cancellation object
793 * @locked: (out) (element-type Gio.DBusProxy) (transfer full) (allow-none):
794 * location to place list of items or collections that were locked
795 * @error: location to place an error on failure
797 * Lock items or collections in the secret service.
799 * The secret service may not be able to lock items individually, and may
800 * lock an entire collection instead.
802 * If @service is NULL, then secret_service_get_sync() will be called to get
803 * the default #SecretService proxy.
805 * This method may block indefinitely and should not be used in user
806 * interface threads. The secret service may prompt the user.
807 * secret_service_prompt() will be used to handle any prompts that show up.
809 * Returns: the number of items or collections that were locked
812 secret_service_lock_sync (SecretService *service,
814 GCancellable *cancellable,
821 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), -1);
822 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1);
823 g_return_val_if_fail (error == NULL || *error == NULL, -1);
825 sync = _secret_sync_new ();
826 g_main_context_push_thread_default (sync->context);
828 secret_service_lock (service, objects, cancellable,
829 _secret_sync_on_result, sync);
831 g_main_loop_run (sync->loop);
833 count = secret_service_lock_finish (service, sync->result, locked, error);
835 g_main_context_pop_thread_default (sync->context);
836 _secret_sync_free (sync);
842 * secret_service_unlock:
843 * @service: (allow-none): the secret service
844 * @objects: (element-type Gio.DBusProxy): the items or collections to unlock
845 * @cancellable: optional cancellation object
846 * @callback: called when the operation completes
847 * @user_data: data to pass to the callback
849 * Unlock items or collections in the secret service.
851 * The secret service may not be able to unlock items individually, and may
852 * unlock an entire collection instead.
854 * If @service is NULL, then secret_service_get() will be called to get
855 * the default #SecretService proxy.
857 * This method may block indefinitely and should not be used in user
858 * interface threads. The secret service may prompt the user.
859 * secret_service_prompt() will be used to handle any prompts that show up.
862 secret_service_unlock (SecretService *service,
864 GCancellable *cancellable,
865 GAsyncReadyCallback callback,
868 g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service));
869 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
871 service_xlock_async (service, FALSE, objects, cancellable, callback, user_data);
875 * secret_service_unlock_finish:
876 * @service: (allow-none): the secret service
877 * @result: asynchronous result passed to the callback
878 * @unlocked: (out) (element-type Gio.DBusProxy) (transfer full) (allow-none):
879 * location to place list of items or collections that were unlocked
880 * @error: location to place an error on failure
882 * Complete asynchronous operation to unlock items or collections in the secret
885 * The secret service may not be able to unlock items individually, and may
886 * unlock an entire collection instead.
888 * Returns: the number of items or collections that were unlocked
891 secret_service_unlock_finish (SecretService *service,
892 GAsyncResult *result,
896 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), -1);
897 g_return_val_if_fail (error == NULL || *error == NULL, -1);
899 return service_xlock_finish (service, result, unlocked, error);
903 * secret_service_unlock_sync:
904 * @service: (allow-none): the secret service
905 * @objects: (element-type Gio.DBusProxy): the items or collections to unlock
906 * @cancellable: optional cancellation object
907 * @unlocked: (out) (element-type Gio.DBusProxy) (transfer full) (allow-none):
908 * location to place list of items or collections that were unlocked
909 * @error: location to place an error on failure
911 * Unlock items or collections in the secret service.
913 * The secret service may not be able to unlock items individually, and may
914 * unlock an entire collection instead.
916 * If @service is NULL, then secret_service_get_sync() will be called to get
917 * the default #SecretService proxy.
919 * This method may block indefinitely and should not be used in user
920 * interface threads. The secret service may prompt the user.
921 * secret_service_prompt() will be used to handle any prompts that show up.
923 * Returns: the number of items or collections that were unlocked
926 secret_service_unlock_sync (SecretService *service,
928 GCancellable *cancellable,
935 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), -1);
936 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1);
937 g_return_val_if_fail (error == NULL || *error == NULL, -1);
939 sync = _secret_sync_new ();
940 g_main_context_push_thread_default (sync->context);
942 secret_service_unlock (service, objects, cancellable,
943 _secret_sync_on_result, sync);
945 g_main_loop_run (sync->loop);
947 count = secret_service_unlock_finish (service, sync->result, unlocked, error);
949 g_main_context_pop_thread_default (sync->context);
950 _secret_sync_free (sync);
956 GCancellable *cancellable;
957 gchar *collection_path;
959 GHashTable *properties;
960 gboolean created_collection;
961 gboolean unlocked_collection;
965 store_closure_free (gpointer data)
967 StoreClosure *store = data;
968 if (store->cancellable)
969 g_object_unref (store->cancellable);
970 g_free (store->collection_path);
971 secret_value_unref (store->value);
972 g_hash_table_unref (store->properties);
973 g_slice_free (StoreClosure, store);
977 on_store_create (GObject *source,
978 GAsyncResult *result,
982 on_store_keyring (GObject *source,
983 GAsyncResult *result,
986 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
987 StoreClosure *store = g_simple_async_result_get_op_res_gpointer (async);
988 SecretService *service = SECRET_SERVICE (source);
989 GError *error = NULL;
992 path = secret_service_create_collection_dbus_path_finish (service, result, &error);
994 store->created_collection = TRUE;
995 secret_service_create_item_dbus_path (service, store->collection_path,
996 store->properties, store->value,
997 SECRET_ITEM_CREATE_REPLACE, store->cancellable,
998 on_store_create, g_object_ref (async));
1000 g_simple_async_result_take_error (async, error);
1001 g_simple_async_result_complete (async);
1004 g_object_unref (async);
1009 on_store_unlock (GObject *source,
1010 GAsyncResult *result,
1013 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
1014 StoreClosure *store = g_simple_async_result_get_op_res_gpointer (async);
1015 SecretService *service = SECRET_SERVICE (source);
1016 GError *error = NULL;
1018 secret_service_unlock_dbus_paths_finish (service, result, NULL, &error);
1019 if (error == NULL) {
1020 store->unlocked_collection = TRUE;
1021 secret_service_create_item_dbus_path (service, store->collection_path,
1022 store->properties, store->value,
1023 SECRET_ITEM_CREATE_REPLACE, store->cancellable,
1024 on_store_create, g_object_ref (async));
1026 g_simple_async_result_take_error (async, error);
1027 g_simple_async_result_complete (async);
1030 g_object_unref (async);
1034 on_store_create (GObject *source,
1035 GAsyncResult *result,
1038 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
1039 StoreClosure *store = g_simple_async_result_get_op_res_gpointer (async);
1040 SecretService *service = SECRET_SERVICE (source);
1041 GError *error = NULL;
1042 GHashTable *properties;
1044 _secret_service_create_item_dbus_path_finish_raw (result, &error);
1047 * This happens when the collection doesn't exist. If the collection is
1048 * the default alias, we should try and create it
1051 if (!store->created_collection &&
1052 (g_error_matches (error, SECRET_ERROR, SECRET_ERROR_NO_SUCH_OBJECT) ||
1053 g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) &&
1054 g_strcmp0 (store->collection_path, SECRET_ALIAS_PREFIX "default") == 0) {
1055 properties = _secret_collection_properties_new (_("Default keyring"));
1056 secret_service_create_collection_dbus_path (service, properties, "default",
1057 SECRET_COLLECTION_CREATE_NONE, store->cancellable,
1058 on_store_keyring, g_object_ref (async));
1059 g_hash_table_unref (properties);
1060 g_error_free (error);
1062 } else if (!store->unlocked_collection &&
1063 g_error_matches (error, SECRET_ERROR, SECRET_ERROR_IS_LOCKED)) {
1064 const gchar *paths[2] = { store->collection_path, NULL };
1065 secret_service_unlock_dbus_paths (service, paths, store->cancellable,
1066 on_store_unlock, g_object_ref (async));
1067 g_error_free (error);
1070 g_simple_async_result_take_error (async, error);
1071 g_simple_async_result_complete (async);
1074 g_object_unref (async);
1078 on_store_service (GObject *source,
1079 GAsyncResult *result,
1082 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
1083 StoreClosure *store = g_simple_async_result_get_op_res_gpointer (async);
1084 SecretService *service;
1085 GError *error = NULL;
1087 service = secret_service_get_finish (result, &error);
1088 if (error == NULL) {
1089 secret_service_create_item_dbus_path (service, store->collection_path,
1090 store->properties, store->value,
1091 SECRET_ITEM_CREATE_REPLACE, store->cancellable,
1092 on_store_create, g_object_ref (async));
1093 g_object_unref (service);
1096 g_simple_async_result_take_error (async, error);
1097 g_simple_async_result_complete (async);
1100 g_object_unref (async);
1104 * secret_service_store:
1105 * @service: (allow-none): the secret service
1106 * @schema: (allow-none): the schema to use to check attributes
1107 * @attributes: (element-type utf8 utf8): the attribute keys and values
1108 * @collection: (allow-none): a collection alias, or D-Bus object path of the collection where to store the secret
1109 * @label: label for the secret
1110 * @value: the secret value
1111 * @cancellable: optional cancellation object
1112 * @callback: called when the operation completes
1113 * @user_data: data to be passed to the callback
1115 * Store a secret value in the secret service.
1117 * The @attributes should be a set of key and value string pairs.
1119 * If the attributes match a secret item already stored in the collection, then
1120 * the item will be updated with these new values.
1122 * If @service is NULL, then secret_service_get() will be called to get
1123 * the default #SecretService proxy.
1125 * If @collection is not specified, then the default collection will be
1126 * used. Use #SECRET_COLLECTION_SESSION to store the password in the session
1127 * collection, which doesn't get stored across login sessions.
1129 * This method will return immediately and complete asynchronously.
1132 secret_service_store (SecretService *service,
1133 const SecretSchema *schema,
1134 GHashTable *attributes,
1135 const gchar *collection,
1138 GCancellable *cancellable,
1139 GAsyncReadyCallback callback,
1142 GSimpleAsyncResult *async;
1143 StoreClosure *store;
1144 const gchar *schema_name;
1147 g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service));
1148 g_return_if_fail (attributes != NULL);
1149 g_return_if_fail (label != NULL);
1150 g_return_if_fail (value != NULL);
1151 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1153 /* Warnings raised already */
1154 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, FALSE))
1157 async = g_simple_async_result_new (G_OBJECT (service), callback, user_data,
1158 secret_service_store);
1159 store = g_slice_new0 (StoreClosure);
1160 store->collection_path = _secret_util_collection_to_path (collection);
1161 store->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1162 store->value = secret_value_ref (value);
1163 store->properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
1164 (GDestroyNotify)g_variant_unref);
1166 propval = g_variant_new_string (label);
1167 g_hash_table_insert (store->properties,
1168 SECRET_ITEM_INTERFACE ".Label",
1169 g_variant_ref_sink (propval));
1171 /* Always store the schema name in the attributes */
1172 schema_name = (schema == NULL) ? NULL : schema->name;
1173 propval = _secret_attributes_to_variant (attributes, schema_name);
1174 g_hash_table_insert (store->properties,
1175 SECRET_ITEM_INTERFACE ".Attributes",
1176 g_variant_ref_sink (propval));
1178 g_simple_async_result_set_op_res_gpointer (async, store, store_closure_free);
1180 if (service == NULL) {
1181 secret_service_get (SECRET_SERVICE_OPEN_SESSION, cancellable,
1182 on_store_service, g_object_ref (async));
1185 secret_service_create_item_dbus_path (service, store->collection_path,
1186 store->properties, store->value,
1187 SECRET_ITEM_CREATE_REPLACE, store->cancellable,
1188 on_store_create, g_object_ref (async));
1191 g_object_unref (async);
1195 * secret_service_store_finish:
1196 * @service: (allow-none): the secret service
1197 * @result: the asynchronous result passed to the callback
1198 * @error: location to place an error on failure
1200 * Finish asynchronous operation to store a secret value in the secret service.
1202 * Returns: whether the storage was successful or not
1205 secret_service_store_finish (SecretService *service,
1206 GAsyncResult *result,
1209 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
1210 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service),
1211 secret_service_store), FALSE);
1212 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1214 if (_secret_util_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
1221 * secret_service_store_sync:
1222 * @service: (allow-none): the secret service
1223 * @schema: (allow-none): the schema for the attributes
1224 * @attributes: (element-type utf8 utf8): the attribute keys and values
1225 * @collection: (allow-none): a collection alias, or D-Bus object path of the collection where to store the secret
1226 * @label: label for the secret
1227 * @value: the secret value
1228 * @cancellable: optional cancellation object
1229 * @error: location to place an error on failure
1231 * Store a secret value in the secret service.
1233 * The @attributes should be a set of key and value string pairs.
1235 * If the attributes match a secret item already stored in the collection, then
1236 * the item will be updated with these new values.
1238 * If @collection is %NULL, then the default collection will be
1239 * used. Use #SECRET_COLLECTION_SESSION to store the password in the session
1240 * collection, which doesn't get stored across login sessions.
1242 * If @service is NULL, then secret_service_get_sync() will be called to get
1243 * the default #SecretService proxy.
1245 * This method may block indefinitely and should not be used in user interface
1248 * Returns: whether the storage was successful or not
1251 secret_service_store_sync (SecretService *service,
1252 const SecretSchema *schema,
1253 GHashTable *attributes,
1254 const gchar *collection,
1257 GCancellable *cancellable,
1263 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
1264 g_return_val_if_fail (attributes != NULL, FALSE);
1265 g_return_val_if_fail (label != NULL, FALSE);
1266 g_return_val_if_fail (value != NULL, FALSE);
1267 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1268 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1270 /* Warnings raised already */
1271 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, FALSE))
1274 sync = _secret_sync_new ();
1275 g_main_context_push_thread_default (sync->context);
1277 secret_service_store (service, schema, attributes, collection,
1278 label, value, cancellable, _secret_sync_on_result, sync);
1280 g_main_loop_run (sync->loop);
1282 ret = secret_service_store_finish (service, sync->result, error);
1284 g_main_context_pop_thread_default (sync->context);
1285 _secret_sync_free (sync);
1291 GVariant *attributes;
1293 GCancellable *cancellable;
1297 lookup_closure_free (gpointer data)
1299 LookupClosure *closure = data;
1300 g_variant_unref (closure->attributes);
1302 secret_value_unref (closure->value);
1303 g_clear_object (&closure->cancellable);
1304 g_slice_free (LookupClosure, closure);
1308 on_lookup_get_secret (GObject *source,
1309 GAsyncResult *result,
1312 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
1313 LookupClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
1314 SecretService *self = SECRET_SERVICE (source);
1315 GError *error = NULL;
1317 closure->value = secret_service_get_secret_for_dbus_path_finish (self, result, &error);
1319 g_simple_async_result_take_error (res, error);
1321 g_simple_async_result_complete (res);
1322 g_object_unref (res);
1326 on_lookup_unlocked (GObject *source,
1327 GAsyncResult *result,
1330 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
1331 LookupClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
1332 SecretService *self = SECRET_SERVICE (source);
1333 GError *error = NULL;
1334 gchar **unlocked = NULL;
1336 secret_service_unlock_dbus_paths_finish (SECRET_SERVICE (source),
1337 result, &unlocked, &error);
1338 if (error != NULL) {
1339 g_simple_async_result_take_error (res, error);
1340 g_simple_async_result_complete (res);
1342 } else if (unlocked && unlocked[0]) {
1343 secret_service_get_secret_for_dbus_path (self, unlocked[0],
1344 closure->cancellable,
1345 on_lookup_get_secret,
1346 g_object_ref (res));
1349 g_simple_async_result_complete (res);
1352 g_strfreev (unlocked);
1353 g_object_unref (res);
1357 on_lookup_searched (GObject *source,
1358 GAsyncResult *result,
1361 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
1362 LookupClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
1363 SecretService *self = SECRET_SERVICE (source);
1364 GError *error = NULL;
1365 gchar **unlocked = NULL;
1366 gchar **locked = NULL;
1368 secret_service_search_for_dbus_paths_finish (self, result, &unlocked, &locked, &error);
1369 if (error != NULL) {
1370 g_simple_async_result_take_error (res, error);
1371 g_simple_async_result_complete (res);
1373 } else if (unlocked && unlocked[0]) {
1374 secret_service_get_secret_for_dbus_path (self, unlocked[0],
1375 closure->cancellable,
1376 on_lookup_get_secret,
1377 g_object_ref (res));
1379 } else if (locked && locked[0]) {
1380 const gchar *paths[] = { locked[0], NULL };
1381 secret_service_unlock_dbus_paths (self, paths,
1382 closure->cancellable,
1384 g_object_ref (res));
1387 g_simple_async_result_complete (res);
1390 g_strfreev (unlocked);
1391 g_strfreev (locked);
1392 g_object_unref (res);
1396 on_lookup_service (GObject *source,
1397 GAsyncResult *result,
1400 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
1401 LookupClosure *lookup = g_simple_async_result_get_op_res_gpointer (async);
1402 SecretService *service;
1403 GError *error = NULL;
1405 service = secret_service_get_finish (result, &error);
1406 if (error == NULL) {
1407 _secret_service_search_for_paths_variant (service, lookup->attributes,
1408 lookup->cancellable,
1409 on_lookup_searched, g_object_ref (async));
1410 g_object_unref (service);
1413 g_simple_async_result_take_error (async, error);
1414 g_simple_async_result_complete (async);
1417 g_object_unref (async);
1421 * secret_service_lookup:
1422 * @service: (allow-none): the secret service
1423 * @schema: (allow-none): the schema for the attributes
1424 * @attributes: (element-type utf8 utf8): the attribute keys and values
1425 * @cancellable: optional cancellation object
1426 * @callback: called when the operation completes
1427 * @user_data: data to be passed to the callback
1429 * Lookup a secret value in the secret service.
1431 * The @attributes should be a set of key and value string pairs.
1433 * If @service is NULL, then secret_service_get() will be called to get
1434 * the default #SecretService proxy.
1436 * This method will return immediately and complete asynchronously.
1439 secret_service_lookup (SecretService *service,
1440 const SecretSchema *schema,
1441 GHashTable *attributes,
1442 GCancellable *cancellable,
1443 GAsyncReadyCallback callback,
1446 const gchar *schema_name = NULL;
1447 GSimpleAsyncResult *res;
1448 LookupClosure *closure;
1450 g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service));
1451 g_return_if_fail (attributes != NULL);
1452 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1454 /* Warnings raised already */
1455 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
1458 if (schema != NULL && !(schema->flags & SECRET_SCHEMA_DONT_MATCH_NAME))
1459 schema_name = schema->name;
1461 res = g_simple_async_result_new (G_OBJECT (service), callback, user_data,
1462 secret_service_lookup);
1463 closure = g_slice_new0 (LookupClosure);
1464 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1465 closure->attributes = _secret_attributes_to_variant (attributes, schema_name);
1466 g_variant_ref_sink (closure->attributes);
1467 g_simple_async_result_set_op_res_gpointer (res, closure, lookup_closure_free);
1469 if (service == NULL) {
1470 secret_service_get (SECRET_SERVICE_OPEN_SESSION, cancellable,
1471 on_lookup_service, g_object_ref (res));
1473 _secret_service_search_for_paths_variant (service, closure->attributes,
1474 closure->cancellable,
1475 on_lookup_searched, g_object_ref (res));
1478 g_object_unref (res);
1482 * secret_service_lookup_finish:
1483 * @service: (allow-none): the secret service
1484 * @result: the asynchronous result passed to the callback
1485 * @error: location to place an error on failure
1487 * Finish asynchronous operation to lookup a secret value in the secret service.
1489 * If no secret is found then %NULL is returned.
1491 * Returns: (transfer full): a newly allocated #SecretValue, which should be
1492 * released with secret_value_unref(), or %NULL if no secret found
1495 secret_service_lookup_finish (SecretService *service,
1496 GAsyncResult *result,
1499 GSimpleAsyncResult *res;
1500 LookupClosure *closure;
1503 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), NULL);
1504 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1505 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service),
1506 secret_service_lookup), NULL);
1508 res = G_SIMPLE_ASYNC_RESULT (result);
1509 if (_secret_util_propagate_error (res, error))
1512 closure = g_simple_async_result_get_op_res_gpointer (res);
1513 value = closure->value;
1514 closure->value = NULL;
1519 * secret_service_lookup_sync:
1520 * @service: (allow-none): the secret service
1521 * @schema: (allow-none): the schema for the attributes
1522 * @attributes: (element-type utf8 utf8): the attribute keys and values
1523 * @cancellable: optional cancellation object
1524 * @error: location to place an error on failure
1526 * Lookup a secret value in the secret service.
1528 * The @attributes should be a set of key and value string pairs.
1530 * If @service is NULL, then secret_service_get_sync() will be called to get
1531 * the default #SecretService proxy.
1533 * This method may block indefinitely and should not be used in user interface
1536 * Returns: (transfer full): a newly allocated #SecretValue, which should be
1537 * released with secret_value_unref(), or %NULL if no secret found
1540 secret_service_lookup_sync (SecretService *service,
1541 const SecretSchema *schema,
1542 GHashTable *attributes,
1543 GCancellable *cancellable,
1549 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), NULL);
1550 g_return_val_if_fail (attributes != NULL, NULL);
1551 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
1553 /* Warnings raised already */
1554 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
1557 sync = _secret_sync_new ();
1558 g_main_context_push_thread_default (sync->context);
1560 secret_service_lookup (service, schema, attributes, cancellable,
1561 _secret_sync_on_result, sync);
1563 g_main_loop_run (sync->loop);
1565 value = secret_service_lookup_finish (service, sync->result, error);
1567 g_main_context_pop_thread_default (sync->context);
1568 _secret_sync_free (sync);
1574 GCancellable *cancellable;
1575 SecretService *service;
1576 GVariant *attributes;
1582 delete_closure_free (gpointer data)
1584 DeleteClosure *closure = data;
1585 if (closure->service)
1586 g_object_unref (closure->service);
1587 g_variant_unref (closure->attributes);
1588 g_clear_object (&closure->cancellable);
1589 g_slice_free (DeleteClosure, closure);
1593 on_delete_password_complete (GObject *source,
1594 GAsyncResult *result,
1597 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
1598 DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
1599 GError *error = NULL;
1602 closure->deleting--;
1604 deleted = _secret_service_delete_path_finish (SECRET_SERVICE (source), result, &error);
1606 g_simple_async_result_take_error (res, error);
1610 if (closure->deleting <= 0)
1611 g_simple_async_result_complete (res);
1613 g_object_unref (res);
1617 on_delete_searched (GObject *source,
1618 GAsyncResult *result,
1621 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
1622 DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
1623 GError *error = NULL;
1624 gchar **unlocked = NULL;
1627 secret_service_search_for_dbus_paths_finish (SECRET_SERVICE (source), result, &unlocked, NULL, &error);
1628 if (error == NULL) {
1629 for (i = 0; unlocked[i] != NULL; i++) {
1630 _secret_service_delete_path (closure->service, unlocked[i], TRUE,
1631 closure->cancellable,
1632 on_delete_password_complete,
1633 g_object_ref (res));
1634 closure->deleting++;
1637 if (closure->deleting == 0)
1638 g_simple_async_result_complete (res);
1640 g_simple_async_result_take_error (res, error);
1641 g_simple_async_result_complete (res);
1644 g_strfreev (unlocked);
1645 g_object_unref (res);
1649 on_delete_service (GObject *source,
1650 GAsyncResult *result,
1653 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
1654 DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (async);
1655 GError *error = NULL;
1657 closure->service = secret_service_get_finish (result, &error);
1658 if (error == NULL) {
1659 _secret_service_search_for_paths_variant (closure->service, closure->attributes,
1660 closure->cancellable,
1661 on_delete_searched, g_object_ref (async));
1664 g_simple_async_result_take_error (async, error);
1665 g_simple_async_result_complete (async);
1668 g_object_unref (async);
1672 * secret_service_clear:
1673 * @service: (allow-none): the secret service
1674 * @schema: (allow-none): the schema for the attributes
1675 * @attributes: (element-type utf8 utf8): the attribute keys and values
1676 * @cancellable: optional cancellation object
1677 * @callback: called when the operation completes
1678 * @user_data: data to be passed to the callback
1680 * Remove unlocked items which match the attributes from the secret service.
1682 * The @attributes should be a set of key and value string pairs.
1684 * If @service is NULL, then secret_service_get() will be called to get
1685 * the default #SecretService proxy.
1687 * This method will return immediately and complete asynchronously.
1690 secret_service_clear (SecretService *service,
1691 const SecretSchema *schema,
1692 GHashTable *attributes,
1693 GCancellable *cancellable,
1694 GAsyncReadyCallback callback,
1697 const gchar *schema_name = NULL;
1698 GSimpleAsyncResult *res;
1699 DeleteClosure *closure;
1701 g_return_if_fail (service == NULL || SECRET_SERVICE (service));
1702 g_return_if_fail (attributes != NULL);
1703 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1705 /* Warnings raised already */
1706 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
1709 if (schema != NULL && !(schema->flags & SECRET_SCHEMA_DONT_MATCH_NAME))
1710 schema_name = schema->name;
1712 res = g_simple_async_result_new (G_OBJECT (service), callback, user_data,
1713 secret_service_clear);
1714 closure = g_slice_new0 (DeleteClosure);
1715 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1716 closure->attributes = _secret_attributes_to_variant (attributes, schema_name);
1717 g_variant_ref_sink (closure->attributes);
1718 g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free);
1720 /* A double check to make sure we don't delete everything, should have been checked earlier */
1721 g_assert (g_variant_n_children (closure->attributes) > 0);
1723 if (service == NULL) {
1724 secret_service_get (SECRET_SERVICE_NONE, cancellable,
1725 on_delete_service, g_object_ref (res));
1727 closure->service = g_object_ref (service);
1728 _secret_service_search_for_paths_variant (closure->service, closure->attributes,
1729 closure->cancellable,
1730 on_delete_searched, g_object_ref (res));
1733 g_object_unref (res);
1737 * secret_service_clear_finish:
1738 * @service: (allow-none): the secret service
1739 * @result: the asynchronous result passed to the callback
1740 * @error: location to place an error on failure
1742 * Finish asynchronous operation to remove items from the secret
1745 * Returns: whether items were removed or not
1748 secret_service_clear_finish (SecretService *service,
1749 GAsyncResult *result,
1752 GSimpleAsyncResult *res;
1753 DeleteClosure *closure;
1755 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
1756 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1757 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service),
1758 secret_service_clear), FALSE);
1760 res = G_SIMPLE_ASYNC_RESULT (result);
1761 if (_secret_util_propagate_error (res, error))
1764 closure = g_simple_async_result_get_op_res_gpointer (res);
1765 return closure->deleted > 0;
1769 * secret_service_clear_sync:
1770 * @service: (allow-none): the secret service
1771 * @schema: (allow-none): the schema for the attributes
1772 * @attributes: (element-type utf8 utf8): the attribute keys and values
1773 * @cancellable: optional cancellation object
1774 * @error: location to place an error on failure
1776 * Remove unlocked items which match the attributes from the secret service.
1778 * The @attributes should be a set of key and value string pairs.
1780 * If @service is NULL, then secret_service_get_sync() will be called to get
1781 * the default #SecretService proxy.
1783 * This method may block indefinitely and should not be used in user interface
1786 * Returns: whether items were removed or not
1789 secret_service_clear_sync (SecretService *service,
1790 const SecretSchema *schema,
1791 GHashTable *attributes,
1792 GCancellable *cancellable,
1798 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
1799 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1800 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1802 /* Warnings raised already */
1803 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
1806 sync = _secret_sync_new ();
1807 g_main_context_push_thread_default (sync->context);
1809 secret_service_clear (service, schema, attributes, cancellable,
1810 _secret_sync_on_result, sync);
1812 g_main_loop_run (sync->loop);
1814 result = secret_service_clear_finish (service, sync->result, error);
1816 g_main_context_pop_thread_default (sync->context);
1817 _secret_sync_free (sync);
1823 GCancellable *cancellable;
1825 gchar *collection_path;
1829 set_closure_free (gpointer data)
1831 SetClosure *set = data;
1832 if (set->cancellable)
1833 g_object_unref (set->cancellable);
1834 g_free (set->alias);
1835 g_free (set->collection_path);
1836 g_slice_free (SetClosure, set);
1840 on_set_alias_done (GObject *source,
1841 GAsyncResult *result,
1844 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
1845 GError *error = NULL;
1847 secret_service_set_alias_to_dbus_path_finish (SECRET_SERVICE (source), result, &error);
1849 g_simple_async_result_take_error (async, error);
1851 g_simple_async_result_complete (async);
1852 g_object_unref (async);
1856 on_set_alias_service (GObject *source,
1857 GAsyncResult *result,
1860 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
1861 SetClosure *set = g_simple_async_result_get_op_res_gpointer (async);
1862 SecretService *service;
1863 GError *error = NULL;
1865 service = secret_service_get_finish (result, &error);
1866 if (error == NULL) {
1867 secret_service_set_alias_to_dbus_path (service, set->alias,
1868 set->collection_path,
1871 g_object_ref (async));
1872 g_object_unref (service);
1875 g_simple_async_result_take_error (async, error);
1876 g_simple_async_result_complete (async);
1879 g_object_unref (async);
1883 * secret_service_set_alias:
1884 * @service: (allow-none): a secret service object
1885 * @alias: the alias to assign the collection to
1886 * @collection: (allow-none): the collection to assign to the alias
1887 * @cancellable: (allow-none): optional cancellation object
1888 * @callback: called when the operation completes
1889 * @user_data: data to pass to the callback
1891 * Assign a collection to this alias. Aliases help determine
1892 * well known collections, such as 'default'.
1894 * If @service is NULL, then secret_service_get() will be called to get
1895 * the default #SecretService proxy.
1897 * This method will return immediately and complete asynchronously.
1900 secret_service_set_alias (SecretService *service,
1902 SecretCollection *collection,
1903 GCancellable *cancellable,
1904 GAsyncReadyCallback callback,
1907 GSimpleAsyncResult *async;
1911 g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service));
1912 g_return_if_fail (alias != NULL);
1913 g_return_if_fail (collection == NULL || SECRET_IS_COLLECTION (collection));
1914 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1916 async = g_simple_async_result_new (G_OBJECT (service), callback, user_data,
1917 secret_service_set_alias);
1918 set = g_slice_new0 (SetClosure);
1919 set->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1920 set->alias = g_strdup (alias);
1923 path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection));
1924 g_return_if_fail (path != NULL);
1929 set->collection_path = g_strdup (path);
1930 g_simple_async_result_set_op_res_gpointer (async, set, set_closure_free);
1932 if (service == NULL) {
1933 secret_service_get (SECRET_SERVICE_NONE, cancellable,
1934 on_set_alias_service, g_object_ref (async));
1936 secret_service_set_alias_to_dbus_path (service, set->alias,
1937 set->collection_path,
1940 g_object_ref (async));
1943 g_object_unref (async);
1947 * secret_service_set_alias_finish:
1948 * @service: (allow-none): a secret service object
1949 * @result: asynchronous result passed to callback
1950 * @error: location to place error on failure
1952 * Finish an asynchronous operation to assign a collection to an alias.
1954 * Returns: %TRUE if successful
1957 secret_service_set_alias_finish (SecretService *service,
1958 GAsyncResult *result,
1961 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
1962 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service),
1963 secret_service_set_alias), FALSE);
1964 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1966 if (_secret_util_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
1973 * secret_service_set_alias_sync:
1974 * @service: (allow-none): a secret service object
1975 * @alias: the alias to assign the collection to
1976 * @collection: (allow-none): the collection to assign to the alias
1977 * @cancellable: (allow-none): optional cancellation object
1978 * @error: location to place error on failure
1980 * Assign a collection to this alias. Aliases help determine
1981 * well known collections, such as 'default'.
1983 * If @service is NULL, then secret_service_get_sync() will be called to get
1984 * the default #SecretService proxy.
1986 * This method may block and should not be used in user interface threads.
1988 * Returns: %TRUE if successful
1991 secret_service_set_alias_sync (SecretService *service,
1993 SecretCollection *collection,
1994 GCancellable *cancellable,
2000 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
2001 g_return_val_if_fail (alias != NULL, FALSE);
2002 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
2003 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2005 sync = _secret_sync_new ();
2006 g_main_context_push_thread_default (sync->context);
2008 secret_service_set_alias (service, alias, collection, cancellable,
2009 _secret_sync_on_result, sync);
2011 g_main_loop_run (sync->loop);
2013 ret = secret_service_set_alias_finish (service, sync->result, error);
2015 g_main_context_pop_thread_default (sync->context);
2016 _secret_sync_free (sync);