2 // accountCirclesViewsPrint.c
5 // Created by Richard Murphy on 12/8/16.
9 #include "accountCirclesViewsPrint.h"
15 // Created by Richard Murphy on 1/27/16.
20 #include "SOSCloudCircleInternal.h"
25 #include <sys/utsname.h>
31 #include <Security/SecItem.h>
33 #include <CoreFoundation/CFNumber.h>
34 #include <CoreFoundation/CFString.h>
36 #include <Security/SecureObjectSync/SOSCloudCircle.h>
37 #include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
38 #include <Security/SecureObjectSync/SOSPeerInfo.h>
39 #include <Security/SecureObjectSync/SOSPeerInfoPriv.h>
40 #include <Security/SecureObjectSync/SOSPeerInfoV2.h>
41 #include <Security/SecureObjectSync/SOSUserKeygen.h>
42 #include <Security/SecureObjectSync/SOSKVSKeys.h>
43 #include <securityd/SOSCloudCircleServer.h>
44 #include <Security/SecOTRSession.h>
45 #include <SOSCircle/CKBridge/SOSCloudKeychainClient.h>
47 #include <utilities/SecCFWrappers.h>
48 #include <utilities/debugging.h>
50 #include <SecurityTool/readline.h>
52 #include "keychain_log.h"
53 #include "secToolFileIO.h"
54 #include "secViewDisplay.h"
57 #include <Security/SecPasswordGenerate.h>
59 /* Copied from CFPriv.h */
60 // #include <CoreFoundation/CFPriv.h>
62 CF_EXPORT CFDictionaryRef
_CFCopySystemVersionDictionary(void);
63 CF_EXPORT
const CFStringRef _kCFSystemVersionProductNameKey
;
64 CF_EXPORT
const CFStringRef _kCFSystemVersionProductVersionKey
;
65 CF_EXPORT
const CFStringRef _kCFSystemVersionBuildVersionKey
;
67 #define MAXKVSKEYTYPE kUnknownKey
68 #define DATE_LENGTH 18
70 #include <utilities/SecCFWrappers.h>
73 static const char *getSOSCCStatusDescription(SOSCCStatus ccstatus
)
77 case kSOSCCInCircle
: return "In Circle";
78 case kSOSCCNotInCircle
: return "Not in Circle";
79 case kSOSCCRequestPending
: return "Request pending";
80 case kSOSCCCircleAbsent
: return "Circle absent";
81 case kSOSCCError
: return "Circle error";
84 return "<unknown ccstatus>";
89 static void printPeerInfos(char *label
, CFArrayRef (^getArray
)(CFErrorRef
*error
)) {
90 CFErrorRef error
= NULL
;
91 CFArrayRef ppi
= getArray(&error
);
92 SOSPeerInfoRef me
= SOSCCCopyMyPeerInfo(NULL
);
93 CFStringRef mypeerID
= SOSPeerInfoGetPeerID(me
);
96 printmsg(CFSTR("%s count: %ld\n"), label
, (long)CFArrayGetCount(ppi
));
97 CFArrayForEach(ppi
, ^(const void *value
) {
99 SOSPeerInfoRef peer
= (SOSPeerInfoRef
)value
;
100 CFIndex version
= SOSPeerInfoGetVersion(peer
);
101 CFStringRef peerName
= SOSPeerInfoGetPeerName(peer
);
102 CFStringRef devtype
= SOSPeerInfoGetPeerDeviceType(peer
);
103 CFStringRef peerID
= SOSPeerInfoGetPeerID(peer
);
104 CFStringRef transportType
= CFSTR("KVS");
105 CFStringRef deviceID
= CFSTR("");
106 CFDictionaryRef gestalt
= SOSPeerInfoCopyPeerGestalt(peer
);
107 CFStringRef osVersion
= CFDictionaryGetValue(gestalt
, CFSTR("OSVersion"));
108 CFReleaseNull(gestalt
);
112 CFDictionaryRef v2Dictionary
= peer
->v2Dictionary
;
113 transportType
= CFDictionaryGetValue(v2Dictionary
, sTransportType
);
114 deviceID
= CFDictionaryGetValue(v2Dictionary
, sDeviceID
);
116 char *pname
= CFStringToCString(peerName
);
117 char *dname
= CFStringToCString(devtype
);
118 char *tname
= CFStringToCString(transportType
);
119 char *iname
= CFStringToCString(deviceID
);
120 char *osname
= CFStringToCString(osVersion
);
121 const char *me
= CFEqualSafe(mypeerID
, peerID
) ? "me>" : " ";
124 snprintf(buf
, 160, "%s %s: %-16s %-16s %-16s %-16s", me
, label
, pname
, dname
, tname
, iname
);
128 CFStringRef pid
= SOSPeerInfoGetPeerID(peer
);
129 CFIndex vers
= SOSPeerInfoGetVersion(peer
);
130 printmsg(CFSTR("%s %@ V%d OS:%s\n"), buf
, pid
, vers
, osname
);
134 printmsg(CFSTR("No %s, error: %@\n"), label
, error
);
137 CFReleaseNull(error
);
140 void SOSCCDumpCircleInformation()
142 CFErrorRef error
= NULL
;
143 CFArrayRef generations
= NULL
;
144 bool is_user_public_trusted
= false;
145 __block
int count
= 0;
147 SOSCCStatus ccstatus
= SOSCCThisDeviceIsInCircle(&error
);
148 printmsg(CFSTR("ccstatus: %s (%d)\n"), getSOSCCStatusDescription(ccstatus
), ccstatus
);
150 is_user_public_trusted
= SOSCCValidateUserPublic(&error
);
151 if(is_user_public_trusted
)
152 printmsg(CFSTR("Account user public is trusted%@"),CFSTR("\n"));
154 printmsg(CFSTR("Account user public is not trusted error:(%@)\n"), error
);
155 CFReleaseNull(error
);
157 generations
= SOSCCCopyGenerationPeerInfo(&error
);
159 CFArrayForEach(generations
, ^(const void *value
) {
162 printmsg(CFSTR("Circle name: %@, "),value
);
165 CFStringRef genDesc
= SOSGenerationCountCopyDescription(value
);
166 printmsg(CFSTR("Generation Count: %@"), genDesc
);
167 CFReleaseNull(genDesc
);
169 printmsg(CFSTR("%s\n"), "");
172 printmsg(CFSTR("No generation count: %@\n"), error
);
174 CFReleaseNull(generations
);
175 CFReleaseNull(error
);
177 printPeerInfos(" Peers", ^(CFErrorRef
*error
) { return SOSCCCopyValidPeerPeerInfo(error
); });
178 printPeerInfos(" Invalid", ^(CFErrorRef
*error
) { return SOSCCCopyNotValidPeerPeerInfo(error
); });
179 printPeerInfos(" Retired", ^(CFErrorRef
*error
) { return SOSCCCopyRetirementPeerInfo(error
); });
180 printPeerInfos(" Concur", ^(CFErrorRef
*error
) { return SOSCCCopyConcurringPeerPeerInfo(error
); });
181 printPeerInfos("Applicants", ^(CFErrorRef
*error
) { return SOSCCCopyApplicantPeerInfo(error
); });
183 CFReleaseNull(error
);
189 /* KVS Dumping Support for iCloud Keychain */
191 static CFTypeRef
getObjectsFromCloud(CFArrayRef keysToGet
, dispatch_queue_t processQueue
, dispatch_group_t dgroup
)
193 __block CFTypeRef object
= NULL
;
195 const uint64_t maxTimeToWaitInSeconds
= 30ull * NSEC_PER_SEC
;
196 dispatch_semaphore_t waitSemaphore
= dispatch_semaphore_create(0);
197 dispatch_time_t finishTime
= dispatch_time(DISPATCH_TIME_NOW
, maxTimeToWaitInSeconds
);
199 dispatch_group_enter(dgroup
);
201 CloudKeychainReplyBlock replyBlock
=
202 ^ (CFDictionaryRef returnedValues
, CFErrorRef error
)
204 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues
);
205 object
= returnedValues
;
210 secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error
);
212 dispatch_group_leave(dgroup
);
213 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud block exit: %@", object
);
214 dispatch_semaphore_signal(waitSemaphore
);
218 SOSCloudKeychainGetAllObjectsFromCloud(processQueue
, replyBlock
);
220 SOSCloudKeychainGetObjectsFromCloud(keysToGet
, processQueue
, replyBlock
);
222 dispatch_semaphore_wait(waitSemaphore
, finishTime
);
223 dispatch_release(waitSemaphore
);
224 if (object
&& (CFGetTypeID(object
) == CFNullGetTypeID())) // return a NULL instead of a CFNull
229 secerror("returned: %@", object
);
233 static CFStringRef
printFullDataString(CFDataRef data
){
234 __block CFStringRef fullData
= NULL
;
236 BufferPerformWithHexString(CFDataGetBytePtr(data
), CFDataGetLength(data
), ^(CFStringRef dataHex
) {
237 fullData
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%@"), dataHex
);
243 static void displayLastKeyParameters(CFTypeRef key
, CFTypeRef value
)
245 CFDataRef valueAsData
= asData(value
, NULL
);
247 CFDataRef dateData
= CFDataCreateCopyFromRange(kCFAllocatorDefault
, valueAsData
, CFRangeMake(0, DATE_LENGTH
));
248 CFDataRef keyParameterData
= CFDataCreateCopyFromPositions(kCFAllocatorDefault
, valueAsData
, DATE_LENGTH
, CFDataGetLength(valueAsData
));
249 CFStringRef dateString
= CFStringCreateFromExternalRepresentation(kCFAllocatorDefault
, dateData
, kCFStringEncodingUTF8
);
250 CFStringRef keyParameterDescription
= UserParametersDescription(keyParameterData
);
251 if(keyParameterDescription
)
252 printmsg(CFSTR("%@: %@: %@\n"), key
, dateString
, keyParameterDescription
);
254 printmsg(CFSTR("%@: %@\n"), key
, printFullDataString(value
));
255 CFReleaseNull(dateString
);
256 CFReleaseNull(keyParameterData
);
257 CFReleaseNull(dateData
);
258 CFReleaseNull(keyParameterDescription
);
261 printmsg(CFSTR("%@: %@\n"), key
, value
);
265 static void displayKeyParameters(CFTypeRef key
, CFTypeRef value
)
268 CFStringRef keyParameterDescription
= UserParametersDescription((CFDataRef
)value
);
270 if(keyParameterDescription
)
271 printmsg(CFSTR("%@: %@\n"), key
, keyParameterDescription
);
273 printmsg(CFSTR("%@: %@\n"), key
, value
);
275 CFReleaseNull(keyParameterDescription
);
278 printmsg(CFSTR("%@: %@\n"), key
, value
);
282 static void displayLastCircle(CFTypeRef key
, CFTypeRef value
)
284 CFDataRef valueAsData
= asData(value
, NULL
);
286 CFErrorRef localError
= NULL
;
288 CFDataRef dateData
= CFDataCreateCopyFromRange(kCFAllocatorDefault
, valueAsData
, CFRangeMake(0, DATE_LENGTH
));
289 CFDataRef circleData
= CFDataCreateCopyFromPositions(kCFAllocatorDefault
, valueAsData
, DATE_LENGTH
, CFDataGetLength(valueAsData
));
290 CFStringRef dateString
= CFStringCreateFromExternalRepresentation(kCFAllocatorDefault
, dateData
, kCFStringEncodingUTF8
);
291 SOSCircleRef circle
= SOSCircleCreateFromData(NULL
, (CFDataRef
) circleData
, &localError
);
295 CFNumberRef idLength
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberCFIndexType
, &size
);
296 CFDictionaryRef format
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength
, NULL
);
297 printmsgWithFormatOptions(format
, CFSTR("%@: %@: %@\n"), key
, dateString
, circle
);
298 CFReleaseNull(idLength
);
299 CFReleaseNull(format
);
303 printmsg(CFSTR("%@: %@\n"), key
, printFullDataString(circleData
));
305 CFReleaseNull(dateString
);
306 CFReleaseNull(circleData
);
307 CFReleaseSafe(circle
);
308 CFReleaseNull(dateData
);
309 CFReleaseNull(localError
);
312 printmsg(CFSTR("%@: %@\n"), key
, value
);
316 static void displayCircle(CFTypeRef key
, CFTypeRef value
)
318 CFDataRef circleData
= (CFDataRef
)value
;
320 CFErrorRef localError
= NULL
;
321 if (isData(circleData
))
324 CFNumberRef idLength
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberCFIndexType
, &size
);
325 CFDictionaryRef format
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength
, NULL
);
326 SOSCircleRef circle
= SOSCircleCreateFromData(NULL
, circleData
, &localError
);
327 printmsgWithFormatOptions(format
, CFSTR("%@: %@\n"), key
, circle
);
328 CFReleaseSafe(circle
);
329 CFReleaseNull(idLength
);
330 CFReleaseNull(format
);
334 printmsg(CFSTR("%@: %@\n"), key
, value
);
337 static void displayMessage(CFTypeRef key
, CFTypeRef value
)
339 CFDataRef message
= (CFDataRef
)value
;
341 const char* messageType
= SecOTRPacketTypeString(message
);
342 printmsg(CFSTR("%@: %s: %ld\n"), key
, messageType
, CFDataGetLength(message
));
345 printmsg(CFSTR("%@: %@\n"), key
, value
);
348 static void printEverything(CFTypeRef objects
)
350 CFDictionaryForEach(objects
, ^(const void *key
, const void *value
) {
353 printmsg(CFSTR("%@: %@\n\n"), key
, printFullDataString(value
));
356 printmsg(CFSTR("%@: %@\n"), key
, value
);
361 static void decodeForKeyType(CFTypeRef key
, CFTypeRef value
, SOSKVSKeyType type
){
364 displayCircle(key
, value
);
368 displayMessage(key
, value
);
371 displayKeyParameters(key
, value
);
373 case kLastKeyParameterKey
:
374 displayLastKeyParameters(key
, value
);
377 displayLastCircle(key
, value
);
379 case kInitialSyncKey
:
380 case kAccountChangedKey
:
385 printmsg(CFSTR("%@: %@\n"), key
, value
);
390 static void decodeAllTheValues(CFTypeRef objects
){
391 SOSKVSKeyType keyType
= 0;
392 __block
bool didPrint
= false;
394 for (keyType
= 0; keyType
<= MAXKVSKEYTYPE
; keyType
++){
395 CFDictionaryForEach(objects
, ^(const void *key
, const void *value
) {
396 if(SOSKVSKeyGetKeyType(key
) == keyType
){
397 decodeForKeyType(key
, value
, keyType
);
402 printmsg(CFSTR("%@\n"), CFSTR(""));
407 bool SOSCCDumpCircleKVSInformation(char *itemName
) {
408 CFArrayRef keysToGet
= NULL
;
411 CFStringRef itemStr
= CFStringCreateWithCString(kCFAllocatorDefault
, itemName
, kCFStringEncodingUTF8
);
412 fprintf(outFile
, "Retrieving %s from KVS\n", itemName
);
413 keysToGet
= CFArrayCreateForCFTypes(kCFAllocatorDefault
, itemStr
, NULL
);
414 CFReleaseSafe(itemStr
);
416 dispatch_queue_t generalq
= dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL
);
417 dispatch_group_t work_group
= dispatch_group_create();
418 CFTypeRef objects
= getObjectsFromCloud(keysToGet
, generalq
, work_group
);
419 CFReleaseSafe(keysToGet
);
422 fprintf(outFile
, "All keys and values straight from KVS\n");
423 printEverything(objects
);
424 fprintf(outFile
, "\nAll values in decoded form...\n");
425 decodeAllTheValues(objects
);
427 fprintf(outFile
, "\n");