1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of gsignond
6 * Copyright (C) 2012 Intel Corporation.
8 * Contact: Imran Zaman <imran.zaman@linux.intel.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 #include "gsignond/gsignond-log.h"
28 #include "gsignond/gsignond-credentials.h"
29 #include "common/db/gsignond-db-error.h"
30 #include "gsignond-db-credentials-database.h"
32 #define GSIGNOND_DB_CREDENTIALS_DATABASE_GET_PRIVATE(obj) \
33 (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
34 GSIGNOND_DB_TYPE_CREDENTIALS_DATABASE, \
35 GSignondDbCredentialsDatabasePrivate))
37 G_DEFINE_TYPE (GSignondDbCredentialsDatabase, gsignond_db_credentials_database,
40 struct _GSignondDbCredentialsDatabasePrivate
42 GSignondDbMetadataDatabase *metadata_db;
53 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
56 _set_property (GObject *object, guint prop_id, const GValue *value,
59 GSignondDbCredentialsDatabase *self =
60 GSIGNOND_DB_CREDENTIALS_DATABASE (object);
64 g_assert (self->config == NULL);
65 self->config = g_value_dup_object (value);
68 g_assert (self->secret_storage == NULL);
69 self->secret_storage = g_value_dup_object (value);
72 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
77 _get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
79 GSignondDbCredentialsDatabase *self =
80 GSIGNOND_DB_CREDENTIALS_DATABASE (object);
84 g_value_set_object (value, self->config);
87 g_value_set_object (value, self->secret_storage);
90 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
95 _gsignond_db_credentials_database_dispose (GObject *gobject)
97 g_return_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (gobject));
98 GSignondDbCredentialsDatabase *self =
99 GSIGNOND_DB_CREDENTIALS_DATABASE (gobject);
102 g_object_unref (self->config);
105 if (self->secret_storage) {
106 g_object_unref (self->secret_storage);
107 self->secret_storage = NULL;
109 if (self->priv->metadata_db) {
110 g_object_unref (self->priv->metadata_db);
111 self->priv->metadata_db = NULL;
113 G_OBJECT_CLASS (gsignond_db_credentials_database_parent_class)->dispose (
118 gsignond_db_credentials_database_class_init (
119 GSignondDbCredentialsDatabaseClass *klass)
121 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
123 gobject_class->set_property = _set_property;
124 gobject_class->get_property = _get_property;
125 gobject_class->dispose = _gsignond_db_credentials_database_dispose;
127 properties[PROP_CONFIG] = g_param_spec_object (
130 "Configuration object",
131 GSIGNOND_TYPE_CONFIG,
132 G_PARAM_CONSTRUCT_ONLY |
134 G_PARAM_STATIC_STRINGS);
135 properties[PROP_STORAGE] = g_param_spec_object (
138 "Secure Storage object",
139 GSIGNOND_TYPE_SECRET_STORAGE,
140 G_PARAM_CONSTRUCT_ONLY |
142 G_PARAM_STATIC_STRINGS);
143 g_object_class_install_properties (gobject_class, N_PROPERTIES, properties);
145 g_type_class_add_private (klass,
146 sizeof (GSignondDbCredentialsDatabasePrivate));
150 gsignond_db_credentials_database_init (
151 GSignondDbCredentialsDatabase *self)
153 self->priv = GSIGNOND_DB_CREDENTIALS_DATABASE_GET_PRIVATE (self);
155 self->secret_storage = NULL;
156 self->priv->metadata_db = NULL;
160 * gsignond_db_credentials_database_new:
162 * @config: (transfer none) the #GSignondConfig object
163 * @storage: (transfer none) the #GSignondSecretStorage object
165 * Creates new #GSignondDbCredentialsDatabase object
167 * Returns: (transfer full) the #GSignondDbCredentialsDatabase object
169 GSignondDbCredentialsDatabase *
170 gsignond_db_credentials_database_new (
171 GSignondConfig *config,
172 GSignondSecretStorage *storage)
175 GSignondDbCredentialsDatabase *self = NULL;
176 self = GSIGNOND_DB_CREDENTIALS_DATABASE (
177 g_object_new (GSIGNOND_DB_TYPE_CREDENTIALS_DATABASE,
184 self->priv->metadata_db = gsignond_db_metadata_database_new (
186 if (self->priv->metadata_db) {
187 gsignond_db_metadata_database_open (self->priv->metadata_db);
194 * gsignond_db_credentials_database_open_secret_storage:
196 * @self: instance of #GSignondDbCredentialsDatabase
198 * Opens (and initializes) secret storage.
200 * Returns: TRUE if successful, FALSE otherwise.
203 gsignond_db_credentials_database_open_secret_storage (
204 GSignondDbCredentialsDatabase *self)
206 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
207 g_return_val_if_fail (self->secret_storage != NULL, FALSE);
209 return gsignond_secret_storage_open_db (self->secret_storage);
213 * gsignond_db_credentials_database_close_secret_storage:
215 * @self: instance of #GSignondDbCredentialsDatabase
217 * Closes the secret storage.
219 * Returns: TRUE if successful, FALSE otherwise.
222 gsignond_db_credentials_database_close_secret_storage (
223 GSignondDbCredentialsDatabase *self)
225 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
226 g_return_val_if_fail (self->secret_storage != NULL, FALSE);
228 return gsignond_secret_storage_close_db (self->secret_storage);
232 * gsignond_db_credentials_database_is_open_secret_storage:
234 * @self: instance of #GSignondDbCredentialsDatabase
236 * Checks if secret storage is open or not.
238 * Returns: TRUE if secret storage is open, FALSE otherwise.
241 gsignond_db_credentials_database_is_open_secret_storage (
242 GSignondDbCredentialsDatabase *self)
244 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
245 g_return_val_if_fail (self->secret_storage != NULL, FALSE);
247 return gsignond_secret_storage_is_open_db (self->secret_storage);
251 * gsignond_db_credentials_database_clear:
253 * @self: instance of #GSignondDbCredentialsDatabase
255 * Clears the credentials database.
257 * Returns: TRUE if secret storage is open, FALSE otherwise.
260 gsignond_db_credentials_database_clear (GSignondDbCredentialsDatabase *self)
262 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
263 g_return_val_if_fail (self->secret_storage != NULL, FALSE);
265 return gsignond_secret_storage_clear_db (self->secret_storage) &&
266 gsignond_db_sql_database_clear (
267 GSIGNOND_DB_SQL_DATABASE (self->priv->metadata_db));
271 * gsignond_db_credentials_database_load_identity:
273 * @self: instance of #GSignondDbCredentialsDatabase
274 * @identity_id: the id of the identity
275 * @query_secret: whether to query the password or not
277 * Fetches the info associated with the specified identity id.
279 * Returns: (transfer full) the info #GSignondIdentityInfo if successful,
280 * NULL otherwise. When done, it should be freed with
281 * gsignond_identity_info_unref (identity)
283 GSignondIdentityInfo *
284 gsignond_db_credentials_database_load_identity (
285 GSignondDbCredentialsDatabase *self,
286 const guint32 identity_id,
287 gboolean query_secret)
289 GSignondIdentityInfo *identity = NULL;
290 gboolean is_un_sec = FALSE;
291 gboolean is_pwd_sec = FALSE;
293 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
295 identity = gsignond_db_metadata_database_get_identity (
296 self->priv->metadata_db, identity_id);
297 if (identity && query_secret &&
298 !gsignond_identity_info_get_is_identity_new (identity) &&
299 gsignond_db_credentials_database_is_open_secret_storage (self)) {
301 is_un_sec = gsignond_identity_info_get_is_username_secret (identity);
302 is_pwd_sec = gsignond_identity_info_get_store_secret (identity);
303 if (is_un_sec || is_pwd_sec) {
304 GSignondCredentials * creds;
305 creds = gsignond_secret_storage_load_credentials (
306 self->secret_storage, identity_id);
309 gsignond_identity_info_set_username (identity,
310 gsignond_credentials_get_username (creds));
312 gsignond_identity_info_set_secret (identity,
313 gsignond_credentials_get_password (creds));
314 g_object_unref (creds);
323 * gsignond_db_credentials_database_load_identities:
325 * @self: instance of #GSignondDbCredentialsDatabase
326 * @filter: (transfer none) filter to apply. Currently supported filters:
327 * ("Owner":GSignondSecurtityContext *context) - Identities matched with this 'context'
328 * ("Type":guint32 type) - Identities matched with 'type'
329 * ("Caption":gchar *caption) - Identties matched/start with 'caption'
331 * Fetches the list of the identities.
333 * Returns: (transfer full) the list if successful, NULL otherwise.
334 * When done list should be freed with gsignond_identity_info_list_free (list)
336 GSignondIdentityInfoList *
337 gsignond_db_credentials_database_load_identities (
338 GSignondDbCredentialsDatabase *self,
339 GSignondDictionary *filter)
341 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
343 return gsignond_db_metadata_database_get_identities (
344 self->priv->metadata_db, filter);
348 * gsignond_db_credentials_database_update_identity:
350 * @self: instance of #GSignondDbCredentialsDatabase
351 * @identity: the identity info which needs to be inserted to db
352 * @store_secret: flag to indicate whether to store the secret or not
354 * Updates the identity info in the credentials database.
356 * Returns: the id of the updated identity, 0 otherwise.
359 gsignond_db_credentials_database_update_identity (
360 GSignondDbCredentialsDatabase *self,
361 GSignondIdentityInfo* identity)
365 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
367 id = gsignond_db_metadata_database_update_identity (self->priv->metadata_db,
371 gsignond_db_credentials_database_is_open_secret_storage (self)) {
372 GSignondCredentials *creds = NULL;
373 gboolean un_sec, pwd_sec;
374 const gchar *tmp_str = NULL;
376 creds = gsignond_credentials_new ();
377 gsignond_credentials_set_id (creds, id);
379 pwd_sec = gsignond_identity_info_get_store_secret (identity) &&
380 (tmp_str = gsignond_identity_info_get_secret (identity));
382 gsignond_credentials_set_password (creds, tmp_str);
385 un_sec = gsignond_identity_info_get_is_username_secret (identity) &&
386 (tmp_str = gsignond_identity_info_get_username (identity));
388 gsignond_credentials_set_username (creds, tmp_str);
391 if (un_sec || pwd_sec) {
392 DBG ("Add credentials to secret storage");
393 gsignond_secret_storage_update_credentials (
394 self->secret_storage, creds);
396 g_object_unref (creds);
403 * gsignond_db_credentials_database_remove_identity:
405 * @self: instance of #GSignondDbCredentialsDatabase
406 * @identity: the identity info which needs to be removed
408 * Removes the identity info from the credentials database.
410 * Returns: TRUE if successful, FALSE otherwise.
413 gsignond_db_credentials_database_remove_identity (
414 GSignondDbCredentialsDatabase *self,
415 const guint32 identity_id)
417 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
419 if (!gsignond_db_credentials_database_is_open_secret_storage (self)) {
420 DBG ("Remove failed as DB is not open");
423 return gsignond_secret_storage_remove_credentials (
424 self->secret_storage,
426 gsignond_db_metadata_database_remove_identity (
427 self->priv->metadata_db,
432 * gsignond_db_credentials_database_check_secret:
434 * @self: instance of #GSignondDbCredentialsDatabase
435 * @identity_id: the id of the identity
436 * @username: the username of the identity
437 * @secret: the secret of the identity
439 * Checks the identity info from the credentials database.
441 * Returns: TRUE if successful, FALSE otherwise.
444 gsignond_db_credentials_database_check_secret (
445 GSignondDbCredentialsDatabase *self,
446 const guint32 identity_id,
447 const gchar *username,
450 GSignondIdentityInfo *identity = NULL;
451 gboolean check = FALSE;
453 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
455 if (!gsignond_db_credentials_database_is_open_secret_storage (self)) {
456 DBG ("Check failed as DB is not open");
460 identity = gsignond_db_metadata_database_get_identity (
461 self->priv->metadata_db, identity_id);
463 GSignondCredentials *creds = NULL;
465 creds = gsignond_credentials_new ();
466 gsignond_credentials_set_id (creds, identity_id);
467 gsignond_credentials_set_password (creds, secret);
468 if (gsignond_identity_info_get_is_username_secret (identity)) {
469 DBG ("Check credentials from storage");
470 gsignond_credentials_set_username (creds, username);
471 check = gsignond_secret_storage_check_credentials (
472 self->secret_storage, creds);
474 gsignond_credentials_set_username (creds, "");
475 check = g_strcmp0 (username,
476 gsignond_identity_info_get_username (identity)) == 0 &&
477 gsignond_secret_storage_check_credentials (
478 self->secret_storage, creds);
480 g_object_unref (creds);
481 gsignond_identity_info_unref (identity);
487 * gsignond_db_credentials_database_load_data:
489 * @self: instance of #GSignondDbCredentialsDatabase
490 * @identity_id: the id of the identity
491 * @method: the name of the method
493 * Fetches the data associated with the identity id and method.
495 * Returns: (transfer full) the data if successful, NULL otherwise.
496 * When done data should be freed with g_hash_table_unref (data)
499 gsignond_db_credentials_database_load_data (
500 GSignondDbCredentialsDatabase *self,
501 const guint32 identity_id,
504 guint32 method_id = 0;
506 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
507 g_return_val_if_fail (method != NULL, NULL);
509 if (identity_id == 0 ||
510 !gsignond_db_credentials_database_is_open_secret_storage (self)) {
511 DBG ("Load data failed - invalid id (%d)/secret storage not opened",
516 method_id = gsignond_db_metadata_database_get_method_id (
517 self->priv->metadata_db,
519 if (method_id == 0) {
520 DBG ("Load data failed - invalid method id");
523 return gsignond_secret_storage_load_data (self->secret_storage,
524 identity_id, method_id);
528 * gsignond_db_credentials_database_update_data:
530 * @self: instance of #GSignondDbCredentialsDatabase
531 * @identity_id: the id of the identity
532 * @method: the name of the method
533 * @data: the data to be stored
535 * Stores/updates the data associated with the identity id and method.
537 * Returns: (transfer full) the data if successful, NULL otherwise.
538 * When done data should be freed with g_hash_table_unref (data)
541 gsignond_db_credentials_database_update_data (
542 GSignondDbCredentialsDatabase *self,
543 const guint32 identity_id,
547 guint32 method_id = 0;
549 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
550 g_return_val_if_fail (method != NULL && data != NULL, FALSE);
552 if (identity_id == 0 ||
553 !gsignond_db_credentials_database_is_open_secret_storage (self)) {
554 DBG ("Update data failed - invalid id(%d)/secret storage not opened",
559 method_id = gsignond_db_metadata_database_get_method_id (
560 self->priv->metadata_db,
562 if (method_id == 0) {
563 if (!gsignond_db_metadata_database_insert_method (
564 self->priv->metadata_db,
567 DBG ("Update data failed - insertion of method to DB failed");
571 return gsignond_secret_storage_update_data (self->secret_storage,
572 identity_id, method_id, data);
576 * gsignond_db_credentials_database_remove_data:
578 * @self: instance of #GSignondDbCredentialsDatabase
579 * @identity_id: the id of the identity
580 * @method: the name of the method
582 * Fetches the data associated with the identity id and method.
584 * Returns: (transfer full) the data if successful, NULL otherwise.
585 * When done data should be freed with g_hash_table_unref (data)
588 gsignond_db_credentials_database_remove_data (
589 GSignondDbCredentialsDatabase *self,
590 const guint32 identity_id,
593 guint32 method_id = 0;
595 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
597 if (identity_id == 0 ||
598 !gsignond_db_credentials_database_is_open_secret_storage (self)) {
599 DBG ("Remove data failed - invalid id (%d)/secret storage not opened",
604 if (method && strlen (method) > 0) {
605 method_id = gsignond_db_metadata_database_get_method_id (
606 self->priv->metadata_db,
608 if (method_id == 0) {
609 DBG ("Remove data failed - method not found");
613 return gsignond_secret_storage_remove_data (self->secret_storage,
614 identity_id, method_id);
618 * gsignond_db_credentials_database_get_methods:
620 * @self: instance of #GSignondDbCredentialsDatabase
621 * @identity_id: the id of the identity
622 * @sec_ctx: the security context
624 * Fetches the list of the methods associated with the specified identity id.
626 * Returns: (transfer full) the list if successful, NULL otherwise.
627 * When done list should be freed with g_list_free_full (list, g_free)
630 gsignond_db_credentials_database_get_methods (
631 GSignondDbCredentialsDatabase *self,
632 const guint32 identity_id,
633 GSignondSecurityContext* sec_ctx)
635 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
637 return gsignond_db_metadata_database_get_methods (self->priv->metadata_db,
638 identity_id, sec_ctx);
642 * gsignond_db_credentials_database_insert_reference:
644 * @self: instance of #GSignondDbCredentialsDatabase
645 * @identity_id: the id of the identity
646 * @ref_owner: the owner security context
647 * @reference: reference for the given identity
649 * Insert reference into the database for the given identity id.
651 * Returns: TRUE if successful,FALSE otherwise.
654 gsignond_db_credentials_database_insert_reference (
655 GSignondDbCredentialsDatabase *self,
656 const guint32 identity_id,
657 const GSignondSecurityContext *ref_owner,
658 const gchar *reference)
660 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
662 return gsignond_db_metadata_database_insert_reference (
663 self->priv->metadata_db, identity_id, ref_owner,reference);
667 * gsignond_db_credentials_database_remove_reference:
669 * @self: instance of #GSignondDbCredentialsDatabase
670 * @identity_id: the id of the identity
671 * @ref_owner: the owner security context
672 * @reference: reference for the given identity
674 * Removes reference from the database for the given identity id.
676 * Returns: TRUE if successful,FALSE otherwise.
679 gsignond_db_credentials_database_remove_reference (
680 GSignondDbCredentialsDatabase *self,
681 const guint32 identity_id,
682 const GSignondSecurityContext *ref_owner,
683 const gchar *reference)
685 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
687 return gsignond_db_metadata_database_remove_reference (
688 self->priv->metadata_db, identity_id, ref_owner, reference);
692 * gsignond_db_credentials_database_get_references:
694 * @self: instance of #GSignondDbCredentialsDatabase
695 * @identity_id: the id of the identity
696 * @ref_owner: the owner security context
698 * Gets references from the database for the given identity id.
700 * Returns: (transfer full) the list #GList if successful,
701 * NULL otherwise. When done the list should be freed with
702 * g_list_free_full (list, g_free)
705 gsignond_db_credentials_database_get_references (
706 GSignondDbCredentialsDatabase *self,
707 const guint32 identity_id,
708 const GSignondSecurityContext* ref_owner)
710 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
712 return gsignond_db_metadata_database_get_references (
713 self->priv->metadata_db, identity_id, ref_owner);
717 * gsignond_db_credentials_database_get_accesscontrol_list:
719 * @self: instance of #GSignondDbCredentialsDatabase
720 * @identity_id: the id of the identity whose access control list is needed
722 * Gets all the access control list from the database into a list.
724 * Returns: (transfer full) the list #GSignondSecurityContextList if successful,
725 * NULL otherwise. When done the list should be freed with
726 * gsignond_identity_info_list_free
728 GSignondSecurityContextList *
729 gsignond_db_credentials_database_get_accesscontrol_list(
730 GSignondDbCredentialsDatabase *self,
731 const guint32 identity_id)
733 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
735 return gsignond_db_metadata_database_get_accesscontrol_list (
736 self->priv->metadata_db, identity_id);
740 * gsignond_db_credentials_database_get_owner:
742 * @self: instance of #GSignondDbCredentialsDatabase
743 * @identity_id: the id of the identity whose owner list is needed
745 * Gets the onwer of the identity referred by @identity_id from the database.
747 * Returns: (transfer full) the list #GSignondSecurityContext if successful,
748 * NULL otherwise. When done the list should be freed with
749 * gsignond_identity_info_unref
751 GSignondSecurityContext *
752 gsignond_db_credentials_database_get_owner(
753 GSignondDbCredentialsDatabase *self,
754 const guint32 identity_id)
756 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
758 return gsignond_db_metadata_database_get_owner (
759 self->priv->metadata_db, identity_id);
763 * gsignond_db_credentials_database_get_identity_owner:
765 * @self: instance of #GSignondDbCredentialsDatabase
766 * @identity_id: the id of the identity whose owner is needed
768 * Gets the owner from the database for the given identity id.
770 * Returns: (transfer full) the #GSignondSecurityContext if successful,
771 * NULL otherwise. When done the context, it should be freed with
772 * gsignond_identity_info_unref
774 GSignondSecurityContext *
775 gsignond_db_credentials_database_get_identity_owner (
776 GSignondDbCredentialsDatabase *self,
777 const guint32 identity_id)
779 GSignondSecurityContext *ctx = NULL;
781 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
783 ctx = gsignond_db_metadata_database_get_owner (
784 self->priv->metadata_db, identity_id);
789 gsignond_db_credentials_database_get_last_error (
790 GSignondDbCredentialsDatabase *self)
792 g_return_val_if_fail (self && GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
794 return gsignond_db_sql_database_get_last_error (
795 GSIGNOND_DB_SQL_DATABASE (self->priv->metadata_db));