]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.c
0bb83bed719abcd68e798c7ac43572073744237e
[apple/security.git] / OSX / sec / SOSCircle / Tool / accountCirclesViewsPrint.c
1 //
2 // accountCirclesViewsPrint.c
3 // Security
4 //
5 // Created by Richard Murphy on 12/8/16.
6 //
7 //
8
9 #include "accountCirclesViewsPrint.h"
10
11 //
12 // SOSSysdiagnose.c
13 // sec
14 //
15 // Created by Richard Murphy on 1/27/16.
16 //
17 //
18
19
20 #include "SOSCloudCircleInternal.h"
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <sys/utsname.h>
26 #include <sys/stat.h>
27 #include <time.h>
28 #include <notify.h>
29 #include <pwd.h>
30
31 #include <Security/SecItem.h>
32
33 #include <CoreFoundation/CFNumber.h>
34 #include <CoreFoundation/CFString.h>
35
36 #include <Security/SecureObjectSync/SOSCloudCircle.h>
37 #include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
38 #include <Security/SecureObjectSync/SOSPeerInfo.h>
39 #include <Security/SecureObjectSync/SOSPeerInfoPriv.h>
40 #include <Security/SecureObjectSync/SOSPeerInfoV2.h>
41 #include <Security/SecureObjectSync/SOSUserKeygen.h>
42 #include <Security/SecureObjectSync/SOSKVSKeys.h>
43 #include <securityd/SOSCloudCircleServer.h>
44 #include <Security/SecOTRSession.h>
45 #include <SOSCircle/CKBridge/SOSCloudKeychainClient.h>
46
47 #include <utilities/SecCFWrappers.h>
48 #include <utilities/debugging.h>
49
50 #include <SecurityTool/readline.h>
51
52 #include "keychain_log.h"
53 #include "secToolFileIO.h"
54 #include "secViewDisplay.h"
55
56
57 #include <Security/SecPasswordGenerate.h>
58
59 /* Copied from CFPriv.h */
60 // #include <CoreFoundation/CFPriv.h>
61
62 CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
63 CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey;
64 CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey;
65 CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
66
67 #define MAXKVSKEYTYPE kUnknownKey
68 #define DATE_LENGTH 18
69
70 #include <utilities/SecCFWrappers.h>
71
72
73 static const char *getSOSCCStatusDescription(SOSCCStatus ccstatus)
74 {
75 switch (ccstatus)
76 {
77 case kSOSCCInCircle: return "In Circle";
78 case kSOSCCNotInCircle: return "Not in Circle";
79 case kSOSCCRequestPending: return "Request pending";
80 case kSOSCCCircleAbsent: return "Circle absent";
81 case kSOSCCError: return "Circle error";
82
83 default:
84 return "<unknown ccstatus>";
85 break;
86 }
87 }
88
89 static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error)) {
90 CFErrorRef error = NULL;
91 CFArrayRef ppi = getArray(&error);
92 SOSPeerInfoRef me = SOSCCCopyMyPeerInfo(NULL);
93 CFStringRef mypeerID = SOSPeerInfoGetPeerID(me);
94
95 if(ppi) {
96 printmsg(CFSTR("%s count: %ld\n"), label, (long)CFArrayGetCount(ppi));
97 CFArrayForEach(ppi, ^(const void *value) {
98 char buf[160];
99 SOSPeerInfoRef peer = (SOSPeerInfoRef)value;
100 CFIndex version = SOSPeerInfoGetVersion(peer);
101 CFStringRef peerName = SOSPeerInfoGetPeerName(peer);
102 CFStringRef devtype = SOSPeerInfoGetPeerDeviceType(peer);
103 CFStringRef peerID = SOSPeerInfoGetPeerID(peer);
104 CFStringRef transportType = CFSTR("KVS");
105 CFStringRef deviceID = CFSTR("");
106 CFDictionaryRef gestalt = SOSPeerInfoCopyPeerGestalt(peer);
107 CFStringRef osVersion = CFDictionaryGetValue(gestalt, CFSTR("OSVersion"));
108 CFReleaseNull(gestalt);
109
110
111 if(version >= 2){
112 CFDictionaryRef v2Dictionary = peer->v2Dictionary;
113 transportType = CFDictionaryGetValue(v2Dictionary, sTransportType);
114 deviceID = CFDictionaryGetValue(v2Dictionary, sDeviceID);
115 }
116 char *pname = CFStringToCString(peerName);
117 char *dname = CFStringToCString(devtype);
118 char *tname = CFStringToCString(transportType);
119 char *iname = CFStringToCString(deviceID);
120 char *osname = CFStringToCString(osVersion);
121 const char *me = CFEqualSafe(mypeerID, peerID) ? "me>" : " ";
122
123
124 snprintf(buf, 160, "%s %s: %-16s %-16s %-16s %-16s", me, label, pname, dname, tname, iname);
125
126 free(pname);
127 free(dname);
128 CFStringRef pid = SOSPeerInfoGetPeerID(peer);
129 CFIndex vers = SOSPeerInfoGetVersion(peer);
130 printmsg(CFSTR("%s %@ V%d OS:%s\n"), buf, pid, vers, osname);
131 free(osname);
132 });
133 } else {
134 printmsg(CFSTR("No %s, error: %@\n"), label, error);
135 }
136 CFReleaseNull(ppi);
137 CFReleaseNull(error);
138 }
139
140 void SOSCCDumpCircleInformation()
141 {
142 CFErrorRef error = NULL;
143 CFArrayRef generations = NULL;
144 bool is_user_public_trusted = false;
145 __block int count = 0;
146
147 SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error);
148 printmsg(CFSTR("ccstatus: %s (%d)\n"), getSOSCCStatusDescription(ccstatus), ccstatus);
149
150 is_user_public_trusted = SOSCCValidateUserPublic(&error);
151 if(is_user_public_trusted)
152 printmsg(CFSTR("Account user public is trusted%@"),CFSTR("\n"));
153 else
154 printmsg(CFSTR("Account user public is not trusted error:(%@)\n"), error);
155 CFReleaseNull(error);
156
157 generations = SOSCCCopyGenerationPeerInfo(&error);
158 if(generations) {
159 CFArrayForEach(generations, ^(const void *value) {
160 count++;
161 if(count%2 == 0)
162 printmsg(CFSTR("Circle name: %@, "),value);
163
164 if(count%2 != 0) {
165 CFStringRef genDesc = SOSGenerationCountCopyDescription(value);
166 printmsg(CFSTR("Generation Count: %@"), genDesc);
167 CFReleaseNull(genDesc);
168 }
169 printmsg(CFSTR("%s\n"), "");
170 });
171 } else {
172 printmsg(CFSTR("No generation count: %@\n"), error);
173 }
174 CFReleaseNull(generations);
175 CFReleaseNull(error);
176
177 printPeerInfos(" Peers", ^(CFErrorRef *error) { return SOSCCCopyValidPeerPeerInfo(error); });
178 printPeerInfos(" Invalid", ^(CFErrorRef *error) { return SOSCCCopyNotValidPeerPeerInfo(error); });
179 printPeerInfos(" Retired", ^(CFErrorRef *error) { return SOSCCCopyRetirementPeerInfo(error); });
180 printPeerInfos(" Concur", ^(CFErrorRef *error) { return SOSCCCopyConcurringPeerPeerInfo(error); });
181 printPeerInfos("Applicants", ^(CFErrorRef *error) { return SOSCCCopyApplicantPeerInfo(error); });
182
183 CFReleaseNull(error);
184 }
185
186
187
188
189 /* KVS Dumping Support for iCloud Keychain */
190
191 static CFTypeRef getObjectsFromCloud(CFArrayRef keysToGet, dispatch_queue_t processQueue, dispatch_group_t dgroup)
192 {
193 __block CFTypeRef object = NULL;
194
195 const uint64_t maxTimeToWaitInSeconds = 30ull * NSEC_PER_SEC;
196 dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
197 dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds);
198
199 dispatch_group_enter(dgroup);
200
201 CloudKeychainReplyBlock replyBlock =
202 ^ (CFDictionaryRef returnedValues, CFErrorRef error)
203 {
204 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues);
205 object = returnedValues;
206 if (object)
207 CFRetain(object);
208 if (error)
209 {
210 secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error);
211 }
212 dispatch_group_leave(dgroup);
213 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud block exit: %@", object);
214 dispatch_semaphore_signal(waitSemaphore);
215 };
216
217 if (!keysToGet)
218 SOSCloudKeychainGetAllObjectsFromCloud(processQueue, replyBlock);
219 else
220 SOSCloudKeychainGetObjectsFromCloud(keysToGet, processQueue, replyBlock);
221
222 dispatch_semaphore_wait(waitSemaphore, finishTime);
223 dispatch_release(waitSemaphore);
224 if (object && (CFGetTypeID(object) == CFNullGetTypeID())) // return a NULL instead of a CFNull
225 {
226 CFRelease(object);
227 object = NULL;
228 }
229 secerror("returned: %@", object);
230 return object;
231 }
232
233 static CFStringRef printFullDataString(CFDataRef data){
234 __block CFStringRef fullData = NULL;
235
236 BufferPerformWithHexString(CFDataGetBytePtr(data), CFDataGetLength(data), ^(CFStringRef dataHex) {
237 fullData = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), dataHex);
238 });
239
240 return fullData;
241 }
242
243 static void displayLastKeyParameters(CFTypeRef key, CFTypeRef value)
244 {
245 CFDataRef valueAsData = asData(value, NULL);
246 if(valueAsData){
247 CFDataRef dateData = CFDataCreateCopyFromRange(kCFAllocatorDefault, valueAsData, CFRangeMake(0, DATE_LENGTH));
248 CFDataRef keyParameterData = CFDataCreateCopyFromPositions(kCFAllocatorDefault, valueAsData, DATE_LENGTH, CFDataGetLength(valueAsData));
249 CFStringRef dateString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, dateData, kCFStringEncodingUTF8);
250 CFStringRef keyParameterDescription = UserParametersDescription(keyParameterData);
251 if(keyParameterDescription)
252 printmsg(CFSTR("%@: %@: %@\n"), key, dateString, keyParameterDescription);
253 else
254 printmsg(CFSTR("%@: %@\n"), key, printFullDataString(value));
255 CFReleaseNull(dateString);
256 CFReleaseNull(keyParameterData);
257 CFReleaseNull(dateData);
258 CFReleaseNull(keyParameterDescription);
259 }
260 else{
261 printmsg(CFSTR("%@: %@\n"), key, value);
262 }
263 }
264
265 static void displayKeyParameters(CFTypeRef key, CFTypeRef value)
266 {
267 if(isData(value)){
268 CFStringRef keyParameterDescription = UserParametersDescription((CFDataRef)value);
269
270 if(keyParameterDescription)
271 printmsg(CFSTR("%@: %@\n"), key, keyParameterDescription);
272 else
273 printmsg(CFSTR("%@: %@\n"), key, value);
274
275 CFReleaseNull(keyParameterDescription);
276 }
277 else{
278 printmsg(CFSTR("%@: %@\n"), key, value);
279 }
280 }
281
282 static void displayLastCircle(CFTypeRef key, CFTypeRef value)
283 {
284 CFDataRef valueAsData = asData(value, NULL);
285 if(valueAsData){
286 CFErrorRef localError = NULL;
287
288 CFDataRef dateData = CFDataCreateCopyFromRange(kCFAllocatorDefault, valueAsData, CFRangeMake(0, DATE_LENGTH));
289 CFDataRef circleData = CFDataCreateCopyFromPositions(kCFAllocatorDefault, valueAsData, DATE_LENGTH, CFDataGetLength(valueAsData));
290 CFStringRef dateString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, dateData, kCFStringEncodingUTF8);
291 SOSCircleRef circle = SOSCircleCreateFromData(NULL, (CFDataRef) circleData, &localError);
292
293 if(circle){
294 CFIndex size = 5;
295 CFNumberRef idLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &size);
296 CFDictionaryRef format = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength, NULL);
297 printmsgWithFormatOptions(format, CFSTR("%@: %@: %@\n"), key, dateString, circle);
298 CFReleaseNull(idLength);
299 CFReleaseNull(format);
300
301 }
302 else
303 printmsg(CFSTR("%@: %@\n"), key, printFullDataString(circleData));
304
305 CFReleaseNull(dateString);
306 CFReleaseNull(circleData);
307 CFReleaseSafe(circle);
308 CFReleaseNull(dateData);
309 CFReleaseNull(localError);
310 }
311 else{
312 printmsg(CFSTR("%@: %@\n"), key, value);
313 }
314 }
315
316 static void displayCircle(CFTypeRef key, CFTypeRef value)
317 {
318 CFDataRef circleData = (CFDataRef)value;
319
320 CFErrorRef localError = NULL;
321 if (isData(circleData))
322 {
323 CFIndex size = 5;
324 CFNumberRef idLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &size);
325 CFDictionaryRef format = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength, NULL);
326 SOSCircleRef circle = SOSCircleCreateFromData(NULL, circleData, &localError);
327 printmsgWithFormatOptions(format, CFSTR("%@: %@\n"), key, circle);
328 CFReleaseSafe(circle);
329 CFReleaseNull(idLength);
330 CFReleaseNull(format);
331
332 }
333 else
334 printmsg(CFSTR("%@: %@\n"), key, value);
335 }
336
337 static void displayMessage(CFTypeRef key, CFTypeRef value)
338 {
339 CFDataRef message = (CFDataRef)value;
340 if(isData(message)){
341 const char* messageType = SecOTRPacketTypeString(message);
342 printmsg(CFSTR("%@: %s: %ld\n"), key, messageType, CFDataGetLength(message));
343 }
344 else
345 printmsg(CFSTR("%@: %@\n"), key, value);
346 }
347
348 static void printEverything(CFTypeRef objects)
349 {
350 CFDictionaryForEach(objects, ^(const void *key, const void *value) {
351 if (isData(value))
352 {
353 printmsg(CFSTR("%@: %@\n\n"), key, printFullDataString(value));
354 }
355 else
356 printmsg(CFSTR("%@: %@\n"), key, value);
357 });
358
359 }
360
361 static void decodeForKeyType(CFTypeRef key, CFTypeRef value, SOSKVSKeyType type){
362 switch (type) {
363 case kCircleKey:
364 displayCircle(key, value);
365 break;
366 case kRetirementKey:
367 case kMessageKey:
368 displayMessage(key, value);
369 break;
370 case kParametersKey:
371 displayKeyParameters(key, value);
372 break;
373 case kLastKeyParameterKey:
374 displayLastKeyParameters(key, value);
375 break;
376 case kLastCircleKey:
377 displayLastCircle(key, value);
378 break;
379 case kInitialSyncKey:
380 case kAccountChangedKey:
381 case kDebugInfoKey:
382 case kRingKey:
383 case kPeerInfoKey:
384 default:
385 printmsg(CFSTR("%@: %@\n"), key, value);
386 break;
387 }
388 }
389
390 static void decodeAllTheValues(CFTypeRef objects){
391 SOSKVSKeyType keyType = 0;
392 __block bool didPrint = false;
393
394 for (keyType = 0; keyType <= MAXKVSKEYTYPE; keyType++){
395 CFDictionaryForEach(objects, ^(const void *key, const void *value) {
396 if(SOSKVSKeyGetKeyType(key) == keyType){
397 decodeForKeyType(key, value, keyType);
398 didPrint = true;
399 }
400 });
401 if(didPrint)
402 printmsg(CFSTR("%@\n"), CFSTR(""));
403 didPrint = false;
404 }
405 }
406
407 bool SOSCCDumpCircleKVSInformation(char *itemName) {
408 CFArrayRef keysToGet = NULL;
409 if (itemName)
410 {
411 CFStringRef itemStr = CFStringCreateWithCString(kCFAllocatorDefault, itemName, kCFStringEncodingUTF8);
412 fprintf(outFile, "Retrieving %s from KVS\n", itemName);
413 keysToGet = CFArrayCreateForCFTypes(kCFAllocatorDefault, itemStr, NULL);
414 CFReleaseSafe(itemStr);
415 }
416 dispatch_queue_t generalq = dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL);
417 dispatch_group_t work_group = dispatch_group_create();
418 CFTypeRef objects = getObjectsFromCloud(keysToGet, generalq, work_group);
419 CFReleaseSafe(keysToGet);
420 if (objects)
421 {
422 fprintf(outFile, "All keys and values straight from KVS\n");
423 printEverything(objects);
424 fprintf(outFile, "\nAll values in decoded form...\n");
425 decodeAllTheValues(objects);
426 }
427 fprintf(outFile, "\n");
428 return true;
429 }