]> git.saurik.com Git - apple/security.git/blob - keychain/SecureObjectSync/SOSControlServer.m
Security-59754.80.3.tar.gz
[apple/security.git] / keychain / SecureObjectSync / SOSControlServer.m
1 #import <Foundation/Foundation.h>
2 #import <Foundation/NSXPCConnection_Private.h>
3 #import <Security/SecEntitlements.h>
4 #import <ipc/securityd_client.h>
5 #import "SOSAccount.h"
6 #import "SOSControlHelper.h"
7 #import "SOSControlServer.h"
8
9 @interface SOSControlServer : NSObject <NSXPCListenerDelegate>
10 @end
11
12 @interface SOSClient ()
13 @property (strong) SOSAccount * account;
14 - (instancetype)initSOSClientWithAccount:(SOSAccount *)account;
15 - (bool)checkEntitlement:(NSString *)entitlement;
16 @end
17
18 @interface SOSClientRemote : SOSClient
19 @property (weak) NSXPCConnection * connection;
20 - (instancetype)initSOSConnectionWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account;
21 @end
22
23 @implementation SOSControlServer
24
25 - (BOOL)listener:(__unused NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
26 {
27 NSNumber *num = [newConnection valueForEntitlement:(__bridge NSString *)kSecEntitlementKeychainCloudCircle];
28 if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) {
29 secerror("sos: Client pid: %d doesn't have entitlement: %@",
30 [newConnection processIdentifier], kSecEntitlementKeychainCloudCircle);
31 return NO;
32 }
33
34 SOSAccount *account = (__bridge SOSAccount *)SOSKeychainAccountGetSharedAccount();
35 if (account == nil) {
36 secerror("sos: SOS have not launched yet, come later, pid: %d",
37 [newConnection processIdentifier]);
38 return NO;
39 }
40
41 SOSClientRemote *sosClient = [[SOSClientRemote alloc] initSOSConnectionWithConnection:newConnection account:account];
42
43 newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)];
44 _SOSControlSetupInterface(newConnection.exportedInterface);
45 newConnection.exportedObject = sosClient;
46
47 [newConnection resume];
48
49 return YES;
50 }
51
52 - (SOSClient *)internalSOSClient
53 {
54 return [[SOSClient alloc] initSOSClientWithAccount:(__bridge SOSAccount *)SOSKeychainAccountGetSharedAccount()];
55 }
56
57 @end
58
59 @implementation SOSClient
60
61 @synthesize account = _account;
62
63 - (instancetype)initSOSClientWithAccount:(SOSAccount *)account
64 {
65 if ((self = [super init])) {
66 _account = account;
67 }
68 return self;
69 }
70
71 - (bool)checkEntitlement:(NSString *)entitlement
72 {
73 return true;
74 }
75
76 - (void)userPublicKey:(void ((^))(BOOL trusted, NSData *spki, NSError *error))reply
77 {
78 [self.account userPublicKey:reply];
79 }
80
81 - (void)kvsPerformanceCounters:(void(^)(NSDictionary <NSString *, NSNumber *> *))reply
82 {
83 [self.account kvsPerformanceCounters:reply];
84 }
85
86 - (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary <NSString *, NSString *> *))reply
87 {
88 [self.account rateLimitingPerformanceCounters:reply];
89 }
90
91 - (void)stashedCredentialPublicKey:(void(^)(NSData *, NSError *error))reply
92 {
93 [self.account stashedCredentialPublicKey:reply];
94 }
95
96 - (void)assertStashedAccountCredential:(void(^)(BOOL result, NSError *error))reply
97 {
98 [self.account assertStashedAccountCredential:reply];
99 }
100
101 - (void)validatedStashedAccountCredential:(void(^)(NSData *credential, NSError *error))complete
102 {
103 [self.account validatedStashedAccountCredential:complete];
104 }
105
106 - (void)stashAccountCredential:(NSData *)credential complete:(void(^)(bool success, NSError *error))complete
107 {
108 [self.account stashAccountCredential:credential complete:complete];
109 }
110
111 - (void)myPeerInfo:(void (^)(NSData *, NSError *))complete
112 {
113 [self.account myPeerInfo:complete];
114 }
115
116 - (void)circleHash:(void (^)(NSString *, NSError *))complete
117 {
118 [self.account circleHash:complete];
119 }
120
121
122 - (void)circleJoiningBlob:(NSData *)applicant complete:(void (^)(NSData *blob, NSError *))complete
123 {
124 [self.account circleJoiningBlob:applicant complete:complete];
125 }
126
127 - (void)joinCircleWithBlob:(NSData *)blob version:(PiggyBackProtocolVersion)version complete:(void (^)(bool success, NSError *))complete
128 {
129 [self.account joinCircleWithBlob:blob version:version complete:complete];
130 }
131
132 - (void)initialSyncCredentials:(uint32_t)flags complete:(void (^)(NSArray *, NSError *))complete
133 {
134 if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainInitialSync]) {
135 complete(@[], [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]);
136 return;
137 }
138
139 [self.account initialSyncCredentials:flags complete:complete];
140 }
141
142 - (void)importInitialSyncCredentials:(NSArray *)items complete:(void (^)(bool success, NSError *))complete
143 {
144 if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainInitialSync]) {
145 complete(false, [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]);
146 return;
147 }
148
149 [self.account importInitialSyncCredentials:items complete:complete];
150 }
151
152 - (void)rpcTriggerSync:(NSArray <NSString *> *)peers complete:(void(^)(bool success, NSError *))complete
153 {
154 [self.account rpcTriggerSync:peers complete:complete];
155 }
156
157 - (void)getWatchdogParameters:(void (^)(NSDictionary* parameters, NSError* error))complete
158 {
159 [self.account getWatchdogParameters:complete];
160 }
161
162 - (void)setWatchdogParmeters:(NSDictionary*)parameters complete:(void (^)(NSError* error))complete
163 {
164 [self.account setWatchdogParmeters:parameters complete:complete];
165 }
166
167 - (void) ghostBust:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool ghostBusted, NSError *error))complete {
168 [self.account ghostBust:options complete:complete];
169 }
170
171 - (void)ghostBustTriggerTimed:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool ghostBusted, NSError *error))complete {
172 [self.account ghostBustTriggerTimed:options complete:complete];
173 }
174
175 - (void) ghostBustPeriodic:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool busted, NSError *error))complete {
176 [self.account ghostBustPeriodic:options complete:complete];
177 }
178
179 - (void) ghostBustInfo: (void(^)(NSData *json, NSError *error))complete {
180 [self.account ghostBustInfo:complete];
181 }
182
183 - (void)iCloudIdentityStatus: (void (^)(NSData *json, NSError *error))complete {
184 [self.account iCloudIdentityStatus: complete];
185 }
186
187 - (void)rpcTriggerBackup:(NSArray<NSString *>* _Nullable)backupPeers complete:(void (^)(NSError *error))complete
188 {
189 [self.account rpcTriggerBackup:backupPeers complete:complete];
190 }
191
192 - (void)rpcTriggerRingUpdate:(void (^)(NSError *))complete {
193 [self.account rpcTriggerRingUpdate:complete];
194 }
195
196 - (void)iCloudIdentityStatus_internal:(void (^)(NSDictionary *, NSError *))complete {
197 [self.account iCloudIdentityStatus_internal:complete];
198 }
199
200
201 @end
202
203 @implementation SOSClientRemote
204
205 - (instancetype)initSOSConnectionWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account
206 {
207 if ((self = [super initSOSClientWithAccount:account])) {
208 self.connection = connection;
209 }
210 return self;
211 }
212
213 - (bool)checkEntitlement:(NSString *)entitlement
214 {
215 NSXPCConnection *strongConnection = _connection;
216
217 NSNumber *num = [strongConnection valueForEntitlement:entitlement];
218 if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) {
219 secerror("sos: Client pid: %d doesn't have entitlement: %@",
220 [strongConnection processIdentifier], entitlement);
221 return false;
222 }
223 return true;
224 }
225 @end
226
227 static SOSControlServer *sosServer;
228
229 void
230 SOSControlServerInitialize(void)
231 {
232 static dispatch_once_t once;
233 static NSXPCListener *listener;
234
235 dispatch_once(&once, ^{
236 @autoreleasepool {
237 sosServer = [SOSControlServer new];
238
239 listener = [[NSXPCListener alloc] initWithMachServiceName:@(kSecuritydSOSServiceName)];
240 listener.delegate = sosServer;
241 [listener resume];
242 }
243 });
244 }
245
246 SOSClient *
247 SOSControlServerInternalClient(void)
248 {
249 SOSControlServerInitialize();
250 return [sosServer internalSOSClient];
251 }