]>
Commit | Line | Data |
---|---|---|
427c49bc A |
1 | // |
2 | // secd-55-account-circle.c | |
3 | // sec | |
4 | // | |
5 | // Created by Mitch Adler on 1/25/12. | |
6 | // | |
7 | // | |
8 | ||
9 | ||
10 | ||
11 | #include <Security/SecBase.h> | |
12 | #include <Security/SecItem.h> | |
13 | ||
14 | #include <CoreFoundation/CFDictionary.h> | |
15 | ||
16 | #include <SecureObjectSync/SOSAccount.h> | |
17 | #include <SecureObjectSync/SOSCloudCircle.h> | |
18 | #include <SecureObjectSync/SOSInternal.h> | |
19 | #include <SecureObjectSync/SOSUserKeygen.h> | |
20 | ||
21 | #include <stdlib.h> | |
22 | #include <unistd.h> | |
23 | ||
24 | #include "secd_regressions.h" | |
25 | #include "SOSTestDataSource.h" | |
26 | ||
27 | #include "SOSRegressionUtilities.h" | |
28 | #include <utilities/SecCFWrappers.h> | |
29 | #include <Security/SecKeyPriv.h> | |
30 | ||
31 | #include <securityd/SOSCloudCircleServer.h> | |
32 | ||
33 | #include "SOSAccountTesting.h" | |
34 | ||
35 | ||
36 | static int kTestTestCount = 202; | |
37 | ||
38 | static void tests(void) | |
39 | { | |
40 | CFErrorRef error = NULL; | |
41 | CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10); | |
42 | CFDataRef cfwrong_password = CFDataCreate(NULL, (uint8_t *) "NotFooFooFoo", 10); | |
43 | CFStringRef cfaccount = CFSTR("test@test.org"); | |
44 | ||
45 | CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); | |
46 | ||
47 | SOSAccountRef alice_account = CreateAccountForLocalChanges(changes, CFSTR("Alice"), CFSTR("TestSource")); | |
48 | SOSAccountRef bob_account = CreateAccountForLocalChanges(changes, CFSTR("Bob"), CFSTR("TestSource")); | |
49 | SOSAccountRef carol_account = CreateAccountForLocalChanges(changes, CFSTR("Carol"), CFSTR("TestSource")); | |
50 | ||
51 | ok(SOSAccountAssertUserCredentials(bob_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error); | |
52 | ||
53 | // Bob wins writing at this point, feed the changes back to alice. | |
54 | ||
55 | FeedChangesToMulti(changes, alice_account, carol_account, NULL); | |
56 | ||
57 | ok(SOSAccountAssertUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error); | |
58 | CFReleaseNull(error); | |
59 | ok(SOSAccountTryUserCredentials(alice_account, cfaccount, cfpassword, &error), "Credential trying (%@)", error); | |
60 | CFReleaseNull(error); | |
61 | ok(!SOSAccountTryUserCredentials(alice_account, cfaccount, cfwrong_password, &error), "Credential failing (%@)", error); | |
62 | CFReleaseNull(cfwrong_password); | |
63 | is(error ? CFErrorGetCode(error) : 0, kSOSErrorWrongPassword, "Expected SOSErrorWrongPassword"); | |
64 | CFReleaseNull(error); | |
65 | ||
66 | ok(SOSAccountResetToOffering(alice_account, &error), "Reset to offering (%@)", error); | |
67 | CFReleaseNull(error); | |
68 | ||
69 | FeedChangesTo(changes, bob_account); | |
70 | ||
71 | ok(SOSAccountJoinCircles(bob_account, &error), "Bob Applies (%@)", error); | |
72 | CFReleaseNull(error); | |
73 | ||
74 | FeedChangesTo(changes, alice_account); | |
75 | ||
76 | { | |
77 | CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error); | |
78 | ||
79 | ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error); | |
80 | ok(SOSAccountAcceptApplicants(alice_account, applicants, &error), "Alice accepts (%@)", error); | |
81 | CFReleaseNull(error); | |
82 | CFReleaseNull(applicants); | |
83 | } | |
84 | ||
85 | ||
86 | FeedChangesTo(changes, bob_account); // Bob sees he's accepted | |
87 | ||
88 | FeedChangesTo(changes, alice_account); // Alice sees bob-concurring | |
89 | ||
90 | ok(CFDictionaryGetCount(changes) == 0, "We converged. (%@)", changes); | |
91 | ||
92 | accounts_agree("bob&alice pair", bob_account, alice_account); | |
93 | ||
94 | CFArrayRef peers = SOSAccountCopyPeers(alice_account, &error); | |
95 | ok(peers && CFArrayGetCount(peers) == 2, "See two peers %@ (%@)", peers, error); | |
96 | CFReleaseNull(peers); | |
97 | ||
98 | CFDictionaryRef alice_new_gestalt = SOSCreatePeerGestaltFromName(CFSTR("Alice, but different")); | |
99 | ||
100 | ok(SOSAccountUpdateGestalt(alice_account, alice_new_gestalt), "Update gestalt %@ (%@)", alice_account, error); | |
101 | CFReleaseNull(alice_new_gestalt); | |
102 | ||
103 | FeedChangesTo(changes, bob_account); // Bob sees alice change her name. | |
104 | ||
105 | FeedChangesTo(changes, alice_account); // Alice sees the fallout. | |
106 | ||
107 | accounts_agree("Alice's name changed", bob_account, alice_account); | |
108 | ||
109 | ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves (%@)", error); | |
110 | CFReleaseNull(error); | |
111 | ||
112 | FeedChangesTo(changes, bob_account); // Bob sees alice bail. | |
113 | ||
114 | FeedChangesTo(changes, alice_account); // Alice sees the fallout. | |
115 | ||
116 | accounts_agree("Alice bails", bob_account, alice_account); | |
117 | ||
118 | peers = SOSAccountCopyPeers(alice_account, &error); | |
119 | ok(peers && CFArrayGetCount(peers) == 1, "See one peer %@ (%@)", peers, error); | |
120 | CFReleaseNull(peers); | |
121 | ||
122 | ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error); | |
123 | CFReleaseNull(error); | |
124 | ||
125 | FeedChangesTo(changes, bob_account); | |
126 | ||
127 | ||
128 | { | |
129 | CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error); | |
130 | ||
131 | ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error); | |
132 | ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts (%@)", error); | |
133 | CFReleaseNull(error); | |
134 | CFReleaseNull(applicants); | |
135 | } | |
136 | ||
137 | FeedChangesTo(changes, alice_account); // Alice sees bob accepting | |
138 | ||
139 | FeedChangesTo(changes, bob_account); // Bob sees Alice concurring | |
140 | ||
141 | accounts_agree("Alice accepts' Bob", bob_account, alice_account); | |
142 | ||
143 | ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves (%@)", error); | |
144 | CFReleaseNull(error); | |
145 | ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error); | |
146 | CFReleaseNull(error); | |
147 | ||
148 | FeedChangesTo(changes, bob_account); // Bob sees Alice leaving and rejoining | |
149 | FeedChangesTo(changes, alice_account); // Alice sees bob concurring | |
150 | ||
151 | { | |
152 | CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error); | |
153 | ||
154 | ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error); | |
155 | ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts (%@)", error); | |
156 | CFReleaseNull(error); | |
157 | CFReleaseNull(applicants); | |
158 | } | |
159 | ||
160 | FeedChangesTo(changes, alice_account); // Alice sees bob accepting | |
161 | ||
162 | FeedChangesTo(changes, bob_account); // Bob sees Alice concurring | |
163 | ||
164 | accounts_agree("Bob accepts Alice", bob_account, alice_account); | |
165 | ||
166 | // As of PR-13917727/PR-13906870 this no longer works (by "design"), in favor of making another more common | |
167 | // failure (apply/OSX-psudo-reject/re-apply) work. Write races might be "fixed better" with affirmitave rejection. | |
168 | #if 0 | |
169 | ||
170 | // | |
171 | // Write race emulation. | |
172 | // | |
173 | // | |
174 | ||
175 | ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves (%@)", error); | |
176 | CFReleaseNull(error); | |
177 | FeedChangesTo(changes, bob_account); // Bob sees Alice leaving and rejoining | |
178 | FeedChangesTo(changes, alice_account); // Alice sees bob concurring | |
179 | ||
180 | accounts_agree("Alice leaves & returns", bob_account, alice_account); | |
181 | ||
182 | ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error); | |
183 | CFReleaseNull(error); | |
184 | ||
185 | FeedChangesTo(changes, bob_account); // Bob sees Alice Applying | |
186 | ||
187 | { | |
188 | CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error); | |
189 | ||
190 | ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error); | |
191 | ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts (%@)", error); | |
192 | CFReleaseNull(error); | |
193 | CFReleaseNull(applicants); | |
194 | } | |
195 | ||
196 | CFMutableDictionaryRef bobAcceptanceChanges = ExtractPendingChanges(changes); | |
197 | ||
198 | // Alice re-applies without seeing that she was accepted. | |
199 | ok(SOSAccountLeaveCircles(alice_account, &error), "Alice Leaves again (%@)", error); | |
200 | CFReleaseNull(error); | |
201 | ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error); | |
202 | CFReleaseNull(error); | |
203 | ||
204 | CFReleaseSafe(ExtractPendingChanges(changes)); // Alice loses the race to write her changes - bob never sees em. | |
205 | ||
206 | FeedChangesTo(&bobAcceptanceChanges, alice_account); // Alice sees bob inviting her in the circle. | |
207 | ||
208 | FeedChangesTo(changes, bob_account); // Bob sees Alice Concurring | |
209 | ||
210 | // As of PR-13917727/PR-13906870 | |
211 | accounts_agree("Alice leave, applies back, loses a race and eventually gets in", bob_account, alice_account); | |
212 | #endif | |
213 | ||
214 | // Both in circle. | |
215 | ||
420ff9d9 A |
216 | // Emulation of <rdar://problem/13919554> Innsbruck11A368 +Roots: Device A was removed when Device B joined. |
217 | ||
427c49bc A |
218 | // We want Alice to leave circle while an Applicant on a full concordance signed circle with old-Alice as an Alum and Bob a peer. |
219 | // ZZZ | |
220 | ok(SOSAccountLeaveCircles(alice_account, &error), "Alice leaves once more (%@)", error); | |
221 | CFReleaseNull(error); | |
222 | ||
223 | FeedChangesTo(changes, bob_account); // Bob sees Alice become an Alum. | |
224 | FeedChangesTo(changes, alice_account); // Alice sees bob concurring | |
225 | accounts_agree("Alice and Bob see Alice out of circle", bob_account, alice_account); | |
226 | ||
227 | ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error); | |
228 | CFReleaseNull(error); | |
229 | ||
230 | ok(SOSAccountLeaveCircles(alice_account, &error), "Alice leaves while applying (%@)", error); | |
231 | FeedChangesTo(changes, bob_account); // Bob sees Alice become an Alum. | |
232 | ||
233 | CFReleaseNull(error); | |
234 | ||
235 | is(SOSAccountIsInCircles(alice_account, &error), kSOSCCNotInCircle, "Alice isn't applying any more"); | |
236 | accounts_agree("Alice leaves & some fancy concordance stuff happens", bob_account, alice_account); | |
237 | ||
238 | ok(SOSAccountJoinCircles(alice_account, &error), "Alice re-applies (%@)", error); | |
239 | CFReleaseNull(error); | |
240 | ||
241 | FeedChangesTo(changes, bob_account); // Bob sees Alice reapply. | |
242 | ||
243 | { | |
244 | CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error); | |
245 | ||
246 | ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error); | |
247 | ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts (%@)", error); | |
248 | CFReleaseNull(error); | |
249 | CFReleaseNull(applicants); | |
250 | } | |
251 | ||
252 | FeedChangesTo(changes, alice_account); // Alice sees bob accepting her | |
253 | FeedChangesTo(changes, bob_account); // Bob sees Alice concur | |
254 | ||
255 | accounts_agree("Alice comes back", bob_account, alice_account); | |
256 | ||
257 | // Emulation of <rdar://problem/13889901> | |
258 | FeedChangesTo(changes, carol_account); | |
259 | ||
260 | ok(SOSAccountAssertUserCredentials(carol_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error); | |
261 | CFReleaseNull(cfpassword); | |
262 | ok(SOSAccountJoinCircles(carol_account, &error), "Carol Applies (%@)", error); | |
263 | CFReleaseNull(error); | |
264 | CFReleaseSafe(ExtractPendingChanges(changes)); // Alice and Bob loses the race to see Carol's changes. | |
265 | ||
266 | ok(SOSAccountResetToOffering(carol_account, &error), "Reset to offering (%@)", error); | |
267 | CFReleaseNull(error); | |
268 | FeedChangesTo(changes, bob_account); | |
269 | accounts_agree("13889901", carol_account, bob_account); | |
270 | is(SOSAccountGetLastDepartureReason(bob_account, &error), kSOSMembershipRevoked, "Bob affirms he hasn't left."); | |
271 | ||
272 | ok(SOSAccountJoinCircles(bob_account, &error), "Bob ReApplies (%@)", error); | |
273 | FeedChangesTo(changes, carol_account); | |
274 | { | |
275 | CFArrayRef applicants = SOSAccountCopyApplicants(carol_account, &error); | |
276 | ||
277 | ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error); | |
278 | ok(SOSAccountAcceptApplicants(carol_account, applicants, &error), "Carol accepts (%@)", error); | |
279 | CFReleaseNull(error); | |
280 | CFReleaseNull(applicants); | |
281 | } | |
282 | FeedChangesTo(changes, bob_account); | |
283 | FeedChangesTo(changes, carol_account); | |
284 | accounts_agree("rdar://problem/13889901-II", bob_account, carol_account); | |
285 | ||
286 | CFReleaseNull(alice_new_gestalt); | |
287 | ||
288 | CFReleaseNull(bob_account); | |
289 | CFReleaseNull(alice_account); | |
290 | CFReleaseNull(carol_account); | |
291 | } | |
292 | ||
293 | int secd_55_account_circle(int argc, char *const *argv) | |
294 | { | |
295 | plan_tests(kTestTestCount); | |
296 | ||
297 | tests(); | |
298 | ||
299 | return 0; | |
300 | } |