1 /* GSecret - GLib wrapper for Secret Service
3 * Copyright 2011 Collabora Ltd.
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 of the licence or (at
8 * your option) any later version.
10 * See the included COPYING file for more information.
15 #include "gsecret-password.h"
16 #include "gsecret-private.h"
17 #include "gsecret-value.h"
19 #include <egg/egg-secure-memory.h>
22 const GSecretSchema *schema;
23 GHashTable *attributes;
24 gchar *collection_path;
27 GCancellable *cancellable;
32 store_closure_free (gpointer data)
34 StoreClosure *closure = data;
35 g_hash_table_unref (closure->attributes);
36 g_free (closure->collection_path);
37 g_free (closure->label);
38 gsecret_value_unref (closure->value);
39 g_clear_object (&closure->cancellable);
40 g_slice_free (StoreClosure, closure);
44 on_store_complete (GObject *source,
48 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
49 StoreClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
52 closure->created = gsecret_service_store_finish (GSECRET_SERVICE (source),
55 g_simple_async_result_take_error (res, error);
57 g_simple_async_result_complete (res);
62 on_store_connected (GObject *source,
66 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
67 StoreClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
68 GSecretService *service;
71 service = gsecret_service_get_finish (result, &error);
73 gsecret_service_storev (service, closure->schema,
75 closure->collection_path,
76 closure->label, closure->value,
80 g_object_unref (service);
83 g_simple_async_result_take_error (res, error);
84 g_simple_async_result_complete (res);
91 gsecret_password_store (const GSecretSchema *schema,
92 const gchar *collection_path,
94 const gchar *password,
95 GCancellable *cancellable,
96 GAsyncReadyCallback callback,
100 GHashTable *attributes;
103 g_return_if_fail (schema != NULL);
104 g_return_if_fail (collection_path != NULL);
105 g_return_if_fail (label != NULL);
106 g_return_if_fail (password != NULL);
107 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
109 va_start (va, user_data);
110 attributes = _gsecret_util_attributes_for_varargs (schema, va);
113 gsecret_password_storev (schema, collection_path, label, password, attributes,
114 cancellable, callback, user_data);
116 g_hash_table_unref (attributes);
120 gsecret_password_storev (const GSecretSchema *schema,
121 const gchar *collection_path,
123 const gchar *password,
124 GHashTable *attributes,
125 GCancellable *cancellable,
126 GAsyncReadyCallback callback,
129 GSimpleAsyncResult *res;
130 StoreClosure *closure;
132 g_return_if_fail (schema != NULL);
133 g_return_if_fail (collection_path != NULL);
134 g_return_if_fail (label != NULL);
135 g_return_if_fail (password != NULL);
136 g_return_if_fail (attributes != NULL);
137 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
139 res = g_simple_async_result_new (NULL, callback, user_data,
140 gsecret_password_storev);
141 closure = g_slice_new0 (StoreClosure);
142 closure->schema = schema;
143 closure->collection_path = g_strdup (collection_path);
144 closure->label = g_strdup (label);
145 closure->value = gsecret_value_new (password, -1, "text/plain");
146 closure->attributes = g_hash_table_ref (attributes);
147 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
148 g_simple_async_result_set_op_res_gpointer (res, closure, store_closure_free);
150 gsecret_service_get (GSECRET_SERVICE_OPEN_SESSION, cancellable,
151 on_store_connected, g_object_ref (res));
153 g_object_unref (res);
157 gsecret_password_store_finish (GAsyncResult *result,
160 GSimpleAsyncResult *res;
161 StoreClosure *closure;
163 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
164 g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
165 gsecret_password_storev), FALSE);
167 res = G_SIMPLE_ASYNC_RESULT (result);
168 if (g_simple_async_result_propagate_error (res, error))
171 closure = g_simple_async_result_get_op_res_gpointer (res);
172 return closure->created;
176 gsecret_password_store_sync (const GSecretSchema *schema,
177 const gchar *collection_path,
179 const gchar *password,
180 GCancellable *cancellable,
184 GHashTable *attributes;
188 g_return_val_if_fail (schema != NULL, FALSE);
189 g_return_val_if_fail (label != NULL, FALSE);
190 g_return_val_if_fail (password != NULL, FALSE);
191 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
192 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
194 va_start (va, error);
195 attributes = _gsecret_util_attributes_for_varargs (schema, va);
198 ret = gsecret_password_storev_sync (schema, collection_path, label, password,
199 attributes, cancellable, error);
201 g_hash_table_unref (attributes);
206 gsecret_password_storev_sync (const GSecretSchema *schema,
207 const gchar *collection_path,
209 const gchar *password,
210 GHashTable *attributes,
211 GCancellable *cancellable,
217 g_return_val_if_fail (schema != NULL, FALSE);
218 g_return_val_if_fail (collection_path != NULL, FALSE);
219 g_return_val_if_fail (label != NULL, FALSE);
220 g_return_val_if_fail (password != NULL, FALSE);
221 g_return_val_if_fail (attributes != 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);
225 sync = _gsecret_sync_new ();
226 g_main_context_push_thread_default (sync->context);
228 gsecret_password_storev (schema, collection_path, label, password, attributes,
229 cancellable, _gsecret_sync_on_result, sync);
231 g_main_loop_run (sync->loop);
233 ret = gsecret_password_store_finish (sync->result, error);
235 g_main_context_pop_thread_default (sync->context);
236 _gsecret_sync_free (sync);
242 GCancellable *cancellable;
243 GHashTable *attributes;
248 lookup_closure_free (gpointer data)
250 LookupClosure *closure = data;
251 g_clear_object (&closure->cancellable);
252 g_hash_table_unref (closure->attributes);
254 gsecret_value_unref (closure->value);
255 g_slice_free (LookupClosure, closure);
259 gsecret_password_lookup (const GSecretSchema *schema,
260 GCancellable *cancellable,
261 GAsyncReadyCallback callback,
265 GHashTable *attributes;
268 g_return_if_fail (schema != NULL);
269 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
271 va_start (va, user_data);
272 attributes = _gsecret_util_attributes_for_varargs (schema, va);
275 gsecret_password_lookupv (attributes, cancellable, callback, user_data);
277 g_hash_table_unref (attributes);
281 on_lookup_complete (GObject *source,
282 GAsyncResult *result,
285 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
286 LookupClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
287 GError *error = NULL;
289 closure->value = gsecret_service_lookup_finish (GSECRET_SERVICE (source),
293 g_simple_async_result_take_error (res, error);
295 g_simple_async_result_complete (res);
296 g_object_unref (res);
300 on_lookup_connected (GObject *source,
301 GAsyncResult *result,
304 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
305 LookupClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
306 GSecretService *service;
307 GError *error = NULL;
309 service = gsecret_service_get_finish (result, &error);
311 g_simple_async_result_take_error (res, error);
312 g_simple_async_result_complete (res);
315 gsecret_service_lookupv (service, closure->attributes, closure->cancellable,
316 on_lookup_complete, g_object_ref (res));
317 g_object_unref (service);
320 g_object_unref (res);
324 gsecret_password_lookupv (GHashTable *attributes,
325 GCancellable *cancellable,
326 GAsyncReadyCallback callback,
329 GSimpleAsyncResult *res;
330 LookupClosure *closure;
332 g_return_if_fail (attributes != NULL);
333 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
335 res = g_simple_async_result_new (NULL, callback, user_data,
336 gsecret_password_lookupv);
337 closure = g_slice_new0 (LookupClosure);
338 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
339 closure->attributes = g_hash_table_ref (attributes);
340 g_simple_async_result_set_op_res_gpointer (res, closure, lookup_closure_free);
342 gsecret_service_get (GSECRET_SERVICE_OPEN_SESSION, cancellable,
343 on_lookup_connected, g_object_ref (res));
345 g_object_unref (res);
349 gsecret_password_lookup_finish (GAsyncResult *result,
352 GSimpleAsyncResult *res;
353 LookupClosure *closure;
354 const gchar *content_type;
355 gchar *password = NULL;
357 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
358 g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
359 gsecret_password_lookupv), NULL);
361 res = G_SIMPLE_ASYNC_RESULT (result);
362 if (g_simple_async_result_propagate_error (res, error))
365 closure = g_simple_async_result_get_op_res_gpointer (res);
366 content_type = gsecret_value_get_content_type (closure->value);
367 if (content_type && g_str_equal (content_type, "text/plain")) {
368 password = _gsecret_value_unref_to_password (closure->value);
369 closure->value = NULL;
376 gsecret_password_lookup_sync (const GSecretSchema *schema,
377 GCancellable *cancellable,
381 GHashTable *attributes;
385 g_return_val_if_fail (schema != NULL, NULL);
386 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
387 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
389 va_start (va, error);
390 attributes = _gsecret_util_attributes_for_varargs (schema, va);
393 password = gsecret_password_lookupv_sync (attributes, cancellable, error);
395 g_hash_table_unref (attributes);
401 gsecret_password_lookupv_sync (GHashTable *attributes,
402 GCancellable *cancellable,
408 g_return_val_if_fail (attributes != NULL, NULL);
409 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
410 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
412 sync = _gsecret_sync_new ();
413 g_main_context_push_thread_default (sync->context);
415 gsecret_password_lookupv (attributes, cancellable,
416 _gsecret_sync_on_result, sync);
418 g_main_loop_run (sync->loop);
420 password = gsecret_password_lookup_finish (sync->result, error);
422 g_main_context_pop_thread_default (sync->context);
423 _gsecret_sync_free (sync);
429 GCancellable *cancellable;
430 GHashTable *attributes;
435 delete_closure_free (gpointer data)
437 DeleteClosure *closure = data;
438 g_clear_object (&closure->cancellable);
439 g_hash_table_unref (closure->attributes);
440 g_slice_free (DeleteClosure, closure);
444 gsecret_password_remove (const GSecretSchema *schema,
445 GCancellable *cancellable,
446 GAsyncReadyCallback callback,
450 GHashTable *attributes;
453 g_return_if_fail (schema != NULL);
454 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
456 va_start (va, user_data);
457 attributes = _gsecret_util_attributes_for_varargs (schema, va);
460 gsecret_password_removev (attributes, cancellable,
461 callback, user_data);
463 g_hash_table_unref (attributes);
467 on_delete_complete (GObject *source,
468 GAsyncResult *result,
471 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
472 DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
473 GError *error = NULL;
475 closure->deleted = gsecret_service_remove_finish (GSECRET_SERVICE (source),
478 g_simple_async_result_take_error (res, error);
479 g_simple_async_result_complete (res);
481 g_object_unref (res);
485 on_delete_connect (GObject *source,
486 GAsyncResult *result,
489 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
490 DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
491 GSecretService *service;
492 GError *error = NULL;
494 service = gsecret_service_get_finish (result, &error);
496 gsecret_service_removev (service, closure->attributes,
497 closure->cancellable, on_delete_complete,
499 g_object_unref (service);
502 g_simple_async_result_take_error (res, error);
503 g_simple_async_result_complete (res);
506 g_object_unref (res);
510 gsecret_password_removev (GHashTable *attributes,
511 GCancellable *cancellable,
512 GAsyncReadyCallback callback,
515 GSimpleAsyncResult *res;
516 DeleteClosure *closure;
518 g_return_if_fail (attributes != NULL);
519 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
521 res = g_simple_async_result_new (NULL, callback, user_data,
522 gsecret_password_removev);
523 closure = g_slice_new0 (DeleteClosure);
524 closure->attributes = g_hash_table_ref (attributes);
525 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
526 g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free);
528 gsecret_service_get (GSECRET_SERVICE_NONE, cancellable,
529 on_delete_connect, g_object_ref (res));
531 g_object_unref (res);
535 gsecret_password_remove_finish (GAsyncResult *result,
538 DeleteClosure *closure;
539 GSimpleAsyncResult *res;
541 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
542 g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
543 gsecret_password_removev), FALSE);
545 res = G_SIMPLE_ASYNC_RESULT (result);
546 if (g_simple_async_result_propagate_error (res, error))
549 closure = g_simple_async_result_get_op_res_gpointer (res);
550 return closure->deleted;
554 gsecret_password_remove_sync (const GSecretSchema* schema,
555 GCancellable *cancellable,
559 GHashTable *attributes;
563 g_return_val_if_fail (schema != NULL, FALSE);
564 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
565 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
567 va_start (va, error);
568 attributes = _gsecret_util_attributes_for_varargs (schema, va);
571 result = gsecret_password_removev_sync (attributes, cancellable, error);
573 g_hash_table_unref (attributes);
579 gsecret_password_removev_sync (GHashTable *attributes,
580 GCancellable *cancellable,
586 g_return_val_if_fail (attributes != NULL, FALSE);
587 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
588 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
590 sync = _gsecret_sync_new ();
591 g_main_context_push_thread_default (sync->context);
593 gsecret_password_removev (attributes, cancellable,
594 _gsecret_sync_on_result, sync);
596 g_main_loop_run (sync->loop);
598 result = gsecret_password_remove_finish (sync->result, error);
600 g_main_context_pop_thread_default (sync->context);
601 _gsecret_sync_free (sync);
607 gsecret_password_free (gpointer password)
609 if (password == NULL)
612 egg_secure_strfree (password);