Bump version number
[platform/upstream/libsecret.git] / library / secret-password.c
1 /* libsecret - GLib wrapper for Secret Service
2  *
3  * Copyright 2011 Collabora Ltd.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published
7  * by the Free Software Foundation; either version 2.1 of the licence or (at
8  * your option) any later version.
9  *
10  * See the included COPYING file for more information.
11  *
12  * Author: Stef Walter <stefw@gnome.org>
13  */
14
15 #include "config.h"
16
17 #include "secret-attributes.h"
18 #include "secret-password.h"
19 #include "secret-private.h"
20 #include "secret-value.h"
21
22 #include <egg/egg-secure-memory.h>
23
24 /**
25  * SECTION:secret-password
26  * @title: Password storage
27  * @short_description: Simple password storage and lookup
28  *
29  * This is a simple API for storing passwords and retrieving passwords in the
30  * Secret Service.
31  *
32  * Each password is associated with a set of attributes. Attribute values can
33  * be either strings, integers or booleans.
34  *
35  * The names and types of allowed attributes for a given password are defined
36  * with a schema. Certain schemas are predefined. Additional schemas can be
37  * defined via the %SecretSchema structure.
38  *
39  * Each of the functions accept a variable list of attributes names and their
40  * values. Include a %NULL to terminate the list of attributes.
41  *
42  * Stability: Stable
43  */
44
45 /**
46  * secret_password_store: (skip)
47  * @schema: the schema for attributes
48  * @collection: (allow-none): a collection alias, or D-Bus object path of the collection where to store the secret
49  * @label: label for the secret
50  * @password: the null-terminated password to store
51  * @cancellable: optional cancellation object
52  * @callback: called when the operation completes
53  * @user_data: data to be passed to the callback
54  * @...: the attribute keys and values, terminated with %NULL
55  *
56  * Store a password in the secret service.
57  *
58  * The variable argument list should contain pairs of a) The attribute name as
59  * a null-terminated string, followed by b) attribute value, either a character
60  * string, an int number, or a gboolean value, as defined in the @schema.
61  * The list of attribtues should be terminated with a %NULL.
62  *
63  * If the attributes match a secret item already stored in the collection, then
64  * the item will be updated with these new values.
65  *
66  * If @collection is %NULL, then the default collection will be
67  * used. Use #SECRET_COLLECTION_SESSION to store the password in the session
68  * collection, which doesn't get stored across login sessions.
69  *
70  * This method will return immediately and complete asynchronously.
71  */
72 void
73 secret_password_store (const SecretSchema *schema,
74                        const gchar *collection,
75                        const gchar *label,
76                        const gchar *password,
77                        GCancellable *cancellable,
78                        GAsyncReadyCallback callback,
79                        gpointer user_data,
80                        ...)
81 {
82         GHashTable *attributes;
83         va_list va;
84
85         g_return_if_fail (schema != NULL);
86         g_return_if_fail (label != NULL);
87         g_return_if_fail (password != NULL);
88         g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
89
90         va_start (va, user_data);
91         attributes = secret_attributes_buildv (schema, va);
92         va_end (va);
93
94         secret_password_storev (schema, attributes, collection, label, password,
95                                 cancellable, callback, user_data);
96
97         g_hash_table_unref (attributes);
98 }
99
100 /**
101  * secret_password_storev:
102  * @schema: the schema for attributes
103  * @attributes: (element-type utf8 utf8): the attribute keys and values
104  * @collection: (allow-none): a collection alias, or D-Bus object path of the collection where to store the secret
105  * @label: label for the secret
106  * @password: the null-terminated password to store
107  * @cancellable: optional cancellation object
108  * @callback: called when the operation completes
109  * @user_data: data to be passed to the callback
110  *
111  * Store a password in the secret service.
112  *
113  * The @attributes should be a set of key and value string pairs.
114  *
115  * If the attributes match a secret item already stored in the collection, then
116  * the item will be updated with these new values.
117  *
118  * If @collection is %NULL, then the default collection will be
119  * used. Use #SECRET_COLLECTION_SESSION to store the password in the session
120  * collection, which doesn't get stored across login sessions.
121  *
122  * This method will return immediately and complete asynchronously.
123  *
124  * Rename to: secret_password_store
125  */
126 void
127 secret_password_storev (const SecretSchema *schema,
128                         GHashTable *attributes,
129                         const gchar *collection,
130                         const gchar *label,
131                         const gchar *password,
132                         GCancellable *cancellable,
133                         GAsyncReadyCallback callback,
134                         gpointer user_data)
135 {
136         SecretValue *value;
137
138         g_return_if_fail (schema != NULL);
139         g_return_if_fail (label != NULL);
140         g_return_if_fail (password != NULL);
141         g_return_if_fail (attributes != NULL);
142         g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
143
144         /* Warnings raised already */
145         if (!_secret_attributes_validate (schema, attributes, G_STRFUNC, FALSE))
146                 return;
147
148         value = secret_value_new (password, -1, "text/plain");
149
150         secret_service_store (NULL, schema, attributes, collection,
151                               label, value, cancellable, callback, user_data);
152
153         secret_value_unref (value);
154 }
155
156 /**
157  * secret_password_store_finish:
158  * @result: the asynchronous result passed to the callback
159  * @error: location to place an error on failure
160  *
161  * Finish asynchronous operation to store a password in the secret service.
162  *
163  * Returns: whether the storage was successful or not
164  */
165 gboolean
166 secret_password_store_finish (GAsyncResult *result,
167                               GError **error)
168 {
169         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
170         return secret_service_store_finish (NULL, result, error);
171 }
172
173 /**
174  * secret_password_store_sync:
175  * @schema: the schema for attributes
176  * @collection: (allow-none): a collection alias, or D-Bus object path of the collection where to store the secret
177  * @label: label for the secret
178  * @password: the null-terminated password to store
179  * @cancellable: optional cancellation object
180  * @error: location to place an error on failure
181  * @...: the attribute keys and values, terminated with %NULL
182  *
183  * Store a password in the secret service.
184  *
185  * The variable argument list should contain pairs of a) The attribute name as
186  * a null-terminated string, followed by b) attribute value, either a character
187  * string, an int number, or a gboolean value, as defined in the @schema.
188  * The list of attribtues should be terminated with a %NULL.
189  *
190  * If the attributes match a secret item already stored in the collection, then
191  * the item will be updated with these new values.
192  *
193  * If @collection is %NULL, then the default collection will be
194  * used. Use #SECRET_COLLECTION_SESSION to store the password in the session
195  * collection, which doesn't get stored across login sessions.
196  *
197  * This method may block indefinitely and should not be used in user interface
198  * threads.
199  *
200  * Returns: whether the storage was successful or not
201  */
202 gboolean
203 secret_password_store_sync (const SecretSchema *schema,
204                             const gchar *collection,
205                             const gchar *label,
206                             const gchar *password,
207                             GCancellable *cancellable,
208                             GError **error,
209                             ...)
210 {
211         GHashTable *attributes;
212         va_list va;
213         gboolean ret;
214
215         g_return_val_if_fail (schema != NULL, FALSE);
216         g_return_val_if_fail (label != NULL, FALSE);
217         g_return_val_if_fail (password != NULL, FALSE);
218         g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
219         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
220
221         va_start (va, error);
222         attributes = secret_attributes_buildv (schema, va);
223         va_end (va);
224
225         ret = secret_password_storev_sync (schema, attributes, collection,
226                                            label, password, cancellable, error);
227
228         g_hash_table_unref (attributes);
229         return ret;
230 }
231
232 /**
233  * secret_password_storev_sync:
234  * @schema: the schema for attributes
235  * @attributes: (element-type utf8 utf8): the attribute keys and values
236  * @collection: (allow-none): a collection alias, or D-Bus object path of the collection where to store the secret
237  * @label: label for the secret
238  * @password: the null-terminated password to store
239  * @cancellable: optional cancellation object
240  * @error: location to place an error on failure
241  *
242  * Store a password in the secret service.
243  *
244  * The @attributes should be a set of key and value string pairs.
245  *
246  * If the attributes match a secret item already stored in the collection, then
247  * the item will be updated with these new values.
248  *
249  * If @collection is %NULL, then the default collection will be
250  * used. Use #SECRET_COLLECTION_SESSION to store the password in the session
251  * collection, which doesn't get stored across login sessions.
252  *
253  * This method may block indefinitely and should not be used in user interface
254  * threads.
255  *
256  * Returns: whether the storage was successful or not
257  *
258  * Rename to: secret_password_store_sync
259  */
260 gboolean
261 secret_password_storev_sync (const SecretSchema *schema,
262                              GHashTable *attributes,
263                              const gchar *collection,
264                              const gchar *label,
265                              const gchar *password,
266                              GCancellable *cancellable,
267                              GError **error)
268 {
269         SecretSync *sync;
270         gboolean ret;
271
272         g_return_val_if_fail (schema != NULL, FALSE);
273         g_return_val_if_fail (label != NULL, FALSE);
274         g_return_val_if_fail (password != NULL, FALSE);
275         g_return_val_if_fail (attributes != NULL, FALSE);
276         g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
277         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
278
279         /* Warnings raised already */
280         if (!_secret_attributes_validate (schema, attributes, G_STRFUNC, FALSE))
281                 return FALSE;
282
283         sync = _secret_sync_new ();
284         g_main_context_push_thread_default (sync->context);
285
286         secret_password_storev (schema, attributes, collection, label, password,
287                                 cancellable, _secret_sync_on_result, sync);
288
289         g_main_loop_run (sync->loop);
290
291         ret = secret_password_store_finish (sync->result, error);
292
293         g_main_context_pop_thread_default (sync->context);
294         _secret_sync_free (sync);
295
296         return ret;
297 }
298
299 /**
300  * secret_password_lookup: (skip)
301  * @schema: the schema for the attributes
302  * @cancellable: optional cancellation object
303  * @callback: called when the operation completes
304  * @user_data: data to be passed to the callback
305  * @...: the attribute keys and values, terminated with %NULL
306  *
307  * Lookup a password in the secret service.
308  *
309  * The variable argument list should contain pairs of a) The attribute name as
310  * a null-terminated string, followed by b) attribute value, either a character
311  * string, an int number, or a gboolean value, as defined in the password
312  * @schema. The list of attribtues should be terminated with a %NULL.
313  *
314  * If no secret is found then %NULL is returned.
315  *
316  * This method will return immediately and complete asynchronously.
317  */
318 void
319 secret_password_lookup (const SecretSchema *schema,
320                         GCancellable *cancellable,
321                         GAsyncReadyCallback callback,
322                         gpointer user_data,
323                         ...)
324 {
325         GHashTable *attributes;
326         va_list va;
327
328         g_return_if_fail (schema != NULL);
329         g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
330
331         va_start (va, user_data);
332         attributes = secret_attributes_buildv (schema, va);
333         va_end (va);
334
335         secret_password_lookupv (schema, attributes, cancellable,
336                                  callback, user_data);
337
338         g_hash_table_unref (attributes);
339 }
340
341 /**
342  * secret_password_lookupv:
343  * @schema: the schema for attributes
344  * @attributes: (element-type utf8 utf8): the attribute keys and values
345  * @cancellable: optional cancellation object
346  * @callback: called when the operation completes
347  * @user_data: data to be passed to the callback
348  *
349  * Lookup a password in the secret service.
350  *
351  * The @attributes should be a set of key and value string pairs.
352  *
353  * If no secret is found then %NULL is returned.
354  *
355  * This method will return immediately and complete asynchronously.
356  *
357  * Rename to: secret_password_lookup
358  */
359 void
360 secret_password_lookupv (const SecretSchema *schema,
361                          GHashTable *attributes,
362                          GCancellable *cancellable,
363                          GAsyncReadyCallback callback,
364                          gpointer user_data)
365 {
366         g_return_if_fail (schema != NULL);
367         g_return_if_fail (attributes != NULL);
368         g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
369
370         /* Warnings raised already */
371         if (!_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
372                 return;
373
374         secret_service_lookup (NULL, schema, attributes,
375                                cancellable, callback, user_data);
376 }
377
378 /**
379  * secret_password_lookup_nonpageable_finish: (skip)
380  * @result: the asynchronous result passed to the callback
381  * @error: location to place an error on failure
382  *
383  * Finish an asynchronous operation to lookup a password in the secret service.
384  *
385  * Returns: (transfer full): a new password string stored in nonpageable memory
386  *          which must be freed with secret_password_free() when done
387  */
388 gchar *
389 secret_password_lookup_nonpageable_finish (GAsyncResult *result,
390                                            GError **error)
391 {
392         SecretValue *value;
393
394         g_return_val_if_fail (error == NULL || *error == NULL, NULL);
395
396         value = secret_service_lookup_finish (NULL, result, error);
397         if (value == NULL)
398                 return NULL;
399
400         return _secret_value_unref_to_password (value);
401 }
402
403 /**
404  * secret_password_lookup_finish:
405  * @result: the asynchronous result passed to the callback
406  * @error: location to place an error on failure
407  *
408  * Finish an asynchronous operation to lookup a password in the secret service.
409  *
410  * Returns: (transfer full): a new password string which should be freed with
411  *          secret_password_free() or may be freed with g_free() when done
412  */
413 gchar *
414 secret_password_lookup_finish (GAsyncResult *result,
415                                GError **error)
416 {
417         SecretValue *value;
418
419         g_return_val_if_fail (error == NULL || *error == NULL, NULL);
420
421         value = secret_service_lookup_finish (NULL, result, error);
422         if (value == NULL)
423                 return NULL;
424
425         return _secret_value_unref_to_string (value);
426 }
427
428 /**
429  * secret_password_lookup_sync: (skip)
430  * @schema: the schema for the attributes
431  * @cancellable: optional cancellation object
432  * @error: location to place an error on failure
433  * @...: the attribute keys and values, terminated with %NULL
434  *
435  * Lookup a password in the secret service.
436  *
437  * The variable argument list should contain pairs of a) The attribute name as
438  * a null-terminated string, followed by b) attribute value, either a character
439  * string, an int number, or a gboolean value, as defined in the password
440  * @schema. The list of attribtues should be terminated with a %NULL.
441  *
442  * If no secret is found then %NULL is returned.
443  *
444  * This method may block indefinitely and should not be used in user interface
445  * threads.
446  *
447  * Returns: (transfer full): a new password string which should be freed with
448  *          secret_password_free() or may be freed with g_free() when done
449  */
450 gchar *
451 secret_password_lookup_sync (const SecretSchema *schema,
452                              GCancellable *cancellable,
453                              GError **error,
454                              ...)
455 {
456         GHashTable *attributes;
457         gchar *password;
458         va_list va;
459
460         g_return_val_if_fail (schema != NULL, NULL);
461         g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
462         g_return_val_if_fail (error == NULL || *error == NULL, NULL);
463
464         va_start (va, error);
465         attributes = secret_attributes_buildv (schema, va);
466         va_end (va);
467
468         password = secret_password_lookupv_sync (schema, attributes,
469                                                  cancellable, error);
470
471         g_hash_table_unref (attributes);
472
473         return password;
474 }
475
476 /**
477  * secret_password_lookup_nonpageable_sync: (skip)
478  * @schema: the schema for the attributes
479  * @cancellable: optional cancellation object
480  * @error: location to place an error on failure
481  * @...: the attribute keys and values, terminated with %NULL
482  *
483  * Lookup a password in the secret service.
484  *
485  * The variable argument list should contain pairs of a) The attribute name as
486  * a null-terminated string, followed by b) attribute value, either a character
487  * string, an int number, or a gboolean value, as defined in the password
488  * @schema. The list of attribtues should be terminated with a %NULL.
489  *
490  * If no secret is found then %NULL is returned.
491  *
492  * This method may block indefinitely and should not be used in user interface
493  * threads.
494  *
495  * Returns: (transfer full): a new password string stored in nonpageable memory
496  *          which must be freed with secret_password_free() when done
497  */
498 gchar *
499 secret_password_lookup_nonpageable_sync (const SecretSchema *schema,
500                                          GCancellable *cancellable,
501                                          GError **error,
502                                          ...)
503 {
504         GHashTable *attributes;
505         gchar *password;
506         va_list va;
507
508         g_return_val_if_fail (schema != NULL, NULL);
509         g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
510         g_return_val_if_fail (error == NULL || *error == NULL, NULL);
511
512         va_start (va, error);
513         attributes = secret_attributes_buildv (schema, va);
514         va_end (va);
515
516         password = secret_password_lookupv_nonpageable_sync (schema, attributes,
517                                                              cancellable, error);
518
519         g_hash_table_unref (attributes);
520
521         return password;
522 }
523
524 /**
525  * secret_password_lookupv_nonpageable_sync: (skip)
526  * @schema: the schema for attributes
527  * @attributes: (element-type utf8 utf8): the attribute keys and values
528  * @cancellable: optional cancellation object
529  * @error: location to place an error on failure
530  *
531  * Lookup a password in the secret service.
532  *
533  * The @attributes should be a set of key and value string pairs.
534  *
535  * If no secret is found then %NULL is returned.
536  *
537  * This method may block indefinitely and should not be used in user interface
538  * threads.
539  *
540  * Returns: (transfer full): a new password string stored in non pageable memory
541  *          which should be freed with secret_password_free() when done
542  */
543 gchar *
544 secret_password_lookupv_nonpageable_sync (const SecretSchema *schema,
545                                           GHashTable *attributes,
546                                           GCancellable *cancellable,
547                                           GError **error)
548 {
549         SecretSync *sync;
550         gchar *password;
551
552         g_return_val_if_fail (schema != NULL, NULL);
553         g_return_val_if_fail (attributes != NULL, NULL);
554         g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
555         g_return_val_if_fail (error == NULL || *error == NULL, NULL);
556
557         /* Warnings raised already */
558         if (!_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
559                 return FALSE;
560
561         sync = _secret_sync_new ();
562         g_main_context_push_thread_default (sync->context);
563
564         secret_password_lookupv (schema, attributes, cancellable,
565                                  _secret_sync_on_result, sync);
566
567         g_main_loop_run (sync->loop);
568
569         password = secret_password_lookup_nonpageable_finish (sync->result, error);
570
571         g_main_context_pop_thread_default (sync->context);
572         _secret_sync_free (sync);
573
574         return password;
575 }
576
577 /**
578  * secret_password_lookupv_sync:
579  * @schema: the schema for attributes
580  * @attributes: (element-type utf8 utf8): the attribute keys and values
581  * @cancellable: optional cancellation object
582  * @error: location to place an error on failure
583  *
584  * Lookup a password in the secret service.
585  *
586  * The @attributes should be a set of key and value string pairs.
587  *
588  * If no secret is found then %NULL is returned.
589  *
590  * This method may block indefinitely and should not be used in user interface
591  * threads.
592  *
593  * Returns: (transfer full): a new password string which should be freed with
594  *          secret_password_free() or may be freed with g_free() when done
595  *
596  * Rename to: secret_password_lookup_sync
597  */
598 gchar *
599 secret_password_lookupv_sync (const SecretSchema *schema,
600                               GHashTable *attributes,
601                               GCancellable *cancellable,
602                               GError **error)
603 {
604         SecretSync *sync;
605         gchar *string;
606
607         g_return_val_if_fail (schema != NULL, NULL);
608         g_return_val_if_fail (attributes != NULL, NULL);
609         g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
610         g_return_val_if_fail (error == NULL || *error == NULL, NULL);
611
612         /* Warnings raised already */
613         if (!_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
614                 return FALSE;
615
616         sync = _secret_sync_new ();
617         g_main_context_push_thread_default (sync->context);
618
619         secret_password_lookupv (schema, attributes, cancellable,
620                                  _secret_sync_on_result, sync);
621
622         g_main_loop_run (sync->loop);
623
624         string = secret_password_lookup_finish (sync->result, error);
625
626         g_main_context_pop_thread_default (sync->context);
627         _secret_sync_free (sync);
628
629         return string;
630 }
631
632 /**
633  * secret_password_remove:
634  * @schema: the schema for the attributes
635  * @cancellable: optional cancellation object
636  * @callback: called when the operation completes
637  * @user_data: data to be passed to the callback
638  * @...: the attribute keys and values, terminated with %NULL
639  *
640  * Remove a password from the secret service.
641  *
642  * The variable argument list should contain pairs of a) The attribute name as
643  * a null-terminated string, followed by b) attribute value, either a character
644  * string, an int number, or a gboolean value, as defined in the password
645  * @schema. The list of attribtues should be terminated with a %NULL.
646  *
647  * If multiple items match the attributes, then only one will be deleted.
648  *
649  * This method will return immediately and complete asynchronously.
650  */
651 void
652 secret_password_remove (const SecretSchema *schema,
653                         GCancellable *cancellable,
654                         GAsyncReadyCallback callback,
655                         gpointer user_data,
656                         ...)
657 {
658         GHashTable *attributes;
659         va_list va;
660
661         g_return_if_fail (schema != NULL);
662         g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
663
664         va_start (va, user_data);
665         attributes = secret_attributes_buildv (schema, va);
666         va_end (va);
667
668         secret_password_removev (schema, attributes, cancellable,
669                                  callback, user_data);
670
671         g_hash_table_unref (attributes);
672 }
673
674
675 /**
676  * secret_password_removev:
677  * @schema: the schema for the attributes
678  * @attributes: (element-type utf8 utf8): the attribute keys and values
679  * @cancellable: optional cancellation object
680  * @callback: called when the operation completes
681  * @user_data: data to be passed to the callback
682  *
683  * Remove passwords from the secret service.
684  *
685  * The @attributes should be a set of key and value string pairs.
686  *
687  * All unlocked items that match the attributes will be deleted.
688  *
689  * This method will return immediately and complete asynchronously.
690  *
691  * Rename to: secret_password_remove
692  */
693 void
694 secret_password_removev (const SecretSchema *schema,
695                          GHashTable *attributes,
696                          GCancellable *cancellable,
697                          GAsyncReadyCallback callback,
698                          gpointer user_data)
699 {
700         g_return_if_fail (schema != NULL);
701         g_return_if_fail (attributes != NULL);
702         g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
703
704         /* Warnings raised already */
705         if (!_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
706                 return;
707
708         secret_service_remove (NULL, schema, attributes,
709                                cancellable, callback, user_data);
710 }
711
712 /**
713  * secret_password_remove_finish:
714  * @result: the asynchronous result passed to the callback
715  * @error: location to place an error on failure
716  *
717  * Finish an asynchronous operation to remove passwords from the secret
718  * service.
719  *
720  * Returns: whether any passwords were removed
721  */
722 gboolean
723 secret_password_remove_finish (GAsyncResult *result,
724                                GError **error)
725 {
726         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
727         return secret_service_remove_finish (NULL, result, error);
728 }
729
730 /**
731  * secret_password_remove_sync:
732  * @schema: the schema for the attributes
733  * @cancellable: optional cancellation object
734  * @error: location to place an error on failure
735  * @...: the attribute keys and values, terminated with %NULL
736  *
737  * Remove passwords from the secret service.
738  *
739  * The variable argument list should contain pairs of a) The attribute name as
740  * a null-terminated string, followed by b) attribute value, either a character
741  * string, an int number, or a gboolean value, as defined in the password
742  * @schema. The list of attribtues should be terminated with a %NULL.
743  *
744  * All unlocked items that match the attributes will be deleted.
745  *
746  * This method may block indefinitely and should not be used in user interface
747  * threads.
748  *
749  * Returns: whether the any passwords were removed
750  */
751 gboolean
752 secret_password_remove_sync (const SecretSchema* schema,
753                              GCancellable *cancellable,
754                              GError **error,
755                              ...)
756 {
757         GHashTable *attributes;
758         gboolean result;
759         va_list va;
760
761         g_return_val_if_fail (schema != NULL, FALSE);
762         g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
763         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
764
765         va_start (va, error);
766         attributes = secret_attributes_buildv (schema, va);
767         va_end (va);
768
769         result = secret_password_removev_sync (schema, attributes,
770                                                cancellable, error);
771
772         g_hash_table_unref (attributes);
773
774         return result;
775 }
776
777 /**
778  * secret_password_removev_sync:
779  * @schema: the schema for the attributes
780  * @attributes: (element-type utf8 utf8): the attribute keys and values
781  * @cancellable: optional cancellation object
782  * @error: location to place an error on failure
783  *
784  * Remove a password from the secret service.
785  *
786  * The @attributes should be a set of key and value string pairs.
787  *
788  * All unlocked items that match the attributes will be deleted.
789  *
790  * This method may block indefinitely and should not be used in user interface
791  * threads.
792  *
793  * Returns: whether any passwords were removed
794  *
795  * Rename to: secret_password_remove_sync
796  */
797 gboolean
798 secret_password_removev_sync (const SecretSchema *schema,
799                               GHashTable *attributes,
800                               GCancellable *cancellable,
801                               GError **error)
802 {
803         SecretSync *sync;
804         gboolean result;
805
806         g_return_val_if_fail (schema != NULL, FALSE);
807         g_return_val_if_fail (attributes != NULL, FALSE);
808         g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
809         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
810
811         /* Warnings raised already */
812         if (!_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
813                 return FALSE;
814
815         sync = _secret_sync_new ();
816         g_main_context_push_thread_default (sync->context);
817
818         secret_password_removev (schema, attributes, cancellable,
819                                  _secret_sync_on_result, sync);
820
821         g_main_loop_run (sync->loop);
822
823         result = secret_password_remove_finish (sync->result, error);
824
825         g_main_context_pop_thread_default (sync->context);
826         _secret_sync_free (sync);
827
828         return result;
829 }
830
831 /**
832  * secret_password_free: (skip)
833  * @password: (allow-none): password to free
834  *
835  * Clear the memory used by a password, and then free it.
836  *
837  * This function must be used to free nonpageable memory returned by
838  * secret_password_lookup_nonpageable_finish(),
839  * secret_password_lookup_nonpageable_sync() or
840  * secret_password_lookupv_nonpageable_sync().
841  */
842 void
843 secret_password_free (gchar *password)
844 {
845         if (password == NULL)
846                 return;
847
848         egg_secure_strfree (password);
849 }
850
851 /**
852  * secret_password_clear:
853  * @password: (allow-none): password to clear
854  *
855  * Clear the memory used by a password.
856  */
857 void
858 secret_password_clear (gchar *password)
859 {
860         if (password == NULL)
861                 return;
862
863         egg_secure_strclear (password);
864 }