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.");
16 static const CFStringRef gClientIsUsingiCloudKeychainSyncing
= CFSTR("com.apple.cloudkeychain.deviceIsUsingICloudKeychain");
17 static const CFStringRef gClientIsNotUsingiCloudKeychainSyncing
= CFSTR("com.apple.cloudkeychain.deviceIsNotUsingICloudKeychain");
18 static const CFStringRef gNumberOfPeers
= CFSTR("com.apple.cloudkeychain.numberOfPeers");
19 static const CFStringRef gNumberOfItemsBeingSynced
= CFSTR("com.apple.cloudkeychain.numberOfItemsBeingSynced");
21 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR))
24 static const char* gMessageTracerDomainField
= "com.apple.message.domain";
25 static const const char* gTopLevelKeyForiCloudKeychainTracing
= "com.apple.cloudkeychain";
27 static bool OSX_SetCloudKeychainTraceValueForKey(CFStringRef key
, int64_t value
)
37 mAsl
= asl_new(ASL_TYPE_MSG
);
43 CFIndex key_length
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(key
), kCFStringEncodingUTF8
);
44 key_length
+= 1; // For null
45 char base_key_buffer
[key_length
];
46 memset(base_key_buffer
, 0,key_length
);
47 if (!CFStringGetCString(key
, base_key_buffer
, key_length
, kCFStringEncodingUTF8
))
54 CFStringRef key_str
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%@%@"), gMessageTracerPrefix
, key
);
61 CFStringRef value_str
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%lld"), value
);
62 if (NULL
== value_str
)
69 CFIndex key_str_numBytes
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(key_str
), kCFStringEncodingUTF8
);
70 key_str_numBytes
+= 1; // For null
71 char key_buffer
[key_str_numBytes
];
72 memset(key_buffer
, 0, key_str_numBytes
);
73 if (!CFStringGetCString(key_str
, key_buffer
, key_str_numBytes
, kCFStringEncodingUTF8
))
82 CFIndex value_str_numBytes
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(value_str
), kCFStringEncodingUTF8
);
83 value_str_numBytes
+= 1; // For null
84 char value_buffer
[value_str_numBytes
];
85 memset(value_buffer
, 0, value_str_numBytes
);
86 if (!CFStringGetCString(value_str
, value_buffer
, value_str_numBytes
, kCFStringEncodingUTF8
))
94 asl_set(mAsl
, gMessageTracerDomainField
, base_key_buffer
);
96 asl_set(mAsl
, key_buffer
, value_buffer
);
97 asl_log(NULL
, mAsl
, ASL_LEVEL_NOTICE
, "%s is %lld", key_buffer
, value
);
103 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
104 #import <AggregateDictionary/ADClient.h>
106 static bool iOS_SetCloudKeychainTraceValueForKey(CFStringRef key
, int64_t value
)
113 ADClientSetValueForScalarKey(key
, value
);
118 static bool ClientIsInCircle()
121 CFErrorRef error
= NULL
;
122 SOSCCStatus status
= kSOSCCError
;
124 status
= SOSCCThisDeviceIsInCircle(&error
);
139 // kSOSCCRequestPending
140 // While this device will be in a circle, it is not in
141 // one yet. For now, this will be treated as if the device
142 // was not in a circle and will wait for the device to
143 // be in a circle and have that turn on this daemon with
145 case kSOSCCRequestPending
:
146 case kSOSCCCircleAbsent
:
156 static bool sendTraceMessage(CFStringRef key
, int64_t value
)
159 #if (TARGET_IPHONE_SIMULATOR)
163 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
164 return OSX_SetCloudKeychainTraceValueForKey(key
, value
);
167 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
168 return iOS_SetCloudKeychainTraceValueForKey(key
, value
);
173 int64_t GetNumberOfPeers()
177 CFErrorRef error
= NULL
;
178 CFArrayRef peers
= NULL
;
180 peers
= SOSCCCopyPeerPeerInfo(&error
);
193 result
= (int64_t)CFArrayGetCount(peers
);
201 int64_t GetNumberOfItemsBeingSynced()
206 CFTypeRef classTypes
[] = {kSecClassInternetPassword
, kSecClassGenericPassword
};
209 CFArrayRef classTypesArray
= CFArrayCreate(kCFAllocatorDefault
,
210 (const void **)classTypes
, (sizeof(classTypes
)/sizeof(classTypes
[0])),
211 &kCFTypeArrayCallBacks
);
212 if (NULL
== classTypesArray
)
217 CFTypeRef keys
[] = {kSecClass
, kSecAttrSynchronizable
, kSecReturnAttributes
};
218 CFTypeRef values
[] = {classTypesArray
, kCFBooleanTrue
, kCFBooleanTrue
};
220 CFDictionaryRef query
= CFDictionaryCreate(kCFAllocatorDefault
, (const void **)keys
, (const void **)values
, (sizeof(keys
)/sizeof(keys
[0])), &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
221 CFRelease(classTypesArray
);
227 CFArrayRef query_result
= NULL
;
228 OSStatus status
= SecItemCopyMatching(query
, (CFTypeRef
*)&query_result
);
232 if (NULL
!= query_result
)
234 CFRelease(query_result
);
240 if (NULL
!= query_result
)
242 result
= 1; // There is at least one item being synced
243 if (CFArrayGetTypeID() == CFGetTypeID(query_result
))
245 result
= (int64_t)CFArrayGetCount(query_result
);
247 CFRelease(query_result
);
254 int main(int argc
, const char * argv
[])
257 if (!ClientIsInCircle())
259 sendTraceMessage(gClientIsNotUsingiCloudKeychainSyncing
, value
);
263 sendTraceMessage(gClientIsUsingiCloudKeychainSyncing
, value
);
265 value
= GetNumberOfPeers();
266 sendTraceMessage(gNumberOfPeers
, value
);
268 value
= GetNumberOfItemsBeingSynced();
269 sendTraceMessage(gNumberOfItemsBeingSynced
, value
);