[gnome-keyring] [wrap-layer] Implement initialize and change password prompts
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] [wrap-layer] Implement initialize and change password prompts
- Date: Sat, 12 Jun 2010 22:33:36 +0000 (UTC)
commit 92fa5ed13833da27403b932c7d815d8f8a07f880
Author: Stef Walter <stef memberwebs com>
Date: Sat Jun 12 22:20:34 2010 +0000
[wrap-layer] Implement initialize and change password prompts
pkcs11/gkm/gkm-mock.c | 10 +-
pkcs11/wrap-layer/gkm-wrap-layer.c | 23 +--
pkcs11/wrap-layer/gkm-wrap-prompt.c | 308 ++++++++++++++++++++++++++++---
pkcs11/wrap-layer/gkm-wrap-prompt.h | 2 -
pkcs11/wrap-layer/tests/Makefile.am | 4 +-
pkcs11/wrap-layer/tests/test-init-pin.c | 92 +++++++++
pkcs11/wrap-layer/tests/test-set-pin.c | 92 +++++++++
ui/gku-prompt.c | 16 ++
ui/gku-prompt.h | 3 +
9 files changed, 501 insertions(+), 49 deletions(-)
---
diff --git a/pkcs11/gkm/gkm-mock.c b/pkcs11/gkm/gkm-mock.c
index a49c382..471f445 100644
--- a/pkcs11/gkm/gkm-mock.c
+++ b/pkcs11/gkm/gkm-mock.c
@@ -666,9 +666,7 @@ gkm_mock_C_InitPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin,
Session *session;
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
- g_assert (session != NULL && "No such session found");
- if (!session)
- return CKR_SESSION_HANDLE_INVALID;
+ g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
g_free (the_pin);
the_pin = g_strndup ((gchar*)pPin, ulPinLen);
@@ -684,12 +682,10 @@ gkm_mock_C_SetPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
gchar *old;
session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
- g_assert (session != NULL && "No such session found");
- if (!session)
- return CKR_SESSION_HANDLE_INVALID;
+ g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
old = g_strndup ((gchar*)pOldPin, ulOldLen);
- if (!g_str_equal (old, the_pin))
+ if (!old || !g_str_equal (old, the_pin))
return CKR_PIN_INCORRECT;
g_free (the_pin);
diff --git a/pkcs11/wrap-layer/gkm-wrap-layer.c b/pkcs11/wrap-layer/gkm-wrap-layer.c
index 337625e..c72ca5a 100644
--- a/pkcs11/wrap-layer/gkm-wrap-layer.c
+++ b/pkcs11/wrap-layer/gkm-wrap-layer.c
@@ -530,24 +530,22 @@ wrap_C_GetSessionInfo (CK_SESSION_HANDLE handle, CK_SESSION_INFO_PTR info)
static CK_RV
wrap_C_InitPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
{
-#if 0
GkmWrapPrompt *prompt;
-#endif
Mapping map;
CK_RV rv;
rv = map_session_to_real (&handle, &map, NULL);
if (rv != CKR_OK)
return rv;
-#if 0
+
prompt = gkm_wrap_prompt_for_init_pin (map.funcs, handle, pin, pin_len);
for (;;) {
if (prompt && !gkm_wrap_prompt_do_init_pin (prompt, rv, &pin, &pin_len))
break;
-#endif
+
rv = (map.funcs->C_InitPIN) (handle, pin, pin_len);
-#if 0
+
if (!prompt || rv != CKR_PIN_INVALID || rv != CKR_PIN_LEN_RANGE)
break;
}
@@ -556,23 +554,21 @@ wrap_C_InitPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
gkm_wrap_prompt_done_init_pin (prompt, rv);
g_object_unref (prompt);
}
-#endif
+
return rv;
}
static CK_RV
wrap_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG old_pin_len, CK_UTF8CHAR_PTR new_pin, CK_ULONG new_pin_len)
{
-#if 0
GkmWrapPrompt *prompt;
-#endif
Mapping map;
CK_RV rv;
rv = map_session_to_real (&handle, &map, NULL);
if (rv != CKR_OK)
return rv;
-#if 0
+
prompt = gkm_wrap_prompt_for_set_pin (map.funcs, handle,
old_pin, old_pin_len,
new_pin, new_pin_len);
@@ -581,10 +577,11 @@ wrap_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG old_p
if (prompt && !gkm_wrap_prompt_do_set_pin (prompt, rv, &old_pin, &old_pin_len,
&new_pin, &new_pin_len))
break;
-#endif
+
rv = (map.funcs->C_SetPIN) (handle, old_pin, old_pin_len, new_pin, new_pin_len);
-#if 0
- if (!prompt || rv != CKR_PIN_INVALID || rv != CKR_PIN_LEN_RANGE)
+
+ if (!prompt || rv != CKR_PIN_INCORRECT ||
+ rv != CKR_PIN_INVALID || rv != CKR_PIN_LEN_RANGE)
break;
}
@@ -592,7 +589,7 @@ wrap_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG old_p
gkm_wrap_prompt_done_set_pin (prompt, rv);
g_object_unref (prompt);
}
-#endif
+
return rv;
}
diff --git a/pkcs11/wrap-layer/gkm-wrap-prompt.c b/pkcs11/wrap-layer/gkm-wrap-prompt.c
index f788ac0..1006254 100644
--- a/pkcs11/wrap-layer/gkm-wrap-prompt.c
+++ b/pkcs11/wrap-layer/gkm-wrap-prompt.c
@@ -52,12 +52,6 @@ struct _GkmWrapPrompt {
GQueue pool;
};
-typedef struct _CredentialPrompt {
- GArray *template;
- CK_ULONG n_template;
- gchar *password;
-} CredentialPrompt;
-
G_DEFINE_TYPE (GkmWrapPrompt, gkm_wrap_prompt, GKU_TYPE_PROMPT);
/* -----------------------------------------------------------------------------
@@ -128,6 +122,28 @@ auto_unlock_object_unique (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
return g_strndup (attr->pValue, attr->ulValueLen);
}
+static void
+convert_upper_case (gchar *str)
+{
+ for (; *str; ++str)
+ *str = g_ascii_toupper (*str);
+}
+
+static gchar*
+auto_unlock_object_digest (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
+{
+ CK_ATTRIBUTE_PTR attr;
+ gchar *result;
+
+ attr = gkm_attributes_find (attrs, n_attrs, CKA_GNOME_INTERNAL_SHA1);
+ if (attr == NULL)
+ return NULL;
+
+ result = g_strndup (attr->pValue, attr->ulValueLen);
+ convert_upper_case (result);
+ return result;
+}
+
static gchar*
auto_unlock_lookup_keyring (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
{
@@ -148,7 +164,7 @@ static gchar*
auto_unlock_lookup_object (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
{
CK_OBJECT_CLASS klass;
- gchar *unique;
+ gchar *value;
gchar *password;
if (!gkm_attributes_find_ulong (attrs, n_attrs, CKA_CLASS, &klass))
@@ -157,13 +173,24 @@ auto_unlock_lookup_object (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
if (klass == CKO_G_COLLECTION)
return auto_unlock_lookup_keyring (attrs, n_attrs);
- unique = auto_unlock_object_unique (attrs, n_attrs);
- if (unique == NULL)
- return NULL;
+ value = auto_unlock_object_unique (attrs, n_attrs);
+ if (value != NULL) {
+ password = gkm_wrap_login_lookup_secret ("unique", value, NULL);
+ g_free (value);
+ if (password)
+ return password;
+ }
- password = gkm_wrap_login_lookup_secret ("unique", unique, NULL);
- g_free (unique);
- return password;
+ /* COMPAT: Check old method of storing secrets for objects in login keyring */
+ value = auto_unlock_object_digest (attrs, n_attrs);
+ if (value != NULL) {
+ password = gkm_wrap_login_lookup_secret ("object-digest", value, NULL);
+ g_free (value);
+ if (password)
+ return password;
+ }
+
+ return NULL;
}
static gchar*
@@ -308,7 +335,7 @@ static void
auto_unlock_remove_object (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
{
CK_OBJECT_CLASS klass;
- gchar *unique;
+ gchar *value;
if (!gkm_attributes_find_ulong (attrs, n_attrs, CKA_CLASS, &klass))
return;
@@ -318,12 +345,19 @@ auto_unlock_remove_object (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
return;
}
- unique = auto_unlock_object_unique (attrs, n_attrs);
- if (unique == NULL)
- return;
+ value = auto_unlock_object_unique (attrs, n_attrs);
+ if (value != NULL) {
+ gkm_wrap_login_remove_secret ("unique", value, NULL);
+ g_free (value);
+ }
+
+ /* COMPAT: Clear old method of storing secrets for objects in login keyring */
+ value = auto_unlock_object_digest (attrs, n_attrs);
+ if (value != NULL) {
+ gkm_wrap_login_remove_secret ("object-digest", value, NULL);
+ g_free (value);
+ }
- gkm_wrap_login_remove_secret ("unique", unique, NULL);
- g_free (unique);
}
static void
@@ -507,7 +541,7 @@ set_unlock_options_on_prompt (GkmWrapPrompt *self, CK_ATTRIBUTE_PTR options, CK_
static CK_ATTRIBUTE_PTR
get_attributes_from_object (GkmWrapPrompt *self, CK_ULONG *n_attrs)
{
- CK_ATTRIBUTE attrs[5];
+ CK_ATTRIBUTE attrs[6];
CK_ULONG i;
CK_RV rv;
@@ -521,6 +555,7 @@ get_attributes_from_object (GkmWrapPrompt *self, CK_ULONG *n_attrs)
attrs[2].type = CKA_CLASS;
attrs[3].type = CKA_G_LOGIN_COLLECTION;
attrs[4].type = CKA_GNOME_UNIQUE;
+ attrs[5].type = CKA_GNOME_INTERNAL_SHA1;
rv = (self->module->C_GetAttributeValue) (self->session, self->object, attrs, G_N_ELEMENTS (attrs));
if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) {
@@ -813,6 +848,12 @@ gkm_wrap_prompt_class_init (GkmWrapPromptClass *klass)
* CREDENTIAL
*/
+typedef struct _CredentialPrompt {
+ GArray *template;
+ CK_ULONG n_template;
+ gchar *password;
+} CredentialPrompt;
+
static void
credential_prompt_free (gpointer user_data)
{
@@ -967,25 +1008,168 @@ gkm_wrap_prompt_done_credential (GkmWrapPrompt *self, CK_RV call_result)
}
}
-#if 0
+/* ------------------------------------------------------------------------------------
+ * INITPIN
+ */
+
+static void
+prepare_init_token (GkmWrapPrompt *self, CK_TOKEN_INFO_PTR tinfo)
+{
+ GkuPrompt *prompt;
+ gchar *label;
+ gchar *text;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+ g_assert (tinfo);
+
+ prompt = GKU_PROMPT (self);
+
+ label = g_strndup ((gchar*)tinfo->label, sizeof (tinfo->label));
+ g_strchomp (label);
+
+ /* Build up the prompt */
+ gku_prompt_show_widget (prompt, "password_area");
+ gku_prompt_show_widget (prompt, "confirm_area");
+ gku_prompt_hide_widget (prompt, "original_area");
+ gku_prompt_set_title (prompt, _("New Password Required"));
+ gku_prompt_set_primary_text (prompt, _("New password required for secure storage"));
+
+ text = g_strdup_printf (_("In order to prepare '%s' for storage of certificates or keys, a password is required"), label);
+ gku_prompt_set_secondary_text (prompt, text);
+ g_free (text);
+
+ if (gkm_wrap_login_is_usable ()) {
+ gku_prompt_show_widget (prompt, "details_area");
+ gku_prompt_show_widget (prompt, "lock_area");
+ gku_prompt_hide_widget (prompt, "options_area");
+ }
+
+ g_free (label);
+}
+
GkmWrapPrompt*
gkm_wrap_prompt_for_init_pin (CK_FUNCTION_LIST_PTR module, CK_SESSION_HANDLE session,
CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
{
+ GkmWrapPrompt *self;
+
+ g_assert (module);
+
+ if (pin != NULL || pin_len != 0)
+ return NULL;
+
+ /* Build up the prompt */
+ self = g_object_new (GKM_WRAP_TYPE_PROMPT, NULL);
+ self->module = module;
+ self->session = session;
+ self->destroy_data = (GDestroyNotify)egg_secure_strfree;
+ return self;
}
gboolean
-gkm_wrap_prompt_do_init_pin (GkmWrapPrompt *prompt, CK_RV last_result,
+gkm_wrap_prompt_do_init_pin (GkmWrapPrompt *self, CK_RV last_result,
CK_UTF8CHAR_PTR *pin, CK_ULONG *n_pin)
{
+ CK_TOKEN_INFO tinfo;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+ g_assert (self->module);
+ g_assert (pin);
+ g_assert (n_pin);
+
+ g_assert (self->destroy_data == (GDestroyNotify)egg_secure_strfree);
+ egg_secure_strfree (self->prompt_data);
+ self->prompt_data = NULL;
+
+ if (!get_info_for_token (self, &tinfo))
+ return FALSE;
+
+ /* Hard reset on first prompt, soft on later */
+ gku_prompt_reset (GKU_PROMPT (self), last_result == CKR_OK);
+
+ prepare_init_token (self, &tinfo);
+
+ gku_prompt_request_attention_sync (NULL, on_prompt_attention,
+ g_object_ref (self), g_object_unref);
+
+ if (gku_prompt_get_response (GKU_PROMPT (self)) != GKU_RESPONSE_OK)
+ return FALSE;
+ self->prompt_data = gku_prompt_get_password (GKU_PROMPT (self), "password");
+ g_return_val_if_fail (self->prompt_data, FALSE);
+
+ *pin = self->prompt_data;
+ *n_pin = strlen (self->prompt_data);
+ return TRUE;
}
void
-gkm_wrap_prompt_done_init_pin (GkmWrapPrompt *prompt, CK_RV call_result)
+gkm_wrap_prompt_done_init_pin (GkmWrapPrompt *self, CK_RV call_result)
{
+ CK_TOKEN_INFO tinfo;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+ g_assert (self->destroy_data == (GDestroyNotify)egg_secure_strfree);
+
+ /* Save auto auto unlock */
+ if (call_result == CKR_OK && auto_unlock_should_attach (self)) {
+ if (get_info_for_token (self, &tinfo))
+ auto_unlock_attach_token (&tinfo, self->prompt_data);
+ }
+}
+
+/* ------------------------------------------------------------------------------------
+ * SETPIN
+ */
+
+typedef struct _SetPinPrompt {
+ gchar *original;
+ gchar *password;
+} SetPinPrompt;
+
+static void
+set_pin_prompt_free (gpointer user_data)
+{
+ SetPinPrompt *data = user_data;
+ egg_secure_strfree (data->original);
+ egg_secure_strfree (data->password);
+ g_slice_free (SetPinPrompt, data);
+}
+
+static void
+prepare_set_token (GkmWrapPrompt *self, CK_TOKEN_INFO_PTR tinfo)
+{
+ GkuPrompt *prompt;
+ gchar *label;
+ gchar *text;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+ g_assert (tinfo);
+
+ prompt = GKU_PROMPT (self);
+
+ label = g_strndup ((gchar*)tinfo->label, sizeof (tinfo->label));
+ g_strchomp (label);
+
+ /* Build up the prompt */
+ gku_prompt_show_widget (prompt, "password_area");
+ gku_prompt_show_widget (prompt, "confirm_area");
+ gku_prompt_show_widget (prompt, "original_area");
+ gku_prompt_set_title (prompt, _("Change Password"));
+ gku_prompt_set_primary_text (prompt, _("Change password for secure storage"));
+
+ text = g_strdup_printf (_("To change the password for '%s', the original and new passwords are required"), label);
+ gku_prompt_set_secondary_text (prompt, text);
+ g_free (text);
+ if (gkm_wrap_login_is_usable ()) {
+ gku_prompt_show_widget (prompt, "details_area");
+ gku_prompt_show_widget (prompt, "lock_area");
+ gku_prompt_hide_widget (prompt, "options_area");
+ }
+
+ g_free (label);
}
GkmWrapPrompt*
@@ -993,23 +1177,95 @@ gkm_wrap_prompt_for_set_pin (CK_FUNCTION_LIST_PTR module, CK_SESSION_HANDLE sess
CK_UTF8CHAR_PTR old_pin, CK_ULONG n_old_pin,
CK_UTF8CHAR_PTR new_pin, CK_ULONG n_new_pin)
{
+ GkmWrapPrompt *self;
+
+ g_assert (module);
+ if (new_pin != NULL || n_new_pin != 0)
+ return NULL;
+
+ /* Build up the prompt */
+ self = g_object_new (GKM_WRAP_TYPE_PROMPT, NULL);
+ self->module = module;
+ self->session = session;
+ self->destroy_data = set_pin_prompt_free;
+ self->prompt_data = g_slice_new0 (SetPinPrompt);
+
+ return self;
}
gboolean
-gkm_wrap_prompt_do_set_pin (GkmWrapPrompt *prompt, CK_RV last_result,
+gkm_wrap_prompt_do_set_pin (GkmWrapPrompt *self, CK_RV last_result,
CK_UTF8CHAR_PTR *old_pin, CK_ULONG *n_old_pin,
CK_UTF8CHAR_PTR *new_pin, CK_ULONG *n_new_pin)
{
+ gboolean initializing = FALSE;
+ CK_TOKEN_INFO tinfo;
+ SetPinPrompt *data;
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+ g_assert (self->module);
+ g_assert (old_pin);
+ g_assert (n_old_pin);
+ g_assert (new_pin);
+ g_assert (n_new_pin);
+
+ g_assert (self->destroy_data == set_pin_prompt_free);
+ data = self->prompt_data;
+
+ if (!get_info_for_token (self, &tinfo))
+ return FALSE;
+
+ /* Hard reset on first prompt, soft on later */
+ gku_prompt_reset (GKU_PROMPT (self), last_result == CKR_OK);
+
+ initializing = !(tinfo.flags & CKF_USER_PIN_INITIALIZED);
+ if (initializing)
+ prepare_init_token (self, &tinfo);
+ else
+ prepare_set_token (self, &tinfo);
+
+ gku_prompt_request_attention_sync (NULL, on_prompt_attention,
+ g_object_ref (self), g_object_unref);
+
+ if (gku_prompt_get_response (GKU_PROMPT (self)) != GKU_RESPONSE_OK)
+ return FALSE;
+
+ egg_secure_strfree (data->password);
+ data->password = gku_prompt_get_password (GKU_PROMPT (self), "password");
+ g_return_val_if_fail (data->password, FALSE);
+
+ *new_pin = (guchar*)data->password;
+ *n_new_pin = strlen (data->password);
+
+ if (!initializing) {
+ egg_secure_strfree (data->original);
+ data->original = gku_prompt_get_password (GKU_PROMPT (self), "original");
+ g_return_val_if_fail (data->original, FALSE);
+
+ *old_pin = (guchar*)data->original;
+ *n_old_pin = strlen (data->original);
+ }
+
+ return TRUE;
}
void
-gkm_wrap_prompt_done_set_pin (GkmWrapPrompt *prompt, CK_RV call_result)
+gkm_wrap_prompt_done_set_pin (GkmWrapPrompt *self, CK_RV call_result)
{
+ CK_TOKEN_INFO tinfo;
+ SetPinPrompt *data;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+ g_assert (self->destroy_data == set_pin_prompt_free);
+ data = self->prompt_data;
+ /* Save auto auto unlock */
+ if (call_result == CKR_OK && auto_unlock_should_attach (self)) {
+ if (get_info_for_token (self, &tinfo))
+ auto_unlock_attach_token (&tinfo, data->password);
+ }
}
-#endif
/* -----------------------------------------------------------------------------
* LOGIN
diff --git a/pkcs11/wrap-layer/gkm-wrap-prompt.h b/pkcs11/wrap-layer/gkm-wrap-prompt.h
index 8e8c0e7..499ce3a 100644
--- a/pkcs11/wrap-layer/gkm-wrap-prompt.h
+++ b/pkcs11/wrap-layer/gkm-wrap-prompt.h
@@ -54,7 +54,6 @@ gboolean gkm_wrap_prompt_do_credential (GkmWrapPrompt *self
void gkm_wrap_prompt_done_credential (GkmWrapPrompt *self,
CK_RV call_result);
-#if 0
GkmWrapPrompt* gkm_wrap_prompt_for_init_pin (CK_FUNCTION_LIST_PTR module,
CK_SESSION_HANDLE session,
CK_UTF8CHAR_PTR pin,
@@ -84,7 +83,6 @@ gboolean gkm_wrap_prompt_do_set_pin (GkmWrapPrompt *prom
void gkm_wrap_prompt_done_set_pin (GkmWrapPrompt *prompt,
CK_RV call_result);
-#endif
GkmWrapPrompt* gkm_wrap_prompt_for_login (CK_FUNCTION_LIST_PTR module,
CK_USER_TYPE user_type,
diff --git a/pkcs11/wrap-layer/tests/Makefile.am b/pkcs11/wrap-layer/tests/Makefile.am
index bcc73cc..007c4d2 100644
--- a/pkcs11/wrap-layer/tests/Makefile.am
+++ b/pkcs11/wrap-layer/tests/Makefile.am
@@ -2,11 +2,13 @@
TESTING_FILES = \
mock-secret-store.c \
test-create-credential.c \
+ test-init-pin.c \
test-login-auto.c \
test-login-hints.c \
test-login-keyring.c \
test-login-specific.c \
- test-login-user.c
+ test-login-user.c \
+ test-set-pin.c
TESTING_LIBS = \
$(top_builddir)/pkcs11/wrap-layer/libgkm-wrap-layer.la \
diff --git a/pkcs11/wrap-layer/tests/test-init-pin.c b/pkcs11/wrap-layer/tests/test-init-pin.c
new file mode 100644
index 0000000..118930f
--- /dev/null
+++ b/pkcs11/wrap-layer/tests/test-init-pin.c
@@ -0,0 +1,92 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "test-suite.h"
+
+#include "gkm/gkm-mock.h"
+#include "gkm/gkm-test.h"
+
+#include "wrap-layer/gkm-wrap-layer.h"
+
+#include "ui/gku-prompt.h"
+
+static CK_FUNCTION_LIST functions;
+static CK_FUNCTION_LIST_PTR module = NULL;
+static CK_SESSION_HANDLE session = 0;
+
+DEFINE_SETUP (init_pin)
+{
+ CK_FUNCTION_LIST_PTR funcs;
+ CK_SLOT_ID slot_id;
+ CK_ULONG n_slots = 1;
+ CK_RV rv;
+
+ /* Always start off with test functions */
+ rv = gkm_mock_C_GetFunctionList (&funcs);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+ memcpy (&functions, funcs, sizeof (functions));
+
+ gkm_wrap_layer_reset_modules ();
+ gkm_wrap_layer_add_module (&functions);
+ module = gkm_wrap_layer_get_functions ();
+
+ gku_prompt_dummy_prepare_response ();
+
+ /* Open a session */
+ rv = (module->C_Initialize) (NULL);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ rv = (module->C_GetSlotList) (CK_TRUE, &slot_id, &n_slots);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ rv = (module->C_OpenSession) (slot_id, CKF_SERIAL_SESSION, NULL, NULL, &session);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+}
+
+DEFINE_TEARDOWN (init_pin)
+{
+ CK_RV rv;
+
+ g_assert (!gku_prompt_dummy_have_response ());
+
+ rv = (module->C_CloseSession) (session);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+ session = 0;
+
+ rv = (module->C_Finalize) (NULL);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+ module = NULL;
+}
+
+DEFINE_TEST (init_pin_ok_password)
+{
+ CK_RV rv;
+
+ gku_prompt_dummy_queue_ok_password ("new");
+
+ rv = (module->C_InitPIN) (session, NULL, 0);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ rv = (module->C_Login) (session, CKU_USER, (guchar*)"new", 3);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+}
diff --git a/pkcs11/wrap-layer/tests/test-set-pin.c b/pkcs11/wrap-layer/tests/test-set-pin.c
new file mode 100644
index 0000000..8b1a879
--- /dev/null
+++ b/pkcs11/wrap-layer/tests/test-set-pin.c
@@ -0,0 +1,92 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "test-suite.h"
+
+#include "gkm/gkm-mock.h"
+#include "gkm/gkm-test.h"
+
+#include "wrap-layer/gkm-wrap-layer.h"
+
+#include "ui/gku-prompt.h"
+
+static CK_FUNCTION_LIST functions;
+static CK_FUNCTION_LIST_PTR module = NULL;
+static CK_SESSION_HANDLE session = 0;
+
+DEFINE_SETUP (set_pin)
+{
+ CK_FUNCTION_LIST_PTR funcs;
+ CK_SLOT_ID slot_id;
+ CK_ULONG n_slots = 1;
+ CK_RV rv;
+
+ /* Always start off with test functions */
+ rv = gkm_mock_C_GetFunctionList (&funcs);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+ memcpy (&functions, funcs, sizeof (functions));
+
+ gkm_wrap_layer_reset_modules ();
+ gkm_wrap_layer_add_module (&functions);
+ module = gkm_wrap_layer_get_functions ();
+
+ gku_prompt_dummy_prepare_response ();
+
+ /* Open a session */
+ rv = (module->C_Initialize) (NULL);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ rv = (module->C_GetSlotList) (CK_TRUE, &slot_id, &n_slots);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ rv = (module->C_OpenSession) (slot_id, CKF_SERIAL_SESSION, NULL, NULL, &session);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+}
+
+DEFINE_TEARDOWN (set_pin)
+{
+ CK_RV rv;
+
+ g_assert (!gku_prompt_dummy_have_response ());
+
+ rv = (module->C_CloseSession) (session);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+ session = 0;
+
+ rv = (module->C_Finalize) (NULL);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+ module = NULL;
+}
+
+DEFINE_TEST (set_pin_ok_passwords)
+{
+ CK_RV rv;
+
+ gku_prompt_dummy_queue_ok_passwords ("booo", "new");
+
+ rv = (module->C_SetPIN) (session, NULL, 0, NULL, 0);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ rv = (module->C_Login) (session, CKU_USER, (guchar*)"new", 3);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+}
diff --git a/ui/gku-prompt.c b/ui/gku-prompt.c
index 2801e60..f609bf9 100644
--- a/ui/gku-prompt.c
+++ b/ui/gku-prompt.c
@@ -1208,6 +1208,22 @@ gku_prompt_dummy_queue_ok_password (const gchar *password)
}
void
+gku_prompt_dummy_queue_ok_passwords (const gchar *original, const gchar *password)
+{
+ const static gchar *RESPONSE = "[password]\nparameter=\nvalue=%s\n"
+ "[original]\nparameter=\nvalue=%s\n"
+ "[prompt]\nresponse=ok\n";
+ gchar *value, *ovalue;
+
+ g_return_if_fail (password);
+ value = egg_hex_encode ((const guchar*)password, strlen (password));
+ ovalue = egg_hex_encode ((const guchar*)original, strlen (original));
+ queue_dummy_response (g_strdup_printf (RESPONSE, value, ovalue));
+ g_free (value);
+ g_free (ovalue);
+}
+
+void
gku_prompt_dummy_queue_auto_password (const gchar *password)
{
const static gchar *RESPONSE = "[password]\nparameter=\nvalue=%s\n[prompt]\nresponse=ok\n"
diff --git a/ui/gku-prompt.h b/ui/gku-prompt.h
index 1f82eb5..060bfcf 100644
--- a/ui/gku-prompt.h
+++ b/ui/gku-prompt.h
@@ -149,6 +149,9 @@ void gku_prompt_dummy_queue_response (const gchar *respons
void gku_prompt_dummy_queue_ok_password (const gchar *password);
+void gku_prompt_dummy_queue_ok_passwords (const gchar *original,
+ const gchar *password);
+
void gku_prompt_dummy_queue_auto_password (const gchar *password);
void gku_prompt_dummy_queue_no (void);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]