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
= 114;
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 CFMutableSetRef ids
= CFSetCreateMutableForCFTypes(kCFAllocatorDefault
);
79 CFSetAddValue(ids
, SOSPeerInfoGetPeerID(peer
));
81 SyncingCompletedOverIDS
= SOSTransportMessageSyncWithPeers(alice_account
->ids_message_transport
, ids
, &localError
);
87 ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
);
89 SOSCircleForEachValidPeer(bob_account
->trusted_circle
, bob_account
->user_public
, ^(SOSPeerInfoRef peer
) {
90 if (!SOSAccountIsThisPeerIDMe(bob_account
, SOSPeerInfoGetPeerID(peer
))) {
91 if(SOSPeerInfoShouldUseIDSTransport(SOSFullPeerInfoGetPeerInfo(bob_account
->my_identity
), peer
) &&
92 SOSPeerInfoShouldUseIDSMessageFragmentation(SOSFullPeerInfoGetPeerInfo(bob_account
->my_identity
), peer
)){
93 secnotice("IDS Transport","Syncing with IDS capable peers using IDS!");
95 CFMutableSetRef ids
= CFSetCreateMutableForCFTypes(kCFAllocatorDefault
);
96 CFSetAddValue(ids
, SOSPeerInfoGetPeerID(peer
));
98 SyncingCompletedOverIDS
= SOSTransportMessageSyncWithPeers(bob_account
->ids_message_transport
, ids
, &localError
);
104 ok(SyncingCompletedOverIDS
, "synced items over IDS");
105 if(CFDictionaryGetCount(SOSTransportMessageIDSTestGetChanges(alice_account
->ids_message_transport
)) == 0 && CFDictionaryGetCount(SOSTransportMessageIDSTestGetChanges(bob_account
->ids_message_transport
)) == 0){
110 ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
);
112 }while(done
== false);
113 CFReleaseNull(changes
);
118 CFErrorRef error
= NULL
;
120 CFMutableDictionaryRef changes
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
121 CFDataRef cfpassword
= CFDataCreate(NULL
, (uint8_t *) "FooFooFoo", 10);
122 CFStringRef cfaccount
= CFSTR("test@test.org");
123 CFStringRef dsName
= CFSTR("Test");
125 SOSAccountRef alice_account
= CreateAccountForLocalChanges(CFSTR("Alice"), dsName
);
126 SOSAccountRef bob_account
= CreateAccountForLocalChanges(CFSTR("Bob"), dsName
);
128 ok(SOSAccountAssertUserCredentialsAndUpdate(bob_account
, cfaccount
, cfpassword
, &error
), "Credential setting (%@)", error
);
130 // Bob wins writing at this point, feed the changes back to alice.
131 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 1, "updates");
133 ok(SOSAccountAssertUserCredentialsAndUpdate(alice_account
, cfaccount
, cfpassword
, &error
), "Credential setting (%@)", error
);
134 CFReleaseNull(cfpassword
);
135 CFReleaseNull(error
);
137 ok(NULL
!= alice_account
, "Alice Created");
138 ok(NULL
!= bob_account
, "Bob Created");
140 ok(SOSAccountResetToOffering_wTxn(alice_account
, &error
), "Reset to offering (%@)", error
);
141 CFReleaseNull(error
);
143 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
145 ok(SOSAccountJoinCircles_wTxn(bob_account
, &error
), "Bob Applies (%@)", error
);
146 CFReleaseNull(error
);
148 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
151 CFArrayRef applicants
= SOSAccountCopyApplicants(alice_account
, &error
);
153 ok(applicants
&& CFArrayGetCount(applicants
) == 1, "See one applicant %@ (%@)", applicants
, error
);
154 ok(SOSAccountAcceptApplicants(alice_account
, applicants
, &error
), "Alice accepts (%@)", error
);
155 CFReleaseNull(error
);
156 CFReleaseNull(applicants
);
159 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 3, "updates");
161 accounts_agree("bob&alice pair", bob_account
, alice_account
);
163 CFArrayRef peers
= SOSAccountCopyPeers(alice_account
, &error
);
164 ok(peers
&& CFArrayGetCount(peers
) == 2, "See two peers %@ (%@)", peers
, error
);
165 CFReleaseNull(peers
);
167 //creating test devices
170 // Optionally prefix each peer with name to make them more unique.
171 CFArrayRef deviceIDs
= CFArrayCreateForCFTypes(kCFAllocatorDefault
,SOSAccountGetMyPeerID(alice_account
), SOSAccountGetMyPeerID(bob_account
), NULL
);
172 CFSetRef views
= SOSViewsCopyTestV2Default();
173 CFMutableArrayRef peerMetas
= CFArrayCreateMutableForCFTypes(kCFAllocatorDefault
);
174 CFStringRef deviceID
;
175 CFArrayForEachC(deviceIDs
, deviceID
) {
176 SOSPeerMetaRef peerMeta
= SOSPeerMetaCreateWithComponents(deviceID
, views
, NULL
);
177 CFArrayAppendValue(peerMetas
, peerMeta
);
178 CFReleaseNull(peerMeta
);
181 CFReleaseNull(views
);
182 CFArrayForEachC(deviceIDs
, deviceID
) {
183 SOSTestDeviceRef device
= SOSTestDeviceCreateWithDbNamed(kCFAllocatorDefault
, deviceID
, deviceID
);
184 SOSTestDeviceSetPeerIDs(device
, peerMetas
, version
, NULL
);
186 if(CFEqualSafe(deviceID
, SOSAccountGetMyPeerID(alice_account
))){
187 alice_account
->factory
= device
->dsf
;
188 SOSTestDeviceAddGenericItem(device
, CFSTR("Alice"), CFSTR("Alice-add"));
191 bob_account
->factory
= device
->dsf
;
192 SOSTestDeviceAddGenericItem(device
, CFSTR("Bob"), CFSTR("Bob-add"));
195 CFReleaseNull(device
);
197 CFReleaseNull(deviceIDs
);
198 CFReleaseNull(peerMetas
);
200 SOSUnregisterAllTransportMessages();
201 CFArrayRemoveAllValues(message_transports
);
203 alice_account
->ids_message_transport
= (SOSTransportMessageRef
)SOSTransportMessageIDSTestCreate(alice_account
, CFSTR("Alice"), SOSCircleGetName(alice_account
->trusted_circle
), &error
);
204 bob_account
->ids_message_transport
= (SOSTransportMessageRef
)SOSTransportMessageIDSTestCreate(bob_account
, CFSTR("Bob"), SOSCircleGetName(bob_account
->trusted_circle
), &error
);
206 ok(alice_account
->ids_message_transport
!= NULL
, "Alice Account, Created IDS Test Transport");
207 ok(bob_account
->ids_message_transport
!= NULL
, "Bob Account, Created IDS Test Transport");
209 bool result
= SOSAccountModifyCircle(alice_account
, &error
, ^bool(SOSCircleRef circle
) {
210 CFErrorRef localError
= NULL
;
212 SOSFullPeerInfoUpdateTransportType(alice_account
->my_identity
, SOSTransportMessageTypeIDSV2
, &localError
);
213 SOSFullPeerInfoUpdateTransportPreference(alice_account
->my_identity
, kCFBooleanFalse
, &localError
);
214 SOSFullPeerInfoUpdateTransportFragmentationPreference(alice_account
->my_identity
, kCFBooleanTrue
, &localError
);
215 SOSFullPeerInfoUpdateTransportAckModelPreference(alice_account
->my_identity
, kCFBooleanTrue
, &localError
);
217 return SOSCircleHasPeer(circle
, SOSFullPeerInfoGetPeerInfo(alice_account
->my_identity
), NULL
);
220 ok(result
, "Alice account update circle with transport type");
222 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
224 result
= SOSAccountModifyCircle(bob_account
, &error
, ^bool(SOSCircleRef circle
) {
225 CFErrorRef localError
= NULL
;
227 SOSFullPeerInfoUpdateTransportType(bob_account
->my_identity
, SOSTransportMessageTypeIDSV2
, &localError
);
228 SOSFullPeerInfoUpdateTransportPreference(bob_account
->my_identity
, kCFBooleanFalse
, &localError
);
229 SOSFullPeerInfoUpdateTransportFragmentationPreference(bob_account
->my_identity
, kCFBooleanTrue
, &localError
);
230 SOSFullPeerInfoUpdateTransportAckModelPreference(bob_account
->my_identity
, kCFBooleanTrue
, &localError
);
232 return SOSCircleHasPeer(circle
, SOSFullPeerInfoGetPeerInfo(bob_account
->my_identity
), NULL
);
235 ok(result
, "Bob account update circle with transport type");
236 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
238 CFStringRef alice_transportType
=SOSPeerInfoCopyTransportType(SOSAccountGetMyPeerInfo(alice_account
));
239 CFStringRef bob_accountTransportType
= SOSPeerInfoCopyTransportType(SOSAccountGetMyPeerInfo(bob_account
));
240 ok(CFEqualSafe(alice_transportType
, CFSTR("IDS2.0")), "Alice transport type not IDS");
241 ok(CFEqualSafe(bob_accountTransportType
, CFSTR("IDS2.0")), "Bob transport type not IDS");
243 CFReleaseNull(alice_transportType
);
244 CFReleaseNull(bob_accountTransportType
);
246 SOSTransportMessageIDSTestSetName(alice_account
->ids_message_transport
, CFSTR("Alice Account"));
247 ok(SOSTransportMessageIDSTestGetName(alice_account
->ids_message_transport
) != NULL
, "retrieved getting account name");
248 ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(alice_account
, &error
) != false, "device ID from KeychainSyncingOverIDSProxy");
250 SOSTransportMessageIDSTestSetName(bob_account
->ids_message_transport
, CFSTR("Bob Account"));
251 ok(SOSTransportMessageIDSTestGetName(bob_account
->ids_message_transport
) != NULL
, "retrieved getting account name");
252 ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(bob_account
, &error
) != false, "device ID from KeychainSyncingOverIDSProxy");
255 ok(SOSAccountSetMyDSID_wTxn(alice_account
, CFSTR("Alice"),&error
), "Setting IDS device ID");
256 CFStringRef alice_dsid
= SOSAccountCopyDeviceID(alice_account
, &error
);
257 ok(CFEqualSafe(alice_dsid
, CFSTR("Alice")), "Getting IDS device ID");
259 ok(SOSAccountSetMyDSID_wTxn(bob_account
, CFSTR("Bob"),&error
), "Setting IDS device ID");
260 CFStringRef bob_dsid
= SOSAccountCopyDeviceID(bob_account
, &error
);
261 ok(CFEqualSafe(bob_dsid
, CFSTR("Bob")), "Getting IDS device ID");
263 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 3, "updates");
266 ok(SOSAccountEnsurePeerRegistration(alice_account
, NULL
), "ensure peer registration - alice");
268 ok(SOSAccountEnsurePeerRegistration(bob_account
, NULL
), "ensure peer registration - bob");
271 ids_test_sync(alice_account
, bob_account
);
273 CFReleaseNull(alice_account
);
274 CFReleaseNull(bob_account
);
275 CFReleaseNull(bob_dsid
);
276 CFReleaseNull(alice_dsid
);
277 CFReleaseNull(changes
);
282 int secd_77_ids_messaging(int argc
, char *const *argv
)
284 plan_tests(kTestTestCount
);
286 secd_test_setup_temp_keychain(__FUNCTION__
, NULL
);