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