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
26 #include "gsignond-db-secret-database.h"
27 #include "gsignond-db-error.h"
29 #include "gsignond/gsignond-log.h"
30 #include "gsignond/gsignond-secret-storage.h"
32 #define GSIGNOND_SECRET_DB_FILENAME "secret.db"
35 * SECTION:gsignond-secret-storage
36 * @short_description: provides access to the database that stores user credentials and identity/method cache
37 * @include: gsignond/gsignond-secret-storage.h
39 * #GSignondSecretStorage provides access to the database where sensitive identity
40 * data (#GSignondCredentials) and identity/method cache are stored. It's preferred
41 * that this database is protected against access by processes other than gSSO.
43 * gSSO can be configured to use a custom extension
44 * that provides a subclassed implementation of #GSignondSecretStorage
45 * (see #GSignondExtension), otherwise a default implementation is used.
49 * GSignondSecretStorage:
51 * Opaque #GSignondSecretStorage data structure.
54 #define GSIGNOND_SECRET_STORAGE_GET_PRIVATE(obj) \
55 (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
56 GSIGNOND_TYPE_SECRET_STORAGE, \
57 GSignondSecretStoragePrivate))
59 struct _GSignondSecretStoragePrivate
61 GSignondDbSecretDatabase *database;
64 G_DEFINE_TYPE (GSignondSecretStorage, gsignond_secret_storage,
74 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
77 _set_property (GObject *object, guint prop_id, const GValue *value,
80 GSignondSecretStorage *self = GSIGNOND_SECRET_STORAGE (object);
84 g_assert (self->config == NULL);
85 self->config = g_value_dup_object (value);
88 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
93 _get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
95 GSignondSecretStorage *self = GSIGNOND_SECRET_STORAGE (object);
99 g_value_set_object (value, self->config);
102 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
107 _gsignond_secret_storage_dispose (GObject *gobject)
109 g_return_if_fail (GSIGNOND_IS_SECRET_STORAGE (gobject));
110 GSignondSecretStorage *self = GSIGNOND_SECRET_STORAGE (gobject);
112 /* dispose might be called multiple times, so we must guard against
113 * calling g_object_unref() on an invalid GObject.
115 if (self->priv->database) {
116 g_object_unref (self->priv->database);
117 self->priv->database = NULL;
121 g_object_unref (self->config);
125 /* Chain up to the parent class */
126 G_OBJECT_CLASS (gsignond_secret_storage_parent_class)->dispose (
131 _open_db (GSignondSecretStorage *self)
133 const gchar *dir = NULL;
134 gchar *db_filename = NULL;
135 gboolean ret = FALSE;
137 g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
138 g_return_val_if_fail (self->config != NULL, FALSE);
140 dir = gsignond_config_get_string (self->config,
141 GSIGNOND_CONFIG_GENERAL_SECURE_DIR);
143 ERR ("No directory specified in config object for secret db...");
146 db_filename = g_build_filename (dir, GSIGNOND_SECRET_DB_FILENAME, NULL);
148 ERR ("Invalid db filename...");
152 if (gsignond_secret_storage_is_open_db (self)) {
153 g_debug("SecretDB is already open. Closing first to start again...");
154 gsignond_secret_storage_close_db (self);
157 if (self->priv->database == NULL) {
158 self->priv->database = gsignond_db_secret_database_new ();
161 ret = gsignond_db_sql_database_open (
162 GSIGNOND_DB_SQL_DATABASE (self->priv->database),
164 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
165 g_free (db_filename);
167 ERR ("Open DB failed");
168 g_object_unref (self->priv->database);
169 self->priv->database = NULL;
176 _close_db (GSignondSecretStorage *self)
178 g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
180 if (self->priv->database != NULL) {
181 gsignond_db_sql_database_close (GSIGNOND_DB_SQL_DATABASE (
182 self->priv->database));
188 _clear_db (GSignondSecretStorage *self)
190 g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
191 return gsignond_db_sql_database_clear (GSIGNOND_DB_SQL_DATABASE (
192 self->priv->database));
196 _is_open_db (GSignondSecretStorage *self)
198 g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
199 return ((self->priv->database != NULL) &&
200 gsignond_db_sql_database_is_open (GSIGNOND_DB_SQL_DATABASE (
201 self->priv->database)));
204 static GSignondCredentials*
206 GSignondSecretStorage *self,
209 g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
210 return gsignond_db_secret_database_load_credentials (self->priv->database,
215 _update_credentials (
216 GSignondSecretStorage *self,
217 GSignondCredentials *creds)
219 g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
220 return gsignond_db_secret_database_update_credentials (self->priv->database,
225 _remove_credentials (
226 GSignondSecretStorage *self,
229 g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
230 return gsignond_db_secret_database_remove_credentials (self->priv->database,
236 GSignondSecretStorage *self,
237 GSignondCredentials *creds)
239 gboolean equal = FALSE;
240 GSignondCredentials *stored_creds = NULL;
242 g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
243 g_return_val_if_fail (creds != NULL, FALSE);
245 GSignondSecretStorageClass *klass =
246 GSIGNOND_SECRET_STORAGE_GET_CLASS (self);
248 stored_creds = klass->load_credentials (self,
249 gsignond_credentials_get_id(creds));
252 DBG ("Credentials from DB found");
253 equal = gsignond_credentials_equal(creds, stored_creds);
254 g_object_unref (stored_creds);
262 GSignondSecretStorage *self,
264 const guint32 method)
266 g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), NULL);
267 return gsignond_db_secret_database_load_data (self->priv->database,
273 GSignondSecretStorage *self,
275 const guint32 method,
278 g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
279 return gsignond_db_secret_database_update_data (self->priv->database,
285 GSignondSecretStorage *self,
287 const guint32 method)
289 g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
290 return gsignond_db_secret_database_remove_data (self->priv->database,
294 static const GError *
295 _get_last_error (GSignondSecretStorage *self)
297 g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), NULL);
298 if (self->priv->database != NULL) {
299 return gsignond_db_sql_database_get_last_error (
300 GSIGNOND_DB_SQL_DATABASE (self->priv->database));
308 * GSignondSecretStorageClass:
309 * @parent_class: parent class.
310 * @open_db: an implementation of gsignond_secret_storage_open_db()
311 * @close_db: an implementation of gsignond_secret_storage_close_db()
312 * @clear_db: an implementation of gsignond_secret_storage_clear_db()
313 * @is_open_db: an implementation of gsignond_secret_storage_is_open_db()
314 * @load_credentials: an implementation of gsignond_secret_storage_load_credentials()
315 * @update_credentials: an implementation of gsignond_secret_storage_update_credentials()
316 * @remove_credentials: an implementation of gsignond_secret_storage_remove_credentials()
317 * @check_credentials: an implementation of gsignond_secret_storage_check_credentials()
318 * @load_data: an implementation of gsignond_secret_storage_load_data()
319 * @update_data: an implementation of gsignond_secret_storage_update_data()
320 * @remove_data: an implementation of gsignond_secret_storage_remove_data()
321 * @get_last_error: an implementation of gsignond_secret_storage_get_last_error()
323 * #GSignondSecretStorageClass class containing pointers to class methods.
326 gsignond_secret_storage_class_init (GSignondSecretStorageClass *klass)
328 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
330 gobject_class->set_property = _set_property;
331 gobject_class->get_property = _get_property;
332 gobject_class->dispose = _gsignond_secret_storage_dispose;
334 properties[PROP_CONFIG] = g_param_spec_object ("config",
336 "Configuration object",
337 GSIGNOND_TYPE_CONFIG,
338 G_PARAM_CONSTRUCT_ONLY |
340 G_PARAM_STATIC_STRINGS);
341 g_object_class_install_properties (gobject_class, N_PROPERTIES, properties);
343 /* virtual methods */
344 klass->open_db = _open_db;
345 klass->close_db = _close_db;
346 klass->clear_db = _clear_db;
347 klass->is_open_db = _is_open_db;
348 klass->load_credentials = _load_credentials;
349 klass->update_credentials = _update_credentials;
350 klass->remove_credentials = _remove_credentials;
351 klass->check_credentials = _check_credentials;
352 klass->load_data = _load_data;
353 klass->update_data = _update_data;
354 klass->remove_data = _remove_data;
355 klass->get_last_error = _get_last_error;
357 g_type_class_add_private (klass, sizeof (GSignondSecretStoragePrivate));
361 gsignond_secret_storage_init (GSignondSecretStorage *self)
363 self->priv = GSIGNOND_SECRET_STORAGE_GET_PRIVATE (self);
364 self->priv->database = gsignond_db_secret_database_new ();
369 * gsignond_secret_storage_open_db:
370 * @self: instance of #GSignondSecretStorage
372 * Opens (and initializes) the database. The implementation should take
373 * care of creating the DB, if it doesn't exist, and it should use
374 * #GSIGNOND_CONFIG_GENERAL_SECURE_DIR
375 * to determine database location in the filesystem.
377 * The default implementation is using SQLite for the storage.
379 * Returns: TRUE if successful, FALSE otherwise.
382 gsignond_secret_storage_open_db (GSignondSecretStorage *self)
384 return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->open_db (self);
388 * gsignond_secret_storage_close_db:
389 * @self: instance of #GSignondSecretStorage
391 * Closes the database. To reopen it, call gsignond_secret_storage_open_db().
393 * Returns: TRUE if successful, FALSE otherwise.
396 gsignond_secret_storage_close_db (GSignondSecretStorage *self)
398 return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->close_db (self);
402 * gsignond_secret_storage_clear_db:
403 * @self: instance of #GSignondSecretStorage
405 * Removes all stored secrets from the database.
407 * Returns: TRUE if successful, FALSE otherwise.
410 gsignond_secret_storage_clear_db (GSignondSecretStorage *self)
412 return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->clear_db (self);
416 * gsignond_secret_storage_is_open_db:
417 * @self: instance of #GSignondSecretStorage
419 * Checks if the database is open or not.
421 * Returns: TRUE if successful, FALSE otherwise.
424 gsignond_secret_storage_is_open_db (GSignondSecretStorage *self)
426 return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->is_open_db (self);
430 * gsignond_secret_storage_load_credentials:
431 * @self: instance of #GSignondSecretStorage
432 * @id: the identity id whose credentials are being loaded.
434 * Loads the credentials from the database.
436 * Returns: (transfer full): #GSignondCredentials if successful,
440 gsignond_secret_storage_load_credentials (
441 GSignondSecretStorage *self,
444 return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->load_credentials (self, id);
448 * gsignond_secret_storage_update_credentials:
449 * @self: instance of #GSignondSecretStorage
450 * @creds: (transfer none): the credentials that are being updated.
452 * Stores/updates the credentials for the given identity.
454 * Returns: TRUE if successful, FALSE otherwise.
457 gsignond_secret_storage_update_credentials (
458 GSignondSecretStorage *self,
459 GSignondCredentials *creds)
461 return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->update_credentials (self, creds);
465 * gsignond_secret_storage_remove_credentials:
466 * @self: instance of #GSignondSecretStorage
467 * @id: the identity whose credentials are being updated.
469 * Remove the credentials for the given identity.
471 * Returns: TRUE if successful, FALSE otherwise.
474 gsignond_secret_storage_remove_credentials (
475 GSignondSecretStorage *self,
478 return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->remove_credentials (self, id);
482 * gsignond_secret_storage_check_credentials:
483 * @self: instance of #GSignondSecretStorage
484 * @creds: (transfer none): the credentials that are being checked.
486 * Checks whether the given credentials match what is stored in the database.
488 * Returns: TRUE if successful, FALSE otherwise.
491 gsignond_secret_storage_check_credentials (
492 GSignondSecretStorage *self,
493 GSignondCredentials *creds)
495 return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->check_credentials (self, creds);
499 * gsignond_secret_storage_load_data:
500 * @self: instance of #GSignondSecretStorage
501 * @id: the identity id whose data are fetched
502 * @method: the authentication method the data is used for.
504 * Loads the secret data associated with a given identity and method.
506 * Returns: (transfer full): the secret data
509 gsignond_secret_storage_load_data (
510 GSignondSecretStorage *self,
512 const guint32 method)
514 return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->load_data (self, id, method);
518 * gsignond_secret_storage_update_data:
519 * @self: instance of #GSignondSecretStorage
520 * @id: the identity whose data are fetched.
521 * @method: the authentication method the data is used for.
522 * @data: (transfer none): the data to update
524 * Calling this method updates the secret data
525 * associated with the given id/method.
527 * Returns: TRUE if successful, FALSE otherwise.
530 gsignond_secret_storage_update_data (
531 GSignondSecretStorage *self,
533 const guint32 method,
534 GSignondDictionary *data)
536 return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->update_data (self, id, method, data);
540 * gsignond_secret_storage_remove_data:
541 * @self: instance of #GSignondSecretStorage
542 * @id: the identity whose data are fetched.
543 * @method: the authentication method the data is used for.
545 * Removes secret data associated with a given id/method.
547 * Returns: TRUE if successful, FALSE otherwise.
550 gsignond_secret_storage_remove_data (
551 GSignondSecretStorage *self,
553 const guint32 method)
555 return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->remove_data (self, id, method);
559 * gsignond_secret_storage_get_last_error:
560 * @self: instance of #GSignondSecretStorage
562 * Retrieves the last occurred error that has occured
564 * Returns: (transfer none): last occurred #GError
567 gsignond_secret_storage_get_last_error (GSignondSecretStorage *self)
569 return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->get_last_error (self);