]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.m
Security-58286.31.2.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / Tool / accountCirclesViewsPrint.m
1 //
2 // accountCirclesViewsPrint.c
3 // Security
4 //
5 // Created by Richard Murphy on 12/8/16.
6 //
7 //
8
9 #include "accountCirclesViewsPrint.h"
10
11 //
12 // SOSSysdiagnose.c
13 // sec
14 //
15 // Created by Richard Murphy on 1/27/16.
16 //
17 //
18
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <sys/utsname.h>
25 #include <sys/stat.h>
26 #include <time.h>
27 #include <notify.h>
28 #include <pwd.h>
29
30 #include <Security/SecItem.h>
31
32 #include <CoreFoundation/CFNumber.h>
33 #include <CoreFoundation/CFString.h>
34
35 #include <Security/SecureObjectSync/SOSCloudCircle.h>
36 #include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
37 #include <Security/SecureObjectSync/SOSPeerInfo.h>
38 #include <Security/SecureObjectSync/SOSPeerInfoPriv.h>
39 #include <Security/SecureObjectSync/SOSPeerInfoV2.h>
40 #include <Security/SecureObjectSync/SOSUserKeygen.h>
41 #include <Security/SecureObjectSync/SOSKVSKeys.h>
42 #include <securityd/SOSCloudCircleServer.h>
43 #include <Security/SecOTRSession.h>
44 #include <SOSCircle/CKBridge/SOSCloudKeychainClient.h>
45
46 #include <utilities/SecCFWrappers.h>
47 #include <utilities/debugging.h>
48
49 #include <SecurityTool/readline.h>
50
51 #include "keychain_log.h"
52 #include "secToolFileIO.h"
53 #include "secViewDisplay.h"
54
55
56 #include <Security/SecPasswordGenerate.h>
57
58 /* Copied from CFPriv.h */
59 // #include <CoreFoundation/CFPriv.h>
60
61 CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
62 CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey;
63 CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey;
64 CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
65
66 #define MAXKVSKEYTYPE kUnknownKey
67 #define DATE_LENGTH 18
68
69 #include <utilities/SecCFWrappers.h>
70
71
72 static const char *getSOSCCStatusDescription(SOSCCStatus ccstatus)
73 {
74 switch (ccstatus)
75 {
76 case kSOSCCInCircle: return "In Circle";
77 case kSOSCCNotInCircle: return "Not in Circle";
78 case kSOSCCRequestPending: return "Request pending";
79 case kSOSCCCircleAbsent: return "Circle absent";
80 case kSOSCCError: return "Circle error";
81
82 default:
83 return "<unknown ccstatus>";
84 break;
85 }
86 }
87
88 static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error)) {
89 CFErrorRef error = NULL;
90 CFArrayRef ppi = getArray(&error);
91 SOSPeerInfoRef me = SOSCCCopyMyPeerInfo(NULL);
92 CFStringRef mypeerID = SOSPeerInfoGetPeerID(me);
93
94 if(ppi) {
95 printmsg(CFSTR("%s count: %ld\n"), label, (long)CFArrayGetCount(ppi));
96 CFArrayForEach(ppi, ^(const void *value) {
97 char buf[160];
98 SOSPeerInfoRef peer = (SOSPeerInfoRef)value;
99 CFIndex version = SOSPeerInfoGetVersion(peer);
100 CFStringRef peerName = SOSPeerInfoGetPeerName(peer);
101 CFStringRef devtype = SOSPeerInfoGetPeerDeviceType(peer);
102 CFStringRef peerID = SOSPeerInfoGetPeerID(peer);
103 CFStringRef transportType = CFSTR("KVS");
104 CFStringRef deviceID = CFSTR("");
105 CFDictionaryRef gestalt = SOSPeerInfoCopyPeerGestalt(peer);
106 CFStringRef osVersion = CFDictionaryGetValue(gestalt, CFSTR("OSVersion"));
107 CFReleaseNull(gestalt);
108
109
110 if(version >= 2){
111 CFDictionaryRef v2Dictionary = peer->v2Dictionary;
112 transportType = CFDictionaryGetValue(v2Dictionary, sTransportType);
113 deviceID = CFDictionaryGetValue(v2Dictionary, sDeviceID);
114 }
115 char *pname = CFStringToCString(peerName);
116 char *dname = CFStringToCString(devtype);
117 char *tname = CFStringToCString(transportType);
118 char *iname = CFStringToCString(deviceID);
119 char *osname = CFStringToCString(osVersion);
120 const char *me = CFEqualSafe(mypeerID, peerID) ? "me>" : " ";
121
122
123 snprintf(buf, 160, "%s %s: %-16s %-16s %-16s %-16s", me, label, pname, dname, tname, iname);
124
125 free(pname);
126 free(dname);
127 CFStringRef pid = SOSPeerInfoGetPeerID(peer);
128 CFIndex vers = SOSPeerInfoGetVersion(peer);
129 printmsg(CFSTR("%s %@ V%d OS:%s\n"), buf, pid, vers, osname);
130 free(osname);
131 });
132 } else {
133 printmsg(CFSTR("No %s, error: %@\n"), label, error);
134 }
135 CFReleaseNull(ppi);
136 CFReleaseNull(error);
137 }
138
139 void SOSCCDumpCircleInformation()
140 {
141 CFErrorRef error = NULL;
142 CFArrayRef generations = NULL;
143 bool is_accountKeyIsTrusted = false;
144 __block int count = 0;
145
146 SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error);
147 printmsg(CFSTR("ccstatus: %s (%d)\n"), getSOSCCStatusDescription(ccstatus), ccstatus);
148
149 is_accountKeyIsTrusted = SOSCCValidateUserPublic(&error);
150 if(is_accountKeyIsTrusted)
151 printmsg(CFSTR("Account user public is trusted%@"),CFSTR("\n"));
152 else
153 printmsg(CFSTR("Account user public is not trusted error:(%@)\n"), error);
154 CFReleaseNull(error);
155
156 generations = SOSCCCopyGenerationPeerInfo(&error);
157 if(generations) {
158 CFArrayForEach(generations, ^(const void *value) {
159 count++;
160 if(count%2 == 0)
161 printmsg(CFSTR("Circle name: %@, "),value);
162
163 if(count%2 != 0) {
164 CFStringRef genDesc = SOSGenerationCountCopyDescription(value);
165 printmsg(CFSTR("Generation Count: %@"), genDesc);
166 CFReleaseNull(genDesc);
167 }
168 printmsg(CFSTR("%s\n"), "");
169 });
170 } else {
171 printmsg(CFSTR("No generation count: %@\n"), error);
172 }
173 CFReleaseNull(generations);
174 CFReleaseNull(error);
175
176 printPeerInfos(" Peers", ^(CFErrorRef *error) { return SOSCCCopyValidPeerPeerInfo(error); });
177 printPeerInfos(" Invalid", ^(CFErrorRef *error) { return SOSCCCopyNotValidPeerPeerInfo(error); });
178 printPeerInfos(" Retired", ^(CFErrorRef *error) { return SOSCCCopyRetirementPeerInfo(error); });
179 printPeerInfos(" Concur", ^(CFErrorRef *error) { return SOSCCCopyConcurringPeerPeerInfo(error); });
180 printPeerInfos("Applicants", ^(CFErrorRef *error) { return SOSCCCopyApplicantPeerInfo(error); });
181
182 CFReleaseNull(error);
183 }
184
185
186
187
188 /* KVS Dumping Support for iCloud Keychain */
189
190 static CFTypeRef getObjectsFromCloud(CFArrayRef keysToGet, dispatch_queue_t processQueue, dispatch_group_t dgroup)
191 {
192 __block CFTypeRef object = NULL;
193
194 const uint64_t maxTimeToWaitInSeconds = 30ull * NSEC_PER_SEC;
195 dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
196 dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds);
197
198 dispatch_group_enter(dgroup);
199
200 CloudKeychainReplyBlock replyBlock =
201 ^ (CFDictionaryRef returnedValues, CFErrorRef error)
202 {
203 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues);
204 object = returnedValues;
205 if (object)
206 CFRetain(object);
207 if (error)
208 {
209 secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error);
210 }
211 dispatch_group_leave(dgroup);
212 secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud block exit: %@", object);
213 dispatch_semaphore_signal(waitSemaphore);
214 };
215
216 if (!keysToGet)
217 SOSCloudKeychainGetAllObjectsFromCloud(processQueue, replyBlock);
218 else
219 SOSCloudKeychainGetObjectsFromCloud(keysToGet, processQueue, replyBlock);
220
221 dispatch_semaphore_wait(waitSemaphore, finishTime);
222 if (object && (CFGetTypeID(object) == CFNullGetTypeID())) // return a NULL instead of a CFNull
223 {
224 CFRelease(object);
225 object = NULL;
226 }
227 secerror("returned: %@", object);
228 return object;
229 }
230
231 static CFStringRef printFullDataString(CFDataRef data){
232 __block CFStringRef fullData = NULL;
233
234 BufferPerformWithHexString(CFDataGetBytePtr(data), CFDataGetLength(data), ^(CFStringRef dataHex) {
235 fullData = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), dataHex);
236 });
237
238 return fullData;
239 }
240
241 static void displayLastKeyParameters(CFTypeRef key, CFTypeRef value)
242 {
243 CFDataRef valueAsData = asData(value, NULL);
244 if(valueAsData){
245 CFDataRef dateData = CFDataCreateCopyFromRange(kCFAllocatorDefault, valueAsData, CFRangeMake(0, DATE_LENGTH));
246 CFDataRef keyParameterData = CFDataCreateCopyFromPositions(kCFAllocatorDefault, valueAsData, DATE_LENGTH, CFDataGetLength(valueAsData));
247 CFStringRef dateString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, dateData, kCFStringEncodingUTF8);
248 CFStringRef keyParameterDescription = UserParametersDescription(keyParameterData);
249 if(keyParameterDescription)
250 printmsg(CFSTR("%@: %@: %@\n"), key, dateString, keyParameterDescription);
251 else
252 printmsg(CFSTR("%@: %@\n"), key, printFullDataString(value));
253 CFReleaseNull(dateString);
254 CFReleaseNull(keyParameterData);
255 CFReleaseNull(dateData);
256 CFReleaseNull(keyParameterDescription);
257 }
258 else{
259 printmsg(CFSTR("%@: %@\n"), key, value);
260 }
261 }
262
263 static void displayKeyParameters(CFTypeRef key, CFTypeRef value)
264 {
265 if(isData(value)){
266 CFStringRef keyParameterDescription = UserParametersDescription((CFDataRef)value);
267
268 if(keyParameterDescription)
269 printmsg(CFSTR("%@: %@\n"), key, keyParameterDescription);
270 else
271 printmsg(CFSTR("%@: %@\n"), key, value);
272
273 CFReleaseNull(keyParameterDescription);
274 }
275 else{
276 printmsg(CFSTR("%@: %@\n"), key, value);
277 }
278 }
279
280 static void displayLastCircle(CFTypeRef key, CFTypeRef value)
281 {
282 CFDataRef valueAsData = asData(value, NULL);
283 if(valueAsData){
284 CFErrorRef localError = NULL;
285
286 CFDataRef dateData = CFDataCreateCopyFromRange(kCFAllocatorDefault, valueAsData, CFRangeMake(0, DATE_LENGTH));
287 CFDataRef circleData = CFDataCreateCopyFromPositions(kCFAllocatorDefault, valueAsData, DATE_LENGTH, CFDataGetLength(valueAsData));
288 CFStringRef dateString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, dateData, kCFStringEncodingUTF8);
289 SOSCircleRef circle = SOSCircleCreateFromData(NULL, (CFDataRef) circleData, &localError);
290
291 if(circle){
292 CFIndex size = 5;
293 CFNumberRef idLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &size);
294 CFDictionaryRef format = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength, NULL);
295 printmsgWithFormatOptions(format, CFSTR("%@: %@: %@\n"), key, dateString, circle);
296 CFReleaseNull(idLength);
297 CFReleaseNull(format);
298
299 }
300 else
301 printmsg(CFSTR("%@: %@\n"), key, printFullDataString(circleData));
302
303 CFReleaseNull(dateString);
304 CFReleaseNull(circleData);
305 CFReleaseSafe(circle);
306 CFReleaseNull(dateData);
307 CFReleaseNull(localError);
308 }
309 else{
310 printmsg(CFSTR("%@: %@\n"), key, value);
311 }
312 }
313
314 static void displayCircle(CFTypeRef key, CFTypeRef value)
315 {
316 CFDataRef circleData = (CFDataRef)value;
317
318 CFErrorRef localError = NULL;
319 if (isData(circleData))
320 {
321 CFIndex size = 5;
322 CFNumberRef idLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &size);
323 CFDictionaryRef format = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength, NULL);
324 SOSCircleRef circle = SOSCircleCreateFromData(NULL, circleData, &localError);
325 printmsgWithFormatOptions(format, CFSTR("%@: %@\n"), key, circle);
326 CFReleaseSafe(circle);
327 CFReleaseNull(idLength);
328 CFReleaseNull(format);
329
330 }
331 else
332 printmsg(CFSTR("%@: %@\n"), key, value);
333 }
334
335 static void displayMessage(CFTypeRef key, CFTypeRef value)
336 {
337 CFDataRef message = (CFDataRef)value;
338 if(isData(message)){
339 const char* messageType = SecOTRPacketTypeString(message);
340 printmsg(CFSTR("%@: %s: %ld\n"), key, messageType, CFDataGetLength(message));
341 }
342 else
343 printmsg(CFSTR("%@: %@\n"), key, value);
344 }
345
346 static void printEverything(CFTypeRef objects)
347 {
348 CFDictionaryForEach(objects, ^(const void *key, const void *value) {
349 if (isData(value))
350 {
351 printmsg(CFSTR("%@: %@\n\n"), key, printFullDataString(value));
352 }
353 else
354 printmsg(CFSTR("%@: %@\n"), key, value);
355 });
356
357 }
358
359 static void decodeForKeyType(CFTypeRef key, CFTypeRef value, SOSKVSKeyType type){
360 switch (type) {
361 case kCircleKey:
362 displayCircle(key, value);
363 break;
364 case kRetirementKey:
365 case kMessageKey:
366 displayMessage(key, value);
367 break;
368 case kParametersKey:
369 displayKeyParameters(key, value);
370 break;
371 case kLastKeyParameterKey:
372 displayLastKeyParameters(key, value);
373 break;
374 case kLastCircleKey:
375 displayLastCircle(key, value);
376 break;
377 case kInitialSyncKey:
378 case kAccountChangedKey:
379 case kDebugInfoKey:
380 case kRingKey:
381 default:
382 printmsg(CFSTR("%@: %@\n"), key, value);
383 break;
384 }
385 }
386
387 static void decodeAllTheValues(CFTypeRef objects){
388 SOSKVSKeyType keyType = 0;
389 __block bool didPrint = false;
390
391 for (keyType = 0; keyType <= MAXKVSKEYTYPE; keyType++){
392 CFDictionaryForEach(objects, ^(const void *key, const void *value) {
393 if(SOSKVSKeyGetKeyType(key) == keyType){
394 decodeForKeyType(key, value, keyType);
395 didPrint = true;
396 }
397 });
398 if(didPrint)
399 printmsg(CFSTR("%@\n"), CFSTR(""));
400 didPrint = false;
401 }
402 }
403
404 bool SOSCCDumpCircleKVSInformation(char *itemName) {
405 CFArrayRef keysToGet = NULL;
406 if (itemName)
407 {
408 CFStringRef itemStr = CFStringCreateWithCString(kCFAllocatorDefault, itemName, kCFStringEncodingUTF8);
409 fprintf(outFile, "Retrieving %s from KVS\n", itemName);
410 keysToGet = CFArrayCreateForCFTypes(kCFAllocatorDefault, itemStr, NULL);
411 CFReleaseSafe(itemStr);
412 }
413 dispatch_queue_t generalq = dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL);
414 dispatch_group_t work_group = dispatch_group_create();
415 CFTypeRef objects = getObjectsFromCloud(keysToGet, generalq, work_group);
416 CFReleaseSafe(keysToGet);
417 if (objects)
418 {
419 fprintf(outFile, "All keys and values straight from KVS\n");
420 printEverything(objects);
421 fprintf(outFile, "\nAll values in decoded form...\n");
422 decodeAllTheValues(objects);
423 }
424 fprintf(outFile, "\n");
425 return true;
426 }