]> git.saurik.com Git - apple/security.git/blob - OSX/sec/ipc/server.c
Security-58286.20.16.tar.gz
[apple/security.git] / OSX / sec / ipc / server.c
1 /*
2 * Copyright (c) 2007-2017 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/SecBase.h>
30 #include <Security/SecBasePriv.h>
31 #include <Security/SecCertificatePriv.h>
32 #include <Security/SecEntitlements.h>
33 #include <Security/SecInternal.h>
34 #include <Security/SecItem.h>
35 #include <Security/SecItemPriv.h> /* For SecItemDeleteAll */
36 #include <Security/SecPolicy.h>
37 #include <Security/SecPolicyInternal.h>
38 #include <Security/SecTask.h>
39 #include <Security/SecTrustInternal.h>
40 #include <Security/SecuritydXPC.h>
41 #include <securityd/OTATrustUtilities.h>
42 #include <securityd/SOSCloudCircleServer.h>
43 #include <securityd/SecItemBackupServer.h>
44 #include <securityd/SecItemServer.h>
45 #include <securityd/SecLogSettingsServer.h>
46 #include <securityd/SecOTRRemote.h>
47 #include <securityd/SecTrustServer.h>
48 #include <securityd/SecTrustStoreServer.h>
49 #include <securityd/iCloudTrace.h>
50 #include <securityd/spi.h>
51 #include <utilities/SecCFError.h>
52 #include <utilities/SecCFWrappers.h>
53 #include <utilities/SecDb.h>
54 #include <utilities/SecIOFormat.h>
55 #include <utilities/SecXPCError.h>
56 #include <utilities/debugging.h>
57 #include <utilities/SecInternalReleasePriv.h>
58 #include <utilities/der_plist_internal.h>
59 #include <utilities/der_plist.h>
60 #include <securityd/personalization.h>
61 #include <securityd/SecPinningDb.h>
62
63 #include <keychain/ckks/CKKS.h>
64
65 #include <AssertMacros.h>
66 #include <CoreFoundation/CFXPCBridge.h>
67 #include <CoreFoundation/CoreFoundation.h>
68 // <rdar://problem/22425706> 13B104+Roots:Device never moved past spinner after using approval to ENABLE icdp
69
70 #if TARGET_OS_OSX
71 #include <Security/SecTaskPriv.h>
72 #include <login/SessionAgentStatusCom.h>
73 #endif
74 #include <asl.h>
75 #include <bsm/libbsm.h>
76 #include <ipc/securityd_client.h>
77 #include <libkern/OSAtomic.h>
78 #include <mach/mach.h>
79 #include <mach/message.h>
80 #include <notify.h>
81 #include <stdlib.h>
82 #include <sys/queue.h>
83 #include <sys/sysctl.h>
84 #include <syslog.h>
85 #include <xpc/private.h>
86 #include <xpc/xpc.h>
87
88 #include <ipc/server_security_helpers.h>
89 #include <ipc/server_entitlement_helpers.h>
90
91 #if TARGET_OS_OSX
92 #include <sandbox.h>
93 #include <pwd.h>
94 #include <err.h>
95 #endif
96
97 static bool accessGroupPermitted(SecurityClient* client, CFArrayRef accessGroups, CFStringRef accessGroup) {
98 /* NULL accessGroups is wildcard. */
99 if (!accessGroups)
100 return true;
101 /* Make sure we have a string. */
102 if (!isString(accessGroup))
103 return false;
104
105 /* Having the special accessGroup "*" allows access to all accessGroups. */
106 CFRange range = { 0, CFArrayGetCount(accessGroups) };
107 if (range.length &&
108 (CFArrayContainsValue(accessGroups, range, accessGroup) ||
109 CFArrayContainsValue(accessGroups, range, CFSTR("*"))))
110 return true;
111
112 return false;
113 }
114
115 static bool extractAccessGroup(SecurityClient *client, CFStringRef requestedAgrp, CFStringRef *resolvedAgrp, CFErrorRef *error) {
116 bool ok = true;
117
118 /* Access group sanity checking.
119 Similar to accessGroupsAllows, but ignores accessGroupIsNetworkExtensionAndClientIsEntitled */
120 CFArrayRef accessGroups = client->accessGroups;
121 CFStringRef agrp = requestedAgrp;
122 /* Having the special accessGroup "*" allows access to all accessGroups. */
123 if (CFArrayContainsValue(accessGroups, CFRangeMake(0,CFArrayGetCount(accessGroups)), CFSTR("*")))
124 accessGroups = NULL;
125
126 if (requestedAgrp) {
127 /* The user specified an explicit access group, validate it. */
128 if (!accessGroupPermitted(client, accessGroups, requestedAgrp))
129 ok = SecError(errSecMissingEntitlement, error, CFSTR("explicit accessGroup %@ not in client access %@"), requestedAgrp, accessGroups);
130 } else {
131 // We are using an implicit access group
132 // Add it as if the user specified it as an attribute.
133 agrp = (CFStringRef)CFArrayGetValueAtIndex(client->accessGroups, 0);
134 }
135
136 if (agrp && resolvedAgrp)
137 *resolvedAgrp = agrp;
138 return ok;
139 }
140
141 static void with_label_and_password(xpc_object_t message, void (^action)(CFStringRef label, CFDataRef password)) {
142 const char *label_utf8 = xpc_dictionary_get_string(message, kSecXPCKeyUserLabel);
143
144 if (label_utf8) { // Anything we would do here requires a user label
145 size_t password_length = 0;
146 const void *password_data = xpc_dictionary_get_data(message, kSecXPCKeyUserPassword, &password_length);
147
148 CFDataRef user_password = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, password_data, password_length, kCFAllocatorNull);
149 CFStringRef user_label = CFStringCreateWithCString(kCFAllocatorDefault, label_utf8, kCFStringEncodingUTF8);
150
151 action(user_label, user_password);
152
153 CFReleaseNull(user_password);
154 CFReleaseNull(user_label);
155 }
156 }
157
158 static void with_label_and_password_and_dsid(xpc_object_t message, void (^action)(CFStringRef label, CFDataRef password, CFStringRef dsid)) {
159 const char *label_utf8 = xpc_dictionary_get_string(message, kSecXPCKeyUserLabel);
160
161 if (label_utf8) { // Anything we would do here requires a user label
162 size_t password_length = 0;
163 const void *password_data = xpc_dictionary_get_data(message, kSecXPCKeyUserPassword, &password_length);
164 const char *xdsid = xpc_dictionary_get_string(message, kSecXPCKeyDSID);
165
166 CFDataRef user_password = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, password_data, password_length, kCFAllocatorNull);
167 CFStringRef user_label = CFStringCreateWithCString(kCFAllocatorDefault, label_utf8, kCFStringEncodingUTF8);
168 CFStringRef dsid = CFStringCreateWithCString(kCFAllocatorDefault, xdsid, kCFStringEncodingUTF8);
169
170 action(user_label, user_password, dsid);
171
172 CFReleaseNull(dsid);
173 CFReleaseNull(user_password);
174 CFReleaseNull(user_label);
175 }
176 }
177
178 static void with_label_and_number(xpc_object_t message, void (^action)(CFStringRef label, uint64_t number)) {
179 const char *label_utf8 = xpc_dictionary_get_string(message, kSecXPCKeyViewName);
180 const int64_t number = xpc_dictionary_get_int64(message, kSecXPCKeyViewActionCode);
181 CFStringRef user_label = CFStringCreateWithCString(kCFAllocatorDefault, label_utf8, kCFStringEncodingUTF8);
182
183 action(user_label, number);
184 CFReleaseNull(user_label);
185 }
186
187 static CFArrayRef SecXPCDictionaryCopyPeerInfoArray(xpc_object_t dictionary, const char *key, CFErrorRef *error) {
188 return CreateArrayOfPeerInfoWithXPCObject(xpc_dictionary_get_value(dictionary, key), error);
189 }
190
191 static CFDataRef SecXPCDictionaryCopyCFDataRef(xpc_object_t message, const char *key, CFErrorRef *error) {
192 CFDataRef retval = NULL;
193 const uint8_t *bytes = NULL;
194 size_t len = 0;
195
196 bytes = xpc_dictionary_get_data(message, key, &len);
197 require_action_quiet(bytes, errOut, SOSCreateError(kSOSErrorBadKey, CFSTR("missing CFDataRef info"), NULL, error));
198 retval = CFDataCreate(NULL, bytes, len);
199 require_action_quiet(retval, errOut, SOSCreateError(kSOSErrorBadKey, CFSTR("could not allocate CFDataRef info"), NULL, error));
200 errOut:
201 return retval;
202 }
203
204 static CFSetRef CreateCFSetRefFromXPCObject(xpc_object_t xpcSetDER, CFErrorRef* error) {
205 CFSetRef retval = NULL;
206 require_action_quiet(xpcSetDER, errOut, SecCFCreateErrorWithFormat(kSecXPCErrorUnexpectedNull, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Unexpected Null Set to decode")));
207
208 require_action_quiet(xpc_get_type(xpcSetDER) == XPC_TYPE_DATA, errOut, SecCFCreateErrorWithFormat(kSecXPCErrorUnexpectedType, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("xpcSetDER not data, got %@"), xpcSetDER));
209
210 const uint8_t* der = xpc_data_get_bytes_ptr(xpcSetDER);
211 const uint8_t* der_end = der + xpc_data_get_length(xpcSetDER);
212 der = der_decode_set(kCFAllocatorDefault, kCFPropertyListMutableContainersAndLeaves, &retval, error, der, der_end);
213 if (der != der_end) {
214 SecError(errSecDecode, error, CFSTR("trailing garbage at end of SecAccessControl data"));
215 goto errOut;
216 }
217 return retval;
218 errOut:
219 CFReleaseNull(retval);
220 return NULL;
221 }
222
223 static SOSPeerInfoRef SecXPCDictionaryCopyPeerInfo(xpc_object_t message, const char *key, CFErrorRef *error) {
224 size_t length = 0;
225 const uint8_t *der = xpc_dictionary_get_data(message, key, &length);
226
227 return SecRequirementError(der != NULL, error, CFSTR("No data for key %s"), key) ? SOSPeerInfoCreateFromDER(kCFAllocatorDefault, error, &der, der + length) : NULL;
228 }
229
230 static CFSetRef SecXPCSetCreateFromXPCDictionaryElement(xpc_object_t event, const char *key) {
231 CFErrorRef error = NULL;
232 xpc_object_t object = xpc_dictionary_get_value(event, key);
233 CFSetRef retval = NULL;
234 if(object) retval = CreateCFSetRefFromXPCObject(object, &error);
235 CFReleaseNull(error);
236 return retval;
237 }
238
239 static inline
240 void xpc_dictionary_set_and_consume_CFArray(xpc_object_t xdict, const char *key, CF_CONSUMED CFArrayRef cf_array) {
241 if (cf_array) {
242 xpc_object_t xpc_array = _CFXPCCreateXPCObjectFromCFObject(cf_array);
243 xpc_dictionary_set_value(xdict, key, xpc_array);
244 xpc_release(xpc_array);
245 }
246 CFReleaseNull(cf_array);
247 }
248
249 static inline
250 bool xpc_dictionary_set_and_consume_PeerInfoArray(xpc_object_t xdict, const char *key, CF_CONSUMED CFArrayRef cf_array, CFErrorRef *error) {
251 bool success = true;
252 if (cf_array) {
253 xpc_object_t xpc_array = CreateXPCObjectWithArrayOfPeerInfo(cf_array, error);
254 if (xpc_array) {
255 xpc_dictionary_set_value(xdict, key, xpc_array);
256 xpc_release(xpc_array);
257 } else {
258 success = false;
259 }
260 }
261 CFReleaseNull(cf_array);
262 return success;
263 }
264
265 static CFDataRef
266 SecDataCopyMmapFileDescriptor(int fd, void **mem, size_t *size, CFErrorRef *error)
267 {
268 struct stat sb;
269 if (fstat(fd, &sb) < 0) {
270 return NULL;
271 }
272
273 *size = (size_t)sb.st_size;
274 if ((off_t)*size != sb.st_size) {
275 return NULL;
276 }
277
278 *mem = mmap(NULL, *size, PROT_READ, MAP_SHARED, fd, 0);
279 if (*mem == MAP_FAILED) {
280 return NULL;
281 }
282
283 return CFDataCreateWithBytesNoCopy(NULL, *mem, *size, kCFAllocatorNull);
284 }
285
286 static bool
287 SecDataWriteFileDescriptor(int fd, CFDataRef data)
288 {
289 CFIndex count = CFDataGetLength(data);
290 const uint8_t *ptr = CFDataGetBytePtr(data);
291 bool writeResult = false;
292
293 while (count) {
294 ssize_t ret = write(fd, ptr, count);
295 if (ret <= 0)
296 break;
297 count -= ret;
298 ptr += ret;
299 }
300 if (count == 0)
301 writeResult = true;
302
303 return writeResult;
304 }
305
306
307 // Returns error if entitlement isn't present.
308 static bool
309 EntitlementPresentAndTrue(uint64_t op, SecTaskRef clientTask, CFStringRef entitlement, CFErrorRef *error)
310 {
311 if (!SecTaskGetBooleanValueForEntitlement(clientTask, entitlement)) {
312 SecError(errSecMissingEntitlement, error, CFSTR("%@: %@ lacks entitlement %@"), SOSCCGetOperationDescription((enum SecXPCOperation)op), clientTask, entitlement);
313 return false;
314 }
315 return true;
316 }
317
318 // Per <rdar://problem/13315020> Disable the entitlement check for "keychain-cloud-circle"
319 // we disable entitlement enforcement. However, we still log so we know who needs the entitlement
320 static bool
321 EntitlementPresentOrWhine(uint64_t op, SecTaskRef clientTask, CFStringRef entitlement, CFErrorRef *error)
322 {
323 if (!SecTaskGetBooleanValueForEntitlement(clientTask, entitlement))
324 secnotice("serverxpc", "%@: %@ lacks entitlement %@", SOSCCGetOperationDescription((enum SecXPCOperation)op), clientTask, entitlement);
325
326 return true;
327 }
328
329
330 static bool
331 EntitlementAbsentOrFalse(uint64_t op, SecTaskRef clientTask, CFStringRef entitlement, CFErrorRef *error)
332 {
333 if (SecTaskGetBooleanValueForEntitlement(clientTask, entitlement)) {
334 SecError(errSecNotAvailable, error, CFSTR("%@: %@ has entitlement %@"), SOSCCGetOperationDescription((enum SecXPCOperation) op), clientTask, entitlement);
335 return false;
336 }
337 return true;
338 }
339
340 static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, xpc_object_t event) {
341 xpc_type_t type = xpc_get_type(event);
342 __block CFErrorRef error = NULL;
343 xpc_object_t xpcError = NULL;
344 xpc_object_t replyMessage = NULL;
345 CFDataRef clientAuditToken = NULL;
346 CFArrayRef domains = NULL;
347 SecurityClient client = {
348 .task = NULL,
349 .accessGroups = NULL,
350 .musr = NULL,
351 .uid = xpc_connection_get_euid(connection),
352 .allowSystemKeychain = false,
353 .allowSyncBubbleKeychain = false,
354 .isNetworkExtension = false,
355 .canAccessNetworkExtensionAccessGroups = false,
356 };
357
358 secdebug("serverxpc", "entering");
359 if (type == XPC_TYPE_DICTIONARY) {
360 // TODO: Find out what we're dispatching.
361 replyMessage = xpc_dictionary_create_reply(event);
362
363 uint64_t operation = xpc_dictionary_get_uint64(event, kSecXPCKeyOperation);
364
365 audit_token_t auditToken = {};
366 xpc_connection_get_audit_token(connection, &auditToken);
367 clientAuditToken = CFDataCreate(kCFAllocatorDefault, (const UInt8*)&auditToken, sizeof(auditToken));
368
369 fill_security_client(&client, xpc_connection_get_euid(connection), auditToken);
370
371 #if TARGET_OS_IOS
372 if (operation == sec_add_shared_web_credential_id || operation == sec_copy_shared_web_credential_id) {
373 domains = SecTaskCopySharedWebCredentialDomains(client.task);
374 }
375 #endif
376 secinfo("serverxpc", "XPC [%@] operation: %@ (%" PRIu64 ")", client.task, SOSCCGetOperationDescription((enum SecXPCOperation)operation), operation);
377
378 switch (operation)
379 {
380 case sec_item_add_id:
381 {
382 if (EntitlementAbsentOrFalse(sec_item_add_id, client.task, kSecEntitlementKeychainDeny, &error)) {
383 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
384 if (query) {
385 // Check for any entitlement-required attributes
386 bool entitlementsCorrect = true;
387 if(CFDictionaryGetValue(query, kSecAttrDeriveSyncIDFromItemAttributes) ||
388 CFDictionaryGetValue(query, kSecAttrPCSPlaintextServiceIdentifier) ||
389 CFDictionaryGetValue(query, kSecAttrPCSPlaintextPublicKey) ||
390 CFDictionaryGetValue(query, kSecAttrPCSPlaintextPublicIdentity)) {
391 entitlementsCorrect = EntitlementPresentAndTrue(sec_item_add_id, client.task, kSecEntitlementPrivateCKKSPlaintextFields, &error);
392 }
393 if (entitlementsCorrect && CFDictionaryGetValue(query, kSecAttrSysBound)) {
394 entitlementsCorrect = EntitlementPresentAndTrue(sec_item_add_id, client.task, kSecEntitlementPrivateSysBound, &error);
395 }
396
397 CFTypeRef result = NULL;
398 if(entitlementsCorrect) {
399 if (_SecItemAdd(query, &client, &result, &error) && result) {
400 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
401 CFReleaseNull(result);
402 }
403 }
404 CFReleaseNull(query);
405 }
406 break;
407 }
408 }
409 case sec_item_copy_matching_id:
410 {
411 if (EntitlementAbsentOrFalse(sec_item_add_id, client.task, kSecEntitlementKeychainDeny, &error)) {
412 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
413 if (query) {
414 CFTypeRef result = NULL;
415 if (_SecItemCopyMatching(query, &client, &result, &error) && result) {
416 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
417 CFReleaseNull(result);
418 }
419 CFReleaseNull(query);
420 }
421 break;
422 }
423 }
424 case sec_item_update_id:
425 {
426 if (EntitlementAbsentOrFalse(sec_item_update_id, client.task, kSecEntitlementKeychainDeny, &error)) {
427 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
428 if (query) {
429 CFDictionaryRef attributesToUpdate = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyAttributesToUpdate, &error);
430 if (attributesToUpdate) {
431 // Check for any entitlement-required attributes
432 bool entitlementsCorrect = true;
433 if(CFDictionaryGetValue(query, kSecAttrDeriveSyncIDFromItemAttributes) ||
434 CFDictionaryGetValue(attributesToUpdate, kSecAttrPCSPlaintextServiceIdentifier) ||
435 CFDictionaryGetValue(attributesToUpdate, kSecAttrPCSPlaintextPublicKey) ||
436 CFDictionaryGetValue(attributesToUpdate, kSecAttrPCSPlaintextPublicIdentity)) {
437 entitlementsCorrect = EntitlementPresentAndTrue(sec_item_update_id, client.task, kSecEntitlementPrivateCKKSPlaintextFields, &error);
438 }
439 if (entitlementsCorrect && CFDictionaryGetValue(query, kSecAttrSysBound)) {
440 entitlementsCorrect = EntitlementPresentAndTrue(sec_item_update_id, client.task, kSecEntitlementPrivateSysBound, &error);
441 }
442
443 if(entitlementsCorrect) {
444 bool result = _SecItemUpdate(query, attributesToUpdate, &client, &error);
445 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
446 }
447 CFReleaseNull(attributesToUpdate);
448 }
449 CFReleaseNull(query);
450 }
451 }
452 break;
453 }
454 case sec_item_delete_id:
455 {
456 if (EntitlementAbsentOrFalse(sec_item_add_id, client.task, kSecEntitlementKeychainDeny, &error)) {
457 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
458 if (query) {
459 bool result = _SecItemDelete(query, &client, &error);
460 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
461 CFReleaseNull(query);
462 }
463 }
464 break;
465 }
466 case sec_item_update_token_items_id:
467 {
468 if (EntitlementAbsentOrFalse(sec_item_add_id, client.task, kSecEntitlementKeychainDeny, &error)) {
469 CFStringRef tokenID = SecXPCDictionaryCopyString(event, kSecXPCKeyString, &error);
470 CFArrayRef attributes = SecXPCDictionaryCopyArray(event, kSecXPCKeyQuery, &error);
471 if (tokenID) {
472 bool result = _SecItemUpdateTokenItems(tokenID, attributes, &client, &error);
473 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
474 }
475 CFReleaseNull(tokenID);
476 CFReleaseNull(attributes);
477 }
478 break;
479 }
480 case sec_delete_all_id:
481 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, _SecItemDeleteAll(&error));
482 break;
483 case sec_keychain_backup_id:
484 {
485 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
486 CFDataRef keybag = NULL, passcode = NULL;
487 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyKeybag, &keybag, &error)) {
488 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
489 CFDataRef backup = _SecServerKeychainCreateBackup(&client, keybag, passcode, &error);
490 if (backup) {
491 int fd = SecXPCDictionaryDupFileDescriptor(event, kSecXPCKeyFileDescriptor, NULL);
492 if (fd < 0) {
493 SecXPCDictionarySetData(replyMessage, kSecXPCKeyResult, backup, &error);
494 } else {
495 bool writeResult = SecDataWriteFileDescriptor(fd, backup);
496 if (close(fd) != 0)
497 writeResult = false;
498 if (!writeResult)
499 SecError(errSecIO, &error, CFSTR("Failed to write backup file: %d"), errno);
500 SecXPCDictionarySetBool(replyMessage, kSecXPCKeyResult, writeResult, NULL);
501 }
502 CFRelease(backup);
503 }
504 CFReleaseSafe(passcode);
505 }
506 CFReleaseSafe(keybag);
507 }
508 }
509 break;
510 }
511 case sec_keychain_restore_id:
512 {
513 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
514 CFDataRef backup = NULL;
515 void *mem = NULL;
516 size_t size = 0;
517
518 int fd = SecXPCDictionaryDupFileDescriptor(event, kSecXPCKeyFileDescriptor, NULL);
519 if (fd != -1) {
520 backup = SecDataCopyMmapFileDescriptor(fd, &mem, &size, &error);
521 } else {
522 backup = SecXPCDictionaryCopyData(event, kSecXPCKeyBackup, &error);
523 }
524 if (backup) {
525 CFDataRef keybag = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
526 if (keybag) {
527 CFDataRef passcode = NULL;
528 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
529 bool result = _SecServerKeychainRestore(backup, &client, keybag, passcode, &error);
530 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
531 CFReleaseSafe(passcode);
532 }
533 }
534 CFReleaseNull(keybag);
535 }
536 CFReleaseNull(backup);
537 if (fd != -1)
538 close(fd);
539 if (mem) {
540 munmap(mem, size);
541 }
542 }
543 break;
544 }
545 case sec_keychain_backup_keybag_uuid_id:
546 {
547 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
548 CFDataRef backup = NULL;
549 CFStringRef uuid = NULL;
550 void *mem = NULL;
551 size_t size = 0;
552
553 int fd = SecXPCDictionaryDupFileDescriptor(event, kSecXPCKeyFileDescriptor, NULL);
554 if (fd != -1) {
555 backup = SecDataCopyMmapFileDescriptor(fd, &mem, &size, &error);
556 if (backup)
557 uuid = _SecServerBackupCopyUUID(backup, &error);
558 }
559 if (uuid)
560 SecXPCDictionarySetString(replyMessage, kSecXPCKeyResult, uuid, &error);
561
562 CFReleaseNull(backup);
563 if (fd != -1)
564 close(fd);
565 if (mem) {
566 munmap(mem, size);
567 }
568 CFReleaseNull(uuid);
569 }
570 break;
571 }
572 case sec_keychain_sync_update_message_id:
573 {
574 CFDictionaryRef updates = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
575 if (updates) {
576 CFArrayRef result = _SecServerKeychainSyncUpdateMessage(updates, &error);
577 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
578 CFReleaseNull(result);
579 }
580 CFReleaseNull(updates);
581 break;
582 }
583 case sec_keychain_backup_syncable_id:
584 {
585 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
586 CFDictionaryRef oldbackup = NULL;
587 if (SecXPCDictionaryCopyDictionaryOptional(event, kSecXPCKeyBackup, &oldbackup, &error)) {
588 CFDataRef keybag = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
589 if (keybag) {
590 CFDataRef passcode = NULL;
591 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
592 CFDictionaryRef newbackup = _SecServerBackupSyncable(oldbackup, keybag, passcode, &error);
593 if (newbackup) {
594 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, newbackup, &error);
595 CFRelease(newbackup);
596 }
597 CFReleaseSafe(passcode);
598 }
599 CFReleaseNull(keybag);
600 }
601 CFReleaseSafe(oldbackup);
602 }
603 }
604 break;
605 }
606 case sec_keychain_restore_syncable_id:
607 {
608 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
609 CFDictionaryRef backup = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyBackup, &error);
610 if (backup) {
611 CFDataRef keybag = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
612 if (keybag) {
613 CFDataRef passcode = NULL;
614 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
615 bool result = _SecServerRestoreSyncable(backup, keybag, passcode, &error);
616 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
617 CFReleaseSafe(passcode);
618 }
619 CFReleaseNull(keybag);
620 }
621 CFReleaseNull(backup);
622 }
623 }
624 break;
625 }
626 case sec_item_backup_copy_names_id:
627 {
628 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
629 CFArrayRef names = SecServerItemBackupCopyNames(&error);
630 SecXPCDictionarySetPListOptional(replyMessage, kSecXPCKeyResult, names, &error);
631 CFReleaseSafe(names);
632 }
633 break;
634 }
635 case sec_item_backup_handoff_fd_id:
636 {
637 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
638 CFStringRef backupName = SecXPCDictionaryCopyString(event, kSecXPCKeyBackup, &error);
639 int fd = -1;
640 if (backupName) {
641 fd = SecServerItemBackupHandoffFD(backupName, &error);
642 CFRelease(backupName);
643 }
644 SecXPCDictionarySetFileDescriptor(replyMessage, kSecXPCKeyResult, fd, &error);
645 if (fd != -1)
646 close(fd);
647 }
648 break;
649 }
650 case sec_item_backup_set_confirmed_manifest_id:
651 {
652 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
653 CFDataRef keybagDigest = NULL;
654 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyKeybag, &keybagDigest, &error)) {
655 CFDataRef manifest = NULL;
656 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCData, &manifest, &error)) {
657 CFStringRef backupName = SecXPCDictionaryCopyString(event, kSecXPCKeyBackup, &error);
658 if (backupName) {
659 bool result = SecServerItemBackupSetConfirmedManifest(backupName, keybagDigest, manifest, &error);
660 CFRelease(backupName);
661 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
662 }
663 CFReleaseSafe(manifest);
664 }
665 }
666 CFReleaseNull(keybagDigest);
667 }
668 break;
669 }
670 case sec_item_backup_restore_id:
671 {
672 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
673 bool result = false;
674 CFStringRef backupName = SecXPCDictionaryCopyString(event, kSecXPCKeyBackup, &error);
675 if (backupName) {
676 CFStringRef peerID = NULL;
677 if (SecXPCDictionaryCopyStringOptional(event, kSecXPCKeyDigest, &peerID, &error)) {
678 CFDataRef keybag = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
679 if (keybag) {
680 CFDataRef secret = SecXPCDictionaryCopyData(event, kSecXPCKeyUserPassword, &error);
681 if (secret) {
682 CFDataRef backup = SecXPCDictionaryCopyData(event, kSecXPCData, &error);
683 if (backup) {
684 result = SecServerItemBackupRestore(backupName, peerID, keybag, secret, backup, &error);
685 CFRelease(backup);
686 }
687 CFRelease(secret);
688 }
689 CFRelease(keybag);
690 }
691 CFReleaseSafe(peerID);
692 }
693 CFRelease(backupName);
694 }
695 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
696 }
697 break;
698 }
699 case sec_add_shared_web_credential_id:
700 {
701 #if TARGET_OS_IOS && !TARGET_OS_BRIDGE
702 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
703 if (query) {
704 CFTypeRef result = NULL;
705
706 CFStringRef appID = (client.task) ? SecTaskCopyApplicationIdentifier(client.task) : NULL;
707 if (_SecAddSharedWebCredential(query, &client, &auditToken, appID, domains, &result, &error) && result) {
708 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
709 CFReleaseNull(result);
710 }
711 CFReleaseSafe(appID);
712 CFReleaseNull(query);
713 }
714 #else
715 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, kCFBooleanFalse, &error);
716 #endif
717 break;
718 }
719 case sec_copy_shared_web_credential_id:
720 {
721 #if TARGET_OS_IOS && !TARGET_OS_BRIDGE
722 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
723 if (query) {
724 CFTypeRef result = NULL;
725 CFStringRef appID = (client.task) ? SecTaskCopyApplicationIdentifier(client.task) : NULL;
726 if (_SecCopySharedWebCredential(query, &client, &auditToken, appID, domains, &result, &error) && result) {
727 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
728 CFReleaseNull(result);
729 }
730 CFReleaseSafe(appID);
731 CFReleaseNull(query);
732 }
733 #else
734 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, kCFBooleanFalse, &error);
735 #endif
736 break;
737 }
738 case sec_get_log_settings_id:
739 {
740 CFPropertyListRef currentList = SecCopyLogSettings_Server(&error);
741 if (currentList) {
742 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, currentList, &error);
743 }
744 CFReleaseSafe(currentList);
745 break;
746 }
747 case sec_set_xpc_log_settings_id:
748 {
749 CFPropertyListRef newSettings = SecXPCDictionaryCopyPList(event, kSecXPCKeyQuery, &error);
750 if (newSettings) {
751 SecSetXPCLogSettings_Server(newSettings, &error);
752 }
753 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true);
754 CFReleaseNull(newSettings);
755 break;
756 }
757 case sec_set_circle_log_settings_id:
758 {
759 CFPropertyListRef newSettings = SecXPCDictionaryCopyPList(event, kSecXPCKeyQuery, &error);
760 if (newSettings) {
761 SecSetCircleLogSettings_Server(newSettings, &error);
762 }
763 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true);
764 CFReleaseNull(newSettings);
765 break;
766 }
767 case sec_otr_session_create_remote_id:
768 {
769 CFDataRef publicPeerId = NULL;
770 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCPublicPeerId, &publicPeerId, &error)) {
771 CFDataRef otrSession = _SecOTRSessionCreateRemote(publicPeerId, &error);
772 if (otrSession) {
773 SecXPCDictionarySetData(replyMessage, kSecXPCKeyResult, otrSession, &error);
774 CFReleaseNull(otrSession);
775 }
776 CFReleaseSafe(publicPeerId);
777 }
778 break;
779 }
780 case sec_otr_session_process_packet_remote_id:
781 {
782 CFDataRef sessionData = NULL, inputPacket = NULL, outputSessionData = NULL, outputPacket = NULL;
783 bool readyForMessages = false;
784 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCOTRSession, &sessionData, &error)) {
785 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCData, &inputPacket, &error)) {
786 bool result = _SecOTRSessionProcessPacketRemote(sessionData, inputPacket, &outputSessionData, &outputPacket, &readyForMessages, &error);
787 if (result) {
788 SecXPCDictionarySetData(replyMessage, kSecXPCOTRSession, outputSessionData, &error);
789 SecXPCDictionarySetData(replyMessage, kSecXPCData, outputPacket, &error);
790 xpc_dictionary_set_bool(replyMessage, kSecXPCOTRReady, readyForMessages);
791 CFReleaseNull(outputSessionData);
792 CFReleaseNull(outputPacket);
793 }
794 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
795
796 CFReleaseSafe(inputPacket);
797 }
798 CFReleaseSafe(sessionData);
799 }
800 break;
801 }
802 case kSecXPCOpTryUserCredentials:
803 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
804 with_label_and_password(event, ^(CFStringRef label, CFDataRef password) {
805 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
806 SOSCCTryUserCredentials_Server(label, password, &error));
807 });
808 }
809 break;
810 case kSecXPCOpSetUserCredentials:
811 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
812 with_label_and_password(event, ^(CFStringRef label, CFDataRef password) {
813 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
814 SOSCCSetUserCredentials_Server(label, password, &error));
815 });
816 }
817 break;
818 case kSecXPCOpSetUserCredentialsAndDSID:
819 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
820 with_label_and_password_and_dsid(event, ^(CFStringRef label, CFDataRef password, CFStringRef dsid) {
821 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
822 SOSCCSetUserCredentialsAndDSID_Server(label, password, dsid, &error));
823 });
824 }
825 break;
826 case kSecXPCOpView:
827 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
828 with_label_and_number(event, ^(CFStringRef view, uint64_t actionCode) {
829 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
830 SOSCCView_Server(view, (SOSViewActionCode)actionCode, &error));
831 });
832 }
833 break;
834 case kSecXPCOpViewSet:
835 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
836 CFSetRef enabledViews = SecXPCSetCreateFromXPCDictionaryElement(event, kSecXPCKeyEnabledViewsKey);
837 CFSetRef disabledViews = SecXPCSetCreateFromXPCDictionaryElement(event, kSecXPCKeyDisabledViewsKey);
838 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCViewSet_Server(enabledViews, disabledViews));
839 CFReleaseNull(enabledViews);
840 CFReleaseNull(disabledViews);
841 }
842 break;
843 case kSecXPCOpSecurityProperty:
844 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
845 with_label_and_number(event, ^(CFStringRef property, uint64_t actionCode) {
846 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
847 SOSCCSecurityProperty_Server(property, (SOSSecurityPropertyActionCode)actionCode, &error));
848 });
849 }
850 break;
851 case kSecXPCOpCanAuthenticate:
852 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
853 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
854 SOSCCCanAuthenticate_Server(&error));
855 }
856 break;
857 case kSecXPCOpPurgeUserCredentials:
858 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
859 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
860 SOSCCPurgeUserCredentials_Server(&error));
861 }
862 break;
863 case kSecXPCOpDeviceInCircle:
864 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
865 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
866 SOSCCThisDeviceIsInCircle_Server(&error));
867 }
868 break;
869 case kSecXPCOpRequestToJoin:
870 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
871 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
872 SOSCCRequestToJoinCircle_Server(&error));
873 }
874 break;
875 case kSecXPCOpAccountHasPublicKey:
876 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
877 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
878 SOSCCAccountHasPublicKey_Server(&error));
879 }
880 break;
881 case kSecXPCOpAccountIsNew:
882 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
883 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
884 SOSCCAccountIsNew_Server(&error));
885 }
886 break;
887 case kSecXPCOpRequestToJoinAfterRestore:
888 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
889 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
890 SOSCCRequestToJoinCircleAfterRestore_Server(&error));
891 }
892 break;
893 case kSecXPCOpRequestEnsureFreshParameters:
894 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
895 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
896 SOSCCRequestEnsureFreshParameters_Server(&error));
897 }
898 break;
899 case kSecXPCOpGetAllTheRings:
900 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
901 CFStringRef ringDescriptions = SOSCCGetAllTheRings_Server(&error);
902 xpc_object_t xpc_dictionary = _CFXPCCreateXPCObjectFromCFObject(ringDescriptions);
903 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_dictionary);
904 xpc_release(xpc_dictionary);
905 }
906 break;
907 case kSecXPCOpApplyToARing:
908 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
909 CFStringRef ringName = SecXPCDictionaryCopyString(event, kSecXPCKeyString, &error);
910 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCApplyToARing_Server(ringName, &error));
911 CFReleaseNull(ringName);
912 }
913 break;
914 case kSecXPCOpWithdrawlFromARing:
915 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
916 CFStringRef ringName = SecXPCDictionaryCopyString(event, kSecXPCKeyString, &error);
917 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCWithdrawlFromARing_Server(ringName, &error));
918 CFReleaseNull(ringName);
919 }
920 break;
921 case kSecXPCOpRingStatus:
922 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
923 CFStringRef ringName = SecXPCDictionaryCopyString(event, kSecXPCKeyString, &error);
924 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRingStatus_Server(ringName, &error));
925 CFReleaseNull(ringName);
926 }
927 break;
928 case kSecXPCOpEnableRing:
929 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
930 CFStringRef ringName = SecXPCDictionaryCopyString(event, kSecXPCKeyString, &error);
931 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCEnableRing_Server(ringName, &error));
932 CFReleaseNull(ringName);
933 }
934 break;
935 case kSecXPCOpRequestDeviceID:
936 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
937 CFStringRef deviceID = SOSCCCopyDeviceID_Server(&error);
938 if (deviceID) {
939 SecXPCDictionarySetString(replyMessage, kSecXPCKeyResult, deviceID, &error);
940 }
941 CFReleaseNull(deviceID);
942 }
943 break;
944 case kSecXPCOpSetDeviceID:
945 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
946 CFStringRef IDS = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error);
947 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCSetDeviceID_Server(IDS, &error));
948 CFReleaseNull(IDS);
949 }
950 break;
951 case kSecXPCOpHandleIDSMessage:
952 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
953 CFDictionaryRef IDS = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyIDSMessage, &error);
954 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult, SOSCCHandleIDSMessage_Server(IDS, &error));
955 CFReleaseNull(IDS);
956 }
957 break;
958 case kSecXPCOpClearKVSPeerMessage:
959 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
960 CFStringRef peerID = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error);
961 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCClearPeerMessageKeyInKVS_Server(peerID, &error));
962 CFReleaseNull(peerID);
963 }
964 break;
965 case kSecXPCOpSendIDSMessage:
966 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
967 CFStringRef message = SecXPCDictionaryCopyString(event, kSecXPCKeySendIDSMessage, &error);
968 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCIDSServiceRegistrationTest_Server(message, &error));
969 CFReleaseNull(message);
970 }
971 break;
972 case kSecXPCOpSyncWithKVSPeer:
973 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
974 CFStringRef peerID = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error);
975 CFDataRef message = SecXPCDictionaryCopyData(event, kSecXPCKeyIDSMessage, &error);
976 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestSyncWithPeerOverKVS_Server(peerID, message, &error));
977 CFReleaseNull(peerID);
978 }
979 break;
980 case kSecXPCOpSyncWithKVSPeerIDOnly:
981 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
982 CFStringRef peerID = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error);
983 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestSyncWithPeerOverKVSUsingIDOnly_Server(peerID, &error));
984 CFReleaseNull(peerID);
985 }
986 break;
987 case kSecXPCOpPingTest:
988 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
989 CFStringRef message = SecXPCDictionaryCopyString(event, kSecXPCKeySendIDSMessage, &error);
990 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCIDSPingTest_Server(message, &error));
991 CFReleaseNull(message);
992 }
993 break;
994 case kSecXPCOpIDSDeviceID:
995 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
996 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCIDSDeviceIDIsAvailableTest_Server(&error));
997 }
998 break;
999 case kSecXPCOpAccountSetToNew:
1000 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1001 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCAccountSetToNew_Server(&error));
1002 }
1003 break;
1004 case kSecXPCOpResetToOffering:
1005 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1006 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1007 SOSCCResetToOffering_Server(&error));
1008 }
1009 break;
1010 case kSecXPCOpResetToEmpty:
1011 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1012 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1013 SOSCCResetToEmpty_Server(&error));
1014 }
1015 break;
1016 case kSecXPCOpRemoveThisDeviceFromCircle:
1017 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1018 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1019 SOSCCRemoveThisDeviceFromCircle_Server(&error));
1020 }
1021 break;
1022 case kSecXPCOpRemovePeersFromCircle:
1023 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1024 CFArrayRef applicants = SecXPCDictionaryCopyPeerInfoArray(event, kSecXPCKeyPeerInfoArray, &error);
1025 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1026 SOSCCRemovePeersFromCircle_Server(applicants, &error));
1027 CFReleaseNull(applicants);
1028 }
1029 break;
1030 case kSecXPCOpLoggedOutOfAccount:
1031 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1032 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1033 SOSCCLoggedOutOfAccount_Server(&error));
1034 }
1035 break;
1036 case kSecXPCOpBailFromCircle:
1037 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1038 uint64_t limit_in_seconds = xpc_dictionary_get_uint64(event, kSecXPCLimitInMinutes);
1039 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1040 SOSCCBailFromCircle_Server(limit_in_seconds, &error));
1041 }
1042 break;
1043 case kSecXPCOpAcceptApplicants:
1044 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1045 xpc_object_t xapplicants = xpc_dictionary_get_value(event, kSecXPCKeyPeerInfoArray);
1046 CFArrayRef applicants = CreateArrayOfPeerInfoWithXPCObject(xapplicants, &error); //(CFArrayRef)(_CFXPCCreateCFObjectFromXPCObject(xapplicants));
1047 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1048 (applicants && SOSCCAcceptApplicants_Server(applicants, &error)));
1049 CFReleaseSafe(applicants);
1050 }
1051 break;
1052 case kSecXPCOpRejectApplicants:
1053 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1054 xpc_object_t xapplicants = xpc_dictionary_get_value(event, kSecXPCKeyPeerInfoArray);
1055 CFArrayRef applicants = CreateArrayOfPeerInfoWithXPCObject(xapplicants, &error); //(CFArrayRef)(_CFXPCCreateCFObjectFromXPCObject(xapplicants));
1056 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1057 (applicants && SOSCCRejectApplicants_Server(applicants, &error)));
1058 CFReleaseSafe(applicants);
1059 }
1060 break;
1061 case kSecXPCOpSetNewPublicBackupKey:
1062 {
1063 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
1064 CFDataRef publicBackupKey = SecXPCDictionaryCopyData(event, kSecXPCKeyNewPublicBackupKey, &error);
1065 SOSPeerInfoRef peerInfo = SOSCCSetNewPublicBackupKey_Server(publicBackupKey, &error);
1066 CFDataRef peerInfoData = peerInfo ? SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, &error) : NULL;
1067 CFReleaseNull(peerInfo);
1068 if (peerInfoData) {
1069 xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(peerInfoData);
1070 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object);
1071 xpc_release(xpc_object);
1072 }
1073 CFReleaseNull(peerInfoData);
1074 CFReleaseSafe(publicBackupKey);
1075
1076 }
1077 }
1078 break;
1079 case kSecXPCOpRegisterRecoveryPublicKey:
1080 {
1081 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
1082 CFDataRef recovery_key = SecXPCDictionaryCopyData(event, kSecXPCKeyRecoveryPublicKey, &error);
1083 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRegisterRecoveryPublicKey_Server(recovery_key, &error));
1084 CFReleaseNull(recovery_key);
1085 }
1086 }
1087 break;
1088 case kSecXPCOpGetRecoveryPublicKey:
1089 {
1090 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
1091 xpc_object_t xpc_recovery_object = NULL;
1092 CFDataRef recovery = SOSCCCopyRecoveryPublicKey(&error);
1093 if(recovery)
1094 xpc_recovery_object = _CFXPCCreateXPCObjectFromCFObject(recovery);
1095
1096 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_recovery_object);
1097 CFReleaseNull(recovery);
1098 }
1099 }
1100 break;
1101 case kSecXPCOpSetBagForAllSlices:
1102 {
1103 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
1104 CFDataRef backupSlice = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
1105 bool includeV0 = xpc_dictionary_get_bool(event, kSecXPCKeyIncludeV0);
1106 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, backupSlice && SOSCCRegisterSingleRecoverySecret_Server(backupSlice, includeV0, &error));
1107 CFReleaseSafe(backupSlice);
1108 }
1109 }
1110 break;
1111 case kSecXPCOpCopyApplicantPeerInfo:
1112 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1113 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1114 SOSCCCopyApplicantPeerInfo_Server(&error),
1115 &error);
1116 }
1117 break;
1118 case kSecXPCOpCopyValidPeerPeerInfo:
1119 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1120 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1121 SOSCCCopyValidPeerPeerInfo_Server(&error),
1122 &error);
1123 }
1124 break;
1125 case kSecXPCOpValidateUserPublic:
1126 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1127 bool trusted = SOSCCValidateUserPublic_Server(&error);
1128 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, trusted);
1129 }
1130 break;
1131 case kSecXPCOpCopyNotValidPeerPeerInfo:
1132 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1133 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1134 SOSCCCopyNotValidPeerPeerInfo_Server(&error),
1135 &error);
1136 }
1137 break;
1138 case kSecXPCOpCopyGenerationPeerInfo:
1139 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1140 xpc_dictionary_set_and_consume_CFArray(replyMessage, kSecXPCKeyResult,
1141 SOSCCCopyGenerationPeerInfo_Server(&error));
1142 }
1143 break;
1144 case kSecXPCOpCopyRetirementPeerInfo:
1145 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1146 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1147 SOSCCCopyRetirementPeerInfo_Server(&error),
1148 &error);
1149 }
1150 break;
1151 case kSecXPCOpCopyViewUnawarePeerInfo:
1152 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1153 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1154 SOSCCCopyViewUnawarePeerInfo_Server(&error),
1155 &error);
1156 }
1157 break;
1158 case kSecXPCOpCopyAccountData:
1159 {
1160 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1161 xpc_object_t xpc_account_object = NULL;
1162 CFDataRef accountData = SOSCCCopyAccountState_Server(&error);
1163 if(accountData)
1164 xpc_account_object = _CFXPCCreateXPCObjectFromCFObject(accountData);
1165
1166 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_account_object);
1167 CFReleaseNull(accountData);
1168 }
1169 break;
1170 }
1171 case kSecXPCOpDeleteAccountData:
1172 {
1173 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1174 bool status = SOSCCDeleteAccountState_Server(&error);
1175 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, status);
1176 }
1177 break;
1178 }
1179 case kSecXPCOpCopyEngineData:
1180 {
1181 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1182
1183 xpc_object_t xpc_engine_object = NULL;
1184 CFDataRef engineData = SOSCCCopyEngineData_Server(&error);
1185 if(engineData)
1186 xpc_engine_object = _CFXPCCreateXPCObjectFromCFObject(engineData);
1187
1188 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_engine_object);
1189 CFReleaseNull(engineData);
1190
1191 }
1192 break;
1193 }
1194 case kSecXPCOpDeleteEngineData:
1195 {
1196 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1197 bool status = SOSCCDeleteEngineState_Server(&error);
1198 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, status);
1199 }
1200 break;
1201 }
1202 case kSecXPCOpCopyEngineState:
1203 {
1204 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1205 CFArrayRef array = SOSCCCopyEngineState_Server(&error);
1206 CFDataRef derData = NULL;
1207
1208 require_quiet(array, done);
1209 derData = CFPropertyListCreateDERData(kCFAllocatorDefault, array, &error);
1210
1211 require_quiet(derData, done);
1212 xpc_dictionary_set_data(replyMessage, kSecXPCKeyResult, CFDataGetBytePtr(derData), CFDataGetLength(derData));
1213 done:
1214 CFReleaseNull(derData);
1215 CFReleaseNull(array);
1216 }
1217 }
1218 break;
1219 case kSecXPCOpCopyPeerPeerInfo:
1220 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1221 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1222 SOSCCCopyPeerPeerInfo_Server(&error),
1223 &error);
1224 }
1225 break;
1226 case kSecXPCOpCopyConcurringPeerPeerInfo:
1227 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1228 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1229 SOSCCCopyConcurringPeerPeerInfo_Server(&error),
1230 &error);
1231 }
1232 break;
1233 case kSecXPCOpCopyMyPeerInfo:
1234 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1235 SOSPeerInfoRef peerInfo = SOSCCCopyMyPeerInfo_Server(&error);
1236 CFDataRef peerInfoData = peerInfo ? SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, &error) : NULL;
1237 CFReleaseNull(peerInfo);
1238 if (peerInfoData) {
1239 xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(peerInfoData);
1240 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object);
1241 xpc_release(xpc_object);
1242 }
1243 CFReleaseNull(peerInfoData);
1244 }
1245 break;
1246 case kSecXPCOpGetLastDepartureReason:
1247 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1248 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
1249 SOSCCGetLastDepartureReason_Server(&error));
1250 }
1251 break;
1252 case kSecXPCOpSetLastDepartureReason:
1253 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1254 int32_t reason = (int32_t) xpc_dictionary_get_int64(event, kSecXPCKeyReason);
1255 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
1256 SOSCCSetLastDepartureReason_Server(reason, &error));
1257 }
1258 break;
1259 case kSecXPCOpProcessSyncWithPeers:
1260 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainSyncUpdates, &error)) {
1261 CFSetRef peers = SecXPCDictionaryCopySet(event, kSecXPCKeySet, &error);
1262 CFSetRef backupPeers = SecXPCDictionaryCopySet(event, kSecXPCKeySet2, &error);
1263 if (peers && backupPeers) {
1264 CFSetRef result = SOSCCProcessSyncWithPeers_Server(peers, backupPeers, &error);
1265 if (result) {
1266 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
1267 }
1268 CFReleaseNull(result);
1269 }
1270 CFReleaseNull(peers);
1271 CFReleaseNull(backupPeers);
1272 }
1273 break;
1274 case kSecXPCOpProcessSyncWithAllPeers:
1275 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainSyncUpdates, &error)) {
1276 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
1277 SOSCCProcessSyncWithAllPeers_Server(&error));
1278 }
1279 break;
1280 case soscc_EnsurePeerRegistration_id:
1281 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainSyncUpdates, &error)) {
1282 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1283 SOSCCProcessEnsurePeerRegistration_Server(&error));
1284 }
1285 break;
1286 case kSecXPCOpCopyIncompatibilityInfo:
1287 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1288 CFStringRef iis = SOSCCCopyIncompatibilityInfo_Server(&error);
1289 SecXPCDictionarySetString(replyMessage, kSecXPCKeyResult, iis, &error);
1290 CFReleaseSafe(iis);
1291 }
1292 break;
1293 case kSecXPCOpRollKeys:
1294 {
1295 bool force = xpc_dictionary_get_bool(event, "force");
1296 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1297 _SecServerRollKeys(force, &client, &error));
1298 }
1299 break;
1300 case kSecXPCOpWaitForInitialSync:
1301 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1302 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1303 SOSCCWaitForInitialSync_Server(&error));
1304 }
1305 break;
1306
1307 case kSecXPCOpCopyYetToSyncViews:
1308 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1309 CFArrayRef array = SOSCCCopyYetToSyncViewsList_Server(&error);
1310 if (array) {
1311 xpc_object_t xpc_array = _CFXPCCreateXPCObjectFromCFObject(array);
1312 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_array);
1313 xpc_release(xpc_array);
1314 }
1315 CFReleaseNull(array);
1316 }
1317 break;
1318 case kSecXPCOpSetEscrowRecord:
1319 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1320 CFStringRef escrow_label = SecXPCDictionaryCopyString(event, kSecXPCKeyEscrowLabel, &error);
1321 uint64_t tries = xpc_dictionary_get_int64(event, kSecXPCKeyTriesLabel);
1322
1323 bool result = SOSCCSetEscrowRecord_Server(escrow_label, tries, &error);
1324 if (result) {
1325 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
1326 }
1327 CFReleaseNull(escrow_label);
1328 }
1329 break;
1330 case kSecXPCOpGetEscrowRecord:
1331 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1332 CFDictionaryRef record = SOSCCCopyEscrowRecord_Server(&error);
1333 if (record) {
1334 xpc_object_t xpc_dictionary = _CFXPCCreateXPCObjectFromCFObject(record);
1335 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_dictionary);
1336 xpc_release(xpc_dictionary);
1337 }
1338 CFReleaseNull(record);
1339 }
1340 break;
1341 case kSecXPCOpCopyBackupInformation:
1342 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1343 CFDictionaryRef record = SOSCCCopyBackupInformation_Server(&error);
1344 if (record) {
1345 xpc_object_t xpc_dictionary = _CFXPCCreateXPCObjectFromCFObject(record);
1346 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_dictionary);
1347 xpc_release(xpc_dictionary);
1348 }
1349 CFReleaseNull(record);
1350 }
1351 break;
1352
1353 case kSecXPCOpCheckPeerAvailability:
1354 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1355 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCCheckPeerAvailability_Server(&error));
1356 }
1357 break;
1358
1359
1360 case kSecXPCOpIsThisDeviceLastBackup:
1361 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1362 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCkSecXPCOpIsThisDeviceLastBackup_Server(&error));
1363 }
1364 break;
1365 case kSecXPCOpPeersHaveViewsEnabled:
1366 {
1367 CFArrayRef viewSet = SecXPCDictionaryCopyArray(event, kSecXPCKeyArray, &error);
1368 if (viewSet) {
1369 CFBooleanRef result = SOSCCPeersHaveViewsEnabled_Server(viewSet, &error);
1370 if (result) {
1371 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result != kCFBooleanFalse);
1372 }
1373 }
1374 CFReleaseNull(viewSet);
1375 }
1376 break;
1377
1378 case kSecXPCOpWhoAmI:
1379 {
1380 if (client.musr)
1381 xpc_dictionary_set_data(replyMessage, "musr", CFDataGetBytePtr(client.musr), CFDataGetLength(client.musr));
1382 xpc_dictionary_set_bool(replyMessage, "system-keychain", client.allowSystemKeychain);
1383 xpc_dictionary_set_bool(replyMessage, "syncbubble-keychain", client.allowSyncBubbleKeychain);
1384 xpc_dictionary_set_bool(replyMessage, "network-extension", client.isNetworkExtension);
1385 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true);
1386 }
1387 break;
1388 case kSecXPCOpTransmogrifyToSyncBubble:
1389 {
1390 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateKeychainSyncBubble, &error)) {
1391 #if TARGET_OS_IOS
1392 uid_t uid = (uid_t)xpc_dictionary_get_int64(event, "uid");
1393 CFArrayRef services = SecXPCDictionaryCopyArray(event, "services", &error);
1394 bool res = false;
1395 if (uid && services) {
1396 res = _SecServerTransmogrifyToSyncBubble(services, uid, &client, &error);
1397 }
1398 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, res);
1399 CFReleaseNull(services);
1400 #else
1401 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false);
1402 #endif
1403 }
1404 }
1405 break;
1406 case kSecXPCOpTransmogrifyToSystemKeychain:
1407 {
1408 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateKeychainMigrateSystemKeychain, &error)) {
1409 #if TARGET_OS_IOS
1410 bool res = _SecServerTransmogrifyToSystemKeychain(&client, &error);
1411 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, res);
1412 #else
1413 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false);
1414 #endif
1415
1416 }
1417 }
1418 break;
1419 case kSecXPCOpDeleteUserView:
1420 {
1421 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateKeychainMigrateSystemKeychain, &error)) {
1422 bool res = false;
1423 #if TARGET_OS_IOS
1424 uid_t uid = (uid_t)xpc_dictionary_get_int64(event, "uid");
1425 if (uid) {
1426 res = _SecServerDeleteMUSERViews(&client, uid, &error);
1427 }
1428 #endif
1429 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, res);
1430
1431 }
1432 }
1433 break;
1434 case kSecXPCOpWrapToBackupSliceKeyBagForView:
1435 {
1436 CFStringRef viewname = SecXPCDictionaryCopyString(event, kSecXPCKeyViewName, &error);
1437 if(viewname) {
1438 CFDataRef plaintext = SecXPCDictionaryCopyData(event, kSecXPCData, &error);
1439 if (plaintext) {
1440 CFDataRef ciphertext = NULL;
1441 CFDataRef bskbEncoded = NULL;
1442
1443 bool result = SOSWrapToBackupSliceKeyBagForView_Server(viewname, plaintext, &ciphertext, &bskbEncoded, &error);
1444 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
1445
1446 if(!error && result) {
1447 if(ciphertext) {
1448 xpc_dictionary_set_data(replyMessage, kSecXPCData, CFDataGetBytePtr(ciphertext), CFDataGetLength(ciphertext));
1449 }
1450 if(bskbEncoded) {
1451 xpc_dictionary_set_data(replyMessage, kSecXPCKeyKeybag, CFDataGetBytePtr(bskbEncoded), CFDataGetLength(bskbEncoded));
1452 }
1453 }
1454 CFReleaseSafe(ciphertext);
1455 CFReleaseSafe(bskbEncoded);
1456 }
1457 CFReleaseSafe(plaintext);
1458 }
1459 CFReleaseNull(viewname);
1460 }
1461 break;
1462 case kSecXPCOpCopyApplication:
1463 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementCircleJoin, &error)) {
1464 SOSPeerInfoRef peerInfo = SOSCCCopyApplication_Server(&error);
1465 CFDataRef peerInfoData = peerInfo ? SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, &error) : NULL;
1466 CFReleaseNull(peerInfo);
1467 if (peerInfoData) {
1468 xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(peerInfoData);
1469 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object);
1470 xpc_release(xpc_object);
1471 }
1472 CFReleaseNull(peerInfoData);
1473 }
1474 break;
1475 case kSecXPCOpCopyCircleJoiningBlob:
1476 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementCircleJoin, &error)) {
1477 CFDataRef appBlob = SecXPCDictionaryCopyCFDataRef(event, kSecXPCData, &error);
1478 SOSPeerInfoRef applicant = SOSPeerInfoCreateFromData(kCFAllocatorDefault, &error, appBlob);
1479 CFDataRef pbblob = SOSCCCopyCircleJoiningBlob_Server(applicant, &error);
1480 if (pbblob) {
1481 xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(pbblob);
1482 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object);
1483 xpc_release(xpc_object);
1484 }
1485 CFReleaseNull(pbblob);
1486 CFReleaseNull(applicant);
1487 CFReleaseNull(appBlob);
1488 }
1489 break;
1490 case kSecXPCOpCopyInitialSyncBlob:
1491 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementCircleJoin, &error)) {
1492 CFDataRef initialblob = SOSCCCopyInitialSyncData_Server(&error);
1493 if (initialblob) {
1494 xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(initialblob);
1495 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object);
1496 xpc_release(xpc_object);
1497 }
1498 CFReleaseNull(initialblob);
1499 }
1500 break;
1501 case kSecXPCOpJoinWithCircleJoiningBlob:
1502 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementCircleJoin, &error)) {
1503 CFDataRef joiningBlob = SecXPCDictionaryCopyCFDataRef(event, kSecXPCData, &error);
1504 uint64_t version = xpc_dictionary_get_uint64(event, kSecXPCVersion);
1505 bool retval = SOSCCJoinWithCircleJoiningBlob_Server(joiningBlob, (PiggyBackProtocolVersion) version, &error);
1506 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, retval);
1507 CFReleaseNull(joiningBlob);
1508 }
1509 break;
1510
1511 case kSecXPCOpKVSKeyCleanup:
1512 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1513 bool retval = SOSCCCleanupKVSKeys_Server(&error);
1514 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, retval);
1515 }
1516 break;
1517 case kSecXPCOpPopulateKVS:
1518 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1519 bool retval = SOSCCTestPopulateKVSWithBadKeys_Server(&error);
1520 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, retval);
1521 }
1522 break;
1523 case kSecXPCOpMessageFromPeerIsPending:
1524 {
1525 SOSPeerInfoRef peer = SecXPCDictionaryCopyPeerInfo(event, kSecXPCKeyPeerInfo, &error);
1526 if (peer) {
1527 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1528 SOSCCMessageFromPeerIsPending_Server(peer, &error));
1529 }
1530 CFReleaseNull(peer);
1531 break;
1532 }
1533 case kSecXPCOpSendToPeerIsPending:
1534 {
1535 SOSPeerInfoRef peer = SecXPCDictionaryCopyPeerInfo(event, kSecXPCKeyPeerInfo, &error);
1536 if (peer) {
1537 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1538 SOSCCSendToPeerIsPending(peer, &error));
1539 }
1540 CFReleaseNull(peer);
1541 break;
1542 }
1543 case sec_delete_items_with_access_groups_id:
1544 {
1545 bool retval = false;
1546 #if TARGET_OS_IPHONE
1547 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateUninstallDeletion, &error)) {
1548 CFArrayRef accessGroups = SecXPCDictionaryCopyArray(event, kSecXPCKeyAccessGroups, &error);
1549
1550 if (accessGroups) {
1551 retval = _SecItemServerDeleteAllWithAccessGroups(accessGroups, &client, &error);
1552 }
1553 CFReleaseNull(accessGroups);
1554 }
1555 #endif
1556 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, retval);
1557 }
1558 break;
1559 case sec_item_copy_parent_certificates_id:
1560 {
1561 CFArrayRef results = NULL;
1562 if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateCertificateAllAccess, &error)) {
1563 CFDataRef issuer = SecXPCDictionaryCopyData(event, kSecXPCKeyNormalizedIssuer, &error);
1564 CFArrayRef accessGroups = SecXPCDictionaryCopyArray(event, kSecXPCKeyAccessGroups, &error);
1565 if (issuer && accessGroups) {
1566 results = _SecItemCopyParentCertificates(issuer, accessGroups, &error);
1567 }
1568 CFReleaseNull(issuer);
1569 CFReleaseNull(accessGroups);
1570 }
1571 SecXPCDictionarySetPListOptional(replyMessage, kSecXPCKeyResult, results, &error);
1572 CFReleaseNull(results);
1573 }
1574 break;
1575 case sec_item_certificate_exists_id:
1576 {
1577 bool result = false;
1578 if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateCertificateAllAccess, &error)) {
1579 CFDataRef issuer = SecXPCDictionaryCopyData(event, kSecXPCKeyNormalizedIssuer, &error);
1580 CFDataRef serialNum = SecXPCDictionaryCopyData(event, kSecXPCKeySerialNumber, &error);
1581 CFArrayRef accessGroups = SecXPCDictionaryCopyArray(event, kSecXPCKeyAccessGroups, &error);
1582 if (issuer && serialNum && accessGroups) {
1583 result = _SecItemCertificateExists(issuer, serialNum, accessGroups, &error);
1584 }
1585 CFReleaseNull(issuer);
1586 CFReleaseNull(serialNum);
1587 CFReleaseNull(accessGroups);
1588 }
1589 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
1590 }
1591 break;
1592 case kSecXPCOpCKKSEndpoint: {
1593 if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateCKKS, &error)) {
1594 xpc_endpoint_t endpoint = SecServerCreateCKKSEndpoint();
1595 if (endpoint) {
1596 xpc_dictionary_set_value(replyMessage, kSecXPCKeyEndpoint, endpoint);
1597 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true);
1598 xpc_release(endpoint);
1599 } else {
1600 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false);
1601 }
1602 }
1603 break;
1604 }
1605 case kSecXPCOpSOSEndpoint: {
1606 if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1607 xpc_endpoint_t endpoint = SOSCCCreateSOSEndpoint_server(&error);
1608 if (endpoint) {
1609 xpc_dictionary_set_value(replyMessage, kSecXPCKeyEndpoint, endpoint);
1610 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true);
1611 xpc_release(endpoint);
1612 } else {
1613 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false);
1614 }
1615 }
1616 break;
1617 }
1618 case kSecXPCOpSecuritydXPCServerEndpoint: {
1619 xpc_endpoint_t endpoint = SecCreateSecuritydXPCServerEndpoint(&error);
1620 if (endpoint) {
1621 xpc_dictionary_set_value(replyMessage, kSecXPCKeyEndpoint, endpoint);
1622 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true);
1623 xpc_release(endpoint);
1624 } else {
1625 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false);
1626 }
1627 break;
1628 }
1629 case kSecXPCOpBackupKeybagAdd: {
1630 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementBackupTableOperations, &error)) {
1631 CFDataRef keybag = NULL, passcode = NULL;
1632 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
1633 CFDataRef identifier = NULL;
1634 CFDataRef pathinfo = NULL; // really a CFURLRef
1635 bool added = _SecServerBackupKeybagAdd(&client, passcode, &identifier, &pathinfo, &error);
1636 if (added) {
1637 added &= SecXPCDictionarySetDataOptional(replyMessage, kSecXPCKeyBackupKeybagIdentifier, identifier, &error);
1638 added &= SecXPCDictionarySetDataOptional(replyMessage, kSecXPCKeyBackupKeybagPath, pathinfo, &error);
1639 SecXPCDictionarySetBool(replyMessage, kSecXPCKeyResult, added, NULL);
1640 } else {
1641 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false);
1642 }
1643 }
1644 CFReleaseSafe(passcode);
1645 CFReleaseSafe(keybag);
1646 }
1647 break;
1648 }
1649 case kSecXPCOpBackupKeybagDelete: {
1650 // >>>
1651 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementBackupTableOperations, &error)) {
1652 bool deleted = false;
1653 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
1654 if (query) {
1655 CFTypeRef matchLimit = CFDictionaryGetValue(query, kSecMatchLimit);
1656 bool deleteAll = matchLimit && CFEqualSafe(matchLimit, kSecMatchLimitAll);
1657
1658 if (deleteAll && !EntitlementPresentAndTrue(operation, client.task, kSecEntitlementBackupTableOperationsDeleteAll, &error)) {
1659 // require special entitlement to delete all backup keybags
1660 } else {
1661 CFMutableDictionaryRef attributes = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, query);
1662 CFStringRef requestedAgrp = CFDictionaryGetValue(attributes, kSecAttrAccessGroup);
1663 CFStringRef resolvedAgrp = NULL;
1664 if (client.musr) {
1665 CFDictionarySetValue(attributes, kSecAttrMultiUser, client.musr);
1666 }
1667 if (extractAccessGroup(&client, requestedAgrp, &resolvedAgrp, &error)) {
1668 if (resolvedAgrp) {
1669 CFDictionarySetValue(attributes, kSecAttrAccessGroup, resolvedAgrp);
1670 }
1671 deleted = _SecServerBackupKeybagDelete(attributes, deleteAll, &error);
1672 }
1673 CFReleaseNull(resolvedAgrp);
1674 CFReleaseNull(attributes);
1675 }
1676 }
1677 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, deleted);
1678 CFReleaseNull(query);
1679 }
1680 break;
1681 }
1682 default:
1683 break;
1684 }
1685
1686 if (error)
1687 {
1688 if(SecErrorGetOSStatus(error) == errSecItemNotFound || isSOSErrorCoded(error, kSOSErrorPublicKeyAbsent))
1689 secdebug("ipc", "%@ %@ %@", client.task, SOSCCGetOperationDescription((enum SecXPCOperation)operation), error);
1690 else if (SecErrorGetOSStatus(error) == errSecAuthNeeded)
1691 secwarning("Authentication is needed %@ %@ %@", client.task, SOSCCGetOperationDescription((enum SecXPCOperation)operation), error);
1692 else
1693 secerror("%@ %@ %@", client.task, SOSCCGetOperationDescription((enum SecXPCOperation)operation), error);
1694
1695 xpcError = SecCreateXPCObjectWithCFError(error);
1696 if (replyMessage) {
1697 xpc_dictionary_set_value(replyMessage, kSecXPCKeyError, xpcError);
1698 }
1699 } else if (replyMessage) {
1700 secdebug("ipc", "%@ %@ responding %@", client.task, SOSCCGetOperationDescription((enum SecXPCOperation)operation), replyMessage);
1701 }
1702 } else {
1703 SecCFCreateErrorWithFormat(kSecXPCErrorUnexpectedType, sSecXPCErrorDomain, NULL, &error, 0, CFSTR("Messages expect to be xpc dictionary, got: %@"), event);
1704 secerror("%@: returning error: %@", client.task, error);
1705 xpcError = SecCreateXPCObjectWithCFError(error);
1706 replyMessage = xpc_create_reply_with_format(event, "{%string: %value}", kSecXPCKeyError, xpcError);
1707 }
1708
1709 if (replyMessage) {
1710 xpc_connection_send_message(connection, replyMessage);
1711 xpc_release(replyMessage);
1712 }
1713 if (xpcError)
1714 xpc_release(xpcError);
1715 #if TARGET_OS_IPHONE
1716 pthread_setspecific(taskThreadKey, NULL);
1717 #endif
1718 CFReleaseSafe(error);
1719 CFReleaseSafe(client.accessGroups);
1720 CFReleaseSafe(client.musr);
1721 CFReleaseSafe(client.task);
1722 CFReleaseSafe(domains);
1723 CFReleaseSafe(clientAuditToken);
1724 }
1725
1726 static void securityd_xpc_init(const char *service_name)
1727 {
1728 #if TARGET_OS_IPHONE
1729 pthread_key_create(&taskThreadKey, NULL);
1730 SecTaskDiagnoseEntitlements = secTaskDiagnoseEntitlements;
1731 #endif
1732
1733 secdebug("serverxpc", "start");
1734 xpc_connection_t listener = xpc_connection_create_mach_service(service_name, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER);
1735 if (!listener) {
1736 seccritical("security failed to register xpc listener for %s, exiting", service_name);
1737 abort();
1738 }
1739
1740 xpc_connection_set_event_handler(listener, ^(xpc_object_t connection) {
1741 if (xpc_get_type(connection) == XPC_TYPE_CONNECTION) {
1742 xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
1743 if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) {
1744 xpc_retain(connection);
1745 xpc_retain(event);
1746 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
1747 securityd_xpc_dictionary_handler(connection, event);
1748 xpc_release(event);
1749 xpc_release(connection);
1750 });
1751 }
1752 });
1753 xpc_connection_resume(connection);
1754 }
1755 });
1756 xpc_connection_resume(listener);
1757
1758 #if OCTAGON
1759 xpc_activity_register("com.apple.securityd.daily", XPC_ACTIVITY_CHECK_IN, ^(xpc_activity_t activity) {
1760 xpc_activity_state_t activityState = xpc_activity_get_state(activity);
1761 if (activityState == XPC_ACTIVITY_STATE_RUN) {
1762 SecCKKS24hrNotification();
1763 }
1764 });
1765 #endif
1766 }
1767
1768
1769 // <rdar://problem/22425706> 13B104+Roots:Device never moved past spinner after using approval to ENABLE icdp
1770
1771 #if TARGET_OS_EMBEDDED
1772 static void securityd_soscc_lock_hack() {
1773 dispatch_queue_t soscc_lock_queue = dispatch_queue_create("soscc_lock_queue", DISPATCH_QUEUE_PRIORITY_DEFAULT);
1774 int soscc_tok;
1775
1776 // <rdar://problem/22500239> Prevent securityd from quitting while holding a keychain assertion
1777 // FIXME: securityd isn't currently registering for any other notifyd events. If/when it does,
1778 // this code will need to be generalized / migrated away from just this specific purpose.
1779 xpc_set_event_stream_handler("com.apple.notifyd.matching", dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(xpc_object_t object) {
1780 char *event_description = xpc_copy_description(object);
1781 secnotice("events", "%s", event_description);
1782 free(event_description);
1783 });
1784
1785 secnotice("lockassertion", "notify_register_dispatch(kSOSCCHoldLockForInitialSync)");
1786 notify_register_dispatch(kSOSCCHoldLockForInitialSync, &soscc_tok, soscc_lock_queue, ^(int token __unused) {
1787 secnotice("lockassertion", "kSOSCCHoldLockForInitialSync: grabbing the lock");
1788 CFErrorRef error = NULL;
1789
1790 uint64_t one_minute = 60ull;
1791 if(SecAKSLockUserKeybag(one_minute, &error)){
1792 // <rdar://problem/22500239> Prevent securityd from quitting while holding a keychain assertion
1793 xpc_transaction_begin();
1794
1795 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, one_minute*NSEC_PER_SEC), soscc_lock_queue, ^{
1796 CFErrorRef localError = NULL;
1797 if(!SecAKSUnLockUserKeybag(&localError))
1798 secerror("failed to unlock: %@", localError);
1799 CFReleaseNull(localError);
1800 xpc_transaction_end();
1801 });
1802 } else {
1803 secerror("Failed to take device lock assertion: %@", error);
1804 }
1805 CFReleaseNull(error);
1806 secnotice("lockassertion", "kSOSCCHoldLockForInitialSync => done");
1807 });
1808 }
1809 #endif
1810
1811 #if TARGET_OS_OSX
1812
1813 static char *
1814 homedirPath(void)
1815 {
1816 static char homeDir[PATH_MAX] = {};
1817
1818 if (homeDir[0] == '\0') {
1819 struct passwd* pwd = getpwuid(getuid());
1820 if (pwd == NULL)
1821 return NULL;
1822
1823 if (realpath(pwd->pw_dir, homeDir) == NULL) {
1824 strlcpy(homeDir, pwd->pw_dir, sizeof(homeDir));
1825 }
1826 }
1827 return homeDir;
1828 }
1829 #endif
1830
1831
1832 int main(int argc, char *argv[])
1833 {
1834 char *wait4debugger = getenv("WAIT4DEBUGGER");
1835 if (wait4debugger && !strcasecmp("YES", wait4debugger)) {
1836 seccritical("SIGSTOPing self, awaiting debugger");
1837 kill(getpid(), SIGSTOP);
1838 seccritical("Again, for good luck (or bad debuggers)");
1839 kill(getpid(), SIGSTOP);
1840 }
1841
1842 /* <rdar://problem/15792007> Users with network home folders are unable to use/save password for Mail/Cal/Contacts/websites
1843 Secd doesn't realize DB connections get invalidated when network home directory users logout
1844 and their home gets unmounted. Exit secd, start fresh when user logs back in.
1845 */
1846 #if TARGET_OS_OSX
1847 int sessionstatechanged_tok;
1848 notify_register_dispatch(kSA_SessionStateChangedNotification, &sessionstatechanged_tok, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(int token __unused) {
1849 // we could be a process running as root.
1850 // However, since root never logs out this isn't an issue.
1851 if (SASSessionStateForUser(getuid()) == kSA_state_loggingout_pointofnoreturn) {
1852 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
1853 xpc_transaction_exit_clean();
1854 });
1855 }
1856 });
1857 #endif
1858
1859 #if TARGET_OS_OSX
1860 #define SECD_PROFILE_NAME "com.apple.secd"
1861 const char *homedir = homedirPath();
1862 if (homedir == NULL)
1863 errx(1, "failed to get home directory for secd");
1864
1865 char *errorbuf = NULL;
1866 const char *sandbox_params[] = {
1867 "_HOME", homedir,
1868 NULL
1869 };
1870 int32_t rc;
1871
1872 rc = sandbox_init_with_parameters(SECD_PROFILE_NAME, SANDBOX_NAMED, sandbox_params, &errorbuf);
1873 if (rc)
1874 err(1, "Failed to process in a sandbox: %d %s", rc, errorbuf);
1875 #endif /* TARGET_OS_OSX */
1876
1877 const char *serviceName = kSecuritydXPCServiceName;
1878 /* setup SQDLite before some other component have a chance to create a database connection */
1879 _SecDbServerSetup();
1880
1881 securityd_init_server();
1882 securityd_xpc_init(serviceName);
1883
1884 // <rdar://problem/22425706> 13B104+Roots:Device never moved past spinner after using approval to ENABLE icdp
1885 #if TARGET_OS_EMBEDDED
1886 securityd_soscc_lock_hack();
1887 #endif
1888
1889 dispatch_main();
1890 }
1891
1892 /* vi:set ts=4 sw=4 et: */