]> git.saurik.com Git - apple/security.git/blob - iCloudStat/main.c
Security-57031.1.35.tar.gz
[apple/security.git] / iCloudStat / 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 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");
18
19 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
20 static const char* gTopLevelKeyForiCloudKeychainTracing = "com.apple.icloudkeychain";
21 #endif
22
23 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
24 static const char* gTopLevelKeyForiCloudKeychainTracing = "com.apple.icloudkeychain";
25 #endif
26
27 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR))
28 #include <asl.h>
29
30
31 static bool OSX_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
32 {
33 bool result = false;
34
35 if (NULL == key)
36 {
37 return result;
38 }
39
40 aslmsg mAsl = NULL;
41 mAsl = asl_new(ASL_TYPE_MSG);
42 if (NULL == mAsl)
43 {
44 return result;
45 }
46
47
48 CFStringRef key_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@%@"), gMessageTracerPrefix, key);
49 if (NULL == key_str)
50 {
51 asl_free(mAsl);
52 return result;
53 }
54
55 CFStringRef value_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%lld"), value);
56 if (NULL == value_str)
57 {
58 asl_free(mAsl);
59 CFRelease(key_str);
60 return result;
61 }
62
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))
68 {
69 asl_free(mAsl);
70 CFRelease(key_str);
71 CFRelease(value_str);
72 return result;
73 }
74 CFRelease(key_str);
75
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))
81 {
82 asl_free(mAsl);
83 CFRelease(value_str);
84 return result;
85 }
86 CFRelease(value_str);
87
88 asl_set(mAsl, key_buffer, value_buffer);
89 asl_log(NULL, mAsl, ASL_LEVEL_NOTICE, "%s", gTopLevelKeyForiCloudKeychainTracing);
90 asl_free(mAsl);
91 return true;
92 }
93 #endif
94
95 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
96 #import <AggregateDictionary/ADClient.h>
97
98 static bool iOS_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
99 {
100 if (NULL == key)
101 {
102 return false;
103 }
104
105 if (0LL == value)
106 {
107 ADClientClearScalarKey(key);
108 }
109
110 ADClientSetValueForScalarKey(key, value);
111 return true;
112 }
113 #endif
114
115 static bool ClientIsInCircle()
116 {
117 bool result = false;
118 CFErrorRef error = NULL;
119 SOSCCStatus status = kSOSCCError;
120
121 status = SOSCCThisDeviceIsInCircle(&error);
122 if (NULL != error)
123 {
124 CFRelease(error);
125 }
126 else
127 {
128 switch (status)
129 {
130 case kSOSCCInCircle:
131 {
132 result = true;
133 }
134 break;
135
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
141 // launchctl
142 case kSOSCCRequestPending:
143 case kSOSCCCircleAbsent:
144 case kSOSCCError:
145 default:
146 break;
147 }
148 }
149 return result;
150 }
151
152
153 static bool sendTraceMessage(CFStringRef key, int64_t value)
154 {
155
156 #if (TARGET_IPHONE_SIMULATOR)
157 return false;
158 #endif
159
160 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
161 return OSX_SetCloudKeychainTraceValueForKey(key, value);
162 #endif
163
164 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
165 return iOS_SetCloudKeychainTraceValueForKey(key, value);
166 #endif
167
168 }
169
170 static int64_t GetNumberOfPeers()
171 {
172 int64_t result = 0LL;
173
174 CFErrorRef error = NULL;
175 CFArrayRef peers = NULL;
176
177 peers = SOSCCCopyPeerPeerInfo(&error);
178 if (NULL != error)
179 {
180 CFRelease(error);
181 if (NULL != peers)
182 {
183 CFRelease(peers);
184 }
185 return result;
186 }
187
188 if (NULL != peers)
189 {
190 result = (int64_t)CFArrayGetCount(peers);
191 CFRelease(peers);
192 }
193
194 return result;
195 }
196
197 static int64_t GetNumberOfItemsBeingSyncedForType(CFTypeRef class)
198 {
199 int64_t result = 0;
200
201 CFTypeRef keys[] = {kSecClass, kSecAttrSynchronizable, kSecMatchLimit, kSecReturnAttributes};
202 CFTypeRef values[] = {class, kCFBooleanTrue, kSecMatchLimitAll, kCFBooleanTrue};
203
204 CFDictionaryRef query = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, (sizeof(keys)/sizeof(keys[0])), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
205
206 if (NULL == query)
207 {
208 return result;
209 }
210
211 CFArrayRef query_result = NULL;
212 OSStatus status = SecItemCopyMatching(query, (CFTypeRef *)&query_result);
213 CFRelease(query);
214 if (noErr != status || NULL == query_result)
215 {
216 if (NULL != query_result)
217 {
218 CFRelease(query_result);
219 }
220 return result;
221 }
222
223 result = (int64_t)CFArrayGetCount(query_result);
224 CFRelease(query_result);
225 return result;
226 }
227
228 static int64_t GetNumberOfItemsBeingSynced()
229 {
230 int64_t result = 0;
231
232 result = GetNumberOfItemsBeingSyncedForType(kSecClassInternetPassword);
233 result += GetNumberOfItemsBeingSyncedForType(kSecClassGenericPassword);
234
235 return result;
236 }
237
238
239 int main(int argc, const char * argv[])
240 {
241 int64_t value = 0;
242 if (!ClientIsInCircle())
243 {
244 // This will clear the value in the backend database if it had been previously set
245 sendTraceMessage(gClientIsUsingiCloudKeychainSyncing, value);
246 return 0;
247 }
248
249 value = 1;
250 sendTraceMessage(gClientIsUsingiCloudKeychainSyncing, value);
251
252 value = GetNumberOfPeers();
253 sendTraceMessage(gNumberOfPeers, value);
254
255 value = GetNumberOfItemsBeingSynced();
256 sendTraceMessage(gNumberOfItemsBeingSynced, value);
257
258 return 0;
259 }
260