]> git.saurik.com Git - apple/security.git/blob - OSX/sec/securityd/Regressions/secd_77_ids_messaging.c
Security-57740.1.18.tar.gz
[apple/security.git] / OSX / sec / securityd / Regressions / secd_77_ids_messaging.c
1 //
2 // secd_77_ids_messaging.c
3 // sec
4 //
5
6 /*
7 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
8 *
9 * @APPLE_LICENSE_HEADER_START@
10 *
11 * This file contains Original Code and/or Modifications of Original Code
12 * as defined in and that are subject to the Apple Public Source License
13 * Version 2.0 (the 'License'). You may not use this file except in
14 * compliance with the License. Please obtain a copy of the License at
15 * http://www.opensource.apple.com/apsl/ and read it before using this
16 * file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_LICENSE_HEADER_END@
27 */
28
29
30 #include <stdio.h>
31 #include <Security/SecBase.h>
32 #include <Security/SecItem.h>
33
34 #include <Security/SecureObjectSync/SOSAccount.h>
35 #include <Security/SecureObjectSync/SOSCloudCircle.h>
36 #include <Security/SecureObjectSync/SOSInternal.h>
37 #include <Security/SecureObjectSync/SOSFullPeerInfo.h>
38 #include <Security/SecureObjectSync/SOSUserKeygen.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41
42 #include "secd_regressions.h"
43 #include "SOSTestDataSource.h"
44
45 #include "SOSRegressionUtilities.h"
46 #include <utilities/SecCFWrappers.h>
47
48 #include <securityd/SOSCloudCircleServer.h>
49 #include "SecdTestKeychainUtilities.h"
50 #include "SOSAccountTesting.h"
51 #include "SOSTransportTestTransports.h"
52 #include "SOSTestDevice.h"
53 #include "SOSTestDataSource.h"
54 #include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
55
56 static int kTestTestCount = 101;
57
58 static bool SOSAccountIsThisPeerIDMe(SOSAccountRef account, CFStringRef peerID) {
59 SOSPeerInfoRef mypi = SOSFullPeerInfoGetPeerInfo(account->my_identity);
60 CFStringRef myPeerID = SOSPeerInfoGetPeerID(mypi);
61
62 return myPeerID && CFEqualSafe(myPeerID, peerID);
63 }
64
65 static void ids_test_sync(SOSAccountRef alice_account, SOSAccountRef bob_account){
66
67 CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
68 __block bool SyncingCompletedOverIDS = false;
69 __block CFErrorRef localError = NULL;
70 __block bool done = false;
71 do{
72 SOSCircleForEachValidPeer(alice_account->trusted_circle, alice_account->user_public, ^(SOSPeerInfoRef peer) {
73 if (!SOSAccountIsThisPeerIDMe(alice_account, SOSPeerInfoGetPeerID(peer))) {
74 if(SOSPeerInfoShouldUseIDSTransport(SOSFullPeerInfoGetPeerInfo(alice_account->my_identity), peer) &&
75 SOSPeerInfoShouldUseIDSMessageFragmentation(SOSFullPeerInfoGetPeerInfo(alice_account->my_identity), peer)){
76 secnotice("IDS Transport","Syncing with IDS capable peers using IDS!");
77
78 CFMutableDictionaryRef circleToIdsId = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
79 CFMutableArrayRef ids = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
80 CFArrayAppendValue(ids, SOSPeerInfoGetPeerID(peer));
81 CFDictionaryAddValue(circleToIdsId, SOSCircleGetName(alice_account->trusted_circle), ids);
82 SyncingCompletedOverIDS = SOSTransportMessageSyncWithPeers(alice_account->ids_message_transport, circleToIdsId, &localError);
83 CFReleaseNull(circleToIdsId);
84 CFReleaseNull(ids);
85 }
86 }
87 });
88
89 ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL);
90
91 SOSCircleForEachValidPeer(bob_account->trusted_circle, bob_account->user_public, ^(SOSPeerInfoRef peer) {
92 if (!SOSAccountIsThisPeerIDMe(bob_account, SOSPeerInfoGetPeerID(peer))) {
93 if(SOSPeerInfoShouldUseIDSTransport(SOSFullPeerInfoGetPeerInfo(bob_account->my_identity), peer) &&
94 SOSPeerInfoShouldUseIDSMessageFragmentation(SOSFullPeerInfoGetPeerInfo(bob_account->my_identity), peer)){
95 secnotice("IDS Transport","Syncing with IDS capable peers using IDS!");
96
97 CFMutableDictionaryRef circleToIdsId = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
98 CFMutableArrayRef ids = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
99 CFArrayAppendValue(ids, SOSPeerInfoGetPeerID(peer));
100 CFDictionaryAddValue(circleToIdsId, SOSCircleGetName(bob_account->trusted_circle), ids);
101 SyncingCompletedOverIDS &= SOSTransportMessageSyncWithPeers(bob_account->ids_message_transport, circleToIdsId, &localError);
102 CFReleaseNull(circleToIdsId);
103 CFReleaseNull(ids);
104 }
105 }
106 });
107
108 ok(SyncingCompletedOverIDS, "synced items over IDS");
109 if(CFDictionaryGetCount(SOSTransportMessageIDSTestGetChanges(alice_account->ids_message_transport)) == 0 && CFDictionaryGetCount(SOSTransportMessageIDSTestGetChanges(bob_account->ids_message_transport)) == 0){
110 done = true;
111 break;
112 }
113
114 ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL);
115
116 }while(done == false);
117 CFReleaseNull(changes);
118 }
119
120 static void tests()
121 {
122 CFErrorRef error = NULL;
123
124 CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
125 CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
126 CFStringRef cfaccount = CFSTR("test@test.org");
127 CFStringRef dsName = CFSTR("Test");
128
129 SOSAccountRef alice_account = CreateAccountForLocalChanges(CFSTR("Alice"), dsName);
130 SOSAccountRef bob_account = CreateAccountForLocalChanges(CFSTR("Bob"), dsName);
131
132 ok(SOSAccountAssertUserCredentialsAndUpdate(bob_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
133
134 // Bob wins writing at this point, feed the changes back to alice.
135 is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 1, "updates");
136
137 ok(SOSAccountAssertUserCredentialsAndUpdate(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
138 CFReleaseNull(cfpassword);
139 CFReleaseNull(error);
140
141 ok(NULL != alice_account, "Alice Created");
142 ok(NULL != bob_account, "Bob Created");
143
144 ok(SOSAccountResetToOffering_wTxn(alice_account, &error), "Reset to offering (%@)", error);
145 CFReleaseNull(error);
146
147 is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates");
148
149 ok(SOSAccountJoinCircles_wTxn(bob_account, &error), "Bob Applies (%@)", error);
150 CFReleaseNull(error);
151
152 is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates");
153
154 {
155 CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
156
157 ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
158 ok(SOSAccountAcceptApplicants(alice_account, applicants, &error), "Alice accepts (%@)", error);
159 CFReleaseNull(error);
160 CFReleaseNull(applicants);
161 }
162
163 is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 3, "updates");
164
165 accounts_agree("bob&alice pair", bob_account, alice_account);
166
167 CFArrayRef peers = SOSAccountCopyPeers(alice_account, &error);
168 ok(peers && CFArrayGetCount(peers) == 2, "See two peers %@ (%@)", peers, error);
169 CFReleaseNull(peers);
170
171 //creating test devices
172 CFIndex version = 0;
173
174 // Optionally prefix each peer with name to make them more unique.
175 CFArrayRef deviceIDs = CFArrayCreateForCFTypes(kCFAllocatorDefault,SOSAccountGetMyPeerID(alice_account), SOSAccountGetMyPeerID(bob_account), NULL);
176 CFSetRef views = SOSViewsCopyTestV2Default();
177 CFMutableArrayRef peerMetas = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
178 CFStringRef deviceID;
179 CFArrayForEachC(deviceIDs, deviceID) {
180 SOSPeerMetaRef peerMeta = SOSPeerMetaCreateWithComponents(deviceID, views, NULL);
181 CFArrayAppendValue(peerMetas, peerMeta);
182 CFReleaseNull(peerMeta);
183 }
184
185 CFReleaseNull(views);
186 CFArrayForEachC(deviceIDs, deviceID) {
187 SOSTestDeviceRef device = SOSTestDeviceCreateWithDbNamed(kCFAllocatorDefault, deviceID, deviceID);
188 SOSTestDeviceSetPeerIDs(device, peerMetas, version, NULL);
189
190 if(CFEqualSafe(deviceID, SOSAccountGetMyPeerID(alice_account))){
191 alice_account->factory = device->dsf;
192 SOSTestDeviceAddGenericItem(device, CFSTR("Alice"), CFSTR("Alice-add"));
193 }
194 else{
195 bob_account->factory = device->dsf;
196 SOSTestDeviceAddGenericItem(device, CFSTR("Bob"), CFSTR("Bob-add"));
197 }
198
199 CFReleaseNull(device);
200 }
201 CFReleaseNull(deviceIDs);
202 CFReleaseNull(peerMetas);
203
204 SOSUnregisterAllTransportMessages();
205 CFArrayRemoveAllValues(message_transports);
206
207 alice_account->ids_message_transport = (SOSTransportMessageRef)SOSTransportMessageIDSTestCreate(alice_account, CFSTR("Alice"), SOSCircleGetName(alice_account->trusted_circle), &error);
208 bob_account->ids_message_transport = (SOSTransportMessageRef)SOSTransportMessageIDSTestCreate(bob_account, CFSTR("Bob"), SOSCircleGetName(bob_account->trusted_circle), &error);
209
210 ok(alice_account->ids_message_transport != NULL, "Alice Account, Created IDS Test Transport");
211 ok(bob_account->ids_message_transport != NULL, "Bob Account, Created IDS Test Transport");
212
213 bool result = SOSAccountModifyCircle(alice_account, &error, ^bool(SOSCircleRef circle) {
214 CFErrorRef localError = NULL;
215
216 SOSFullPeerInfoUpdateTransportType(alice_account->my_identity, SOSTransportMessageTypeIDSV2, &localError);
217 SOSFullPeerInfoUpdateTransportPreference(alice_account->my_identity, kCFBooleanFalse, &localError);
218 SOSFullPeerInfoUpdateTransportFragmentationPreference(alice_account->my_identity, kCFBooleanTrue, &localError);
219
220 return SOSCircleHasPeer(circle, SOSFullPeerInfoGetPeerInfo(alice_account->my_identity), NULL);
221 });
222
223 ok(result, "Alice account update circle with transport type");
224
225 is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates");
226
227 result = SOSAccountModifyCircle(bob_account, &error, ^bool(SOSCircleRef circle) {
228 CFErrorRef localError = NULL;
229
230 SOSFullPeerInfoUpdateTransportType(bob_account->my_identity, SOSTransportMessageTypeIDSV2, &localError);
231 SOSFullPeerInfoUpdateTransportPreference(bob_account->my_identity, kCFBooleanFalse, &localError);
232 SOSFullPeerInfoUpdateTransportFragmentationPreference(bob_account->my_identity, kCFBooleanTrue, &localError);
233
234 return SOSCircleHasPeer(circle, SOSFullPeerInfoGetPeerInfo(bob_account->my_identity), NULL);
235 });
236
237 ok(result, "Bob account update circle with transport type");
238 is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates");
239
240 CFStringRef alice_transportType =SOSPeerInfoCopyTransportType(SOSAccountGetMyPeerInfo(alice_account));
241 CFStringRef bob_accountTransportType = SOSPeerInfoCopyTransportType(SOSAccountGetMyPeerInfo(bob_account));
242 ok(CFEqualSafe(alice_transportType, CFSTR("IDS2.0")), "Alice transport type not IDS");
243 ok(CFEqualSafe(bob_accountTransportType, CFSTR("IDS2.0")), "Bob transport type not IDS");
244
245 CFReleaseNull(alice_transportType);
246 CFReleaseNull(bob_accountTransportType);
247
248 SOSTransportMessageIDSTestSetName(alice_account->ids_message_transport, CFSTR("Alice Account"));
249 ok(SOSTransportMessageIDSTestGetName(alice_account->ids_message_transport) != NULL, "retrieved getting account name");
250 ok(SOSAccountRetrieveDeviceIDFromIDSKeychainSyncingProxy(alice_account, &error) != false, "device ID from IDSKeychainSyncingProxy");
251
252 SOSTransportMessageIDSTestSetName(bob_account->ids_message_transport, CFSTR("Bob Account"));
253 ok(SOSTransportMessageIDSTestGetName(bob_account->ids_message_transport) != NULL, "retrieved getting account name");
254 ok(SOSAccountRetrieveDeviceIDFromIDSKeychainSyncingProxy(bob_account, &error) != false, "device ID from IDSKeychainSyncingProxy");
255
256
257 ok(SOSAccountSetMyDSID(alice_account, CFSTR("Alice"),&error), "Setting IDS device ID");
258 CFStringRef alice_dsid = SOSAccountCopyDeviceID(alice_account, &error);
259 ok(CFEqualSafe(alice_dsid, CFSTR("Alice")), "Getting IDS device ID");
260
261 ok(SOSAccountSetMyDSID(bob_account, CFSTR("Bob"),&error), "Setting IDS device ID");
262 CFStringRef bob_dsid = SOSAccountCopyDeviceID(bob_account, &error);
263 ok(CFEqualSafe(bob_dsid, CFSTR("Bob")), "Getting IDS device ID");
264
265 is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 3, "updates");
266
267
268 ok(SOSAccountEnsurePeerRegistration(alice_account, NULL), "ensure peer registration - alice");
269
270 ok(SOSAccountEnsurePeerRegistration(bob_account, NULL), "ensure peer registration - bob");
271
272
273 ids_test_sync(alice_account, bob_account);
274
275 CFReleaseNull(alice_account);
276 CFReleaseNull(bob_account);
277 CFReleaseNull(bob_dsid);
278 CFReleaseNull(alice_dsid);
279 CFReleaseNull(changes);
280
281 SOSUnregisterAllTransportMessages();
282 SOSUnregisterAllTransportCircles();
283 SOSUnregisterAllTransportKeyParameters();
284 CFArrayRemoveAllValues(key_transports);
285 CFArrayRemoveAllValues(circle_transports);
286 CFArrayRemoveAllValues(message_transports);
287
288 }
289
290 int secd_77_ids_messaging(int argc, char *const *argv)
291 {
292 plan_tests(kTestTestCount);
293
294 secd_test_setup_temp_keychain(__FUNCTION__, NULL);
295
296 tests();
297
298 return 0;
299 }