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 "egg/egg-secure-memory.h"
24 : #include "egg/egg-testing.h"
25 :
26 : #include "gkm/gkm-attributes.h"
27 : #include "gkm/gkm-mock.h"
28 : #include "gkm/gkm-test.h"
29 :
30 : #include "wrap-layer/gkm-wrap-layer.h"
31 : #include "wrap-layer/gkm-wrap-login.h"
32 :
33 : #include <glib-object.h>
34 :
35 : extern CK_FUNCTION_LIST mock_secret_store;
36 :
37 : typedef struct {
38 : CK_FUNCTION_LIST functions;
39 : CK_FUNCTION_LIST_PTR module;
40 : } Test;
41 :
42 : static void
43 12 : setup (Test *test, gconstpointer unused)
44 : {
45 : CK_RV rv;
46 :
47 : /* Always start off with test test->functions */
48 12 : memcpy (&test->functions, &mock_secret_store, sizeof (test->functions));
49 12 : gkm_wrap_layer_reset_modules ();
50 12 : gkm_wrap_layer_add_module (&test->functions);
51 12 : test->module = gkm_wrap_layer_get_functions ();
52 :
53 : /* Initialize */
54 12 : rv = (test->module->C_Initialize) (NULL);
55 12 : gkm_assert_cmprv (rv, ==, CKR_OK);
56 12 : }
57 :
58 : static void
59 12 : teardown (Test *test, gconstpointer unused)
60 : {
61 : CK_RV rv;
62 :
63 12 : rv = (test->module->C_Finalize) (NULL);
64 12 : gkm_assert_cmprv (rv, ==, CKR_OK);
65 12 : test->module = NULL;
66 12 : }
67 :
68 : static void
69 1 : test_is_usable (Test *test, gconstpointer unused)
70 : {
71 : gboolean ret;
72 :
73 1 : ret = gkm_wrap_login_is_usable ();
74 1 : g_assert (ret == TRUE);
75 1 : }
76 :
77 : static void
78 1 : test_usable_fail_open_session (Test *test, gconstpointer unused)
79 : {
80 : gboolean ret;
81 :
82 1 : test->functions.C_OpenSession = gkm_mock_fail_C_OpenSession;
83 1 : ret = gkm_wrap_login_is_usable ();
84 1 : g_assert (ret == FALSE);
85 1 : }
86 :
87 : static void
88 1 : test_usable_fail_not_trusted (Test *test, gconstpointer unused)
89 : {
90 : CK_OBJECT_HANDLE object;
91 : CK_ATTRIBUTE attr;
92 : CK_BBOOL bval;
93 : gboolean ret;
94 :
95 1 : ret = gkm_wrap_login_is_usable ();
96 1 : g_assert (ret == TRUE);
97 :
98 1 : bval = CK_TRUE;
99 1 : attr.type = CKA_G_LOGIN_COLLECTION;
100 1 : attr.pValue = &bval;
101 1 : attr.ulValueLen = sizeof (bval);
102 :
103 1 : object = gkm_mock_module_find_object (0, &attr, 1);
104 1 : gkm_assert_cmpulong (object, !=, 0);
105 :
106 1 : bval = CK_FALSE;
107 1 : attr.type = CKA_TRUSTED;
108 1 : attr.pValue = &bval;
109 1 : attr.ulValueLen = sizeof (bval);
110 :
111 1 : gkm_mock_module_set_object (object, &attr, 1);
112 :
113 : /* Not trusted, so no longer usable */
114 1 : ret = gkm_wrap_login_is_usable ();
115 1 : g_assert (ret == FALSE);
116 1 : }
117 :
118 : static void
119 1 : test_usable_fail_locked (Test *test, gconstpointer unused)
120 : {
121 : CK_OBJECT_HANDLE object;
122 : CK_ATTRIBUTE attr;
123 : CK_BBOOL bval;
124 : gboolean ret;
125 :
126 1 : ret = gkm_wrap_login_is_usable ();
127 1 : g_assert (ret == TRUE);
128 :
129 1 : bval = CK_TRUE;
130 1 : attr.type = CKA_G_LOGIN_COLLECTION;
131 1 : attr.pValue = &bval;
132 1 : attr.ulValueLen = sizeof (bval);
133 :
134 1 : object = gkm_mock_module_find_object (0, &attr, 1);
135 1 : gkm_assert_cmpulong (object, !=, 0);
136 :
137 1 : bval = CK_TRUE;
138 1 : attr.type = CKA_G_LOCKED;
139 1 : attr.pValue = &bval;
140 1 : attr.ulValueLen = sizeof (bval);
141 :
142 1 : gkm_mock_module_set_object (object, &attr, 1);
143 :
144 : /* Not unlocked, so no longer usable */
145 1 : ret = gkm_wrap_login_is_usable ();
146 1 : g_assert (ret == FALSE);
147 1 : }
148 :
149 : static void
150 1 : test_lookup_secret_no_match (Test *test, gconstpointer unused)
151 : {
152 : gchar *password;
153 :
154 1 : password = gkm_wrap_login_lookup_secret ("invalid", "attribute",
155 : "second", "attribute", NULL);
156 1 : g_assert_cmpstr (password, ==, NULL);
157 1 : }
158 :
159 : static void
160 1 : test_lookup_secret_and_match (Test *test, gconstpointer unused)
161 : {
162 : gchar *password;
163 :
164 : /* Secret stored in mock-secret-store.c */
165 1 : password = gkm_wrap_login_lookup_secret ("one", "1",
166 : "two", "2", NULL);
167 1 : g_assert_cmpstr (password, ==, "mock");
168 :
169 1 : egg_secure_free (password);
170 1 : }
171 :
172 : static void
173 1 : test_lookup_store_secret (Test *test, gconstpointer unused)
174 : {
175 1 : CK_OBJECT_CLASS klass = CKO_SECRET_KEY;
176 1 : CK_BBOOL tval = CK_TRUE;
177 1 : CK_ATTRIBUTE attrs[] = {
178 : { CKA_LABEL, "Unlock password for: The label", 30 },
179 : { CKA_CLASS, &klass, sizeof (klass) },
180 : { CKA_VALUE, "the password", 12 },
181 : { CKA_TOKEN, &tval, sizeof (tval) },
182 : { CKA_G_COLLECTION, "login", 5 },
183 : { CKA_G_FIELDS, "one\0" "1\0" "three\0" "3\0", 14 },
184 : };
185 :
186 : CK_OBJECT_HANDLE object;
187 :
188 : /* Secret stored in mock-secret-store.c */
189 1 : gkm_wrap_login_attach_secret ("The label", "the password",
190 : "one", "1",
191 : "three", "3", NULL);
192 :
193 1 : object = gkm_mock_module_find_object (0, attrs, G_N_ELEMENTS (attrs));
194 1 : gkm_assert_cmpulong (object, !=, 0);
195 1 : }
196 :
197 : static void
198 1 : test_lookup_store_secret_overwrite (Test *test, gconstpointer unused)
199 : {
200 1 : CK_OBJECT_CLASS klass = CKO_SECRET_KEY;
201 1 : CK_BBOOL tval = CK_TRUE;
202 1 : CK_ATTRIBUTE attrs[] = {
203 : { CKA_VALUE, "the password", 12 },
204 : { CKA_LABEL, "Unlock password for: The label", 30 },
205 : { CKA_CLASS, &klass, sizeof (klass) },
206 : { CKA_TOKEN, &tval, sizeof (tval) },
207 : { CKA_G_COLLECTION, "login", 5 },
208 : { CKA_G_FIELDS, "one\0" "1\0" "three\0" "3\0", 14 },
209 : };
210 :
211 : CK_OBJECT_HANDLE object1, object2;
212 :
213 : /* Secret stored in mock-secret-store.c */
214 1 : gkm_wrap_login_attach_secret ("The label", "the password",
215 : "one", "1",
216 : "three", "3", NULL);
217 :
218 1 : object1 = gkm_mock_module_find_object (0, attrs, G_N_ELEMENTS (attrs));
219 1 : gkm_assert_cmpulong (object1, !=, 0);
220 :
221 : /* Secret stored in mock-secret-store.c */
222 1 : gkm_wrap_login_attach_secret ("The label", "other",
223 : "one", "1",
224 : "three", "3", NULL);
225 :
226 1 : attrs[0].pValue = "other";
227 1 : attrs[0].ulValueLen = 5;
228 :
229 1 : object2 = gkm_mock_module_find_object (0, attrs, G_N_ELEMENTS (attrs));
230 1 : gkm_assert_cmpulong (object2, !=, 0);
231 :
232 : /* Should have been stored on same object */
233 1 : gkm_assert_cmpulong (object1, ==, object2);
234 1 : }
235 :
236 : static void
237 1 : test_lookup_store_null_secret (Test *test, gconstpointer unused)
238 : {
239 1 : CK_OBJECT_CLASS klass = CKO_SECRET_KEY;
240 1 : CK_BBOOL tval = CK_TRUE;
241 1 : CK_ATTRIBUTE attrs[] = {
242 : { CKA_LABEL, "Unlock password for: The label", 30 },
243 : { CKA_CLASS, &klass, sizeof (klass) },
244 : { CKA_VALUE, "", 0 },
245 : { CKA_TOKEN, &tval, sizeof (tval) },
246 : { CKA_G_COLLECTION, "login", 5 },
247 : { CKA_G_FIELDS, "one\0" "1\0" "three\0" "3\0", 14 },
248 : };
249 :
250 : CK_OBJECT_HANDLE object;
251 :
252 1 : gkm_wrap_login_attach_secret ("The label", NULL,
253 : "one", "1",
254 : "three", "3", NULL);
255 :
256 1 : object = gkm_mock_module_find_object (0, attrs, G_N_ELEMENTS (attrs));
257 1 : gkm_assert_cmpulong (object, !=, 0);
258 1 : }
259 :
260 : static void
261 1 : test_lookup_store_no_attributes_not_stored (Test *test, gconstpointer unused)
262 : {
263 1 : CK_OBJECT_CLASS klass = CKO_SECRET_KEY;
264 1 : CK_BBOOL tval = CK_TRUE;
265 1 : CK_ATTRIBUTE attrs[] = {
266 : { CKA_LABEL, "Unlock password for: The label", 30 },
267 : { CKA_CLASS, &klass, sizeof (klass) },
268 : { CKA_VALUE, "the password", 0 },
269 : { CKA_TOKEN, &tval, sizeof (tval) },
270 : { CKA_G_COLLECTION, "login", 5 },
271 : { CKA_G_FIELDS, "", 0 },
272 : };
273 :
274 : CK_OBJECT_HANDLE object;
275 :
276 1 : gkm_wrap_login_attach_secret ("The label", "the password", NULL);
277 :
278 1 : object = gkm_mock_module_find_object (0, attrs, G_N_ELEMENTS (attrs));
279 1 : gkm_assert_cmpulong (object, ==, 0);
280 1 : }
281 :
282 :
283 : static void
284 1 : test_lookup_remove_present (Test *test, gconstpointer unused)
285 : {
286 1 : CK_OBJECT_CLASS klass = CKO_SECRET_KEY;
287 1 : CK_BBOOL tval = CK_TRUE;
288 1 : CK_ATTRIBUTE attrs[] = {
289 : { CKA_LABEL, "Unlock password for: Mock", 25 },
290 : { CKA_CLASS, &klass, sizeof (klass) },
291 : { CKA_VALUE, "mock", 4 },
292 : { CKA_TOKEN, &tval, sizeof (tval) },
293 : { CKA_G_COLLECTION, "login", 5 },
294 : { CKA_G_FIELDS, "one\0" "1\0" "two\0" "2\0", 12 },
295 : };
296 :
297 : CK_OBJECT_HANDLE object;
298 :
299 : /* This object is created in mock-secret-store.c */
300 1 : object = gkm_mock_module_find_object (0, attrs, G_N_ELEMENTS (attrs));
301 1 : gkm_assert_cmpulong (object, !=, 0);
302 :
303 1 : gkm_wrap_login_remove_secret ("one", "1", "two", "2", NULL);
304 :
305 : /* No longer there */
306 1 : object = gkm_mock_module_find_object (0, attrs, G_N_ELEMENTS (attrs));
307 1 : gkm_assert_cmpulong (object, ==, 0);
308 1 : }
309 :
310 : static void
311 1 : test_lookup_remove_no_attributes (Test *test, gconstpointer unused)
312 : {
313 : guint n_objects, check;
314 :
315 1 : n_objects = gkm_mock_module_count_objects (0);
316 1 : g_assert_cmpuint (n_objects, >, 0);
317 :
318 : /* Shouldn't remove anything if no attributes */
319 1 : gkm_wrap_login_remove_secret (NULL);
320 :
321 1 : check = gkm_mock_module_count_objects (0);
322 1 : g_assert_cmpuint (check, ==, n_objects);
323 1 : }
324 :
325 : int
326 1 : main (int argc, char **argv)
327 : {
328 : #if !GLIB_CHECK_VERSION(2,35,0)
329 : g_type_init ();
330 : #endif
331 1 : g_test_init (&argc, &argv, NULL);
332 :
333 1 : g_test_add ("/wrap-layer/login-keyring/is_usable", Test, NULL, setup, test_is_usable, teardown);
334 1 : g_test_add ("/wrap-layer/login-keyring/usable_fail_open_session", Test, NULL, setup, test_usable_fail_open_session, teardown);
335 1 : g_test_add ("/wrap-layer/login-keyring/usable_fail_not_trusted", Test, NULL, setup, test_usable_fail_not_trusted, teardown);
336 1 : g_test_add ("/wrap-layer/login-keyring/usable_fail_locked", Test, NULL, setup, test_usable_fail_locked, teardown);
337 1 : g_test_add ("/wrap-layer/login-keyring/lookup_secret_no_match", Test, NULL, setup, test_lookup_secret_no_match, teardown);
338 1 : g_test_add ("/wrap-layer/login-keyring/lookup_secret_and_match", Test, NULL, setup, test_lookup_secret_and_match, teardown);
339 1 : g_test_add ("/wrap-layer/login-keyring/lookup_store_secret", Test, NULL, setup, test_lookup_store_secret, teardown);
340 1 : g_test_add ("/wrap-layer/login-keyring/lookup_store_secret_overwrite", Test, NULL, setup, test_lookup_store_secret_overwrite, teardown);
341 1 : g_test_add ("/wrap-layer/login-keyring/lookup_store_null_secret", Test, NULL, setup, test_lookup_store_null_secret, teardown);
342 1 : g_test_add ("/wrap-layer/login-keyring/lookup_store_no_attributes_not_stored", Test, NULL, setup, test_lookup_store_no_attributes_not_stored, teardown);
343 1 : g_test_add ("/wrap-layer/login-keyring/lookup_remove_present", Test, NULL, setup, test_lookup_remove_present, teardown);
344 1 : g_test_add ("/wrap-layer/login-keyring/lookup_remove_no_attributes", Test, NULL, setup, test_lookup_remove_no_attributes, teardown);
345 :
346 1 : return egg_tests_run_in_thread_with_loop ();
347 : }
|