]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/regressions/kc-21-item-use-callback.c
Security-57740.31.2.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / regressions / kc-21-item-use-callback.c
1 #include <Security/SecKeychainItem.h>
2 #include <Security/SecKeychain.h>
3 #include <CoreFoundation/CFRunLoop.h>
4 #include <unistd.h>
5
6 #include "keychain_regressions.h"
7 #include "kc-helpers.h"
8
9 static char account[] = "account";
10 static char service[] = "service";
11 static char password[] = "password";
12 static bool callbackCalled = false;
13
14 static void checkContent(SecKeychainItemRef itemRef)
15 {
16 SecItemClass itemClass;
17
18 SecKeychainAttribute attrs[] =
19 {
20 { kSecLabelItemAttr, 0, NULL },
21 { kSecAccountItemAttr, 0, NULL },
22 { kSecServiceItemAttr, 0, NULL }
23 };
24
25 SecKeychainAttributeList attrList =
26 { sizeof(attrs) / sizeof(*attrs), attrs };
27 UInt32 length;
28 void *data;
29
30 ok_status(SecKeychainItemCopyContent(itemRef, &itemClass, &attrList,
31 &length, &data), "get item data in callback");
32 is(length, sizeof(password), "<rdar://problem/3867900> "
33 "SecKeychainItemCopyContent() returns bad data on items "
34 "from notifications");
35
36 ok(!memcmp(password, data, length), "password data matches.");
37
38 ok_status(SecKeychainItemFreeContent(&attrList, data),
39 "free item data in callback");
40 }
41
42 static OSStatus callbackFunction(SecKeychainEvent keychainEvent,
43 SecKeychainCallbackInfo *info, void *context)
44 {
45 is(keychainEvent, kSecAddEvent, "Got an incorrect keychain event");
46 ok(context != NULL, "context is null");
47 ok(info != NULL, "info is NULL");
48 ok(info->item != NULL, "info-<item is NULL");
49
50 checkContent(info->item);
51 *((UInt32 *)context) = 1;
52
53 ok_status(SecKeychainItemDelete(info->item), "delete item");
54
55 // We processed an item, quit the run loop
56 callbackCalled = true;
57 CFRunLoopStop(CFRunLoopGetCurrent());
58 return 0;
59 }
60
61 int
62 kc_21_item_use_callback(int argc, char *const *argv)
63 {
64 plan_tests(14);
65
66 // Run the CFRunLoop to clear out existing notifications
67 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, false);
68
69 UInt32 didGetNotification = 0;
70 ok_status(SecKeychainAddCallback(callbackFunction, kSecAddEventMask,
71 &didGetNotification), "add callback");
72
73 SecKeychainRef keychain = createNewKeychain("test", "test");
74 SecKeychainItemRef itemRef;
75 ok_status(SecKeychainAddGenericPassword(keychain,
76 sizeof(account), account,
77 sizeof(service), service,
78 sizeof(password), password,
79 &itemRef),
80 "add generic password, release and wait for callback");
81
82 // Run the CFRunLoop to process events (and call our callback)
83 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10.0, false);
84 is(callbackCalled, true, "Keychain callback function was not called or did not finish");
85
86 CFRelease(itemRef);
87
88 ok_status(SecKeychainDelete(keychain), "%s: SecKeychainDelete", testName);
89 CFRelease(keychain);
90
91 deleteTestFiles();
92 return 0;
93 }