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