iCloudKeychainTrace.c [plain text]
#include "iCloudKeychainTrace.h"
#include <TargetConditionals.h>
#include <inttypes.h>
#include "SecCFWrappers.h"
#include <sys/time.h>
#include <CoreFoundation/CoreFoundation.h>
const CFStringRef kNumberOfiCloudKeychainPeers = CFSTR("numberOfPeers");
const CFStringRef kNumberOfiCloudKeychainItemsBeingSynced = CFSTR("numberOfItemsBeingSynced");
const CFStringRef kCloudKeychainNumberOfSyncingConflicts = CFSTR("conflictsCount");
const CFStringRef kCloudKeychainNumberOfTimesSyncFailed = CFSTR("syncFailureCount");
const CFStringRef kCloudKeychainNumberOfConflictsResolved = CFSTR("conflictsResolved");
const CFStringRef kCloudKeychainNumberOfTimesSyncedWithPeers = CFSTR("syncedWithPeers");
#if !TARGET_IPHONE_SIMULATOR
#if TARGET_OS_IPHONE
static const char* gTopLevelKeyForiCloudKeychainTracing = "com.apple.icdp";
#else
static const char* gTopLevelKeyForiCloudKeychainTracing = "com.apple.icdp.KeychainStats";
#endif
#endif
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR))
#include <msgtracer_client.h>
struct msgtracer_instance {
msgtracer_msg_t message;
msgtracer_domain_t domain;
};
static const char* gMessageTracerSetPrefix = "com.apple.message.";
static void *OSX_BeginCloudKeychainLoggingTransaction()
{
struct msgtracer_instance *instance = calloc(1, sizeof *instance);
if (!instance) {
return NULL;
}
instance->domain = msgtracer_domain_new(gTopLevelKeyForiCloudKeychainTracing);
if (instance->domain) {
instance->message = msgtracer_msg_new(instance->domain);
if (instance->message) {
return (void *)instance;
}
msgtracer_domain_free(instance->domain);
}
free(instance);
return NULL;
}
static bool OSX_AddKeyValuePairToKeychainLoggingTransaction(void *token, CFStringRef key, int64_t value)
{
if (NULL == token || NULL == key)
{
return false;
}
struct msgtracer_instance *instance = (struct msgtracer_instance *)token;
msgtracer_msg_t msg = instance->message;
CFStringRef real_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s%@"), gMessageTracerSetPrefix, key);
if (NULL == real_key)
{
return false;
}
CFIndex key_length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(real_key), kCFStringEncodingUTF8);
key_length += 1; char key_buffer[key_length];
memset(key_buffer, 0, key_length);
if (!CFStringGetCString(real_key, key_buffer, key_length, kCFStringEncodingUTF8))
{
CFRelease(real_key);
return false;
}
CFRelease(real_key);
CFStringRef value_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%lld"), value);
if (NULL == value_str)
{
return false;
}
CFIndex value_str_numBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value_str), kCFStringEncodingUTF8);
value_str_numBytes += 1; char value_buffer[value_str_numBytes];
memset(value_buffer, 0, value_str_numBytes);
if (!CFStringGetCString(value_str, value_buffer, value_str_numBytes, kCFStringEncodingUTF8))
{
CFRelease(value_str);
return false;
}
CFRelease(value_str);
msgtracer_set(msg, key_buffer, value_buffer);
return true;
}
static void OSX_CloseCloudKeychainLoggingTransaction(void *token)
{
if (NULL != token)
{
struct msgtracer_instance *instance = (struct msgtracer_instance *)token;
msgtracer_log(instance->message, ASL_LEVEL_NOTICE, "");
msgtracer_msg_free(instance->message);
msgtracer_domain_free(instance->domain);
free(instance);
}
}
static bool OSX_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
{
bool result = false;
if (NULL == key)
{
return result;
}
msgtracer_msg_t message = NULL;
msgtracer_domain_t domain = msgtracer_domain_new(gTopLevelKeyForiCloudKeychainTracing);
if (NULL == domain) {
return result;
}
message = msgtracer_msg_new(domain);
if (NULL == message) {
msgtracer_domain_free(domain);
return result;
}
CFStringRef real_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s%@"), gMessageTracerSetPrefix, key);
if (NULL == real_key)
{
return false;
}
CFIndex key_length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(real_key), kCFStringEncodingUTF8);
key_length += 1; char key_buffer[key_length];
memset(key_buffer, 0,key_length);
if (!CFStringGetCString(real_key, key_buffer, key_length, kCFStringEncodingUTF8))
{
CFRelease(real_key);
return false;
}
CFRelease(real_key);
CFStringRef value_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%lld"), value);
if (NULL == value_str)
{
msgtracer_msg_free(message);
return result;
}
CFIndex value_str_numBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value_str), kCFStringEncodingUTF8);
value_str_numBytes += 1; char value_buffer[value_str_numBytes];
memset(value_buffer, 0, value_str_numBytes);
if (!CFStringGetCString(value_str, value_buffer, value_str_numBytes, kCFStringEncodingUTF8))
{
msgtracer_msg_free(message);
CFRelease(value_str);
return result;
}
CFRelease(value_str);
msgtracer_set(message, key_buffer, value_buffer);
msgtracer_log(message, ASL_LEVEL_NOTICE, "%s is %lld", key_buffer, value);
msgtracer_msg_free(message);
msgtracer_domain_free(domain);
return true;
}
#endif
#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
typedef void (*type_ADClientClearScalarKey)(CFStringRef key);
typedef void (*type_ADClientSetValueForScalarKey)(CFStringRef key, int64_t value);
static type_ADClientClearScalarKey gADClientClearScalarKey = NULL;
static type_ADClientSetValueForScalarKey gADClientSetValueForScalarKey = NULL;
static dispatch_once_t gADFunctionPointersSet = 0;
static CFBundleRef gAggdBundleRef = NULL;
static bool gFunctionPointersAreLoaded = false;
static bool InitializeADFunctionPointers()
{
if (gFunctionPointersAreLoaded)
{
return gFunctionPointersAreLoaded;
}
dispatch_once(&gADFunctionPointersSet,
^{
CFStringRef path_to_aggd_framework = CFSTR("/System/Library/PrivateFrameworks/AggregateDictionary.framework");
CFURLRef aggd_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_to_aggd_framework, kCFURLPOSIXPathStyle, true);
if (NULL != aggd_url)
{
gAggdBundleRef = CFBundleCreate(kCFAllocatorDefault, aggd_url);
if (NULL != gAggdBundleRef)
{
gADClientClearScalarKey = (type_ADClientClearScalarKey)
CFBundleGetFunctionPointerForName(gAggdBundleRef, CFSTR("ADClientClearScalarKey"));
gADClientSetValueForScalarKey = (type_ADClientSetValueForScalarKey)
CFBundleGetFunctionPointerForName(gAggdBundleRef, CFSTR("ADClientSetValueForScalarKey"));
}
CFRelease(aggd_url);
}
});
gFunctionPointersAreLoaded = ((NULL != gADClientClearScalarKey) && (NULL != gADClientSetValueForScalarKey));
return gFunctionPointersAreLoaded;
}
static void Internal_ADClientClearScalarKey(CFStringRef key)
{
if (InitializeADFunctionPointers())
{
CFStringRef real_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s.%@"), gTopLevelKeyForiCloudKeychainTracing, key);
if (NULL == real_key)
{
return;
}
gADClientClearScalarKey(real_key);
CFRelease(real_key);
}
}
static void Internal_ADClientSetValueForScalarKey(CFStringRef key, int64_t value)
{
if (InitializeADFunctionPointers())
{
CFStringRef real_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s.%@"), gTopLevelKeyForiCloudKeychainTracing, key);
if (NULL == real_key)
{
return;
}
gADClientSetValueForScalarKey(real_key, value);
CFRelease(real_key);
}
}
static bool iOS_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
{
if (NULL == key)
{
return false;
}
if (0LL == value)
{
Internal_ADClientClearScalarKey(key);
}
else
{
Internal_ADClientSetValueForScalarKey(key, value);
}
return true;
}
static bool iOS_AddKeyValuePairToKeychainLoggingTransaction(void* token, CFStringRef key, int64_t value)
{
#pragma unused(token)
return iOS_SetCloudKeychainTraceValueForKey(key, value);
}
#endif
bool SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
{
#if (TARGET_IPHONE_SIMULATOR)
return false;
#endif
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
return OSX_SetCloudKeychainTraceValueForKey(key, value);
#endif
#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
return iOS_SetCloudKeychainTraceValueForKey(key, value);
#endif
}
void* BeginCloudKeychainLoggingTransaction()
{
#if (TARGET_IPHONE_SIMULATOR)
return (void *)-1;
#endif
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
return OSX_BeginCloudKeychainLoggingTransaction();
#endif
#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
return NULL;
#endif
}
bool AddKeyValuePairToKeychainLoggingTransaction(void* token, CFStringRef key, int64_t value)
{
#if (TARGET_IPHONE_SIMULATOR)
return false;
#endif
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
return OSX_AddKeyValuePairToKeychainLoggingTransaction(token, key, value);
#endif
#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
return iOS_AddKeyValuePairToKeychainLoggingTransaction(token, key, value);
#endif
}
void CloseCloudKeychainLoggingTransaction(void* token)
{
#if (TARGET_IPHONE_SIMULATOR)
; #endif
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
OSX_CloseCloudKeychainLoggingTransaction(token);
#endif
#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
; #endif
}