Line data Source code
1 : /*
2 : * gnome-keyring
3 : *
4 : * Copyright (C) 2010 Stefan Walter
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser General Public License as
8 : * published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, see
18 : * <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "config.h"
22 :
23 : #include "wrap-layer/gkm-wrap-layer.h"
24 : #include "wrap-layer/gkm-wrap-prompt.h"
25 :
26 : #include "egg/egg-testing.h"
27 :
28 : #include "gkm/gkm-mock.h"
29 : #include "gkm/gkm-test.h"
30 :
31 : #include <gcr/gcr-base.h>
32 :
33 : #include <glib-object.h>
34 :
35 : #include <string.h>
36 :
37 : extern CK_FUNCTION_LIST mock_secret_store;
38 :
39 : typedef struct {
40 : CK_FUNCTION_LIST functions;
41 : CK_FUNCTION_LIST_PTR module;
42 : CK_SESSION_HANDLE session;
43 : CK_OBJECT_HANDLE key;
44 : CK_OBJECT_HANDLE collection;
45 : CK_MECHANISM mech;
46 : } Test;
47 :
48 : static void
49 3 : setup (Test *test, gconstpointer unused)
50 : {
51 : CK_SLOT_ID slot_id;
52 3 : CK_ULONG n_slots = 1;
53 : CK_ULONG count;
54 : const gchar *prompter;
55 : CK_RV rv;
56 :
57 3 : CK_BBOOL always = TRUE;
58 3 : CK_ATTRIBUTE kattrs[] = {
59 : { CKA_ALWAYS_AUTHENTICATE, &always, sizeof (always) }
60 : };
61 :
62 3 : CK_OBJECT_CLASS fklass = CKO_G_COLLECTION;
63 3 : CK_ATTRIBUTE fattrs[] = {
64 : { CKA_CLASS, &fklass, sizeof (fklass) },
65 : { CKA_ID, "other", 5 },
66 : };
67 :
68 3 : test->mech.mechanism = CKM_MOCK_PREFIX;
69 :
70 : /* Always start off with test test->functions */
71 3 : memcpy (&test->functions, &mock_secret_store, sizeof (test->functions));
72 :
73 3 : gkm_wrap_layer_reset_modules ();
74 3 : gkm_wrap_layer_add_module (&test->functions);
75 3 : test->module = gkm_wrap_layer_get_functions ();
76 :
77 3 : prompter = gcr_mock_prompter_start ();
78 3 : gkm_wrap_prompt_set_prompter_name (prompter);
79 :
80 : /* Open a test->session */
81 3 : rv = (test->module->C_Initialize) (NULL);
82 3 : gkm_assert_cmprv (rv, ==, CKR_OK);
83 :
84 3 : rv = (test->module->C_GetSlotList) (CK_TRUE, &slot_id, &n_slots);
85 3 : gkm_assert_cmprv (rv, ==, CKR_OK);
86 :
87 3 : rv = (test->module->C_OpenSession) (slot_id, CKF_SERIAL_SESSION, NULL, NULL, &test->session);
88 3 : gkm_assert_cmprv (rv, ==, CKR_OK);
89 :
90 : /* Find keyring object */
91 3 : rv = (test->module->C_FindObjectsInit) (test->session, fattrs, 1);
92 3 : gkm_assert_cmprv (rv, ==, CKR_OK);
93 3 : rv = (test->module->C_FindObjects) (test->session, &test->collection, 1, &count);
94 3 : gkm_assert_cmprv (rv, ==, CKR_OK);
95 3 : gkm_assert_cmpulong (count, ==, 1);
96 3 : gkm_assert_cmpulong (test->collection, !=, 0);
97 3 : rv = (test->module->C_FindObjectsFinal) (test->session);
98 3 : gkm_assert_cmprv (rv, ==, CKR_OK);
99 :
100 : /* Find the test->key object */
101 3 : rv = (test->module->C_FindObjectsInit) (test->session, kattrs, 1);
102 3 : gkm_assert_cmprv (rv, ==, CKR_OK);
103 3 : rv = (test->module->C_FindObjects) (test->session, &test->key, 1, &count);
104 3 : gkm_assert_cmprv (rv, ==, CKR_OK);
105 3 : gkm_assert_cmpulong (count, ==, 1);
106 3 : gkm_assert_cmpulong (test->key, !=, 0);
107 3 : rv = (test->module->C_FindObjectsFinal) (test->session);
108 3 : gkm_assert_cmprv (rv, ==, CKR_OK);
109 :
110 : /* Start a signing operation, that needs to be authenticated */
111 3 : rv = (test->module->C_SignInit) (test->session, &test->mech, test->key);
112 3 : gkm_assert_cmprv (rv, ==, CKR_OK);
113 3 : }
114 :
115 : static void
116 3 : teardown (Test *test, gconstpointer unused)
117 : {
118 : CK_RV rv;
119 :
120 3 : g_assert (!gcr_mock_prompter_is_expecting ());
121 3 : gcr_mock_prompter_stop ();
122 :
123 3 : test->key = 0;
124 3 : test->collection = 0;
125 :
126 3 : rv = (test->module->C_CloseSession) (test->session);
127 3 : gkm_assert_cmprv (rv, ==, CKR_OK);
128 3 : test->session = 0;
129 :
130 3 : rv = (test->module->C_Finalize) (NULL);
131 3 : gkm_assert_cmprv (rv, ==, CKR_OK);
132 3 : test->module = NULL;
133 3 : }
134 :
135 : static void
136 1 : test_specific (Test *test, gconstpointer unused)
137 : {
138 : CK_RV rv;
139 :
140 : /* Login with prompt */
141 1 : gcr_mock_prompter_expect_password_ok ("booo",
142 : "choice-label", "Automatically unlock this key whenever I’m logged in",
143 : "choice-chosen", TRUE,
144 : NULL);
145 :
146 1 : rv = (test->module->C_Login) (test->session, CKU_CONTEXT_SPECIFIC, NULL, 0);
147 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
148 :
149 : /* Start a signing operation, that needs to be authenticated */
150 1 : rv = (test->module->C_SignInit) (test->session, &test->mech, test->key);
151 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
152 :
153 : /* No further prompting should be shown, uses stored password */
154 1 : g_assert (!gcr_mock_prompter_is_expecting ());
155 :
156 1 : rv = (test->module->C_Login) (test->session, CKU_CONTEXT_SPECIFIC, NULL, 0);
157 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
158 :
159 : /* Change the password */
160 1 : gkm_mock_module_set_pin ("other");
161 :
162 : /* Start a signing operation, that needs to be authenticated */
163 1 : rv = (test->module->C_SignInit) (test->session, &test->mech, test->key);
164 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
165 :
166 : /* This should prompt again, as stored password is now wrong */
167 1 : gcr_mock_prompter_expect_password_ok ("other", NULL);
168 :
169 1 : rv = (test->module->C_Login) (test->session, CKU_CONTEXT_SPECIFIC, NULL, 0);
170 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
171 1 : }
172 :
173 : static void
174 1 : test_user_token (Test *test, gconstpointer unused)
175 : {
176 : CK_RV rv;
177 :
178 : /* Login with prompt */
179 1 : gcr_mock_prompter_expect_password_ok ("booo",
180 : "choice-label", "Automatically unlock whenever I’m logged in",
181 : "choice-chosen", TRUE,
182 : NULL);
183 :
184 1 : rv = (test->module->C_Login) (test->session, CKU_USER, NULL, 0);
185 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
186 1 : rv = (test->module->C_Logout) (test->session);
187 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
188 :
189 : /* No further prompting should be shown, uses stored password */
190 1 : g_assert (!gcr_mock_prompter_is_expecting ());
191 :
192 1 : rv = (test->module->C_Login) (test->session, CKU_USER, NULL, 0);
193 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
194 1 : rv = (test->module->C_Logout) (test->session);
195 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
196 :
197 : /* Change the password */
198 1 : gkm_mock_module_set_pin ("other");
199 :
200 : /* This should prompt again, as stored password is now wrong */
201 1 : gcr_mock_prompter_expect_password_ok ("other", NULL);
202 :
203 1 : rv = (test->module->C_Login) (test->session, CKU_USER, NULL, 0);
204 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
205 1 : }
206 :
207 : static void
208 1 : test_unlock_keyring (Test *test, gconstpointer unused)
209 : {
210 : CK_OBJECT_HANDLE credential;
211 : CK_RV rv;
212 :
213 1 : CK_OBJECT_CLASS klass = CKO_G_CREDENTIAL;
214 1 : CK_ATTRIBUTE attrs[] = {
215 : { CKA_CLASS, &klass, sizeof (klass) },
216 : { CKA_VALUE, NULL, 0 },
217 1 : { CKA_G_OBJECT, &test->collection, sizeof (test->collection) },
218 : };
219 :
220 : /* Create credential with prompt */
221 1 : gcr_mock_prompter_expect_password_ok ("booo",
222 : "choice-label", "Automatically unlock this keyring whenever I’m logged in",
223 : "choice-chosen", TRUE,
224 : NULL);
225 :
226 1 : rv = (test->module->C_CreateObject) (test->session, attrs, G_N_ELEMENTS (attrs), &credential);
227 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
228 1 : rv = (test->module->C_DestroyObject) (test->session, credential);
229 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
230 :
231 : /* No further prompting should be shown, uses stored password */
232 1 : g_assert (!gcr_mock_prompter_is_expecting ());
233 :
234 1 : rv = (test->module->C_CreateObject) (test->session, attrs, G_N_ELEMENTS (attrs), &credential);
235 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
236 :
237 : /* Change the password */
238 1 : gkm_mock_module_set_pin ("other");
239 :
240 : /* This should prompt again, as stored password is now wrong */
241 1 : gcr_mock_prompter_expect_password_ok ("other", NULL);
242 :
243 1 : rv = (test->module->C_CreateObject) (test->session, attrs, G_N_ELEMENTS (attrs), &credential);
244 1 : gkm_assert_cmprv (rv, ==, CKR_OK);
245 1 : }
246 :
247 : int
248 1 : main (int argc, char **argv)
249 : {
250 : #if !GLIB_CHECK_VERSION(2,35,0)
251 : g_type_init ();
252 : #endif
253 1 : g_test_init (&argc, &argv, NULL);
254 :
255 1 : g_test_add ("/wrap-layer/login-auto/specific", Test, NULL, setup, test_specific, teardown);
256 1 : g_test_add ("/wrap-layer/login-auto/user_token", Test, NULL, setup, test_user_token, teardown);
257 1 : g_test_add ("/wrap-layer/login-auto/unlock_keyring", Test, NULL, setup, test_unlock_keyring, teardown);
258 :
259 1 : return egg_tests_run_in_thread_with_loop ();
260 : }
|