]> git.saurik.com Git - apple/security.git/blame - OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.c
Security-57740.20.22.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSTransport.c
CommitLineData
d8f41ccd 1
5c19dc3a
A
2#include <Security/SecureObjectSync/SOSInternal.h>
3#include <Security/SecureObjectSync/SOSKVSKeys.h>
4#include <Security/SecureObjectSync/SOSAccountPriv.h>
5#include <Security/SecureObjectSync/SOSTransport.h>
6#include <Security/SecureObjectSync/SOSTransportKeyParameterKVS.h>
7#include <Security/SecureObjectSync/SOSTransportCircleKVS.h>
8#include <Security/SecureObjectSync/SOSTransportMessageKVS.h>
9#include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
10#include <Security/SecureObjectSync/SOSTransportMessage.h>
11#include <Security/SecureObjectSync/SOSRing.h>
12
d8f41ccd 13#include <SOSCloudKeychainClient.h>
fa7225c8 14#include <SOSCloudKeychainLogging.h>
d8f41ccd 15#include <utilities/debugging.h>
5c19dc3a
A
16#include <utilities/SecCFWrappers.h>
17#include <CoreFoundation/CFBase.h>
d8f41ccd
A
18
19CFStringRef kKeyParameter = CFSTR("KeyParameter");
20CFStringRef kCircle = CFSTR("Circle");
21CFStringRef kMessage = CFSTR("Message");
22CFStringRef kAlwaysKeys = CFSTR("AlwaysKeys");
23CFStringRef kFirstUnlocked = CFSTR("FirstUnlockKeys");
24CFStringRef kUnlocked = CFSTR("UnlockedKeys");
5c19dc3a 25extern CFStringRef kSOSAccountDebugScope;
d8f41ccd 26
5c19dc3a 27#define DATE_LENGTH 18
d8f41ccd
A
28
29CFStringRef SOSInterestListCopyDescription(CFArrayRef interests)
30{
31 CFMutableStringRef description = CFStringCreateMutable(kCFAllocatorDefault, 0);
32 CFStringAppendFormat(description, NULL, CFSTR("<Interest: "));
33
5c19dc3a
A
34 if (interests) {
35 CFArrayForEach(interests, ^(const void* string) {
36 if (isString(string))
37
38 CFStringAppendFormat(description, NULL, CFSTR(" '%@'"), string);
39 });
40 }
d8f41ccd 41 CFStringAppend(description, CFSTR(">"));
5c19dc3a 42
d8f41ccd
A
43 return description;
44}
45
46
47//
48// MARK: Key Interest Processing
49//
50
51CFGiblisGetSingleton(CFMutableArrayRef, SOSGetTransportMessages, sTransportMessages, ^{
52 *sTransportMessages = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
53});
54
55CFGiblisGetSingleton(CFMutableArrayRef, SOSGetTransportKeyParameters, sTransportKeyParameters, ^{
56 *sTransportKeyParameters = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
57});
58
59CFGiblisGetSingleton(CFMutableArrayRef, SOSGetTransportCircles, sTransportCircles, ^{
60 *sTransportCircles = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
61});
62
63
64void SOSRegisterTransportMessage(SOSTransportMessageRef additional) {
65 CFArrayAppendValue(SOSGetTransportMessages(), additional);
66}
67
68void SOSUnregisterTransportMessage(SOSTransportMessageRef removal) {
69 CFArrayRemoveAllValue(SOSGetTransportMessages(), removal);
70}
71
72void SOSUnregisterAllTransportMessages() {
73 CFArrayRemoveAllValues(SOSGetTransportMessages());
74}
75
76void SOSRegisterTransportCircle(SOSTransportCircleRef additional) {
77 CFArrayAppendValue(SOSGetTransportCircles(), additional);
78}
79
80void SOSUnregisterTransportCircle(SOSTransportCircleRef removal) {
81 CFArrayRemoveAllValue(SOSGetTransportCircles(), removal);
82}
83
84void SOSUnregisterAllTransportCircles() {
85 CFArrayRemoveAllValues(SOSGetTransportCircles());
86}
87
88void SOSRegisterTransportKeyParameter(SOSTransportKeyParameterRef additional) {
89 CFArrayAppendValue(SOSGetTransportKeyParameters(), additional);
90}
91
92void SOSUnregisterTransportKeyParameter(SOSTransportKeyParameterRef removal) {
93 CFArrayRemoveAllValue(SOSGetTransportKeyParameters(), removal);
94}
95
96void SOSUnregisterAllTransportKeyParameters() {
97 CFArrayRemoveAllValues(SOSGetTransportKeyParameters());
98}
99
100//
101// Should we be dispatching back to our queue to handle later
102//
e0e0d90e 103void SOSUpdateKeyInterest(SOSAccountRef account)
d8f41ccd
A
104{
105 CFMutableArrayRef alwaysKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
106 CFMutableArrayRef afterFirstUnlockKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
107 CFMutableArrayRef whenUnlockedKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
108 CFMutableDictionaryRef keyDict = CFDictionaryCreateMutableForCFTypes (kCFAllocatorDefault);
109
110 CFArrayForEach(SOSGetTransportKeyParameters(), ^(const void *value) {
5c19dc3a 111 SOSTransportKeyParameterRef tKP = (SOSTransportKeyParameterRef) value;
e0e0d90e 112 if (SOSTransportKeyParameterGetAccount(tKP) == account && SOSTransportKeyParameterGetTransportType(tKP, NULL) == kKVS) {
5c19dc3a
A
113 SOSTransportKeyParameterKVSRef tkvs = (SOSTransportKeyParameterKVSRef) value;
114 CFErrorRef localError = NULL;
d8f41ccd 115
5c19dc3a
A
116 if (!SOSTransportKeyParameterKVSAppendKeyInterests(tkvs, alwaysKeys, afterFirstUnlockKeys, whenUnlockedKeys, &localError)) {
117 secerror("Error getting key parameters interests %@", localError);
118 }
119 CFReleaseNull(localError);
d8f41ccd 120 }
d8f41ccd
A
121 });
122 CFMutableDictionaryRef keyParamsDict = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
123 CFDictionarySetValue(keyParamsDict, kAlwaysKeys, alwaysKeys);
124 CFDictionarySetValue(keyParamsDict, kFirstUnlocked, afterFirstUnlockKeys);
125 CFDictionarySetValue(keyParamsDict, kUnlocked, whenUnlockedKeys);
126 CFDictionarySetValue(keyDict, kKeyParameter, keyParamsDict);
5c19dc3a 127
d8f41ccd
A
128 CFReleaseNull(alwaysKeys);
129 CFReleaseNull(afterFirstUnlockKeys);
130 CFReleaseNull(whenUnlockedKeys);
131 alwaysKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
132 afterFirstUnlockKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
133 whenUnlockedKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
134
135 CFArrayForEach(SOSGetTransportCircles(), ^(const void *value) {
e0e0d90e 136 if (SOSTransportCircleGetAccount((SOSTransportCircleRef)value) == account && SOSTransportCircleGetTransportType((SOSTransportCircleRef)value, NULL) == kKVS) {
5c19dc3a
A
137 SOSTransportCircleKVSRef tkvs = (SOSTransportCircleKVSRef) value;
138 CFErrorRef localError = NULL;
139
140 if(!SOSTransportCircleKVSAppendKeyInterest(tkvs, alwaysKeys, afterFirstUnlockKeys, whenUnlockedKeys, &localError)){
141 secerror("Error getting circle interests %@", localError);
142 }
143 if(!SOSTransportCircleKVSAppendPeerInfoKeyInterest(tkvs, alwaysKeys, afterFirstUnlockKeys, whenUnlockedKeys, &localError)){
144 secerror("Error getting peer info interests %@", localError);
145 }
5c19dc3a
A
146 if(!SOSTransportCircleKVSAppendRingKeyInterest(tkvs, alwaysKeys, afterFirstUnlockKeys, whenUnlockedKeys, &localError)){
147 secerror("Error getting ring interests %@", localError);
148 }
5c19dc3a
A
149 if(!SOSTransportCircleKVSAppendDebugKeyInterest(tkvs, alwaysKeys, afterFirstUnlockKeys, whenUnlockedKeys, &localError)){
150 secerror("Error getting debug key interests %@", localError);
151 }
152 CFReleaseNull(localError);
d8f41ccd 153 }
d8f41ccd
A
154
155 });
156 CFMutableDictionaryRef circleDict = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
157 CFDictionarySetValue(circleDict, kAlwaysKeys, alwaysKeys);
158 CFDictionarySetValue(circleDict, kFirstUnlocked, afterFirstUnlockKeys);
159 CFDictionarySetValue(circleDict, kUnlocked, whenUnlockedKeys);
160 CFDictionarySetValue(keyDict, kCircle, circleDict);
161
162 CFReleaseNull(alwaysKeys);
163 CFReleaseNull(afterFirstUnlockKeys);
164 CFReleaseNull(whenUnlockedKeys);
165 alwaysKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
166 afterFirstUnlockKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
167 whenUnlockedKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
168
169 CFArrayForEach(SOSGetTransportMessages(), ^(const void *value) {
e0e0d90e 170 if (SOSTransportMessageGetAccount((SOSTransportMessageRef) value) == account && SOSTransportMessageGetTransportType((SOSTransportMessageRef) value, NULL) == kKVS) {
5c19dc3a
A
171 SOSTransportMessageKVSRef tkvs = (SOSTransportMessageKVSRef) value;
172 CFErrorRef localError = NULL;
d8f41ccd 173
5c19dc3a
A
174 if(!SOSTransportMessageKVSAppendKeyInterest(tkvs, alwaysKeys, afterFirstUnlockKeys, whenUnlockedKeys, &localError)){
175 secerror("Error getting message interests %@", localError);
176 }
177 CFReleaseNull(localError);
d8f41ccd 178 }
d8f41ccd
A
179 });
180
181 CFMutableDictionaryRef messageDict = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
182 CFDictionarySetValue(messageDict, kAlwaysKeys, alwaysKeys);
183 CFDictionarySetValue(messageDict, kFirstUnlocked, afterFirstUnlockKeys);
184 CFDictionarySetValue(messageDict, kUnlocked, whenUnlockedKeys);
185 CFDictionarySetValue(keyDict, kMessage, messageDict);
186
5c19dc3a
A
187 //
188 // Log what we are about to do.
189 //
e0e0d90e 190 secnotice("key-interests", "Updating interests: %@", keyDict);
5c19dc3a 191
5c19dc3a
A
192 SOSCloudKeychainUpdateKeys(keyDict, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef returnedValues, CFErrorRef error) {
193 if (error) {
194 secerror("Error updating keys: %@", error);
d8f41ccd 195 }
5c19dc3a 196 });
d8f41ccd 197
d8f41ccd
A
198 CFReleaseNull(alwaysKeys);
199 CFReleaseNull(afterFirstUnlockKeys);
200 CFReleaseNull(whenUnlockedKeys);
201 CFReleaseNull(keyParamsDict);
202 CFReleaseNull(circleDict);
203 CFReleaseNull(messageDict);
204 CFReleaseNull(keyDict);
205}
206
207
208static void showWhatWasHandled(CFDictionaryRef updates, CFMutableArrayRef handledKeys) {
209
210 CFMutableStringRef updateStr = CFStringCreateMutable(kCFAllocatorDefault, 0);
211 CFMutableStringRef handledKeysStr = CFStringCreateMutable(kCFAllocatorDefault, 0);
212
213 CFDictionaryForEach(updates, ^(const void *key, const void *value) {
214 if (isString(key)) {
215 CFStringAppendFormat(updateStr, NULL, CFSTR("%@ "), (CFStringRef)key);
216 }
217 });
218 CFArrayForEach(handledKeys, ^(const void *value) {
219 if (isString(value)) {
220 CFStringAppendFormat(handledKeysStr, NULL, CFSTR("%@ "), (CFStringRef)value);
221 }
222 });
5c19dc3a
A
223 secinfo("updates", "Updates [%ld]: %@", CFDictionaryGetCount(updates), updateStr);
224 secinfo("updates", "Handled [%ld]: %@", CFArrayGetCount(handledKeys), handledKeysStr);
d8f41ccd
A
225
226 CFReleaseSafe(updateStr);
227 CFReleaseSafe(handledKeysStr);
228}
229
fa7225c8
A
230#define KVS_STATE_INTERVAL 50
231
d8f41ccd
A
232CF_RETURNS_RETAINED
233CFMutableArrayRef SOSTransportDispatchMessages(SOSAccountRef account, CFDictionaryRef updates, CFErrorRef *error){
fa7225c8 234 static int KVSLogCountDown = 0;
d8f41ccd
A
235
236 CFMutableArrayRef handledKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
fa7225c8 237 CFStringRef dsid = NULL;
d8f41ccd 238
fa7225c8 239 if(CFDictionaryGetValueIfPresent(updates, kSOSKVSAccountChangedKey, (const void**)&dsid)){
949d2ff0 240 secnotice("accountChange", "SOSTransportDispatchMessages received kSOSKVSAccountChangedKey");
fa7225c8 241 KVSLogCountDown = 0; // Get an initial check on KVS values
d8f41ccd 242 // While changing accounts we may modify the key params array. To avoid stepping on ourselves we
5c19dc3a 243 // copy the list for iteration. Now modifying the transport outside of the list iteration.
fa7225c8
A
244 CFMutableArrayRef transportsToUse = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
245
246 CFArrayForEach(SOSGetTransportKeyParameters(), ^(const void *value) {
247 SOSTransportKeyParameterRef transport = (SOSTransportKeyParameterRef) value;
248 if(CFEqualSafe(SOSTransportKeyParameterGetAccount(transport), account)){
249 CFArrayAppendValue(transportsToUse, transport);
250 }
251
252 });
253
254 CFArrayForEach(transportsToUse, ^(const void *value) {
255 SOSTransportKeyParameterRef tempTransport = (SOSTransportKeyParameterRef) value;
256
257 CFStringRef accountDSID = (CFStringRef)SOSAccountGetValue(account, kSOSDSIDKey, error);
258
259 if(accountDSID == NULL){
5c19dc3a 260 SOSTransportKeyParameterHandleNewAccount(tempTransport, account);
fa7225c8
A
261 SOSAccountSetValue(account, kSOSDSIDKey, dsid, error);
262 secdebug("dsid", "Assigning new DSID: %@", dsid);
263 } else if(accountDSID != NULL && CFStringCompare(accountDSID, dsid, 0) != 0 ) {
264 SOSTransportKeyParameterHandleNewAccount(tempTransport, account);
265 SOSAccountSetValue(account, kSOSDSIDKey, dsid, error);
266 secdebug("dsid", "Assigning new DSID: %@", dsid);
267 } else {
268 secdebug("dsid", "DSIDs are the same!");
d8f41ccd 269 }
fa7225c8 270 });
5c19dc3a 271
fa7225c8
A
272 CFReleaseNull(transportsToUse);
273
274 CFArrayAppendValue(handledKeys, kSOSKVSAccountChangedKey);
d8f41ccd 275 }
5c19dc3a 276
d8f41ccd
A
277
278 // Iterate through keys in updates. Perform circle change update.
279 // Then instantiate circles and engines and peers for all peers that
280 // are receiving a message in updates.
281 CFMutableDictionaryRef circle_peer_messages_table = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
282 CFMutableDictionaryRef circle_circle_messages_table = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
283 CFMutableDictionaryRef circle_retirement_messages_table = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
5c19dc3a
A
284 CFMutableDictionaryRef ring_update_message_table = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
285 CFMutableDictionaryRef peer_info_message_table = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
286 CFMutableDictionaryRef debug_info_message_table = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
287
d8f41ccd
A
288 __block CFDataRef newParameters = NULL;
289 __block bool initial_sync = false;
290 __block bool new_account = false;
291
292 CFDictionaryForEach(updates, ^(const void *key, const void *value) {
293 CFErrorRef localError = NULL;
294 CFStringRef circle_name = NULL;
5c19dc3a
A
295 CFStringRef ring_name = NULL;
296 CFStringRef peer_info_name = NULL;
d8f41ccd
A
297 CFStringRef from_name = NULL;
298 CFStringRef to_name = NULL;
5c19dc3a
A
299 CFStringRef backup_name = NULL;
300
fa7225c8 301 require_quiet(isString(key), errOut);
5c19dc3a 302 switch (SOSKVSKeyGetKeyTypeAndParse(key, &circle_name, &peer_info_name, &ring_name, &backup_name, &from_name, &to_name)) {
d8f41ccd
A
303 case kCircleKey:
304 CFDictionarySetValue(circle_circle_messages_table, circle_name, value);
305 break;
306 case kInitialSyncKey:
307 initial_sync = true;
308 break;
309 case kParametersKey:
310 if (isData(value)) {
311 newParameters = (CFDataRef) CFRetainSafe(value);
312 }
313 break;
314 case kMessageKey: {
315 CFMutableDictionaryRef circle_messages = CFDictionaryEnsureCFDictionaryAndGetCurrentValue(circle_peer_messages_table, circle_name);
316 CFDictionarySetValue(circle_messages, from_name, value);
317 break;
318 }
319 case kRetirementKey: {
320 CFMutableDictionaryRef circle_retirements = CFDictionaryEnsureCFDictionaryAndGetCurrentValue(circle_retirement_messages_table, circle_name);
321 CFDictionarySetValue(circle_retirements, from_name, value);
322 break;
323 }
324 case kAccountChangedKey:
325 new_account = true;
326 break;
5c19dc3a
A
327 case kPeerInfoKey:
328 CFDictionarySetValue(peer_info_message_table, peer_info_name, value);
329 break;
330 case kRingKey:
331 if(isString(ring_name))
332 CFDictionarySetValue(ring_update_message_table, ring_name, value);
333 break;
334 case kDebugInfoKey:
335 CFDictionarySetValue(debug_info_message_table, peer_info_name, value);
336 break;
337 case kLastCircleKey:
338 case kLastKeyParameterKey:
d8f41ccd
A
339 case kUnknownKey:
340 secnotice("updates", "Unknown key '%@', ignoring", key);
341 break;
342
343 }
fa7225c8
A
344
345 errOut:
d8f41ccd
A
346 CFReleaseNull(circle_name);
347 CFReleaseNull(from_name);
348 CFReleaseNull(to_name);
5c19dc3a
A
349 CFReleaseNull(ring_name);
350 CFReleaseNull(peer_info_name);
351 CFReleaseNull(backup_name);
d8f41ccd
A
352
353 if (error && *error)
354 secerror("Peer message processing error for: %@ -> %@ (%@)", key, value, *error);
355 if (localError)
356 secerror("Peer message local processing error for: %@ -> %@ (%@)", key, value, localError);
357
358 CFReleaseNull(localError);
359 });
360
361
362 if (newParameters) {
363 CFArrayForEach(SOSGetTransportKeyParameters(), ^(const void *value) {
364 SOSTransportKeyParameterRef tkvs = (SOSTransportKeyParameterRef) value;
365 CFErrorRef localError = NULL;
366 if(CFEqualSafe(SOSTransportKeyParameterGetAccount(tkvs), account)){
367 if(!SOSTransportKeyParameterHandleKeyParameterChanges(tkvs, newParameters, localError))
368 secerror("Transport failed to handle new key parameters: %@", localError);
369 }
370 });
371 CFArrayAppendValue(handledKeys, kSOSKVSKeyParametersKey);
372 }
373 CFReleaseNull(newParameters);
374
375 if(initial_sync){
376 CFArrayAppendValue(handledKeys, kSOSKVSInitialSyncKey);
377 }
378
5c19dc3a
A
379 if(CFDictionaryGetCount(debug_info_message_table)) {
380 /* check for a newly set circle debug scope */
381 CFTypeRef debugScope = CFDictionaryGetValue(debug_info_message_table, kSOSAccountDebugScope);
382 if (debugScope) {
383 if(isString(debugScope)){
384 ApplyScopeListForID(debugScope, kScopeIDCircle);
385 }else if(isDictionary(debugScope)){
386 ApplyScopeDictionaryForID(debugScope, kScopeIDCircle);
387 }
388 }
e0e0d90e
A
389 CFStringRef debugInfoKey = SOSDebugInfoKeyCreateWithTypeName(kSOSAccountDebugScope);
390 CFArrayAppendValue(handledKeys, debugInfoKey);
391 CFReleaseNull(debugInfoKey);
5c19dc3a 392 }
d8f41ccd
A
393
394 if(CFDictionaryGetCount(circle_retirement_messages_table)) {
395 CFArrayForEach(SOSGetTransportCircles(), ^(const void *value) {
396 SOSTransportCircleRef tkvs = (SOSTransportCircleRef) value;
397 if(CFEqualSafe(SOSTransportCircleGetAccount((SOSTransportCircleRef)value), account)){
398 CFErrorRef localError = NULL;
399 CFDictionaryRef handledRetirementKeys = SOSTransportCircleHandleRetirementMessages(tkvs, circle_retirement_messages_table, error);
400 if(handledRetirementKeys == NULL){
401 secerror("Transport failed to handle retirement messages: %@", localError);
402 } else {
403 CFDictionaryForEach(handledRetirementKeys, ^(const void *key, const void *value) {
404 CFStringRef circle_name = (CFStringRef)key;
405 CFArrayRef handledPeerIDs = (CFArrayRef)value;
406 CFArrayForEach(handledPeerIDs, ^(const void *value) {
407 CFStringRef peer_id = (CFStringRef)value;
408 CFStringRef keyHandled = SOSRetirementKeyCreateWithCircleNameAndPeer(circle_name, peer_id);
409 CFArrayAppendValue(handledKeys, keyHandled);
410 CFReleaseNull(keyHandled);
411 });
412 });
413 }
414 CFReleaseNull(handledRetirementKeys);
415 CFReleaseNull(localError);
416 }
417 });
418 }
5c19dc3a
A
419 if(CFDictionaryGetCount(peer_info_message_table)){
420 CFArrayForEach(SOSGetTransportCircles(), ^(const void *value) {
421 SOSTransportCircleRef tkvs = (SOSTransportCircleRef) value;
422 if(CFEqualSafe(SOSTransportCircleGetAccount((SOSTransportCircleRef)value), account)){
423 CFErrorRef localError = NULL;
424 CFArrayRef handledPeerInfoMessages = SOSTransportCircleKVSHandlePeerInfoV2Messages(tkvs, peer_info_message_table, error);
425 if(handledPeerInfoMessages == NULL){
426 secerror("Transport failed to handle peer info messages: %@", localError);
427 } else {
428 CFArrayForEach(handledPeerInfoMessages, ^(const void *value) {
429 CFStringRef peer_id = (CFStringRef)value;
430 CFStringRef keyHandled = SOSPeerInfoV2KeyCreateWithPeerName(peer_id);
431 CFArrayAppendValue(handledKeys, keyHandled);
432 CFReleaseNull(keyHandled);
433 });
434 }
435 CFReleaseNull(handledPeerInfoMessages);
436 CFReleaseNull(localError);
437 }
438 });
439 }
440 if(CFDictionaryGetCount(circle_peer_messages_table)) {
441 CFArrayForEach(SOSGetTransportMessages(), ^(const void *value) {
442 SOSTransportMessageRef tkvs = (SOSTransportMessageRef) value;
fa7225c8
A
443
444 if(SOSTransportMessageGetTransportType(tkvs, error) == kIDSTest){ //this case is for the IDS test transport
445 if(CFEqualSafe(SOSTransportMessageGetAccount((SOSTransportMessageRef)value), account)){
446 CFErrorRef handleMessagesError = NULL;
447 CFDictionaryRef handledPeers = SOSTransportMessageHandleMessages(account->ids_message_transport, circle_peer_messages_table, &handleMessagesError);
448
449 if (handledPeers) {
450 // We need to look for and send responses.
451 SOSAccountSendIKSPSyncList(account, error);
452 SOSAccountSyncWithAllKVSPeers(account, error);
453
454 CFDictionaryForEach(handledPeers, ^(const void *key, const void *value) {
455 if (isString(key) && isArray(value)) {
456 CFArrayForEach(value, ^(const void *value) {
457 if (isString(value)) {
458 CFStringRef peerID = (CFStringRef) value;
459 CFStringRef kvsHandledKey = SOSMessageKeyCreateFromPeerToTransport(account->ids_message_transport, peerID);
460 CFArrayAppendValue(handledKeys, kvsHandledKey);
461 CFReleaseSafe(kvsHandledKey);
462 }
463 });
464 }
465 });
466 CFErrorRef flushError = NULL;
467 if (!SOSTransportMessageFlushChanges((SOSTransportMessageRef)account->kvs_message_transport, &flushError)) {
468 secerror("Flush failed: %@", flushError);
469 }
470 }
471 else {
472 secerror("Didn't handle? : %@", handleMessagesError);
473 }
474 CFReleaseNull(handledPeers);
475 CFReleaseNull(handleMessagesError);
476 }
477 }
478
479 else if(SOSTransportMessageGetTransportType(tkvs, error) != kIDS){
5c19dc3a
A
480 if(CFEqualSafe(SOSTransportMessageGetAccount((SOSTransportMessageRef)value), account)){
481 CFErrorRef handleMessagesError = NULL;
482 CFDictionaryRef handledPeers = SOSTransportMessageHandleMessages(account->kvs_message_transport, circle_peer_messages_table, &handleMessagesError);
483
484 if (handledPeers) {
485 // We need to look for and send responses.
fa7225c8
A
486 SOSAccountSendIKSPSyncList(account, error);
487 SOSAccountSyncWithAllKVSPeers(account, error);
e3d460c9 488
5c19dc3a
A
489 CFDictionaryForEach(handledPeers, ^(const void *key, const void *value) {
490 if (isString(key) && isArray(value)) {
491 CFArrayForEach(value, ^(const void *value) {
492 if (isString(value)) {
493 CFStringRef peerID = (CFStringRef) value;
494
fa7225c8
A
495 CFStringRef kvsHandledKey = SOSMessageKeyCreateFromPeerToTransport(account->kvs_message_transport, peerID);
496 if(kvsHandledKey != NULL)
497 CFArrayAppendValue(handledKeys, kvsHandledKey);
5c19dc3a
A
498 CFReleaseSafe(kvsHandledKey);
499 }
500 });
501 }
502 });
5c19dc3a
A
503 CFErrorRef flushError = NULL;
504 if (!SOSTransportMessageFlushChanges((SOSTransportMessageRef)account->kvs_message_transport, &flushError)) {
505 secerror("Flush failed: %@", flushError);
506 }
507 }
508 else {
509 secerror("Didn't handle? : %@", handleMessagesError);
510 }
511 CFReleaseNull(handledPeers);
512 CFReleaseNull(handleMessagesError);
513 }
514 }
515 });
516
517 }
d8f41ccd
A
518 if(CFDictionaryGetCount(circle_circle_messages_table)) {
519 CFArrayForEach(SOSGetTransportCircles(), ^(const void *value) {
520 SOSTransportCircleRef tkvs = (SOSTransportCircleRef) value;
521 if(CFEqualSafe(SOSTransportCircleGetAccount((SOSTransportCircleRef)value), account)){
522 CFArrayRef handleCircleMessages = SOSTransportCircleHandleCircleMessages(tkvs, circle_circle_messages_table, error);
523 CFErrorRef localError = NULL;
524 if(handleCircleMessages == NULL){
525 secerror("Transport failed to handle circle messages: %@", localError);
526 } else if(CFArrayGetCount(handleCircleMessages) == 0) {
527 if(CFDictionaryGetCount(circle_circle_messages_table) != 0) {
528 secerror("Transport failed to process all circle messages: (%ld/%ld) %@",
529 CFArrayGetCount(handleCircleMessages),
530 CFDictionaryGetCount(circle_circle_messages_table), localError);
531 } else {
532 secnotice("circle", "Transport handled no circle messages");
533 }
534 } else {
535 CFArrayForEach(handleCircleMessages, ^(const void *value) {
536 CFStringRef keyHandled = SOSCircleKeyCreateWithName((CFStringRef)value, error);
537 CFArrayAppendValue(handledKeys, keyHandled);
538 CFReleaseNull(keyHandled);
539 });
540 }
5c19dc3a 541
d8f41ccd
A
542 CFReleaseNull(localError);
543 CFReleaseNull(handleCircleMessages);
544 }
545
546 });
547 }
5c19dc3a
A
548 if(CFDictionaryGetCount(ring_update_message_table)){
549 CFArrayForEach(SOSGetTransportCircles(), ^(const void *value) {
550 if(CFEqualSafe(SOSTransportCircleGetAccount((SOSTransportCircleRef)value), account)){
551 CFErrorRef localError = NULL;
552 CFMutableArrayRef handledRingMessages = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
553
554 CFDictionaryForEach(ring_update_message_table, ^(const void *key, const void *value) {
fa7225c8 555 CFDataRef ringData = asData(value, NULL);
5c19dc3a
A
556 SOSRingRef ring = SOSRingCreateFromData(error, ringData);
557
558 if(SOSAccountUpdateRingFromRemote(account, ring, error)){
559 CFArrayAppendValue(handledRingMessages, key);
d8f41ccd 560 }
5c19dc3a
A
561 CFReleaseNull(ring);
562 });
563 if(CFArrayGetCount(handledRingMessages) == 0){
564 secerror("Transport failed to handle ring messages: %@", localError);
565 } else {
566 CFArrayForEach(handledRingMessages, ^(const void *value) {
567 CFStringRef ring_name = (CFStringRef)value;
568 CFStringRef keyHandled = SOSRingKeyCreateWithRingName(ring_name);
569 CFArrayAppendValue(handledKeys, keyHandled);
570 CFReleaseNull(keyHandled);
d8f41ccd 571 });
d8f41ccd 572 }
5c19dc3a
A
573 CFReleaseNull(handledRingMessages);
574 CFReleaseNull(localError);
d8f41ccd
A
575 }
576 });
577 }
5c19dc3a 578
d8f41ccd
A
579 CFReleaseNull(circle_retirement_messages_table);
580 CFReleaseNull(circle_circle_messages_table);
581 CFReleaseNull(circle_peer_messages_table);
5c19dc3a
A
582 CFReleaseNull(debug_info_message_table);
583 CFReleaseNull(ring_update_message_table);
584 CFReleaseNull(peer_info_message_table);
585 CFReleaseNull(debug_info_message_table);
fa7225c8
A
586
587 if(KVSLogCountDown <= 0) {
588 SOSCloudKVSLogState();
589 KVSLogCountDown = KVS_STATE_INTERVAL;
590 } else KVSLogCountDown--;
5c19dc3a 591
d8f41ccd
A
592 showWhatWasHandled(updates, handledKeys);
593
594 return handledKeys;
595}
596