]> git.saurik.com Git - apple/security.git/blob - MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.m
Security-58286.270.3.0.1.tar.gz
[apple/security.git] / MultiDeviceSimulator / DeviceSimulator / DeviceSimulator.m
1 //
2 // DeviceSimulator.m
3 // DeviceSimulator
4 //
5
6 #import <Foundation/Foundation.h>
7 #import <Foundation/NSXPCConnection_Private.h>
8 #import <securityd/SOSCloudCircleServer.h>
9 #import <Security/SecureObjectSync/SOSPeerInfo.h>
10 #import <Security/SecureObjectSync/SOSCloudCircleInternal.h>
11 #import <Security/SecureObjectSync/SOSViews.h>
12 #import <Security/SecureObjectSync/SOSInternal.h>
13
14 #import <stdlib.h>
15 #import <unistd.h>
16 #import <libproc.h>
17
18 #import "keychain/ckks/CKKS.h"
19 #import "SOSCloudKeychainClient.h"
20
21 #import "DeviceSimulatorProtocol.h"
22 #import "DeviceSimulator.h"
23
24
25 @implementation DeviceSimulator
26
27 - (void)setDevice:(NSString *)name
28 version:(NSString *)version
29 model:(NSString *)model
30 testInstance:(NSString *)testUUID
31 network:(NSXPCListenerEndpoint *)network
32 complete:(void(^)(BOOL success))complete
33 {
34 self.name = name;
35
36 SecCKKSDisable(); // for now
37 SecCKKSContainerName = [NSString stringWithFormat:@"com.apple.test.p01.B.%@.com.apple.security.keychain", testUUID];
38
39 SOSCCSetGestalt_Server((__bridge CFStringRef)name, (__bridge CFStringRef)version,
40 (__bridge CFStringRef)model, (__bridge CFStringRef)deviceInstance);
41
42 boot_securityd(network);
43
44 complete(TRUE);
45 }
46
47
48 - (void)secItemAdd:(NSDictionary *)input complete:(void (^)(OSStatus, NSDictionary *))reply
49 {
50 NSMutableDictionary *attributes = [input mutableCopy];
51 CFTypeRef data = NULL;
52
53 attributes[(__bridge NSString *)kSecReturnAttributes] = @YES;
54 attributes[(__bridge NSString *)kSecReturnPersistentRef] = @YES;
55 attributes[(__bridge NSString *)kSecReturnData] = @YES;
56
57 OSStatus status = SecItemAdd((__bridge CFDictionaryRef)attributes, &data);
58 NSDictionary *returnData = CFBridgingRelease(data);
59
60 reply(status, returnData);
61 }
62
63 - (void)secItemCopyMatching:(NSDictionary *)input complete:(void (^)(OSStatus, NSArray<NSDictionary *>*))reply
64 {
65 NSMutableDictionary *attributes = [input mutableCopy];
66 CFTypeRef data = NULL;
67
68 attributes[(__bridge NSString *)kSecReturnAttributes] = @YES;
69 attributes[(__bridge NSString *)kSecReturnData] = @YES;
70 attributes[(__bridge NSString *)kSecReturnPersistentRef] = @YES;
71 attributes[(__bridge NSString *)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll;
72
73 OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)attributes, &data);
74 NSArray<NSDictionary *>* array = CFBridgingRelease(data);
75 NSMutableArray *result = [NSMutableArray array];
76 for (NSDictionary *d in array) {
77 NSMutableDictionary *r = [d mutableCopy];
78 r[@"accc"] = nil;
79 [result addObject:r];
80 }
81
82 reply(status, result);
83 }
84
85 - (void)setupSOSCircle:(NSString *)username password:(NSString *)password complete:(void (^)(bool success, NSError *error))complete
86 {
87 CFErrorRef cferror = NULL;
88 bool result = SOSCCSetUserCredentialsAndDSID((__bridge CFStringRef)username,
89 (__bridge CFDataRef)[password dataUsingEncoding:NSUTF8StringEncoding],
90 CFSTR("1"), &cferror);
91 if (result) {
92 SOSCCStatus circleStat = SOSCCThisDeviceIsInCircle(&cferror);
93 if (circleStat == kSOSCCCircleAbsent) {
94 result = SOSCCResetToOffering(&cferror);
95 }
96 }
97 complete(result, (__bridge NSError *)cferror);
98 CFReleaseNull(cferror);
99 }
100
101 - (void)sosCircleStatus:(void(^)(SOSCCStatus status, NSError *error))complete
102 {
103 SOSCloudKeychainFlush(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef __unused returnedValues, CFErrorRef __unused sync_error) {
104 CFErrorRef cferror = NULL;
105 SOSCCStatus status = SOSCCThisDeviceIsInCircle(&cferror);
106 complete(status, (__bridge NSError *)cferror);
107 CFReleaseNull(cferror);
108 });
109 }
110
111 - (void)sosCircleStatusNonCached:(void(^)(SOSCCStatus status, NSError *error))complete
112 {
113 SOSCloudKeychainFlush(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef __unused returnedValues, CFErrorRef __unused sync_error) {
114 CFErrorRef cferror = NULL;
115 SOSCCStatus status = SOSCCThisDeviceIsInCircleNonCached(&cferror);
116 complete(status, (__bridge NSError *)cferror);
117 CFReleaseNull(cferror);
118 });
119 }
120
121
122 - (void)sosViewStatus:(NSString *) viewName withCompletion: (void(^)(SOSViewResultCode status, NSError *error))complete
123 {
124 CFErrorRef cferror = NULL;
125 SOSViewResultCode status = SOSCCView((__bridge CFStringRef)(viewName), kSOSCCViewQuery, &cferror);
126 complete(status, (__bridge NSError *)cferror);
127 CFReleaseNull(cferror);
128 }
129
130
131 - (void)sosICKStatus: (void(^)(bool status))complete
132 {
133 CFErrorRef cferror = NULL;
134 bool status = SOSCCIsIcloudKeychainSyncing();
135 complete(status);
136 CFReleaseNull(cferror);
137 }
138
139 - (void)sosPeerID:(void (^)(NSString *))complete
140 {
141 CFErrorRef cferror = NULL;
142 CFStringRef peerID = NULL;
143 SOSPeerInfoRef peerInfo = SOSCCCopyMyPeerInfo(&cferror);
144 if (peerInfo)
145 peerID = SOSPeerInfoGetPeerID(peerInfo);
146
147 complete((__bridge NSString *)peerID);
148 CFReleaseNull(peerInfo);
149 }
150
151 - (void)sosRequestToJoin:(void(^)(bool success, NSString *peerID, NSError *error))complete
152 {
153 CFErrorRef cferror = NULL;
154
155 os_log(NULL, "[%@] sosRequestToJoin", self.name);
156
157 SOSCCStatus status = SOSCCThisDeviceIsInCircle(&cferror);
158 if (status == kSOSCCCircleAbsent) {
159 cferror = CFErrorCreate(NULL, CFSTR("MDCircleAbsent"), 1, NULL);
160 complete(false, NULL, (__bridge NSError *)cferror);
161 CFReleaseNull(cferror);
162 } else if (status == kSOSCCNotInCircle) {
163 CFReleaseNull(cferror);
164 NSString *peerID = NULL;
165 bool result = SOSCCRequestToJoinCircle(&cferror);
166 if (result) {
167 SOSPeerInfoRef peerInfo = SOSCCCopyMyPeerInfo(&cferror);
168 if (peerInfo) {
169 peerID = (__bridge NSString *)SOSPeerInfoGetPeerID(peerInfo);
170 }
171 CFReleaseNull(peerInfo);
172 CFReleaseNull(cferror);
173 }
174 complete(result, peerID, (__bridge NSError *)cferror);
175 CFReleaseNull(cferror);
176 } else {
177 if(!cferror) {
178 cferror = CFErrorCreate(NULL, CFSTR("MDGeneralJoinError"), 1, NULL);
179 }
180 complete(false, NULL, (__bridge NSError *)cferror);
181 CFReleaseNull(cferror);
182 }
183 }
184
185 - (void)sosLeaveCircle: (void(^)(bool success, NSError *error))complete {
186 CFErrorRef cferror = NULL;
187 bool retval = false;
188
189 os_log(NULL, "[%@] sosLeaveCircle", self.name);
190
191 SOSCCStatus status = SOSCCThisDeviceIsInCircle(&cferror);
192 if(status == kSOSCCInCircle || status == kSOSCCRequestPending) {
193 retval = SOSCCRemoveThisDeviceFromCircle(&cferror);
194 }
195 complete(retval, (__bridge NSError *) cferror);
196 CFReleaseNull(cferror);
197 }
198
199
200 - (void)sosApprovePeer:(NSString *)peerID complete:(void(^)(BOOL success, NSError *error))complete
201 {
202 CFErrorRef cferror = NULL;
203 os_log(NULL, "[%@] sosApprovePeer: %@", self.name, peerID);
204 NSArray *applicants = CFBridgingRelease(SOSCCCopyApplicantPeerInfo(&cferror));
205 if ([applicants count] == 0) {
206 CFReleaseNull(cferror);
207 cferror = CFErrorCreate(NULL, CFSTR("MDNoApplicant"), 1, NULL);
208 complete(false, (__bridge NSError *)cferror);
209 CFReleaseNull(cferror);
210 return;
211 }
212 NSMutableArray *approvedApplicants = [NSMutableArray array];
213 for (id peer in applicants) {
214 SOSPeerInfoRef peerInfo = (__bridge SOSPeerInfoRef)peer;
215 NSString *applicantPeerID = (__bridge NSString *)SOSPeerInfoGetPeerID(peerInfo);
216 if (peerID == NULL || [peerID isEqualToString:applicantPeerID]){
217 [approvedApplicants addObject:(__bridge id)peerInfo];
218 }
219 }
220 bool result = false;
221 if ([approvedApplicants count]) {
222 result = SOSCCAcceptApplicants((__bridge CFArrayRef)approvedApplicants, &cferror);
223 } else {
224 cferror = CFErrorCreate(NULL, CFSTR("MDNoApplicant"), 1, NULL);
225 }
226 complete(result, (__bridge NSError *)cferror);
227 CFReleaseNull(cferror);
228 }
229
230 - (void)sosWaitForInitialSync:(void(^)(bool success, NSError *error))complete
231 {
232 CFErrorRef cferror = NULL;
233 bool success = SOSCCWaitForInitialSync(&cferror);
234 complete(success, (__bridge NSError *)cferror);
235 CFReleaseNull(cferror);
236 }
237
238 - (void)sosEnableAllViews:(void(^)(BOOL success, NSError *error))complete
239 {
240 CFMutableSetRef viewsToEnable = SOSViewCopyViewSet(kViewSetAll);
241 CFMutableSetRef viewsToDisable = CFSetCreateMutable(NULL, 0, NULL);
242
243 bool success = SOSCCViewSet(viewsToEnable, viewsToDisable);
244 CFRelease(viewsToEnable);
245 CFRelease(viewsToDisable);
246 complete(success, NULL);
247
248 }
249
250 - (void) sosCachedViewBitmask: (void(^)(uint64_t bitmask))complete {
251 uint64_t result = SOSCachedViewBitmask();
252 complete(result);
253 }
254
255
256
257 //PRAGMA mark: - Diagnostics
258
259 - (void)diagnosticsLeaks:(void(^)(bool success, NSString *outout, NSError *error))complete
260 {
261 complete(true, NULL, NULL);
262 }
263
264 - (void)diagnosticsCPUUsage:(void(^)(bool success, uint64_t user_usec, uint64_t sys_usec, NSError *error))complete
265 {
266 struct rusage usage;
267 getrusage(RUSAGE_SELF, &usage);
268 uint64_t user_usec = usage.ru_utime.tv_sec * USEC_PER_SEC + usage.ru_utime.tv_usec;
269 uint64_t sys_usec = usage.ru_stime.tv_sec * USEC_PER_SEC + usage.ru_stime.tv_usec;
270
271 complete(true, user_usec, sys_usec, NULL);
272 }
273
274 - (void)diagnosticsDiskUsage:(void(^)(bool success, uint64_t usage, NSError *error))complete
275 {
276 rusage_info_current rusage;
277
278 if (proc_pid_rusage(getpid(), RUSAGE_INFO_CURRENT, (rusage_info_t *)&rusage) == 0) {
279 complete(true, rusage.ri_logical_writes, NULL);
280 } else {
281 complete(false, 0, NULL);
282 }
283 }
284
285 @end