5 // Created by Richard Murphy on 1/26/16.
9 #include "keychain_log.h"
12 * Copyright (c) 2003-2007,2009-2010,2013-2014 Apple Inc. All Rights Reserved.
14 * @APPLE_LICENSE_HEADER_START@
16 * This file contains Original Code and/or Modifications of Original Code
17 * as defined in and that are subject to the Apple Public Source License
18 * Version 2.0 (the 'License'). You may not use this file except in
19 * compliance with the License. Please obtain a copy of the License at
20 * http://www.opensource.apple.com/apsl/ and read it before using this
23 * The Original Code and all software distributed under the License are
24 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
25 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
26 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
28 * Please see the License for the specific language governing rights and
29 * limitations under the License.
31 * @APPLE_LICENSE_HEADER_END@
41 #include <sys/utsname.h>
45 #include <Security/SecItem.h>
47 #include <CoreFoundation/CFNumber.h>
48 #include <CoreFoundation/CFString.h>
50 #include <Security/SecureObjectSync/SOSCloudCircle.h>
51 #include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
52 #include <Security/SecureObjectSync/SOSPeerInfo.h>
53 #include <Security/SecureObjectSync/SOSPeerInfoPriv.h>
54 #include <Security/SecureObjectSync/SOSPeerInfoV2.h>
55 #include <Security/SecureObjectSync/SOSUserKeygen.h>
56 #include <Security/SecureObjectSync/SOSKVSKeys.h>
57 #include <securityd/SOSCloudCircleServer.h>
58 #include <Security/SecOTRSession.h>
59 #include <SOSCircle/CKBridge/SOSCloudKeychainClient.h>
61 #include <utilities/SecCFWrappers.h>
62 #include <utilities/debugging.h>
64 #include <SecurityTool/readline.h>
67 #include "keychain_log.h"
68 #include "secToolFileIO.h"
69 #include <Security/SecPasswordGenerate.h>
71 #define MAXKVSKEYTYPE kUnknownKey
72 #define DATE_LENGTH 18
75 static const char *getSOSCCStatusDescription(SOSCCStatus ccstatus
)
79 case kSOSCCInCircle
: return "In Circle";
80 case kSOSCCNotInCircle
: return "Not in Circle";
81 case kSOSCCRequestPending
: return "Request pending";
82 case kSOSCCCircleAbsent
: return "Circle absent";
83 case kSOSCCError
: return "Circle error";
86 return "<unknown ccstatus>";
91 static void printPeerInfos(char *label
, CFArrayRef (^getArray
)(CFErrorRef
*error
)) {
92 CFErrorRef error
= NULL
;
93 CFArrayRef ppi
= getArray(&error
);
94 SOSPeerInfoRef me
= SOSCCCopyMyPeerInfo(NULL
);
95 CFStringRef mypeerID
= SOSPeerInfoGetPeerID(me
);
98 printmsg(CFSTR("%s count: %ld\n"), label
, (long)CFArrayGetCount(ppi
));
99 CFArrayForEach(ppi
, ^(const void *value
) {
101 SOSPeerInfoRef peer
= (SOSPeerInfoRef
)value
;
102 CFIndex version
= SOSPeerInfoGetVersion(peer
);
103 CFStringRef peerName
= SOSPeerInfoGetPeerName(peer
);
104 CFStringRef devtype
= SOSPeerInfoGetPeerDeviceType(peer
);
105 CFStringRef peerID
= SOSPeerInfoGetPeerID(peer
);
106 CFStringRef transportType
= CFSTR("KVS");
107 CFStringRef deviceID
= CFSTR("");
108 CFDictionaryRef gestalt
= SOSPeerInfoCopyPeerGestalt(peer
);
109 CFStringRef osVersion
= CFDictionaryGetValue(gestalt
, CFSTR("OSVersion"));
110 CFReleaseNull(gestalt
);
114 CFDictionaryRef v2Dictionary
= peer
->v2Dictionary
;
115 transportType
= CFDictionaryGetValue(v2Dictionary
, sTransportType
);
116 deviceID
= CFDictionaryGetValue(v2Dictionary
, sDeviceID
);
118 char *pname
= CFStringToCString(peerName
);
119 char *dname
= CFStringToCString(devtype
);
120 char *tname
= CFStringToCString(transportType
);
121 char *iname
= CFStringToCString(deviceID
);
122 char *osname
= CFStringToCString(osVersion
);
123 const char *me
= CFEqualSafe(mypeerID
, peerID
) ? "me>" : " ";
126 snprintf(buf
, 160, "%s %s: %-16s %-16s %-16s %-16s", me
, label
, pname
, dname
, tname
, iname
);
130 CFStringRef pid
= SOSPeerInfoGetPeerID(peer
);
131 CFIndex vers
= SOSPeerInfoGetVersion(peer
);
132 printmsg(CFSTR("%s %@ V%d OS:%s\n"), buf
, pid
, vers
, osname
);
136 printmsg(CFSTR("No %s, error: %@\n"), label
, error
);
139 CFReleaseNull(error
);
142 static void dumpCircleInfo()
144 CFErrorRef error
= NULL
;
145 CFArrayRef generations
= NULL
;
146 CFArrayRef confirmedDigests
= NULL
;
147 bool is_user_public_trusted
= false;
148 __block
int count
= 0;
150 SOSCCStatus ccstatus
= SOSCCThisDeviceIsInCircle(&error
);
151 if(ccstatus
== kSOSCCError
) {
152 printmsg(CFSTR("End of Dump - unable to proceed due to ccstatus (%s) error: %@\n"), getSOSCCStatusDescription(ccstatus
), error
);
155 printmsg(CFSTR("ccstatus: %s (%d)\n"), getSOSCCStatusDescription(ccstatus
), ccstatus
, error
);
157 is_user_public_trusted
= SOSCCValidateUserPublic(&error
);
158 if(is_user_public_trusted
)
159 printmsg(CFSTR("Account user public is trusted%@"),CFSTR("\n"));
161 printmsg(CFSTR("Account user public is not trusted error:(%@)\n"), error
);
162 CFReleaseNull(error
);
164 generations
= SOSCCCopyGenerationPeerInfo(&error
);
166 CFArrayForEach(generations
, ^(const void *value
) {
169 printmsg(CFSTR("Circle name: %@, "),value
);
172 CFStringRef genDesc
= SOSGenerationCountCopyDescription(value
);
173 printmsg(CFSTR("Generation Count: %@"), genDesc
);
174 CFReleaseNull(genDesc
);
176 printmsg(CFSTR("%s\n"), "");
179 printmsg(CFSTR("No generation count: %@\n"), error
);
181 CFReleaseNull(generations
);
182 CFReleaseNull(error
);
184 printPeerInfos(" Peers", ^(CFErrorRef
*error
) { return SOSCCCopyValidPeerPeerInfo(error
); });
185 printPeerInfos(" Invalid", ^(CFErrorRef
*error
) { return SOSCCCopyNotValidPeerPeerInfo(error
); });
186 printPeerInfos(" Retired", ^(CFErrorRef
*error
) { return SOSCCCopyRetirementPeerInfo(error
); });
187 printPeerInfos(" Concur", ^(CFErrorRef
*error
) { return SOSCCCopyConcurringPeerPeerInfo(error
); });
188 printPeerInfos("Applicants", ^(CFErrorRef
*error
) { return SOSCCCopyApplicantPeerInfo(error
); });
190 confirmedDigests
= SOSCCCopyEngineState(&error
);
194 CFArrayForEach(confirmedDigests
, ^(const void *value
) {
197 printmsg(CFSTR("%@"), value
);
200 CFStringRef hexDigest
= CFDataCopyHexString(value
);
201 printmsg(CFSTR(" %@\n"), hexDigest
);
202 CFReleaseSafe(hexDigest
);
207 printmsg(CFSTR("No engine peers: %@\n"), error
);
208 CFReleaseNull(confirmedDigests
);
211 static CFTypeRef
getObjectsFromCloud(CFArrayRef keysToGet
, dispatch_queue_t processQueue
, dispatch_group_t dgroup
)
213 __block CFTypeRef object
= NULL
;
215 const uint64_t maxTimeToWaitInSeconds
= 30ull * NSEC_PER_SEC
;
216 dispatch_semaphore_t waitSemaphore
= dispatch_semaphore_create(0);
217 dispatch_time_t finishTime
= dispatch_time(DISPATCH_TIME_NOW
, maxTimeToWaitInSeconds
);
219 dispatch_group_enter(dgroup
);
221 CloudKeychainReplyBlock replyBlock
=
222 ^ (CFDictionaryRef returnedValues
, CFErrorRef error
)
224 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues
);
225 object
= returnedValues
;
230 secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error
);
231 // CFRelease(*error);
233 dispatch_group_leave(dgroup
);
234 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud block exit: %@", object
);
235 dispatch_semaphore_signal(waitSemaphore
);
239 SOSCloudKeychainGetAllObjectsFromCloud(processQueue
, replyBlock
);
241 SOSCloudKeychainGetObjectsFromCloud(keysToGet
, processQueue
, replyBlock
);
243 dispatch_semaphore_wait(waitSemaphore
, finishTime
);
244 dispatch_release(waitSemaphore
);
245 if (object
&& (CFGetTypeID(object
) == CFNullGetTypeID())) // return a NULL instead of a CFNull
250 secerror("returned: %@", object
);
254 static CFStringRef
printFullDataString(CFDataRef data
){
255 __block CFStringRef fullData
= NULL
;
257 BufferPerformWithHexString(CFDataGetBytePtr(data
), CFDataGetLength(data
), ^(CFStringRef dataHex
) {
258 fullData
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%@"), dataHex
);
264 static void displayLastKeyParameters(CFTypeRef key
, CFTypeRef value
)
266 CFDataRef valueAsData
= asData(value
, NULL
);
268 CFDataRef dateData
= CFDataCreateCopyFromRange(kCFAllocatorDefault
, valueAsData
, CFRangeMake(0, DATE_LENGTH
));
269 CFDataRef keyParameterData
= CFDataCreateCopyFromPositions(kCFAllocatorDefault
, valueAsData
, DATE_LENGTH
, CFDataGetLength(valueAsData
));
270 CFStringRef dateString
= CFStringCreateFromExternalRepresentation(kCFAllocatorDefault
, dateData
, kCFStringEncodingUTF8
);
271 CFStringRef keyParameterDescription
= UserParametersDescription(keyParameterData
);
272 if(keyParameterDescription
)
273 printmsg(CFSTR("%@: %@: %@\n"), key
, dateString
, keyParameterDescription
);
275 printmsg(CFSTR("%@: %@\n"), key
, printFullDataString(value
));
276 CFReleaseNull(dateString
);
277 CFReleaseNull(keyParameterData
);
278 CFReleaseNull(dateData
);
279 CFReleaseNull(keyParameterDescription
);
282 printmsg(CFSTR("%@: %@\n"), key
, value
);
286 static void displayKeyParameters(CFTypeRef key
, CFTypeRef value
)
289 CFStringRef keyParameterDescription
= UserParametersDescription((CFDataRef
)value
);
291 if(keyParameterDescription
)
292 printmsg(CFSTR("%@: %@\n"), key
, keyParameterDescription
);
294 printmsg(CFSTR("%@: %@\n"), key
, value
);
296 CFReleaseNull(keyParameterDescription
);
299 printmsg(CFSTR("%@: %@\n"), key
, value
);
303 static void displayLastCircle(CFTypeRef key
, CFTypeRef value
)
305 CFDataRef valueAsData
= asData(value
, NULL
);
307 CFErrorRef localError
= NULL
;
309 CFDataRef dateData
= CFDataCreateCopyFromRange(kCFAllocatorDefault
, valueAsData
, CFRangeMake(0, DATE_LENGTH
));
310 CFDataRef circleData
= CFDataCreateCopyFromPositions(kCFAllocatorDefault
, valueAsData
, DATE_LENGTH
, CFDataGetLength(valueAsData
));
311 CFStringRef dateString
= CFStringCreateFromExternalRepresentation(kCFAllocatorDefault
, dateData
, kCFStringEncodingUTF8
);
312 SOSCircleRef circle
= SOSCircleCreateFromData(NULL
, (CFDataRef
) circleData
, &localError
);
316 CFNumberRef idLength
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberCFIndexType
, &size
);
317 CFDictionaryRef format
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength
, NULL
);
318 printmsgWithFormatOptions(format
, CFSTR("%@: %@: %@\n"), key
, dateString
, circle
);
319 CFReleaseNull(idLength
);
320 CFReleaseNull(format
);
324 printmsg(CFSTR("%@: %@\n"), key
, printFullDataString(circleData
));
326 CFReleaseNull(dateString
);
327 CFReleaseNull(circleData
);
328 CFReleaseSafe(circle
);
329 CFReleaseNull(dateData
);
330 CFReleaseNull(localError
);
333 printmsg(CFSTR("%@: %@\n"), key
, value
);
337 static void displayCircle(CFTypeRef key
, CFTypeRef value
)
339 CFDataRef circleData
= (CFDataRef
)value
;
341 CFErrorRef localError
= NULL
;
342 if (isData(circleData
))
345 CFNumberRef idLength
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberCFIndexType
, &size
);
346 CFDictionaryRef format
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength
, NULL
);
347 SOSCircleRef circle
= SOSCircleCreateFromData(NULL
, circleData
, &localError
);
348 printmsgWithFormatOptions(format
, CFSTR("%@: %@\n"), key
, circle
);
349 CFReleaseSafe(circle
);
350 CFReleaseNull(idLength
);
351 CFReleaseNull(format
);
355 printmsg(CFSTR("%@: %@\n"), key
, value
);
358 static void displayMessage(CFTypeRef key
, CFTypeRef value
)
360 CFDataRef message
= (CFDataRef
)value
;
362 const char* messageType
= SecOTRPacketTypeString(message
);
363 printmsg(CFSTR("%@: %s: %ld\n"), key
, messageType
, CFDataGetLength(message
));
366 printmsg(CFSTR("%@: %@\n"), key
, value
);
369 static void printEverything(CFTypeRef objects
)
371 CFDictionaryForEach(objects
, ^(const void *key
, const void *value
) {
374 printmsg(CFSTR("%@: %@\n\n"), key
, printFullDataString(value
));
377 printmsg(CFSTR("%@: %@\n"), key
, value
);
382 static void decodeForKeyType(CFTypeRef key
, CFTypeRef value
, SOSKVSKeyType type
){
385 displayCircle(key
, value
);
389 displayMessage(key
, value
);
392 displayKeyParameters(key
, value
);
394 case kLastKeyParameterKey
:
395 displayLastKeyParameters(key
, value
);
398 displayLastCircle(key
, value
);
400 case kInitialSyncKey
:
401 case kAccountChangedKey
:
406 printmsg(CFSTR("%@: %@\n"), key
, value
);
411 static void decodeAllTheValues(CFTypeRef objects
){
412 SOSKVSKeyType keyType
= 0;
413 __block
bool didPrint
= false;
415 for (keyType
= 0; keyType
<= MAXKVSKEYTYPE
; keyType
++){
416 CFDictionaryForEach(objects
, ^(const void *key
, const void *value
) {
417 if(SOSKVSKeyGetKeyType(key
) == keyType
){
418 decodeForKeyType(key
, value
, keyType
);
423 printmsg(CFSTR("%@\n"), CFSTR(""));
427 static bool dumpKVS(char *itemName
, CFErrorRef
*err
)
429 CFArrayRef keysToGet
= NULL
;
432 CFStringRef itemStr
= CFStringCreateWithCString(kCFAllocatorDefault
, itemName
, kCFStringEncodingUTF8
);
433 fprintf(outFile
, "Retrieving %s from KVS\n", itemName
);
434 keysToGet
= CFArrayCreateForCFTypes(kCFAllocatorDefault
, itemStr
, NULL
);
435 CFReleaseSafe(itemStr
);
437 dispatch_queue_t generalq
= dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL
);
438 dispatch_group_t work_group
= dispatch_group_create();
439 CFTypeRef objects
= getObjectsFromCloud(keysToGet
, generalq
, work_group
);
440 CFReleaseSafe(keysToGet
);
443 fprintf(outFile
, "All keys and values straight from KVS\n");
444 printEverything(objects
);
445 fprintf(outFile
, "\nAll values in decoded form...\n");
446 decodeAllTheValues(objects
);
448 fprintf(outFile
, "\n");
455 const CFStringRef
*viewspec
;
458 "keychain", &kSOSViewKeychainV0
460 "masterkey", &kSOSViewPCSMasterKey
,
462 "iclouddrive", &kSOSViewPCSiCloudDrive
,
464 "photos", &kSOSViewPCSPhotos
,
466 "escrow", &kSOSViewPCSEscrow
,
468 "fde", &kSOSViewPCSFDE
,
470 "maildrop", &kSOSViewPCSMailDrop
,
472 "icloudbackup", &kSOSViewPCSiCloudBackup
,
474 "notes", &kSOSViewPCSNotes
,
476 "imessage", &kSOSViewPCSiMessage
,
478 "feldspar", &kSOSViewPCSFeldspar
,
480 "appletv", &kSOSViewAppleTV
,
482 "homekit", &kSOSViewHomeKit
,
484 "wifi", &kSOSViewWiFi
,
486 "passwords", &kSOSViewAutofillPasswords
,
488 "creditcards", &kSOSViewSafariCreditCards
,
490 "icloudidentity", &kSOSViewiCloudIdentity
,
492 "othersyncable", &kSOSViewOtherSyncable
,
496 static CFStringRef
convertViewReturnCodeToString(SOSViewActionCode ac
) {
497 CFStringRef retval
= NULL
;
499 case kSOSCCGeneralViewError
:
500 retval
= CFSTR("General Error"); break;
501 case kSOSCCViewMember
:
502 retval
= CFSTR("Is Member of View"); break;
503 case kSOSCCViewNotMember
:
504 retval
= CFSTR("Is Not Member of View"); break;
505 case kSOSCCViewNotQualified
:
506 retval
= CFSTR("Is not qualified for View"); break;
507 case kSOSCCNoSuchView
:
508 retval
= CFSTR("No Such View"); break;
513 static bool listviewcmd(CFErrorRef
*err
) {
516 for (n
= 0; n
< sizeof(string2View
)/sizeof(string2View
[0]); n
++) {
517 CFStringRef viewspec
= *string2View
[n
].viewspec
;
519 SOSViewResultCode rc
= SOSCCView(viewspec
, kSOSCCViewQuery
, err
);
520 CFStringRef resultString
= convertViewReturnCodeToString(rc
);
522 printmsg(CFSTR("View Result: %@ : %@\n"), resultString
, viewspec
);
528 #define USE_NEW_SPI 1
531 static char *createDateStrNow() {
538 tmstruct
= localtime(&clock
);
541 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
);
545 // #include <CoreFoundation/CFPriv.h>
547 CF_EXPORT CFDictionaryRef
_CFCopySystemVersionDictionary(void);
548 CF_EXPORT
const CFStringRef _kCFSystemVersionProductNameKey
;
549 CF_EXPORT
const CFStringRef _kCFSystemVersionProductVersionKey
;
550 CF_EXPORT
const CFStringRef _kCFSystemVersionBuildVersionKey
;
552 static char *CFDictionaryCopyCString(CFDictionaryRef dict
, const void *key
) {
553 CFStringRef val
= CFDictionaryGetValue(dict
, key
);
554 char *retval
= CFStringToCString(val
);
560 static void sysdiagnose_dump() {
561 char *outputBase
= NULL
;
562 char *outputParent
= NULL
;
563 char *outputDir
= NULL
;
565 char *productName
= NULL
;
566 char *productVersion
= NULL
;
567 char *buildVersion
= NULL
;
568 char *keysToRegister
= NULL
;
569 char *cloudkeychainproxy3
= NULL
;
570 char *now
= createDateStrNow();
573 CFDictionaryRef sysfdef
= _CFCopySystemVersionDictionary();
575 if(gethostname(hostname
, 80)) {
576 strcpy(hostname
, "unknownhost");
580 productName
= CFDictionaryCopyCString(sysfdef
, _kCFSystemVersionProductNameKey
);
581 productVersion
= CFDictionaryCopyCString(sysfdef
, _kCFSystemVersionProductVersionKey
);
582 buildVersion
= CFDictionaryCopyCString(sysfdef
, _kCFSystemVersionBuildVersionKey
);
584 strcpy(productName
, "unknownProduct");
585 strcpy(productVersion
, "unknownProductVersion");
586 strcpy(buildVersion
, "unknownVersion");
589 // OUTPUTBASE=ckcdiagnose_snapshot_${HOSTNAME}_${PRODUCT_VERSION}_${NOW}
590 length
= strlen("ckcdiagnose_snapshot___") + strlen(hostname
) + strlen(productVersion
) + strlen(now
) + 1;
591 outputBase
= malloc(length
);
592 status
= snprintf(outputBase
, length
, "ckcdiagnose_snapshot_%s_%s_%s", hostname
, productVersion
, now
);
593 if(status
< 0) outputBase
= "";
595 #if TARGET_OS_EMBEDDED
596 outputParent
= "/Library/Logs/CrashReporter";
597 keysToRegister
= "/private/var/preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist";
598 cloudkeychainproxy3
= "/var/mobile/Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist";
600 outputParent
= "/var/tmp";
603 struct passwd
* pwd
= getpwuid(getuid());
604 if (pwd
) homeDir
= pwd
->pw_dir
;
606 char *k2regfmt
= "%s/Library/Preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist";
607 char *ckp3fmt
= "%s/Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist";
608 size_t k2rlen
= strlen(homeDir
) + strlen(k2regfmt
) + 2;
609 size_t ckp3len
= strlen(homeDir
) + strlen(ckp3fmt
) + 2;
610 keysToRegister
= malloc(k2rlen
);
611 cloudkeychainproxy3
= malloc(ckp3len
);
612 snprintf(keysToRegister
, k2rlen
, k2regfmt
, homeDir
);
613 snprintf(cloudkeychainproxy3
, ckp3len
, ckp3fmt
, homeDir
);
617 length
= strlen(outputParent
) + strlen(outputBase
) + 2;
618 outputDir
= malloc(length
);
619 status
= snprintf(outputDir
, length
, "%s/%s", outputParent
, outputBase
);
620 if(status
< 0) return;
622 mkdir(outputDir
, 0700);
624 setOutputTo(outputDir
, "sw_vers.log");
625 // report uname stuff + hostname
626 fprintf(outFile
, "HostName: %s\n", hostname
);
627 fprintf(outFile
, "ProductName: %s\n", productName
);
628 fprintf(outFile
, "ProductVersion: %s\n", productVersion
);
629 fprintf(outFile
, "BuildVersion: %s\n", buildVersion
);
632 setOutputTo(outputDir
, "syncD.log");
634 dumpKVS(optarg
, NULL
);
637 setOutputTo(outputDir
, "synci.log");
642 setOutputTo(outputDir
, "syncL.log");
647 copyFileToOutputDir(outputDir
, keysToRegister
);
648 copyFileToOutputDir(outputDir
, cloudkeychainproxy3
);
651 if(productName
) free(productName
);
652 if(productVersion
) free(productVersion
);
653 if(buildVersion
) free(buildVersion
);
654 CFReleaseNull(sysfdef
);
655 #if ! TARGET_OS_EMBEDDED
656 free(keysToRegister
);
657 free(cloudkeychainproxy3
);
662 static void sysdiagnose_dump() {
663 SOSCCSysdiagnose(NULL
);
666 #endif /* USE_NEW_SPI */
669 // enable, disable, accept, reject, status, Reset, Clear
671 keychain_log(int argc
, char * const *argv
)
675 " -i info (current status)"
676 " -D [itemName] dump contents of KVS"
677 " -L list all known view and their status"
678 " -s sysdiagnose log dumps"
681 setOutputTo(NULL
, NULL
);
684 CFErrorRef error
= NULL
;
685 bool hadError
= false;
687 while ((ch
= getopt(argc
, argv
, "DiLs")) != -1)
700 hadError
= !dumpKVS(optarg
, &error
);
704 hadError
= !listviewcmd(&error
);
709 return 2; /* Return 2 triggers usage message. */
713 printerr(CFSTR("Error: %@\n"), error
);