-#include <CoreFoundation/CoreFoundation.h>
-#include <CoreFoundation/CFRunLoop.h>
-#include <dispatch/dispatch.h>
-#include <AssertMacros.h>
-#include <pthread.h>
-
-/*
- * MARK: CFRunloop
- */
-
-static OSStatus SecLegacySourceChanged(__unused SecKeychainEvent keychainEvent, __unused SecKeychainCallbackInfo *info, __unused void *context) {
- // Purge keychain parent cache
- SecItemParentCachePurge();
- // Purge unrestricted roots cache
- SecTrustSettingsPurgeUserAdminCertsCache();
- return 0;
-}
-
-static void *SecTrustOSXCFRunloop(__unused void *unused) {
- CFRunLoopTimerRef timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, (CFTimeInterval) UINT_MAX, 0, 0, 0, ^(__unused CFRunLoopTimerRef _timer) {
- /* do nothing */
- });
-
- /* add a timer to force the runloop to stay running */
- CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
- /* add keychain callback before we initiate a runloop to avoid it exiting due to no sources */
-
- SecKeychainEventMask trustdMask = (kSecAddEventMask | kSecDeleteEventMask | kSecUpdateEventMask |
- kSecDefaultChangedEventMask | kSecKeychainListChangedMask |
- kSecTrustSettingsChangedEventMask);
- SecKeychainAddCallback(SecLegacySourceChanged, trustdMask, NULL);
-
- try {
- CFRunLoopRun();
- }
- catch (...) {
- /* An exception was rethrown from the runloop. Since we can't reliably
- * obtain info about changes to keychains or trust settings anymore,
- * just exit and respawn the process when needed. */
-
- secerror("Exception occurred in CFRunLoopRun; exiting");
- exit(0);
- }
- CFRelease(timer);
- return NULL;
-}
-
-void SecTrustLegacySourcesEventRunloopCreate(void) {
- /* A runloop is currently necessary to receive notifications about changes in the
- * legacy keychains and trust settings. */
- static dispatch_once_t once;
-
- dispatch_once(&once, ^{
- pthread_attr_t attrs;
- pthread_t thread;