2 * Copyright (c) 2012-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@
25 SOSCloudTransport.c - Implementation of the transport layer from CKBridge to SOSAccount/SOSCircle
26 These are the exported functions from CloudKeychainProxy
30 This XPC service is essentially just a proxy to iCloud KVS, which exists since
31 the main security code cannot link against Foundation.
33 See sendTSARequestWithXPC in tsaSupport.c for how to call the service
35 The client of an XPC service does not get connection events, nor does it
36 need to deal with transactions.
39 #include <AssertMacros.h>
42 #include <CoreFoundation/CoreFoundation.h>
43 #include <CoreFoundation/CFXPCBridge.h>
46 #include <CoreFoundation/CFUserNotification.h>
48 #include <utilities/debugging.h>
49 #include <utilities/SecCFWrappers.h>
50 #include <utilities/SecXPCError.h>
52 #include "SOSCloudKeychainConstants.h"
53 #include "SOSCloudKeychainClient.h"
55 static CFStringRef sErrorDomain
= CFSTR("com.apple.security.sos.transport.error");
57 #define SOSCKCSCOPE "sync"
59 // MARK: ---------- SOSCloudTransport ----------
61 /* SOSCloudTransport, a statically initialized transport singleton. */
62 static SOSCloudTransportRef sTransport
= NULL
;
64 static SOSCloudTransportRef
SOSCloudTransportCreateXPCTransport(void);
66 void SOSCloudKeychainSetTransport(SOSCloudTransportRef transport
) {
67 sTransport
= transport
;
70 /* Return the singleton cloud transport instance. */
71 static SOSCloudTransportRef
SOSCloudTransportDefaultTransport(void)
73 static dispatch_once_t sTransportOnce
;
74 dispatch_once(&sTransportOnce
, ^{
76 SOSCloudKeychainSetTransport(SOSCloudTransportCreateXPCTransport());
82 // MARK: ----- utilities -----
84 static CFErrorRef
makeError(CFIndex which
)
86 CFDictionaryRef userInfo
= NULL
;
87 return CFErrorCreate(kCFAllocatorDefault
, sErrorDomain
, which
, userInfo
);
90 // MARK: ----- DEBUG Utilities -----
92 //------------------------------------------------------------------------------------------------
94 //------------------------------------------------------------------------------------------------
96 static void describeXPCObject(char *prefix
, xpc_object_t object
)
99 // This is useful for debugging.
102 char *desc
= xpc_copy_description(object
);
103 secdebug(SOSCKCSCOPE
, "%s%s\n", prefix
, desc
);
107 secdebug(SOSCKCSCOPE
, "%s<NULL>\n", prefix
);
111 static void describeXPCType(char *prefix
, xpc_type_t xtype
)
113 // Add others as necessary, e.g. XPC_TYPE_DOUBLE
115 // This is useful for debugging.
117 if (XPC_TYPE_CONNECTION
== xtype
)
118 strcpy(msg
, "XPC_TYPE_CONNECTION");
119 else if (XPC_TYPE_ERROR
== xtype
)
120 strcpy(msg
, "XPC_TYPE_ERROR");
121 else if (XPC_TYPE_DICTIONARY
== xtype
)
122 strcpy(msg
, "XPC_TYPE_DICTIONARY");
124 strcpy(msg
, "<unknown>");
126 secdebug(SOSCKCSCOPE
, "%s type:%s\n", prefix
, msg
);
130 // MARK: ---------- SOSXPCCloudTransport ----------
132 typedef struct SOSXPCCloudTransport
*SOSXPCCloudTransportRef
;
133 struct SOSXPCCloudTransport
135 struct SOSCloudTransport transport
;
136 xpc_connection_t serviceConnection
;
137 dispatch_queue_t xpc_queue
;
140 static bool xpc_event_filter(const xpc_connection_t peer
, xpc_object_t event
, CFErrorRef
*error
)
142 // return true if the type is XPC_TYPE_DICTIONARY (and therefore something more to process)
143 secdebug(SOSCKCSCOPE
, "handle_connection_event\n");
144 xpc_type_t xtype
= xpc_get_type(event
);
145 describeXPCType("handle_xpc_event", xtype
);
146 if (XPC_TYPE_CONNECTION
== xtype
)
148 secdebug(SOSCKCSCOPE
, "handle_xpc_event: XPC_TYPE_CONNECTION (unexpected)");
149 // The client of an XPC service does not get connection events
150 // For now, we log this and keep going
151 describeXPCObject("handle_xpc_event: XPC_TYPE_CONNECTION, obj : ", event
);
154 *error
= makeError(kSOSOUnexpectedConnectionEvent
); // FIX
159 if (XPC_TYPE_ERROR
== xtype
)
162 const char *estr
= xpc_dictionary_get_string(event
, XPC_ERROR_KEY_DESCRIPTION
);
164 secdebug(SOSCKCSCOPE
, "default: xpc error: %s\n", estr
);
165 #if 0 // just log for now
166 CFStringRef errStr
= CFStringCreateWithCString(kCFAllocatorDefault
, estr
, kCFStringEncodingUTF8
);
167 CFMutableDictionaryRef userInfo
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
169 CFDictionaryAddValue(userInfo
, kCFErrorLocalizedDescriptionKey
, errStr
);
171 *error
= CFErrorCreate(kCFAllocatorDefault
, sErrorDomain
, kSOSOXPCErrorEvent
, userInfo
);
172 CFReleaseSafe(errStr
);
173 CFReleaseSafe(userInfo
);
177 if (XPC_TYPE_DICTIONARY
== xtype
)
179 secdebug(SOSCKCSCOPE
, "received dictionary event %p\n", event
);
184 secdebug(SOSCKCSCOPE
, "default: unexpected connection event %p\n", event
);
185 describeXPCObject("handle_xpc_event: obj : ", event
);
187 *error
= makeError(kSOSOUnexpectedXPCEvent
);
192 static void SOSXPCCloudTransportInit(SOSXPCCloudTransportRef transport
)
194 secdebug(SOSCKCSCOPE
, "initXPCConnection\n");
196 transport
->xpc_queue
= dispatch_queue_create(xpcServiceName
, DISPATCH_QUEUE_SERIAL
);
198 transport
->serviceConnection
= xpc_connection_create_mach_service(xpcServiceName
, transport
->xpc_queue
, 0);
200 secdebug(SOSCKCSCOPE
, "serviceConnection: %p\n", transport
->serviceConnection
);
202 xpc_connection_set_event_handler(transport
->serviceConnection
, ^(xpc_object_t event
)
204 secdebug(SOSCKCSCOPE
, "xpc_connection_set_event_handler\n");
207 xpc_connection_resume(transport
->serviceConnection
);
208 xpc_retain(transport
->serviceConnection
);
211 static void talkWithKVS(SOSXPCCloudTransportRef transport
, xpc_object_t message
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
213 CFErrorRef connectionError
= NULL
;
214 require_action(transport
->serviceConnection
, xit
, connectionError
= makeError(kSOSConnectionNotOpen
));
215 require_action(message
, xit
, connectionError
= makeError(kSOSObjectNotFoundError
));
216 dispatch_retain(processQueue
);
218 xpc_connection_send_message_with_reply(transport
->serviceConnection
, message
, transport
->xpc_queue
, ^(xpc_object_t reply
)
220 CFErrorRef serverError
= NULL
;
221 CFTypeRef object
= NULL
;
222 if (xpc_event_filter(transport
->serviceConnection
, reply
, &serverError
) && reply
)
224 describeXPCObject("getValuesFromKVS: reply : ", reply
);
226 secerror("Error from xpc_event_filter: %@", serverError
);
227 xpc_object_t xrv
= xpc_dictionary_get_value(reply
, kMessageKeyValue
);
230 describeXPCObject("talkWithKVS: xrv: ", xrv
);
232 * The given XPC object must be one that was previously returned by
233 * _CFXPCCreateXPCMessageWithCFObject().
235 object
= _CFXPCCreateCFObjectFromXPCObject(xrv
); // CF object is retained; release in callback
236 secnotice("talkwithkvs", "converted CF object: %@", object
);
239 secerror("missing value reply");
241 xpc_object_t xerror
= xpc_dictionary_get_value(reply
, kMessageKeyError
);
243 serverError
= SecCreateCFErrorWithXPCObject(xerror
); // use SecCFCreateErrorWithFormat?
245 dispatch_async(processQueue
, ^{
247 replyBlock(object
, serverError
);
248 CFReleaseSafe(object
);
251 secerror("callback error: %@", serverError
);
252 CFReleaseSafe(serverError
);
254 dispatch_release(processQueue
);
260 secerror("talkWithKVS error: %@", connectionError
);
261 dispatch_async(processQueue
, ^{
263 replyBlock(NULL
, connectionError
);
264 CFReleaseSafe(connectionError
);
265 dispatch_release(processQueue
);
269 // MARK: ---------- SOSXPCCloudTransport Client Calls ----------
271 /* Concrete function backend implementations. */
272 static void SOSCloudTransportSetItemsChangedBlock(SOSCloudTransportRef transport
,
273 CloudItemsChangedBlock itemsChangedBlock
) {
274 if (transport
->itemsChangedBlock
!= itemsChangedBlock
)
276 secnotice(SOSCKCSCOPE
, "Changing itemsChangedBlock");
277 if (transport
->itemsChangedBlock
)
278 Block_release(transport
->itemsChangedBlock
);
279 transport
->itemsChangedBlock
= Block_copy(itemsChangedBlock
);
283 /* Virtual function backend implementations. */
284 static void SOSCloudTransportPut(SOSCloudTransportRef transport
, CFDictionaryRef values
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
286 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
287 secdebug(SOSCKCSCOPE
, "%@", values
);
288 CFErrorRef error
= NULL
;
289 xpc_object_t message
= NULL
;
290 xpc_object_t xobject
= NULL
;
291 require_action(values
, xit
, error
= makeError(kSOSObjectNotFoundError
));
293 message
= xpc_dictionary_create(NULL
, NULL
, 0);
294 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
295 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationPUTDictionary
);
297 xobject
= _CFXPCCreateXPCObjectFromCFObject(values
);
298 require_action(xobject
, xit
, error
= makeError(kSOSObjectCantBeConvertedToXPCObject
));
299 xpc_dictionary_set_value(message
, kMessageKeyValue
, xobject
);
300 xpc_release(xobject
);
302 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
303 xpc_release(message
);
308 replyBlock(NULL
, error
);
309 CFReleaseSafe(error
);
313 static void SOSCloudTransportGet(SOSCloudTransportRef transport
, CFArrayRef keysToGet
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
315 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
316 secdebug(SOSCKCSCOPE
, "%@", keysToGet
);
317 CFErrorRef error
= NULL
;
318 xpc_object_t xkeysOfInterest
= xpc_dictionary_create(NULL
, NULL
, 0);
319 xpc_object_t xkeysToGet
= keysToGet
? _CFXPCCreateXPCObjectFromCFObject(keysToGet
) : xpc_null_create();
321 require_action(xkeysToGet
, xit
, error
= makeError(kSOSObjectNotFoundError
));
323 if (keysToGet
) // don't add if nulll; will call getall
324 xpc_dictionary_set_value(xkeysOfInterest
, kMessageKeyKeysToGet
, xkeysToGet
);
326 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
327 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
328 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationGETv2
);
329 xpc_dictionary_set_value(message
, kMessageKeyValue
, xkeysOfInterest
);
331 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
332 xpc_release(xkeysToGet
);
333 xpc_release(xkeysOfInterest
);
334 xpc_release(message
);
339 xpc_release(xkeysOfInterest
);
341 xpc_release(xkeysToGet
);
343 replyBlock(NULL
, error
);
344 CFReleaseSafe(error
);
348 // Handles NULL by seting xpc_null.
349 static void SecXPCDictionarySetCFObject(xpc_object_t xdict
, const char *key
, CFTypeRef object
)
351 xpc_object_t xpc_obj
= object
? _CFXPCCreateXPCObjectFromCFObject(object
) : xpc_null_create();
352 xpc_dictionary_set_value(xdict
, key
, xpc_obj
);
353 xpc_release(xpc_obj
);
356 static bool SOSCloudTransportUpdateKeys(SOSCloudTransportRef transport
,
357 CFDictionaryRef keys
,
360 __block
bool success
= true;
361 dispatch_queue_t processQueue
= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0);
363 CloudKeychainReplyBlock replyBlock
= ^(CFDictionaryRef returnedValues
, CFErrorRef returnedError
)
368 *error
= returnedError
;
372 CFReleaseSafe(returnedError
);
375 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
377 xpc_object_t xkeysOfInterest
= xpc_dictionary_create(NULL
, NULL
, 0);
378 SecXPCDictionarySetCFObject(xkeysOfInterest
, kMessageAllKeys
, keys
);
380 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
381 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
382 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationRegisterKeys
);
383 xpc_dictionary_set_value(message
, kMessageKeyValue
, xkeysOfInterest
);
385 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
386 xpc_release(message
);
387 xpc_release(xkeysOfInterest
);
392 static void SOSCloudTransportGetAll(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
394 secdebug(SOSCKCSCOPE
, "start");
395 SOSCloudTransportGet(transport
, NULL
, processQueue
, replyBlock
);
398 static void SOSCloudTransportSync(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
400 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
401 secdebug(SOSCKCSCOPE
, "start");
402 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
403 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
404 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationSynchronize
);
405 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
406 xpc_release(message
);
409 static void SOSCloudTransportSyncAndWait(SOSCloudTransportRef transport
, CFArrayRef keysToGet
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
411 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
412 secdebug(SOSCKCSCOPE
, "%@", keysToGet
);
413 secnotice(SOSCKCSCOPE
, "%s XPC request to CKD: %s", kWAIT2MINID
, kOperationSynchronizeAndWait
);
414 xpc_object_t xkeysOfInterest
= xpc_dictionary_create(NULL
, NULL
, 0);
416 xpc_object_t xkeysToRegister
= keysToGet
? _CFXPCCreateXPCObjectFromCFObject(keysToGet
) : xpc_null_create();
417 xpc_dictionary_set_value(xkeysOfInterest
, kMessageKeyKeysToGet
, xkeysToRegister
);
418 xpc_release(xkeysToRegister
);
419 xkeysToRegister
= NULL
;
421 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
422 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
423 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationSynchronizeAndWait
);
424 xpc_dictionary_set_value(message
, kMessageKeyValue
, xkeysOfInterest
);
425 xpc_release(xkeysOfInterest
);
426 xkeysOfInterest
= NULL
;
428 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
429 xpc_release(message
);
432 static void SOSCloudTransportClearAll(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
434 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
435 secdebug(SOSCKCSCOPE
, "start");
436 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
437 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
438 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationClearStore
);
439 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
440 xpc_release(message
);
443 static void SOSCloudTransportRemoveObjectForKey(SOSCloudTransportRef transport
, CFStringRef keyToRemove
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
445 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
446 secdebug(SOSCKCSCOPE
, "start");
447 CFErrorRef error
= NULL
;
448 xpc_object_t message
= NULL
;
449 xpc_object_t xkeytoremove
= NULL
;
451 require_action(keyToRemove
, xit
, error
= makeError(kSOSObjectNotFoundError
));
453 message
= xpc_dictionary_create(NULL
, NULL
, 0);
454 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
455 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationRemoveObjectForKey
);
457 xkeytoremove
= _CFXPCCreateXPCObjectFromCFObject(keyToRemove
);
458 require_action(xkeytoremove
, xit
, error
= makeError(kSOSObjectCantBeConvertedToXPCObject
));
459 xpc_dictionary_set_value(message
, kMessageKeyKey
, xkeytoremove
);
460 xpc_release(xkeytoremove
);
462 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
463 xpc_release(message
);
468 xpc_release(xkeytoremove
);
470 xpc_release(message
);
472 replyBlock(NULL
, error
);
473 CFReleaseSafe(error
);
475 static void SOSCloudTransportLocalNotification(SOSCloudTransportRef transport
, CFStringRef messageToUser
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
477 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
478 secdebug(SOSCKCSCOPE
, "start");
479 xpc_object_t xLocalNotificationDict
= xpc_dictionary_create(NULL
, NULL
, 0);
480 char *headerKey
= CFStringToCString(kCFUserNotificationAlertHeaderKey
);
481 char *message
= CFStringToCString(messageToUser
);
482 xpc_dictionary_set_string(xLocalNotificationDict
, headerKey
, message
);
484 xpc_object_t xpcmessage
= xpc_dictionary_create(NULL
, NULL
, 0);
485 xpc_dictionary_set_uint64(xpcmessage
, kMessageKeyVersion
, kCKDXPCVersion
);
486 xpc_dictionary_set_string(xpcmessage
, kMessageKeyOperation
, kOperationUILocalNotification
);
487 xpc_dictionary_set_value (xpcmessage
, kMessageKeyValue
, xLocalNotificationDict
);
488 xpc_release(xLocalNotificationDict
);
490 talkWithKVS(xpcTransport
, xpcmessage
, processQueue
, replyBlock
);
494 xpc_release(xpcmessage
);
497 static void SOSCloudTransportRequestSyncWithAllPeers(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
499 secdebug(SOSCKCSCOPE
, "start");
500 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
502 xpc_object_t xpcmessage
= xpc_dictionary_create(NULL
, NULL
, 0);
503 xpc_dictionary_set_uint64(xpcmessage
, kMessageKeyVersion
, kCKDXPCVersion
);
504 xpc_dictionary_set_string(xpcmessage
, kMessageKeyOperation
, kOperationRequestSyncWithAllPeers
);
506 talkWithKVS(xpcTransport
, xpcmessage
, processQueue
, replyBlock
);
508 xpc_release(xpcmessage
);
511 static void SOSCloudTransportRequestEnsurePeerRegistration(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
513 secdebug(SOSCKCSCOPE
, "start");
514 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
516 xpc_object_t xpcmessage
= xpc_dictionary_create(NULL
, NULL
, 0);
517 xpc_dictionary_set_uint64(xpcmessage
, kMessageKeyVersion
, kCKDXPCVersion
);
518 xpc_dictionary_set_string(xpcmessage
, kMessageKeyOperation
, kOperationRequestEnsurePeerRegistration
);
520 talkWithKVS(xpcTransport
, xpcmessage
, processQueue
, replyBlock
);
522 xpc_release(xpcmessage
);
525 static void SOSCloudTransportFlush(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
527 secdebug(SOSCKCSCOPE
, "start");
528 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
530 xpc_object_t xpcmessage
= xpc_dictionary_create(NULL
, NULL
, 0);
531 xpc_dictionary_set_uint64(xpcmessage
, kMessageKeyVersion
, kCKDXPCVersion
);
532 xpc_dictionary_set_string(xpcmessage
, kMessageKeyOperation
, kOperationFlush
);
534 talkWithKVS(xpcTransport
, xpcmessage
, processQueue
, replyBlock
);
536 xpc_release(xpcmessage
);
539 static SOSCloudTransportRef
SOSCloudTransportCreateXPCTransport(void)
541 SOSXPCCloudTransportRef st
;
542 st
= calloc(1, sizeof(*st
));
543 st
->transport
.put
= SOSCloudTransportPut
;
544 st
->transport
.updateKeys
= SOSCloudTransportUpdateKeys
;
545 st
->transport
.get
= SOSCloudTransportGet
;
546 st
->transport
.getAll
= SOSCloudTransportGetAll
;
547 st
->transport
.synchronize
= SOSCloudTransportSync
;
548 st
->transport
.synchronizeAndWait
= SOSCloudTransportSyncAndWait
;
549 st
->transport
.clearAll
= SOSCloudTransportClearAll
;
550 st
->transport
.removeObjectForKey
= SOSCloudTransportRemoveObjectForKey
;
551 st
->transport
.localNotification
= SOSCloudTransportLocalNotification
;
552 st
->transport
.requestSyncWithAllPeers
= SOSCloudTransportRequestSyncWithAllPeers
;
553 st
->transport
.requestEnsurePeerRegistration
= SOSCloudTransportRequestEnsurePeerRegistration
;
554 st
->transport
.flush
= SOSCloudTransportFlush
;
555 st
->transport
.itemsChangedBlock
= Block_copy(^CFArrayRef(CFDictionaryRef changes
) {
556 secerror("Calling default itemsChangedBlock - fatal: %@", changes
);
560 SOSXPCCloudTransportInit(st
);
561 return &st
->transport
;
564 // MARK: ---------- SOSCloudKeychain concrete client APIs ----------
565 void SOSCloudKeychainSetItemsChangedBlock(CloudItemsChangedBlock itemsChangedBlock
)
567 secdebug(SOSCKCSCOPE
, "start");
568 SOSCloudTransportSetItemsChangedBlock(SOSCloudTransportDefaultTransport(),
572 // MARK: ---------- SOSCloudKeychain virtual client APIs ----------
574 void SOSCloudKeychainPutObjectsInCloud(CFDictionaryRef objects
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
576 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
578 cTransportRef
->put(cTransportRef
, objects
, processQueue
, replyBlock
);
581 bool SOSCloudKeychainUpdateKeys(CFDictionaryRef keys
,
584 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
586 return cTransportRef
->updateKeys(cTransportRef
, keys
, error
);
591 CF_RETURNS_RETAINED CFArrayRef
SOSCloudKeychainHandleUpdateKeyParameter(CFDictionaryRef updates
)
593 CFArrayRef result
= NULL
;
594 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
595 if (cTransportRef
->itemsChangedBlock
)
596 result
= ((CloudItemsChangedBlock
)cTransportRef
->itemsChangedBlock
)(updates
);
600 CF_RETURNS_RETAINED CFArrayRef
SOSCloudKeychainHandleUpdateCircle(CFDictionaryRef updates
)
602 CFArrayRef result
= NULL
;
603 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
604 if (cTransportRef
->itemsChangedBlock
)
605 result
= ((CloudItemsChangedBlock
)cTransportRef
->itemsChangedBlock
)(updates
);
609 CF_RETURNS_RETAINED CFArrayRef
SOSCloudKeychainHandleUpdateMessage(CFDictionaryRef updates
)
611 CFArrayRef result
= NULL
;
612 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
613 if (cTransportRef
->itemsChangedBlock
)
614 result
= ((CloudItemsChangedBlock
)cTransportRef
->itemsChangedBlock
)(updates
);
619 void SOSCloudKeychainGetObjectsFromCloud(CFArrayRef keysToGet
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
621 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
623 cTransportRef
->get(cTransportRef
, keysToGet
, processQueue
, replyBlock
);
626 void SOSCloudKeychainGetAllObjectsFromCloud(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
628 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
630 cTransportRef
->getAll(cTransportRef
, processQueue
, replyBlock
);
633 void SOSCloudKeychainSynchronizeAndWait(CFArrayRef keysToGet
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
635 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
637 cTransportRef
->synchronizeAndWait(cTransportRef
, keysToGet
, processQueue
, replyBlock
);
641 void SOSCloudKeychainSynchronize(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
643 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
645 cTransportRef
->synchronize(cTransportRef
, processQueue
, replyBlock
);
649 void SOSCloudKeychainClearAll(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
651 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
653 cTransportRef
->clearAll(cTransportRef
, processQueue
, replyBlock
);
656 void SOSCloudKeychainRemoveObjectForKey(CFStringRef keyToRemove
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
658 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
660 cTransportRef
->removeObjectForKey(cTransportRef
, keyToRemove
, processQueue
, replyBlock
);
663 void SOSCloudKeychainRequestSyncWithAllPeers(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
665 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
667 cTransportRef
->requestSyncWithAllPeers(cTransportRef
, processQueue
, replyBlock
);
670 void SOSCloudKeychainRequestEnsurePeerRegistration(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
672 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
674 cTransportRef
->requestEnsurePeerRegistration(cTransportRef
, processQueue
, replyBlock
);
677 void SOSCloudKeychainFlush(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
679 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
681 cTransportRef
->flush(cTransportRef
, processQueue
, replyBlock
);