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-enum-types.h"
21 #include "secret-item.h"
22 #include "secret-paths.h"
23 #include "secret-private.h"
24 #include "secret-service.h"
25 #include "secret-types.h"
26 #include "secret-value.h"
28 #include "egg/egg-secure-memory.h"
31 * SECTION:secret-service
32 * @title: SecretService
33 * @short_description: the Secret Service
35 * A #SecretService object represents the Secret Service implementation which
36 * runs as a D-Bus service.
38 * Normally a single #SecretService object can be shared between multiple
39 * callers. The secret_service_get() method is used to access this #SecretService
40 * object. If a new independent #SecretService object is required, use
41 * secret_service_open().
43 * In order to securely transfer secrets to the Sercret Service, an session
44 * is established. This session can be established while initializing a
45 * #SecretService object by passing the %SECRET_SERVICE_OPEN_SESSION flag
46 * to the secret_service_get() or secret_service_open() functions. In order to
47 * establish a session on an already existing #SecretService, use the
48 * secret_service_ensure_session() function.
50 * To search for items, use the secret_service_search() method.
52 * Multiple collections can exist in the Secret Service, each of which contains
53 * secret items. In order to instantiate #SecretCollection objects which
54 * represent those collections while initializing a #SecretService then pass
55 * the %SECRET_SERVICE_LOAD_COLLECTIONS flag to the secret_service_get() or
56 * secret_service_open() functions. In order to establish a session on an already
57 * existing #SecretService, use the secret_service_load_collections() function.
58 * To access the list of collections use secret_service_get_collections().
60 * Certain actions on the Secret Service require user prompting to complete,
61 * such as creating a collection, or unlocking a collection. When such a prompt
62 * is necessary, then a #SecretPrompt object is created by this library, and
63 * passed to the secret_service_prompt() method. In this way it is handled
66 * In order to customize prompt handling, override the <literal>prompt_async</literal>
67 * and <literal>prompt_finish</literal> virtual methods of the #SecretService class.
69 * These functions have an unstable API and may change across versions. Use
70 * <literal>libsecret-unstable</literal> package to access them.
78 * A proxy object representing the Secret Service.
83 * @parent_class: the parent class
84 * @collection_gtype: the #GType of the #SecretCollection objects instantiated
85 * by the #SecretService proxy
86 * @item_gtype: the #GType of the #SecretItem objects instantiated by the
87 * #SecretService proxy
88 * @prompt_async: called to perform asynchronous prompting when necessary
89 * @prompt_finish: called to complete an asynchronous prompt operation
90 * @prompt_sync: called to perform synchronous prompting when necessary
92 * The class for #SecretService.
97 * @SECRET_SERVICE_NONE: no flags for initializing the #SecretService
98 * @SECRET_SERVICE_OPEN_SESSION: establish a session for transfer of secrets
99 * while initializing the #SecretService
100 * @SECRET_SERVICE_LOAD_COLLECTIONS: load collections while initializing the
103 * Flags which determine which parts of the #SecretService proxy are initialized
104 * during a secret_service_get() or secret_service_open() operation.
107 EGG_SECURE_DEFINE_GLIB_GLOBALS ();
109 GQuark _secret_error_quark = 0;
117 struct _SecretServicePrivate {
118 /* No change between construct and finalize */
119 GCancellable *cancellable;
120 SecretServiceFlags init_flags;
122 /* Locked by mutex */
125 GHashTable *collections;
128 G_LOCK_DEFINE (service_instance);
129 static gpointer service_instance = NULL;
130 static guint service_watch = 0;
132 static GInitableIface *secret_service_initable_parent_iface = NULL;
134 static GAsyncInitableIface *secret_service_async_initable_parent_iface = NULL;
136 static void secret_service_initable_iface (GInitableIface *iface);
138 static void secret_service_async_initable_iface (GAsyncInitableIface *iface);
140 G_DEFINE_TYPE_WITH_CODE (SecretService, secret_service, G_TYPE_DBUS_PROXY,
141 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, secret_service_initable_iface);
142 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, secret_service_async_initable_iface);
145 static SecretService *
146 service_get_instance (void)
148 SecretService *instance = NULL;
150 G_LOCK (service_instance);
151 if (service_instance != NULL)
152 instance = g_object_ref (service_instance);
153 G_UNLOCK (service_instance);
159 service_uncache_instance (SecretService *which)
161 SecretService *instance = NULL;
163 gboolean matched = FALSE;
165 G_LOCK (service_instance);
166 if (which == NULL || service_instance == which) {
167 instance = service_instance;
168 service_instance = NULL;
169 watch = service_watch;
173 G_UNLOCK (service_instance);
175 if (instance != NULL)
176 g_object_unref (instance);
178 g_bus_unwatch_name (watch);
184 on_service_instance_vanished (GDBusConnection *connection,
188 if (!service_uncache_instance (user_data)) {
189 g_warning ("Global default SecretService instance out of sync "
190 "with the watch for its DBus name");
195 service_cache_instance (SecretService *instance)
200 g_object_ref (instance);
201 proxy = G_DBUS_PROXY (instance);
202 watch = g_bus_watch_name_on_connection (g_dbus_proxy_get_connection (proxy),
203 g_dbus_proxy_get_name (proxy),
204 G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
205 NULL, on_service_instance_vanished,
208 G_LOCK (service_instance);
209 if (service_instance == NULL) {
210 service_instance = instance;
212 service_watch = watch;
215 G_UNLOCK (service_instance);
217 if (instance != NULL)
218 g_object_unref (instance);
220 g_bus_unwatch_name (watch);
224 secret_service_init (SecretService *self)
226 self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SECRET_TYPE_SERVICE,
227 SecretServicePrivate);
229 g_mutex_init (&self->pv->mutex);
230 self->pv->cancellable = g_cancellable_new ();
234 secret_service_get_property (GObject *obj,
239 SecretService *self = SECRET_SERVICE (obj);
243 g_value_set_flags (value, secret_service_get_flags (self));
245 case PROP_COLLECTIONS:
246 g_value_take_boxed (value, secret_service_get_collections (self));
249 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
255 secret_service_set_property (GObject *obj,
260 SecretService *self = SECRET_SERVICE (obj);
264 self->pv->init_flags = g_value_get_flags (value);
267 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
273 secret_service_dispose (GObject *obj)
275 SecretService *self = SECRET_SERVICE (obj);
277 g_cancellable_cancel (self->pv->cancellable);
279 G_OBJECT_CLASS (secret_service_parent_class)->dispose (obj);
283 secret_service_finalize (GObject *obj)
285 SecretService *self = SECRET_SERVICE (obj);
287 _secret_session_free (self->pv->session);
288 if (self->pv->collections)
289 g_hash_table_destroy (self->pv->collections);
290 g_clear_object (&self->pv->cancellable);
291 g_mutex_clear (&self->pv->mutex);
293 G_OBJECT_CLASS (secret_service_parent_class)->finalize (obj);
297 secret_service_real_prompt_sync (SecretService *self,
298 SecretPrompt *prompt,
299 GCancellable *cancellable,
300 const GVariantType *return_type,
303 return secret_prompt_perform_sync (prompt, 0, cancellable, return_type, error);
307 on_real_prompt_completed (GObject *source,
308 GAsyncResult *result,
311 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
312 GError *error = NULL;
315 retval = secret_prompt_perform_finish (SECRET_PROMPT (source), result, &error);
317 g_simple_async_result_set_op_res_gpointer (res, retval, (GDestroyNotify)g_variant_unref);
319 g_simple_async_result_take_error (res, error);
320 g_simple_async_result_complete (res);
321 g_object_unref (res);
325 secret_service_real_prompt_async (SecretService *self,
326 SecretPrompt *prompt,
327 const GVariantType *return_type,
328 GCancellable *cancellable,
329 GAsyncReadyCallback callback,
332 GSimpleAsyncResult *res;
334 res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
335 secret_service_real_prompt_async);
337 secret_prompt_perform (prompt, 0, return_type, cancellable,
338 on_real_prompt_completed,
341 g_object_unref (res);
345 secret_service_real_prompt_finish (SecretService *self,
346 GAsyncResult *result,
349 GSimpleAsyncResult *res;
352 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
353 secret_service_real_prompt_async), NULL);
355 res = G_SIMPLE_ASYNC_RESULT (result);
356 if (_secret_util_propagate_error (res, error))
359 retval = g_simple_async_result_get_op_res_gpointer (res);
363 return g_variant_ref (retval);
367 handle_property_changed (SecretService *self,
368 const gchar *property_name,
373 g_variant_ref_sink (value);
375 if (g_str_equal (property_name, "Collections")) {
377 g_mutex_lock (&self->pv->mutex);
378 perform = self->pv->collections != NULL;
379 g_mutex_unlock (&self->pv->mutex);
382 secret_service_load_collections (self, self->pv->cancellable, NULL, NULL);
385 g_variant_unref (value);
389 secret_service_properties_changed (GDBusProxy *proxy,
390 GVariant *changed_properties,
391 const gchar* const *invalidated_properties)
393 SecretService *self = SECRET_SERVICE (proxy);
394 gchar *property_name;
398 g_object_freeze_notify (G_OBJECT (self));
400 g_variant_iter_init (&iter, changed_properties);
401 while (g_variant_iter_loop (&iter, "{sv}", &property_name, &value))
402 handle_property_changed (self, property_name, value);
404 g_object_thaw_notify (G_OBJECT (self));
408 secret_service_signal (GDBusProxy *proxy,
409 const gchar *sender_name,
410 const gchar *signal_name,
411 GVariant *parameters)
413 SecretService *self = SECRET_SERVICE (proxy);
414 SecretCollection *collection;
415 const gchar *collection_path;
416 GVariantBuilder builder;
417 gboolean found = FALSE;
424 * Remember that these signals come from a time before PropertiesChanged.
425 * We support them because they're in the spec, and ksecretservice uses them.
428 paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Collections");
430 /* A new collection was added, add it to the Collections property */
431 if (g_str_equal (signal_name, SECRET_SIGNAL_COLLECTION_CREATED)) {
432 g_variant_get (parameters, "(@o)", &value);
433 g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
434 g_variant_iter_init (&iter, paths);
435 while ((path = g_variant_iter_next_value (&iter)) != NULL) {
436 if (g_variant_equal (path, value)) {
440 g_variant_builder_add_value (&builder, path);
441 g_variant_unref (path);
444 g_variant_builder_add_value (&builder, value);
445 handle_property_changed (self, "Collections", g_variant_builder_end (&builder));
447 g_variant_builder_clear (&builder);
448 g_variant_unref (value);
450 /* A collection was deleted, remove it from the Collections property */
451 } else if (g_str_equal (signal_name, SECRET_SIGNAL_COLLECTION_DELETED)) {
452 g_variant_get (parameters, "(@o)", &value);
453 g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
454 g_variant_iter_init (&iter, paths);
455 while ((path = g_variant_iter_next_value (&iter)) != NULL) {
456 if (g_variant_equal (path, value))
459 g_variant_builder_add_value (&builder, path);
460 g_variant_unref (path);
463 handle_property_changed (self, "Collections", g_variant_builder_end (&builder));
464 g_variant_unref (value);
466 /* The collection changed, update it */
467 } else if (g_str_equal (signal_name, SECRET_SIGNAL_COLLECTION_CHANGED)) {
468 g_variant_get (parameters, "(&o)", &collection_path);
470 g_mutex_lock (&self->pv->mutex);
472 if (self->pv->collections)
473 collection = g_hash_table_lookup (self->pv->collections, collection_path);
477 g_object_ref (collection);
479 g_mutex_unlock (&self->pv->mutex);
482 secret_collection_refresh (collection);
483 g_object_unref (collection);
487 g_variant_unref (paths);
491 secret_service_real_get_collection_gtype (SecretService *self)
493 SecretServiceClass *klass;
495 klass = SECRET_SERVICE_GET_CLASS (self);
496 return klass->collection_gtype;
500 secret_service_real_get_item_gtype (SecretService *self)
502 SecretServiceClass *klass;
504 klass = SECRET_SERVICE_GET_CLASS (self);
505 return klass->item_gtype;
509 secret_service_class_init (SecretServiceClass *klass)
511 GObjectClass *object_class = G_OBJECT_CLASS (klass);
512 GDBusProxyClass *proxy_class = G_DBUS_PROXY_CLASS (klass);
514 object_class->get_property = secret_service_get_property;
515 object_class->set_property = secret_service_set_property;
516 object_class->dispose = secret_service_dispose;
517 object_class->finalize = secret_service_finalize;
519 proxy_class->g_properties_changed = secret_service_properties_changed;
520 proxy_class->g_signal = secret_service_signal;
522 klass->prompt_sync = secret_service_real_prompt_sync;
523 klass->prompt_async = secret_service_real_prompt_async;
524 klass->prompt_finish = secret_service_real_prompt_finish;
526 klass->item_gtype = SECRET_TYPE_ITEM;
527 klass->collection_gtype = SECRET_TYPE_COLLECTION;
528 klass->get_item_gtype = secret_service_real_get_item_gtype;
529 klass->get_collection_gtype = secret_service_real_get_collection_gtype;
532 * SecretService:flags:
534 * A set of flags describing which parts of the secret service have
537 g_object_class_install_property (object_class, PROP_FLAGS,
538 g_param_spec_flags ("flags", "Flags", "Service flags",
539 secret_service_flags_get_type (), SECRET_SERVICE_NONE,
540 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
543 * SecretService:collections:
545 * A list of #SecretCollection objects representing the collections in
546 * the Secret Service. This list may be %NULL if the collections have
549 * To load the collections, specify the %SECRET_SERVICE_LOAD_COLLECTIONS
550 * initialization flag when calling the secret_service_get() or
551 * secret_service_open() functions. Or call the secret_service_load_collections()
554 g_object_class_install_property (object_class, PROP_COLLECTIONS,
555 g_param_spec_boxed ("collections", "Collections", "Secret Service Collections",
556 _secret_list_get_type (), G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
558 g_type_class_add_private (klass, sizeof (SecretServicePrivate));
560 /* Initialize this error domain, registers dbus errors */
561 _secret_error_quark = secret_error_get_quark ();
565 GCancellable *cancellable;
566 SecretServiceFlags flags;
570 init_closure_free (gpointer data)
572 InitClosure *closure = data;
573 g_clear_object (&closure->cancellable);
574 g_slice_free (InitClosure, closure);
578 service_ensure_for_flags_sync (SecretService *self,
579 SecretServiceFlags flags,
580 GCancellable *cancellable,
583 if (flags & SECRET_SERVICE_OPEN_SESSION)
584 if (!secret_service_ensure_session_sync (self, cancellable, error))
587 if (flags & SECRET_SERVICE_LOAD_COLLECTIONS)
588 if (!secret_service_load_collections_sync (self, cancellable, error))
595 on_load_collections (GObject *source,
596 GAsyncResult *result,
599 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
600 SecretService *self = SECRET_SERVICE (source);
601 GError *error = NULL;
603 if (!secret_service_load_collections_finish (self, result, &error))
604 g_simple_async_result_take_error (res, error);
606 g_simple_async_result_complete (res);
607 g_object_unref (res);
611 on_ensure_session (GObject *source,
612 GAsyncResult *result,
615 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
616 InitClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
617 SecretService *self = SECRET_SERVICE (source);
618 GError *error = NULL;
620 if (!secret_service_ensure_session_finish (self, result, &error)) {
621 g_simple_async_result_take_error (res, error);
622 g_simple_async_result_complete (res);
624 } else if (closure->flags & SECRET_SERVICE_LOAD_COLLECTIONS) {
625 secret_service_load_collections (self, closure->cancellable,
626 on_load_collections, g_object_ref (res));
629 g_simple_async_result_complete_in_idle (res);
632 g_object_unref (res);
636 service_ensure_for_flags_async (SecretService *self,
637 SecretServiceFlags flags,
638 GSimpleAsyncResult *res)
640 InitClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
642 closure->flags = flags;
644 if (closure->flags & SECRET_SERVICE_OPEN_SESSION)
645 secret_service_ensure_session (self, closure->cancellable,
646 on_ensure_session, g_object_ref (res));
648 else if (closure->flags & SECRET_SERVICE_LOAD_COLLECTIONS)
649 secret_service_load_collections (self, closure->cancellable,
650 on_load_collections, g_object_ref (res));
653 g_simple_async_result_complete_in_idle (res);
657 secret_service_initable_init (GInitable *initable,
658 GCancellable *cancellable,
663 if (!secret_service_initable_parent_iface->init (initable, cancellable, error))
666 self = SECRET_SERVICE (initable);
667 return service_ensure_for_flags_sync (self, self->pv->init_flags, cancellable, error);
671 secret_service_initable_iface (GInitableIface *iface)
673 secret_service_initable_parent_iface = g_type_interface_peek_parent (iface);
675 iface->init = secret_service_initable_init;
679 on_init_base (GObject *source,
680 GAsyncResult *result,
683 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
684 SecretService *self = SECRET_SERVICE (source);
685 GError *error = NULL;
687 if (!secret_service_async_initable_parent_iface->init_finish (G_ASYNC_INITABLE (self),
689 g_simple_async_result_take_error (res, error);
690 g_simple_async_result_complete (res);
692 service_ensure_for_flags_async (self, self->pv->init_flags, res);
695 g_object_unref (res);
699 secret_service_async_initable_init_async (GAsyncInitable *initable,
701 GCancellable *cancellable,
702 GAsyncReadyCallback callback,
705 GSimpleAsyncResult *res;
706 InitClosure *closure;
708 res = g_simple_async_result_new (G_OBJECT (initable), callback, user_data,
709 secret_service_async_initable_init_async);
710 closure = g_slice_new0 (InitClosure);
711 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
712 g_simple_async_result_set_op_res_gpointer (res, closure, init_closure_free);
714 secret_service_async_initable_parent_iface->init_async (initable, io_priority,
719 g_object_unref (res);
723 secret_service_async_initable_init_finish (GAsyncInitable *initable,
724 GAsyncResult *result,
727 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (initable),
728 secret_service_async_initable_init_async), FALSE);
730 if (_secret_util_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
737 secret_service_async_initable_iface (GAsyncInitableIface *iface)
739 secret_service_async_initable_parent_iface = g_type_interface_peek_parent (iface);
741 iface->init_async = secret_service_async_initable_init_async;
742 iface->init_finish = secret_service_async_initable_init_finish;
746 get_default_bus_name (void)
748 const gchar *bus_name;
750 bus_name = g_getenv ("SECRET_SERVICE_BUS_NAME");
751 if (bus_name == NULL)
752 bus_name = SECRET_SERVICE_BUS_NAME;
758 * secret_service_get:
759 * @flags: flags for which service functionality to ensure is initialized
760 * @cancellable: optional cancellation object
761 * @callback: called when the operation completes
762 * @user_data: data to be passed to the callback
764 * Get a #SecretService proxy for the Secret Service. If such a proxy object
765 * already exists, then the same proxy is returned.
767 * If @flags contains any flags of which parts of the secret service to
768 * ensure are initialized, then those will be initialized before completing.
770 * This method will return immediately and complete asynchronously.
773 secret_service_get (SecretServiceFlags flags,
774 GCancellable *cancellable,
775 GAsyncReadyCallback callback,
778 SecretService *service = NULL;
779 GSimpleAsyncResult *res;
780 InitClosure *closure;
782 service = service_get_instance ();
784 /* Create a whole new service */
785 if (service == NULL) {
786 g_async_initable_new_async (SECRET_TYPE_SERVICE, G_PRIORITY_DEFAULT,
787 cancellable, callback, user_data,
788 "g-flags", G_DBUS_PROXY_FLAGS_NONE,
789 "g-interface-info", _secret_gen_service_interface_info (),
790 "g-name", get_default_bus_name (),
791 "g-bus-type", G_BUS_TYPE_SESSION,
792 "g-object-path", SECRET_SERVICE_PATH,
793 "g-interface-name", SECRET_SERVICE_INTERFACE,
797 /* Just have to ensure that the service matches flags */
799 res = g_simple_async_result_new (G_OBJECT (service), callback,
800 user_data, secret_service_get);
801 closure = g_slice_new0 (InitClosure);
802 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
803 closure->flags = flags;
804 g_simple_async_result_set_op_res_gpointer (res, closure, init_closure_free);
806 service_ensure_for_flags_async (service, flags, res);
808 g_object_unref (service);
809 g_object_unref (res);
814 * secret_service_get_finish:
815 * @result: the asynchronous result passed to the callback
816 * @error: location to place an error on failure
818 * Complete an asynchronous operation to get a #SecretService proxy for the
821 * Returns: (transfer full): a new reference to a #SecretService proxy, which
822 * should be released with g_object_unref().
825 secret_service_get_finish (GAsyncResult *result,
828 GObject *service = NULL;
829 GObject *source_object;
831 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
832 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
834 source_object = g_async_result_get_source_object (result);
836 /* Just ensuring that the service matches flags */
837 if (g_simple_async_result_is_valid (result, source_object, secret_service_get)) {
838 if (!_secret_util_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
839 service = g_object_ref (source_object);
841 /* Creating a whole new service */
843 service = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error);
845 service_cache_instance (SECRET_SERVICE (service));
849 g_object_unref (source_object);
854 return SECRET_SERVICE (service);
858 * secret_service_get_sync:
859 * @flags: flags for which service functionality to ensure is initialized
860 * @cancellable: optional cancellation object
861 * @error: location to place an error on failure
863 * Get a #SecretService proxy for the Secret Service. If such a proxy object
864 * already exists, then the same proxy is returned.
866 * If @flags contains any flags of which parts of the secret service to
867 * ensure are initialized, then those will be initialized before returning.
869 * This method may block indefinitely and should not be used in user interface
872 * Returns: (transfer full): a new reference to a #SecretService proxy, which
873 * should be released with g_object_unref().
876 secret_service_get_sync (SecretServiceFlags flags,
877 GCancellable *cancellable,
880 SecretService *service = NULL;
882 service = service_get_instance ();
884 if (service == NULL) {
885 service = g_initable_new (SECRET_TYPE_SERVICE, cancellable, error,
886 "g-flags", G_DBUS_PROXY_FLAGS_NONE,
887 "g-interface-info", _secret_gen_service_interface_info (),
888 "g-name", get_default_bus_name (),
889 "g-bus-type", G_BUS_TYPE_SESSION,
890 "g-object-path", SECRET_SERVICE_PATH,
891 "g-interface-name", SECRET_SERVICE_INTERFACE,
896 service_cache_instance (service);
899 if (!service_ensure_for_flags_sync (service, flags, cancellable, error)) {
900 g_object_unref (service);
909 * secret_service_disconnect:
911 * Disconnect the default #SecretService proxy returned by secret_service_get()
912 * and secret_service_get_sync().
914 * It is not necessary to call this function, but you may choose to do so at
915 * program exit. It is useful for testing that memory is not leaked.
917 * This function is safe to call at any time. But if other objects in this
918 * library are still referenced, then this will not result in all memory
922 secret_service_disconnect (void)
924 service_uncache_instance (NULL);
928 * secret_service_open:
929 * @service_gtype: the GType of the new secret service
930 * @service_bus_name: (allow-none): the D-Bus service name of the secret service
931 * @flags: flags for which service functionality to ensure is initialized
932 * @cancellable: optional cancellation object
933 * @callback: called when the operation completes
934 * @user_data: data to be passed to the callback
936 * Create a new #SecretService proxy for the Secret Service.
938 * This function is rarely used, see secret_service_get() instead.
940 * The @service_gtype argument should be set to %SECRET_TYPE_SERVICE or a the type
941 * of a derived class.
943 * If @flags contains any flags of which parts of the secret service to
944 * ensure are initialized, then those will be initialized before returning.
946 * If @service_bus_name is %NULL then the default is used.
948 * This method will return immediately and complete asynchronously.
951 secret_service_open (GType service_gtype,
952 const gchar *service_bus_name,
953 SecretServiceFlags flags,
954 GCancellable *cancellable,
955 GAsyncReadyCallback callback,
958 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
959 g_return_if_fail (g_type_is_a (service_gtype, SECRET_TYPE_SERVICE));
961 if (service_bus_name == NULL)
962 service_bus_name = get_default_bus_name ();
964 g_async_initable_new_async (service_gtype, G_PRIORITY_DEFAULT,
965 cancellable, callback, user_data,
966 "g-flags", G_DBUS_PROXY_FLAGS_NONE,
967 "g-interface-info", _secret_gen_service_interface_info (),
968 "g-name", service_bus_name,
969 "g-bus-type", G_BUS_TYPE_SESSION,
970 "g-object-path", SECRET_SERVICE_PATH,
971 "g-interface-name", SECRET_SERVICE_INTERFACE,
977 * secret_service_open_finish:
978 * @result: the asynchronous result passed to the callback
979 * @error: location to place an error on failure
981 * Complete an asynchronous operation to create a new #SecretService proxy for
982 * the Secret Service.
984 * Returns: (transfer full): a new reference to a #SecretService proxy, which
985 * should be released with g_object_unref().
988 secret_service_open_finish (GAsyncResult *result,
991 GObject *source_object;
994 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
995 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
997 source_object = g_async_result_get_source_object (result);
998 object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
1000 g_object_unref (source_object);
1005 return SECRET_SERVICE (object);
1009 * secret_service_open_sync:
1010 * @service_gtype: the GType of the new secret service
1011 * @service_bus_name: (allow-none): the D-Bus service name of the secret service
1012 * @flags: flags for which service functionality to ensure is initialized
1013 * @cancellable: optional cancellation object
1014 * @error: location to place an error on failure
1016 * Create a new #SecretService proxy for the Secret Service.
1018 * This function is rarely used, see secret_service_get_sync() instead.
1020 * The @service_gtype argument should be set to %SECRET_TYPE_SERVICE or a the
1021 * type of a derived class.
1023 * If @flags contains any flags of which parts of the secret service to
1024 * ensure are initialized, then those will be initialized before returning.
1026 * If @service_bus_name is %NULL then the default is used.
1028 * This method may block indefinitely and should not be used in user interface
1031 * Returns: (transfer full): a new reference to a #SecretService proxy, which
1032 * should be released with g_object_unref().
1035 secret_service_open_sync (GType service_gtype,
1036 const gchar *service_bus_name,
1037 SecretServiceFlags flags,
1038 GCancellable *cancellable,
1041 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
1042 g_return_val_if_fail (g_type_is_a (service_gtype, SECRET_TYPE_SERVICE), NULL);
1044 if (service_bus_name == NULL)
1045 service_bus_name = get_default_bus_name ();
1047 return g_initable_new (service_gtype, cancellable, error,
1048 "g-flags", G_DBUS_PROXY_FLAGS_NONE,
1049 "g-interface-info", _secret_gen_service_interface_info (),
1050 "g-name", service_bus_name,
1051 "g-bus-type", G_BUS_TYPE_SESSION,
1052 "g-object-path", SECRET_SERVICE_PATH,
1053 "g-interface-name", SECRET_SERVICE_INTERFACE,
1059 * secret_service_get_flags:
1060 * @self: the secret service proxy
1062 * Get the flags representing what features of the #SecretService proxy
1063 * have been initialized.
1065 * Use secret_service_ensure_session() or secret_service_load_collections()
1066 * to initialize further features and change the flags.
1068 * Returns: the flags for features initialized
1071 secret_service_get_flags (SecretService *self)
1073 SecretServiceFlags flags = 0;
1075 g_return_val_if_fail (SECRET_IS_SERVICE (self), SECRET_SERVICE_NONE);
1077 g_mutex_lock (&self->pv->mutex);
1079 if (self->pv->session)
1080 flags |= SECRET_SERVICE_OPEN_SESSION;
1081 if (self->pv->collections)
1082 flags |= SECRET_SERVICE_LOAD_COLLECTIONS;
1084 g_mutex_unlock (&self->pv->mutex);
1090 * secret_service_get_collections:
1091 * @self: the secret service proxy
1093 * Get a list of #SecretCollection objects representing all the collections
1094 * in the secret service.
1096 * If the %SECRET_SERVICE_LOAD_COLLECTIONS flag was not specified when
1097 * initializing #SecretService proxy object, then this method will return
1098 * %NULL. Use secret_service_load_collections() to load the collections.
1100 * Returns: (transfer full) (element-type SecretUnstable.Collection) (allow-none): a
1101 * list of the collections in the secret service
1104 secret_service_get_collections (SecretService *self)
1106 GList *l, *collections;
1108 g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
1110 g_mutex_lock (&self->pv->mutex);
1112 if (self->pv->collections == NULL) {
1116 collections = g_hash_table_get_values (self->pv->collections);
1117 for (l = collections; l != NULL; l = g_list_next (l))
1118 g_object_ref (l->data);
1121 g_mutex_unlock (&self->pv->mutex);
1127 _secret_service_find_item_instance (SecretService *self,
1128 const gchar *item_path)
1130 SecretCollection *collection = NULL;
1131 gchar *collection_path;
1134 collection_path = _secret_util_parent_path (item_path);
1136 collection = _secret_service_find_collection_instance (self, collection_path);
1138 g_free (collection_path);
1140 if (collection == NULL)
1143 item = _secret_collection_find_item_instance (collection, item_path);
1144 g_object_unref (collection);
1150 _secret_service_find_collection_instance (SecretService *self,
1151 const gchar *collection_path)
1153 SecretCollection *collection = NULL;
1155 g_mutex_lock (&self->pv->mutex);
1156 if (self->pv->collections) {
1157 collection = g_hash_table_lookup (self->pv->collections, collection_path);
1158 if (collection != NULL)
1159 g_object_ref (collection);
1161 g_mutex_unlock (&self->pv->mutex);
1167 _secret_service_get_session (SecretService *self)
1169 SecretSession *session;
1171 g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
1173 g_mutex_lock (&self->pv->mutex);
1174 session = self->pv->session;
1175 g_mutex_unlock (&self->pv->mutex);
1181 _secret_service_take_session (SecretService *self,
1182 SecretSession *session)
1184 g_return_if_fail (SECRET_IS_SERVICE (self));
1185 g_return_if_fail (session != NULL);
1187 g_mutex_lock (&self->pv->mutex);
1188 if (self->pv->session == NULL)
1189 self->pv->session = session;
1191 _secret_session_free (session);
1192 g_mutex_unlock (&self->pv->mutex);
1196 * secret_service_get_session_algorithms:
1197 * @self: the secret service proxy
1199 * Get the set of algorithms being used to transfer secrets between this
1200 * secret service proxy and the Secret Service itself.
1202 * This will be %NULL if no session has been established. Use
1203 * secret_service_ensure_session() to establish a session.
1205 * Returns: (allow-none): a string representing the algorithms for transferring
1209 secret_service_get_session_algorithms (SecretService *self)
1211 SecretSession *session;
1212 const gchar *algorithms;
1214 g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
1216 g_mutex_lock (&self->pv->mutex);
1217 session = self->pv->session;
1218 algorithms = session ? _secret_session_get_algorithms (session) : NULL;
1219 g_mutex_unlock (&self->pv->mutex);
1221 /* Session never changes once established, so can return const */
1226 * secret_service_get_session_dbus_path:
1227 * @self: the secret service proxy
1229 * Get the D-Bus object path of the session object being used to transfer
1230 * secrets between this secret service proxy and the Secret Service itself.
1232 * This will be %NULL if no session has been established. Use
1233 * secret_service_ensure_session() to establish a session.
1235 * Returns: (allow-none): a string representing the D-Bus object path of the
1239 secret_service_get_session_dbus_path (SecretService *self)
1241 SecretSession *session;
1244 g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
1246 g_mutex_lock (&self->pv->mutex);
1247 session = self->pv->session;
1248 path = session ? _secret_session_get_path (session) : NULL;
1249 g_mutex_unlock (&self->pv->mutex);
1251 /* Session never changes once established, so can return const */
1256 * secret_service_ensure_session:
1257 * @self: the secret service
1258 * @cancellable: optional cancellation object
1259 * @callback: called when the operation completes
1260 * @user_data: data to be passed to the callback
1262 * Ensure that the #SecretService proxy has established a session with the
1263 * Secret Service. This session is used to transfer secrets.
1265 * It is not normally necessary to call this method, as the session is
1266 * established as necessary. You can also pass the %SECRET_SERVICE_OPEN_SESSION
1267 * to secret_service_get() in order to ensure that a session has been established
1268 * by the time you get the #SecretService proxy.
1270 * This method will return immediately and complete asynchronously.
1273 secret_service_ensure_session (SecretService *self,
1274 GCancellable *cancellable,
1275 GAsyncReadyCallback callback,
1278 GSimpleAsyncResult *res;
1279 SecretSession *session;
1281 g_return_if_fail (SECRET_IS_SERVICE (self));
1282 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1284 g_mutex_lock (&self->pv->mutex);
1285 session = self->pv->session;
1286 g_mutex_unlock (&self->pv->mutex);
1288 if (session == NULL) {
1289 _secret_session_open (self, cancellable, callback, user_data);
1292 res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
1293 secret_service_ensure_session);
1294 g_simple_async_result_complete_in_idle (res);
1295 g_object_unref (res);
1300 * secret_service_ensure_session_finish:
1301 * @self: the secret service
1302 * @result: the asynchronous result passed to the callback
1303 * @error: location to place an error on failure
1305 * Finish an asynchronous operation to ensure that the #SecretService proxy
1306 * has established a session with the Secret Service.
1308 * Returns: whether a session is established or not
1311 secret_service_ensure_session_finish (SecretService *self,
1312 GAsyncResult *result,
1315 g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
1316 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1318 if (!g_simple_async_result_is_valid (result, G_OBJECT (self),
1319 secret_service_ensure_session)) {
1320 if (!_secret_session_open_finish (result, error))
1324 g_return_val_if_fail (self->pv->session != NULL, FALSE);
1329 * secret_service_ensure_session_sync:
1330 * @self: the secret service
1331 * @cancellable: optional cancellation object
1332 * @error: location to place an error on failure
1334 * Ensure that the #SecretService proxy has established a session with the
1335 * Secret Service. This session is used to transfer secrets.
1337 * It is not normally necessary to call this method, as the session is
1338 * established as necessary. You can also pass the %SECRET_SERVICE_OPEN_SESSION
1339 * to secret_service_get_sync() in order to ensure that a session has been
1340 * established by the time you get the #SecretService proxy.
1342 * This method may block indefinitely and should not be used in user interface
1345 * Returns: whether a session is established or not
1348 secret_service_ensure_session_sync (SecretService *self,
1349 GCancellable *cancellable,
1355 g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
1356 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1357 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1359 sync = _secret_sync_new ();
1360 g_main_context_push_thread_default (sync->context);
1362 secret_service_ensure_session (self, cancellable,
1363 _secret_sync_on_result, sync);
1365 g_main_loop_run (sync->loop);
1367 ret = secret_service_ensure_session_finish (self, sync->result, error);
1369 g_main_context_pop_thread_default (sync->context);
1370 _secret_sync_free (sync);
1375 static SecretCollection *
1376 service_lookup_collection (SecretService *self,
1379 SecretCollection *collection = NULL;
1381 g_mutex_lock (&self->pv->mutex);
1383 if (self->pv->collections) {
1384 collection = g_hash_table_lookup (self->pv->collections, path);
1385 if (collection != NULL)
1386 g_object_ref (collection);
1389 g_mutex_unlock (&self->pv->mutex);
1395 service_update_collections (SecretService *self,
1396 GHashTable *collections)
1398 GHashTable *previous;
1400 g_hash_table_ref (collections);
1402 g_mutex_lock (&self->pv->mutex);
1404 previous = self->pv->collections;
1405 self->pv->collections = collections;
1407 g_mutex_unlock (&self->pv->mutex);
1409 if (previous != NULL)
1410 g_hash_table_unref (previous);
1412 g_object_notify (G_OBJECT (self), "collections");
1416 GCancellable *cancellable;
1417 GHashTable *collections;
1418 gint collections_loading;
1422 collections_table_new (void)
1424 return g_hash_table_new_full (g_str_hash, g_str_equal,
1425 g_free, g_object_unref);
1429 ensure_closure_free (gpointer data)
1431 EnsureClosure *closure = data;
1432 g_clear_object (&closure->cancellable);
1433 g_hash_table_unref (closure->collections);
1434 g_slice_free (EnsureClosure, closure);
1438 on_ensure_collection (GObject *source,
1439 GAsyncResult *result,
1442 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
1443 SecretService *self = SECRET_SERVICE (g_async_result_get_source_object (user_data));
1444 EnsureClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
1445 SecretCollection *collection;
1447 GError *error = NULL;
1449 closure->collections_loading--;
1451 collection = secret_collection_new_for_dbus_path_finish (result, &error);
1454 g_simple_async_result_take_error (res, error);
1456 if (collection != NULL) {
1457 path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection));
1458 g_hash_table_insert (closure->collections, g_strdup (path), collection);
1461 if (closure->collections_loading == 0) {
1462 service_update_collections (self, closure->collections);
1463 g_simple_async_result_complete (res);
1466 g_object_unref (self);
1467 g_object_unref (res);
1471 * secret_service_load_collections:
1472 * @self: the secret service
1473 * @cancellable: optional cancellation object
1474 * @callback: called when the operation completes
1475 * @user_data: data to be passed to the callback
1477 * Ensure that the #SecretService proxy has loaded all the collections present
1478 * in the Secret Service. This affects the result of
1479 * secret_service_get_collections().
1481 * You can also pass the %SECRET_SERVICE_LOAD_COLLECTIONS to
1482 * secret_service_get_sync() in order to ensure that the collections have been
1483 * loaded by the time you get the #SecretService proxy.
1485 * This method will return immediately and complete asynchronously.
1488 secret_service_load_collections (SecretService *self,
1489 GCancellable *cancellable,
1490 GAsyncReadyCallback callback,
1493 EnsureClosure *closure;
1494 SecretCollection *collection;
1495 GSimpleAsyncResult *res;
1500 g_return_if_fail (SECRET_IS_SERVICE (self));
1501 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1503 paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Collections");
1504 g_return_if_fail (paths != NULL);
1506 res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
1507 secret_service_load_collections);
1508 closure = g_slice_new0 (EnsureClosure);
1509 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1510 closure->collections = collections_table_new ();
1511 g_simple_async_result_set_op_res_gpointer (res, closure, ensure_closure_free);
1513 g_variant_iter_init (&iter, paths);
1514 while (g_variant_iter_loop (&iter, "&o", &path)) {
1515 collection = service_lookup_collection (self, path);
1517 /* No such collection yet create a new one */
1518 if (collection == NULL) {
1519 secret_collection_new_for_dbus_path (self, path, SECRET_COLLECTION_LOAD_ITEMS,
1520 cancellable, on_ensure_collection, g_object_ref (res));
1521 closure->collections_loading++;
1523 g_hash_table_insert (closure->collections, g_strdup (path), collection);
1527 if (closure->collections_loading == 0) {
1528 service_update_collections (self, closure->collections);
1529 g_simple_async_result_complete_in_idle (res);
1532 g_variant_unref (paths);
1533 g_object_unref (res);
1537 * secret_service_load_collections_finish:
1538 * @self: the secret service
1539 * @result: the asynchronous result passed to the callback
1540 * @error: location to place an error on failure
1542 * Complete an asynchronous operation to ensure that the #SecretService proxy
1543 * has loaded all the collections present in the Secret Service.
1545 * Returns: whether the load was successful or not
1548 secret_service_load_collections_finish (SecretService *self,
1549 GAsyncResult *result,
1552 g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
1553 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1554 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
1555 secret_service_load_collections), FALSE);
1557 if (_secret_util_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
1564 * secret_service_load_collections_sync:
1565 * @self: the secret service
1566 * @cancellable: optional cancellation object
1567 * @error: location to place an error on failure
1569 * Ensure that the #SecretService proxy has loaded all the collections present
1570 * in the Secret Service. This affects the result of
1571 * secret_service_get_collections().
1573 * You can also pass the %SECRET_SERVICE_LOAD_COLLECTIONS to
1574 * secret_service_get_sync() in order to ensure that the collections have been
1575 * loaded by the time you get the #SecretService proxy.
1577 * This method may block indefinitely and should not be used in user interface
1580 * Returns: whether the load was successful or not
1583 secret_service_load_collections_sync (SecretService *self,
1584 GCancellable *cancellable,
1587 SecretCollection *collection;
1588 GHashTable *collections;
1592 gboolean ret = TRUE;
1594 g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
1595 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1596 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1598 paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Collections");
1599 g_return_val_if_fail (paths != NULL, FALSE);
1601 collections = collections_table_new ();
1603 g_variant_iter_init (&iter, paths);
1604 while (g_variant_iter_next (&iter, "&o", &path)) {
1605 collection = service_lookup_collection (self, path);
1607 /* No such collection yet create a new one */
1608 if (collection == NULL) {
1609 collection = secret_collection_new_for_dbus_path_sync (self, path,
1610 SECRET_COLLECTION_LOAD_ITEMS,
1611 cancellable, error);
1612 if (collection == NULL) {
1618 g_hash_table_insert (collections, g_strdup (path), collection);
1622 service_update_collections (self, collections);
1624 g_hash_table_unref (collections);
1625 g_variant_unref (paths);
1630 * secret_service_prompt_sync:
1631 * @self: the secret service
1632 * @prompt: the prompt
1633 * @cancellable: optional cancellation object
1634 * @return_type: the variant type of the prompt result
1635 * @error: location to place an error on failure
1637 * Perform prompting for a #SecretPrompt.
1639 * Runs a prompt and performs the prompting. Returns a variant result if the
1640 * prompt was completed and not dismissed. The type of result depends on the
1641 * action the prompt is completing, and is defined in the Secret Service DBus
1642 * API specification.
1644 * This function is called by other parts of this library to handle prompts
1645 * for the various actions that can require prompting.
1647 * Override the #SecretServiceClass <literal>prompt_sync</literal> virtual method
1648 * to change the behavior of the propmting. The default behavior is to simply
1649 * run secret_prompt_perform_sync() on the prompt.
1651 * Returns: (transfer full): %NULL if the prompt was dismissed or an error occurred,
1652 * a variant result if the prompt was successful
1655 secret_service_prompt_sync (SecretService *self,
1656 SecretPrompt *prompt,
1657 GCancellable *cancellable,
1658 const GVariantType *return_type,
1661 SecretServiceClass *klass;
1663 g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
1664 g_return_val_if_fail (SECRET_IS_PROMPT (prompt), NULL);
1665 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
1666 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1668 klass = SECRET_SERVICE_GET_CLASS (self);
1669 g_return_val_if_fail (klass->prompt_sync != NULL, NULL);
1671 return (klass->prompt_sync) (self, prompt, cancellable, return_type, error);
1675 * secret_service_prompt:
1676 * @self: the secret service
1677 * @prompt: the prompt
1678 * @return_type: (allow-none): the variant type of the prompt result
1679 * @cancellable: optional cancellation object
1680 * @callback: called when the operation completes
1681 * @user_data: data to be passed to the callback
1683 * Perform prompting for a #SecretPrompt.
1685 * This function is called by other parts of this library to handle prompts
1686 * for the various actions that can require prompting.
1688 * Override the #SecretServiceClass <literal>prompt_async</literal> virtual method
1689 * to change the behavior of the propmting. The default behavior is to simply
1690 * run secret_prompt_perform() on the prompt.
1693 secret_service_prompt (SecretService *self,
1694 SecretPrompt *prompt,
1695 const GVariantType *return_type,
1696 GCancellable *cancellable,
1697 GAsyncReadyCallback callback,
1700 SecretServiceClass *klass;
1702 g_return_if_fail (SECRET_IS_SERVICE (self));
1703 g_return_if_fail (SECRET_IS_PROMPT (prompt));
1704 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1706 klass = SECRET_SERVICE_GET_CLASS (self);
1707 g_return_if_fail (klass->prompt_async != NULL);
1709 (klass->prompt_async) (self, prompt, return_type, cancellable, callback, user_data);
1713 * secret_service_prompt_finish:
1714 * @self: the secret service
1715 * @result: the asynchronous result passed to the callback
1716 * @error: location to place an error on failure
1718 * Complete asynchronous operation to perform prompting for a #SecretPrompt.
1720 * Returns a variant result if the prompt was completed and not dismissed. The
1721 * type of result depends on the action the prompt is completing, and is defined
1722 * in the Secret Service DBus API specification.
1724 * Returns: (transfer full): %NULL if the prompt was dismissed or an error occurred,
1725 * a variant result if the prompt was successful
1728 secret_service_prompt_finish (SecretService *self,
1729 GAsyncResult *result,
1732 SecretServiceClass *klass;
1734 g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
1735 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
1736 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1738 klass = SECRET_SERVICE_GET_CLASS (self);
1739 g_return_val_if_fail (klass->prompt_finish != NULL, NULL);
1741 return (klass->prompt_finish) (self, result, error);
1745 * secret_service_get_collection_gtype:
1746 * @self: the secret service
1748 * Get the GObject type for collections instantiated by this service.
1749 * This will always be either #SecretCollection or derived from it.
1751 * Returns: the gobject type for collections
1754 secret_service_get_collection_gtype (SecretService *self)
1756 SecretServiceClass *klass;
1759 g_return_val_if_fail (SECRET_IS_SERVICE (self), 0);
1761 klass = SECRET_SERVICE_GET_CLASS (self);
1762 g_return_val_if_fail (klass->get_collection_gtype != NULL,
1763 SECRET_TYPE_COLLECTION);
1765 type = (klass->get_collection_gtype) (self);
1766 g_return_val_if_fail (g_type_is_a (type, SECRET_TYPE_COLLECTION),
1767 SECRET_TYPE_COLLECTION);
1773 * secret_service_get_item_gtype:
1774 * @self: the collection
1776 * Get the GObject type for items instantiated by this collection.
1777 * This will always be either #SecretItem or derived from it.
1779 * Returns: the gobject type for items
1782 secret_service_get_item_gtype (SecretService *self)
1784 SecretServiceClass *klass;
1787 g_return_val_if_fail (SECRET_IS_SERVICE (self), 0);
1789 klass = SECRET_SERVICE_GET_CLASS (self);
1790 g_return_val_if_fail (klass->get_item_gtype != NULL,
1793 type = (klass->get_item_gtype) (self);
1794 g_return_val_if_fail (g_type_is_a (type, SECRET_TYPE_ITEM),