2 * Copyright (c) 2012,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_103_syncupdate -v -- -i alice
27 // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_103_syncupdate -v -- -i bob
29 // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_101_accountsync -v -- -i
30 // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_101_accountsync -v -- -i
32 #include <AssertMacros.h>
39 #include <Security/SecBase.h>
40 #include <Security/SecItem.h>
41 #include <Security/SecItemPriv.h>
43 #include <CKBridge/SOSCloudKeychainClient.h>
44 #include <SecureObjectSync/SOSCloudCircle.h>
47 #include <dispatch/dispatch.h>
50 #include <utilities/SecCFWrappers.h>
51 #include <utilities/debugging.h>
52 #include <utilities/SecCFRelease.h>
54 #include "SOSCircle_regressions.h"
55 #include "SOSRegressionUtilities.h"
56 #include <CKBridge/SOSCloudKeychainConstants.h>
58 #define xsecdebug(format...) secerror(format)
60 static dispatch_group_t sDispatchGroup
= NULL
;
62 __unused
static const uint64_t putTestInterval
= 10ull * NSEC_PER_SEC
;
63 static const uint64_t leeway
= 1ull * NSEC_PER_SEC
;
65 __unused
static const uint64_t syncInterval
= 60ull * NSEC_PER_SEC
; // seconds
67 __unused
static const uint64_t putDelay
= 10ull * NSEC_PER_SEC
; // seconds; should probably be longer than syncedefaultsd latency (6 sec)
69 static const uint64_t exitDelay
= 180ull * NSEC_PER_SEC
; // seconds
71 static dispatch_queue_t requestqueue
;
73 static dispatch_source_t exitTimerSource
;
75 static uint64_t failCounter
= 0;
76 static uint64_t putAttemptCounter
= 0;
77 static uint64_t itemsChangedCount
= 0;
80 // MARK: ----- Debug Routines -----
82 static void tearDown(void)
85 CFRunLoopStop(CFRunLoopGetMain());
88 // MARK: ----- Get Cycle Tester -----
90 static void initCyclerTests(dispatch_group_t dgroup
)
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
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
);
104 dispatch_source_set_event_handler(exitTimerSource
,
106 xsecdebug("Test Exit: %lld", failCounter
);
107 printf("Test Exit: fail: %lld, total: %lld, changed: %lld\n", failCounter
, putAttemptCounter
, itemsChangedCount
);
113 static void updateSyncingEnabledSwitch()
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
);
122 static void requestToJoinCircle()
124 // Set the visual state of switch based on membership in circle
126 CFErrorRef error
= NULL
;
127 SOSCCStatus ccstatus
= SOSCCThisDeviceIsInCircle(&error
);
128 pass("ccstatus: %d, error: %@", ccstatus
, error
);
129 if (ccstatus
== kSOSCCInCircle
)
132 if (ccstatus
== kSOSCCNotInCircle
)
134 pass("Not in circle, requesting admission");
135 bx
= SOSCCRequestToJoinCircle(&error
);
137 pass("SOSCCRequestToJoinCircle error: %@", error
);
140 if (ccstatus
== kSOSCCRequestPending
)
141 pass("Not in circle, admission pending");
144 static void handleEnableSyncing(bool turningOn
)
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
149 pass("Keychain syncing is being turned ON");
150 dispatch_async(workq
, ^
152 CFErrorRef error
= NULL
;
153 bool bx
= SOSCCResetToOffering(&error
);
155 pass("ResetToOffering OK");
157 pass("ResetToOffering fail: %@", error
);
159 requestToJoinCircle();
160 updateSyncingEnabledSwitch();
161 dispatch_group_leave(sDispatchGroup
);
166 pass("Keychain syncing is being turned OFF");
167 CFErrorRef error
= NULL
;
168 bool bx
= SOSCCRemoveThisDeviceFromCircle(&error
);
169 updateSyncingEnabledSwitch();
171 pass("SOSCCRemoveThisDeviceFromCircle fail: %@", error
);
175 // MARK: ----- start of all tests -----
177 static void initialEstablish(void)
179 dispatch_group_enter(sDispatchGroup
);
180 dispatch_group_notify(sDispatchGroup
, requestqueue
, ^
182 printf("Exiting via dispatch_group_notify; all work done\n");
183 CFRunLoopStop(CFRunLoopGetMain());
186 handleEnableSyncing(true);
189 CFErrorRef error
= NULL
;
191 SOSCCStatus sccStatus
= SOSCCThisDeviceIsInCircle(&error
);
192 if (sccStatus
== kSOSCCNotInCircle
)
193 bx
= SOSCCResetToOffering(&error
);
195 bx
= SOSCCRequestToJoinCircle(&error
);
197 xsecdebug("circle establish error: %@", error
);
198 ok(bx
, "Circle established");
202 // MARK: ---------- Main ----------
204 // define the options table for the command line
205 static const struct option options
[] =
207 { "verbose", optional_argument
, NULL
, 'v' },
211 static int kTestCount
= 22;
213 int sc_103_syncupdate(int argc
, char *const *argv
)
218 while (argSlot
= -1, (arg
= getopt_long(argc
, (char * const *)argv
, "i:v", options
, &argSlot
)) != -1)
222 secerror("arg: %s", optarg
);
226 plan_tests(kTestCount
);
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
);
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");