5 // Created by Richard Murphy on 1/27/16.
10 #include "SOSCloudCircleInternal.h"
15 #include <sys/utsname.h>
21 #include <Security/SecItem.h>
23 #include <CoreFoundation/CFNumber.h>
24 #include <CoreFoundation/CFString.h>
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>
37 #include <utilities/SecCFWrappers.h>
38 #include <utilities/debugging.h>
40 #include <SecurityTool/readline.h>
42 #include "keychain_log.h"
43 #include "secToolFileIO.h"
45 #include <Security/SecPasswordGenerate.h>
47 /* Copied from CFPriv.h */
48 // #include <CoreFoundation/CFPriv.h>
50 CF_EXPORT CFDictionaryRef
_CFCopySystemVersionDictionary(void);
51 CF_EXPORT
const CFStringRef _kCFSystemVersionProductNameKey
;
52 CF_EXPORT
const CFStringRef _kCFSystemVersionProductVersionKey
;
53 CF_EXPORT
const CFStringRef _kCFSystemVersionBuildVersionKey
;
57 static char *CFDictionaryCopyCString(CFDictionaryRef dict
, const void *key
) {
58 CFStringRef val
= CFDictionaryGetValue(dict
, key
);
59 char *retval
= CFStringToCString(val
);
65 #define MAXKVSKEYTYPE kUnknownKey
66 #define DATE_LENGTH 18
72 // Created by Richard Murphy on 1/22/16.
78 #include <utilities/SecCFWrappers.h>
80 #define printmsg(format, ...) _printcfmsg(outFile, NULL, format, __VA_ARGS__)
81 #define printmsgWithFormatOptions(formatOptions, format, ...) _printcfmsg(outFile, formatOptions, format, __VA_ARGS__)
82 #define printerr(format, ...) _printcfmsg(errFile, NULL, format, __VA_ARGS__)
88 void _printcfmsg(FILE *ff
, CFDictionaryRef formatOptions
, CFStringRef format
, ...)
91 va_start(args
, format
);
92 CFStringRef message
= CFStringCreateWithFormatAndArguments(kCFAllocatorDefault
, formatOptions
, format
, args
);
94 CFStringPerformWithCString(message
, ^(const char *utf8String
) { fprintf(ff
, utf8String
, ""); });
99 int setOutputTo(char *dir
, char *filename
) {
102 if(dir
&& filename
) {
103 pathlen
= strlen(dir
) + strlen(filename
) + 2;
105 snprintf(path
, pathlen
, "%s/%s", dir
, filename
);
106 outFile
= fopen(path
, "a");
107 } else if(dir
|| filename
) {
117 void closeOutput(void) {
118 if(outFile
!= stdout
) {
124 int copyFileToOutputDir(char *dir
, char *toCopy
) {
125 char *bname
= basename(toCopy
);
128 copyfile_state_t cpfilestate
= copyfile_state_alloc();
130 status
= snprintf(destpath
, 256, "%s/%s", dir
, bname
);
131 if(status
< 0 || status
> 256) return -1;
133 int retval
= copyfile(toCopy
, destpath
, cpfilestate
, COPYFILE_ALL
);
135 copyfile_state_free(cpfilestate
);
141 static const char *getSOSCCStatusDescription(SOSCCStatus ccstatus
)
145 case kSOSCCInCircle
: return "In Circle";
146 case kSOSCCNotInCircle
: return "Not in Circle";
147 case kSOSCCRequestPending
: return "Request pending";
148 case kSOSCCCircleAbsent
: return "Circle absent";
149 case kSOSCCError
: return "Circle error";
152 return "<unknown ccstatus>";
157 static void printPeerInfos(char *label
, CFArrayRef (^getArray
)(CFErrorRef
*error
)) {
158 CFErrorRef error
= NULL
;
159 CFArrayRef ppi
= getArray(&error
);
160 SOSPeerInfoRef me
= SOSCCCopyMyPeerInfo(NULL
);
161 CFStringRef mypeerID
= SOSPeerInfoGetPeerID(me
);
164 printmsg(CFSTR("%s count: %ld\n"), label
, (long)CFArrayGetCount(ppi
));
165 CFArrayForEach(ppi
, ^(const void *value
) {
167 SOSPeerInfoRef peer
= (SOSPeerInfoRef
)value
;
168 CFIndex version
= SOSPeerInfoGetVersion(peer
);
169 CFStringRef peerName
= SOSPeerInfoGetPeerName(peer
);
170 CFStringRef devtype
= SOSPeerInfoGetPeerDeviceType(peer
);
171 CFStringRef peerID
= SOSPeerInfoGetPeerID(peer
);
172 CFStringRef transportType
= CFSTR("KVS");
173 CFStringRef deviceID
= CFSTR("");
174 CFDictionaryRef gestalt
= SOSPeerInfoCopyPeerGestalt(peer
);
175 CFStringRef osVersion
= CFDictionaryGetValue(gestalt
, CFSTR("OSVersion"));
176 CFReleaseNull(gestalt
);
180 CFDictionaryRef v2Dictionary
= peer
->v2Dictionary
;
181 transportType
= CFDictionaryGetValue(v2Dictionary
, sTransportType
);
182 deviceID
= CFDictionaryGetValue(v2Dictionary
, sDeviceID
);
184 char *pname
= CFStringToCString(peerName
);
185 char *dname
= CFStringToCString(devtype
);
186 char *tname
= CFStringToCString(transportType
);
187 char *iname
= CFStringToCString(deviceID
);
188 char *osname
= CFStringToCString(osVersion
);
189 const char *me
= CFEqualSafe(mypeerID
, peerID
) ? "me>" : " ";
192 snprintf(buf
, 160, "%s %s: %-16s %-16s %-16s %-16s", me
, label
, pname
, dname
, tname
, iname
);
196 CFStringRef pid
= SOSPeerInfoGetPeerID(peer
);
197 CFIndex vers
= SOSPeerInfoGetVersion(peer
);
198 printmsg(CFSTR("%s %@ V%d OS:%s\n"), buf
, pid
, vers
, osname
);
202 printmsg(CFSTR("No %s, error: %@\n"), label
, error
);
205 CFReleaseNull(error
);
208 static void dumpCircleInfo()
210 CFErrorRef error
= NULL
;
211 CFArrayRef generations
= NULL
;
212 CFArrayRef confirmedDigests
= NULL
;
213 bool is_user_public_trusted
= false;
214 __block
int count
= 0;
216 SOSCCStatus ccstatus
= SOSCCThisDeviceIsInCircle(&error
);
217 if(ccstatus
== kSOSCCError
) {
218 printmsg(CFSTR("End of Dump - unable to proceed due to ccstatus (%s) error: %@\n"), getSOSCCStatusDescription(ccstatus
), error
);
221 printmsg(CFSTR("ccstatus: %s (%d)\n"), getSOSCCStatusDescription(ccstatus
), ccstatus
, error
);
223 is_user_public_trusted
= SOSCCValidateUserPublic(&error
);
224 if(is_user_public_trusted
)
225 printmsg(CFSTR("Account user public is trusted%@"),CFSTR("\n"));
227 printmsg(CFSTR("Account user public is not trusted error:(%@)\n"), error
);
228 CFReleaseNull(error
);
230 generations
= SOSCCCopyGenerationPeerInfo(&error
);
232 CFArrayForEach(generations
, ^(const void *value
) {
235 printmsg(CFSTR("Circle name: %@, "),value
);
238 CFStringRef genDesc
= SOSGenerationCountCopyDescription(value
);
239 printmsg(CFSTR("Generation Count: %@"), genDesc
);
240 CFReleaseNull(genDesc
);
242 printmsg(CFSTR("%s\n"), "");
245 printmsg(CFSTR("No generation count: %@\n"), error
);
247 CFReleaseNull(generations
);
248 CFReleaseNull(error
);
250 printPeerInfos(" Peers", ^(CFErrorRef
*error
) { return SOSCCCopyValidPeerPeerInfo(error
); });
251 printPeerInfos(" Invalid", ^(CFErrorRef
*error
) { return SOSCCCopyNotValidPeerPeerInfo(error
); });
252 printPeerInfos(" Retired", ^(CFErrorRef
*error
) { return SOSCCCopyRetirementPeerInfo(error
); });
253 printPeerInfos(" Concur", ^(CFErrorRef
*error
) { return SOSCCCopyConcurringPeerPeerInfo(error
); });
254 printPeerInfos("Applicants", ^(CFErrorRef
*error
) { return SOSCCCopyApplicantPeerInfo(error
); });
256 confirmedDigests
= SOSCCCopyEngineState(&error
);
260 CFArrayForEach(confirmedDigests
, ^(const void *value
) {
263 printmsg(CFSTR("%@"), value
);
266 CFStringRef hexDigest
= CFDataCopyHexString(value
);
267 printmsg(CFSTR(" %@\n"), hexDigest
);
268 CFReleaseSafe(hexDigest
);
273 printmsg(CFSTR("No engine peers: %@\n"), error
);
274 CFReleaseNull(confirmedDigests
);
277 static CFTypeRef
getObjectsFromCloud(CFArrayRef keysToGet
, dispatch_queue_t processQueue
, dispatch_group_t dgroup
)
279 __block CFTypeRef object
= NULL
;
281 const uint64_t maxTimeToWaitInSeconds
= 30ull * NSEC_PER_SEC
;
282 dispatch_semaphore_t waitSemaphore
= dispatch_semaphore_create(0);
283 dispatch_time_t finishTime
= dispatch_time(DISPATCH_TIME_NOW
, maxTimeToWaitInSeconds
);
285 dispatch_group_enter(dgroup
);
287 CloudKeychainReplyBlock replyBlock
=
288 ^ (CFDictionaryRef returnedValues
, CFErrorRef error
)
290 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues
);
291 object
= returnedValues
;
296 secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error
);
297 // CFRelease(*error);
299 dispatch_group_leave(dgroup
);
300 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud block exit: %@", object
);
301 dispatch_semaphore_signal(waitSemaphore
);
305 SOSCloudKeychainGetAllObjectsFromCloud(processQueue
, replyBlock
);
307 SOSCloudKeychainGetObjectsFromCloud(keysToGet
, processQueue
, replyBlock
);
309 dispatch_semaphore_wait(waitSemaphore
, finishTime
);
310 dispatch_release(waitSemaphore
);
311 if (object
&& (CFGetTypeID(object
) == CFNullGetTypeID())) // return a NULL instead of a CFNull
316 secerror("returned: %@", object
);
320 static CFStringRef
printFullDataString(CFDataRef data
){
321 __block CFStringRef fullData
= NULL
;
323 BufferPerformWithHexString(CFDataGetBytePtr(data
), CFDataGetLength(data
), ^(CFStringRef dataHex
) {
324 fullData
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%@"), dataHex
);
330 static void displayLastKeyParameters(CFTypeRef key
, CFTypeRef value
)
332 CFDataRef valueAsData
= asData(value
, NULL
);
334 CFDataRef dateData
= CFDataCreateCopyFromRange(kCFAllocatorDefault
, valueAsData
, CFRangeMake(0, DATE_LENGTH
));
335 CFDataRef keyParameterData
= CFDataCreateCopyFromPositions(kCFAllocatorDefault
, valueAsData
, DATE_LENGTH
, CFDataGetLength(valueAsData
));
336 CFStringRef dateString
= CFStringCreateFromExternalRepresentation(kCFAllocatorDefault
, dateData
, kCFStringEncodingUTF8
);
337 CFStringRef keyParameterDescription
= UserParametersDescription(keyParameterData
);
338 if(keyParameterDescription
)
339 printmsg(CFSTR("%@: %@: %@\n"), key
, dateString
, keyParameterDescription
);
341 printmsg(CFSTR("%@: %@\n"), key
, printFullDataString(value
));
342 CFReleaseNull(dateString
);
343 CFReleaseNull(keyParameterData
);
344 CFReleaseNull(dateData
);
345 CFReleaseNull(keyParameterDescription
);
348 printmsg(CFSTR("%@: %@\n"), key
, value
);
352 static void displayKeyParameters(CFTypeRef key
, CFTypeRef value
)
355 CFStringRef keyParameterDescription
= UserParametersDescription((CFDataRef
)value
);
357 if(keyParameterDescription
)
358 printmsg(CFSTR("%@: %@\n"), key
, keyParameterDescription
);
360 printmsg(CFSTR("%@: %@\n"), key
, value
);
362 CFReleaseNull(keyParameterDescription
);
365 printmsg(CFSTR("%@: %@\n"), key
, value
);
369 static void displayLastCircle(CFTypeRef key
, CFTypeRef value
)
371 CFDataRef valueAsData
= asData(value
, NULL
);
373 CFErrorRef localError
= NULL
;
375 CFDataRef dateData
= CFDataCreateCopyFromRange(kCFAllocatorDefault
, valueAsData
, CFRangeMake(0, DATE_LENGTH
));
376 CFDataRef circleData
= CFDataCreateCopyFromPositions(kCFAllocatorDefault
, valueAsData
, DATE_LENGTH
, CFDataGetLength(valueAsData
));
377 CFStringRef dateString
= CFStringCreateFromExternalRepresentation(kCFAllocatorDefault
, dateData
, kCFStringEncodingUTF8
);
378 SOSCircleRef circle
= SOSCircleCreateFromData(NULL
, (CFDataRef
) circleData
, &localError
);
382 CFNumberRef idLength
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberCFIndexType
, &size
);
383 CFDictionaryRef format
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength
, NULL
);
384 printmsgWithFormatOptions(format
, CFSTR("%@: %@: %@\n"), key
, dateString
, circle
);
385 CFReleaseNull(idLength
);
386 CFReleaseNull(format
);
390 printmsg(CFSTR("%@: %@\n"), key
, printFullDataString(circleData
));
392 CFReleaseNull(dateString
);
393 CFReleaseNull(circleData
);
394 CFReleaseSafe(circle
);
395 CFReleaseNull(dateData
);
396 CFReleaseNull(localError
);
399 printmsg(CFSTR("%@: %@\n"), key
, value
);
403 static void displayCircle(CFTypeRef key
, CFTypeRef value
)
405 CFDataRef circleData
= (CFDataRef
)value
;
407 CFErrorRef localError
= NULL
;
408 if (isData(circleData
))
411 CFNumberRef idLength
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberCFIndexType
, &size
);
412 CFDictionaryRef format
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength
, NULL
);
413 SOSCircleRef circle
= SOSCircleCreateFromData(NULL
, circleData
, &localError
);
414 printmsgWithFormatOptions(format
, CFSTR("%@: %@\n"), key
, circle
);
415 CFReleaseSafe(circle
);
416 CFReleaseNull(idLength
);
417 CFReleaseNull(format
);
421 printmsg(CFSTR("%@: %@\n"), key
, value
);
424 static void displayMessage(CFTypeRef key
, CFTypeRef value
)
426 CFDataRef message
= (CFDataRef
)value
;
428 const char* messageType
= SecOTRPacketTypeString(message
);
429 printmsg(CFSTR("%@: %s: %ld\n"), key
, messageType
, CFDataGetLength(message
));
432 printmsg(CFSTR("%@: %@\n"), key
, value
);
435 static void printEverything(CFTypeRef objects
)
437 CFDictionaryForEach(objects
, ^(const void *key
, const void *value
) {
440 printmsg(CFSTR("%@: %@\n\n"), key
, printFullDataString(value
));
443 printmsg(CFSTR("%@: %@\n"), key
, value
);
448 static void decodeForKeyType(CFTypeRef key
, CFTypeRef value
, SOSKVSKeyType type
){
451 displayCircle(key
, value
);
455 displayMessage(key
, value
);
458 displayKeyParameters(key
, value
);
460 case kLastKeyParameterKey
:
461 displayLastKeyParameters(key
, value
);
464 displayLastCircle(key
, value
);
466 case kInitialSyncKey
:
467 case kAccountChangedKey
:
472 printmsg(CFSTR("%@: %@\n"), key
, value
);
477 static void decodeAllTheValues(CFTypeRef objects
){
478 SOSKVSKeyType keyType
= 0;
479 __block
bool didPrint
= false;
481 for (keyType
= 0; keyType
<= MAXKVSKEYTYPE
; keyType
++){
482 CFDictionaryForEach(objects
, ^(const void *key
, const void *value
) {
483 if(SOSKVSKeyGetKeyType(key
) == keyType
){
484 decodeForKeyType(key
, value
, keyType
);
489 printmsg(CFSTR("%@\n"), CFSTR(""));
493 static bool dumpKVS(char *itemName
, CFErrorRef
*err
)
495 CFArrayRef keysToGet
= NULL
;
498 CFStringRef itemStr
= CFStringCreateWithCString(kCFAllocatorDefault
, itemName
, kCFStringEncodingUTF8
);
499 fprintf(outFile
, "Retrieving %s from KVS\n", itemName
);
500 keysToGet
= CFArrayCreateForCFTypes(kCFAllocatorDefault
, itemStr
, NULL
);
501 CFReleaseSafe(itemStr
);
503 dispatch_queue_t generalq
= dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL
);
504 dispatch_group_t work_group
= dispatch_group_create();
505 CFTypeRef objects
= getObjectsFromCloud(keysToGet
, generalq
, work_group
);
506 CFReleaseSafe(keysToGet
);
509 fprintf(outFile
, "All keys and values straight from KVS\n");
510 printEverything(objects
);
511 fprintf(outFile
, "\nAll values in decoded form...\n");
512 decodeAllTheValues(objects
);
514 fprintf(outFile
, "\n");
521 const CFStringRef
*viewspec
;
524 "keychain", &kSOSViewKeychainV0
526 "masterkey", &kSOSViewPCSMasterKey
,
528 "iclouddrive", &kSOSViewPCSiCloudDrive
,
530 "photos", &kSOSViewPCSPhotos
,
532 "escrow", &kSOSViewPCSEscrow
,
534 "fde", &kSOSViewPCSFDE
,
536 "maildrop", &kSOSViewPCSMailDrop
,
538 "icloudbackup", &kSOSViewPCSiCloudBackup
,
540 "notes", &kSOSViewPCSNotes
,
542 "imessage", &kSOSViewPCSiMessage
,
544 "feldspar", &kSOSViewPCSFeldspar
,
546 "appletv", &kSOSViewAppleTV
,
548 "homekit", &kSOSViewHomeKit
,
550 "wifi", &kSOSViewWiFi
,
552 "passwords", &kSOSViewAutofillPasswords
,
554 "creditcards", &kSOSViewSafariCreditCards
,
556 "icloudidentity", &kSOSViewiCloudIdentity
,
558 "othersyncable", &kSOSViewOtherSyncable
,
562 static CFStringRef
convertViewReturnCodeToString(SOSViewActionCode ac
) {
563 CFStringRef retval
= NULL
;
565 case kSOSCCGeneralViewError
:
566 retval
= CFSTR("General Error"); break;
567 case kSOSCCViewMember
:
568 retval
= CFSTR("Is Member of View"); break;
569 case kSOSCCViewNotMember
:
570 retval
= CFSTR("Is Not Member of View"); break;
571 case kSOSCCViewNotQualified
:
572 retval
= CFSTR("Is not qualified for View"); break;
573 case kSOSCCNoSuchView
:
574 retval
= CFSTR("No Such View"); break;
579 static bool listviewcmd(CFErrorRef
*err
) {
582 for (n
= 0; n
< sizeof(string2View
)/sizeof(string2View
[0]); n
++) {
583 CFStringRef viewspec
= *string2View
[n
].viewspec
;
585 SOSViewResultCode rc
= SOSCCView(viewspec
, kSOSCCViewQuery
, err
);
586 CFStringRef resultString
= convertViewReturnCodeToString(rc
);
588 printmsg(CFSTR("View Result: %@ : %@\n"), resultString
, viewspec
);
595 static char *createDateStrNow() {
602 tmstruct
= localtime(&clock
);
605 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
);
609 #if !TARGET_OS_EMBEDDED
610 static char *assemblePath(char *dir
, char *fname
) {
611 size_t length
= strlen(dir
) + strlen(fname
) + 2;
612 char *outputDir
= malloc(length
);
613 int status
= snprintf(outputDir
, length
, "%s/%s", dir
, fname
);
614 if(status
< 0) return NULL
;
618 static char *homedirPath() {
620 struct passwd
* pwd
= getpwuid(getuid());
621 if (pwd
) homeDir
= pwd
->pw_dir
;
626 static char *sysdiagnose_dir(const char *passedIn
, const char *hostname
, const char *productVersion
, const char *now
) {
627 if(passedIn
) return (char *) passedIn
;
629 // OUTPUTBASE=ckcdiagnose_snapshot_${HOSTNAME}_${PRODUCT_VERSION}_${NOW}
630 char *outputParent
= NULL
;
631 size_t length
= strlen("ckcdiagnose_snapshot___") + strlen(hostname
) + strlen(productVersion
) + strlen(now
) + 1;
632 char *outputBase
= malloc(length
);
633 int status
= snprintf(outputBase
, length
, "ckcdiagnose_snapshot_%s_%s_%s", hostname
, productVersion
, now
);
634 if(status
< 0) outputBase
= "";
636 #if TARGET_OS_EMBEDDED
637 outputParent
= "/Library/Logs/CrashReporter";
639 outputParent
= "/var/tmp";
641 length
= strlen(outputParent
) + strlen(outputBase
) + 2;
642 char *outputDir
= malloc(length
);
643 status
= snprintf(outputDir
, length
, "%s/%s", outputParent
, outputBase
);
644 if(status
< 0) return NULL
;
650 static char *sysdiagnose_dump(const char *dirname
) {
651 char *outputDir
= NULL
;
653 char *productName
= NULL
;
654 char *productVersion
= NULL
;
655 char *buildVersion
= NULL
;
656 char *keysToRegister
= NULL
;
657 char *cloudkeychainproxy3
= NULL
;
658 char *now
= createDateStrNow();
660 CFDictionaryRef sysfdef
= _CFCopySystemVersionDictionary();
662 productName
= CFDictionaryCopyCString(sysfdef
, _kCFSystemVersionProductNameKey
);
663 productVersion
= CFDictionaryCopyCString(sysfdef
, _kCFSystemVersionProductVersionKey
);
664 buildVersion
= CFDictionaryCopyCString(sysfdef
, _kCFSystemVersionBuildVersionKey
);
666 if (productName
== NULL
)
667 productName
= strdup("unknownProduct");
668 if (productVersion
== NULL
)
669 productVersion
= strdup("unknownProductVersion");
671 buildVersion
= strdup("unknownVersion");
673 if(gethostname(hostname
, 80)) {
674 strcpy(hostname
, "unknownhost");
677 #if TARGET_OS_EMBEDDED
678 keysToRegister
= "/private/var/preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist";
679 cloudkeychainproxy3
= "/var/mobile/Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist";
681 char *homeDir
= homedirPath();
682 keysToRegister
= assemblePath(homeDir
, "Library/Preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist");
683 cloudkeychainproxy3
= assemblePath(homeDir
, "Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist");
686 outputDir
= sysdiagnose_dir(dirname
, hostname
, productVersion
, now
);
687 if(!outputDir
) return NULL
;
689 mkdir(outputDir
, 0700);
691 setOutputTo(outputDir
, "sw_vers.log");
692 // report uname stuff + hostname
693 fprintf(outFile
, "HostName: %s\n", hostname
);
694 fprintf(outFile
, "ProductName: %s\n", productName
);
695 fprintf(outFile
, "ProductVersion: %s\n", productVersion
);
696 fprintf(outFile
, "BuildVersion: %s\n", buildVersion
);
699 setOutputTo(outputDir
, "syncD.log");
701 dumpKVS(optarg
, NULL
);
704 setOutputTo(outputDir
, "synci.log");
709 setOutputTo(outputDir
, "syncL.log");
714 copyFileToOutputDir(outputDir
, keysToRegister
);
715 copyFileToOutputDir(outputDir
, cloudkeychainproxy3
);
717 if(productName
) free(productName
);
718 if(productVersion
) free(productVersion
);
719 if(buildVersion
) free(buildVersion
);
722 CFReleaseNull(sysfdef
);
723 #if ! TARGET_OS_EMBEDDED
724 free(keysToRegister
);
725 free(cloudkeychainproxy3
);
731 char *SOSCCSysdiagnose(const char *directoryname
) {
732 sysdiagnose_dump(directoryname
);