2 // secd-76-idstransport.c
8 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
10 * @APPLE_LICENSE_HEADER_START@
12 * This file contains Original Code and/or Modifications of Original Code
13 * as defined in and that are subject to the Apple Public Source License
14 * Version 2.0 (the 'License'). You may not use this file except in
15 * compliance with the License. Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this
19 * The Original Code and all software distributed under the License are
20 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
21 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
22 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
24 * Please see the License for the specific language governing rights and
25 * limitations under the License.
27 * @APPLE_LICENSE_HEADER_END@
32 #include <Security/SecBase.h>
33 #include <Security/SecItem.h>
35 #include <Security/SecureObjectSync/SOSAccount.h>
36 #include <Security/SecureObjectSync/SOSCloudCircle.h>
37 #include <Security/SecureObjectSync/SOSInternal.h>
38 #include <Security/SecureObjectSync/SOSFullPeerInfo.h>
39 #include <Security/SecureObjectSync/SOSUserKeygen.h>
43 #include "secd_regressions.h"
44 #include "SOSTestDataSource.h"
46 #include "SOSRegressionUtilities.h"
47 #include <utilities/SecCFWrappers.h>
49 #include <securityd/SOSCloudCircleServer.h>
50 #include "SecdTestKeychainUtilities.h"
51 #include "SOSAccountTesting.h"
52 #include "SOSTransportTestTransports.h"
53 #include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
54 #include <SOSCircle/CKBridge/SOSCloudKeychainConstants.h>
55 #include "SOSTestDevice.h"
57 static int kTestTestCount
= 92;
61 CFErrorRef error
= NULL
;
63 CFMutableDictionaryRef changes
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
64 CFDataRef cfpassword
= CFDataCreate(NULL
, (uint8_t *) "FooFooFoo", 10);
65 CFStringRef cfaccount
= CFSTR("test@test.org");
67 SOSAccountRef alice_account
= CreateAccountForLocalChanges(CFSTR("Alice"), CFSTR("ak"));
68 SOSAccountRef bob_account
= CreateAccountForLocalChanges(CFSTR("Bob"), CFSTR("ak"));
70 ok(SOSAccountAssertUserCredentialsAndUpdate(bob_account
, cfaccount
, cfpassword
, &error
), "Credential setting (%@)", error
);
72 // Bob wins writing at this point, feed the changes back to alice.
73 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 1, "updates");
75 ok(SOSAccountAssertUserCredentialsAndUpdate(alice_account
, cfaccount
, cfpassword
, &error
), "Credential setting (%@)", error
);
76 CFReleaseNull(cfpassword
);
79 ok(NULL
!= alice_account
, "Alice Created");
80 ok(NULL
!= bob_account
, "Bob Created");
82 ok(SOSAccountResetToOffering_wTxn(alice_account
, &error
), "Reset to offering (%@)", error
);
85 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
87 ok(SOSAccountJoinCircles_wTxn(bob_account
, &error
), "Bob Applies (%@)", error
);
90 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
93 CFArrayRef applicants
= SOSAccountCopyApplicants(alice_account
, &error
);
95 ok(applicants
&& CFArrayGetCount(applicants
) == 1, "See one applicant %@ (%@)", applicants
, error
);
96 ok(SOSAccountAcceptApplicants(alice_account
, applicants
, &error
), "Alice accepts (%@)", error
);
98 CFReleaseNull(applicants
);
101 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 3, "updates");
103 accounts_agree("bob&alice pair", bob_account
, alice_account
);
105 CFArrayRef peers
= SOSAccountCopyPeers(alice_account
, &error
);
106 ok(peers
&& CFArrayGetCount(peers
) == 2, "See two peers %@ (%@)", peers
, error
);
107 CFReleaseNull(peers
);
109 //creating test devices
112 // Optionally prefix each peer with name to make them more unique.
113 CFArrayRef deviceIDs
= CFArrayCreateForCFTypes(kCFAllocatorDefault
,SOSAccountGetMyPeerID(alice_account
), SOSAccountGetMyPeerID(bob_account
), NULL
);
114 CFSetRef views
= SOSViewsCopyTestV2Default();
115 CFMutableArrayRef peerMetas
= CFArrayCreateMutableForCFTypes(kCFAllocatorDefault
);
116 CFStringRef deviceID
;
117 CFArrayForEachC(deviceIDs
, deviceID
) {
118 SOSPeerMetaRef peerMeta
= SOSPeerMetaCreateWithComponents(deviceID
, views
, NULL
);
119 CFArrayAppendValue(peerMetas
, peerMeta
);
120 CFReleaseNull(peerMeta
);
123 CFReleaseNull(views
);
124 CFArrayForEachC(deviceIDs
, deviceID
) {
125 SOSTestDeviceRef device
= SOSTestDeviceCreateWithDbNamed(kCFAllocatorDefault
, deviceID
, deviceID
);
126 SOSTestDeviceSetPeerIDs(device
, peerMetas
, version
, NULL
);
128 if(CFEqualSafe(deviceID
, SOSAccountGetMyPeerID(alice_account
))){
129 alice_account
->factory
= device
->dsf
;
130 SOSTestDeviceAddGenericItem(device
, CFSTR("Alice"), CFSTR("Alice-add"));
133 bob_account
->factory
= device
->dsf
;
134 SOSTestDeviceAddGenericItem(device
, CFSTR("Bob"), CFSTR("Bob-add"));
136 CFReleaseNull(device
);
138 CFReleaseNull(deviceIDs
);
139 CFReleaseNull(peerMetas
);
141 SOSUnregisterAllTransportMessages();
142 CFArrayRemoveAllValues(message_transports
);
144 alice_account
->ids_message_transport
= (SOSTransportMessageRef
)SOSTransportMessageIDSTestCreate(alice_account
, CFSTR("Alice"), SOSCircleGetName(alice_account
->trusted_circle
), &error
);
145 bob_account
->ids_message_transport
= (SOSTransportMessageRef
)SOSTransportMessageIDSTestCreate(bob_account
, CFSTR("Bob"), SOSCircleGetName(bob_account
->trusted_circle
), &error
);
147 ok(alice_account
->ids_message_transport
!= NULL
, "Alice Account, Created IDS Test Transport");
148 ok(bob_account
->ids_message_transport
!= NULL
, "Bob Account, Created IDS Test Transport");
150 bool result
= SOSAccountModifyCircle(alice_account
, &error
, ^bool(SOSCircleRef circle
) {
151 CFErrorRef localError
= NULL
;
153 SOSFullPeerInfoUpdateTransportType(alice_account
->my_identity
, SOSTransportMessageTypeIDSV2
, &localError
);
154 SOSFullPeerInfoUpdateTransportPreference(alice_account
->my_identity
, kCFBooleanFalse
, &localError
);
155 SOSFullPeerInfoUpdateTransportFragmentationPreference(alice_account
->my_identity
, kCFBooleanTrue
, &localError
);
156 SOSFullPeerInfoUpdateTransportAckModelPreference(alice_account
->my_identity
, kCFBooleanTrue
, &localError
);
158 return SOSCircleHasPeer(circle
, SOSFullPeerInfoGetPeerInfo(alice_account
->my_identity
), NULL
);
161 ok(result
, "Alice account update circle with transport type");
163 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
165 result
= SOSAccountModifyCircle(bob_account
, &error
, ^bool(SOSCircleRef circle
) {
166 CFErrorRef localError
= NULL
;
168 SOSFullPeerInfoUpdateTransportType(bob_account
->my_identity
, SOSTransportMessageTypeIDSV2
, &localError
);
169 SOSFullPeerInfoUpdateTransportPreference(bob_account
->my_identity
, kCFBooleanFalse
, &localError
);
170 SOSFullPeerInfoUpdateTransportFragmentationPreference(bob_account
->my_identity
, kCFBooleanTrue
, &localError
);
171 SOSFullPeerInfoUpdateTransportAckModelPreference(bob_account
->my_identity
, kCFBooleanTrue
, &localError
);
173 return SOSCircleHasPeer(circle
, SOSFullPeerInfoGetPeerInfo(bob_account
->my_identity
), NULL
);
176 ok(result
, "Bob account update circle with transport type");
177 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
179 CFStringRef alice_transportType
=SOSPeerInfoCopyTransportType(SOSAccountGetMyPeerInfo(alice_account
));
180 CFStringRef bob_accountTransportType
= SOSPeerInfoCopyTransportType(SOSAccountGetMyPeerInfo(bob_account
));
181 ok(CFEqualSafe(alice_transportType
, CFSTR("IDS2.0")), "Alice transport type not IDS");
182 ok(CFEqualSafe(bob_accountTransportType
, CFSTR("IDS2.0")), "Bob transport type not IDS");
184 CFReleaseNull(alice_transportType
);
185 CFReleaseNull(bob_accountTransportType
);
187 SOSTransportMessageIDSTestSetName(alice_account
->ids_message_transport
, CFSTR("Alice Account"));
188 ok(SOSTransportMessageIDSTestGetName(alice_account
->ids_message_transport
) != NULL
, "retrieved getting account name");
189 ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(alice_account
, &error
) != false, "device ID from KeychainSyncingOverIDSProxy");
191 SOSTransportMessageIDSTestSetName(bob_account
->ids_message_transport
, CFSTR("Bob Account"));
192 ok(SOSTransportMessageIDSTestGetName(bob_account
->ids_message_transport
) != NULL
, "retrieved getting account name");
193 ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(bob_account
, &error
) != false, "device ID from KeychainSyncingOverIDSProxy");
195 ok(SOSAccountSetMyDSID_wTxn(alice_account
, CFSTR("Alice"),&error
), "Setting IDS device ID");
196 CFStringRef alice_dsid
= SOSAccountCopyDeviceID(alice_account
, &error
);
197 ok(CFEqualSafe(alice_dsid
, CFSTR("Alice")), "Getting IDS device ID");
199 ok(SOSAccountSetMyDSID_wTxn(bob_account
, CFSTR("Bob"),&error
), "Setting IDS device ID");
200 CFStringRef bob_dsid
= SOSAccountCopyDeviceID(bob_account
, &error
);
201 ok(CFEqualSafe(bob_dsid
, CFSTR("Bob")), "Getting IDS device ID");
203 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 3, "updates");
205 SOSTransportMessageIDSTestSetName(alice_account
->ids_message_transport
, CFSTR("Alice Account"));
206 ok(SOSTransportMessageIDSTestGetName(alice_account
->ids_message_transport
) != NULL
, "retrieved getting account name");
207 ok(SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(alice_account
, &error
) != false, "device ID from KeychainSyncingOverIDSProxy");
209 ok(SOSAccountSetMyDSID_wTxn(alice_account
, CFSTR("DSID"),&error
), "Setting IDS device ID");
210 CFStringRef dsid
= SOSAccountCopyDeviceID(alice_account
, &error
);
211 ok(CFEqualSafe(dsid
, CFSTR("DSID")), "Getting IDS device ID");
214 ok(SOSAccountStartPingTest(alice_account
, CFSTR("hai there!"), &error
), "Ping test");
215 ok(CFDictionaryGetCount(SOSTransportMessageIDSTestGetChanges(alice_account
->ids_message_transport
)) != 0, "ping message made it to transport");
216 SOSTransportMessageIDSTestClearChanges(alice_account
->ids_message_transport
);
218 ok(SOSAccountSendIDSTestMessage(alice_account
, CFSTR("hai again!"), &error
), "Send Test Message");
219 ok(CFDictionaryGetCount(SOSTransportMessageIDSTestGetChanges(alice_account
->ids_message_transport
)) != 0, "ping message made it to transport");
221 CFStringRef dataKey
= CFStringCreateWithCString(kCFAllocatorDefault
, kMessageKeyIDSDataMessage
, kCFStringEncodingASCII
);
222 CFStringRef deviceIDKey
= CFStringCreateWithCString(kCFAllocatorDefault
, kMessageKeyDeviceID
, kCFStringEncodingASCII
);
223 CFStringRef sendersPeerIDKey
= CFStringCreateWithCString(kCFAllocatorDefault
, kMessageKeySendersPeerID
, kCFStringEncodingASCII
);
225 //test IDS message handling
226 CFMutableDictionaryRef messageDict
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
227 ok(SOSTransportMessageIDSHandleMessage(alice_account
, messageDict
, &error
) == kHandleIDSMessageDontHandle
, "sending empty message dictionary");
229 CFDictionaryAddValue(messageDict
, deviceIDKey
, CFSTR("Alice Account"));
230 ok(SOSTransportMessageIDSHandleMessage(alice_account
, messageDict
, &error
) == kHandleIDSMessageDontHandle
, "sending device ID only");
232 CFReleaseNull(messageDict
);
233 messageDict
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
234 CFDictionaryAddValue(messageDict
, sendersPeerIDKey
, CFSTR("Alice Account"));
235 ok(SOSTransportMessageIDSHandleMessage(alice_account
, messageDict
, &error
) == kHandleIDSMessageDontHandle
, "sending peer ID only");
237 CFReleaseNull(messageDict
);
238 messageDict
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
239 CFDataRef data
= CFDataCreate(kCFAllocatorDefault
, 0, 0);
240 CFDictionaryAddValue(messageDict
, dataKey
, data
);
241 ok(SOSTransportMessageIDSHandleMessage(alice_account
, messageDict
, &error
) == kHandleIDSMessageDontHandle
, "sending data only");
243 CFReleaseNull(messageDict
);
245 messageDict
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
246 data
= CFDataCreate(kCFAllocatorDefault
, 0, 0);
247 CFDictionaryAddValue(messageDict
, dataKey
, data
);
248 CFDictionaryAddValue(messageDict
, sendersPeerIDKey
, CFSTR("Alice Account"));
249 ok(SOSTransportMessageIDSHandleMessage(alice_account
, messageDict
, &error
) == kHandleIDSMessageDontHandle
, "sending data and peerid only");
251 CFReleaseNull(messageDict
);
253 messageDict
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
254 data
= CFDataCreate(kCFAllocatorDefault
, 0, 0);
255 CFDictionaryAddValue(messageDict
, dataKey
, data
);
256 CFDictionaryAddValue(messageDict
, deviceIDKey
, CFSTR("Alice Account"));
257 ok(SOSTransportMessageIDSHandleMessage(alice_account
, messageDict
, &error
) == kHandleIDSMessageDontHandle
, "sending data and deviceid only");
259 CFReleaseNull(messageDict
);
261 messageDict
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
262 CFDictionaryAddValue(messageDict
, deviceIDKey
, CFSTR("Alice Account"));
263 CFDictionaryAddValue(messageDict
, sendersPeerIDKey
, CFSTR("Alice Account"));
264 ok(SOSTransportMessageIDSHandleMessage(alice_account
, messageDict
, &error
) == kHandleIDSMessageDontHandle
, "sending peerid and deviceid only");
266 CFReleaseNull(messageDict
);
268 messageDict
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
269 data
= CFDataCreate(kCFAllocatorDefault
, 0, 0);
270 CFDictionaryAddValue(messageDict
, dataKey
, data
);
271 CFDictionaryAddValue(messageDict
, deviceIDKey
, CFSTR("Alice Account"));
272 CFDictionaryAddValue(messageDict
, sendersPeerIDKey
, SOSPeerInfoGetPeerID(SOSAccountGetMyPeerInfo(bob_account
)));
273 ok(SOSTransportMessageIDSHandleMessage(alice_account
, messageDict
, &error
) == kHandleIDSMessageDontHandle
, "sending peerid and deviceid and data");
275 CFReleaseNull(messageDict
);
278 messageDict
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
279 data
= CFDataCreate(kCFAllocatorDefault
, 0, 0);
280 CFDictionaryAddValue(messageDict
, dataKey
, data
);
281 CFStringRef BobDeviceID
= SOSPeerInfoCopyDeviceID(SOSAccountGetMyPeerInfo(bob_account
));
282 CFDictionaryAddValue(messageDict
, deviceIDKey
, BobDeviceID
);
283 CFReleaseNull(BobDeviceID
);
284 CFDictionaryAddValue(messageDict
, sendersPeerIDKey
, CFSTR("Alice Account"));
285 ok(SOSTransportMessageIDSHandleMessage(alice_account
, messageDict
, &error
) == kHandleIDSMessageDontHandle
, "sending peerid and deviceid and data");
288 CFReleaseNull(dataKey
);
289 CFReleaseNull(deviceIDKey
);
290 CFReleaseNull(sendersPeerIDKey
);
292 CFReleaseNull(alice_account
);
293 CFReleaseNull(bob_account
);
294 CFReleaseNull(alice_dsid
);
295 CFReleaseNull(bob_dsid
);
296 CFReleaseNull(changes
);
300 int secd_76_idstransport(int argc
, char *const *argv
)
302 plan_tests(kTestTestCount
);
304 secd_test_setup_temp_keychain(__FUNCTION__
, NULL
);