SOSCloudKeychainClient.c [plain text]
#include <AssertMacros.h>
#include <xpc/xpc.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFXPCBridge.h>
#include <sysexits.h>
#include <syslog.h>
#include <CoreFoundation/CFUserNotification.h>
#include <utilities/debugging.h>
#include <utilities/SecCFWrappers.h>
#include <utilities/SecXPCError.h>
#include "SOSCloudKeychainConstants.h"
#include "SOSCloudKeychainClient.h"
static CFStringRef sErrorDomain = CFSTR("com.apple.security.sos.transport.error");
#define SOSCKCSCOPE "sync"
static SOSCloudTransportRef sTransport = NULL;
static SOSCloudTransportRef SOSCloudTransportCreateXPCTransport(void);
void SOSCloudKeychainSetTransport(SOSCloudTransportRef transport) {
sTransport = transport;
}
static SOSCloudTransportRef SOSCloudTransportDefaultTransport(void)
{
static dispatch_once_t sTransportOnce;
dispatch_once(&sTransportOnce, ^{
if (!sTransport)
SOSCloudKeychainSetTransport(SOSCloudTransportCreateXPCTransport());
});
return sTransport;
}
static CFErrorRef makeError(CFIndex which)
{
CFDictionaryRef userInfo = NULL;
return CFErrorCreate(kCFAllocatorDefault, sErrorDomain, which, userInfo);
}
static void describeXPCObject(char *prefix, xpc_object_t object)
{
if (object)
{
char *desc = xpc_copy_description(object);
secdebug(SOSCKCSCOPE, "%s%s\n", prefix, desc);
free(desc);
}
else
secdebug(SOSCKCSCOPE, "%s<NULL>\n", prefix);
}
static void describeXPCType(char *prefix, xpc_type_t xtype)
{
#ifndef NDEBUG
char msg[256]={0,};
if (XPC_TYPE_CONNECTION == xtype)
strcpy(msg, "XPC_TYPE_CONNECTION");
else if (XPC_TYPE_ERROR == xtype)
strcpy(msg, "XPC_TYPE_ERROR");
else if (XPC_TYPE_DICTIONARY == xtype)
strcpy(msg, "XPC_TYPE_DICTIONARY");
else
strcpy(msg, "<unknown>");
secdebug(SOSCKCSCOPE, "%s type:%s\n", prefix, msg);
#endif
}
typedef struct SOSXPCCloudTransport *SOSXPCCloudTransportRef;
struct SOSXPCCloudTransport
{
struct SOSCloudTransport transport;
xpc_connection_t serviceConnection;
dispatch_queue_t xpc_queue;
};
static bool xpc_event_filter(const xpc_connection_t peer, xpc_object_t event, CFErrorRef *error)
{
secdebug(SOSCKCSCOPE, "handle_connection_event\n");
xpc_type_t xtype = xpc_get_type(event);
describeXPCType("handle_xpc_event", xtype);
if (XPC_TYPE_CONNECTION == xtype)
{
secdebug(SOSCKCSCOPE, "handle_xpc_event: XPC_TYPE_CONNECTION (unexpected)");
describeXPCObject("handle_xpc_event: XPC_TYPE_CONNECTION, obj : ", event);
#if 0
if (error)
*error = makeError(kSOSOUnexpectedConnectionEvent); assert(true);
#endif
}
else
if (XPC_TYPE_ERROR == xtype)
{
#ifndef NDEBUG
const char *estr = xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION);
#endif
secdebug(SOSCKCSCOPE, "default: xpc error: %s\n", estr);
#if 0 // just log for now
CFStringRef errStr = CFStringCreateWithCString(kCFAllocatorDefault, estr, kCFStringEncodingUTF8);
CFMutableDictionaryRef userInfo = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (errStr)
CFDictionaryAddValue(userInfo, kCFErrorLocalizedDescriptionKey, errStr);
if (error)
*error = CFErrorCreate(kCFAllocatorDefault, sErrorDomain, kSOSOXPCErrorEvent, userInfo);
CFReleaseSafe(errStr);
CFReleaseSafe(userInfo);
#endif
}
else
if (XPC_TYPE_DICTIONARY == xtype)
{
secdebug(SOSCKCSCOPE, "received dictionary event %p\n", event);
return true;
}
else
{
secdebug(SOSCKCSCOPE, "default: unexpected connection event %p\n", event);
describeXPCObject("handle_xpc_event: obj : ", event);
if (error)
*error = makeError(kSOSOUnexpectedXPCEvent);
}
return false;
}
static bool handle_xpc_event(SOSXPCCloudTransportRef transport, xpc_object_t event)
{
CFErrorRef localError = NULL;
secerror(">>>>> handle_connection_event via event_handler <<<<<, WTF?");
bool result = false;
if ((result = xpc_event_filter(transport->serviceConnection, event, &localError)))
{
const char *operation = xpc_dictionary_get_string(event, kMessageKeyOperation);
if (!operation || strcmp(operation, kMessageOperationItemChanged)) {
secdebug(SOSCKCSCOPE, "operation: %s", operation);
return result;
}
xpc_object_t xrv = xpc_dictionary_get_value(event, kMessageKeyValue);
if (!xrv)
{
secdebug(SOSCKCSCOPE, "xrv null for kMessageKeyValue");
return result;
}
describeXPCObject("xrv", xrv);
CFDictionaryRef returnedValues = _CFXPCCreateCFObjectFromXPCObject(xrv);
secdebug(SOSCKCSCOPE, "returnedValues: %@", returnedValues);
SOSCloudKeychainHandleUpdate(returnedValues);
CFReleaseNull(returnedValues);
}
CFReleaseSafe(localError);
return result;
}
static void SOSXPCCloudTransportInit(SOSXPCCloudTransportRef transport)
{
secdebug(SOSCKCSCOPE, "initXPCConnection\n");
transport->xpc_queue = dispatch_queue_create(xpcServiceName, DISPATCH_QUEUE_SERIAL);
transport->serviceConnection = xpc_connection_create_mach_service(xpcServiceName, transport->xpc_queue, 0);
secdebug(SOSCKCSCOPE, "serviceConnection: %p\n", transport->serviceConnection);
xpc_connection_set_event_handler(transport->serviceConnection, ^(xpc_object_t event)
{
secdebug(SOSCKCSCOPE, "xpc_connection_set_event_handler\n");
handle_xpc_event(transport, event);
});
xpc_connection_resume(transport->serviceConnection);
xpc_retain(transport->serviceConnection);
}
static void talkWithKVS(SOSXPCCloudTransportRef transport, xpc_object_t message, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
__block CFErrorRef error = NULL;
__block CFTypeRef object = NULL;
dispatch_block_t callback = ^{
if (replyBlock)
replyBlock(object, error);
if(object)
CFReleaseNull(object);
if (error)
{
secerror("callback error: %@", error);
CFReleaseNull(error);
}
dispatch_release(processQueue);
};
require_action(transport->serviceConnection, xit, error = makeError(kSOSConnectionNotOpen));
require_action(message, xit, error = makeError(kSOSObjectNotFoundError));
dispatch_retain(processQueue);
xpc_connection_send_message_with_reply(transport->serviceConnection, message, transport->xpc_queue, ^(xpc_object_t reply)
{
if (xpc_event_filter(transport->serviceConnection, reply, &error) && reply)
{
describeXPCObject("getValuesFromKVS: reply : ", reply);
if (error)
secerror("Error from xpc_event_filter: %@", error);
xpc_object_t xrv = xpc_dictionary_get_value(reply, kMessageKeyValue);
if (xrv)
{
describeXPCObject("talkWithKVS: xrv: ", xrv);
object = _CFXPCCreateCFObjectFromXPCObject(xrv); secnotice("talkwithkvs", "converted CF object: %@", object);
}
else
secerror("missing value reply");
xpc_object_t xerror = xpc_dictionary_get_value(reply, kMessageKeyError);
if (xerror)
error = SecCreateCFErrorWithXPCObject(xerror); }
dispatch_async(processQueue, callback);
});
return;
xit:
secerror("talkWithKVS error: %@", error);
if (replyBlock)
dispatch_async(processQueue, callback);
CFReleaseSafe(error);
}
static void SOSCloudTransportSetItemsChangedBlock(SOSCloudTransportRef transport,
CloudItemsChangedBlock itemsChangedBlock) {
if (transport->itemsChangedBlock != itemsChangedBlock)
{
if (transport->itemsChangedBlock)
Block_release(transport->itemsChangedBlock);
transport->itemsChangedBlock = Block_copy(itemsChangedBlock);
}
}
static void SOSCloudTransportPut(SOSCloudTransportRef transport, CFDictionaryRef values, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
secdebug(SOSCKCSCOPE, "%@", values);
CFErrorRef error = NULL;
xpc_object_t message = NULL;
xpc_object_t xobject = NULL;
require_action(values, xit, error = makeError(kSOSObjectNotFoundError));
message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationPUTDictionary);
xobject = _CFXPCCreateXPCObjectFromCFObject(values);
require_action(xobject, xit, error = makeError(kSOSObjectCantBeConvertedToXPCObject));
xpc_dictionary_set_value(message, kMessageKeyValue, xobject);
xpc_release(xobject);
talkWithKVS(xpcTransport, message, processQueue, replyBlock);
xpc_release(message);
return;
xit:
if (replyBlock)
replyBlock(NULL, error);
CFReleaseSafe(error);
}
static void SOSCloudTransportGet(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
secdebug(SOSCKCSCOPE, "%@", keysToGet);
CFErrorRef error = NULL;
xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
xpc_object_t xkeysToGet = keysToGet ? _CFXPCCreateXPCObjectFromCFObject(keysToGet) : xpc_null_create();
require_action(xkeysToGet, xit, error = makeError(kSOSObjectNotFoundError));
if (keysToGet) xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToGet);
xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationGETv2);
xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
talkWithKVS(xpcTransport, message, processQueue, replyBlock);
xpc_release(xkeysToGet);
xpc_release(xkeysOfInterest);
xpc_release(message);
return;
xit:
if(xkeysOfInterest)
xpc_release(xkeysOfInterest);
if(xkeysToGet)
xpc_release(xkeysToGet);
if (replyBlock)
replyBlock(NULL, error);
CFReleaseSafe(error);
}
static void SOSCloudTransportRegisterKeys(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock, CloudItemsChangedBlock notificationBlock)
{
SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
secdebug(SOSCKCSCOPE, "%@", keysToGet);
xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
xpc_object_t xkeysToRegister = keysToGet ? _CFXPCCreateXPCObjectFromCFObject(keysToGet) : xpc_null_create();
xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToRegister);
xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationRegisterKeysAndGet);
xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
SOSCloudTransportSetItemsChangedBlock(transport, notificationBlock);
talkWithKVS(xpcTransport, message, processQueue, replyBlock);
xpc_release(xkeysOfInterest);
xpc_release(xkeysToRegister);
xpc_release(message);
}
static void SecXPCDictionarySetCFObject(xpc_object_t xdict, const char *key, CFTypeRef object)
{
xpc_object_t xpc_obj = object ? _CFXPCCreateXPCObjectFromCFObject(object) : xpc_null_create();
xpc_dictionary_set_value(xdict, key, xpc_obj);
xpc_release(xpc_obj);
}
static bool SOSCloudTransportUpdateKeys(SOSCloudTransportRef transport,
bool getNewKeysOnly,
CFArrayRef alwaysKeys,
CFArrayRef afterFirstUnlockKeys,
CFArrayRef unlockedKeys,
CFErrorRef *error)
{
__block bool success = true;
dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
CloudKeychainReplyBlock replyBlock = ^(CFDictionaryRef returnedValues, CFErrorRef returnedError)
{
if (returnedError) {
success = false;
if (error) {
*error = returnedError;
CFRetain(*error);
}
}
CFReleaseSafe(returnedError);
};
SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_bool(xkeysOfInterest, kMessageKeyGetNewKeysOnly, getNewKeysOnly);
SecXPCDictionarySetCFObject(xkeysOfInterest, kMessageKeyKeysToGet, alwaysKeys);
SecXPCDictionarySetCFObject(xkeysOfInterest, kMessageKeyKeysRequireFirstUnlock, afterFirstUnlockKeys);
SecXPCDictionarySetCFObject(xkeysOfInterest, kMessageKeyKeysRequiresUnlocked, unlockedKeys);
xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationRegisterKeysAndGet);
xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
talkWithKVS(xpcTransport, message, processQueue, replyBlock);
xpc_release(message);
xpc_release(xkeysOfInterest);
return success;
}
static void SOSCloudTransportUnregisterKeys(SOSCloudTransportRef transport, CFArrayRef keysToUnregister, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
secdebug(SOSCKCSCOPE, "%@", keysToUnregister);
xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
xpc_object_t xkeysToUnregister = keysToUnregister ? _CFXPCCreateXPCObjectFromCFObject(keysToUnregister) : xpc_null_create();
xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToUnregister);
xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationUnregisterKeys);
xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
talkWithKVS(xpcTransport, message, processQueue, replyBlock);
xpc_release(xkeysOfInterest);
xpc_release(xkeysToUnregister);
xpc_release(message);
}
static void SOSCloudTransportGetAll(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
secdebug(SOSCKCSCOPE, "start");
SOSCloudTransportGet(transport, NULL, processQueue, replyBlock);
}
static void SOSCloudTransportSync(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
secdebug(SOSCKCSCOPE, "start");
xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationSynchronize);
talkWithKVS(xpcTransport, message, processQueue, replyBlock);
xpc_release(message);
}
static void SOSCloudTransportSyncAndWait(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
secdebug(SOSCKCSCOPE, "%@", keysToGet);
xpc_object_t xkeysOfInterest = xpc_dictionary_create(NULL, NULL, 0);
xpc_object_t xkeysToRegister = keysToGet ? _CFXPCCreateXPCObjectFromCFObject(keysToGet) : xpc_null_create();
xpc_dictionary_set_value(xkeysOfInterest, kMessageKeyKeysToGet, xkeysToRegister);
xpc_release(xkeysToRegister);
xkeysToRegister = NULL;
xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationSynchronizeAndWait);
xpc_dictionary_set_value(message, kMessageKeyValue, xkeysOfInterest);
xpc_release(xkeysOfInterest);
xkeysOfInterest = NULL;
talkWithKVS(xpcTransport, message, processQueue, replyBlock);
xpc_release(message);
}
static void SOSCloudTransportClearAll(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
secdebug(SOSCKCSCOPE, "start");
xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationClearStore);
talkWithKVS(xpcTransport, message, processQueue, replyBlock);
xpc_release(message);
}
static void SOSCloudTransportRemoveObjectForKey(SOSCloudTransportRef transport, CFStringRef keyToRemove, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
secdebug(SOSCKCSCOPE, "start");
CFErrorRef error = NULL;
xpc_object_t message = NULL;
xpc_object_t xkeytoremove = NULL;
require_action(keyToRemove, xit, error = makeError(kSOSObjectNotFoundError));
message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(message, kMessageKeyVersion, kCKDXPCVersion);
xpc_dictionary_set_string(message, kMessageKeyOperation, kOperationRemoveObjectForKey);
xkeytoremove = _CFXPCCreateXPCObjectFromCFObject(keyToRemove);
require_action(xkeytoremove, xit, error = makeError(kSOSObjectCantBeConvertedToXPCObject));
xpc_dictionary_set_value(message, kMessageKeyKey, xkeytoremove);
xpc_release(xkeytoremove);
talkWithKVS(xpcTransport, message, processQueue, replyBlock);
xpc_release(message);
return;
xit:
if(xkeytoremove)
xpc_release(xkeytoremove);
if(message)
xpc_release(message);
if (replyBlock)
replyBlock(NULL, error);
CFReleaseSafe(error);
}
static void SOSCloudTransportLocalNotification(SOSCloudTransportRef transport, CFStringRef messageToUser, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
secdebug(SOSCKCSCOPE, "start");
xpc_object_t xLocalNotificationDict = xpc_dictionary_create(NULL, NULL, 0);
char *headerKey = CFStringToCString(kCFUserNotificationAlertHeaderKey);
char *message = CFStringToCString(messageToUser);
xpc_dictionary_set_string(xLocalNotificationDict, headerKey, message);
xpc_object_t xpcmessage = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(xpcmessage, kMessageKeyVersion, kCKDXPCVersion);
xpc_dictionary_set_string(xpcmessage, kMessageKeyOperation, kOperationUILocalNotification);
xpc_dictionary_set_value (xpcmessage, kMessageKeyValue, xLocalNotificationDict);
xpc_release(xLocalNotificationDict);
talkWithKVS(xpcTransport, xpcmessage, processQueue, replyBlock);
free(headerKey);
free(message);
xpc_release(xpcmessage);
}
static void SOSCloudTransportSetParams(SOSCloudTransportRef transport, CFDictionaryRef paramsDict, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
secdebug(SOSCKCSCOPE, "start");
SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
xpc_object_t xParamsDict = paramsDict ? _CFXPCCreateXPCObjectFromCFObject(paramsDict) : xpc_null_create();
xpc_object_t xpcmessage = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(xpcmessage, kMessageKeyVersion, kCKDXPCVersion);
xpc_dictionary_set_string(xpcmessage, kMessageKeyOperation, kOperationSetParams);
xpc_dictionary_set_value (xpcmessage, kMessageKeyValue, xParamsDict);
xpc_release(xParamsDict);
talkWithKVS(xpcTransport, xpcmessage, processQueue, replyBlock);
xpc_release(xpcmessage);
}
static void SOSCloudTransportRequestSyncWithAllPeers(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
secdebug(SOSCKCSCOPE, "start");
SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport;
xpc_object_t xpcmessage = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(xpcmessage, kMessageKeyVersion, kCKDXPCVersion);
xpc_dictionary_set_string(xpcmessage, kMessageKeyOperation, kOperationRequestSyncWithAllPeers);
talkWithKVS(xpcTransport, xpcmessage, processQueue, replyBlock);
xpc_release(xpcmessage);
}
static SOSCloudTransportRef SOSCloudTransportCreateXPCTransport(void)
{
SOSXPCCloudTransportRef st;
st = calloc(1, sizeof(*st));
st->transport.put = SOSCloudTransportPut;
st->transport.registerKeys = SOSCloudTransportRegisterKeys;
st->transport.updateKeys = SOSCloudTransportUpdateKeys;
st->transport.unregisterKeys = SOSCloudTransportUnregisterKeys;
st->transport.get = SOSCloudTransportGet;
st->transport.getAll = SOSCloudTransportGetAll;
st->transport.synchronize = SOSCloudTransportSync;
st->transport.synchronizeAndWait = SOSCloudTransportSyncAndWait;
st->transport.clearAll = SOSCloudTransportClearAll;
st->transport.removeObjectForKey = SOSCloudTransportRemoveObjectForKey;
st->transport.localNotification = SOSCloudTransportLocalNotification;
st->transport.setParams = SOSCloudTransportSetParams;
st->transport.requestSyncWithAllPeers = SOSCloudTransportRequestSyncWithAllPeers;
SOSXPCCloudTransportInit(st);
return &st->transport;
}
void SOSCloudKeychainSetItemsChangedBlock(CloudItemsChangedBlock itemsChangedBlock)
{
secdebug(SOSCKCSCOPE, "start");
SOSCloudTransportSetItemsChangedBlock(SOSCloudTransportDefaultTransport(),
itemsChangedBlock);
}
void SOSCloudKeychainPutObjectsInCloud(CFDictionaryRef objects, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
cTransportRef->put(cTransportRef, objects, processQueue, replyBlock);
}
void SOSCloudKeychainRegisterKeysAndGet(CFArrayRef keysToRegister, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock, CloudItemsChangedBlock notificationBlock)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
cTransportRef->registerKeys(cTransportRef, keysToRegister, processQueue, replyBlock, notificationBlock);
}
bool SOSCloudKeychainUpdateKeys(bool getNewKeysOnly,
CFArrayRef alwaysKeys,
CFArrayRef afterFirstUnlockKeys,
CFArrayRef unlockedKeys,
CFErrorRef *error)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
return cTransportRef->updateKeys(cTransportRef, getNewKeysOnly, alwaysKeys, afterFirstUnlockKeys, unlockedKeys, error);
return false;
}
void SOSCloudKeychainUnRegisterKeys(CFArrayRef keysToUnregister, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
cTransportRef->unregisterKeys(cTransportRef, keysToUnregister, processQueue, replyBlock);
}
void SOSCloudKeychainHandleUpdate(CFDictionaryRef updates)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef->itemsChangedBlock)
((CloudItemsChangedBlock)cTransportRef->itemsChangedBlock)(updates);
}
void SOSCloudKeychainGetObjectsFromCloud(CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
cTransportRef->get(cTransportRef, keysToGet, processQueue, replyBlock);
}
void SOSCloudKeychainGetAllObjectsFromCloud(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
cTransportRef->getAll(cTransportRef, processQueue, replyBlock);
}
void SOSCloudKeychainSynchronizeAndWait(CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
cTransportRef->synchronizeAndWait(cTransportRef, keysToGet, processQueue, replyBlock);
}
void SOSCloudKeychainSynchronize(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
cTransportRef->synchronize(cTransportRef, processQueue, replyBlock);
}
void SOSCloudKeychainClearAll(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
cTransportRef->clearAll(cTransportRef, processQueue, replyBlock);
}
void SOSCloudKeychainRemoveObjectForKey(CFStringRef keyToRemove, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
cTransportRef->removeObjectForKey(cTransportRef, keyToRemove, processQueue, replyBlock);
}
void SOSCloudKeychainUserNotification(CFStringRef messageToUser, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
cTransportRef->localNotification(cTransportRef, messageToUser, processQueue, replyBlock);
}
void SOSCloudKeychainSetParams(CFDictionaryRef paramsDict, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
cTransportRef->setParams(cTransportRef, paramsDict, processQueue, replyBlock);
}
void SOSCloudKeychainRequestSyncWithAllPeers(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock)
{
SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport();
if (cTransportRef)
cTransportRef->requestSyncWithAllPeers(cTransportRef, processQueue, replyBlock);
}
void SOSCloudKeychainSetCallbackMethodXPC(void)
{
CFDictionaryRef paramsDict = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
kParamCallbackMethod, kParamCallbackMethodXPC, NULL);
dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
SOSCloudKeychainSetParams(paramsDict, processQueue, ^(CFDictionaryRef returnedValues, CFErrorRef error)
{
secerror("set params called back");
});
CFReleaseSafe(paramsDict);
}