]> git.saurik.com Git - apple/security.git/blob - Security/sec/SOSCircle/Regressions/sc-103-syncupdate.c
Security-57031.10.10.tar.gz
[apple/security.git] / Security / sec / SOSCircle / Regressions / sc-103-syncupdate.c
1 /*
2 * Copyright (c) 2012,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 // Run on 2 devices:
26 // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_103_syncupdate -v -- -i alice
27 // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_103_syncupdate -v -- -i bob
28 // Run on 2 devices:
29 // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_101_accountsync -v -- -i
30 // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_101_accountsync -v -- -i
31
32 #include <AssertMacros.h>
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <xpc/xpc.h>
38
39 #include <Security/SecBase.h>
40 #include <Security/SecItem.h>
41 #include <Security/SecItemPriv.h>
42
43 #include <CKBridge/SOSCloudKeychainClient.h>
44 #include <SecureObjectSync/SOSCloudCircle.h>
45
46 #include <notify.h>
47 #include <dispatch/dispatch.h>
48 #include <getopt.h>
49
50 #include <utilities/SecCFWrappers.h>
51 #include <utilities/debugging.h>
52 #include <utilities/SecCFRelease.h>
53
54 #include "SOSCircle_regressions.h"
55 #include "SOSRegressionUtilities.h"
56 #include <CKBridge/SOSCloudKeychainConstants.h>
57
58 #define xsecdebug(format...) secerror(format)
59
60 static dispatch_group_t sDispatchGroup = NULL;
61
62 __unused static const uint64_t putTestInterval = 10ull * NSEC_PER_SEC;
63 static const uint64_t leeway = 1ull * NSEC_PER_SEC;
64
65 __unused static const uint64_t syncInterval = 60ull * NSEC_PER_SEC; // seconds
66
67 __unused static const uint64_t putDelay = 10ull * NSEC_PER_SEC; // seconds; should probably be longer than syncedefaultsd latency (6 sec)
68
69 static const uint64_t exitDelay = 180ull * NSEC_PER_SEC; // seconds
70
71 static dispatch_queue_t requestqueue;
72
73 static dispatch_source_t exitTimerSource;
74
75 static uint64_t failCounter = 0;
76 static uint64_t putAttemptCounter = 0;
77 static uint64_t itemsChangedCount = 0;
78
79
80 // MARK: ----- Debug Routines -----
81
82 static void tearDown(void)
83 {
84 xsecdebug("exit");
85 CFRunLoopStop(CFRunLoopGetMain());
86 }
87
88 // MARK: ----- Get Cycle Tester -----
89
90 static void initCyclerTests(dispatch_group_t dgroup)
91 {
92 /*
93 We set up two timer sources:
94 - getRequestsource waits 5 seconds, then gets every 5 seconds
95 - exitTimerSource fires once after 300 seconds (5 minutes)
96 All are created suspended, so they don't start yet
97 */
98
99 uint64_t delay = exitDelay;
100 dispatch_time_t exitFireTime = dispatch_time(DISPATCH_TIME_NOW, delay);
101 exitTimerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, (uintptr_t)NULL, 0, requestqueue);
102 dispatch_source_set_timer(exitTimerSource, exitFireTime, 0ull, leeway);
103
104 dispatch_source_set_event_handler(exitTimerSource,
105 ^{
106 xsecdebug("Test Exit: %lld", failCounter);
107 printf("Test Exit: fail: %lld, total: %lld, changed: %lld\n", failCounter, putAttemptCounter, itemsChangedCount);
108 tearDown();
109 exit(0);
110 });
111 }
112
113 static void updateSyncingEnabledSwitch()
114 {
115 // Set the visual state of switch based on membership in circle
116 CFErrorRef error = NULL;
117 SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error);
118 // [_syncingEnabled setOn:(BOOL)(ccstatus == kSOSCCInCircle) animated:NO];
119 pass("ccstatus: %d, error: %@", ccstatus, error);
120 }
121
122 static void requestToJoinCircle()
123 {
124 // Set the visual state of switch based on membership in circle
125 bool bx;
126 CFErrorRef error = NULL;
127 SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error);
128 pass("ccstatus: %d, error: %@", ccstatus, error);
129 if (ccstatus == kSOSCCInCircle)
130 return;
131
132 if (ccstatus == kSOSCCNotInCircle)
133 {
134 pass("Not in circle, requesting admission");
135 bx = SOSCCRequestToJoinCircle(&error);
136 if (!bx)
137 pass("SOSCCRequestToJoinCircle error: %@", error);
138 }
139 else
140 if (ccstatus == kSOSCCRequestPending)
141 pass("Not in circle, admission pending");
142 }
143
144 static void handleEnableSyncing(bool turningOn)
145 {
146 dispatch_queue_t workq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
147 if (turningOn) // i.e. we are trying to turn on syncing
148 {
149 pass("Keychain syncing is being turned ON");
150 dispatch_async(workq, ^
151 {
152 CFErrorRef error = NULL;
153 bool bx = SOSCCResetToOffering(&error);
154 if (bx)
155 pass("ResetToOffering OK");
156 else
157 pass("ResetToOffering fail: %@", error);
158
159 requestToJoinCircle();
160 updateSyncingEnabledSwitch();
161 dispatch_group_leave(sDispatchGroup);
162 });
163 }
164 else
165 {
166 pass("Keychain syncing is being turned OFF");
167 CFErrorRef error = NULL;
168 bool bx = SOSCCRemoveThisDeviceFromCircle(&error);
169 updateSyncingEnabledSwitch();
170 if (!bx)
171 pass("SOSCCRemoveThisDeviceFromCircle fail: %@", error);
172 }
173 }
174
175 // MARK: ----- start of all tests -----
176
177 static void initialEstablish(void)
178 {
179 dispatch_group_enter(sDispatchGroup);
180 dispatch_group_notify(sDispatchGroup, requestqueue, ^
181 {
182 printf("Exiting via dispatch_group_notify; all work done\n");
183 CFRunLoopStop(CFRunLoopGetMain());
184 // exit(0);
185 });
186 handleEnableSyncing(true);
187
188 #if 0
189 CFErrorRef error = NULL;
190 bool bx = false;
191 SOSCCStatus sccStatus = SOSCCThisDeviceIsInCircle(&error);
192 if (sccStatus == kSOSCCNotInCircle)
193 bx = SOSCCResetToOffering(&error);
194 else
195 bx = SOSCCRequestToJoinCircle(&error);
196 if (!bx)
197 xsecdebug("circle establish error: %@", error);
198 ok(bx, "Circle established");
199 #endif
200 }
201
202 // MARK: ---------- Main ----------
203
204 // define the options table for the command line
205 static const struct option options[] =
206 {
207 { "verbose", optional_argument, NULL, 'v' },
208 { }
209 };
210
211 static int kTestCount = 22;
212
213 int sc_103_syncupdate(int argc, char *const *argv)
214 {
215 extern char *optarg;
216 int arg, argSlot;
217
218 while (argSlot = -1, (arg = getopt_long(argc, (char * const *)argv, "i:v", options, &argSlot)) != -1)
219 switch (arg)
220 {
221 default:
222 secerror("arg: %s", optarg);
223 break;
224 }
225
226 plan_tests(kTestCount);
227
228 SKIP:
229 {
230 skip("Skipping ckdclient tests because CloudKeychainProxy.xpc is not installed", kTestCount, XPCServiceInstalled());
231 sDispatchGroup = dispatch_group_create();
232 requestqueue = dispatch_queue_create("sc_103_syncupdate", DISPATCH_QUEUE_CONCURRENT);
233 initCyclerTests(sDispatchGroup);
234 initialEstablish();
235 }
236
237 dispatch_group_wait(sDispatchGroup, DISPATCH_TIME_FOREVER);
238 pass("Tests are running...");
239 printf("Tests are running...\n");
240 CFRunLoopRun(); // Wait for it...
241 pass("Exit from run loop");
242
243 return 0;
244 }
245
246
247