]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.c
Security-57740.1.18.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSSysdiagnose.c
1 //
2 // SOSSysdiagnose.c
3 // sec
4 //
5 // Created by Richard Murphy on 1/27/16.
6 //
7 //
8
9
10 #include "SOSCloudCircleInternal.h"
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <sys/utsname.h>
16 #include <sys/stat.h>
17 #include <time.h>
18 #include <notify.h>
19 #include <pwd.h>
20
21 #include <Security/SecItem.h>
22
23 #include <CoreFoundation/CFNumber.h>
24 #include <CoreFoundation/CFString.h>
25
26 #include <Security/SecureObjectSync/SOSCloudCircle.h>
27 #include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
28 #include <Security/SecureObjectSync/SOSPeerInfo.h>
29 #include <Security/SecureObjectSync/SOSPeerInfoPriv.h>
30 #include <Security/SecureObjectSync/SOSPeerInfoV2.h>
31 #include <Security/SecureObjectSync/SOSUserKeygen.h>
32 #include <Security/SecureObjectSync/SOSKVSKeys.h>
33 #include <securityd/SOSCloudCircleServer.h>
34 #include <Security/SecOTRSession.h>
35 #include <SOSCircle/CKBridge/SOSCloudKeychainClient.h>
36
37 #include <utilities/SecCFWrappers.h>
38 #include <utilities/debugging.h>
39
40 #include <SecurityTool/readline.h>
41
42 #include "keychain_log.h"
43 #include "secToolFileIO.h"
44 #include "secViewDisplay.h"
45
46
47 #include <Security/SecPasswordGenerate.h>
48
49 /* Copied from CFPriv.h */
50 // #include <CoreFoundation/CFPriv.h>
51
52 CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
53 CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey;
54 CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey;
55 CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
56
57
58
59 static char *CFDictionaryCopyCStringWithDefault(CFDictionaryRef dict, const void *key, char *defaultString) {
60 char *retval = NULL;
61 require_quiet(dict, use_default);
62 CFStringRef val = CFDictionaryGetValue(dict, key);
63 retval = CFStringToCString(val);
64 use_default:
65 if(!retval) retval = strdup(defaultString);
66 return retval;
67 }
68
69
70
71 #define MAXKVSKEYTYPE kUnknownKey
72 #define DATE_LENGTH 18
73
74 //
75 // secToolFileIO.c
76 // sec
77 //
78 // Created by Richard Murphy on 1/22/16.
79 //
80 //
81
82 #include <copyfile.h>
83 #include <libgen.h>
84 #include <utilities/SecCFWrappers.h>
85
86 #define printmsg(format, ...) _printcfmsg(outFile, NULL, format, __VA_ARGS__)
87 #define printmsgWithFormatOptions(formatOptions, format, ...) _printcfmsg(outFile, formatOptions, format, __VA_ARGS__)
88 #define printerr(format, ...) _printcfmsg(errFile, NULL, format, __VA_ARGS__)
89
90
91 FILE *outFile = NULL;
92 FILE *errFile = NULL;
93
94 void _printcfmsg(FILE *ff, CFDictionaryRef formatOptions, CFStringRef format, ...)
95 {
96 va_list args;
97 va_start(args, format);
98 CFStringRef message = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, formatOptions, format, args);
99 va_end(args);
100 CFStringPerformWithCString(message, ^(const char *utf8String) { fprintf(ff, utf8String, ""); });
101 CFRelease(message);
102 }
103
104
105 int setOutputTo(char *dir, char *filename) {
106 size_t pathlen = 0;
107
108 if(dir && filename) {
109 pathlen = strlen(dir) + strlen(filename) + 2;
110 char path[pathlen];
111 snprintf(path, pathlen, "%s/%s", dir, filename);
112 outFile = fopen(path, "a");
113 } else if(dir || filename) {
114 outFile = stdout;
115 return -1;
116 } else {
117 outFile = stdout;
118 }
119 errFile = stderr;
120 return 0;
121 }
122
123 void closeOutput(void) {
124 if(outFile != stdout) {
125 fclose(outFile);
126 }
127 outFile = stdout;
128 }
129
130 int copyFileToOutputDir(char *dir, char *toCopy) {
131 char *bname = basename(toCopy);
132 char destpath[256];
133 int status;
134 copyfile_state_t cpfilestate = copyfile_state_alloc();
135
136 status = snprintf(destpath, 256, "%s/%s", dir, bname);
137 if(status < 0 || status > 256) return -1;
138
139 int retval = copyfile(toCopy, destpath, cpfilestate, COPYFILE_ALL);
140
141 copyfile_state_free(cpfilestate);
142 return retval;
143 }
144
145
146
147 static const char *getSOSCCStatusDescription(SOSCCStatus ccstatus)
148 {
149 switch (ccstatus)
150 {
151 case kSOSCCInCircle: return "In Circle";
152 case kSOSCCNotInCircle: return "Not in Circle";
153 case kSOSCCRequestPending: return "Request pending";
154 case kSOSCCCircleAbsent: return "Circle absent";
155 case kSOSCCError: return "Circle error";
156
157 default:
158 return "<unknown ccstatus>";
159 break;
160 }
161 }
162
163 static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error)) {
164 CFErrorRef error = NULL;
165 CFArrayRef ppi = getArray(&error);
166 SOSPeerInfoRef me = SOSCCCopyMyPeerInfo(NULL);
167 CFStringRef mypeerID = SOSPeerInfoGetPeerID(me);
168
169 if(ppi) {
170 printmsg(CFSTR("%s count: %ld\n"), label, (long)CFArrayGetCount(ppi));
171 CFArrayForEach(ppi, ^(const void *value) {
172 char buf[160];
173 SOSPeerInfoRef peer = (SOSPeerInfoRef)value;
174 CFIndex version = SOSPeerInfoGetVersion(peer);
175 CFStringRef peerName = SOSPeerInfoGetPeerName(peer);
176 CFStringRef devtype = SOSPeerInfoGetPeerDeviceType(peer);
177 CFStringRef peerID = SOSPeerInfoGetPeerID(peer);
178 CFStringRef transportType = CFSTR("KVS");
179 CFStringRef deviceID = CFSTR("");
180 CFDictionaryRef gestalt = SOSPeerInfoCopyPeerGestalt(peer);
181 CFStringRef osVersion = CFDictionaryGetValue(gestalt, CFSTR("OSVersion"));
182 CFReleaseNull(gestalt);
183
184
185 if(version >= 2){
186 CFDictionaryRef v2Dictionary = peer->v2Dictionary;
187 transportType = CFDictionaryGetValue(v2Dictionary, sTransportType);
188 deviceID = CFDictionaryGetValue(v2Dictionary, sDeviceID);
189 }
190 char *pname = CFStringToCString(peerName);
191 char *dname = CFStringToCString(devtype);
192 char *tname = CFStringToCString(transportType);
193 char *iname = CFStringToCString(deviceID);
194 char *osname = CFStringToCString(osVersion);
195 const char *me = CFEqualSafe(mypeerID, peerID) ? "me>" : " ";
196
197
198 snprintf(buf, 160, "%s %s: %-16s %-16s %-16s %-16s", me, label, pname, dname, tname, iname);
199
200 free(pname);
201 free(dname);
202 CFStringRef pid = SOSPeerInfoGetPeerID(peer);
203 CFIndex vers = SOSPeerInfoGetVersion(peer);
204 printmsg(CFSTR("%s %@ V%d OS:%s\n"), buf, pid, vers, osname);
205 free(osname);
206 });
207 } else {
208 printmsg(CFSTR("No %s, error: %@\n"), label, error);
209 }
210 CFReleaseNull(ppi);
211 CFReleaseNull(error);
212 }
213
214 static void dumpCircleInfo()
215 {
216 CFErrorRef error = NULL;
217 CFArrayRef generations = NULL;
218 CFArrayRef confirmedDigests = NULL;
219 bool is_user_public_trusted = false;
220 __block int count = 0;
221
222 SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error);
223 if(ccstatus == kSOSCCError) {
224 printmsg(CFSTR("End of Dump - unable to proceed due to ccstatus (%s) error: %@\n"), getSOSCCStatusDescription(ccstatus), error);
225 return;
226 }
227 printmsg(CFSTR("ccstatus: %s (%d)\n"), getSOSCCStatusDescription(ccstatus), ccstatus, error);
228
229 is_user_public_trusted = SOSCCValidateUserPublic(&error);
230 if(is_user_public_trusted)
231 printmsg(CFSTR("Account user public is trusted%@"),CFSTR("\n"));
232 else
233 printmsg(CFSTR("Account user public is not trusted error:(%@)\n"), error);
234 CFReleaseNull(error);
235
236 generations = SOSCCCopyGenerationPeerInfo(&error);
237 if(generations) {
238 CFArrayForEach(generations, ^(const void *value) {
239 count++;
240 if(count%2 == 0)
241 printmsg(CFSTR("Circle name: %@, "),value);
242
243 if(count%2 != 0) {
244 CFStringRef genDesc = SOSGenerationCountCopyDescription(value);
245 printmsg(CFSTR("Generation Count: %@"), genDesc);
246 CFReleaseNull(genDesc);
247 }
248 printmsg(CFSTR("%s\n"), "");
249 });
250 } else {
251 printmsg(CFSTR("No generation count: %@\n"), error);
252 }
253 CFReleaseNull(generations);
254 CFReleaseNull(error);
255
256 printPeerInfos(" Peers", ^(CFErrorRef *error) { return SOSCCCopyValidPeerPeerInfo(error); });
257 printPeerInfos(" Invalid", ^(CFErrorRef *error) { return SOSCCCopyNotValidPeerPeerInfo(error); });
258 printPeerInfos(" Retired", ^(CFErrorRef *error) { return SOSCCCopyRetirementPeerInfo(error); });
259 printPeerInfos(" Concur", ^(CFErrorRef *error) { return SOSCCCopyConcurringPeerPeerInfo(error); });
260 printPeerInfos("Applicants", ^(CFErrorRef *error) { return SOSCCCopyApplicantPeerInfo(error); });
261
262 confirmedDigests = SOSCCCopyEngineState(&error);
263 if(confirmedDigests)
264 {
265 count = 0;
266 CFArrayForEach(confirmedDigests, ^(const void *value) {
267 count++;
268 if(count % 2 != 0)
269 printmsg(CFSTR("%@"), value);
270
271 if(count % 2 == 0) {
272 CFStringRef hexDigest = CFDataCopyHexString(value);
273 printmsg(CFSTR(" %@\n"), hexDigest);
274 CFReleaseSafe(hexDigest);
275 }
276 });
277 }
278 else
279 printmsg(CFSTR("No engine peers: %@\n"), error);
280 CFReleaseNull(confirmedDigests);
281 }
282
283 static CFTypeRef getObjectsFromCloud(CFArrayRef keysToGet, dispatch_queue_t processQueue, dispatch_group_t dgroup)
284 {
285 __block CFTypeRef object = NULL;
286
287 const uint64_t maxTimeToWaitInSeconds = 30ull * NSEC_PER_SEC;
288 dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
289 dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds);
290
291 dispatch_group_enter(dgroup);
292
293 CloudKeychainReplyBlock replyBlock =
294 ^ (CFDictionaryRef returnedValues, CFErrorRef error)
295 {
296 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues);
297 object = returnedValues;
298 if (object)
299 CFRetain(object);
300 if (error)
301 {
302 secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error);
303 // CFRelease(*error);
304 }
305 dispatch_group_leave(dgroup);
306 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud block exit: %@", object);
307 dispatch_semaphore_signal(waitSemaphore);
308 };
309
310 if (!keysToGet)
311 SOSCloudKeychainGetAllObjectsFromCloud(processQueue, replyBlock);
312 else
313 SOSCloudKeychainGetObjectsFromCloud(keysToGet, processQueue, replyBlock);
314
315 dispatch_semaphore_wait(waitSemaphore, finishTime);
316 dispatch_release(waitSemaphore);
317 if (object && (CFGetTypeID(object) == CFNullGetTypeID())) // return a NULL instead of a CFNull
318 {
319 CFRelease(object);
320 object = NULL;
321 }
322 secerror("returned: %@", object);
323 return object;
324 }
325
326 static CFStringRef printFullDataString(CFDataRef data){
327 __block CFStringRef fullData = NULL;
328
329 BufferPerformWithHexString(CFDataGetBytePtr(data), CFDataGetLength(data), ^(CFStringRef dataHex) {
330 fullData = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), dataHex);
331 });
332
333 return fullData;
334 }
335
336 static void displayLastKeyParameters(CFTypeRef key, CFTypeRef value)
337 {
338 CFDataRef valueAsData = asData(value, NULL);
339 if(valueAsData){
340 CFDataRef dateData = CFDataCreateCopyFromRange(kCFAllocatorDefault, valueAsData, CFRangeMake(0, DATE_LENGTH));
341 CFDataRef keyParameterData = CFDataCreateCopyFromPositions(kCFAllocatorDefault, valueAsData, DATE_LENGTH, CFDataGetLength(valueAsData));
342 CFStringRef dateString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, dateData, kCFStringEncodingUTF8);
343 CFStringRef keyParameterDescription = UserParametersDescription(keyParameterData);
344 if(keyParameterDescription)
345 printmsg(CFSTR("%@: %@: %@\n"), key, dateString, keyParameterDescription);
346 else
347 printmsg(CFSTR("%@: %@\n"), key, printFullDataString(value));
348 CFReleaseNull(dateString);
349 CFReleaseNull(keyParameterData);
350 CFReleaseNull(dateData);
351 CFReleaseNull(keyParameterDescription);
352 }
353 else{
354 printmsg(CFSTR("%@: %@\n"), key, value);
355 }
356 }
357
358 static void displayKeyParameters(CFTypeRef key, CFTypeRef value)
359 {
360 if(isData(value)){
361 CFStringRef keyParameterDescription = UserParametersDescription((CFDataRef)value);
362
363 if(keyParameterDescription)
364 printmsg(CFSTR("%@: %@\n"), key, keyParameterDescription);
365 else
366 printmsg(CFSTR("%@: %@\n"), key, value);
367
368 CFReleaseNull(keyParameterDescription);
369 }
370 else{
371 printmsg(CFSTR("%@: %@\n"), key, value);
372 }
373 }
374
375 static void displayLastCircle(CFTypeRef key, CFTypeRef value)
376 {
377 CFDataRef valueAsData = asData(value, NULL);
378 if(valueAsData){
379 CFErrorRef localError = NULL;
380
381 CFDataRef dateData = CFDataCreateCopyFromRange(kCFAllocatorDefault, valueAsData, CFRangeMake(0, DATE_LENGTH));
382 CFDataRef circleData = CFDataCreateCopyFromPositions(kCFAllocatorDefault, valueAsData, DATE_LENGTH, CFDataGetLength(valueAsData));
383 CFStringRef dateString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, dateData, kCFStringEncodingUTF8);
384 SOSCircleRef circle = SOSCircleCreateFromData(NULL, (CFDataRef) circleData, &localError);
385
386 if(circle){
387 CFIndex size = 5;
388 CFNumberRef idLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &size);
389 CFDictionaryRef format = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength, NULL);
390 printmsgWithFormatOptions(format, CFSTR("%@: %@: %@\n"), key, dateString, circle);
391 CFReleaseNull(idLength);
392 CFReleaseNull(format);
393
394 }
395 else
396 printmsg(CFSTR("%@: %@\n"), key, printFullDataString(circleData));
397
398 CFReleaseNull(dateString);
399 CFReleaseNull(circleData);
400 CFReleaseSafe(circle);
401 CFReleaseNull(dateData);
402 CFReleaseNull(localError);
403 }
404 else{
405 printmsg(CFSTR("%@: %@\n"), key, value);
406 }
407 }
408
409 static void displayCircle(CFTypeRef key, CFTypeRef value)
410 {
411 CFDataRef circleData = (CFDataRef)value;
412
413 CFErrorRef localError = NULL;
414 if (isData(circleData))
415 {
416 CFIndex size = 5;
417 CFNumberRef idLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &size);
418 CFDictionaryRef format = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength, NULL);
419 SOSCircleRef circle = SOSCircleCreateFromData(NULL, circleData, &localError);
420 printmsgWithFormatOptions(format, CFSTR("%@: %@\n"), key, circle);
421 CFReleaseSafe(circle);
422 CFReleaseNull(idLength);
423 CFReleaseNull(format);
424
425 }
426 else
427 printmsg(CFSTR("%@: %@\n"), key, value);
428 }
429
430 static void displayMessage(CFTypeRef key, CFTypeRef value)
431 {
432 CFDataRef message = (CFDataRef)value;
433 if(isData(message)){
434 const char* messageType = SecOTRPacketTypeString(message);
435 printmsg(CFSTR("%@: %s: %ld\n"), key, messageType, CFDataGetLength(message));
436 }
437 else
438 printmsg(CFSTR("%@: %@\n"), key, value);
439 }
440
441 static void printEverything(CFTypeRef objects)
442 {
443 CFDictionaryForEach(objects, ^(const void *key, const void *value) {
444 if (isData(value))
445 {
446 printmsg(CFSTR("%@: %@\n\n"), key, printFullDataString(value));
447 }
448 else
449 printmsg(CFSTR("%@: %@\n"), key, value);
450 });
451
452 }
453
454 static void decodeForKeyType(CFTypeRef key, CFTypeRef value, SOSKVSKeyType type){
455 switch (type) {
456 case kCircleKey:
457 displayCircle(key, value);
458 break;
459 case kRetirementKey:
460 case kMessageKey:
461 displayMessage(key, value);
462 break;
463 case kParametersKey:
464 displayKeyParameters(key, value);
465 break;
466 case kLastKeyParameterKey:
467 displayLastKeyParameters(key, value);
468 break;
469 case kLastCircleKey:
470 displayLastCircle(key, value);
471 break;
472 case kInitialSyncKey:
473 case kAccountChangedKey:
474 case kDebugInfoKey:
475 case kRingKey:
476 case kPeerInfoKey:
477 default:
478 printmsg(CFSTR("%@: %@\n"), key, value);
479 break;
480 }
481 }
482
483 static void decodeAllTheValues(CFTypeRef objects){
484 SOSKVSKeyType keyType = 0;
485 __block bool didPrint = false;
486
487 for (keyType = 0; keyType <= MAXKVSKEYTYPE; keyType++){
488 CFDictionaryForEach(objects, ^(const void *key, const void *value) {
489 if(SOSKVSKeyGetKeyType(key) == keyType){
490 decodeForKeyType(key, value, keyType);
491 didPrint = true;
492 }
493 });
494 if(didPrint)
495 printmsg(CFSTR("%@\n"), CFSTR(""));
496 didPrint = false;
497 }
498 }
499 static bool dumpKVS(char *itemName, CFErrorRef *err)
500 {
501 CFArrayRef keysToGet = NULL;
502 if (itemName)
503 {
504 CFStringRef itemStr = CFStringCreateWithCString(kCFAllocatorDefault, itemName, kCFStringEncodingUTF8);
505 fprintf(outFile, "Retrieving %s from KVS\n", itemName);
506 keysToGet = CFArrayCreateForCFTypes(kCFAllocatorDefault, itemStr, NULL);
507 CFReleaseSafe(itemStr);
508 }
509 dispatch_queue_t generalq = dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL);
510 dispatch_group_t work_group = dispatch_group_create();
511 CFTypeRef objects = getObjectsFromCloud(keysToGet, generalq, work_group);
512 CFReleaseSafe(keysToGet);
513 if (objects)
514 {
515 fprintf(outFile, "All keys and values straight from KVS\n");
516 printEverything(objects);
517 fprintf(outFile, "\nAll values in decoded form...\n");
518 decodeAllTheValues(objects);
519 }
520 fprintf(outFile, "\n");
521 return true;
522 }
523
524
525 static char *createDateStrNow() {
526 char *retval = NULL;
527 time_t clock;
528
529 struct tm *tmstruct;
530
531 time(&clock);
532 tmstruct = localtime(&clock);
533
534 retval = malloc(15);
535 sprintf(retval, "%04d%02d%02d%02d%02d%02d", tmstruct->tm_year+1900, tmstruct->tm_mon+1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec);
536 return retval;
537 }
538
539 #if !TARGET_OS_EMBEDDED
540 static char *assemblePath(char *dir, char *fname) {
541 size_t length = strlen(dir) + strlen(fname) + 2;
542 char *outputDir = malloc(length);
543 int status = snprintf(outputDir, length, "%s/%s", dir, fname);
544 if(status < 0) return NULL;
545 return outputDir;
546 }
547
548 static char *homedirPath() {
549 char *homeDir = "";
550 struct passwd* pwd = getpwuid(getuid());
551 if (pwd) homeDir = pwd->pw_dir;
552 return homeDir;
553 }
554 #endif
555
556 static char *sysdiagnose_dir(const char *passedIn, const char *hostname, const char *productVersion, const char *now) {
557 if(passedIn) return (char *) passedIn;
558
559 // OUTPUTBASE=ckcdiagnose_snapshot_${HOSTNAME}_${PRODUCT_VERSION}_${NOW}
560 char *outputParent = NULL;
561 size_t length = strlen("ckcdiagnose_snapshot___") + strlen(hostname) + strlen(productVersion) + strlen(now) + 1;
562 char *outputBase = malloc(length);
563 int status = snprintf(outputBase, length, "ckcdiagnose_snapshot_%s_%s_%s", hostname, productVersion, now);
564 if(status < 0) outputBase = "";
565
566 #if TARGET_OS_EMBEDDED
567 outputParent = "/Library/Logs/CrashReporter";
568 #else
569 outputParent = "/var/tmp";
570 #endif
571 length = strlen(outputParent) + strlen(outputBase) + 2;
572 char *outputDir = malloc(length);
573 status = snprintf(outputDir, length, "%s/%s", outputParent, outputBase);
574 if(status < 0) return NULL;
575 return outputDir;
576 }
577
578
579 static char *sysdiagnose_dump(const char *dirname) {
580 char *outputDir = NULL;
581 char hostname[80];
582 char *productName = NULL;
583 char *productVersion = NULL;
584 char *buildVersion = NULL;
585 char *keysToRegister = NULL;
586 char *cloudkeychainproxy3 = NULL;
587 char *now = createDateStrNow();
588
589 CFDictionaryRef sysfdef = _CFCopySystemVersionDictionary();
590 productName = CFDictionaryCopyCStringWithDefault(sysfdef, _kCFSystemVersionProductNameKey, "unknownProduct");
591 productVersion = CFDictionaryCopyCStringWithDefault(sysfdef, _kCFSystemVersionProductVersionKey, "unknownProductVersion");
592 buildVersion = CFDictionaryCopyCStringWithDefault(sysfdef, _kCFSystemVersionBuildVersionKey, "unknownVersion");
593
594 if(gethostname(hostname, 80)) {
595 strcpy(hostname, "unknownhost");
596 }
597
598 #if TARGET_OS_EMBEDDED
599 keysToRegister = "/private/var/preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist";
600 cloudkeychainproxy3 = "/var/mobile/Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist";
601 #else
602 char *homeDir = homedirPath();
603 keysToRegister = assemblePath(homeDir, "Library/Preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist");
604 cloudkeychainproxy3 = assemblePath(homeDir, "Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist");
605 #endif
606
607 outputDir = sysdiagnose_dir(dirname, hostname, productVersion, now);
608 if(!outputDir) goto errOut;
609
610 mkdir(outputDir, 0700);
611
612 setOutputTo(outputDir, "sw_vers.log");
613 // report uname stuff + hostname
614 fprintf(outFile, "HostName: %s\n", hostname);
615 fprintf(outFile, "ProductName: %s\n", productName);
616 fprintf(outFile, "ProductVersion: %s\n", productVersion);
617 fprintf(outFile, "BuildVersion: %s\n", buildVersion);
618 closeOutput();
619
620 setOutputTo(outputDir, "syncD.log");
621 // do sync -D
622 dumpKVS(optarg, NULL);
623 closeOutput();
624
625 setOutputTo(outputDir, "synci.log");
626 // do sync -i
627 dumpCircleInfo();
628 closeOutput();
629
630 setOutputTo(outputDir, "syncL.log");
631 // do sync -L
632 listviewcmd(NULL);
633 closeOutput();
634
635 copyFileToOutputDir(outputDir, keysToRegister);
636 copyFileToOutputDir(outputDir, cloudkeychainproxy3);
637
638 errOut:
639 if(now) free(now);
640 CFReleaseNull(sysfdef);
641 #if ! TARGET_OS_EMBEDDED
642 free(keysToRegister);
643 free(cloudkeychainproxy3);
644 #endif
645 if(productName) free(productName);
646 if(productVersion) free(productVersion);
647 if(buildVersion) free(buildVersion);
648 return outputDir;
649 }
650
651
652 char *SOSCCSysdiagnose(const char *directoryname) {
653 sysdiagnose_dump(directoryname);
654 return NULL;
655 }
656