]> git.saurik.com Git - apple/security.git/blob - iCloudStats/main.c
Security-55471.14.8.tar.gz
[apple/security.git] / iCloudStats / main.c
1 //
2 // main.c
3 // iCloudStats
4 //
5 // Created by local on 7/20/13.
6 //
7 //
8
9 #include <CoreFoundation/CoreFoundation.h>
10
11 #import "SOSCloudCircle.h"
12 #import <Security/Security.h>
13
14 static const CFStringRef gMessageTracerPrefix = CFSTR("com.apple.message.");
15
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");
20
21 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR))
22 #include <asl.h>
23
24 static const char* gMessageTracerDomainField = "com.apple.message.domain";
25 static const const char* gTopLevelKeyForiCloudKeychainTracing = "com.apple.cloudkeychain";
26
27 static bool OSX_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
28 {
29 bool result = false;
30
31 if (NULL == key)
32 {
33 return result;
34 }
35
36 aslmsg mAsl = NULL;
37 mAsl = asl_new(ASL_TYPE_MSG);
38 if (NULL == mAsl)
39 {
40 return result;
41 }
42
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))
48 {
49 asl_free(mAsl);
50 return result;
51 }
52
53
54 CFStringRef key_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@%@"), gMessageTracerPrefix, key);
55 if (NULL == key_str)
56 {
57 asl_free(mAsl);
58 return result;
59 }
60
61 CFStringRef value_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%lld"), value);
62 if (NULL == value_str)
63 {
64 asl_free(mAsl);
65 CFRelease(key_str);
66 return result;
67 }
68
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))
74 {
75 asl_free(mAsl);
76 CFRelease(key_str);
77 CFRelease(value_str);
78 return result;
79 }
80 CFRelease(key_str);
81
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))
87 {
88 asl_free(mAsl);
89 CFRelease(value_str);
90 return result;
91 }
92 CFRelease(value_str);
93
94 asl_set(mAsl, gMessageTracerDomainField, base_key_buffer);
95
96 asl_set(mAsl, key_buffer, value_buffer);
97 asl_log(NULL, mAsl, ASL_LEVEL_NOTICE, "%s is %lld", key_buffer, value);
98 asl_free(mAsl);
99 return true;
100 }
101 #endif
102
103 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
104 #import <AggregateDictionary/ADClient.h>
105
106 static bool iOS_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
107 {
108 if (NULL == key)
109 {
110 return false;
111 }
112
113 ADClientSetValueForScalarKey(key, value);
114 return true;
115 }
116 #endif
117
118 static bool ClientIsInCircle()
119 {
120 bool result = false;
121 CFErrorRef error = NULL;
122 SOSCCStatus status = kSOSCCError;
123
124 status = SOSCCThisDeviceIsInCircle(&error);
125 if (NULL != error)
126 {
127 CFRelease(error);
128 }
129 else
130 {
131 switch (status)
132 {
133 case kSOSCCInCircle:
134 {
135 result = true;
136 }
137 break;
138
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
144 // launchctl
145 case kSOSCCRequestPending:
146 case kSOSCCCircleAbsent:
147 case kSOSCCError:
148 default:
149 break;
150 }
151 }
152 return result;
153 }
154
155
156 static bool sendTraceMessage(CFStringRef key, int64_t value)
157 {
158
159 #if (TARGET_IPHONE_SIMULATOR)
160 return false;
161 #endif
162
163 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
164 return OSX_SetCloudKeychainTraceValueForKey(key, value);
165 #endif
166
167 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
168 return iOS_SetCloudKeychainTraceValueForKey(key, value);
169 #endif
170
171 }
172
173 int64_t GetNumberOfPeers()
174 {
175 int64_t result = 0;
176
177 CFErrorRef error = NULL;
178 CFArrayRef peers = NULL;
179
180 peers = SOSCCCopyPeerPeerInfo(&error);
181 if (NULL != error)
182 {
183 CFRelease(error);
184 if (NULL != peers)
185 {
186 CFRelease(peers);
187 }
188 return result;
189 }
190
191 if (NULL != peers)
192 {
193 result = (int64_t)CFArrayGetCount(peers);
194 CFRelease(peers);
195 }
196
197 return result;
198 }
199
200
201 int64_t GetNumberOfItemsBeingSynced()
202 {
203 int64_t result = 0;
204
205
206 CFTypeRef classTypes[] = {kSecClassInternetPassword, kSecClassGenericPassword};
207
208
209 CFArrayRef classTypesArray = CFArrayCreate(kCFAllocatorDefault,
210 (const void **)classTypes, (sizeof(classTypes)/sizeof(classTypes[0])),
211 &kCFTypeArrayCallBacks);
212 if (NULL == classTypesArray)
213 {
214 return result;
215 }
216
217 CFTypeRef keys[] = {kSecClass, kSecAttrSynchronizable, kSecReturnAttributes};
218 CFTypeRef values[] = {classTypesArray, kCFBooleanTrue, kCFBooleanTrue};
219
220 CFDictionaryRef query = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, (sizeof(keys)/sizeof(keys[0])), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
221 CFRelease(classTypesArray);
222 if (NULL == query)
223 {
224 return result;
225 }
226
227 CFArrayRef query_result = NULL;
228 OSStatus status = SecItemCopyMatching(query, (CFTypeRef *)&query_result);
229 if (noErr != status)
230 {
231 CFRelease(query);
232 if (NULL != query_result)
233 {
234 CFRelease(query_result);
235 }
236 return result;
237 }
238 CFRelease(query);
239
240 if (NULL != query_result)
241 {
242 result = 1; // There is at least one item being synced
243 if (CFArrayGetTypeID() == CFGetTypeID(query_result))
244 {
245 result = (int64_t)CFArrayGetCount(query_result);
246 }
247 CFRelease(query_result);
248 }
249
250 return result;
251 }
252
253
254 int main(int argc, const char * argv[])
255 {
256 int64_t value = 1;
257 if (!ClientIsInCircle())
258 {
259 sendTraceMessage(gClientIsNotUsingiCloudKeychainSyncing, value);
260 return 0;
261 }
262
263 sendTraceMessage(gClientIsUsingiCloudKeychainSyncing, value);
264
265 value = GetNumberOfPeers();
266 sendTraceMessage(gNumberOfPeers, value);
267
268 value = GetNumberOfItemsBeingSynced();
269 sendTraceMessage(gNumberOfItemsBeingSynced, value);
270
271
272 return 0;
273 }
274