]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainLogging.c
Security-57740.1.18.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / CKBridge / SOSCloudKeychainLogging.c
1 //
2 // SOSCloudKeychainLogging.c
3 // sec
4 //
5 // Created by Richard Murphy on 6/21/16.
6 //
7 //
8
9 #include <AssertMacros.h>
10 #include <CoreFoundation/CoreFoundation.h>
11 //#include <syslog.h>
12 //#include <os/activity.h>
13 #include <utilities/debugging.h>
14 #include <utilities/SecCFWrappers.h>
15 #include <utilities/SecXPCError.h>
16 #include "SOSCloudKeychainConstants.h"
17 #include "SOSCloudKeychainClient.h"
18 #include "SOSKVSKeys.h"
19 #include "SOSUserKeygen.h"
20 #include "SecOTRSession.h"
21 #include "SOSCloudKeychainLogging.h"
22
23
24 #define DATE_LENGTH 18
25
26 #define KVSLOGSTATE "kvsLogState"
27
28 static CFStringRef SOSCloudKVSCreateDateFromValue(CFDataRef valueAsData) {
29 CFStringRef dateString = NULL;
30 CFDataRef dateData = CFDataCreateCopyFromRange(kCFAllocatorDefault, valueAsData, CFRangeMake(0, DATE_LENGTH));
31 require_quiet(dateData, retOut);
32 dateString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, dateData, kCFStringEncodingUTF8);
33 CFReleaseNull(dateData);
34 retOut:
35 return dateString;
36 }
37
38 static CFDataRef SOSCloudKVSCreateDataFromValueAfterDate(CFDataRef valueAsData) {
39 return CFDataCreateCopyFromPositions(kCFAllocatorDefault, valueAsData, DATE_LENGTH, CFDataGetLength(valueAsData));
40 }
41
42 static void SOSCloudKVSLogCircle(CFTypeRef key, CFStringRef dateString, CFTypeRef value) {
43 if(!isData(value)) return;
44 SOSCircleRef circle = SOSCircleCreateFromData(NULL, value, NULL);
45 require_quiet(circle, retOut);
46 secnotice(KVSLOGSTATE, "%@ %@:", key, dateString);
47 SOSCircleLogState(KVSLOGSTATE, circle, NULL, NULL);
48 CFReleaseSafe(circle);
49 retOut:
50 return;
51 }
52
53 static void SOSCloudKVSLogLastCircle(CFTypeRef key, CFTypeRef value) {
54 if(!isData(value)) return;
55 CFStringRef circle = NULL;
56 CFStringRef from = NULL;
57 CFStringRef peerID = CFSTR(" ");
58 bool parsed = SOSKVSKeyParse(kLastCircleKey, key, &circle, NULL, NULL, NULL, &from, NULL);
59 if(parsed) {
60 peerID = from;
61 }
62 CFStringRef speerID = CFStringCreateTruncatedCopy(peerID, 8);
63 CFStringRef dateString = SOSCloudKVSCreateDateFromValue(value);
64 CFDataRef circleData = SOSCloudKVSCreateDataFromValueAfterDate(value);
65 CFStringRef keyPrefix = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ from %@: "), circle, speerID);
66 SOSCloudKVSLogCircle(keyPrefix, dateString, circleData);
67 CFReleaseNull(keyPrefix);
68 CFReleaseNull(speerID);
69 CFReleaseNull(from);
70 CFReleaseNull(dateString);
71 CFReleaseNull(circleData);
72 }
73
74 static void SOSCloudKVSLogKeyParameters(CFTypeRef key, CFStringRef dateString, CFTypeRef value) {
75 if(!isData(value)) return;
76 CFStringRef keyParameterDescription = UserParametersDescription(value);
77 if(!keyParameterDescription) keyParameterDescription = CFDataCopyHexString(value);
78 secnotice(KVSLOGSTATE, "%@: %@: %@", key, dateString, keyParameterDescription);
79 CFReleaseNull(keyParameterDescription);
80 }
81
82 static void SOSCloudKVSLogLastKeyParameters(CFTypeRef key, CFTypeRef value) {
83 if(!isData(value)) return;
84 CFStringRef from = NULL;
85 CFStringRef peerID = CFSTR(" ");
86 bool parsed = SOSKVSKeyParse(kLastKeyParameterKey, key, NULL, NULL, NULL, NULL, &from, NULL);
87 if(parsed) {
88 peerID = from;
89 }
90 CFStringRef speerID = CFStringCreateTruncatedCopy(peerID, 8);
91 CFDataRef keyParameterData = SOSCloudKVSCreateDataFromValueAfterDate(value);
92 CFStringRef dateString = SOSCloudKVSCreateDateFromValue(value);
93 CFStringRef keyPrefix = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("k%@ from %@: "), kSOSKVSKeyParametersKey, speerID);
94
95 SOSCloudKVSLogKeyParameters(keyPrefix, dateString, keyParameterData);
96 CFReleaseNull(keyPrefix);
97 CFReleaseNull(speerID);
98 CFReleaseNull(dateString);
99 CFReleaseNull(from);
100 CFReleaseNull(keyParameterData);
101 }
102
103 static void SOSCloudKVSLogMessage(CFTypeRef key, CFTypeRef value) {
104 CFStringRef circle = NULL;
105 CFStringRef from = NULL;
106 CFStringRef to = NULL;
107 bool parsed = SOSKVSKeyParse(kMessageKey, key, &circle, NULL, NULL, NULL, &from, &to);
108 if(parsed) {
109 CFStringRef sfrom = CFStringCreateTruncatedCopy(from, 8);
110 CFStringRef sto = CFStringCreateTruncatedCopy(to, 8);
111 if(isData(value)){
112 const char* messageType = SecOTRPacketTypeString(value);
113 secnotice(KVSLOGSTATE, "message packet from: %@ to: %@ : %s: %ld", sfrom, sto, messageType, CFDataGetLength(value));
114 } else {
115 secnotice(KVSLOGSTATE, "message packet from: %@ to: %@: %@", sfrom, sto, value);
116 }
117 CFReleaseNull(sfrom);
118 CFReleaseNull(sto);
119 } else {
120 secnotice(KVSLOGSTATE, "%@: %@", key, value);
121 }
122 CFReleaseNull(circle);
123 CFReleaseNull(from);
124 CFReleaseNull(to);
125 }
126
127 static void SOSCloudKVSLogRetirement(CFTypeRef key, CFTypeRef value) {
128 CFStringRef circle = NULL;
129 CFStringRef from = NULL;
130 bool parsed = SOSKVSKeyParse(kRetirementKey, key, &circle, NULL, NULL, NULL, &from, NULL);
131 if(parsed) {
132 CFStringRef sfrom = CFStringCreateTruncatedCopy(from, 8);
133 secnotice(KVSLOGSTATE, "Retired Peer: %@, from Circle: %@", sfrom, circle);
134 CFReleaseNull(sfrom);
135 } else {
136 secnotice(KVSLOGSTATE, "Retired Peer format unknown - %@", key);
137 }
138 CFReleaseNull(circle);
139 CFReleaseNull(from);
140 }
141
142 static void SOSCloudKVSLogKeyType(CFTypeRef key, CFTypeRef value, SOSKVSKeyType type){
143 switch (type) {
144 case kCircleKey:
145 SOSCloudKVSLogCircle(key, CFSTR(" Current "), value);
146 break;
147 case kRetirementKey:
148 SOSCloudKVSLogRetirement(key, value);
149 break;
150 case kMessageKey:
151 SOSCloudKVSLogMessage(key, value);
152 break;
153 case kParametersKey:
154 SOSCloudKVSLogKeyParameters(key, CFSTR(" Current "), value);
155 break;
156 case kLastKeyParameterKey:
157 SOSCloudKVSLogLastKeyParameters(key, value);
158 break;
159 case kLastCircleKey:
160 SOSCloudKVSLogLastCircle(key, value);
161 break;
162 case kInitialSyncKey:
163 case kAccountChangedKey:
164 case kDebugInfoKey:
165 case kRingKey:
166 case kPeerInfoKey:
167 default:
168 break;
169 }
170 }
171
172 void SOSCloudKVSLogState(void) {
173 static int ordering[] = {
174 kParametersKey,
175 kLastKeyParameterKey,
176 kCircleKey,
177 kLastCircleKey,
178 kRetirementKey,
179 kMessageKey,
180 kInitialSyncKey,
181 kAccountChangedKey,
182 kDebugInfoKey,
183 kRingKey,
184 kPeerInfoKey,
185 kUnknownKey,
186 };
187 dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
188 dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, 10ull * NSEC_PER_SEC);
189 static volatile bool inUse = false; // Don't let log attempts stack
190
191 if(!inUse) {
192 inUse = true;
193 dispatch_retain(waitSemaphore);
194 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
195 CFDictionaryRef kvsDictionary = SOSCloudCopyKVSState();
196 if(kvsDictionary){
197 secnotice(KVSLOGSTATE, "Start");
198 // if we have anything to log - do it here.
199 for (size_t i = 0; i < (sizeof(ordering) / sizeof(SOSKVSKeyType)); i++){
200 CFDictionaryForEach(kvsDictionary, ^(const void *key, const void *value) {
201 if(SOSKVSKeyGetKeyType(key) == ordering[i]){
202 SOSCloudKVSLogKeyType(key, value, ordering[i]);
203 }
204 });
205 }
206 secnotice(KVSLOGSTATE, "Finish");
207 CFReleaseNull(kvsDictionary);
208 } else{
209 secnotice(KVSLOGSTATE, "dictionary from KVS is NULL");
210 }
211
212 inUse=false;
213 dispatch_semaphore_signal(waitSemaphore);
214 dispatch_release(waitSemaphore);
215 });
216 }
217
218 dispatch_semaphore_wait(waitSemaphore, finishTime);
219 dispatch_release(waitSemaphore);
220
221 }
222