[gnome-keyring/dbus-api] [secret-store] Additional methods for GckSecretData.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring/dbus-api] [secret-store] Additional methods for GckSecretData.
- Date: Mon, 10 Aug 2009 01:02:35 +0000 (UTC)
commit 943b63f6ebe91ddb043ad211d7d17cd6b6219725
Author: Stef Walter <stef memberwebs com>
Date: Sun Aug 9 17:44:48 2009 +0000
[secret-store] Additional methods for GckSecretData.
Add gck_secret_data_get_raw() to return secret directly. And
gck_secret_data_set_transacted() to set a secret as part of
a transaction.
pkcs11/secret-store/gck-secret-data.c | 98 +++++++++++++++++
pkcs11/secret-store/gck-secret-data.h | 11 ++-
pkcs11/secret-store/tests/unit-test-secret-data.c | 122 +++++++++++++++++++++
3 files changed, 230 insertions(+), 1 deletions(-)
---
diff --git a/pkcs11/secret-store/gck-secret-data.c b/pkcs11/secret-store/gck-secret-data.c
index b1862ed..9d677d1 100644
--- a/pkcs11/secret-store/gck-secret-data.c
+++ b/pkcs11/secret-store/gck-secret-data.c
@@ -24,6 +24,7 @@
#include "gck-secret-data.h"
#include "gck/gck-secret.h"
+#include "gck/gck-transaction.h"
#include "gck/gck-util.h"
#include "egg/egg-secure-memory.h"
@@ -39,6 +40,72 @@ struct _GckSecretData {
G_DEFINE_TYPE (GckSecretData, gck_secret_data, G_TYPE_OBJECT);
/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+typedef struct _set_secret_args {
+ gchar *identifier;
+ GckSecret *old_secret;
+} set_secret_args;
+
+static gboolean
+complete_set_secret (GckTransaction *transaction, GObject *obj, gpointer user_data)
+{
+ GckSecretData *self = GCK_SECRET_DATA (obj);
+ set_secret_args *args = user_data;
+
+ /* If the transaction failed, revert */
+ if (gck_transaction_get_failed (transaction)) {
+ if (!args->old_secret) {
+ g_hash_table_remove (self->secrets, args->identifier);
+ } else {
+ g_hash_table_replace (self->secrets, args->identifier, args->old_secret);
+ args->identifier = NULL; /* hash table took ownership */
+ args->old_secret = NULL; /* ditto */
+ }
+ }
+
+ /* Free up transaction data */
+ g_free (args->identifier);
+ if (args->old_secret)
+ g_object_unref (args->old_secret);
+ g_slice_free (set_secret_args, args);
+
+ return TRUE;
+}
+
+static void
+begin_set_secret (GckSecretData *self, GckTransaction *transaction,
+ const gchar *identifier, GckSecret *secret)
+{
+ set_secret_args *args;
+
+ g_assert (GCK_IS_SECRET_DATA (self));
+ g_assert (!gck_transaction_get_failed (transaction));
+ g_assert (identifier);
+ g_assert (GCK_IS_SECRET (secret));
+
+ args = g_slice_new0 (set_secret_args);
+
+ /* Take ownership of the old data, if present */
+ if (g_hash_table_lookup_extended (self->secrets, identifier,
+ (gpointer*)&args->identifier,
+ (gpointer*)&args->old_secret)) {
+ if (!g_hash_table_steal (self->secrets, args->identifier))
+ g_assert_not_reached ();
+ } else {
+ args->identifier = g_strdup (identifier);
+ }
+
+ /* Replace with our new data */
+ g_hash_table_replace (self->secrets, g_strdup (identifier),
+ g_object_ref (secret));
+
+ /* Track in the transaction */
+ gck_transaction_add (transaction, self, complete_set_secret, args);
+}
+
+/* -----------------------------------------------------------------------------
* OBJECT
*/
@@ -84,6 +151,24 @@ gck_secret_data_get_secret (GckSecretData *self, const gchar *identifier)
return g_hash_table_lookup (self->secrets, identifier);
}
+const guchar*
+gck_secret_data_get_raw (GckSecretData *self, const gchar *identifier,
+ gsize *n_result)
+{
+ GckSecret *secret;
+
+ g_return_val_if_fail (GCK_IS_SECRET_DATA (self), NULL);
+ g_return_val_if_fail (identifier, NULL);
+ g_return_val_if_fail (n_result, NULL);
+
+ secret = gck_secret_data_get_secret (self, identifier);
+ if (secret == NULL)
+ return NULL;
+
+ return gck_secret_get (secret, n_result);
+}
+
+
void
gck_secret_data_set_secret (GckSecretData *self, const gchar *identifier,
GckSecret *secret)
@@ -96,6 +181,19 @@ gck_secret_data_set_secret (GckSecretData *self, const gchar *identifier,
}
void
+gck_secret_data_set_transacted (GckSecretData *self, GckTransaction *transaction,
+ const gchar *identifier, GckSecret *secret)
+{
+ g_return_if_fail (GCK_IS_SECRET_DATA (self));
+ g_return_if_fail (GCK_IS_TRANSACTION (transaction));
+ g_return_if_fail (!gck_transaction_get_failed (transaction));
+ g_return_if_fail (identifier);
+ g_return_if_fail (GCK_IS_SECRET (secret));
+
+ begin_set_secret (self, transaction, identifier, secret);
+}
+
+void
gck_secret_data_remove_secret (GckSecretData *self, const gchar *identifier)
{
g_return_if_fail (GCK_IS_SECRET_DATA (self));
diff --git a/pkcs11/secret-store/gck-secret-data.h b/pkcs11/secret-store/gck-secret-data.h
index 48a3f0d..570a200 100644
--- a/pkcs11/secret-store/gck-secret-data.h
+++ b/pkcs11/secret-store/gck-secret-data.h
@@ -26,7 +26,7 @@
#include "gck-secret-types.h"
-#include "gck/gck-secret.h"
+#include "gck/gck-types.h"
#define GCK_TYPE_SECRET_DATA (gck_secret_data_get_type ())
#define GCK_SECRET_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCK_TYPE_SECRET_DATA, GckSecretData))
@@ -46,10 +46,19 @@ GType gck_secret_data_get_type (void);
GckSecret* gck_secret_data_get_secret (GckSecretData *self,
const gchar *identifier);
+const guchar* gck_secret_data_get_raw (GckSecretData *self,
+ const gchar *identifier,
+ gsize *n_result);
+
void gck_secret_data_set_secret (GckSecretData *self,
const gchar *identifier,
GckSecret *secret);
+void gck_secret_data_set_transacted (GckSecretData *self,
+ GckTransaction *transaction,
+ const gchar *identifier,
+ GckSecret *secret);
+
void gck_secret_data_remove_secret (GckSecretData *self,
const gchar *identifier);
diff --git a/pkcs11/secret-store/tests/unit-test-secret-data.c b/pkcs11/secret-store/tests/unit-test-secret-data.c
index 7460b46..9ca3ff5 100644
--- a/pkcs11/secret-store/tests/unit-test-secret-data.c
+++ b/pkcs11/secret-store/tests/unit-test-secret-data.c
@@ -27,6 +27,9 @@
#include "gck-secret-data.h"
+#include "gck/gck-secret.h"
+#include "gck/gck-transaction.h"
+
#include <glib.h>
#include <stdlib.h>
@@ -57,6 +60,27 @@ DEFINE_TEST(secret_data_get_set)
g_object_unref (data);
}
+DEFINE_TEST(secret_data_get_raw)
+{
+ GckSecretData *data = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
+ GckSecret *secret = gck_secret_new_from_password ("barn");
+ const guchar *raw;
+ gsize n_raw;
+
+ gck_secret_data_set_secret (data, "my-identifier", secret);
+ g_object_unref (secret);
+
+ raw = gck_secret_data_get_raw (data, "my-identifier", &n_raw);
+ g_assert (raw);
+ g_assert_cmpuint (n_raw, ==, 4);
+ g_assert (memcmp (raw, "barn", 4) == 0);
+
+ raw = gck_secret_data_get_raw (data, "not-identifier", &n_raw);
+ g_assert (raw == NULL);
+
+ g_object_unref (data);
+}
+
DEFINE_TEST(secret_data_remove)
{
GckSecretData *data = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
@@ -75,6 +99,104 @@ DEFINE_TEST(secret_data_remove)
g_object_unref (data);
}
+DEFINE_TEST(secret_data_set_transacted)
+{
+ GckTransaction *transaction = gck_transaction_new ();
+ GckSecretData *data = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
+ GckSecret *secret = gck_secret_new_from_password ("barn");
+
+ /* Transaction, but not complete */
+ gck_secret_data_set_transacted (data, transaction, "my-identifier", secret);
+ g_assert (!gck_transaction_get_failed (transaction));
+ g_assert (gck_secret_data_get_secret (data, "my-identifier") == secret);
+
+ /* Transaction complete */
+ gck_transaction_complete (transaction);
+ g_assert (!gck_transaction_get_failed (transaction));
+ g_assert (gck_secret_data_get_secret (data, "my-identifier") == secret);
+
+ g_object_unref (data);
+ g_object_unref (secret);
+ g_object_unref (transaction);
+}
+
+DEFINE_TEST(secret_data_set_transacted_replace)
+{
+ GckTransaction *transaction = gck_transaction_new ();
+ GckSecretData *data = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
+ GckSecret *old = gck_secret_new_from_password ("old");
+ GckSecret *secret = gck_secret_new_from_password ("secret");
+
+ /* The old secret */
+ gck_secret_data_set_secret (data, "my-identifier", old);
+ g_assert (gck_secret_data_get_secret (data, "my-identifier") == old);
+
+ /* Transaction, but not complete */
+ gck_secret_data_set_transacted (data, transaction, "my-identifier", secret);
+ g_assert (!gck_transaction_get_failed (transaction));
+ g_assert (gck_secret_data_get_secret (data, "my-identifier") == secret);
+
+ /* Transaction complete */
+ gck_transaction_complete (transaction);
+ g_assert (!gck_transaction_get_failed (transaction));
+ g_assert (gck_secret_data_get_secret (data, "my-identifier") == secret);
+
+ g_object_unref (old);
+ g_object_unref (data);
+ g_object_unref (secret);
+ g_object_unref (transaction);
+}
+
+DEFINE_TEST(secret_data_set_transacted_fail)
+{
+ GckTransaction *transaction = gck_transaction_new ();
+ GckSecretData *data = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
+ GckSecret *secret = gck_secret_new_from_password ("barn");
+
+ /* Transaction, but not complete */
+ gck_secret_data_set_transacted (data, transaction, "my-identifier", secret);
+ g_assert (!gck_transaction_get_failed (transaction));
+ g_assert (gck_secret_data_get_secret (data, "my-identifier") == secret);
+
+ /* Transaction fails here */
+ gck_transaction_fail (transaction, CKR_CANCEL);
+ gck_transaction_complete (transaction);
+ g_assert (gck_transaction_get_failed (transaction));
+ g_assert (gck_secret_data_get_secret (data, "my-identifier") == NULL);
+
+ g_object_unref (data);
+ g_object_unref (secret);
+ g_object_unref (transaction);
+}
+
+DEFINE_TEST(secret_data_set_transacted_fail_revert)
+{
+ GckTransaction *transaction = gck_transaction_new ();
+ GckSecretData *data = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
+ GckSecret *old = gck_secret_new_from_password ("old");
+ GckSecret *secret = gck_secret_new_from_password ("secret");
+
+ /* The old secret */
+ gck_secret_data_set_secret (data, "my-identifier", old);
+ g_assert (gck_secret_data_get_secret (data, "my-identifier") == old);
+
+ /* Transaction, but not complete */
+ gck_secret_data_set_transacted (data, transaction, "my-identifier", secret);
+ g_assert (!gck_transaction_get_failed (transaction));
+ g_assert (gck_secret_data_get_secret (data, "my-identifier") == secret);
+
+ /* Transaction fails here */
+ gck_transaction_fail (transaction, CKR_CANCEL);
+ gck_transaction_complete (transaction);
+ g_assert (gck_transaction_get_failed (transaction));
+ g_assert (gck_secret_data_get_secret (data, "my-identifier") == old);
+
+ g_object_unref (old);
+ g_object_unref (data);
+ g_object_unref (secret);
+ g_object_unref (transaction);
+}
+
DEFINE_TEST(secret_data_get_set_master)
{
GckSecretData *data = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]