2 * Copyright (c) 2013-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 #include "iCloudKeychainTrace.h"
26 #include <TargetConditionals.h>
28 #include "SecCFWrappers.h"
30 #include <CoreFoundation/CoreFoundation.h>
32 const CFStringRef kNumberOfiCloudKeychainPeers
= CFSTR("numberOfPeers");
33 const CFStringRef kNumberOfiCloudKeychainItemsBeingSynced
= CFSTR("numberOfItemsBeingSynced");
34 const CFStringRef kCloudKeychainNumberOfSyncingConflicts
= CFSTR("conflictsCount");
35 const CFStringRef kCloudKeychainNumberOfTimesSyncFailed
= CFSTR("syncFailureCount");
36 const CFStringRef kCloudKeychainNumberOfConflictsResolved
= CFSTR("conflictsResolved");
37 const CFStringRef kCloudKeychainNumberOfTimesSyncedWithPeers
= CFSTR("syncedWithPeers");
39 #if !TARGET_IPHONE_SIMULATOR
40 static const char* gTopLevelKeyForiCloudKeychainTracing
= "com.apple.icdp";
43 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR))
46 static const char* gMessageTracerSetPrefix
= "com.apple.message.";
48 static const char* gMessageTracerDomainField
= "com.apple.message.domain";
50 /* --------------------------------------------------------------------------
51 Function: OSX_BeginCloudKeychainLoggingTransaction
53 Description: For OSX the message tracer back end wants its logging
54 done in "bunches". This function allows for beginning
55 a 'transaction' of logging which will allow for putting
56 all of the transactions items into a single log making
57 the message tracer folks happy.
59 The work of this function is to create the aslmsg context
60 and set the domain field and then return the aslmsg
62 -------------------------------------------------------------------------- */
63 static void* OSX_BeginCloudKeychainLoggingTransaction()
67 mAsl
= asl_new(ASL_TYPE_MSG
);
73 asl_set(mAsl
, gMessageTracerDomainField
, gTopLevelKeyForiCloudKeychainTracing
);
75 result
= (void *)mAsl
;
79 /* --------------------------------------------------------------------------
80 Function: OSX_AddKeyValuePairToKeychainLoggingTransaction
82 Description: Once a call to OSX_BeginCloudKeychainLoggingTransaction
83 is done, this call all allow for adding items to the
84 "bunch" of items being logged.
86 NOTE: The key should be a simple key such as
87 "numberOfPeers". This is because this function will
88 apptend the required prefix of "com.apple.message."
89 -------------------------------------------------------------------------- */
90 static bool OSX_AddKeyValuePairToKeychainLoggingTransaction(void* token
, CFStringRef key
, int64_t value
)
92 if (NULL
== token
|| NULL
== key
)
97 aslmsg mAsl
= (aslmsg
)token
;
100 CFStringRef real_key
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%s%@"), gMessageTracerSetPrefix
, key
);
101 if (NULL
== real_key
)
106 CFIndex key_length
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(real_key
), kCFStringEncodingUTF8
);
107 key_length
+= 1; // For null
108 char key_buffer
[key_length
];
109 memset(key_buffer
, 0,key_length
);
110 if (!CFStringGetCString(real_key
, key_buffer
, key_length
, kCFStringEncodingUTF8
))
117 CFStringRef value_str
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%lld"), value
);
118 if (NULL
== value_str
)
123 CFIndex value_str_numBytes
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(value_str
), kCFStringEncodingUTF8
);
124 value_str_numBytes
+= 1; // For null
125 char value_buffer
[value_str_numBytes
];
126 memset(value_buffer
, 0, value_str_numBytes
);
127 if (!CFStringGetCString(value_str
, value_buffer
, value_str_numBytes
, kCFStringEncodingUTF8
))
129 CFRelease(value_str
);
132 CFRelease(value_str
);
134 asl_set(mAsl
, key_buffer
, value_buffer
);
138 /* --------------------------------------------------------------------------
139 Function: OSX_CloseCloudKeychainLoggingTransaction
141 Description: Once a call to OSX_BeginCloudKeychainLoggingTransaction
142 is done, and all of the items that are to be in the
143 "bunch" of items being logged, this function will do the
144 real logging and free the aslmsg context.
145 -------------------------------------------------------------------------- */
146 static void OSX_CloseCloudKeychainLoggingTransaction(void* token
)
150 aslmsg mAsl
= (aslmsg
)token
;
151 asl_log(NULL
, mAsl
, ASL_LEVEL_NOTICE
, "");
156 /* --------------------------------------------------------------------------
157 Function: OSX_SetCloudKeychainTraceValueForKey
159 Description: If "bunching" of items either cannot be done or is not
160 desired, then this 'single shot' function shold be used.
161 It will create the aslmsg context, register the domain
162 fix up the key and log the key value pair and then
163 do the real logging and free the aslmsg context.
164 -------------------------------------------------------------------------- */
165 static bool OSX_SetCloudKeychainTraceValueForKey(CFStringRef key
, int64_t value
)
175 mAsl
= asl_new(ASL_TYPE_MSG
);
182 CFStringRef real_key
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%s%@"), gMessageTracerSetPrefix
, key
);
183 if (NULL
== real_key
)
188 CFIndex key_length
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(real_key
), kCFStringEncodingUTF8
);
189 key_length
+= 1; // For null
190 char key_buffer
[key_length
];
191 memset(key_buffer
, 0,key_length
);
192 if (!CFStringGetCString(real_key
, key_buffer
, key_length
, kCFStringEncodingUTF8
))
200 CFStringRef value_str
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%lld"), value
);
201 if (NULL
== value_str
)
207 CFIndex value_str_numBytes
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(value_str
), kCFStringEncodingUTF8
);
208 value_str_numBytes
+= 1; // For null
209 char value_buffer
[value_str_numBytes
];
210 memset(value_buffer
, 0, value_str_numBytes
);
211 if (!CFStringGetCString(value_str
, value_buffer
, value_str_numBytes
, kCFStringEncodingUTF8
))
214 CFRelease(value_str
);
217 CFRelease(value_str
);
219 asl_set(mAsl
, gMessageTracerDomainField
, gTopLevelKeyForiCloudKeychainTracing
);
221 asl_set(mAsl
, key_buffer
, value_buffer
);
222 asl_log(NULL
, mAsl
, ASL_LEVEL_NOTICE
, "%s is %lld", key_buffer
, value
);
229 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
231 typedef void (*type_ADClientClearScalarKey
)(CFStringRef key
);
232 typedef void (*type_ADClientSetValueForScalarKey
)(CFStringRef key
, int64_t value
);
234 static type_ADClientClearScalarKey gADClientClearScalarKey
= NULL
;
235 static type_ADClientSetValueForScalarKey gADClientSetValueForScalarKey
= NULL
;
237 static dispatch_once_t gADFunctionPointersSet
= 0;
238 static CFBundleRef gAggdBundleRef
= NULL
;
239 static bool gFunctionPointersAreLoaded
= false;
241 /* --------------------------------------------------------------------------
242 Function: InitializeADFunctionPointers
244 Description: Linking to the Aggregate library causes a build cycle so
245 This function will dynamically load the needed function
247 -------------------------------------------------------------------------- */
248 static bool InitializeADFunctionPointers()
250 if (gFunctionPointersAreLoaded
)
252 return gFunctionPointersAreLoaded
;
255 dispatch_once(&gADFunctionPointersSet
,
257 CFStringRef path_to_aggd_framework
= CFSTR("/System/Library/PrivateFrameworks/AggregateDictionary.framework");
259 CFURLRef aggd_url
= CFURLCreateWithFileSystemPath(kCFAllocatorDefault
, path_to_aggd_framework
, kCFURLPOSIXPathStyle
, true);
261 if (NULL
!= aggd_url
)
263 gAggdBundleRef
= CFBundleCreate(kCFAllocatorDefault
, aggd_url
);
264 if (NULL
!= gAggdBundleRef
)
266 gADClientClearScalarKey
= (type_ADClientClearScalarKey
)
267 CFBundleGetFunctionPointerForName(gAggdBundleRef
, CFSTR("ADClientClearScalarKey"));
269 gADClientSetValueForScalarKey
= (type_ADClientSetValueForScalarKey
)
270 CFBundleGetFunctionPointerForName(gAggdBundleRef
, CFSTR("ADClientSetValueForScalarKey"));
276 gFunctionPointersAreLoaded
= ((NULL
!= gADClientClearScalarKey
) && (NULL
!= gADClientSetValueForScalarKey
));
277 return gFunctionPointersAreLoaded
;
280 /* --------------------------------------------------------------------------
281 Function: Internal_ADClientClearScalarKey
283 Description: This fucntion is a wrapper around calling the
284 ADClientClearScalarKey function.
286 NOTE: The key should be a simple key such as
287 "numberOfPeers". This is because this function will
288 apptend the required prefix of "com.apple.cloudkeychain"
289 -------------------------------------------------------------------------- */
290 static void Internal_ADClientClearScalarKey(CFStringRef key
)
292 if (InitializeADFunctionPointers())
294 CFStringRef real_key
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%s.%@"), gTopLevelKeyForiCloudKeychainTracing
, key
);
295 if (NULL
== real_key
)
300 gADClientClearScalarKey(real_key
);
305 /* --------------------------------------------------------------------------
306 Function: Internal_ADClientSetValueForScalarKey
308 Description: This fucntion is a wrapper around calling the
309 ADClientSetValueForScalarKey function.
311 NOTE: The key should be a simple key such as
312 "numberOfPeers". This is because this function will
313 apptend the required prefix of "com.apple.cloudkeychain"
314 -------------------------------------------------------------------------- */
315 static void Internal_ADClientSetValueForScalarKey(CFStringRef key
, int64_t value
)
317 if (InitializeADFunctionPointers())
319 CFStringRef real_key
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%s.%@"), gTopLevelKeyForiCloudKeychainTracing
, key
);
320 if (NULL
== real_key
)
325 gADClientSetValueForScalarKey(real_key
, value
);
331 /* --------------------------------------------------------------------------
332 Function: iOS_SetCloudKeychainTraceValueForKey
334 Description: This fucntion is a wrapper around calling either
335 ADClientSetValueForScalarKey or ADClientClearScalarKey
336 depending on if the value is 0.
338 NOTE: The key should be a simple key such as
339 "numberOfPeers". This is because this function will
340 apptend the required prefix of "com.apple.cloudkeychain"
341 -------------------------------------------------------------------------- */
342 static bool iOS_SetCloudKeychainTraceValueForKey(CFStringRef key
, int64_t value
)
351 Internal_ADClientClearScalarKey(key
);
355 Internal_ADClientSetValueForScalarKey(key
, value
);
360 /* --------------------------------------------------------------------------
361 Function: iOS_AddKeyValuePairToKeychainLoggingTransaction
363 Description: For iOS the is no "bunching" This function will simply
364 call iOS_SetCloudKeychainTraceValueForKey to log the
366 -------------------------------------------------------------------------- */
367 static bool iOS_AddKeyValuePairToKeychainLoggingTransaction(void* token
, CFStringRef key
, int64_t value
)
369 #pragma unused(token)
370 return iOS_SetCloudKeychainTraceValueForKey(key
, value
);
374 /* --------------------------------------------------------------------------
375 Function: SetCloudKeychainTraceValueForKey
377 Description: SPI to log a single key value pair with the logging system
378 -------------------------------------------------------------------------- */
379 bool SetCloudKeychainTraceValueForKey(CFStringRef key
, int64_t value
)
381 #if (TARGET_IPHONE_SIMULATOR)
385 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
386 return OSX_SetCloudKeychainTraceValueForKey(key
, value
);
389 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
390 return iOS_SetCloudKeychainTraceValueForKey(key
, value
);
394 /* --------------------------------------------------------------------------
395 Function: BeginCloudKeychainLoggingTransaction
397 Description: SPI to begin a logging transaction
398 -------------------------------------------------------------------------- */
399 void* BeginCloudKeychainLoggingTransaction()
401 #if (TARGET_IPHONE_SIMULATOR)
405 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
406 return OSX_BeginCloudKeychainLoggingTransaction();
409 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
414 /* --------------------------------------------------------------------------
415 Function: AddKeyValuePairToKeychainLoggingTransaction
417 Description: SPI to add a key value pair to an outstanding logging
419 -------------------------------------------------------------------------- */
420 bool AddKeyValuePairToKeychainLoggingTransaction(void* token
, CFStringRef key
, int64_t value
)
422 #if (TARGET_IPHONE_SIMULATOR)
426 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
427 return OSX_AddKeyValuePairToKeychainLoggingTransaction(token
, key
, value
);
430 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
431 return iOS_AddKeyValuePairToKeychainLoggingTransaction(token
, key
, value
);
435 /* --------------------------------------------------------------------------
436 Function: CloseCloudKeychainLoggingTransaction
438 Description: SPI to complete a logging transaction and clean up the
440 -------------------------------------------------------------------------- */
441 void CloseCloudKeychainLoggingTransaction(void* token
)
443 #if (TARGET_IPHONE_SIMULATOR)
447 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
448 OSX_CloseCloudKeychainLoggingTransaction(token
);
451 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)