]> git.saurik.com Git - apple/security.git/blob - OSX/sec/ipc/server.c
Security-57337.20.44.tar.gz
[apple/security.git] / OSX / sec / ipc / server.c
1 /*
2 * Copyright (c) 2007-2015 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <Security/SecureObjectSync/SOSPeerInfoDER.h>
25 #include <Security/SecureObjectSync/SOSCloudCircle.h>
26 #include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
27 #include <Security/SecureObjectSync/SOSInternal.h>
28 #include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
29 #include <Security/SecBasePriv.h>
30 #include <Security/SecCertificatePriv.h>
31 #include <Security/SecEntitlements.h>
32 #include <Security/SecInternal.h>
33 #include <Security/SecItemPriv.h> /* For SecItemDeleteAll */
34 #include <Security/SecPolicyInternal.h>
35 #include <Security/SecTask.h>
36 #include <Security/SecuritydXPC.h>
37 #include <securityd/OTATrustUtilities.h>
38 #include <securityd/SOSCloudCircleServer.h>
39 #include <securityd/SecItemBackupServer.h>
40 #include <securityd/SecItemServer.h>
41 #include <securityd/SecLogSettingsServer.h>
42 #include <securityd/SecOTRRemote.h>
43 #include <securityd/SecTrustServer.h>
44 #include <securityd/SecTrustStoreServer.h>
45 #include <securityd/iCloudTrace.h>
46 #include <securityd/spi.h>
47 #include <utilities/SecCFError.h>
48 #include <utilities/SecCFWrappers.h>
49 #include <utilities/SecDb.h>
50 #include <utilities/SecIOFormat.h>
51 #include <utilities/SecXPCError.h>
52 #include <utilities/debugging.h>
53 #include <utilities/SecInternalReleasePriv.h>
54
55 #include <AssertMacros.h>
56 #include <CoreFoundation/CFXPCBridge.h>
57 #include <CoreFoundation/CoreFoundation.h>
58 // <rdar://problem/22425706> 13B104+Roots:Device never moved past spinner after using approval to ENABLE icdp
59 #if (TARGET_OS_MAC && TARGET_OS_EMBEDDED)
60 #include <MobileKeyBag/MobileKeyBag.h>
61 #endif // #if (TARGET_OS_MAC && TARGET_OS_EMBEDDED)
62 #include <asl.h>
63 #include <bsm/libbsm.h>
64 #include <ipc/securityd_client.h>
65 #include <libkern/OSAtomic.h>
66 #include <mach/mach.h>
67 #include <mach/message.h>
68 #include <notify.h>
69 #include <stdlib.h>
70 #include <sys/queue.h>
71 #include <sys/sysctl.h>
72 #include <syslog.h>
73 #include <xpc/private.h>
74 #include <xpc/xpc.h>
75
76 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
77 #include <Security/SecTaskPriv.h>
78 #endif
79
80 static CFStringRef SecTaskCopyStringForEntitlement(SecTaskRef task,
81 CFStringRef entitlement)
82 {
83 CFStringRef value = (CFStringRef)SecTaskCopyValueForEntitlement(task,
84 entitlement, NULL);
85 if (value && CFGetTypeID(value) != CFStringGetTypeID()) {
86 CFRelease(value);
87 value = NULL;
88 }
89
90 return value;
91 }
92
93 static CFArrayRef SecTaskCopyArrayOfStringsForEntitlement(SecTaskRef task,
94 CFStringRef entitlement)
95 {
96 CFArrayRef value = (CFArrayRef)SecTaskCopyValueForEntitlement(task,
97 entitlement, NULL);
98 if (value) {
99 if (CFGetTypeID(value) == CFArrayGetTypeID()) {
100 CFIndex ix, count = CFArrayGetCount(value);
101 for (ix = 0; ix < count; ++ix) {
102 CFStringRef string = (CFStringRef)CFArrayGetValueAtIndex(value, ix);
103 if (CFGetTypeID(string) != CFStringGetTypeID()) {
104 CFRelease(value);
105 value = NULL;
106 break;
107 }
108 }
109 } else {
110 CFRelease(value);
111 value = NULL;
112 }
113 }
114
115 return value;
116 }
117
118 static CFStringRef SecTaskCopyApplicationIdentifier(SecTaskRef task) {
119 return SecTaskCopyStringForEntitlement(task,
120 kSecEntitlementApplicationIdentifier);
121 }
122
123 static CFArrayRef SecTaskCopySharedWebCredentialDomains(SecTaskRef task) {
124 return SecTaskCopyArrayOfStringsForEntitlement(task,
125 kSecEntitlementAssociatedDomains);
126 }
127
128 static CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task) {
129 CFMutableArrayRef groups = NULL;
130 CFArrayRef keychainAccessGroups = SecTaskCopyArrayOfStringsForEntitlement(task,
131 kSecEntitlementKeychainAccessGroups);
132 CFArrayRef appleSecurityApplicationGroups = SecTaskCopyArrayOfStringsForEntitlement(task,
133 kSecEntitlementAppleSecurityApplicationGroups);
134 CFStringRef appID = SecTaskCopyApplicationIdentifier(task);
135 CFIndex kagLen = keychainAccessGroups ? CFArrayGetCount(keychainAccessGroups) : 0;
136 CFIndex asagLen = appleSecurityApplicationGroups ? CFArrayGetCount(appleSecurityApplicationGroups) : 0;
137 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
138 if ((appID || asagLen) && !SecTaskEntitlementsValidated(task)) {
139 CFReleaseNull(appID);
140 asagLen = 0;
141 }
142 #endif
143 CFIndex len = kagLen + asagLen + (appID ? 1 : 0);
144 if (len) {
145 groups = CFArrayCreateMutable(kCFAllocatorDefault, len, &kCFTypeArrayCallBacks);
146 if (kagLen)
147 CFArrayAppendArray(groups, keychainAccessGroups, CFRangeMake(0, kagLen));
148 if (appID)
149 CFArrayAppendValue(groups, appID);
150 if (asagLen)
151 CFArrayAppendArray(groups, appleSecurityApplicationGroups, CFRangeMake(0, asagLen));
152 #if TARGET_IPHONE_SIMULATOR
153 } else {
154 secwarning("No keychain access group specified whilst running in simulator, falling back to default set");
155 groups = (CFMutableArrayRef)CFRetainSafe(SecAccessGroupsGetCurrent());
156 #endif
157 }
158
159 CFReleaseSafe(appID);
160 CFReleaseSafe(keychainAccessGroups);
161 CFReleaseSafe(appleSecurityApplicationGroups);
162 return groups;
163 }
164
165 static pthread_key_t taskThreadKey;
166 static void secTaskDiagnoseEntitlements(CFArrayRef accessGroups) {
167 SecTaskRef taskRef = pthread_getspecific(taskThreadKey);
168 if (taskRef == NULL) {
169 secerror("MISSING keychain entitlements: no stored taskRef found");
170 return;
171 }
172
173 CFErrorRef error = NULL;
174 CFArrayRef entitlementNames = CFArrayCreateForCFTypes(NULL,
175 kSecEntitlementApplicationIdentifier,
176 kSecEntitlementKeychainAccessGroups,
177 kSecEntitlementAppleSecurityApplicationGroups,
178 NULL);
179 CFDictionaryRef rawEntitlements = SecTaskCopyValuesForEntitlements(taskRef, entitlementNames, &error);
180 CFRelease(entitlementNames);
181
182 if (rawEntitlements == NULL) {
183 secerror("MISSING keychain entitlements: retrieve-entitlements error %@", error);
184 CFReleaseSafe(error);
185 __security_simulatecrash(CFSTR("failed to read keychain client entitlement(s)"), __sec_exception_code_MissingEntitlements);
186 return;
187 }
188
189 secerror("MISSING keychain entitlements: raw entitlement values: %@", rawEntitlements);
190 secerror("MISSING keychain entitlements: original ag: %@", accessGroups);
191 CFArrayRef newAccessGroups = SecTaskCopyAccessGroups(taskRef);
192 secerror("MISSING keychain entitlements: newly parsed ag: %@", newAccessGroups);
193
194 __security_simulatecrash(CFSTR("keychain entitlement(s) missing"), __sec_exception_code_MissingEntitlements);
195
196 CFReleaseSafe(newAccessGroups);
197 CFReleaseSafe(rawEntitlements);
198 }
199
200 static bool SecTaskGetBooleanValueForEntitlement(SecTaskRef task,
201 CFStringRef entitlement) {
202 CFStringRef canModify = (CFStringRef)SecTaskCopyValueForEntitlement(task,
203 entitlement, NULL);
204 if (!canModify)
205 return false;
206 CFTypeID canModifyType = CFGetTypeID(canModify);
207 bool ok = (CFBooleanGetTypeID() == canModifyType) && CFBooleanGetValue((CFBooleanRef)canModify);
208 CFRelease(canModify);
209 return ok;
210 }
211
212 static void with_label_and_password(xpc_object_t message, void (^action)(CFStringRef label, CFDataRef password)) {
213 const char *label_utf8 = xpc_dictionary_get_string(message, kSecXPCKeyUserLabel);
214
215 if (label_utf8) { // Anything we would do here requires a user label
216 size_t password_length = 0;
217 const void *password_data = xpc_dictionary_get_data(message, kSecXPCKeyUserPassword, &password_length);
218
219 CFDataRef user_password = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, password_data, password_length, kCFAllocatorNull);
220 CFStringRef user_label = CFStringCreateWithCString(kCFAllocatorDefault, label_utf8, kCFStringEncodingUTF8);
221
222 action(user_label, user_password);
223
224 CFReleaseNull(user_password);
225 CFReleaseNull(user_label);
226 }
227 }
228
229 static void with_label_and_password_and_dsid(xpc_object_t message, void (^action)(CFStringRef label, CFDataRef password, CFStringRef dsid)) {
230 const char *label_utf8 = xpc_dictionary_get_string(message, kSecXPCKeyUserLabel);
231
232 if (label_utf8) { // Anything we would do here requires a user label
233 size_t password_length = 0;
234 const void *password_data = xpc_dictionary_get_data(message, kSecXPCKeyUserPassword, &password_length);
235 const char *xdsid = xpc_dictionary_get_string(message, kSecXPCKeyDSID);
236
237 CFDataRef user_password = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, password_data, password_length, kCFAllocatorNull);
238 CFStringRef user_label = CFStringCreateWithCString(kCFAllocatorDefault, label_utf8, kCFStringEncodingUTF8);
239 CFStringRef dsid = CFStringCreateWithCString(kCFAllocatorDefault, xdsid, kCFStringEncodingUTF8);
240
241 action(user_label, user_password, dsid);
242
243 CFReleaseNull(dsid);
244 CFReleaseNull(user_password);
245 CFReleaseNull(user_label);
246 }
247 }
248
249 static void with_label_and_number(xpc_object_t message, void (^action)(CFStringRef label, uint64_t number)) {
250 const char *label_utf8 = xpc_dictionary_get_string(message, kSecXPCKeyViewName);
251 const int64_t number = xpc_dictionary_get_int64(message, kSecXPCKeyViewActionCode);
252 secnotice("views", "Action Code Raw is %d", (int) number);
253 CFStringRef user_label = CFStringCreateWithCString(kCFAllocatorDefault, label_utf8, kCFStringEncodingUTF8);
254
255 action(user_label, number);
256 CFReleaseNull(user_label);
257 }
258
259 static bool SecXPCDictionarySetChainOptional(xpc_object_t message, const char *key, SecCertificatePathRef path, CFErrorRef *error) {
260 if (!path)
261 return true;
262 xpc_object_t xpc_chain = SecCertificatePathCopyXPCArray(path, error);
263 if (!xpc_chain)
264 return false;
265
266 xpc_dictionary_set_value(message, key, xpc_chain);
267 xpc_release(xpc_chain);
268 return true;
269 }
270
271 static SecCertificateRef SecXPCDictionaryCopyCertificate(xpc_object_t message, const char *key, CFErrorRef *error) {
272 size_t length = 0;
273 const void *bytes = xpc_dictionary_get_data(message, key, &length);
274 if (bytes) {
275 SecCertificateRef certificate = SecCertificateCreateWithBytes(kCFAllocatorDefault, bytes, length);
276 if (certificate)
277 return certificate;
278 SecError(errSecDecode, error, CFSTR("object for key %s failed to create certificate from data"), key);
279 } else {
280 SecError(errSecParam, error, CFSTR("object for key %s missing"), key);
281 }
282 return NULL;
283 }
284
285 static bool SecXPCDictionaryCopyCertificates(xpc_object_t message, const char *key, CFArrayRef *certificates, CFErrorRef *error) {
286 xpc_object_t xpc_certificates = xpc_dictionary_get_value(message, key);
287 if (!xpc_certificates)
288 return SecError(errSecAllocate, error, CFSTR("no certs for key %s"), key);
289 *certificates = SecCertificateXPCArrayCopyArray(xpc_certificates, error);
290 return *certificates;
291 }
292
293 static bool SecXPCDictionaryCopyCertificatesOptional(xpc_object_t message, const char *key, CFArrayRef *certificates, CFErrorRef *error) {
294 xpc_object_t xpc_certificates = xpc_dictionary_get_value(message, key);
295 if (!xpc_certificates) {
296 *certificates = NULL;
297 return true;
298 }
299 *certificates = SecCertificateXPCArrayCopyArray(xpc_certificates, error);
300 return *certificates;
301 }
302
303 static bool SecXPCDictionaryCopyPoliciesOptional(xpc_object_t message, const char *key, CFArrayRef *policies, CFErrorRef *error) {
304 xpc_object_t xpc_policies = xpc_dictionary_get_value(message, key);
305 if (!xpc_policies) {
306 if (policies)
307 *policies = NULL;
308 return true;
309 }
310 *policies = SecPolicyXPCArrayCopyArray(xpc_policies, error);
311 return *policies != NULL;
312 }
313
314 static SecTrustStoreRef SecXPCDictionaryGetTrustStore(xpc_object_t message, const char *key, CFErrorRef *error) {
315 SecTrustStoreRef ts = NULL;
316 CFStringRef domain = SecXPCDictionaryCopyString(message, key, error);
317 if (domain) {
318 ts = SecTrustStoreForDomainName(domain, error);
319 CFRelease(domain);
320 }
321 return ts;
322 }
323
324 static bool SecXPCDictionaryGetDouble(xpc_object_t message, const char *key, double *pvalue, CFErrorRef *error) {
325 *pvalue = xpc_dictionary_get_double(message, key);
326 if (*pvalue == NAN) {
327 return SecError(errSecParam, error, CFSTR("object for key %s bad double"), key);
328 }
329 return true;
330 }
331
332 static CFArrayRef SecXPCDictionaryCopyPeerInfoArray(xpc_object_t dictionary, const char *key, CFErrorRef *error) {
333 return CreateArrayOfPeerInfoWithXPCObject(xpc_dictionary_get_value(dictionary, key), error);
334 }
335
336 static CFDataRef CFDataCreateWithXPCArrayAtIndex(xpc_object_t xpc_data_array, size_t index, CFErrorRef *error) {
337 CFDataRef data = NULL;
338 size_t length = 0;
339 const uint8_t *bytes = xpc_array_get_data(xpc_data_array, index, &length);
340 if (bytes) {
341 data = CFDataCreate(kCFAllocatorDefault, bytes, length);
342 }
343 if (!data)
344 SecError(errSecParam, error, CFSTR("data_array[%zu] failed to decode"), index);
345
346 return data;
347 }
348
349 static CFArrayRef CFDataXPCArrayCopyArray(xpc_object_t xpc_data_array, CFErrorRef *error) {
350 CFMutableArrayRef data_array = NULL;
351 require_action_quiet(xpc_get_type(xpc_data_array) == XPC_TYPE_ARRAY, exit,
352 SecError(errSecParam, error, CFSTR("data_array xpc value is not an array")));
353 size_t count = xpc_array_get_count(xpc_data_array);
354 require_action_quiet(data_array = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks), exit,
355 SecError(errSecAllocate, error, CFSTR("failed to create CFArray of capacity %zu"), count));
356
357 size_t ix;
358 for (ix = 0; ix < count; ++ix) {
359 CFDataRef data = CFDataCreateWithXPCArrayAtIndex(xpc_data_array, ix, error);
360 if (!data) {
361 CFRelease(data_array);
362 return NULL;
363 }
364 CFArraySetValueAtIndex(data_array, ix, data);
365 CFRelease(data);
366 }
367
368 exit:
369 return data_array;
370 }
371
372 static bool SecXPCDictionaryCopyCFDataArrayOptional(xpc_object_t message, const char *key, CFArrayRef *data_array, CFErrorRef *error) {
373 xpc_object_t xpc_data_array = xpc_dictionary_get_value(message, key);
374 if (!xpc_data_array) {
375 if (data_array)
376 *data_array = NULL;
377 return true;
378 }
379 *data_array = CFDataXPCArrayCopyArray(xpc_data_array, error);
380 return *data_array != NULL;
381 }
382
383 static CFSetRef SecXPCSetCreateFromXPCDictionaryElement(xpc_object_t event, const char *key) {
384 CFErrorRef error = NULL;
385 xpc_object_t object = xpc_dictionary_get_value(event, key);
386 CFSetRef retval = NULL;
387 if(object) retval = CreateCFSetRefFromXPCObject(object, &error);
388 CFReleaseNull(error);
389 return retval;
390 }
391
392 static inline
393 void xpc_dictionary_set_and_consume_CFArray(xpc_object_t xdict, const char *key, CF_CONSUMED CFArrayRef cf_array) {
394 if (cf_array) {
395 xpc_object_t xpc_array = _CFXPCCreateXPCObjectFromCFObject(cf_array);
396 xpc_dictionary_set_value(xdict, key, xpc_array);
397 xpc_release(xpc_array);
398 }
399 CFReleaseNull(cf_array);
400 }
401
402 static inline
403 bool xpc_dictionary_set_and_consume_PeerInfoArray(xpc_object_t xdict, const char *key, CF_CONSUMED CFArrayRef cf_array, CFErrorRef *error) {
404 bool success = true;
405 if (cf_array) {
406 xpc_object_t xpc_array = CreateXPCObjectWithArrayOfPeerInfo(cf_array, error);
407 if (xpc_array) {
408 xpc_dictionary_set_value(xdict, key, xpc_array);
409 xpc_release(xpc_array);
410 } else {
411 success = false;
412 }
413 }
414 CFReleaseNull(cf_array);
415 return success;
416 }
417
418 static bool
419 EntitlementMissing(enum SecXPCOperation op, SecTaskRef clientTask, CFStringRef entitlement, CFErrorRef *error)
420 {
421 SecError(errSecMissingEntitlement, error, CFSTR("%@: %@ lacks entitlement %@"), SOSCCGetOperationDescription(op), clientTask, entitlement);
422 return false;
423 }
424
425
426
427 static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, xpc_object_t event) {
428 xpc_type_t type = xpc_get_type(event);
429 __block CFErrorRef error = NULL;
430 xpc_object_t xpcError = NULL;
431 xpc_object_t replyMessage = NULL;
432 SecTaskRef clientTask = NULL;
433 CFDataRef clientAuditToken = NULL;
434 CFArrayRef accessGroups = NULL;
435 CFArrayRef domains = NULL;
436
437 secdebug("serverxpc", "entering");
438 if (type == XPC_TYPE_DICTIONARY) {
439 // TODO: Find out what we're dispatching.
440 replyMessage = xpc_dictionary_create_reply(event);
441
442 uint64_t operation = xpc_dictionary_get_uint64(event, kSecXPCKeyOperation);
443
444 bool hasEntitlement;
445 audit_token_t auditToken = {};
446 xpc_connection_get_audit_token(connection, &auditToken);
447
448 clientTask = SecTaskCreateWithAuditToken(kCFAllocatorDefault, auditToken);
449 clientAuditToken = CFDataCreate(kCFAllocatorDefault, (const UInt8*)&auditToken, sizeof(auditToken));
450 pthread_setspecific(taskThreadKey, clientTask);
451 accessGroups = SecTaskCopyAccessGroups(clientTask);
452 if (operation == sec_add_shared_web_credential_id || operation == sec_copy_shared_web_credential_id) {
453 domains = SecTaskCopySharedWebCredentialDomains(clientTask);
454 }
455
456 // TODO: change back to secdebug
457 secinfo("serverxpc", "XPC [%@] operation: %@ (%" PRIu64 ")", clientTask, SOSCCGetOperationDescription((enum SecXPCOperation)operation), operation);
458
459 if (true) {
460 // Ensure that we remain dirty for a minimum of two seconds to avoid jetsam loops.
461 // Refer to rdar://problem/18615626&18616300 for more details.
462 int64_t minimumDirtyInterval = (int64_t) (2 * NSEC_PER_SEC);
463 xpc_transaction_begin();
464 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, minimumDirtyInterval), dispatch_get_main_queue(), ^{
465 xpc_transaction_end();
466 });
467 }
468
469 // operations before kSecXPCOpTryUserCredentials don't need this entitlement.
470 hasEntitlement = (operation < kSecXPCOpTryUserCredentials) ||
471 (clientTask && SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementKeychainCloudCircle));
472
473 // Per <rdar://problem/13315020> Disable the entitlement check for "keychain-cloud-circle"
474 // we disable entitlement enforcement. However, we still log so we know who needs the entitlement
475
476 if (!hasEntitlement) {
477 CFErrorRef entitlementError = NULL;
478 SecError(errSecMissingEntitlement, &entitlementError, CFSTR("%@: %@ lacks entitlement %@"), SOSCCGetOperationDescription((enum SecXPCOperation)operation), clientTask, kSecEntitlementKeychainCloudCircle);
479 secnotice("serverxpc", "MissingEntitlement: %@", entitlementError);
480 CFReleaseSafe(entitlementError);
481 }
482
483 if (true) {
484 switch (operation)
485 {
486 case sec_item_add_id:
487 {
488 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
489 if (query) {
490 CFTypeRef result = NULL;
491 if (_SecItemAdd(query, accessGroups, &result, &error) && result) {
492 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
493 CFRelease(result);
494 }
495 CFRelease(query);
496 }
497 break;
498 }
499 case sec_item_copy_matching_id:
500 {
501 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
502 if (query) {
503 CFTypeRef result = NULL;
504 if (_SecItemCopyMatching(query, accessGroups, &result, &error) && result) {
505 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
506 CFRelease(result);
507 }
508 CFRelease(query);
509 }
510 break;
511 }
512 case sec_item_update_id:
513 {
514 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
515 if (query) {
516 CFDictionaryRef attributesToUpdate = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyAttributesToUpdate, &error);
517 if (attributesToUpdate) {
518 bool result = _SecItemUpdate(query, attributesToUpdate, accessGroups, &error);
519 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
520 CFRelease(attributesToUpdate);
521 }
522 CFRelease(query);
523 }
524 break;
525 }
526 case sec_item_delete_id:
527 {
528 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
529 if (query) {
530 bool result = _SecItemDelete(query, accessGroups, &error);
531 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
532 CFRelease(query);
533 }
534 break;
535 }
536 case sec_trust_store_contains_id:
537 {
538 SecTrustStoreRef ts = SecXPCDictionaryGetTrustStore(event, kSecXPCKeyDomain, &error);
539 if (ts) {
540 CFDataRef digest = SecXPCDictionaryCopyData(event, kSecXPCKeyDigest, &error);
541 if (digest) {
542 bool contains;
543 if (SecTrustStoreContainsCertificateWithDigest(ts, digest, &contains, &error))
544 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, contains);
545 CFRelease(digest);
546 }
547 }
548 break;
549 }
550 case sec_trust_store_set_trust_settings_id:
551 {
552 if (SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementModifyAnchorCertificates)) {
553 SecTrustStoreRef ts = SecXPCDictionaryGetTrustStore(event, kSecXPCKeyDomain, &error);
554 if (ts) {
555 SecCertificateRef certificate = SecXPCDictionaryCopyCertificate(event, kSecXPCKeyCertificate, &error);
556 if (certificate) {
557 CFTypeRef trustSettingsDictOrArray = NULL;
558 if (SecXPCDictionaryCopyPListOptional(event, kSecXPCKeySettings, &trustSettingsDictOrArray, &error)) {
559 bool result = _SecTrustStoreSetTrustSettings(ts, certificate, trustSettingsDictOrArray, &error);
560 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
561 CFReleaseSafe(trustSettingsDictOrArray);
562 }
563 CFRelease(certificate);
564 }
565 }
566 } else {
567 EntitlementMissing(((enum SecXPCOperation)operation), clientTask, kSecEntitlementModifyAnchorCertificates, &error);
568 }
569 break;
570 }
571 case sec_trust_store_remove_certificate_id:
572 {
573 if (SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementModifyAnchorCertificates)) {
574 SecTrustStoreRef ts = SecXPCDictionaryGetTrustStore(event, kSecXPCKeyDomain, &error);
575 if (ts) {
576 CFDataRef digest = SecXPCDictionaryCopyData(event, kSecXPCKeyDigest, &error);
577 if (digest) {
578 bool result = SecTrustStoreRemoveCertificateWithDigest(ts, digest, &error);
579 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
580 CFRelease(digest);
581 }
582 }
583 } else {
584 EntitlementMissing(((enum SecXPCOperation)operation), clientTask, kSecEntitlementModifyAnchorCertificates, &error);
585 }
586 break;
587 }
588 case sec_delete_all_id:
589 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, _SecItemDeleteAll(&error));
590 break;
591 case sec_trust_evaluate_id:
592 {
593 CFArrayRef certificates = NULL, anchors = NULL, policies = NULL, responses = NULL, scts = NULL, trustedLogs = NULL;
594 bool anchorsOnly = xpc_dictionary_get_bool(event, kSecTrustAnchorsOnlyKey);
595 double verifyTime;
596 if (SecXPCDictionaryCopyCertificates(event, kSecTrustCertificatesKey, &certificates, &error) &&
597 SecXPCDictionaryCopyCertificatesOptional(event, kSecTrustAnchorsKey, &anchors, &error) &&
598 SecXPCDictionaryCopyPoliciesOptional(event, kSecTrustPoliciesKey, &policies, &error) &&
599 SecXPCDictionaryCopyCFDataArrayOptional(event, kSecTrustResponsesKey, &responses, &error) &&
600 SecXPCDictionaryCopyCFDataArrayOptional(event, kSecTrustSCTsKey, &scts, &error) &&
601 SecXPCDictionaryCopyArrayOptional(event, kSecTrustTrustedLogsKey, &trustedLogs, &error) &&
602 SecXPCDictionaryGetDouble(event, kSecTrustVerifyDateKey, &verifyTime, &error)) {
603 // If we have no error yet, capture connection and reply in block and properly retain them.
604 xpc_retain(connection);
605 CFRetainSafe(clientTask);
606 CFRetainSafe(clientAuditToken);
607
608 // Clear replyMessage so we don't send a synchronous reply.
609 xpc_object_t asyncReply = replyMessage;
610 replyMessage = NULL;
611
612 SecTrustServerEvaluateBlock(clientAuditToken,
613 certificates, anchors, anchorsOnly, policies, responses, scts, trustedLogs, verifyTime, accessGroups,
614 ^(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef replyError) {
615 // Send back reply now
616 if (replyError) {
617 CFRetain(replyError);
618 } else {
619 xpc_dictionary_set_int64(asyncReply, kSecTrustResultKey, tr);
620 SecXPCDictionarySetPListOptional(asyncReply, kSecTrustDetailsKey, details, &replyError) &&
621 SecXPCDictionarySetPListOptional(asyncReply, kSecTrustInfoKey, info, &replyError) &&
622 SecXPCDictionarySetChainOptional(asyncReply, kSecTrustChainKey, chain, &replyError);
623 }
624 if (replyError) {
625 secdebug("ipc", "%@ %@ %@", clientTask, SOSCCGetOperationDescription((enum SecXPCOperation)operation), replyError);
626 xpc_object_t xpcReplyError = SecCreateXPCObjectWithCFError(replyError);
627 if (xpcReplyError) {
628 xpc_dictionary_set_value(asyncReply, kSecXPCKeyError, xpcReplyError);
629 xpc_release(xpcReplyError);
630 }
631 CFRelease(replyError);
632 } else {
633 secdebug("ipc", "%@ %@ responding %@", clientTask, SOSCCGetOperationDescription((enum SecXPCOperation)operation), asyncReply);
634 }
635
636 xpc_connection_send_message(connection, asyncReply);
637 xpc_release(asyncReply);
638 xpc_release(connection);
639 CFReleaseSafe(clientTask);
640 CFReleaseSafe(clientAuditToken);
641 });
642 }
643 CFReleaseSafe(policies);
644 CFReleaseSafe(anchors);
645 CFReleaseSafe(certificates);
646 CFReleaseSafe(responses);
647 CFReleaseSafe(scts);
648 CFReleaseSafe(trustedLogs);
649 break;
650 }
651 case sec_keychain_backup_id:
652 {
653 if (SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementRestoreKeychain)) {
654 CFDataRef keybag = NULL, passcode = NULL;
655 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyKeybag, &keybag, &error)) {
656 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
657 CFDataRef backup = _SecServerKeychainBackup(keybag, passcode, &error);
658 if (backup) {
659 SecXPCDictionarySetData(replyMessage, kSecXPCKeyResult, backup, &error);
660 CFRelease(backup);
661 }
662 CFReleaseSafe(passcode);
663 }
664 CFReleaseSafe(keybag);
665 }
666 } else {
667 EntitlementMissing(((enum SecXPCOperation)operation), clientTask, kSecEntitlementRestoreKeychain, &error);
668 }
669 break;
670 }
671 case sec_keychain_restore_id:
672 {
673 if (SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementRestoreKeychain)) {
674 CFDataRef backup = SecXPCDictionaryCopyData(event, kSecXPCKeyBackup, &error);
675 if (backup) {
676 CFDataRef keybag = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
677 if (keybag) {
678 CFDataRef passcode = NULL;
679 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
680 bool result = _SecServerKeychainRestore(backup, keybag, passcode, &error);
681 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
682 CFReleaseSafe(passcode);
683 }
684 CFRelease(keybag);
685 }
686 CFRelease(backup);
687 }
688 } else {
689 EntitlementMissing(((enum SecXPCOperation)operation), clientTask, kSecEntitlementRestoreKeychain, &error);
690 }
691 break;
692 }
693 case sec_keychain_sync_update_message_id:
694 {
695 CFDictionaryRef updates = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
696 if (updates) {
697 CFArrayRef result = _SecServerKeychainSyncUpdateMessage(updates, &error);
698 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
699 CFReleaseNull(result);
700 }
701 CFReleaseNull(updates);
702 break;
703 }
704 case sec_keychain_backup_syncable_id:
705 {
706 if (SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementRestoreKeychain)) {
707
708 CFDictionaryRef oldbackup = NULL;
709 if (SecXPCDictionaryCopyDictionaryOptional(event, kSecXPCKeyBackup, &oldbackup, &error)) {
710 CFDataRef keybag = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
711 if (keybag) {
712 CFDataRef passcode = NULL;
713 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
714 CFDictionaryRef newbackup = _SecServerBackupSyncable(oldbackup, keybag, passcode, &error);
715 if (newbackup) {
716 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, newbackup, &error);
717 CFRelease(newbackup);
718 }
719 CFReleaseSafe(passcode);
720 }
721 CFRelease(keybag);
722 }
723 CFReleaseSafe(oldbackup);
724 }
725 } else {
726 EntitlementMissing(((enum SecXPCOperation)operation), clientTask, kSecEntitlementRestoreKeychain, &error);
727 }
728 break;
729 }
730 case sec_keychain_restore_syncable_id:
731 {
732 if (SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementRestoreKeychain)) {
733
734 CFDictionaryRef backup = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyBackup, &error);
735 if (backup) {
736 CFDataRef keybag = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
737 if (keybag) {
738 CFDataRef passcode = NULL;
739 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
740 bool result = _SecServerRestoreSyncable(backup, keybag, passcode, &error);
741 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
742 CFReleaseSafe(passcode);
743 }
744 CFRelease(keybag);
745 }
746 CFRelease(backup);
747 }
748 } else {
749 EntitlementMissing(((enum SecXPCOperation)operation), clientTask, kSecEntitlementRestoreKeychain, &error);
750 }
751 break;
752 }
753 case sec_item_backup_copy_names_id:
754 {
755 if (SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementRestoreKeychain)) {
756 CFArrayRef names = SecServerItemBackupCopyNames(&error);
757 SecXPCDictionarySetPListOptional(replyMessage, kSecXPCKeyResult, names, &error);
758 CFReleaseSafe(names);
759 } else {
760 EntitlementMissing(((enum SecXPCOperation)operation), clientTask, kSecEntitlementRestoreKeychain, &error);
761 }
762 break;
763 }
764 case sec_item_backup_handoff_fd_id:
765 {
766 if (SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementRestoreKeychain)) {
767 CFStringRef backupName = SecXPCDictionaryCopyString(event, kSecXPCKeyBackup, &error);
768 int fd = -1;
769 if (backupName) {
770 fd = SecServerItemBackupHandoffFD(backupName, &error);
771 CFRelease(backupName);
772 }
773 SecXPCDictionarySetFileDescriptor(replyMessage, kSecXPCKeyResult, fd, &error);
774 if (fd != -1)
775 close(fd);
776 } else {
777 EntitlementMissing(((enum SecXPCOperation)operation), clientTask, kSecEntitlementRestoreKeychain, &error);
778 }
779 break;
780 }
781 case sec_item_backup_set_confirmed_manifest_id:
782 {
783 if (SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementRestoreKeychain)) {
784 CFDataRef keybagDigest = NULL;
785 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyKeybag, &keybagDigest, &error)) {
786 CFDataRef manifest = NULL;
787 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCData, &manifest, &error)) {
788 CFStringRef backupName = SecXPCDictionaryCopyString(event, kSecXPCKeyBackup, &error);
789 if (backupName) {
790 bool result = SecServerItemBackupSetConfirmedManifest(backupName, keybagDigest, manifest, &error);
791 CFRelease(backupName);
792 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
793 }
794 CFReleaseSafe(manifest);
795 }
796 CFReleaseNull(keybagDigest);
797 }
798 } else {
799 EntitlementMissing(((enum SecXPCOperation)operation), clientTask, kSecEntitlementRestoreKeychain, &error);
800 }
801 break;
802 }
803 case sec_item_backup_restore_id:
804 {
805 if (SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementRestoreKeychain)) {
806 bool result = false;
807 CFStringRef backupName = SecXPCDictionaryCopyString(event, kSecXPCKeyBackup, &error);
808 if (backupName) {
809 CFStringRef peerID = NULL;
810 if (SecXPCDictionaryCopyStringOptional(event, kSecXPCKeyDigest, &peerID, &error)) {
811 CFDataRef keybag = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
812 if (keybag) {
813 CFDataRef secret = SecXPCDictionaryCopyData(event, kSecXPCKeyUserPassword, &error);
814 if (secret) {
815 CFDataRef backup = SecXPCDictionaryCopyData(event, kSecXPCData, &error);
816 if (backup) {
817 result = SecServerItemBackupRestore(backupName, peerID, keybag, secret, backup, &error);
818 CFRelease(backup);
819 }
820 CFRelease(secret);
821 }
822 CFRelease(keybag);
823 }
824 CFReleaseSafe(peerID);
825 }
826 CFRelease(backupName);
827 }
828 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
829 } else {
830 EntitlementMissing(((enum SecXPCOperation)operation), clientTask, kSecEntitlementRestoreKeychain, &error);
831 }
832 break;
833 }
834 case sec_ota_pki_asset_version_id:
835 {
836 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
837 SecOTAPKIGetCurrentAssetVersion(&error));
838 break;
839 }
840 case sec_add_shared_web_credential_id:
841 {
842 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
843 if (query) {
844 CFTypeRef result = NULL;
845 CFStringRef appID = (clientTask) ? SecTaskCopyApplicationIdentifier(clientTask) : NULL;
846 if (_SecAddSharedWebCredential(query, &auditToken, appID, domains, &result, &error) && result) {
847 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
848 CFRelease(result);
849 }
850 CFReleaseSafe(appID);
851 CFRelease(query);
852 }
853 break;
854 }
855 case sec_copy_shared_web_credential_id:
856 {
857 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
858 if (query) {
859 CFTypeRef result = NULL;
860 CFStringRef appID = (clientTask) ? SecTaskCopyApplicationIdentifier(clientTask) : NULL;
861 if (_SecCopySharedWebCredential(query, &auditToken, appID, domains, &result, &error) && result) {
862 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
863 CFRelease(result);
864 }
865 CFReleaseSafe(appID);
866 CFRelease(query);
867 }
868 break;
869 }
870 case sec_get_log_settings_id:
871 {
872 CFPropertyListRef currentList = SecCopyLogSettings_Server(&error);
873 if (currentList) {
874 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, currentList, &error);
875 }
876 CFReleaseSafe(currentList);
877 break;
878 }
879 case sec_set_xpc_log_settings_id:
880 {
881 CFPropertyListRef newSettings = SecXPCDictionaryCopyPList(event, kSecXPCKeyQuery, &error);
882 if (newSettings) {
883 SecSetXPCLogSettings_Server(newSettings, &error);
884 }
885 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true);
886 CFReleaseNull(newSettings);
887 break;
888 }
889 case sec_set_circle_log_settings_id:
890 {
891 CFPropertyListRef newSettings = SecXPCDictionaryCopyPList(event, kSecXPCKeyQuery, &error);
892 if (newSettings) {
893 SecSetCircleLogSettings_Server(newSettings, &error);
894 }
895 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true);
896 CFReleaseNull(newSettings);
897 break;
898 }
899 case sec_otr_session_create_remote_id:
900 {
901 CFDataRef publicPeerId = NULL;
902 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCPublicPeerId, &publicPeerId, &error)) {
903 CFDataRef otrSession = _SecOTRSessionCreateRemote(publicPeerId, &error);
904 if (otrSession) {
905 SecXPCDictionarySetData(replyMessage, kSecXPCKeyResult, otrSession, &error);
906 CFRelease(otrSession);
907 }
908 CFReleaseSafe(publicPeerId);
909 }
910 break;
911 }
912 case sec_otr_session_process_packet_remote_id:
913 {
914 CFDataRef sessionData = NULL, inputPacket = NULL, outputSessionData = NULL, outputPacket = NULL;
915 bool readyForMessages = false;
916 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCOTRSession, &sessionData, &error)) {
917 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCData, &inputPacket, &error)) {
918 bool result = _SecOTRSessionProcessPacketRemote(sessionData, inputPacket, &outputSessionData, &outputPacket, &readyForMessages, &error);
919 if (result) {
920 SecXPCDictionarySetData(replyMessage, kSecXPCOTRSession, outputSessionData, &error);
921 SecXPCDictionarySetData(replyMessage, kSecXPCData, outputPacket, &error);
922 xpc_dictionary_set_bool(replyMessage, kSecXPCOTRReady, readyForMessages);
923 CFRelease(outputSessionData);
924 CFRelease(outputPacket);
925 }
926 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
927
928 CFReleaseSafe(inputPacket);
929 }
930 CFReleaseSafe(sessionData);
931 }
932 break;
933 }
934 case kSecXPCOpTryUserCredentials:
935 with_label_and_password(event, ^(CFStringRef label, CFDataRef password) {
936 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
937 SOSCCTryUserCredentials_Server(label, password, &error));
938 });
939 break;
940 case kSecXPCOpSetUserCredentials:
941 with_label_and_password(event, ^(CFStringRef label, CFDataRef password) {
942 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
943 SOSCCSetUserCredentials_Server(label, password, &error));
944 });
945 break;
946 case kSecXPCOpSetUserCredentialsAndDSID:
947 with_label_and_password_and_dsid(event, ^(CFStringRef label, CFDataRef password, CFStringRef dsid) {
948 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
949 SOSCCSetUserCredentialsAndDSID_Server(label, password, dsid, &error));
950 });
951 break;
952 case kSecXPCOpView:
953 with_label_and_number(event, ^(CFStringRef view, uint64_t actionCode) {
954 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
955 SOSCCView_Server(view, (SOSViewActionCode)actionCode, &error));
956 });
957 break;
958 case kSecXPCOpViewSet:
959 {
960 CFSetRef enabledViews = SecXPCSetCreateFromXPCDictionaryElement(event, kSecXPCKeyEnabledViewsKey);
961 CFSetRef disabledViews = SecXPCSetCreateFromXPCDictionaryElement(event, kSecXPCKeyDisabledViewsKey);
962 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCViewSet_Server(enabledViews, disabledViews));
963 CFReleaseNull(enabledViews);
964 CFReleaseNull(disabledViews);
965 }
966 break;
967 case kSecXPCOpSecurityProperty:
968 with_label_and_number(event, ^(CFStringRef property, uint64_t actionCode) {
969 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
970 SOSCCSecurityProperty_Server(property, (SOSSecurityPropertyActionCode)actionCode, &error));
971 });
972 break;
973 case kSecXPCOpCanAuthenticate:
974 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
975 SOSCCCanAuthenticate_Server(&error));
976 break;
977 case kSecXPCOpPurgeUserCredentials:
978 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
979 SOSCCPurgeUserCredentials_Server(&error));
980 break;
981 case kSecXPCOpDeviceInCircle:
982 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
983 SOSCCThisDeviceIsInCircle_Server(&error));
984 break;
985 case kSecXPCOpRequestToJoin:
986 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
987 SOSCCRequestToJoinCircle_Server(&error));
988 break;
989 case kSecXPCOpRequestToJoinAfterRestore:
990 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
991 SOSCCRequestToJoinCircleAfterRestore_Server(&error));
992 break;
993 case kSecXPCOpRequestEnsureFreshParameters:
994 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
995 SOSCCRequestEnsureFreshParameters_Server(&error));
996 break;
997 case kSecXPCOpGetAllTheRings:
998 {
999 CFStringRef ringDescriptions = SOSCCGetAllTheRings_Server(&error);
1000 xpc_object_t xpc_dictionary = _CFXPCCreateXPCObjectFromCFObject(ringDescriptions);
1001 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_dictionary);
1002 xpc_release(xpc_dictionary);
1003 }
1004 break;
1005 case kSecXPCOpApplyToARing:
1006 {
1007 CFStringRef ringName = SecXPCDictionaryCopyString(event, kSecXPCKeyString, &error);
1008 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCApplyToARing_Server(ringName, &error));
1009 CFReleaseNull(ringName);
1010 }
1011 break;
1012 case kSecXPCOpWithdrawlFromARing:
1013 {
1014 CFStringRef ringName = SecXPCDictionaryCopyString(event, kSecXPCKeyString, &error);
1015 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCWithdrawlFromARing_Server(ringName, &error));
1016 CFReleaseNull(ringName);
1017 }
1018 break;
1019 case kSecXPCOpRingStatus:
1020 {
1021 CFStringRef ringName = SecXPCDictionaryCopyString(event, kSecXPCKeyString, &error);
1022 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRingStatus_Server(ringName, &error));
1023 CFReleaseNull(ringName);
1024 }
1025 break;
1026 case kSecXPCOpEnableRing:
1027 {
1028 CFStringRef ringName = SecXPCDictionaryCopyString(event, kSecXPCKeyString, &error);
1029 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCEnableRing_Server(ringName, &error));
1030 CFReleaseNull(ringName);
1031 }
1032 break;
1033 case kSecXPCOpRequestDeviceID:
1034 {
1035 CFStringRef deviceID = SOSCCCopyDeviceID_Server(&error);
1036 if (deviceID) {
1037 SecXPCDictionarySetString(replyMessage, kSecXPCKeyResult, deviceID, &error);
1038 }
1039 CFReleaseNull(deviceID);
1040 }
1041 break;
1042 case kSecXPCOpSetDeviceID:
1043 {
1044 CFStringRef IDS = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error);
1045 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCSetDeviceID_Server(IDS, &error));
1046 CFReleaseNull(IDS);
1047 }
1048 break;
1049 case kSecXPCOpHandleIDSMessage:
1050 {
1051 CFDictionaryRef IDS = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyIDSMessage, &error);
1052 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult, SOSCCHandleIDSMessage_Server(IDS, &error));
1053 CFReleaseNull(IDS);
1054 }
1055 break;
1056
1057 case kSecXPCOpSendIDSMessage:
1058 {
1059 CFStringRef message = SecXPCDictionaryCopyString(event, kSecXPCKeySendIDSMessage, &error);
1060 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCIDSServiceRegistrationTest_Server(message, &error));
1061 CFReleaseNull(message);
1062 }
1063 break;
1064 case kSecXPCOpPingTest:
1065 {
1066 CFStringRef message = SecXPCDictionaryCopyString(event, kSecXPCKeySendIDSMessage, &error);
1067 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCIDSPingTest_Server(message, &error));
1068 CFReleaseNull(message);
1069 }
1070 break;
1071 case kSecXPCOpIDSDeviceID:
1072 {
1073 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCIDSDeviceIDIsAvailableTest_Server(&error));
1074 }
1075 break;
1076 case kSecXPCOpAccountSetToNew:
1077 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCAccountSetToNew_Server(&error));
1078 break;
1079 case kSecXPCOpResetToOffering:
1080 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1081 SOSCCResetToOffering_Server(&error));
1082 break;
1083 case kSecXPCOpResetToEmpty:
1084 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1085 SOSCCResetToEmpty_Server(&error));
1086 break;
1087 case kSecXPCOpRemoveThisDeviceFromCircle:
1088 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1089 SOSCCRemoveThisDeviceFromCircle_Server(&error));
1090 break;
1091 case kSecXPCOpRemovePeersFromCircle:
1092 {
1093 CFArrayRef applicants = SecXPCDictionaryCopyPeerInfoArray(event, kSecXPCKeyPeerInfos, &error);
1094 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1095 SOSCCRemovePeersFromCircle_Server(applicants, &error));
1096 CFReleaseNull(applicants);
1097 }
1098 break;
1099 case kSecXPCOpLoggedOutOfAccount:
1100 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1101 SOSCCLoggedOutOfAccount_Server(&error));
1102 break;
1103 case kSecXPCOpBailFromCircle:
1104 {
1105 uint64_t limit_in_seconds = xpc_dictionary_get_uint64(event, kSecXPCLimitInMinutes);
1106 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1107 SOSCCBailFromCircle_Server(limit_in_seconds, &error));
1108 }
1109 break;
1110 case kSecXPCOpAcceptApplicants:
1111 {
1112 xpc_object_t xapplicants = xpc_dictionary_get_value(event, kSecXPCKeyPeerInfos);
1113 CFArrayRef applicants = CreateArrayOfPeerInfoWithXPCObject(xapplicants, &error); //(CFArrayRef)(_CFXPCCreateCFObjectFromXPCObject(xapplicants));
1114 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1115 (applicants && SOSCCAcceptApplicants_Server(applicants, &error)));
1116 CFReleaseSafe(applicants);
1117 }
1118 break;
1119 case kSecXPCOpRejectApplicants:
1120 {
1121 xpc_object_t xapplicants = xpc_dictionary_get_value(event, kSecXPCKeyPeerInfos);
1122 CFArrayRef applicants = CreateArrayOfPeerInfoWithXPCObject(xapplicants, &error); //(CFArrayRef)(_CFXPCCreateCFObjectFromXPCObject(xapplicants));
1123 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1124 (applicants && SOSCCRejectApplicants_Server(applicants, &error)));
1125 CFReleaseSafe(applicants);
1126 }
1127 break;
1128 case kSecXPCOpSetNewPublicBackupKey:
1129 {
1130 if (SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementRestoreKeychain)) {
1131 CFDataRef publicBackupKey = SecXPCDictionaryCopyData(event, kSecXPCKeyNewPublicBackupKey, &error);
1132 SOSPeerInfoRef peerInfo = SOSCCSetNewPublicBackupKey_Server(publicBackupKey, &error);
1133 CFDataRef peerInfoData = peerInfo ? SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, &error) : NULL;
1134 CFReleaseNull(peerInfo);
1135 if (peerInfoData) {
1136 xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(peerInfoData);
1137 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object);
1138 xpc_release(xpc_object);
1139 }
1140 CFReleaseNull(peerInfoData);
1141 CFReleaseSafe(publicBackupKey);
1142
1143 } else {
1144 EntitlementMissing(((enum SecXPCOperation)operation), clientTask, kSecEntitlementRestoreKeychain, &error);
1145 }
1146 }
1147 break;
1148 case kSecXPCOpSetBagForAllSlices:
1149 {
1150 if (SecTaskGetBooleanValueForEntitlement(clientTask, kSecEntitlementRestoreKeychain)) {
1151 CFDataRef backupSlice = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
1152 bool includeV0 = xpc_dictionary_get_bool(event, kSecXPCKeyIncludeV0);
1153 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, backupSlice && SOSCCRegisterSingleRecoverySecret_Server(backupSlice, includeV0, &error));
1154 CFReleaseSafe(backupSlice);
1155 } else {
1156 EntitlementMissing(((enum SecXPCOperation)operation), clientTask, kSecEntitlementRestoreKeychain, &error);
1157 }
1158 }
1159 break;
1160 case kSecXPCOpCopyApplicantPeerInfo:
1161 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1162 SOSCCCopyApplicantPeerInfo_Server(&error),
1163 &error);
1164 break;
1165 case kSecXPCOpCopyValidPeerPeerInfo:
1166 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1167 SOSCCCopyValidPeerPeerInfo_Server(&error),
1168 &error);
1169 break;
1170 case kSecXPCOpValidateUserPublic:
1171 {
1172 bool trusted = SOSCCValidateUserPublic_Server(&error);
1173 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, trusted);
1174 }
1175 break;
1176 case kSecXPCOpCopyNotValidPeerPeerInfo:
1177 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1178 SOSCCCopyNotValidPeerPeerInfo_Server(&error),
1179 &error);
1180 break;
1181 case kSecXPCOpCopyGenerationPeerInfo:
1182 xpc_dictionary_set_and_consume_CFArray(replyMessage, kSecXPCKeyResult,
1183 SOSCCCopyGenerationPeerInfo_Server(&error));
1184 break;
1185 case kSecXPCOpCopyRetirementPeerInfo:
1186 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1187 SOSCCCopyRetirementPeerInfo_Server(&error),
1188 &error);
1189 break;
1190 case kSecXPCOpCopyViewUnawarePeerInfo:
1191 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1192 SOSCCCopyViewUnawarePeerInfo_Server(&error),
1193 &error);
1194 break;
1195 case kSecXPCOpCopyEngineState:
1196 {
1197 CFArrayRef array = SOSCCCopyEngineState_Server(&error);
1198 if (array) {
1199 xpc_object_t xpc_array = _CFXPCCreateXPCObjectFromCFObject(array);
1200 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_array);
1201 xpc_release(xpc_array);
1202 }
1203 CFReleaseNull(array);
1204 }
1205 break;
1206 case kSecXPCOpCopyPeerPeerInfo:
1207 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1208 SOSCCCopyPeerPeerInfo_Server(&error),
1209 &error);
1210 break;
1211 case kSecXPCOpCopyConcurringPeerPeerInfo:
1212 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1213 SOSCCCopyConcurringPeerPeerInfo_Server(&error),
1214 &error);
1215 break;
1216 case kSecXPCOpCopyMyPeerInfo:
1217 {
1218 SOSPeerInfoRef peerInfo = SOSCCCopyMyPeerInfo_Server(&error);
1219 CFDataRef peerInfoData = peerInfo ? SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, &error) : NULL;
1220 CFReleaseNull(peerInfo);
1221 if (peerInfoData) {
1222 xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(peerInfoData);
1223 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object);
1224 xpc_release(xpc_object);
1225 }
1226 CFReleaseNull(peerInfoData);
1227 }
1228 break;
1229 case kSecXPCOpGetLastDepartureReason:
1230 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
1231 SOSCCGetLastDepartureReason_Server(&error));
1232 break;
1233 case kSecXPCOpSetLastDepartureReason:
1234 {
1235 int32_t reason = (int32_t) xpc_dictionary_get_int64(event, kSecXPCKeyReason);
1236 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
1237 SOSCCSetLastDepartureReason_Server(reason, &error));
1238 break;
1239 }
1240 case kSecXPCOpProcessSyncWithAllPeers:
1241 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
1242 SOSCCProcessSyncWithAllPeers_Server(&error));
1243 break;
1244 case soscc_EnsurePeerRegistration_id:
1245 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1246 SOSCCProcessEnsurePeerRegistration_Server(&error));
1247 break;
1248 case kSecXPCOpCopyIncompatibilityInfo:
1249 {
1250 CFStringRef iis = SOSCCCopyIncompatibilityInfo_Server(&error);
1251 SecXPCDictionarySetString(replyMessage, kSecXPCKeyResult, iis, &error);
1252 CFReleaseSafe(iis);
1253 break;
1254 }
1255 case kSecXPCOpOTAGetEscrowCertificates:
1256 {
1257 uint32_t escrowRootType = (uint32_t)xpc_dictionary_get_uint64(event, "escrowType");
1258 CFArrayRef array = SecOTAPKICopyCurrentEscrowCertificates(escrowRootType, &error);
1259 if (array) {
1260 xpc_object_t xpc_array = _CFXPCCreateXPCObjectFromCFObject(array);
1261 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_array);
1262 xpc_release(xpc_array);
1263 }
1264 CFReleaseNull(array);
1265 }
1266 break;
1267 case kSecXPCOpOTAPKIGetNewAsset:
1268 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
1269 SecOTAPKISignalNewAsset(&error));
1270 break;
1271 case kSecXPCOpRollKeys:
1272 {
1273 bool force = xpc_dictionary_get_bool(event, "force");
1274 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1275 _SecServerRollKeys(force, &error));
1276 }
1277 break;
1278 case kSecXPCOpSetHSA2AutoAcceptInfo:
1279 {
1280 CFDataRef cfbytes = NULL;
1281 const uint8_t *bytes = NULL;
1282 size_t len = 0;
1283
1284 bytes = xpc_dictionary_get_data(event,
1285 kSecXPCKeyHSA2AutoAcceptInfo, &len);
1286 if (!bytes) {
1287 SOSCreateError(kSOSErrorBadKey,
1288 CFSTR("missing autoaccept info"), NULL, &error);
1289 break;
1290 }
1291
1292 cfbytes = CFDataCreate(NULL, bytes, len);
1293 if (!cfbytes) {
1294 SOSCreateError(kSOSErrorAllocationFailure,
1295 CFSTR("could not allocate autoaccept info"),
1296 NULL, &error);
1297 break;
1298 }
1299
1300 xpc_dictionary_set_bool(replyMessage,
1301 kSecXPCKeyResult,
1302 SOSCCSetHSA2AutoAcceptInfo_Server(cfbytes, &error));
1303 CFRelease(cfbytes);
1304 }
1305 break;
1306 case kSecXPCOpWaitForInitialSync:
1307 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1308 SOSCCWaitForInitialSync_Server(&error));
1309 break;
1310
1311 case kSecXPCOpCopyYetToSyncViews:
1312 {
1313 CFArrayRef array = SOSCCCopyYetToSyncViewsList_Server(&error);
1314 if (array) {
1315 xpc_object_t xpc_array = _CFXPCCreateXPCObjectFromCFObject(array);
1316 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_array);
1317 xpc_release(xpc_array);
1318 }
1319 CFReleaseNull(array);
1320 }
1321 break;
1322 case kSecXPCOpSetEscrowRecord:
1323 {
1324 CFStringRef escrow_label = SecXPCDictionaryCopyString(event, kSecXPCKeyEscrowLabel, &error);
1325 uint64_t tries = xpc_dictionary_get_int64(event, kSecXPCKeyTriesLabel);
1326
1327 bool result = SOSCCSetEscrowRecord_Server(escrow_label, tries, &error);
1328 if (result) {
1329 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
1330 }
1331 CFReleaseNull(escrow_label);
1332 }
1333 break;
1334 case kSecXPCOpGetEscrowRecord:
1335 {
1336 CFDictionaryRef record = SOSCCCopyEscrowRecord_Server(&error);
1337 if (record) {
1338 xpc_object_t xpc_dictionary = _CFXPCCreateXPCObjectFromCFObject(record);
1339 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_dictionary);
1340 xpc_release(xpc_dictionary);
1341 }
1342 CFReleaseNull(record);
1343 }
1344 break;
1345 case kSecXPCOpCheckPeerAvailability:
1346 {
1347 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCCheckPeerAvailability_Server(&error));
1348 }
1349 break;
1350 default:
1351 break;
1352 }
1353
1354 }
1355
1356 if (error)
1357 {
1358 if(SecErrorGetOSStatus(error) == errSecItemNotFound || isSOSErrorCoded(error, kSOSErrorPublicKeyAbsent))
1359 secdebug("ipc", "%@ %@ %@", clientTask, SOSCCGetOperationDescription((enum SecXPCOperation)operation), error);
1360 else if (SecErrorGetOSStatus(error) == errSecAuthNeeded)
1361 secwarning("Authentication is needed %@ %@ %@", clientTask, SOSCCGetOperationDescription((enum SecXPCOperation)operation), error);
1362 else
1363 secerror("%@ %@ %@", clientTask, SOSCCGetOperationDescription((enum SecXPCOperation)operation), error);
1364
1365 xpcError = SecCreateXPCObjectWithCFError(error);
1366 if (replyMessage) {
1367 xpc_dictionary_set_value(replyMessage, kSecXPCKeyError, xpcError);
1368 }
1369 } else if (replyMessage) {
1370 secdebug("ipc", "%@ %@ responding %@", clientTask, SOSCCGetOperationDescription((enum SecXPCOperation)operation), replyMessage);
1371 }
1372 } else {
1373 SecCFCreateErrorWithFormat(kSecXPCErrorUnexpectedType, sSecXPCErrorDomain, NULL, &error, 0, CFSTR("Messages expect to be xpc dictionary, got: %@"), event);
1374 secerror("%@: returning error: %@", clientTask, error);
1375 xpcError = SecCreateXPCObjectWithCFError(error);
1376 replyMessage = xpc_create_reply_with_format(event, "{%string: %value}", kSecXPCKeyError, xpcError);
1377 }
1378
1379 if (replyMessage) {
1380 xpc_connection_send_message(connection, replyMessage);
1381 xpc_release(replyMessage);
1382 }
1383 if (xpcError)
1384 xpc_release(xpcError);
1385 CFReleaseSafe(error);
1386 CFReleaseSafe(accessGroups);
1387 CFReleaseSafe(domains);
1388 pthread_setspecific(taskThreadKey, NULL);
1389 CFReleaseSafe(clientTask);
1390 CFReleaseSafe(clientAuditToken);
1391 }
1392
1393 static void securityd_xpc_init(const char *service_name)
1394 {
1395 pthread_key_create(&taskThreadKey, NULL);
1396 SecTaskDiagnoseEntitlements = secTaskDiagnoseEntitlements;
1397
1398 secdebug("serverxpc", "start");
1399 xpc_connection_t listener = xpc_connection_create_mach_service(service_name, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER);
1400 if (!listener) {
1401 seccritical("security failed to register xpc listener for %s, exiting", service_name);
1402 abort();
1403 }
1404
1405 xpc_connection_set_event_handler(listener, ^(xpc_object_t connection) {
1406 if (xpc_get_type(connection) == XPC_TYPE_CONNECTION) {
1407 xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
1408 if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) {
1409 xpc_retain(connection);
1410 xpc_retain(event);
1411 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
1412 securityd_xpc_dictionary_handler(connection, event);
1413 xpc_release(event);
1414 xpc_release(connection);
1415 });
1416 }
1417 });
1418 xpc_connection_resume(connection);
1419 }
1420 });
1421 xpc_connection_resume(listener);
1422 }
1423
1424
1425 // <rdar://problem/22425706> 13B104+Roots:Device never moved past spinner after using approval to ENABLE icdp
1426
1427 #if (TARGET_OS_MAC && TARGET_OS_EMBEDDED)
1428 static void securityd_soscc_lock_hack() {
1429 dispatch_queue_t soscc_lock_queue = dispatch_queue_create("soscc_lock_queue", DISPATCH_QUEUE_PRIORITY_DEFAULT);
1430 int soscc_tok;
1431 __block MKBAssertionRef lockAssertion = NULL;
1432 uint32_t rc;
1433
1434 // <rdar://problem/22500239> Prevent securityd from quitting while holding a keychain assertion
1435 // FIXME: securityd isn't currently registering for any other notifyd events. If/when it does,
1436 // this code will need to be generalized / migrated away from just this specific purpose.
1437 xpc_set_event_stream_handler("com.apple.notifyd.matching", dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(xpc_object_t object) {
1438 char *event_description = xpc_copy_description(object);
1439 secnotice("events", "%s", event_description);
1440 free(event_description);
1441 });
1442
1443 secnotice("lockassertion", "notify_register_dispatch(kSOSCCHoldLockForInitialSync)");
1444 rc = notify_register_dispatch(kSOSCCHoldLockForInitialSync, &soscc_tok, soscc_lock_queue, ^(int token __unused) {
1445 secnotice("lockassertion", "kSOSCCHoldLockForInitialSync: already holding lock %d", (int) (lockAssertion != NULL));
1446
1447 // Release previously held assertion (if present)
1448 CFReleaseSafe(lockAssertion);
1449
1450 // New lock assertion
1451 int k300 = 300;
1452 CFNumberRef cfn300 = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &k300);
1453 const void *keys[] = {kMKBAssertionTypeKey , kMKBAssertionTimeoutKey};
1454 const void *vals[] = {kMKBAssertionTypeProfile, cfn300};
1455 CFDictionaryRef lockOptions = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, 2,
1456 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1457 CFErrorRef err = NULL;
1458
1459 lockAssertion = MKBDeviceLockAssertion(lockOptions, &err);
1460 if (lockAssertion) {
1461 // <rdar://problem/22500239> Prevent securityd from quitting while holding a keychain assertion
1462 xpc_transaction_begin();
1463
1464 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, k300*NSEC_PER_SEC), soscc_lock_queue, ^{
1465 xpc_transaction_end();
1466 });
1467 } else {
1468 secerror("Failed to take device lock assertion: %@", err);
1469 }
1470 CFReleaseSafe(err);
1471 secnotice("lockassertion", "kSOSCCHoldLockForInitialSync => done");
1472
1473 CFReleaseSafe(cfn300);
1474 CFReleaseSafe(lockOptions);
1475 });
1476 }
1477 #endif // #if (TARGET_OS_MAC && TARGET_OS_EMBEDDED)
1478
1479 int main(int argc, char *argv[])
1480 {
1481 char *wait4debugger = getenv("WAIT4DEBUGGER");
1482 if (wait4debugger && !strcasecmp("YES", wait4debugger)) {
1483 seccritical("SIGSTOPing self, awaiting debugger");
1484 kill(getpid(), SIGSTOP);
1485 asl_log(NULL, NULL, ASL_LEVEL_CRIT,
1486 "Again, for good luck (or bad debuggers)");
1487 kill(getpid(), SIGSTOP);
1488 }
1489
1490 const char *serviceName = kSecuritydXPCServiceName;
1491 #if TRUSTD_SERVER
1492 serviceName = kTrustdXPCServiceName;
1493 if (argc > 1 && (!strcmp(argv[1], "--agent"))) {
1494 serviceName = kTrustdAgentXPCServiceName;
1495 }
1496 #endif
1497 securityd_init_server();
1498 securityd_xpc_init(serviceName);
1499
1500 // <rdar://problem/22425706> 13B104+Roots:Device never moved past spinner after using approval to ENABLE icdp
1501 #if (TARGET_OS_MAC && TARGET_OS_EMBEDDED)
1502 securityd_soscc_lock_hack();
1503 #endif // #if (TARGET_OS_MAC && TARGET_OS_EMBEDDED)
1504
1505 dispatch_main();
1506
1507 return 0;
1508 }
1509
1510 /* vi:set ts=4 sw=4 et: */