]> git.saurik.com Git - apple/security.git/blobdiff - iCloudStat/main.c
Security-57031.1.35.tar.gz
[apple/security.git] / iCloudStat / main.c
diff --git a/iCloudStat/main.c b/iCloudStat/main.c
new file mode 100644 (file)
index 0000000..28c257e
--- /dev/null
@@ -0,0 +1,260 @@
+//
+//  main.c
+//  iCloudStats
+//
+//  Created by local on 7/20/13.
+//
+//
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#import "SOSCloudCircle.h"
+#import <Security/Security.h>
+
+static const CFStringRef gMessageTracerPrefix = CFSTR("com.apple.message.");
+static const CFStringRef gClientIsUsingiCloudKeychainSyncing = CFSTR("com.apple.icloudkeychain.deviceIsUsingICloudKeychain");
+static const CFStringRef gNumberOfPeers = CFSTR("com.apple.icloudkeychain.numberOfPeers");
+static const CFStringRef gNumberOfItemsBeingSynced = CFSTR("com.apple.icloudkeychain.numberOfItemsBeingSynced");
+    
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+static const char* gTopLevelKeyForiCloudKeychainTracing = "com.apple.icloudkeychain";
+#endif
+    
+#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
+static const char* gTopLevelKeyForiCloudKeychainTracing = "com.apple.icloudkeychain";
+#endif
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR))
+#include <asl.h>
+
+
+static bool OSX_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
+{
+       bool result = false;
+       
+       if (NULL == key)
+       {
+               return result;
+       }
+       
+       aslmsg mAsl = NULL;
+       mAsl = asl_new(ASL_TYPE_MSG);
+       if (NULL == mAsl)
+       {
+               return result;
+       }
+    
+    
+    CFStringRef key_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@%@"), gMessageTracerPrefix, key);
+    if (NULL == key_str)
+    {
+        asl_free(mAsl);
+        return result;
+    }
+       
+       CFStringRef value_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%lld"), value);
+    if (NULL == value_str)
+    {
+        asl_free(mAsl);
+        CFRelease(key_str);
+        return result;
+    }
+    
+    CFIndex key_str_numBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key_str), kCFStringEncodingUTF8);
+    key_str_numBytes += 1; // For null
+    char key_buffer[key_str_numBytes];
+    memset(key_buffer, 0, key_str_numBytes);
+    if (!CFStringGetCString(key_str, key_buffer, key_str_numBytes, kCFStringEncodingUTF8))
+    {
+        asl_free(mAsl);
+        CFRelease(key_str);
+        CFRelease(value_str);
+        return result;
+    }
+    CFRelease(key_str);
+    
+    CFIndex value_str_numBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value_str), kCFStringEncodingUTF8);
+    value_str_numBytes += 1; // For null
+    char value_buffer[value_str_numBytes];
+    memset(value_buffer, 0, value_str_numBytes);
+    if (!CFStringGetCString(value_str, value_buffer, value_str_numBytes, kCFStringEncodingUTF8))
+    {
+        asl_free(mAsl);
+        CFRelease(value_str);
+        return result;
+    }
+    CFRelease(value_str);
+       
+       asl_set(mAsl, key_buffer, value_buffer);
+       asl_log(NULL, mAsl, ASL_LEVEL_NOTICE, "%s", gTopLevelKeyForiCloudKeychainTracing);
+       asl_free(mAsl);
+       return true;
+}
+#endif
+
+#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
+#import <AggregateDictionary/ADClient.h>
+
+static bool iOS_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
+{
+       if (NULL == key)
+       {
+               return false;
+       }
+       
+    if (0LL == value)
+    {
+        ADClientClearScalarKey(key);
+    }
+    
+       ADClientSetValueForScalarKey(key, value);
+       return true;
+}
+#endif
+
+static bool ClientIsInCircle()
+{
+    bool result = false;
+    CFErrorRef error = NULL;
+    SOSCCStatus status = kSOSCCError;
+    
+    status = SOSCCThisDeviceIsInCircle(&error);
+    if (NULL != error)
+    {
+        CFRelease(error);
+    }
+    else
+    {
+        switch (status)
+        {
+            case kSOSCCInCircle:
+            {
+                result = true;
+            }
+                               break;
+                               
+                               // kSOSCCRequestPending
+                               // While this device will be in a circle, it is not in
+                               // one yet. For now, this will be treated as if the device
+                               // was not in a circle and will wait for the device to
+                               // be in a circle and have that turn on this daemon with
+                               // launchctl
+            case kSOSCCRequestPending:
+            case kSOSCCCircleAbsent:
+            case kSOSCCError:
+            default:
+                break;
+        }
+    }
+    return result;
+}
+
+
+static bool sendTraceMessage(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
+       
+}
+
+static int64_t GetNumberOfPeers()
+{
+       int64_t result = 0LL;
+       
+       CFErrorRef error = NULL;
+       CFArrayRef peers = NULL;
+       
+       peers = SOSCCCopyPeerPeerInfo(&error);
+       if (NULL != error)
+       {
+               CFRelease(error);
+               if (NULL != peers)
+               {
+                       CFRelease(peers);
+               }
+               return result;
+       }
+       
+       if (NULL != peers)
+       {
+               result = (int64_t)CFArrayGetCount(peers);
+               CFRelease(peers);
+       }
+       
+       return result;
+}
+
+static int64_t GetNumberOfItemsBeingSyncedForType(CFTypeRef class)
+{
+    int64_t result = 0;
+    
+    CFTypeRef keys[] = {kSecClass, kSecAttrSynchronizable, kSecMatchLimit, kSecReturnAttributes};
+    CFTypeRef values[] = {class, kCFBooleanTrue, kSecMatchLimitAll, kCFBooleanTrue};
+    
+    CFDictionaryRef query = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, (sizeof(keys)/sizeof(keys[0])), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    
+    if (NULL == query)
+    {
+        return result;
+    }
+    
+    CFArrayRef query_result = NULL;
+       OSStatus status =  SecItemCopyMatching(query, (CFTypeRef *)&query_result);
+    CFRelease(query);
+    if (noErr != status || NULL == query_result)
+       {
+               if (NULL != query_result)
+               {
+                       CFRelease(query_result);
+               }
+               return result;
+       }
+    
+    result = (int64_t)CFArrayGetCount(query_result);
+    CFRelease(query_result);
+    return result;
+}
+
+static int64_t GetNumberOfItemsBeingSynced()
+{
+       int64_t result = 0;
+       
+    result = GetNumberOfItemsBeingSyncedForType(kSecClassInternetPassword);
+    result += GetNumberOfItemsBeingSyncedForType(kSecClassGenericPassword);
+       
+       return result;
+}
+
+
+int main(int argc, const char * argv[])
+{
+    int64_t value =  0;
+    if (!ClientIsInCircle())
+    {
+        // This will clear the value in the backend database if it had been previously set
+        sendTraceMessage(gClientIsUsingiCloudKeychainSyncing, value);
+        return 0;
+    }
+    
+    value = 1;
+    sendTraceMessage(gClientIsUsingiCloudKeychainSyncing, value);
+    
+    value = GetNumberOfPeers();
+    sendTraceMessage(gNumberOfPeers, value);
+    
+    value = GetNumberOfItemsBeingSynced();
+    sendTraceMessage(gNumberOfItemsBeingSynced, value);
+    
+    return 0;
+}
+