Line data Source code
1 : /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 : /*
3 : Copyright (C) 2009 Stefan Walter
4 :
5 : The Gnome Keyring Library is free software; you can redistribute it and/or
6 : modify it under the terms of the GNU Library General Public License as
7 : published by the Free Software Foundation; either version 2 of the
8 : License, or (at your option) any later version.
9 :
10 : The Gnome Keyring Library is distributed in the hope that it will be useful,
11 : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : Library General Public License for more details.
14 :
15 : You should have received a copy of the GNU Library General Public
16 : License along with the Gnome Library; see the file COPYING.LIB. If not,
17 : <http://www.gnu.org/licenses/>.
18 :
19 : Author: Stef Walter <stef@memberwebs.com>
20 : */
21 :
22 : #include "config.h"
23 :
24 : #include "mock-secret-module.h"
25 :
26 : #include "secret-store/gkm-secret-collection.h"
27 : #include "secret-store/gkm-secret-fields.h"
28 : #include "secret-store/gkm-secret-item.h"
29 : #include "secret-store/gkm-secret-search.h"
30 :
31 : #include "gkm/gkm-session.h"
32 : #include "gkm/gkm-transaction.h"
33 : #include "gkm/gkm-test.h"
34 :
35 : #include "pkcs11/pkcs11i.h"
36 :
37 : #include <glib.h>
38 :
39 : #include <stdlib.h>
40 : #include <stdio.h>
41 : #include <string.h>
42 :
43 : typedef struct {
44 : GkmModule *module;
45 : GkmSession *session;
46 : GkmFactory *factory;
47 : GkmSecretCollection *collection;
48 : GkmSecretItem *item;
49 : } Test;
50 :
51 : static void
52 10 : setup (Test *test, gconstpointer unused)
53 : {
54 : GHashTable *fields;
55 :
56 10 : test->module = test_secret_module_initialize_and_enter ();
57 10 : test->session = test_secret_module_open_session (TRUE);
58 10 : test->factory = GKM_FACTORY_SECRET_SEARCH;
59 10 : g_assert (test->factory);
60 :
61 10 : test->collection = g_object_new (GKM_TYPE_SECRET_COLLECTION,
62 : "module", test->module,
63 : "manager", gkm_session_get_manager (test->session),
64 : "identifier", "test-collection",
65 : NULL);
66 :
67 : /* Create an test->item */
68 10 : test->item = gkm_secret_collection_new_item (test->collection, "test-item");
69 10 : fields = gkm_secret_fields_new ();
70 10 : gkm_secret_fields_add (fields, "name1", "value1");
71 10 : gkm_secret_fields_add (fields, "name2", "value2");
72 10 : gkm_secret_item_set_fields (test->item, fields);
73 10 : g_hash_table_unref (fields);
74 :
75 10 : gkm_object_expose (GKM_OBJECT (test->collection), TRUE);
76 10 : }
77 :
78 : static void
79 10 : teardown (Test *test, gconstpointer unused)
80 : {
81 10 : g_object_unref (test->collection);
82 10 : test_secret_module_leave_and_finalize ();
83 10 : }
84 :
85 : static void
86 1 : test_incomplete (Test *test, gconstpointer unused)
87 : {
88 : CK_ATTRIBUTE attrs[1];
89 1 : GkmObject *object = NULL;
90 1 : GkmTransaction *transaction = gkm_transaction_new ();
91 :
92 1 : object = gkm_session_create_object_for_factory (test->session, test->factory, transaction, attrs, 0);
93 1 : g_assert (gkm_transaction_complete_and_unref (transaction) == CKR_TEMPLATE_INCOMPLETE);
94 1 : g_assert (object == NULL);
95 1 : }
96 :
97 : static void
98 1 : test_bad_fields (Test *test, gconstpointer unused)
99 : {
100 1 : CK_ATTRIBUTE attrs[] = {
101 : { CKA_G_FIELDS, "bad-value", 9 },
102 : };
103 :
104 1 : GkmObject *object = NULL;
105 1 : GkmTransaction *transaction = gkm_transaction_new ();
106 :
107 1 : object = gkm_session_create_object_for_factory (test->session, test->factory, transaction, attrs, 1);
108 1 : g_assert (gkm_transaction_complete_and_unref (transaction) == CKR_ATTRIBUTE_VALUE_INVALID);
109 1 : g_assert (object == NULL);
110 1 : }
111 :
112 : static void
113 1 : test_new (Test *test, gconstpointer unused)
114 : {
115 1 : CK_ATTRIBUTE attrs[] = {
116 : { CKA_G_FIELDS, "test\0value\0two\0value2", 22 },
117 : };
118 :
119 : const gchar *identifier;
120 1 : GkmObject *object = NULL;
121 : GHashTable *fields;
122 : gpointer vdata;
123 : gulong vulong;
124 : gboolean vbool;
125 : gsize vsize;
126 :
127 1 : object = gkm_session_create_object_for_factory (test->session, test->factory, NULL, attrs, 1);
128 1 : g_assert (object != NULL);
129 1 : g_assert (GKM_IS_SECRET_SEARCH (object));
130 :
131 1 : if (!gkm_object_get_attribute_ulong (object, test->session, CKA_CLASS, &vulong))
132 0 : g_assert_not_reached ();
133 1 : g_assert (vulong == CKO_G_SEARCH);
134 :
135 1 : if (!gkm_object_get_attribute_boolean (object, test->session, CKA_MODIFIABLE, &vbool))
136 0 : g_assert_not_reached ();
137 1 : g_assert (vbool == CK_TRUE);
138 :
139 1 : vdata = gkm_object_get_attribute_data (object, test->session, CKA_G_FIELDS, &vsize);
140 1 : g_assert (vdata);
141 1 : g_assert (vsize == attrs[0].ulValueLen);
142 1 : g_free (vdata);
143 :
144 1 : vdata = gkm_object_get_attribute_data (object, test->session, CKA_G_COLLECTION, &vsize);
145 1 : g_assert (vdata);
146 1 : g_assert (vsize == 0);
147 1 : g_free (vdata);
148 :
149 : /* No objects matched */
150 1 : vdata = gkm_object_get_attribute_data (object, test->session, CKA_G_MATCHED, &vsize);
151 1 : g_assert (vdata);
152 1 : g_assert (vsize == 0);
153 1 : g_free (vdata);
154 :
155 : /* Get the fields object and check */
156 1 : fields = gkm_secret_search_get_fields (GKM_SECRET_SEARCH (object));
157 1 : g_assert (fields);
158 1 : g_assert_cmpstr (gkm_secret_fields_get (fields, "test"), ==, "value");
159 :
160 : /* No test->collection */
161 1 : identifier = gkm_secret_search_get_collection_id (GKM_SECRET_SEARCH (object));
162 1 : g_assert (identifier == NULL);
163 :
164 1 : g_object_unref (object);
165 1 : }
166 :
167 : static void
168 1 : test_and_match (Test *test, gconstpointer unused)
169 : {
170 1 : CK_ATTRIBUTE attrs[] = {
171 : { CKA_G_FIELDS, "name1\0value1\0name2\0value2", 26 },
172 : };
173 :
174 1 : GkmObject *object = NULL;
175 : gpointer vdata;
176 : gsize vsize;
177 :
178 1 : object = gkm_session_create_object_for_factory (test->session, test->factory, NULL, attrs, 1);
179 1 : g_assert (object != NULL);
180 1 : g_assert (GKM_IS_SECRET_SEARCH (object));
181 :
182 : /* One object matched */
183 1 : vdata = gkm_object_get_attribute_data (object, test->session, CKA_G_MATCHED, &vsize);
184 1 : g_assert (vdata);
185 1 : g_assert (vsize == sizeof (CK_OBJECT_HANDLE));
186 1 : g_assert (*((CK_OBJECT_HANDLE_PTR)vdata) == gkm_object_get_handle (GKM_OBJECT (test->item)));
187 1 : g_free (vdata);
188 :
189 1 : g_object_unref (object);
190 1 : }
191 :
192 : static void
193 1 : test_and_change_to_match (Test *test, gconstpointer unused)
194 : {
195 1 : CK_ATTRIBUTE attrs[] = {
196 : { CKA_G_FIELDS, "name1\0value1", 13 },
197 : };
198 :
199 1 : GkmObject *object = NULL;
200 : GHashTable *fields;
201 : gpointer vdata;
202 : gsize vsize;
203 :
204 : /* Make it not match */
205 1 : fields = gkm_secret_fields_new ();
206 1 : gkm_secret_item_set_fields (test->item, fields);
207 1 : g_hash_table_unref (fields);
208 :
209 1 : object = gkm_session_create_object_for_factory (test->session, test->factory, NULL, attrs, 1);
210 1 : g_assert (object != NULL);
211 1 : g_assert (GKM_IS_SECRET_SEARCH (object));
212 :
213 : /* Nothing matched */
214 1 : vdata = gkm_object_get_attribute_data (object, test->session, CKA_G_MATCHED, &vsize);
215 1 : g_assert (vsize == 0);
216 1 : g_free (vdata);
217 :
218 : /* Make it match */
219 1 : fields = gkm_secret_fields_new ();
220 1 : gkm_secret_fields_add (fields, "name1", "value1");
221 1 : gkm_secret_fields_add (fields, "name2", "value2");
222 1 : gkm_secret_item_set_fields (test->item, fields);
223 1 : g_hash_table_unref (fields);
224 :
225 : /* One object matched */
226 1 : vdata = gkm_object_get_attribute_data (object, test->session, CKA_G_MATCHED, &vsize);
227 1 : g_assert (vdata);
228 1 : g_assert (vsize == sizeof (CK_OBJECT_HANDLE));
229 1 : g_assert (*((CK_OBJECT_HANDLE_PTR)vdata) == gkm_object_get_handle (GKM_OBJECT (test->item)));
230 1 : g_free (vdata);
231 :
232 1 : g_object_unref (object);
233 1 : }
234 :
235 : static void
236 1 : test_and_change_to_not_match (Test *test, gconstpointer unused)
237 : {
238 1 : CK_ATTRIBUTE attrs[] = {
239 : { CKA_G_FIELDS, "name1\0value1", 13 },
240 : };
241 :
242 1 : GkmObject *object = NULL;
243 : GHashTable *fields;
244 : gpointer vdata;
245 : gsize vsize;
246 :
247 1 : object = gkm_session_create_object_for_factory (test->session, test->factory, NULL, attrs, 1);
248 1 : g_assert (object != NULL);
249 1 : g_assert (GKM_IS_SECRET_SEARCH (object));
250 :
251 : /* One object matched */
252 1 : vdata = gkm_object_get_attribute_data (object, test->session, CKA_G_MATCHED, &vsize);
253 1 : g_assert (vdata);
254 1 : g_assert (vsize == sizeof (CK_OBJECT_HANDLE));
255 1 : g_assert (*((CK_OBJECT_HANDLE_PTR)vdata) == gkm_object_get_handle (GKM_OBJECT (test->item)));
256 1 : g_free (vdata);
257 :
258 : /* Make it not match */
259 1 : fields = gkm_secret_fields_new ();
260 1 : gkm_secret_item_set_fields (test->item, fields);
261 1 : g_hash_table_unref (fields);
262 :
263 : /* Nothing matched */
264 1 : vdata = gkm_object_get_attribute_data (object, test->session, CKA_G_MATCHED, &vsize);
265 1 : g_assert (vsize == 0);
266 1 : g_free (vdata);
267 :
268 1 : g_object_unref (object);
269 1 : }
270 :
271 : static void
272 1 : test_for_bad_collection (Test *test, gconstpointer unused)
273 : {
274 1 : CK_ATTRIBUTE attrs[] = {
275 : { CKA_G_FIELDS, "name1\0value1", 13 },
276 : { CKA_G_COLLECTION, "bad-test->collection", 14 },
277 : };
278 :
279 1 : GkmObject *object = NULL;
280 1 : GkmTransaction *transaction = gkm_transaction_new ();
281 :
282 1 : object = gkm_session_create_object_for_factory (test->session, test->factory, transaction, attrs, 2);
283 1 : g_assert (gkm_transaction_complete_and_unref (transaction) == CKR_OK);
284 :
285 1 : g_object_unref (object);
286 1 : }
287 :
288 : static void
289 1 : test_for_collection (Test *test, gconstpointer unused)
290 : {
291 1 : CK_ATTRIBUTE attrs[] = {
292 : { CKA_G_FIELDS, "name1\0value1", 13 },
293 : { CKA_G_COLLECTION, "test-collection", 15 },
294 : };
295 :
296 1 : GkmObject *object = NULL;
297 : gpointer vdata;
298 : gsize vsize;
299 :
300 1 : object = gkm_session_create_object_for_factory (test->session, test->factory, NULL, attrs, 2);
301 1 : g_assert (object != NULL);
302 1 : g_assert (GKM_IS_SECRET_SEARCH (object));
303 :
304 : /* Should have the test->collection set properly */
305 1 : vdata = gkm_object_get_attribute_data (object, test->session, CKA_G_COLLECTION , &vsize);
306 1 : g_assert (vdata);
307 1 : g_assert (vsize == 15);
308 1 : g_assert (memcmp (vdata, "test-collection", 15) == 0);
309 1 : g_free (vdata);
310 :
311 : /* One object matched */
312 1 : vdata = gkm_object_get_attribute_data (object, test->session, CKA_G_MATCHED, &vsize);
313 1 : g_assert (vdata);
314 1 : g_assert (vsize == sizeof (CK_OBJECT_HANDLE));
315 1 : g_assert (*((CK_OBJECT_HANDLE_PTR)vdata) == gkm_object_get_handle (GKM_OBJECT (test->item)));
316 1 : g_free (vdata);
317 :
318 1 : g_object_unref (object);
319 1 : }
320 :
321 : static void
322 1 : test_for_collection_no_match (Test *test, gconstpointer unused)
323 : {
324 1 : CK_ATTRIBUTE attrs[] = {
325 : { CKA_G_FIELDS, "test\0value", 11 },
326 : { CKA_G_COLLECTION, "test-collection", 15 },
327 : };
328 :
329 1 : GkmObject *object = NULL;
330 : GkmSecretCollection *ocoll;
331 : GkmSecretItem *oitem;
332 : GHashTable *fields;
333 : gpointer vdata;
334 : gsize vsize;
335 :
336 1 : ocoll = g_object_new (GKM_TYPE_SECRET_COLLECTION,
337 : "module", test->module,
338 : "manager", gkm_session_get_manager (test->session),
339 : "identifier", "other-collection",
340 : NULL);
341 1 : oitem = gkm_secret_collection_new_item (ocoll, "other-item");
342 1 : gkm_object_expose (GKM_OBJECT (ocoll), TRUE);
343 :
344 : /* Make it match, but remember, wrong collection*/
345 1 : fields = gkm_secret_fields_new ();
346 1 : gkm_secret_fields_add (fields, "test", "value");
347 1 : gkm_secret_item_set_fields (oitem, fields);
348 1 : g_hash_table_unref (fields);
349 :
350 1 : object = gkm_session_create_object_for_factory (test->session, test->factory, NULL, attrs, 2);
351 1 : g_assert (object != NULL);
352 1 : g_assert (GKM_IS_SECRET_SEARCH (object));
353 :
354 : /* No objects matched */
355 1 : vdata = gkm_object_get_attribute_data (object, test->session, CKA_G_MATCHED, &vsize);
356 1 : g_assert (vsize == 0);
357 1 : g_free (vdata);
358 :
359 1 : g_object_unref (object);
360 1 : g_object_unref (ocoll);
361 1 : }
362 :
363 : static void
364 1 : test_order (Test *test,
365 : gconstpointer unused)
366 : {
367 1 : CK_ATTRIBUTE attrs[] = {
368 : { CKA_G_FIELDS, "test\0value", 11 },
369 : { CKA_G_COLLECTION, "other-collection", 16 },
370 : };
371 :
372 1 : GkmObject *object = NULL;
373 : GkmSecretCollection *collection;
374 : GkmSecretItem *item;
375 : GHashTable *fields;
376 : gulong *matched;
377 : gsize vsize;
378 : gchar *identifier;
379 : glong modified;
380 : glong last;
381 : gint i;
382 : CK_RV rv;
383 :
384 1 : collection = g_object_new (GKM_TYPE_SECRET_COLLECTION,
385 : "module", test->module,
386 : "manager", gkm_session_get_manager (test->session),
387 : "identifier", "other-collection",
388 : NULL);
389 :
390 1 : gkm_object_expose (GKM_OBJECT (collection), TRUE);
391 :
392 : /* Add a bunch of items */
393 2001 : for (i = 0; i < 2000; i++) {
394 2000 : identifier = g_strdup_printf ("item-%d", i);
395 2000 : item = gkm_secret_collection_new_item (collection, identifier);
396 2000 : g_free (identifier);
397 :
398 : /* Make it match, but remember, wrong collection*/
399 2000 : fields = gkm_secret_fields_new ();
400 2000 : gkm_secret_fields_add (fields, "test", "value");
401 2000 : gkm_secret_item_set_fields (item, fields);
402 2000 : g_hash_table_unref (fields);
403 :
404 2000 : gkm_secret_object_set_modified (GKM_SECRET_OBJECT (item),
405 2000 : (glong)g_random_int ());
406 2000 : gkm_object_expose (GKM_OBJECT (item), TRUE);
407 : }
408 :
409 1 : object = gkm_session_create_object_for_factory (test->session, test->factory, NULL, attrs, 2);
410 1 : g_assert (object != NULL);
411 1 : g_assert (GKM_IS_SECRET_SEARCH (object));
412 :
413 : /* No objects matched */
414 1 : matched = gkm_object_get_attribute_data (object, test->session, CKA_G_MATCHED, &vsize);
415 1 : g_assert (matched != NULL);
416 1 : gkm_assert_cmpulong (vsize, ==, sizeof (gulong) * 2000);
417 :
418 1 : last = G_MAXLONG;
419 2001 : for (i = 0; i < vsize / sizeof (gulong); i++) {
420 2000 : rv = gkm_session_lookup_readable_object (test->session, matched[i], (GkmObject **)&item);
421 2000 : gkm_assert_cmprv (rv, ==, CKR_OK);
422 :
423 2000 : modified = gkm_secret_object_get_modified (GKM_SECRET_OBJECT (item));
424 2000 : g_assert (last > modified);
425 2000 : last = modified;
426 : }
427 :
428 1 : g_free (matched);
429 :
430 1 : g_object_unref (object);
431 1 : g_object_unref (collection);
432 1 : }
433 :
434 : int
435 1 : main (int argc, char **argv)
436 : {
437 : #if !GLIB_CHECK_VERSION(2,35,0)
438 : g_type_init ();
439 : #endif
440 1 : g_test_init (&argc, &argv, NULL);
441 :
442 1 : g_test_add ("/secret-store/search/new", Test, NULL, setup, test_new, teardown);
443 1 : g_test_add ("/secret-store/search/incomplete", Test, NULL, setup, test_incomplete, teardown);
444 1 : g_test_add ("/secret-store/search/bad_fields", Test, NULL, setup, test_bad_fields, teardown);
445 1 : g_test_add ("/secret-store/search/and_match", Test, NULL, setup, test_and_match, teardown);
446 1 : g_test_add ("/secret-store/search/and_change_to_match", Test, NULL, setup, test_and_change_to_match, teardown);
447 1 : g_test_add ("/secret-store/search/and_change_to_not_match", Test, NULL, setup, test_and_change_to_not_match, teardown);
448 1 : g_test_add ("/secret-store/search/for_bad_collection", Test, NULL, setup, test_for_bad_collection, teardown);
449 1 : g_test_add ("/secret-store/search/for_collection", Test, NULL, setup, test_for_collection, teardown);
450 1 : g_test_add ("/secret-store/search/for_collection_no_match", Test, NULL, setup, test_for_collection_no_match, teardown);
451 1 : g_test_add ("/secret-store/search/order", Test, NULL, setup, test_order, teardown);
452 :
453 1 : return g_test_run ();
454 : }
|