1 #include <Security/SecKeychainItem.h>
2 #include <Security/SecKeychain.h>
3 #include <CoreFoundation/CFRunLoop.h>
6 #include "keychain_regressions.h"
7 #include "kc-helpers.h"
10 Note: to force a failure, run this as root:
11 chmod o-r /var/db/mds/messages/se_SecurityMessages
13 chmod o+r /var/db/mds/messages/se_SecurityMessages
16 static char account
[] = "account";
17 static char service
[] = "service";
18 static char password
[] = "password";
19 static bool callbackCalled
= false;
21 static void checkContent(SecKeychainItemRef itemRef
)
23 SecItemClass itemClass
;
25 SecKeychainAttribute attrs
[] =
27 { kSecLabelItemAttr
, 0, NULL
},
28 { kSecAccountItemAttr
, 0, NULL
},
29 { kSecServiceItemAttr
, 0, NULL
}
32 SecKeychainAttributeList attrList
=
33 { sizeof(attrs
) / sizeof(*attrs
), attrs
};
37 ok_status(SecKeychainItemCopyContent(itemRef
, &itemClass
, &attrList
,
38 &length
, &data
), "get item data in callback");
39 is(length
, sizeof(password
), "<rdar://problem/3867900> "
40 "SecKeychainItemCopyContent() returns bad data on items "
41 "from notifications");
42 ok(data
, "received data from item");
44 ok(!memcmp(password
, data
, length
), "password data matches.");
46 ok_status(SecKeychainItemFreeContent(&attrList
, data
),
47 "free item data in callback");
50 static OSStatus
callbackFunction(SecKeychainEvent keychainEvent
,
51 SecKeychainCallbackInfo
*info
, void *context
)
53 is(keychainEvent
, kSecAddEvent
, "Got an incorrect keychain event");
54 ok(context
!= NULL
, "context is null");
55 ok(info
!= NULL
, "info is NULL");
56 ok(info
->item
!= NULL
, "info-<item is NULL");
58 checkContent(info
->item
);
59 *((UInt32
*)context
) = 1;
61 ok_status(SecKeychainItemDelete(info
->item
), "delete item");
63 // We processed an item, quit the run loop
64 callbackCalled
= true;
65 CFRunLoopStop(CFRunLoopGetCurrent());
70 kc_21_item_use_callback(int argc
, char *const *argv
)
74 // Run the CFRunLoop to clear out existing notifications
75 CFRunLoopRunInMode(kCFRunLoopDefaultMode
, 1.0, false);
77 UInt32 didGetNotification
= 0;
78 ok_status(SecKeychainAddCallback(callbackFunction
, kSecAddEventMask
,
79 &didGetNotification
), "add callback");
81 SecKeychainRef keychain
= createNewKeychain("test", "test");
82 SecKeychainItemRef itemRef
;
83 ok_status(SecKeychainAddGenericPassword(keychain
,
84 sizeof(account
), account
,
85 sizeof(service
), service
,
86 sizeof(password
), password
,
88 "add generic password, release and wait for callback");
90 // Run the CFRunLoop to process events (and call our callback)
91 CFRunLoopRunInMode(kCFRunLoopDefaultMode
, 10.0, false);
92 is(callbackCalled
, true, "Keychain callback function was not called or did not finish");
96 ok_status(SecKeychainRemoveCallback(callbackFunction
), "Remove callback");
98 ok_status(SecKeychainDelete(keychain
), "%s: SecKeychainDelete", testName
);