]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/Tool/keychain_log.c
Security-57337.50.23.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 <Security/SecPasswordGenerate.h>
70
71 #define MAXKVSKEYTYPE kUnknownKey
72 #define DATE_LENGTH 18
73
74
75 static const char *getSOSCCStatusDescription(SOSCCStatus ccstatus)
76 {
77 switch (ccstatus)
78 {
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";
84
85 default:
86 return "<unknown ccstatus>";
87 break;
88 }
89 }
90
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);
96
97 if(ppi) {
98 printmsg(CFSTR("%s count: %ld\n"), label, (long)CFArrayGetCount(ppi));
99 CFArrayForEach(ppi, ^(const void *value) {
100 char buf[160];
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);
111
112
113 if(version >= 2){
114 CFDictionaryRef v2Dictionary = peer->v2Dictionary;
115 transportType = CFDictionaryGetValue(v2Dictionary, sTransportType);
116 deviceID = CFDictionaryGetValue(v2Dictionary, sDeviceID);
117 }
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>" : " ";
124
125
126 snprintf(buf, 160, "%s %s: %-16s %-16s %-16s %-16s", me, label, pname, dname, tname, iname);
127
128 free(pname);
129 free(dname);
130 CFStringRef pid = SOSPeerInfoGetPeerID(peer);
131 CFIndex vers = SOSPeerInfoGetVersion(peer);
132 printmsg(CFSTR("%s %@ V%d OS:%s\n"), buf, pid, vers, osname);
133 free(osname);
134 });
135 } else {
136 printmsg(CFSTR("No %s, error: %@\n"), label, error);
137 }
138 CFReleaseNull(ppi);
139 CFReleaseNull(error);
140 }
141
142 static void dumpCircleInfo()
143 {
144 CFErrorRef error = NULL;
145 CFArrayRef generations = NULL;
146 CFArrayRef confirmedDigests = NULL;
147 bool is_user_public_trusted = false;
148 __block int count = 0;
149
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);
153 return;
154 }
155 printmsg(CFSTR("ccstatus: %s (%d)\n"), getSOSCCStatusDescription(ccstatus), ccstatus, error);
156
157 is_user_public_trusted = SOSCCValidateUserPublic(&error);
158 if(is_user_public_trusted)
159 printmsg(CFSTR("Account user public is trusted%@"),CFSTR("\n"));
160 else
161 printmsg(CFSTR("Account user public is not trusted error:(%@)\n"), error);
162 CFReleaseNull(error);
163
164 generations = SOSCCCopyGenerationPeerInfo(&error);
165 if(generations) {
166 CFArrayForEach(generations, ^(const void *value) {
167 count++;
168 if(count%2 == 0)
169 printmsg(CFSTR("Circle name: %@, "),value);
170
171 if(count%2 != 0) {
172 CFStringRef genDesc = SOSGenerationCountCopyDescription(value);
173 printmsg(CFSTR("Generation Count: %@"), genDesc);
174 CFReleaseNull(genDesc);
175 }
176 printmsg(CFSTR("%s\n"), "");
177 });
178 } else {
179 printmsg(CFSTR("No generation count: %@\n"), error);
180 }
181 CFReleaseNull(generations);
182 CFReleaseNull(error);
183
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); });
189
190 confirmedDigests = SOSCCCopyEngineState(&error);
191 if(confirmedDigests)
192 {
193 count = 0;
194 CFArrayForEach(confirmedDigests, ^(const void *value) {
195 count++;
196 if(count % 2 != 0)
197 printmsg(CFSTR("%@"), value);
198
199 if(count % 2 == 0) {
200 CFStringRef hexDigest = CFDataCopyHexString(value);
201 printmsg(CFSTR(" %@\n"), hexDigest);
202 CFReleaseSafe(hexDigest);
203 }
204 });
205 }
206 else
207 printmsg(CFSTR("No engine peers: %@\n"), error);
208 CFReleaseNull(confirmedDigests);
209 }
210
211 static CFTypeRef getObjectsFromCloud(CFArrayRef keysToGet, dispatch_queue_t processQueue, dispatch_group_t dgroup)
212 {
213 __block CFTypeRef object = NULL;
214
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);
218
219 dispatch_group_enter(dgroup);
220
221 CloudKeychainReplyBlock replyBlock =
222 ^ (CFDictionaryRef returnedValues, CFErrorRef error)
223 {
224 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues);
225 object = returnedValues;
226 if (object)
227 CFRetain(object);
228 if (error)
229 {
230 secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error);
231 // CFRelease(*error);
232 }
233 dispatch_group_leave(dgroup);
234 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud block exit: %@", object);
235 dispatch_semaphore_signal(waitSemaphore);
236 };
237
238 if (!keysToGet)
239 SOSCloudKeychainGetAllObjectsFromCloud(processQueue, replyBlock);
240 else
241 SOSCloudKeychainGetObjectsFromCloud(keysToGet, processQueue, replyBlock);
242
243 dispatch_semaphore_wait(waitSemaphore, finishTime);
244 dispatch_release(waitSemaphore);
245 if (object && (CFGetTypeID(object) == CFNullGetTypeID())) // return a NULL instead of a CFNull
246 {
247 CFRelease(object);
248 object = NULL;
249 }
250 secerror("returned: %@", object);
251 return object;
252 }
253
254 static CFStringRef printFullDataString(CFDataRef data){
255 __block CFStringRef fullData = NULL;
256
257 BufferPerformWithHexString(CFDataGetBytePtr(data), CFDataGetLength(data), ^(CFStringRef dataHex) {
258 fullData = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), dataHex);
259 });
260
261 return fullData;
262 }
263
264 static void displayLastKeyParameters(CFTypeRef key, CFTypeRef value)
265 {
266 CFDataRef valueAsData = asData(value, NULL);
267 if(valueAsData){
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);
274 else
275 printmsg(CFSTR("%@: %@\n"), key, printFullDataString(value));
276 CFReleaseNull(dateString);
277 CFReleaseNull(keyParameterData);
278 CFReleaseNull(dateData);
279 CFReleaseNull(keyParameterDescription);
280 }
281 else{
282 printmsg(CFSTR("%@: %@\n"), key, value);
283 }
284 }
285
286 static void displayKeyParameters(CFTypeRef key, CFTypeRef value)
287 {
288 if(isData(value)){
289 CFStringRef keyParameterDescription = UserParametersDescription((CFDataRef)value);
290
291 if(keyParameterDescription)
292 printmsg(CFSTR("%@: %@\n"), key, keyParameterDescription);
293 else
294 printmsg(CFSTR("%@: %@\n"), key, value);
295
296 CFReleaseNull(keyParameterDescription);
297 }
298 else{
299 printmsg(CFSTR("%@: %@\n"), key, value);
300 }
301 }
302
303 static void displayLastCircle(CFTypeRef key, CFTypeRef value)
304 {
305 CFDataRef valueAsData = asData(value, NULL);
306 if(valueAsData){
307 CFErrorRef localError = NULL;
308
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);
313
314 if(circle){
315 CFIndex size = 5;
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);
321
322 }
323 else
324 printmsg(CFSTR("%@: %@\n"), key, printFullDataString(circleData));
325
326 CFReleaseNull(dateString);
327 CFReleaseNull(circleData);
328 CFReleaseSafe(circle);
329 CFReleaseNull(dateData);
330 CFReleaseNull(localError);
331 }
332 else{
333 printmsg(CFSTR("%@: %@\n"), key, value);
334 }
335 }
336
337 static void displayCircle(CFTypeRef key, CFTypeRef value)
338 {
339 CFDataRef circleData = (CFDataRef)value;
340
341 CFErrorRef localError = NULL;
342 if (isData(circleData))
343 {
344 CFIndex size = 5;
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);
352
353 }
354 else
355 printmsg(CFSTR("%@: %@\n"), key, value);
356 }
357
358 static void displayMessage(CFTypeRef key, CFTypeRef value)
359 {
360 CFDataRef message = (CFDataRef)value;
361 if(isData(message)){
362 const char* messageType = SecOTRPacketTypeString(message);
363 printmsg(CFSTR("%@: %s: %ld\n"), key, messageType, CFDataGetLength(message));
364 }
365 else
366 printmsg(CFSTR("%@: %@\n"), key, value);
367 }
368
369 static void printEverything(CFTypeRef objects)
370 {
371 CFDictionaryForEach(objects, ^(const void *key, const void *value) {
372 if (isData(value))
373 {
374 printmsg(CFSTR("%@: %@\n\n"), key, printFullDataString(value));
375 }
376 else
377 printmsg(CFSTR("%@: %@\n"), key, value);
378 });
379
380 }
381
382 static void decodeForKeyType(CFTypeRef key, CFTypeRef value, SOSKVSKeyType type){
383 switch (type) {
384 case kCircleKey:
385 displayCircle(key, value);
386 break;
387 case kRetirementKey:
388 case kMessageKey:
389 displayMessage(key, value);
390 break;
391 case kParametersKey:
392 displayKeyParameters(key, value);
393 break;
394 case kLastKeyParameterKey:
395 displayLastKeyParameters(key, value);
396 break;
397 case kLastCircleKey:
398 displayLastCircle(key, value);
399 break;
400 case kInitialSyncKey:
401 case kAccountChangedKey:
402 case kDebugInfoKey:
403 case kRingKey:
404 case kPeerInfoKey:
405 default:
406 printmsg(CFSTR("%@: %@\n"), key, value);
407 break;
408 }
409 }
410
411 static void decodeAllTheValues(CFTypeRef objects){
412 SOSKVSKeyType keyType = 0;
413 __block bool didPrint = false;
414
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);
419 didPrint = true;
420 }
421 });
422 if(didPrint)
423 printmsg(CFSTR("%@\n"), CFSTR(""));
424 didPrint = false;
425 }
426 }
427 static bool dumpKVS(char *itemName, CFErrorRef *err)
428 {
429 CFArrayRef keysToGet = NULL;
430 if (itemName)
431 {
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);
436 }
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);
441 if (objects)
442 {
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);
447 }
448 fprintf(outFile, "\n");
449 return true;
450 }
451
452
453 static struct foo {
454 const char *name;
455 const CFStringRef *viewspec;
456 } string2View[] = {
457 {
458 "keychain", &kSOSViewKeychainV0
459 }, {
460 "masterkey", &kSOSViewPCSMasterKey,
461 }, {
462 "iclouddrive", &kSOSViewPCSiCloudDrive,
463 }, {
464 "photos", &kSOSViewPCSPhotos,
465 }, {
466 "escrow", &kSOSViewPCSEscrow,
467 }, {
468 "fde", &kSOSViewPCSFDE,
469 }, {
470 "maildrop", &kSOSViewPCSMailDrop,
471 }, {
472 "icloudbackup", &kSOSViewPCSiCloudBackup,
473 }, {
474 "notes", &kSOSViewPCSNotes,
475 }, {
476 "imessage", &kSOSViewPCSiMessage,
477 }, {
478 "feldspar", &kSOSViewPCSFeldspar,
479 }, {
480 "appletv", &kSOSViewAppleTV,
481 }, {
482 "homekit", &kSOSViewHomeKit,
483 }, {
484 "wifi", &kSOSViewWiFi,
485 }, {
486 "passwords", &kSOSViewAutofillPasswords,
487 }, {
488 "creditcards", &kSOSViewSafariCreditCards,
489 }, {
490 "icloudidentity", &kSOSViewiCloudIdentity,
491 }, {
492 "othersyncable", &kSOSViewOtherSyncable,
493 }
494 };
495
496 static CFStringRef convertViewReturnCodeToString(SOSViewActionCode ac) {
497 CFStringRef retval = NULL;
498 switch(ac) {
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;
509 }
510 return retval;
511 }
512
513 static bool listviewcmd(CFErrorRef *err) {
514 unsigned n;
515
516 for (n = 0; n < sizeof(string2View)/sizeof(string2View[0]); n++) {
517 CFStringRef viewspec = *string2View[n].viewspec;
518
519 SOSViewResultCode rc = SOSCCView(viewspec, kSOSCCViewQuery, err);
520 CFStringRef resultString = convertViewReturnCodeToString(rc);
521
522 printmsg(CFSTR("View Result: %@ : %@\n"), resultString, viewspec);
523 };
524
525 return true;
526 }
527
528 #define USE_NEW_SPI 1
529 #if ! USE_NEW_SPI
530
531 static char *createDateStrNow() {
532 char *retval = NULL;
533 time_t clock;
534
535 struct tm *tmstruct;
536
537 time(&clock);
538 tmstruct = localtime(&clock);
539
540 retval = malloc(15);
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);
542 return retval;
543 }
544
545 // #include <CoreFoundation/CFPriv.h>
546
547 CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
548 CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey;
549 CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey;
550 CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
551
552 static char *CFDictionaryCopyCString(CFDictionaryRef dict, const void *key) {
553 CFStringRef val = CFDictionaryGetValue(dict, key);
554 char *retval = CFStringToCString(val);
555 return retval;
556 }
557
558 #include <pwd.h>
559
560 static void sysdiagnose_dump() {
561 char *outputBase = NULL;
562 char *outputParent = NULL;
563 char *outputDir = NULL;
564 char hostname[80];
565 char *productName = NULL;
566 char *productVersion = NULL;
567 char *buildVersion = NULL;
568 char *keysToRegister = NULL;
569 char *cloudkeychainproxy3 = NULL;
570 char *now = createDateStrNow();
571 size_t length = 0;
572 int status = 0;
573 CFDictionaryRef sysfdef = _CFCopySystemVersionDictionary();
574
575 if(gethostname(hostname, 80)) {
576 strcpy(hostname, "unknownhost");
577 }
578
579 if(sysfdef) {
580 productName = CFDictionaryCopyCString(sysfdef, _kCFSystemVersionProductNameKey);
581 productVersion = CFDictionaryCopyCString(sysfdef, _kCFSystemVersionProductVersionKey);
582 buildVersion = CFDictionaryCopyCString(sysfdef, _kCFSystemVersionBuildVersionKey);
583 } else {
584 strcpy(productName, "unknownProduct");
585 strcpy(productVersion, "unknownProductVersion");
586 strcpy(buildVersion, "unknownVersion");
587 }
588
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 = "";
594
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";
599 #else
600 outputParent = "/var/tmp";
601 {
602 char *homeDir = "";
603 struct passwd* pwd = getpwuid(getuid());
604 if (pwd) homeDir = pwd->pw_dir;
605
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);
614 }
615 #endif
616
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;
621
622 mkdir(outputDir, 0700);
623
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);
630 closeOutput();
631
632 setOutputTo(outputDir, "syncD.log");
633 // do sync -D
634 dumpKVS(optarg, NULL);
635 closeOutput();
636
637 setOutputTo(outputDir, "synci.log");
638 // do sync -i
639 dumpCircleInfo();
640 closeOutput();
641
642 setOutputTo(outputDir, "syncL.log");
643 // do sync -L
644 listviewcmd(NULL);
645 closeOutput();
646
647 copyFileToOutputDir(outputDir, keysToRegister);
648 copyFileToOutputDir(outputDir, cloudkeychainproxy3);
649
650 free(now);
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);
658 #endif
659
660 }
661 #else
662 static void sysdiagnose_dump() {
663 SOSCCSysdiagnose(NULL);
664 }
665
666 #endif /* USE_NEW_SPI */
667
668
669 // enable, disable, accept, reject, status, Reset, Clear
670 int
671 keychain_log(int argc, char * const *argv)
672 {
673 /*
674 "Keychain Logging"
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"
679
680 */
681 setOutputTo(NULL, NULL);
682
683 int ch, result = 0;
684 CFErrorRef error = NULL;
685 bool hadError = false;
686
687 while ((ch = getopt(argc, argv, "DiLs")) != -1)
688 switch (ch) {
689
690 case 'i':
691 dumpCircleInfo();
692 break;
693
694
695 case 's':
696 sysdiagnose_dump();
697 break;
698
699 case 'D':
700 hadError = !dumpKVS(optarg, &error);
701 break;
702
703 case 'L':
704 hadError = !listviewcmd(&error);
705 break;
706
707 case '?':
708 default:
709 return 2; /* Return 2 triggers usage message. */
710 }
711
712 if (hadError)
713 printerr(CFSTR("Error: %@\n"), error);
714
715 return result;
716 }