2 // secd_77_ids_messaging.c
7 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
9 * @APPLE_LICENSE_HEADER_START@
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
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.
26 * @APPLE_LICENSE_HEADER_END@
31 #include <Security/SecBase.h>
32 #include <Security/SecItem.h>
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>
42 #include "secd_regressions.h"
43 #include "SOSTestDataSource.h"
45 #include "SOSRegressionUtilities.h"
46 #include <utilities/SecCFWrappers.h>
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>
56 static int kTestTestCount
= 101;
58 static bool SOSAccountIsThisPeerIDMe(SOSAccountRef account
, CFStringRef peerID
) {
59 SOSPeerInfoRef mypi
= SOSFullPeerInfoGetPeerInfo(account
->my_identity
);
60 CFStringRef myPeerID
= SOSPeerInfoGetPeerID(mypi
);
62 return myPeerID
&& CFEqualSafe(myPeerID
, peerID
);
65 static void ids_test_sync(SOSAccountRef alice_account
, SOSAccountRef bob_account
){
67 CFMutableDictionaryRef changes
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
68 __block
bool SyncingCompletedOverIDS
= false;
69 __block CFErrorRef localError
= NULL
;
70 __block
bool done
= false;
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!");
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
);
89 ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
);
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!");
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
);
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){
114 ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
);
116 }while(done
== false);
117 CFReleaseNull(changes
);
122 CFErrorRef error
= NULL
;
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");
129 SOSAccountRef alice_account
= CreateAccountForLocalChanges(CFSTR("Alice"), dsName
);
130 SOSAccountRef bob_account
= CreateAccountForLocalChanges(CFSTR("Bob"), dsName
);
132 ok(SOSAccountAssertUserCredentialsAndUpdate(bob_account
, cfaccount
, cfpassword
, &error
), "Credential setting (%@)", error
);
134 // Bob wins writing at this point, feed the changes back to alice.
135 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 1, "updates");
137 ok(SOSAccountAssertUserCredentialsAndUpdate(alice_account
, cfaccount
, cfpassword
, &error
), "Credential setting (%@)", error
);
138 CFReleaseNull(cfpassword
);
139 CFReleaseNull(error
);
141 ok(NULL
!= alice_account
, "Alice Created");
142 ok(NULL
!= bob_account
, "Bob Created");
144 ok(SOSAccountResetToOffering_wTxn(alice_account
, &error
), "Reset to offering (%@)", error
);
145 CFReleaseNull(error
);
147 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
149 ok(SOSAccountJoinCircles_wTxn(bob_account
, &error
), "Bob Applies (%@)", error
);
150 CFReleaseNull(error
);
152 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
155 CFArrayRef applicants
= SOSAccountCopyApplicants(alice_account
, &error
);
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
);
163 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 3, "updates");
165 accounts_agree("bob&alice pair", bob_account
, alice_account
);
167 CFArrayRef peers
= SOSAccountCopyPeers(alice_account
, &error
);
168 ok(peers
&& CFArrayGetCount(peers
) == 2, "See two peers %@ (%@)", peers
, error
);
169 CFReleaseNull(peers
);
171 //creating test devices
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
);
185 CFReleaseNull(views
);
186 CFArrayForEachC(deviceIDs
, deviceID
) {
187 SOSTestDeviceRef device
= SOSTestDeviceCreateWithDbNamed(kCFAllocatorDefault
, deviceID
, deviceID
);
188 SOSTestDeviceSetPeerIDs(device
, peerMetas
, version
, NULL
);
190 if(CFEqualSafe(deviceID
, SOSAccountGetMyPeerID(alice_account
))){
191 alice_account
->factory
= device
->dsf
;
192 SOSTestDeviceAddGenericItem(device
, CFSTR("Alice"), CFSTR("Alice-add"));
195 bob_account
->factory
= device
->dsf
;
196 SOSTestDeviceAddGenericItem(device
, CFSTR("Bob"), CFSTR("Bob-add"));
199 CFReleaseNull(device
);
201 CFReleaseNull(deviceIDs
);
202 CFReleaseNull(peerMetas
);
204 SOSUnregisterAllTransportMessages();
205 CFArrayRemoveAllValues(message_transports
);
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
);
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");
213 bool result
= SOSAccountModifyCircle(alice_account
, &error
, ^bool(SOSCircleRef circle
) {
214 CFErrorRef localError
= NULL
;
216 SOSFullPeerInfoUpdateTransportType(alice_account
->my_identity
, SOSTransportMessageTypeIDSV2
, &localError
);
217 SOSFullPeerInfoUpdateTransportPreference(alice_account
->my_identity
, kCFBooleanFalse
, &localError
);
218 SOSFullPeerInfoUpdateTransportFragmentationPreference(alice_account
->my_identity
, kCFBooleanTrue
, &localError
);
220 return SOSCircleHasPeer(circle
, SOSFullPeerInfoGetPeerInfo(alice_account
->my_identity
), NULL
);
223 ok(result
, "Alice account update circle with transport type");
225 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
227 result
= SOSAccountModifyCircle(bob_account
, &error
, ^bool(SOSCircleRef circle
) {
228 CFErrorRef localError
= NULL
;
230 SOSFullPeerInfoUpdateTransportType(bob_account
->my_identity
, SOSTransportMessageTypeIDSV2
, &localError
);
231 SOSFullPeerInfoUpdateTransportPreference(bob_account
->my_identity
, kCFBooleanFalse
, &localError
);
232 SOSFullPeerInfoUpdateTransportFragmentationPreference(bob_account
->my_identity
, kCFBooleanTrue
, &localError
);
234 return SOSCircleHasPeer(circle
, SOSFullPeerInfoGetPeerInfo(bob_account
->my_identity
), NULL
);
237 ok(result
, "Bob account update circle with transport type");
238 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
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");
245 CFReleaseNull(alice_transportType
);
246 CFReleaseNull(bob_accountTransportType
);
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");
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");
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");
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");
265 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 3, "updates");
268 ok(SOSAccountEnsurePeerRegistration(alice_account
, NULL
), "ensure peer registration - alice");
270 ok(SOSAccountEnsurePeerRegistration(bob_account
, NULL
), "ensure peer registration - bob");
273 ids_test_sync(alice_account
, bob_account
);
275 CFReleaseNull(alice_account
);
276 CFReleaseNull(bob_account
);
277 CFReleaseNull(bob_dsid
);
278 CFReleaseNull(alice_dsid
);
279 CFReleaseNull(changes
);
281 SOSUnregisterAllTransportMessages();
282 SOSUnregisterAllTransportCircles();
283 SOSUnregisterAllTransportKeyParameters();
284 CFArrayRemoveAllValues(key_transports
);
285 CFArrayRemoveAllValues(circle_transports
);
286 CFArrayRemoveAllValues(message_transports
);
290 int secd_77_ids_messaging(int argc
, char *const *argv
)
292 plan_tests(kTestTestCount
);
294 secd_test_setup_temp_keychain(__FUNCTION__
, NULL
);