]> git.saurik.com Git - apple/security.git/blame - KVSKeychainSyncingProxy/CKDAKSLockMonitor.m
Security-58286.200.222.tar.gz
[apple/security.git] / KVSKeychainSyncingProxy / CKDAKSLockMonitor.m
CommitLineData
6b200bc3
A
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
866f8763 17#include <notify.h>
6b200bc3
A
18
19@interface CKDAKSLockMonitor ()
20
21@property XPCNotificationDispatcher* dispatcher;
22@property XPCNotificationBlock notificationBlock;
866f8763 23@property dispatch_queue_t queue;
6b200bc3
A
24
25@end
26
27@implementation CKDAKSLockMonitor
28
29+ (instancetype) monitor {
30 return [[CKDAKSLockMonitor alloc] init];
31}
32
33- (instancetype)init {
34 self = [super init];
35
36 if (self) {
37 XPCNotificationDispatcher* dispatcher = [XPCNotificationDispatcher dispatcher];
38
866f8763
A
39 _queue = dispatch_queue_create("CKDAKSLockMonitor", NULL);
40 _locked = true;
41 _unlockedSinceBoot = false;
6b200bc3 42
866f8763
A
43 /* also use dispatch to make sure */
44 int token = 0;
45 __weak typeof(self) weakSelf = self;
46 notify_register_dispatch(kUserKeybagStateChangeNotification, &token, _queue, ^(int t) {
47 [weakSelf _onqueueRecheck];
48 });
6b200bc3
A
49
50 [self recheck];
866f8763
A
51
52 [dispatcher addListener: self];
6b200bc3
A
53 }
54
55 return self;
56}
57
58- (void) handleNotification:(const char *)name {
866f8763 59 if (strcmp(name, kUserKeybagStateChangeNotification) == 0 || strcmp(name, "com.apple.mobile.keybagd.lock_status") == 0) {
6b200bc3
A
60 [self recheck];
61 }
62}
63
64- (void) notifyListener {
866f8763
A
65 // Take a strong reference:
66 __strong __typeof(self.listener) listener = self.listener;
67
68 if (listener) {
6b200bc3 69 if (self.locked) {
866f8763 70 [listener locked];
6b200bc3 71 } else {
866f8763 72 [listener unlocked];
6b200bc3
A
73 }
74 }
75}
76
77- (void)connectTo: (NSObject<CKDLockListener>*) listener {
866f8763 78 _listener = listener;
6b200bc3
A
79 [self notifyListener];
80}
81
82- (void) recheck {
866f8763
A
83 dispatch_async(_queue, ^{
84 [self _onqueueRecheck];
85 });
86}
87
88- (void) _onqueueRecheck {
6b200bc3
A
89 CFErrorRef aksError = NULL;
90 bool locked = true; // Assume locked if we get an error
91
92 if (!SecAKSGetIsLocked(&locked, &aksError)) {
93 secerror("%@ Got error querying lock state: %@", self, aksError);
94 CFReleaseSafe(aksError);
95 }
96
97 BOOL previousLocked = self.locked;
866f8763 98 _locked = locked;
6b200bc3
A
99
100 if (!self.locked) {
866f8763 101 _unlockedSinceBoot = true;
6b200bc3
A
102 }
103
104 if (previousLocked != self.locked) {
105 // recheck might get called from ckdkvsproxy_queue (see 30510390)
106 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
107 [self notifyListener];
108 });
109 }
110}
111
112@end