]> git.saurik.com Git - apple/security.git/blob - MultiDeviceSimulator/ClientInfoByNotification/ClientInfoByNotification.m
Security-58286.270.3.0.1.tar.gz
[apple/security.git] / MultiDeviceSimulator / ClientInfoByNotification / ClientInfoByNotification.m
1 //
2 // ClientInfoByNotification.m
3 // Security
4 //
5 // Created by murf on 4/12/18.
6 //
7
8 #import <XCTest/XCTest.h>
9 #import <Foundation/Foundation.h>
10 #import <Foundation/NSXPCConnection_Private.h>
11 #import <Security/Security.h>
12 #include <Security/SecureObjectSync/SOSCloudCircle.h>
13 #include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
14
15 #undef DOVIEWMACRO
16 #define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULTSETTING, INITIALSYNCSETTING, ALWAYSONSETTING, BACKUPSETTING, V0SETTING) \
17 const CFStringRef k##SYSTEM##View##VIEWNAME = CFSTR(DEFSTRING);
18 #include "Security/SecureObjectSync/ViewList.list"
19
20 #import "DeviceSimulatorProtocol.h"
21 #import "MultiDeviceNetworking.h"
22 #import <objc/runtime.h>
23
24
25 #if 1
26 @interface MDDevice2 : NSObject<DeviceSimulatorProtocol>
27 @property NSXPCConnection *connection;
28 @property NSString *name;
29 - (instancetype)initWithConnection:(NSXPCConnection *)connection;
30 @end
31
32 #pragma clang diagnostic push
33 #pragma clang diagnostic ignored "-Wprotocol"
34 @implementation MDDevice2
35
36 - (instancetype)initWithConnection:(NSXPCConnection *)connection
37 {
38 self = [super init];
39 if (self) {
40 self.connection = connection;
41 }
42 return self;
43 }
44
45 /* Oh, ObjC, you are my friend */
46 - (void)forwardInvocation:(NSInvocation *)invocation
47 {
48 struct objc_method_description desc = protocol_getMethodDescription(@protocol(DeviceSimulatorProtocol), [invocation selector], true, true);
49 if (desc.name == NULL) {
50 [super forwardInvocation:invocation];
51 } else {
52 __block bool dooooooEeeeetExclamationPoint = true;
53 id object = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
54 NSLog(@"peer failed with: %@", error);
55 dooooooEeeeetExclamationPoint = false;
56 //abort();
57 }];
58 if(dooooooEeeeetExclamationPoint) {
59 [invocation invokeWithTarget:object];
60 }
61 }
62 }
63 @end
64 #pragma clang diagnostic pop
65 #endif
66
67 @interface ClientInfoByNotification : XCTestCase
68 @property NSMutableDictionary<NSString *,MDDevice2 *> *connections;
69 @property MultiDeviceNetworking *network;
70 @property MDDevice2 *masterDevice;
71 @end
72
73 static NSString *testInstanceUUID;
74
75 @implementation ClientInfoByNotification
76
77
78 + (void)setUp
79 {
80 testInstanceUUID = [[NSUUID UUID] UUIDString];
81 }
82
83 - (void)setUp
84 {
85 self.connections = [NSMutableDictionary dictionary];
86 self.network = [[MultiDeviceNetworking alloc] init];
87 [self runSigninWithAdditionalDevices:0];
88 }
89
90 - (void)tearDown
91 {
92 __block uint64_t totalUserUsec = 0, totalSysUsec = 0;
93 NSMutableDictionary *result = [NSMutableDictionary dictionary];
94
95 for (NSString *name in self.connections) {
96 MDDevice2 *device = self.connections[name];
97 NSLog(@"device: %@", name);
98 [device diagnosticsCPUUsage:^(bool success, uint64_t user_usec, uint64_t sys_usec, NSError *error) {
99 NSLog(@"%@: %d: u:%llu s:%llu", device.name, success, (unsigned long long)user_usec, (unsigned long long)sys_usec);
100 totalUserUsec += user_usec;
101 totalSysUsec += sys_usec;
102 result[[NSString stringWithFormat:@"cpu-%@", name]] = @{ @"user_usec" : @(user_usec), @"system_usec" : @(sys_usec)};
103 }];
104 }
105
106 result[@"cpu-total"] = @{ @"user_usec" : @(totalUserUsec), @"system_usec" : @(totalSysUsec)};
107
108 NSLog(@"Total: u:%llu s:%llu", (unsigned long long)totalUserUsec, (unsigned long long)totalSysUsec);
109
110 /* XXX check for leaks in all devices */
111 for (NSString *name in self.connections) {
112 MDDevice2 *device = self.connections[name];
113 [device.connection invalidate];
114 }
115 self.connections = NULL;
116 [self.network dumpKVSState];
117 [self.network dumpCounters];
118 [self.network disconnectAll];
119 self.network = NULL;
120
121 NSData * jsonData = [NSJSONSerialization dataWithJSONObject:result options:0 error:NULL];
122
123 [jsonData writeToFile:[NSString stringWithFormat:@"/tmp/test-result-%@", [self name]] atomically:NO];
124
125 }
126
127 //MARK: - Device logic
128
129 - (MDDevice2 *)device:(NSString *)name model:(NSString *)model version:(NSString *)version
130 {
131 MDDevice2 *device = self.connections[name];
132 if (device != NULL) {
133 return NULL;
134 }
135
136 NSXPCConnection *conn = [[NSXPCConnection alloc] initWithServiceName:@"com.apple.Security.DeviceSimulator"];
137 conn.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(DeviceSimulatorProtocol)];
138 [conn _setUUID:[NSUUID UUID]]; // select a random instance
139 [conn resume];
140
141 device = [[MDDevice2 alloc] initWithConnection:conn];
142 device.name = name;
143
144 self.connections[name] = device;
145
146 [device setDevice:name
147 version:version
148 model:model
149 testInstance:testInstanceUUID
150 network:[self.network endpoint]
151 complete:^(BOOL success) {
152 if (!success) {
153 abort();
154 }
155 }];
156 return device;
157 }
158
159 - (void)runSigninWithAdditionalDevices:(unsigned)additionalDeviceCount {
160 signal(SIGPIPE, SIG_IGN);
161 _masterDevice = [self device:@"ipad" model:@"iPad" version:@"15E143a"];
162 NSMutableArray<MDDevice2 *> *otherDevices = [NSMutableArray array];
163
164 [_masterDevice setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) {
165 XCTAssert(success, "Expect success: %@", error);
166 }];
167
168 [_masterDevice sosCircleStatus:^void(SOSCCStatus status, NSError *error) {
169 XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error);
170 }];
171
172 sleep(4); // give "kvs" a chance to get the word out.
173 for (unsigned n = 0; n < additionalDeviceCount; n++) {
174 MDDevice2 *dev = [self device:[NSString stringWithFormat:@"mac-%u", n] model:@"Mac Pro" version:@"17E121"];
175
176 [dev setupSOSCircle:@"user" password:@"foo" complete:^void(bool success, NSError *error) {
177 XCTAssert(success, "%u: Expect success: %@", n, error);
178 }];
179
180 __block NSString *devPeerID = NULL;
181 [dev sosRequestToJoin:^(bool success, NSString *peerID, NSError *error) {
182 XCTAssert(success, "%u: Expect success: %@", n, error);
183 XCTAssertNotEqual(peerID, NULL, @"%u: expected to find peerID for peer2", n);
184 devPeerID = peerID;
185 }];
186
187 __block NSError *localErr = nil;
188 __block bool done = false;
189 for(int tries=0; tries < 5; tries++) {
190
191 [_masterDevice sosApprovePeer:devPeerID complete:^(BOOL success, NSError *error) {
192 localErr = [error copy];
193 if(success) {
194 localErr = nil;
195 done = true;
196 }
197 }];
198 if(done) break;
199 sleep(10);
200 }
201 XCTAssert(done, "%u: Expect success (for approve of %@): %@", n, devPeerID, localErr);
202
203 [otherDevices addObject:dev];
204 }
205 }
206
207 - (void)testSOSIsThisDeviceInCircle
208 {
209 [self measureBlock:^{
210 for(int i=0; i<100; i++) {
211 [self.masterDevice sosCircleStatus:^void(SOSCCStatus status, NSError *error) {
212 XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error);
213 }];
214 }
215 }];
216 }
217
218 - (void)testSOSIsThisDeviceInCircleNonCached
219 {
220 [self measureBlock:^{
221 for(int i=0; i<100; i++) {
222 [self.masterDevice sosCircleStatusNonCached:^void(SOSCCStatus status, NSError *error) {
223 XCTAssertEqual(status, kSOSCCInCircle, @"expected to be in circle: %@", error);
224 }];
225 }
226 }];
227 }
228
229
230 #if TARGET_OS_IPHONE
231 - (void)testSOSViews2
232 {
233 [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewAutofillPasswords withCompletion: ^void(SOSCCStatus status, NSError *error) {
234 XCTAssertEqual(status, kSOSCCViewNotMember, @"expected to be not in view: %@", error);
235 }];
236 [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewHomeKit withCompletion: ^void(SOSCCStatus status, NSError *error) {
237 XCTAssertEqual(status, kSOSCCViewMember, @"expected to be in view: %@", error);
238 }];
239 [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewWiFi withCompletion: ^void(SOSCCStatus status, NSError *error) {
240 XCTAssertEqual(status, kSOSCCViewNotMember, @"expected to be not in view: %@", error);
241 }];
242 [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewContinuityUnlock withCompletion: ^void(SOSCCStatus status, NSError *error) {
243 XCTAssertEqual(status, kSOSCCViewMember, @"expected to be in view: %@", error);
244 }];
245
246 [self.masterDevice sosEnableAllViews:^(BOOL success, NSError *error) {
247 XCTAssert(success, "Expected to enable all views");
248 }];
249
250 //uint64_t bitmask = [self.masterDevice sosCachedCircleBitmask];
251 //XCTAssertEqual(bitmask, 0, "Expected bitmask to be %llx", bitmask);
252
253
254 [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewWiFi withCompletion: ^void(SOSCCStatus status, NSError *error) {
255 XCTAssertEqual(status, kSOSCCViewMember, @"expected to be in view: %@", error);
256 }];
257
258 [self.masterDevice sosCachedViewBitmask:^(uint64_t bitmask) {
259 XCTAssertEqual(bitmask, 33554367, @"expected bitmask of %llx", bitmask);
260 }];
261
262 [self measureBlock:^{
263 for(int i=0; i<100; i++) {
264 [self.masterDevice sosViewStatus: (__bridge NSString*)kSOSViewHomeKit withCompletion: ^void(SOSCCStatus status, NSError *error) {
265 }];
266 }
267 }];
268 }
269 #endif
270
271
272 - (void)testSOSMultiView
273 {
274 [self.masterDevice sosEnableAllViews:^(BOOL success, NSError *error) {
275 XCTAssert(success, "Expected to enable all views");
276 }];
277
278 [self.masterDevice sosICKStatus: ^void(bool status) {
279 XCTAssert(status, "Expected to enable iCloud Keychain");
280 }];
281
282 [self measureBlock:^{
283 for(int i=0; i<100; i++) {
284 [self.masterDevice sosICKStatus: ^void(bool status) {
285 }];
286 }
287 }];
288 }
289
290 - (void) testMaster2
291 {
292 [self testSOSMultiView];
293 }
294
295 @end