X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b04fe171f0375ecd5d8a24747ca1dff85720a0ca..6b200bc335dc93c5516ccb52f14bd896d8c7fad7:/KVSKeychainSyncingProxy/CKDAKSLockMonitor.m diff --git a/KVSKeychainSyncingProxy/CKDAKSLockMonitor.m b/KVSKeychainSyncingProxy/CKDAKSLockMonitor.m new file mode 100644 index 00000000..328d96a4 --- /dev/null +++ b/KVSKeychainSyncingProxy/CKDAKSLockMonitor.m @@ -0,0 +1,93 @@ +// +// CKDAKSLockMonitor.m +// Security +// +// Created by Mitch Adler on 11/2/16. +// +// + +#import + +#import "CKDAKSLockMonitor.h" + +#include +#include +#include + + +@interface CKDAKSLockMonitor () + +@property XPCNotificationDispatcher* dispatcher; +@property XPCNotificationBlock notificationBlock; + +@end + +@implementation CKDAKSLockMonitor + ++ (instancetype) monitor { + return [[CKDAKSLockMonitor alloc] init]; +} + +- (instancetype)init { + self = [super init]; + + if (self) { + XPCNotificationDispatcher* dispatcher = [XPCNotificationDispatcher dispatcher]; + + [dispatcher addListener: self]; + + self->_locked = true; + self->_unlockedSinceBoot = false; + + [self recheck]; + } + + return self; +} + +- (void) handleNotification:(const char *)name { + if (strcmp(name, kUserKeybagStateChangeNotification) == 0) { + [self recheck]; + } +} + +- (void) notifyListener { + if (self.listener) { + if (self.locked) { + [self.listener locked]; + } else { + [self.listener unlocked]; + } + } +} + +- (void)connectTo: (NSObject*) listener { + self->_listener = listener; + [self notifyListener]; +} + +- (void) recheck { + CFErrorRef aksError = NULL; + bool locked = true; // Assume locked if we get an error + + if (!SecAKSGetIsLocked(&locked, &aksError)) { + secerror("%@ Got error querying lock state: %@", self, aksError); + CFReleaseSafe(aksError); + } + + BOOL previousLocked = self.locked; + self->_locked = locked; + + if (!self.locked) { + self->_unlockedSinceBoot = true; + } + + if (previousLocked != self.locked) { + // recheck might get called from ckdkvsproxy_queue (see 30510390) + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [self notifyListener]; + }); + } +} + +@end