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