2 * Copyright (c) 2013-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 #include <Security/SecBase.h>
27 #include <Security/SecItem.h>
29 #include <CoreFoundation/CFDictionary.h>
31 #include <SecureObjectSync/SOSAccount.h>
32 #include <SecureObjectSync/SOSCloudCircle.h>
33 #include <SecureObjectSync/SOSInternal.h>
34 #include <SecureObjectSync/SOSUserKeygen.h>
35 #include <SecureObjectSync/SOSTransport.h>
40 #include "secd_regressions.h"
41 #include "SOSTestDataSource.h"
43 #include "SOSRegressionUtilities.h"
44 #include <utilities/SecCFWrappers.h>
45 #include <Security/SecKeyPriv.h>
47 #include <securityd/SOSCloudCircleServer.h>
49 #include "SOSAccountTesting.h"
51 static int kTestTestCount
= 126;
53 static int countPeers(SOSAccountRef account
, bool active
) {
54 CFErrorRef error
= NULL
;
57 if(active
) peers
= SOSAccountCopyActivePeers(account
, &error
);
58 else peers
= SOSAccountCopyPeers(account
, &error
);
59 int retval
= (int) CFArrayGetCount(peers
);
66 static void trim_retirements_from_circle(SOSAccountRef account) {
67 SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
68 SOSCircleRemoveRetired(circle, NULL);
72 static bool accept_applicants(SOSAccountRef account
, int count
) {
73 CFErrorRef error
= NULL
;
74 CFArrayRef applicants
= SOSAccountCopyApplicants(account
, &error
);
76 ok(applicants
, "Have Applicants");
77 if(!applicants
) goto errout
;
78 is(CFArrayGetCount(applicants
), count
, "See applicants %@ (%@)", applicants
, error
);
79 if(CFArrayGetCount(applicants
) != count
) goto errout
;
80 ok(retval
= SOSAccountAcceptApplicants(account
, applicants
, &error
), "Account accepts (%@)", error
);
83 CFReleaseNull(applicants
);
88 static void tests(void)
90 CFErrorRef error
= NULL
;
91 CFDataRef cfpassword
= CFDataCreate(NULL
, (uint8_t *) "FooFooFoo", 10);
92 CFStringRef cfaccount
= CFSTR("test@test.org");
94 CFMutableDictionaryRef changes
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
96 SOSAccountRef alice_account
= CreateAccountForLocalChanges ( CFSTR("Alice"), CFSTR("TestSource"));
97 SOSAccountRef bob_account
= CreateAccountForLocalChanges ( CFSTR("Bob"), CFSTR("TestSource"));
98 SOSAccountRef carole_account
= CreateAccountForLocalChanges ( CFSTR("Carole"), CFSTR("TestSource"));
99 SOSAccountRef david_account
= CreateAccountForLocalChanges ( CFSTR("David"), CFSTR("TestSource"));
101 ok(SOSAccountAssertUserCredentials(bob_account
, cfaccount
, cfpassword
, &error
), "Credential setting (%@)", error
);
103 // Bob wins writing at this point, feed the changes back to alice.
104 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, carole_account
, david_account
, NULL
), 1, "updates");
106 ok(SOSAccountAssertUserCredentials(alice_account
, cfaccount
, cfpassword
, &error
), "Credential setting (%@)", error
);
107 CFReleaseNull(error
);
109 ok(SOSAccountAssertUserCredentials(carole_account
, cfaccount
, cfpassword
, &error
), "Credential setting (%@)", error
);
110 CFReleaseNull(error
);
112 ok(SOSAccountAssertUserCredentials(david_account
, cfaccount
, cfpassword
, &error
), "Credential setting (%@)", error
);
113 CFReleaseNull(error
);
115 ok(SOSAccountResetToOffering(alice_account
, &error
), "Reset to offering (%@)", error
);
116 CFReleaseNull(error
);
118 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, carole_account
, david_account
, NULL
), 2, "updates");
121 ok(SOSAccountJoinCircles(bob_account
, &error
), "Bob Applies (%@)", error
);
122 CFReleaseNull(error
);
124 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, NULL
), 2, "updates");
127 ok(accept_applicants(alice_account
, 1), "Alice Accepts Application");
129 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, carole_account
, david_account
, NULL
), 3, "updates");
131 accounts_agree("bob&alice pair", bob_account
, alice_account
);
132 is(SOSAccountGetLastDepartureReason(bob_account
, &error
), kSOSNeverLeftCircle
, "Bob affirms he hasn't left.");
134 // ============================== Alice and Bob are in the Account. ============================================
137 ok(SOSAccountJoinCircles(carole_account
, &error
), "Carole Applies (%@)", error
);
138 CFReleaseNull(error
);
139 is(ProcessChangesUntilNoChange(changes
, alice_account
, carole_account
, david_account
, NULL
), 2, "updates");
141 ok(accept_applicants(alice_account
, 1), "Alice Accepts Application");
143 // Let everyone concur.
144 is(ProcessChangesUntilNoChange(changes
, alice_account
, carole_account
, david_account
, NULL
), 3, "updates");
146 CFArrayRef peers
= SOSAccountCopyPeers(alice_account
, &error
);
148 ok(peers
&& CFArrayGetCount(peers
) == 3, "See three peers %@ (%@)", peers
, error
);
149 CFReleaseNull(peers
);
151 // SOSAccountPurgePrivateCredential(alice_account);
153 ok(SOSAccountLeaveCircles(alice_account
, &error
), "Alice Leaves (%@)", error
);
154 CFReleaseNull(error
);
156 is(ProcessChangesUntilNoChange(changes
, alice_account
, carole_account
, david_account
, NULL
), 3, "updates");
159 ok(SOSAccountJoinCircles(david_account
, &error
), "David Applies (%@)", error
);
160 CFReleaseNull(error
);
162 is(ProcessChangesUntilNoChange(changes
, alice_account
, carole_account
, david_account
, NULL
), 2, "updates");
164 ok(accept_applicants(carole_account
, 1), "Carole Accepts Application");
166 // ============================== We added Carole and David while Bob was in a drawer. Alice has left ============================================
168 // ============================== Bob comes out of the drawer seeing alice left and doesn't recognize the remainder. ============================================
170 is(ProcessChangesUntilNoChange(changes
, alice_account
, bob_account
, carole_account
, david_account
, NULL
), 4, "updates");
172 CFReleaseNull(error
);
173 is(SOSAccountIsInCircles(carole_account
, &error
), kSOSCCInCircle
, "Carole still in Circle (%@)", error
);
174 CFReleaseNull(error
);
175 is(SOSAccountIsInCircles(david_account
, &error
), kSOSCCInCircle
, "David still in Circle (%@)", error
);
176 CFReleaseNull(error
);
177 is(SOSAccountIsInCircles(bob_account
, &error
), kSOSCCNotInCircle
, "Bob is not in Circle (%@)", error
);
178 CFReleaseNull(error
);
179 is(SOSAccountGetLastDepartureReason(bob_account
, &error
), kSOSLeftUntrustedCircle
, "Bob affirms he left because he doesn't know anyone.");
180 CFReleaseNull(error
);
181 is(SOSAccountIsInCircles(alice_account
, &error
), kSOSCCNotInCircle
, "Alice is not in Circle (%@)", error
);
182 CFReleaseNull(error
);
183 is(SOSAccountGetLastDepartureReason(alice_account
, &error
), kSOSWithdrewMembership
, "Alice affirms she left by request.");
184 CFReleaseNull(error
);
187 CFReleaseNull(carole_account
);
188 CFReleaseNull(david_account
);
189 CFReleaseNull(bob_account
);
190 CFReleaseNull(alice_account
);
191 CFReleaseNull(cfpassword
);
193 SOSUnregisterAllTransportMessages();
194 SOSUnregisterAllTransportCircles();
195 SOSUnregisterAllTransportKeyParameters();
196 CFArrayRemoveAllValues(key_transports
);
197 CFArrayRemoveAllValues(circle_transports
);
198 CFArrayRemoveAllValues(message_transports
);
202 int secd_61_account_leave_not_in_kansas_anymore(int argc
, char *const *argv
)
204 plan_tests(kTestTestCount
);