]> git.saurik.com Git - apple/security.git/blob - KVSKeychainSyncingProxy/CKDAKSLockMonitor.m
Security-57740.51.3.tar.gz
[apple/security.git] / KVSKeychainSyncingProxy / CKDAKSLockMonitor.m
1 //
2 // CKDAKSLockMonitor.m
3 // Security
4 //
5 // Created by Mitch Adler on 11/2/16.
6 //
7 //
8
9 #import <Foundation/Foundation.h>
10
11 #import "CKDAKSLockMonitor.h"
12
13 #include <utilities/SecCFRelease.h>
14 #include <utilities/SecAKSWrappers.h>
15 #include <utilities/debugging.h>
16
17
18 @interface CKDAKSLockMonitor ()
19
20 @property XPCNotificationDispatcher* dispatcher;
21 @property XPCNotificationBlock notificationBlock;
22
23 @end
24
25 @implementation CKDAKSLockMonitor
26
27 + (instancetype) monitor {
28 return [[CKDAKSLockMonitor alloc] init];
29 }
30
31 - (instancetype)init {
32 self = [super init];
33
34 if (self) {
35 XPCNotificationDispatcher* dispatcher = [XPCNotificationDispatcher dispatcher];
36
37 [dispatcher addListener: self];
38
39 self->_locked = true;
40 self->_unlockedSinceBoot = false;
41
42 [self recheck];
43 }
44
45 return self;
46 }
47
48 - (void) handleNotification:(const char *)name {
49 if (strcmp(name, kUserKeybagStateChangeNotification) == 0) {
50 [self recheck];
51 }
52 }
53
54 - (void) notifyListener {
55 if (self.listener) {
56 if (self.locked) {
57 [self.listener locked];
58 } else {
59 [self.listener unlocked];
60 }
61 }
62 }
63
64 - (void)connectTo: (NSObject<CKDLockListener>*) listener {
65 self->_listener = listener;
66 [self notifyListener];
67 }
68
69 - (void) recheck {
70 CFErrorRef aksError = NULL;
71 bool locked = true; // Assume locked if we get an error
72
73 if (!SecAKSGetIsLocked(&locked, &aksError)) {
74 secerror("%@ Got error querying lock state: %@", self, aksError);
75 CFReleaseSafe(aksError);
76 }
77
78 BOOL previousLocked = self.locked;
79 self->_locked = locked;
80
81 if (!self.locked) {
82 self->_unlockedSinceBoot = true;
83 }
84
85 if (previousLocked != self.locked) {
86 // recheck might get called from ckdkvsproxy_queue (see 30510390)
87 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
88 [self notifyListener];
89 });
90 }
91 }
92
93 @end