]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_keychain/regressions/kc-21-item-use-callback.c
Security-57740.1.18.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / regressions / kc-21-item-use-callback.c
diff --git a/OSX/libsecurity_keychain/regressions/kc-21-item-use-callback.c b/OSX/libsecurity_keychain/regressions/kc-21-item-use-callback.c
new file mode 100644 (file)
index 0000000..808c93a
--- /dev/null
@@ -0,0 +1,93 @@
+#include <Security/SecKeychainItem.h>
+#include <Security/SecKeychain.h>
+#include <CoreFoundation/CFRunLoop.h>
+#include <unistd.h>
+
+#include "keychain_regressions.h"
+#include "kc-helpers.h"
+
+static char account[] = "account";
+static char service[] = "service";
+static char password[] = "password";
+static bool callbackCalled = false;
+
+static void checkContent(SecKeychainItemRef itemRef)
+{
+       SecItemClass itemClass;
+
+       SecKeychainAttribute attrs[] =
+       {
+               { kSecLabelItemAttr, 0, NULL },
+               { kSecAccountItemAttr, 0, NULL },
+               { kSecServiceItemAttr, 0, NULL }
+       };
+
+       SecKeychainAttributeList attrList =
+               { sizeof(attrs) / sizeof(*attrs), attrs };
+       UInt32 length;
+       void *data;
+
+       ok_status(SecKeychainItemCopyContent(itemRef, &itemClass, &attrList,
+               &length, &data), "get item data in callback");
+    is(length, sizeof(password), "<rdar://problem/3867900> "
+        "SecKeychainItemCopyContent() returns bad data on items "
+        "from notifications");
+
+    ok(!memcmp(password, data, length), "password data matches.");
+
+       ok_status(SecKeychainItemFreeContent(&attrList, data),
+               "free item data in callback");
+}
+
+static OSStatus callbackFunction(SecKeychainEvent keychainEvent,
+       SecKeychainCallbackInfo *info, void *context)
+{
+    is(keychainEvent, kSecAddEvent, "Got an incorrect keychain event");
+    ok(context != NULL, "context is null");
+    ok(info != NULL, "info is NULL");
+    ok(info->item != NULL, "info-<item is NULL");
+
+       checkContent(info->item);
+       *((UInt32 *)context) = 1;
+
+       ok_status(SecKeychainItemDelete(info->item), "delete item");
+
+    // We processed an item, quit the run loop
+    callbackCalled = true;
+    CFRunLoopStop(CFRunLoopGetCurrent());
+       return 0;
+}
+
+int
+kc_21_item_use_callback(int argc, char *const *argv)
+{
+       plan_tests(14);
+
+    // Run the CFRunLoop to clear out existing notifications
+    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, false);
+
+       UInt32 didGetNotification = 0;
+       ok_status(SecKeychainAddCallback(callbackFunction, kSecAddEventMask,
+               &didGetNotification), "add callback");
+
+    SecKeychainRef keychain = createNewKeychain("test", "test");
+       SecKeychainItemRef itemRef;
+       ok_status(SecKeychainAddGenericPassword(keychain,
+               sizeof(account), account,
+               sizeof(service), service,
+               sizeof(password), password,
+               &itemRef),
+               "add generic password, release and wait for callback");
+
+    // Run the CFRunLoop to process events (and call our callback)
+    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10.0, false);
+    is(callbackCalled, true, "Keychain callback function was not called or did not finish");
+
+       CFRelease(itemRef);
+
+    ok_status(SecKeychainDelete(keychain), "%s: SecKeychainDelete", testName);
+       CFRelease(keychain);
+
+    deleteTestFiles();
+       return 0;
+}