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