5 // Created by local on 7/20/13.
9 #include <CoreFoundation/CoreFoundation.h>
11 #import "SOSCloudCircle.h"
12 #import <Security/Security.h>
14 static const CFStringRef gMessageTracerPrefix
= CFSTR("com.apple.message.");
15 static const CFStringRef gClientIsUsingiCloudKeychainSyncing
= CFSTR("com.apple.icloudkeychain.deviceIsUsingICloudKeychain");
16 static const CFStringRef gNumberOfPeers
= CFSTR("com.apple.icloudkeychain.numberOfPeers");
17 static const CFStringRef gNumberOfItemsBeingSynced
= CFSTR("com.apple.icloudkeychain.numberOfItemsBeingSynced");
19 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
20 static const char* gTopLevelKeyForiCloudKeychainTracing
= "com.apple.icloudkeychain";
23 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
24 static const char* gTopLevelKeyForiCloudKeychainTracing
= "com.apple.icloudkeychain";
27 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR))
31 static bool OSX_SetCloudKeychainTraceValueForKey(CFStringRef key
, int64_t value
)
41 mAsl
= asl_new(ASL_TYPE_MSG
);
48 CFStringRef key_str
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%@%@"), gMessageTracerPrefix
, key
);
55 CFStringRef value_str
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%lld"), value
);
56 if (NULL
== value_str
)
63 CFIndex key_str_numBytes
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(key_str
), kCFStringEncodingUTF8
);
64 key_str_numBytes
+= 1; // For null
65 char key_buffer
[key_str_numBytes
];
66 memset(key_buffer
, 0, key_str_numBytes
);
67 if (!CFStringGetCString(key_str
, key_buffer
, key_str_numBytes
, kCFStringEncodingUTF8
))
76 CFIndex value_str_numBytes
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(value_str
), kCFStringEncodingUTF8
);
77 value_str_numBytes
+= 1; // For null
78 char value_buffer
[value_str_numBytes
];
79 memset(value_buffer
, 0, value_str_numBytes
);
80 if (!CFStringGetCString(value_str
, value_buffer
, value_str_numBytes
, kCFStringEncodingUTF8
))
88 asl_set(mAsl
, key_buffer
, value_buffer
);
89 asl_log(NULL
, mAsl
, ASL_LEVEL_NOTICE
, "%s", gTopLevelKeyForiCloudKeychainTracing
);
95 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
96 #import <AggregateDictionary/ADClient.h>
98 static bool iOS_SetCloudKeychainTraceValueForKey(CFStringRef key
, int64_t value
)
107 ADClientClearScalarKey(key
);
110 ADClientSetValueForScalarKey(key
, value
);
115 static bool ClientIsInCircle()
118 CFErrorRef error
= NULL
;
119 SOSCCStatus status
= kSOSCCError
;
121 status
= SOSCCThisDeviceIsInCircle(&error
);
136 // kSOSCCRequestPending
137 // While this device will be in a circle, it is not in
138 // one yet. For now, this will be treated as if the device
139 // was not in a circle and will wait for the device to
140 // be in a circle and have that turn on this daemon with
142 case kSOSCCRequestPending
:
143 case kSOSCCCircleAbsent
:
153 static bool sendTraceMessage(CFStringRef key
, int64_t value
)
156 #if (TARGET_IPHONE_SIMULATOR)
160 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
161 return OSX_SetCloudKeychainTraceValueForKey(key
, value
);
164 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
165 return iOS_SetCloudKeychainTraceValueForKey(key
, value
);
170 static int64_t GetNumberOfPeers()
172 int64_t result
= 0LL;
174 CFErrorRef error
= NULL
;
175 CFArrayRef peers
= NULL
;
177 peers
= SOSCCCopyPeerPeerInfo(&error
);
190 result
= (int64_t)CFArrayGetCount(peers
);
197 static int64_t GetNumberOfItemsBeingSyncedForType(CFTypeRef
class)
201 CFTypeRef keys
[] = {kSecClass
, kSecAttrSynchronizable
, kSecMatchLimit
, kSecReturnAttributes
};
202 CFTypeRef values
[] = {class, kCFBooleanTrue
, kSecMatchLimitAll
, kCFBooleanTrue
};
204 CFDictionaryRef query
= CFDictionaryCreate(kCFAllocatorDefault
, (const void **)keys
, (const void **)values
, (sizeof(keys
)/sizeof(keys
[0])), &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
211 CFArrayRef query_result
= NULL
;
212 OSStatus status
= SecItemCopyMatching(query
, (CFTypeRef
*)&query_result
);
214 if (noErr
!= status
|| NULL
== query_result
)
216 if (NULL
!= query_result
)
218 CFRelease(query_result
);
223 result
= (int64_t)CFArrayGetCount(query_result
);
224 CFRelease(query_result
);
228 static int64_t GetNumberOfItemsBeingSynced()
232 result
= GetNumberOfItemsBeingSyncedForType(kSecClassInternetPassword
);
233 result
+= GetNumberOfItemsBeingSyncedForType(kSecClassGenericPassword
);
239 int main(int argc
, const char * argv
[])
242 if (!ClientIsInCircle())
244 // This will clear the value in the backend database if it had been previously set
245 sendTraceMessage(gClientIsUsingiCloudKeychainSyncing
, value
);
250 sendTraceMessage(gClientIsUsingiCloudKeychainSyncing
, value
);
252 value
= GetNumberOfPeers();
253 sendTraceMessage(gNumberOfPeers
, value
);
255 value
= GetNumberOfItemsBeingSynced();
256 sendTraceMessage(gNumberOfItemsBeingSynced
, value
);