]>
Commit | Line | Data |
---|---|---|
d8f41ccd A |
1 | /* |
2 | * Copyright (c) 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 | // Test syncing between SecItemDataSource and SOSTestDataSource | |
26 | ||
5c19dc3a A |
27 | #include <SOSCircle/Regressions/SOSTestDevice.h> |
28 | #include <SOSCircle/Regressions/SOSTestDataSource.h> | |
d8f41ccd A |
29 | #include "secd_regressions.h" |
30 | #include "SecdTestKeychainUtilities.h" | |
31 | ||
5c19dc3a A |
32 | #include <Security/SecureObjectSync/SOSEngine.h> |
33 | #include <Security/SecureObjectSync/SOSPeer.h> | |
d8f41ccd A |
34 | #include <Security/SecBase64.h> |
35 | #include <Security/SecItem.h> | |
36 | #include <Security/SecItemPriv.h> | |
37 | #include <corecrypto/ccsha2.h> | |
38 | #include <securityd/SecItemServer.h> | |
39 | #include <securityd/SecItemDataSource.h> | |
40 | #include <utilities/SecCFWrappers.h> | |
41 | #include <utilities/SecIOFormat.h> | |
42 | #include <utilities/SecFileLocations.h> | |
43 | ||
44 | #include <AssertMacros.h> | |
45 | #include <stdint.h> | |
46 | ||
5c19dc3a | 47 | static int kTestTestCount = 1306; |
d8f41ccd A |
48 | |
49 | __unused static bool SOSCircleHandleCircleWithLock(SOSEngineRef engine, CFStringRef myID, CFDataRef message, CFErrorRef *error) { | |
50 | ||
51 | CFMutableArrayRef trustedPeers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); | |
52 | CFMutableArrayRef untrustedPeers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); | |
53 | CFStringRef peerID = NULL; | |
54 | const uint8_t expected[20] = { 0xea, 0x6c, 0x01, 0x4d, | |
55 | 0xc7, 0x2d, 0x6f, 0x8c, | |
56 | 0xcd, 0x1e, 0xd9, 0x2a, | |
57 | 0xce, 0x1d, 0x41, 0xf0, | |
58 | 0xd8, 0xde, 0x89, 0x57 }; | |
59 | ||
60 | const char resultSize = sizeof(expected); | |
61 | ||
62 | CFDataRef coder = CFDataCreate(kCFAllocatorDefault, expected, resultSize); | |
63 | CFArrayForEachC(SOSEngineGetPeerIDs(engine), peerID){ | |
64 | CFArrayAppendValue(trustedPeers, peerID); | |
d8f41ccd A |
65 | }; |
66 | CFReleaseNull(coder); | |
67 | ||
68 | CFShow(trustedPeers); | |
69 | // all trusted | |
5c19dc3a | 70 | SOSEngineCircleChanged(engine, myID,trustedPeers, untrustedPeers); |
d8f41ccd A |
71 | |
72 | // make first peer untrusted | |
73 | peerID = (CFStringRef)CFArrayGetValueAtIndex(trustedPeers, 0); | |
74 | CFArrayAppendValue(untrustedPeers, peerID); | |
75 | CFArrayRemoveAllValue(trustedPeers, peerID); | |
76 | //we should see peerState cleared out except for the coder! | |
5c19dc3a | 77 | SOSEngineCircleChanged(engine, myID, trustedPeers, untrustedPeers); |
d8f41ccd A |
78 | |
79 | CFArrayAppendValue(trustedPeers, peerID); | |
80 | CFArrayRemoveAllValue(untrustedPeers, peerID); | |
81 | ||
82 | ||
83 | return true; | |
84 | } | |
85 | ||
86 | static void testsync3(const char *name, const char *test_directive, const char *test_reason) { | |
87 | __block int iteration=0; | |
88 | SOSTestDeviceListTestSync(name, test_directive, test_reason, 0, false, ^bool(SOSTestDeviceRef source, SOSTestDeviceRef dest) { | |
89 | iteration++; | |
90 | if (iteration == 12 || iteration == 13) { | |
91 | pass("pre-rcv %@", dest); | |
92 | } | |
93 | if (iteration == 19) { | |
94 | pass("pre-send %@", source); | |
95 | } | |
96 | return false; | |
97 | }, ^bool(SOSTestDeviceRef source, SOSTestDeviceRef dest, SOSMessageRef message) { | |
98 | if (iteration == 10) { | |
99 | pass("pre-add %@", source); | |
100 | //SOSTestDeviceAddGenericItem(source, CFSTR("test_account"), CFSTR("test service")); | |
101 | SOSTestDeviceAddRemoteGenericItem(source, CFSTR("test_account"), CFSTR("test service")); | |
102 | pass("post-add %@", source); | |
103 | return true; // db changed | |
104 | } else if (iteration == 12 || iteration == 15) { | |
105 | pass("post-rcv %@", dest); | |
106 | } | |
107 | return false; | |
108 | }, CFSTR("AAA"), CFSTR("BBB"), CFSTR("CCC"), NULL); | |
109 | } | |
110 | ||
111 | static void testsync2(const char *name, const char *test_directive, const char *test_reason, void (^aliceInit)(SOSDataSourceRef ds), void (^bobInit)(SOSDataSourceRef ds), CFStringRef msg, ...) { | |
112 | __block int iteration=0; | |
113 | SOSTestDeviceListTestSync(name, test_directive, test_reason, kSOSPeerVersion, false, ^bool(SOSTestDeviceRef source, SOSTestDeviceRef dest) { | |
114 | if (iteration == 96) { | |
115 | pass("%@ before message", source); | |
116 | } | |
117 | return false; | |
118 | }, ^bool(SOSTestDeviceRef source, SOSTestDeviceRef dest, SOSMessageRef message) { | |
119 | iteration++; | |
120 | if (iteration == 60) { | |
121 | pass("%@ before addition", source); | |
122 | //SOSTestDeviceAddGenericItem(source, CFSTR("test_account"), CFSTR("test service")); | |
123 | SOSTestDeviceAddRemoteGenericItem(source, CFSTR("test_account"), CFSTR("test service")); | |
124 | pass("%@ after addition", source); | |
125 | return true; | |
126 | } | |
127 | return false; | |
128 | }, CFSTR("alice"), CFSTR("bob"), CFSTR("claire"), CFSTR("dave"),CFSTR("edward"), CFSTR("frank"), CFSTR("gary"), NULL); | |
129 | } | |
130 | ||
131 | static void testsync(const char *name, const char *test_directive, const char *test_reason, void (^aliceInit)(SOSDataSourceRef ds), void (^bobInit)(SOSDataSourceRef ds), ...) { | |
132 | __block int msg_index = 0; | |
133 | __block int last_msg_index = 0; | |
134 | va_list args; | |
135 | va_start(args, bobInit); | |
136 | CFArrayRef messages = CFArrayCreateForVC(kCFAllocatorDefault, &kCFTypeArrayCallBacks, args); | |
137 | SOSTestDeviceListTestSync(name, test_directive, test_reason, 0, false, | |
138 | ^bool(SOSTestDeviceRef source, SOSTestDeviceRef dest) { | |
139 | if (msg_index == 0) { | |
140 | aliceInit(source->ds); | |
141 | bobInit(dest->ds); | |
142 | return true; | |
143 | } | |
144 | return false; | |
145 | }, ^bool(SOSTestDeviceRef source, SOSTestDeviceRef dest, SOSMessageRef message) { | |
146 | CFStringRef hexMsg = msg_index < CFArrayGetCount(messages) ? (CFStringRef)CFArrayGetValueAtIndex(messages, msg_index) : 0; | |
147 | /* We are expecting a message and msg is it's digest. */ | |
148 | if (message) { | |
149 | msg_index++; | |
150 | CFStringRef messageDigestStr = SOSMessageCopyDigestHex(message); | |
151 | if (hexMsg) { | |
152 | if (CFEqual(messageDigestStr, hexMsg)) { | |
153 | pass("%s %@ handled message [%d] %@", name, SOSEngineGetMyID(dest->ds->engine), msg_index, message); | |
154 | } else { | |
5c19dc3a A |
155 | TODO: { |
156 | todo("manifest caching changed"); | |
d8f41ccd A |
157 | fail("%s %@ received message [%d] digest %@ != %@ %@", name, SOSEngineGetMyID(dest->ds->engine), msg_index, messageDigestStr, hexMsg, message); |
158 | } | |
5c19dc3a | 159 | } |
d8f41ccd A |
160 | last_msg_index = msg_index; |
161 | } else { | |
5c19dc3a A |
162 | TODO: { |
163 | todo("manifest caching changed"); | |
d8f41ccd A |
164 | fail("%s %@ sent extra message [%d] with digest %@: %@", name, SOSEngineGetMyID(source->ds->engine), msg_index, messageDigestStr, message); |
165 | } | |
5c19dc3a | 166 | } |
d8f41ccd A |
167 | CFReleaseSafe(messageDigestStr); |
168 | //SOSCircleHandleCircleWithLock(source->ds->engine, SOSEngineGetMyID(source->ds->engine), CFDataCreate(kCFAllocatorDefault, 0, 0), NULL); | |
169 | ||
170 | } | |
171 | return false; | |
172 | }, CFSTR("alice"), CFSTR("bob"), NULL); | |
173 | ||
174 | if (msg_index < CFArrayGetCount(messages)) { | |
5c19dc3a A |
175 | TODO: { |
176 | todo("manifest caching changed"); | |
d8f41ccd | 177 | fail("%s nothing sent expecting message [%d] digest %@", name, msg_index, CFArrayGetValueAtIndex(messages, msg_index)); |
5c19dc3a | 178 | } |
d8f41ccd | 179 | } else if (last_msg_index < msg_index) { |
5c19dc3a A |
180 | TODO: { |
181 | todo("manifest caching changed"); | |
d8f41ccd A |
182 | fail("%s exchanged %d messages not in expected list", name, msg_index - last_msg_index); |
183 | } | |
5c19dc3a | 184 | } |
d8f41ccd A |
185 | |
186 | ||
187 | } | |
188 | ||
189 | #if 0 | |
190 | // Test syncing an empty circle with 1 to 10 devices and both version 0 and version 2 protocols | |
191 | static void testsyncempty(void) { | |
192 | CFMutableArrayRef deviceIDs = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); | |
193 | for (int deviceIX=0; deviceIX < 10; ++deviceIX) { | |
194 | CFStringRef deviceID = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%c"), 'A' + deviceIX); | |
195 | CFArrayAppendValue(deviceIDs, deviceID); | |
196 | CFReleaseSafe(deviceID); | |
197 | if (deviceIX > 0) { | |
198 | for (CFIndex version = 0; version < 3; version += 2) { | |
199 | CFMutableDictionaryRef testDevices = SOSTestDeviceListCreate(false, version, deviceIDs); | |
200 | SOSTestDeviceListSync("syncempty", test_directive, test_reason, testDevices, NULL, NULL); | |
201 | SOSTestDeviceListInSync("syncempty", test_directive, test_reason, testDevices); | |
5c19dc3a | 202 | SOSTestDeviceDestroyEngine(testDevices); |
d8f41ccd A |
203 | CFReleaseSafe(testDevices); |
204 | } | |
205 | } | |
206 | } | |
207 | CFReleaseSafe(deviceIDs); | |
208 | } | |
209 | #endif | |
210 | ||
211 | static CFIndex syncmany_add(int iteration) { | |
212 | if (iteration % 7 < 3 && iteration < 10) | |
213 | return iteration % 17 + 200; | |
214 | return 0; | |
215 | } | |
216 | ||
217 | static void testsyncmany(const char *name, const char *test_directive, const char *test_reason, int devFirst, int devCount, int version, CFIndex (*should_add)(int iteration)) { | |
218 | CFMutableArrayRef deviceIDs = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); | |
219 | for (int deviceIX=0; deviceIX < devCount; ++deviceIX) { | |
220 | CFStringRef deviceID = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%c"), 'A' + deviceIX); | |
221 | CFArrayAppendValue(deviceIDs, deviceID); | |
222 | CFReleaseSafe(deviceID); | |
223 | if (deviceIX >= devFirst) { | |
224 | CFMutableDictionaryRef testDevices = SOSTestDeviceListCreate(false, version, deviceIDs); | |
225 | __block int iteration = 0; | |
226 | SOSTestDeviceListSync(name, test_directive, test_reason, testDevices, ^bool(SOSTestDeviceRef source, SOSTestDeviceRef dest) { | |
227 | bool didAdd = false; | |
228 | iteration++; | |
229 | // Add 10 items in first 10 sync messages | |
230 | CFIndex toAdd = should_add(iteration); | |
231 | if (toAdd) { | |
232 | CFStringRef account = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("item%d"), iteration); | |
233 | didAdd = SOSTestDeviceAddGenericItems(source, toAdd, account, CFSTR("testsyncmany")); | |
234 | CFReleaseSafe(account); | |
235 | } | |
236 | if (iteration == 279 || iteration == 459) | |
237 | pass("pre-send[%d] %@", iteration, source); | |
238 | ||
239 | return didAdd; | |
240 | }, ^bool(SOSTestDeviceRef source, SOSTestDeviceRef dest, SOSMessageRef message) { | |
241 | if (iteration == 262) | |
242 | pass("post-rcv[%d] %@", iteration, dest); | |
243 | ||
244 | if (iteration == 272 || iteration == 279) | |
245 | pass("post-send[%d] %@", iteration, source); | |
246 | ||
247 | return false; | |
248 | }); | |
249 | SOSTestDeviceListInSync(name, test_directive, test_reason, testDevices); | |
5c19dc3a | 250 | SOSTestDeviceDestroyEngine(testDevices); |
d8f41ccd A |
251 | CFReleaseSafe(testDevices); |
252 | } | |
253 | } | |
254 | CFReleaseSafe(deviceIDs); | |
255 | } | |
256 | ||
257 | static void testsync2p(void) { | |
258 | __block int iteration = 0; | |
259 | SOSTestDeviceListTestSync("testsync2p", test_directive, test_reason, 0, false, ^bool(SOSTestDeviceRef source, SOSTestDeviceRef dest) { | |
260 | iteration++; | |
261 | // Add 10 items in first 10 sync messages | |
262 | if (iteration <= 10) { | |
263 | CFStringRef account = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("item%d"), iteration); | |
264 | SOSTestDeviceAddGenericItem(source, account, CFSTR("testsync2p")); | |
265 | CFReleaseSafe(account); | |
266 | return true; | |
267 | } | |
268 | return false; | |
269 | }, ^bool(SOSTestDeviceRef source, SOSTestDeviceRef dest, SOSMessageRef message) { | |
270 | return false; | |
271 | }, CFSTR("Atestsync2p"), CFSTR("Btestsync2p"), NULL); | |
272 | } | |
273 | ||
274 | static void synctests(void) { | |
275 | #if 0 | |
276 | // TODO: Adding items gives us non predictable creation and mod dates so | |
277 | // the message hashes can't be precomputed. | |
278 | CFDictionaryRef item = CFDictionaryCreateForCFTypes | |
279 | (0, | |
280 | kSecClass, kSecClassGenericPassword, | |
281 | kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, | |
282 | kSecAttrSynchronizable, kCFBooleanTrue, | |
283 | kSecAttrService, CFSTR("service"), | |
284 | kSecAttrAccount, CFSTR("account"), | |
285 | NULL); | |
286 | SecItemAdd(item, NULL); | |
287 | CFReleaseSafe(item); | |
288 | #endif | |
289 | ||
290 | SKIP: | |
291 | { | |
292 | ||
293 | #ifdef NO_SERVER | |
294 | // Careful with this in !NO_SERVER, it'll destroy debug keychains. | |
295 | WithPathInKeychainDirectory(CFSTR("keychain-2-debug.db"), ^(const char *keychain_path) { | |
296 | unlink(keychain_path); | |
297 | }); | |
298 | ||
299 | // Don't ever do this in !NO_SERVER, it'll destroy real keychains. | |
300 | WithPathInKeychainDirectory(CFSTR("keychain-2.db"), ^(const char *keychain_path) { | |
301 | unlink(keychain_path); | |
302 | }); | |
303 | ||
e3d460c9 | 304 | SecKeychainDbReset(NULL); |
d8f41ccd A |
305 | #else |
306 | skip("Keychain not reset", kTestTestCount, false); | |
307 | #endif | |
308 | ||
309 | testsync3("secd_70_engine3", test_directive, test_reason); | |
310 | ||
311 | // Sync between 2 empty dataSources | |
312 | testsync("secd_70_engine", test_directive, test_reason, | |
313 | ^ (SOSDataSourceRef dataSource) {}, | |
314 | ^ (SOSDataSourceRef dataSource) {}, | |
315 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
316 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
317 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
318 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
319 | NULL); | |
320 | ||
321 | // Sync a dataSource with one object to an empty dataSource | |
322 | testsync("secd_70_engine-alice1", test_directive, test_reason, | |
323 | ^ (SOSDataSourceRef dataSource) { | |
324 | __block CFErrorRef error = NULL; | |
325 | SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service")); | |
326 | // TODO: Needs to be a SecDBItemRef for the SecItemDataSource... | |
327 | ok(SOSDataSourceWith(dataSource, &error, ^(SOSTransactionRef txn, bool *commit) { | |
328 | ok(SOSDataSourceMergeObject(dataSource, txn, object, NULL, &error), "dataSource %@ added object %@", SOSEngineGetMyID(dataSource->engine), error); | |
329 | }), "ds transaction failed %@", error); | |
330 | CFReleaseSafe(object); | |
331 | CFReleaseNull(error); | |
332 | }, | |
333 | ^ (SOSDataSourceRef dataSource) {}, | |
334 | CFSTR("DDDB2DCEB7B36F0757F400251ECD11E377A0DCE8"), | |
335 | CFSTR("B2777CC898AE381B3F375B27E4FD9757F6CE9948"), | |
336 | CFSTR("CB67BF9ECF00DC7664834DE7A2D7CC1523D25341"), | |
337 | CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"), | |
338 | ||
339 | //CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"), | |
340 | //CFSTR("147B6C509908CC4A9FC4263973A842104A64CE01"), | |
341 | //CFSTR("019B494F3C06B48BB02C280AF1E19AD861A7003C"), | |
342 | //CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"), | |
343 | NULL); | |
344 | ||
345 | // Sync a dataSource with one object to another dataSource with the same object | |
346 | testsync("secd_70_engine-alice1bob1", test_directive, test_reason, | |
347 | ^ (SOSDataSourceRef dataSource) { | |
348 | #if 0 | |
349 | CFErrorRef error = NULL; | |
350 | // TODO: Needs to be a SecDBItemRef for the SecItemDataSource... | |
351 | CFDictionaryRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service")); | |
352 | ok(SOSDataSourceMergeObject(dataSource, object, NULL, &error), "dataSource %@ added object %@", SOSEngineGetMyID(dataSource->engine), error); | |
353 | CFReleaseSafe(object); | |
354 | CFReleaseNull(error); | |
355 | #endif | |
356 | }, | |
357 | ^ (SOSDataSourceRef dataSource) { | |
358 | __block CFErrorRef error = NULL; | |
359 | SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service")); | |
360 | ok(SOSDataSourceWith(dataSource, &error, ^(SOSTransactionRef txn, bool *commit) { | |
361 | ok(SOSDataSourceMergeObject(dataSource, txn, object, NULL, &error), "dataSource %@ added object %@", SOSEngineGetMyID(dataSource->engine), error); | |
362 | }), "ds transaction failed %@", error); | |
363 | CFReleaseSafe(object); | |
364 | CFReleaseNull(error); | |
365 | }, | |
366 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
367 | CFSTR("CB67BF9ECF00DC7664834DE7A2D7CC1523D25341"), | |
368 | CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"), | |
369 | ||
370 | //CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"), | |
371 | //CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"), | |
372 | //CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"), | |
373 | NULL); | |
374 | ||
375 | // Sync a dataSource with one object to another dataSource with the same object | |
376 | testsync("secd_70_engine-alice1bob2", test_directive, test_reason, | |
377 | ^ (SOSDataSourceRef dataSource) { | |
378 | #if 0 | |
379 | CFErrorRef error = NULL; | |
380 | // TODO: Needs to be a SecDBItemRef for the SecItemDataSource... | |
381 | SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service")); | |
382 | ok(SOSDataSourceMergeObject(dataSource, object, NULL, &error), "dataSource %@ added object %@", SOSEngineGetMyID(dataSource->engine), error); | |
383 | CFReleaseSafe(object); | |
384 | CFReleaseNull(error); | |
385 | #endif | |
386 | }, | |
387 | ^ (SOSDataSourceRef dataSource) { | |
388 | __block CFErrorRef error = NULL; | |
389 | __block SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service")); | |
390 | ok(SOSDataSourceWith(dataSource, &error, ^(SOSTransactionRef txn, bool *commit) { | |
391 | ok(SOSDataSourceMergeObject(dataSource, txn, object, NULL, &error), "dataSource %@ added object %@", SOSEngineGetMyID(dataSource->engine), error); | |
392 | CFReleaseSafe(object); | |
393 | CFReleaseNull(error); | |
394 | object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("account1"), CFSTR("service1")); | |
395 | ok(SOSDataSourceMergeObject(dataSource, txn, object, NULL, &error), "dataSource %@ added object %@", SOSEngineGetMyID(dataSource->engine), error); | |
396 | CFReleaseSafe(object); | |
397 | }), "ds transaction failed %@", error); | |
398 | CFReleaseNull(error); | |
399 | }, | |
400 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
401 | CFSTR("270EB3953B2E1E295F668CFC27CBB7137991A4BE"), | |
402 | CFSTR("D1B3944E3084425F41B2C2EA0BE82170E10AA37D"), | |
403 | ||
404 | //CFSTR("ADAA3ACE75ED516CB91893413EE9CC9ED04CA47B"), | |
405 | //CFSTR("D4049A1063CFBF7CAF8424E13DE3CE926FF5856C"), | |
406 | //CFSTR("9624EA855BBED6B668868BB723443E804D04F6A1"), | |
407 | //CFSTR("063E097CCD4FEB7F3610ED12B3DA828467314846"), | |
408 | //CFSTR("D1B3944E3084425F41B2C2EA0BE82170E10AA37D"), | |
409 | NULL); | |
410 | ||
411 | // Sync a dataSource with a tombstone object to another dataSource with the same object | |
412 | TODO: { | |
413 | todo("<rdar://problem/14049022> Test case in sd-70-engine fails due to need for RowID"); | |
414 | testsync("secd_70_engine-update", test_directive, test_reason, | |
415 | ^ (SOSDataSourceRef dataSource) { | |
416 | __block CFErrorRef error = NULL; | |
417 | const char *password = "password1"; | |
418 | CFDataRef data = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)password, strlen(password)); | |
419 | // TODO: Needs to be a SecDBItemRef for the SecItemDataSource... | |
420 | SOSObjectRef object_to_find = SOSDataSourceCreateGenericItemWithData(dataSource, CFSTR("test_account"), CFSTR("test service"), true, NULL); | |
421 | SOSObjectRef object = SOSDataSourceCopyObject(dataSource, object_to_find, &error); | |
422 | SOSObjectRef old_object = NULL; | |
423 | SKIP: { | |
424 | skip("no object", 1, ok(object, "Finding object %@, error: %@", object_to_find, error)); | |
425 | CFReleaseNull(data); | |
426 | // TODO: Needs to be a SecDBItemRef for the SecItemDataSource... | |
427 | old_object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service")); | |
428 | ok(SOSDataSourceWith(dataSource, &error, ^(SOSTransactionRef txn, bool *commit) { | |
429 | ok(SOSDataSourceMergeObject(dataSource, txn, object, NULL, &error), "dataSource %@ update object %@", SOSEngineGetMyID(dataSource->engine), error); | |
430 | }), "ds transaction failed %@", error); | |
431 | } | |
432 | CFReleaseSafe(data); | |
433 | CFReleaseSafe(old_object); | |
434 | CFReleaseSafe(object); | |
435 | CFReleaseNull(error); | |
436 | }, | |
437 | ^ (SOSDataSourceRef dataSource) { | |
438 | __block CFErrorRef error = NULL; | |
439 | __block SOSObjectRef object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("test_account"), CFSTR("test service")); | |
440 | ok(SOSDataSourceWith(dataSource, &error, ^(SOSTransactionRef txn, bool *commit) { | |
441 | ok(SOSDataSourceMergeObject(dataSource, txn, object, NULL, &error), "dataSource %@ added object %@", SOSEngineGetMyID(dataSource->engine), error); | |
442 | CFReleaseSafe(object); | |
443 | CFReleaseNull(error); | |
444 | object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("account1"), CFSTR("service1")); | |
445 | ok(SOSDataSourceMergeObject(dataSource, txn, object, NULL, &error), "dataSource %@ added object %@", SOSEngineGetMyID(dataSource->engine), error); | |
446 | CFReleaseSafe(object); | |
447 | }), "ds transaction failed %@", error); | |
448 | CFReleaseNull(error); | |
449 | }, | |
450 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
451 | CFSTR("270EB3953B2E1E295F668CFC27CBB7137991A4BE"), | |
452 | CFSTR("D1B3944E3084425F41B2C2EA0BE82170E10AA37D"), | |
453 | ||
454 | //CFSTR("5D07A221A152D6D6C5F1919189F259A7278A08C5"), | |
455 | //CFSTR("D4049A1063CFBF7CAF8424E13DE3CE926FF5856C"), | |
456 | //CFSTR("137FD34E9BF11B4BA0620E8EBFAB8576BCCCF294"), | |
457 | //CFSTR("5D07A221A152D6D6C5F1919189F259A7278A08C5"), | |
458 | NULL); | |
459 | } | |
460 | ||
461 | // Sync a dataSource with one object to another dataSource with the same object | |
462 | testsync("secd_70_engine-foreign-add", test_directive, test_reason, | |
463 | ^ (SOSDataSourceRef dataSource) { | |
464 | }, | |
465 | ^ (SOSDataSourceRef dataSource) { | |
466 | __block CFErrorRef error = NULL; | |
467 | const char *password = "password1"; | |
468 | CFDataRef data = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)password, strlen(password)); | |
469 | __block SOSObjectRef object = SOSDataSourceCreateGenericItemWithData(dataSource, CFSTR("test_account"), CFSTR("test service"), false, data); | |
470 | CFReleaseSafe(data); | |
471 | ok(SOSDataSourceWith(dataSource, &error, ^(SOSTransactionRef txn, bool *commit) { | |
472 | ok(SOSDataSourceMergeObject(dataSource, txn, object, NULL, &error), "dataSource %@ added object %@", SOSEngineGetMyID(dataSource->engine), error); | |
473 | CFReleaseSafe(object); | |
474 | CFReleaseNull(error); | |
475 | object = SOSDataSourceCreateGenericItem(dataSource, CFSTR("account1"), CFSTR("service1")); | |
476 | ok(SOSDataSourceMergeObject(dataSource, txn, object, NULL, &error), "dataSource %@ added object %@", SOSEngineGetMyID(dataSource->engine), error); | |
477 | CFReleaseSafe(object); | |
478 | }), "ds transaction failed %@", error); | |
479 | CFReleaseNull(error); | |
480 | }, | |
481 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
482 | CFSTR("769F63675CEE9CB968BFD9CA48DB9079BFCAFB6C"), | |
483 | CFSTR("818C24B9BC495940836B9C8F76517C838CEFFA98"), | |
484 | ||
485 | //CFSTR("D1B3944E3084425F41B2C2EA0BE82170E10AA37D"), | |
486 | //CFSTR("607EEF976943FD781CFD2B3850E6DC7979AA61EF"), | |
487 | //CFSTR("28434CD1B90CC205460557CAC03D7F12067F2329"), | |
488 | //CFSTR("D1B3944E3084425F41B2C2EA0BE82170E10AA37D"), | |
489 | NULL); | |
490 | } | |
491 | ||
492 | // Sync between 2 empty dataSources | |
493 | testsync2("secd_70_engine2", test_directive, test_reason, | |
494 | ^ (SOSDataSourceRef dataSource) {}, | |
495 | ^ (SOSDataSourceRef dataSource) {}, | |
496 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
497 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
498 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
499 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
500 | CFSTR("2AF312E092D67308A0083DFFBF2B6B754B967864"), | |
501 | NULL); | |
502 | ||
503 | //testsyncempty(); | |
d8f41ccd | 504 | testsyncmany("syncmany", test_directive, test_reason, 9, 10, 0, syncmany_add); |
d8f41ccd A |
505 | testsyncmany("v2syncmany", test_directive, test_reason, 9, 10, 2, syncmany_add); |
506 | testsync2p(); | |
507 | } | |
508 | ||
509 | int secd_70_engine(int argc, char *const *argv) | |
510 | { | |
511 | plan_tests(kTestTestCount); | |
512 | ||
513 | /* custom keychain dir */ | |
5c19dc3a | 514 | secd_test_setup_temp_keychain(__FUNCTION__, NULL); |
d8f41ccd A |
515 | |
516 | synctests(); | |
517 | ||
518 | return 0; | |
519 | } |