]> git.saurik.com Git - apple/security.git/blob - OSX/sec/ipc/server.c
Security-58286.41.2.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 uint8_t zero = 0;
1084 CFDataRef nullData = CFDataCreate(kCFAllocatorDefault, &zero, 1); // token we send if we really wanted to send NULL
1085 if(CFEqual(recovery_key, nullData)) {
1086 CFReleaseNull(recovery_key);
1087 }
1088 CFReleaseNull(nullData);
1089 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRegisterRecoveryPublicKey_Server(recovery_key, &error));
1090 CFReleaseNull(recovery_key);
1091 }
1092 }
1093 break;
1094 case kSecXPCOpGetRecoveryPublicKey:
1095 {
1096 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
1097 xpc_object_t xpc_recovery_object = NULL;
1098 CFDataRef recovery = SOSCCCopyRecoveryPublicKey(&error);
1099 if(recovery)
1100 xpc_recovery_object = _CFXPCCreateXPCObjectFromCFObject(recovery);
1101
1102 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_recovery_object);
1103 CFReleaseNull(recovery);
1104 }
1105 }
1106 break;
1107 case kSecXPCOpSetBagForAllSlices:
1108 {
1109 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) {
1110 CFDataRef backupSlice = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error);
1111 bool includeV0 = xpc_dictionary_get_bool(event, kSecXPCKeyIncludeV0);
1112 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, backupSlice && SOSCCRegisterSingleRecoverySecret_Server(backupSlice, includeV0, &error));
1113 CFReleaseSafe(backupSlice);
1114 }
1115 }
1116 break;
1117 case kSecXPCOpCopyApplicantPeerInfo:
1118 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1119 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1120 SOSCCCopyApplicantPeerInfo_Server(&error),
1121 &error);
1122 }
1123 break;
1124 case kSecXPCOpCopyValidPeerPeerInfo:
1125 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1126 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1127 SOSCCCopyValidPeerPeerInfo_Server(&error),
1128 &error);
1129 }
1130 break;
1131 case kSecXPCOpValidateUserPublic:
1132 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1133 bool trusted = SOSCCValidateUserPublic_Server(&error);
1134 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, trusted);
1135 }
1136 break;
1137 case kSecXPCOpCopyNotValidPeerPeerInfo:
1138 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1139 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1140 SOSCCCopyNotValidPeerPeerInfo_Server(&error),
1141 &error);
1142 }
1143 break;
1144 case kSecXPCOpCopyGenerationPeerInfo:
1145 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1146 xpc_dictionary_set_and_consume_CFArray(replyMessage, kSecXPCKeyResult,
1147 SOSCCCopyGenerationPeerInfo_Server(&error));
1148 }
1149 break;
1150 case kSecXPCOpCopyRetirementPeerInfo:
1151 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1152 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1153 SOSCCCopyRetirementPeerInfo_Server(&error),
1154 &error);
1155 }
1156 break;
1157 case kSecXPCOpCopyViewUnawarePeerInfo:
1158 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1159 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1160 SOSCCCopyViewUnawarePeerInfo_Server(&error),
1161 &error);
1162 }
1163 break;
1164 case kSecXPCOpCopyAccountData:
1165 {
1166 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1167 xpc_object_t xpc_account_object = NULL;
1168 CFDataRef accountData = SOSCCCopyAccountState_Server(&error);
1169 if(accountData)
1170 xpc_account_object = _CFXPCCreateXPCObjectFromCFObject(accountData);
1171
1172 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_account_object);
1173 CFReleaseNull(accountData);
1174 }
1175 break;
1176 }
1177 case kSecXPCOpDeleteAccountData:
1178 {
1179 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1180 bool status = SOSCCDeleteAccountState_Server(&error);
1181 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, status);
1182 }
1183 break;
1184 }
1185 case kSecXPCOpCopyEngineData:
1186 {
1187 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1188
1189 xpc_object_t xpc_engine_object = NULL;
1190 CFDataRef engineData = SOSCCCopyEngineData_Server(&error);
1191 if(engineData)
1192 xpc_engine_object = _CFXPCCreateXPCObjectFromCFObject(engineData);
1193
1194 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_engine_object);
1195 CFReleaseNull(engineData);
1196
1197 }
1198 break;
1199 }
1200 case kSecXPCOpDeleteEngineData:
1201 {
1202 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1203 bool status = SOSCCDeleteEngineState_Server(&error);
1204 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, status);
1205 }
1206 break;
1207 }
1208 case kSecXPCOpCopyEngineState:
1209 {
1210 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1211 CFArrayRef array = SOSCCCopyEngineState_Server(&error);
1212 CFDataRef derData = NULL;
1213
1214 require_quiet(array, done);
1215 derData = CFPropertyListCreateDERData(kCFAllocatorDefault, array, &error);
1216
1217 require_quiet(derData, done);
1218 xpc_dictionary_set_data(replyMessage, kSecXPCKeyResult, CFDataGetBytePtr(derData), CFDataGetLength(derData));
1219 done:
1220 CFReleaseNull(derData);
1221 CFReleaseNull(array);
1222 }
1223 }
1224 break;
1225 case kSecXPCOpCopyPeerPeerInfo:
1226 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1227 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1228 SOSCCCopyPeerPeerInfo_Server(&error),
1229 &error);
1230 }
1231 break;
1232 case kSecXPCOpCopyConcurringPeerPeerInfo:
1233 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1234 xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult,
1235 SOSCCCopyConcurringPeerPeerInfo_Server(&error),
1236 &error);
1237 }
1238 break;
1239 case kSecXPCOpCopyMyPeerInfo:
1240 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1241 SOSPeerInfoRef peerInfo = SOSCCCopyMyPeerInfo_Server(&error);
1242 CFDataRef peerInfoData = peerInfo ? SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, &error) : NULL;
1243 CFReleaseNull(peerInfo);
1244 if (peerInfoData) {
1245 xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(peerInfoData);
1246 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object);
1247 xpc_release(xpc_object);
1248 }
1249 CFReleaseNull(peerInfoData);
1250 }
1251 break;
1252 case kSecXPCOpGetLastDepartureReason:
1253 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1254 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
1255 SOSCCGetLastDepartureReason_Server(&error));
1256 }
1257 break;
1258 case kSecXPCOpSetLastDepartureReason:
1259 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1260 int32_t reason = (int32_t) xpc_dictionary_get_int64(event, kSecXPCKeyReason);
1261 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
1262 SOSCCSetLastDepartureReason_Server(reason, &error));
1263 }
1264 break;
1265 case kSecXPCOpProcessSyncWithPeers:
1266 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainSyncUpdates, &error)) {
1267 CFSetRef peers = SecXPCDictionaryCopySet(event, kSecXPCKeySet, &error);
1268 CFSetRef backupPeers = SecXPCDictionaryCopySet(event, kSecXPCKeySet2, &error);
1269 if (peers && backupPeers) {
1270 CFSetRef result = SOSCCProcessSyncWithPeers_Server(peers, backupPeers, &error);
1271 if (result) {
1272 SecXPCDictionarySetPList(replyMessage, kSecXPCKeyResult, result, &error);
1273 }
1274 CFReleaseNull(result);
1275 }
1276 CFReleaseNull(peers);
1277 CFReleaseNull(backupPeers);
1278 }
1279 break;
1280 case kSecXPCOpProcessSyncWithAllPeers:
1281 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainSyncUpdates, &error)) {
1282 xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult,
1283 SOSCCProcessSyncWithAllPeers_Server(&error));
1284 }
1285 break;
1286 case soscc_EnsurePeerRegistration_id:
1287 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainSyncUpdates, &error)) {
1288 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1289 SOSCCProcessEnsurePeerRegistration_Server(&error));
1290 }
1291 break;
1292 case kSecXPCOpCopyIncompatibilityInfo:
1293 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1294 CFStringRef iis = SOSCCCopyIncompatibilityInfo_Server(&error);
1295 SecXPCDictionarySetString(replyMessage, kSecXPCKeyResult, iis, &error);
1296 CFReleaseSafe(iis);
1297 }
1298 break;
1299 case kSecXPCOpRollKeys:
1300 {
1301 bool force = xpc_dictionary_get_bool(event, "force");
1302 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1303 _SecServerRollKeys(force, &client, &error));
1304 }
1305 break;
1306 case kSecXPCOpWaitForInitialSync:
1307 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1308 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1309 SOSCCWaitForInitialSync_Server(&error));
1310 }
1311 break;
1312
1313 case kSecXPCOpCopyYetToSyncViews:
1314 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1315 CFArrayRef array = SOSCCCopyYetToSyncViewsList_Server(&error);
1316 if (array) {
1317 xpc_object_t xpc_array = _CFXPCCreateXPCObjectFromCFObject(array);
1318 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_array);
1319 xpc_release(xpc_array);
1320 }
1321 CFReleaseNull(array);
1322 }
1323 break;
1324 case kSecXPCOpSetEscrowRecord:
1325 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1326 CFStringRef escrow_label = SecXPCDictionaryCopyString(event, kSecXPCKeyEscrowLabel, &error);
1327 uint64_t tries = xpc_dictionary_get_int64(event, kSecXPCKeyTriesLabel);
1328
1329 bool result = SOSCCSetEscrowRecord_Server(escrow_label, tries, &error);
1330 if (result) {
1331 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
1332 }
1333 CFReleaseNull(escrow_label);
1334 }
1335 break;
1336 case kSecXPCOpGetEscrowRecord:
1337 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1338 CFDictionaryRef record = SOSCCCopyEscrowRecord_Server(&error);
1339 if (record) {
1340 xpc_object_t xpc_dictionary = _CFXPCCreateXPCObjectFromCFObject(record);
1341 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_dictionary);
1342 xpc_release(xpc_dictionary);
1343 }
1344 CFReleaseNull(record);
1345 }
1346 break;
1347 case kSecXPCOpCopyBackupInformation:
1348 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1349 CFDictionaryRef record = SOSCCCopyBackupInformation_Server(&error);
1350 if (record) {
1351 xpc_object_t xpc_dictionary = _CFXPCCreateXPCObjectFromCFObject(record);
1352 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_dictionary);
1353 xpc_release(xpc_dictionary);
1354 }
1355 CFReleaseNull(record);
1356 }
1357 break;
1358
1359 case kSecXPCOpCheckPeerAvailability:
1360 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1361 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCCheckPeerAvailability_Server(&error));
1362 }
1363 break;
1364
1365
1366 case kSecXPCOpIsThisDeviceLastBackup:
1367 if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1368 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCkSecXPCOpIsThisDeviceLastBackup_Server(&error));
1369 }
1370 break;
1371 case kSecXPCOpPeersHaveViewsEnabled:
1372 {
1373 CFArrayRef viewSet = SecXPCDictionaryCopyArray(event, kSecXPCKeyArray, &error);
1374 if (viewSet) {
1375 CFBooleanRef result = SOSCCPeersHaveViewsEnabled_Server(viewSet, &error);
1376 if (result) {
1377 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result != kCFBooleanFalse);
1378 }
1379 }
1380 CFReleaseNull(viewSet);
1381 }
1382 break;
1383
1384 case kSecXPCOpWhoAmI:
1385 {
1386 if (client.musr)
1387 xpc_dictionary_set_data(replyMessage, "musr", CFDataGetBytePtr(client.musr), CFDataGetLength(client.musr));
1388 xpc_dictionary_set_bool(replyMessage, "system-keychain", client.allowSystemKeychain);
1389 xpc_dictionary_set_bool(replyMessage, "syncbubble-keychain", client.allowSyncBubbleKeychain);
1390 xpc_dictionary_set_bool(replyMessage, "network-extension", client.isNetworkExtension);
1391 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true);
1392 }
1393 break;
1394 case kSecXPCOpTransmogrifyToSyncBubble:
1395 {
1396 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateKeychainSyncBubble, &error)) {
1397 #if TARGET_OS_IOS
1398 uid_t uid = (uid_t)xpc_dictionary_get_int64(event, "uid");
1399 CFArrayRef services = SecXPCDictionaryCopyArray(event, "services", &error);
1400 bool res = false;
1401 if (uid && services) {
1402 res = _SecServerTransmogrifyToSyncBubble(services, uid, &client, &error);
1403 }
1404 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, res);
1405 CFReleaseNull(services);
1406 #else
1407 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false);
1408 #endif
1409 }
1410 }
1411 break;
1412 case kSecXPCOpTransmogrifyToSystemKeychain:
1413 {
1414 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateKeychainMigrateSystemKeychain, &error)) {
1415 #if TARGET_OS_IOS
1416 bool res = _SecServerTransmogrifyToSystemKeychain(&client, &error);
1417 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, res);
1418 #else
1419 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false);
1420 #endif
1421
1422 }
1423 }
1424 break;
1425 case kSecXPCOpDeleteUserView:
1426 {
1427 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateKeychainMigrateSystemKeychain, &error)) {
1428 bool res = false;
1429 #if TARGET_OS_IOS
1430 uid_t uid = (uid_t)xpc_dictionary_get_int64(event, "uid");
1431 if (uid) {
1432 res = _SecServerDeleteMUSERViews(&client, uid, &error);
1433 }
1434 #endif
1435 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, res);
1436
1437 }
1438 }
1439 break;
1440 case kSecXPCOpWrapToBackupSliceKeyBagForView:
1441 {
1442 CFStringRef viewname = SecXPCDictionaryCopyString(event, kSecXPCKeyViewName, &error);
1443 if(viewname) {
1444 CFDataRef plaintext = SecXPCDictionaryCopyData(event, kSecXPCData, &error);
1445 if (plaintext) {
1446 CFDataRef ciphertext = NULL;
1447 CFDataRef bskbEncoded = NULL;
1448
1449 bool result = SOSWrapToBackupSliceKeyBagForView_Server(viewname, plaintext, &ciphertext, &bskbEncoded, &error);
1450 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
1451
1452 if(!error && result) {
1453 if(ciphertext) {
1454 xpc_dictionary_set_data(replyMessage, kSecXPCData, CFDataGetBytePtr(ciphertext), CFDataGetLength(ciphertext));
1455 }
1456 if(bskbEncoded) {
1457 xpc_dictionary_set_data(replyMessage, kSecXPCKeyKeybag, CFDataGetBytePtr(bskbEncoded), CFDataGetLength(bskbEncoded));
1458 }
1459 }
1460 CFReleaseSafe(ciphertext);
1461 CFReleaseSafe(bskbEncoded);
1462 }
1463 CFReleaseSafe(plaintext);
1464 }
1465 CFReleaseNull(viewname);
1466 }
1467 break;
1468 case kSecXPCOpCopyApplication:
1469 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementCircleJoin, &error)) {
1470 SOSPeerInfoRef peerInfo = SOSCCCopyApplication_Server(&error);
1471 CFDataRef peerInfoData = peerInfo ? SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, &error) : NULL;
1472 CFReleaseNull(peerInfo);
1473 if (peerInfoData) {
1474 xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(peerInfoData);
1475 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object);
1476 xpc_release(xpc_object);
1477 }
1478 CFReleaseNull(peerInfoData);
1479 }
1480 break;
1481 case kSecXPCOpCopyCircleJoiningBlob:
1482 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementCircleJoin, &error)) {
1483 CFDataRef appBlob = SecXPCDictionaryCopyCFDataRef(event, kSecXPCData, &error);
1484 SOSPeerInfoRef applicant = SOSPeerInfoCreateFromData(kCFAllocatorDefault, &error, appBlob);
1485 CFDataRef pbblob = SOSCCCopyCircleJoiningBlob_Server(applicant, &error);
1486 if (pbblob) {
1487 xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(pbblob);
1488 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object);
1489 xpc_release(xpc_object);
1490 }
1491 CFReleaseNull(pbblob);
1492 CFReleaseNull(applicant);
1493 CFReleaseNull(appBlob);
1494 }
1495 break;
1496 case kSecXPCOpCopyInitialSyncBlob:
1497 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementCircleJoin, &error)) {
1498 CFDataRef initialblob = SOSCCCopyInitialSyncData_Server(&error);
1499 if (initialblob) {
1500 xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(initialblob);
1501 xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object);
1502 xpc_release(xpc_object);
1503 }
1504 CFReleaseNull(initialblob);
1505 }
1506 break;
1507 case kSecXPCOpJoinWithCircleJoiningBlob:
1508 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementCircleJoin, &error)) {
1509 CFDataRef joiningBlob = SecXPCDictionaryCopyCFDataRef(event, kSecXPCData, &error);
1510 uint64_t version = xpc_dictionary_get_uint64(event, kSecXPCVersion);
1511 bool retval = SOSCCJoinWithCircleJoiningBlob_Server(joiningBlob, (PiggyBackProtocolVersion) version, &error);
1512 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, retval);
1513 CFReleaseNull(joiningBlob);
1514 }
1515 break;
1516
1517 case kSecXPCOpKVSKeyCleanup:
1518 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1519 bool retval = SOSCCCleanupKVSKeys_Server(&error);
1520 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, retval);
1521 }
1522 break;
1523 case kSecXPCOpPopulateKVS:
1524 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1525 bool retval = SOSCCTestPopulateKVSWithBadKeys_Server(&error);
1526 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, retval);
1527 }
1528 break;
1529 case kSecXPCOpMessageFromPeerIsPending:
1530 {
1531 SOSPeerInfoRef peer = SecXPCDictionaryCopyPeerInfo(event, kSecXPCKeyPeerInfo, &error);
1532 if (peer) {
1533 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1534 SOSCCMessageFromPeerIsPending_Server(peer, &error));
1535 }
1536 CFReleaseNull(peer);
1537 break;
1538 }
1539 case kSecXPCOpSendToPeerIsPending:
1540 {
1541 SOSPeerInfoRef peer = SecXPCDictionaryCopyPeerInfo(event, kSecXPCKeyPeerInfo, &error);
1542 if (peer) {
1543 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult,
1544 SOSCCSendToPeerIsPending(peer, &error));
1545 }
1546 CFReleaseNull(peer);
1547 break;
1548 }
1549 case sec_delete_items_with_access_groups_id:
1550 {
1551 bool retval = false;
1552 #if TARGET_OS_IPHONE
1553 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateUninstallDeletion, &error)) {
1554 CFArrayRef accessGroups = SecXPCDictionaryCopyArray(event, kSecXPCKeyAccessGroups, &error);
1555
1556 if (accessGroups) {
1557 retval = _SecItemServerDeleteAllWithAccessGroups(accessGroups, &client, &error);
1558 }
1559 CFReleaseNull(accessGroups);
1560 }
1561 #endif
1562 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, retval);
1563 }
1564 break;
1565 case sec_item_copy_parent_certificates_id:
1566 {
1567 CFArrayRef results = NULL;
1568 if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateCertificateAllAccess, &error)) {
1569 CFDataRef issuer = SecXPCDictionaryCopyData(event, kSecXPCKeyNormalizedIssuer, &error);
1570 CFArrayRef accessGroups = SecXPCDictionaryCopyArray(event, kSecXPCKeyAccessGroups, &error);
1571 if (issuer && accessGroups) {
1572 results = _SecItemCopyParentCertificates(issuer, accessGroups, &error);
1573 }
1574 CFReleaseNull(issuer);
1575 CFReleaseNull(accessGroups);
1576 }
1577 SecXPCDictionarySetPListOptional(replyMessage, kSecXPCKeyResult, results, &error);
1578 CFReleaseNull(results);
1579 }
1580 break;
1581 case sec_item_certificate_exists_id:
1582 {
1583 bool result = false;
1584 if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateCertificateAllAccess, &error)) {
1585 CFDataRef issuer = SecXPCDictionaryCopyData(event, kSecXPCKeyNormalizedIssuer, &error);
1586 CFDataRef serialNum = SecXPCDictionaryCopyData(event, kSecXPCKeySerialNumber, &error);
1587 CFArrayRef accessGroups = SecXPCDictionaryCopyArray(event, kSecXPCKeyAccessGroups, &error);
1588 if (issuer && serialNum && accessGroups) {
1589 result = _SecItemCertificateExists(issuer, serialNum, accessGroups, &error);
1590 }
1591 CFReleaseNull(issuer);
1592 CFReleaseNull(serialNum);
1593 CFReleaseNull(accessGroups);
1594 }
1595 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result);
1596 }
1597 break;
1598 case kSecXPCOpCKKSEndpoint: {
1599 if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateCKKS, &error)) {
1600 xpc_endpoint_t endpoint = SecServerCreateCKKSEndpoint();
1601 if (endpoint) {
1602 xpc_dictionary_set_value(replyMessage, kSecXPCKeyEndpoint, endpoint);
1603 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true);
1604 xpc_release(endpoint);
1605 } else {
1606 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false);
1607 }
1608 }
1609 break;
1610 }
1611 case kSecXPCOpSOSEndpoint: {
1612 if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) {
1613 xpc_endpoint_t endpoint = SOSCCCreateSOSEndpoint_server(&error);
1614 if (endpoint) {
1615 xpc_dictionary_set_value(replyMessage, kSecXPCKeyEndpoint, endpoint);
1616 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true);
1617 xpc_release(endpoint);
1618 } else {
1619 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false);
1620 }
1621 }
1622 break;
1623 }
1624 case kSecXPCOpSecuritydXPCServerEndpoint: {
1625 xpc_endpoint_t endpoint = SecCreateSecuritydXPCServerEndpoint(&error);
1626 if (endpoint) {
1627 xpc_dictionary_set_value(replyMessage, kSecXPCKeyEndpoint, endpoint);
1628 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true);
1629 xpc_release(endpoint);
1630 } else {
1631 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false);
1632 }
1633 break;
1634 }
1635 case kSecXPCOpBackupKeybagAdd: {
1636 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementBackupTableOperations, &error)) {
1637 CFDataRef keybag = NULL, passcode = NULL;
1638 if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) {
1639 CFDataRef identifier = NULL;
1640 CFDataRef pathinfo = NULL; // really a CFURLRef
1641 bool added = _SecServerBackupKeybagAdd(&client, passcode, &identifier, &pathinfo, &error);
1642 if (added) {
1643 added &= SecXPCDictionarySetDataOptional(replyMessage, kSecXPCKeyBackupKeybagIdentifier, identifier, &error);
1644 added &= SecXPCDictionarySetDataOptional(replyMessage, kSecXPCKeyBackupKeybagPath, pathinfo, &error);
1645 SecXPCDictionarySetBool(replyMessage, kSecXPCKeyResult, added, NULL);
1646 } else {
1647 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false);
1648 }
1649 }
1650 CFReleaseSafe(passcode);
1651 CFReleaseSafe(keybag);
1652 }
1653 break;
1654 }
1655 case kSecXPCOpBackupKeybagDelete: {
1656 // >>>
1657 if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementBackupTableOperations, &error)) {
1658 bool deleted = false;
1659 CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error);
1660 if (query) {
1661 CFTypeRef matchLimit = CFDictionaryGetValue(query, kSecMatchLimit);
1662 bool deleteAll = matchLimit && CFEqualSafe(matchLimit, kSecMatchLimitAll);
1663
1664 if (deleteAll && !EntitlementPresentAndTrue(operation, client.task, kSecEntitlementBackupTableOperationsDeleteAll, &error)) {
1665 // require special entitlement to delete all backup keybags
1666 } else {
1667 CFMutableDictionaryRef attributes = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, query);
1668 CFStringRef requestedAgrp = CFDictionaryGetValue(attributes, kSecAttrAccessGroup);
1669 CFStringRef resolvedAgrp = NULL;
1670 if (client.musr) {
1671 CFDictionarySetValue(attributes, kSecAttrMultiUser, client.musr);
1672 }
1673 if (extractAccessGroup(&client, requestedAgrp, &resolvedAgrp, &error)) {
1674 if (resolvedAgrp) {
1675 CFDictionarySetValue(attributes, kSecAttrAccessGroup, resolvedAgrp);
1676 }
1677 deleted = _SecServerBackupKeybagDelete(attributes, deleteAll, &error);
1678 }
1679 CFReleaseNull(resolvedAgrp);
1680 CFReleaseNull(attributes);
1681 }
1682 }
1683 xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, deleted);
1684 CFReleaseNull(query);
1685 }
1686 break;
1687 }
1688 default:
1689 break;
1690 }
1691
1692 if (error)
1693 {
1694 if(SecErrorGetOSStatus(error) == errSecItemNotFound || isSOSErrorCoded(error, kSOSErrorPublicKeyAbsent))
1695 secdebug("ipc", "%@ %@ %@", client.task, SOSCCGetOperationDescription((enum SecXPCOperation)operation), error);
1696 else if (SecErrorGetOSStatus(error) == errSecAuthNeeded)
1697 secwarning("Authentication is needed %@ %@ %@", client.task, SOSCCGetOperationDescription((enum SecXPCOperation)operation), error);
1698 else
1699 secerror("%@ %@ %@", client.task, SOSCCGetOperationDescription((enum SecXPCOperation)operation), error);
1700
1701 xpcError = SecCreateXPCObjectWithCFError(error);
1702 if (replyMessage) {
1703 xpc_dictionary_set_value(replyMessage, kSecXPCKeyError, xpcError);
1704 }
1705 } else if (replyMessage) {
1706 secdebug("ipc", "%@ %@ responding %@", client.task, SOSCCGetOperationDescription((enum SecXPCOperation)operation), replyMessage);
1707 }
1708 } else {
1709 SecCFCreateErrorWithFormat(kSecXPCErrorUnexpectedType, sSecXPCErrorDomain, NULL, &error, 0, CFSTR("Messages expect to be xpc dictionary, got: %@"), event);
1710 secerror("%@: returning error: %@", client.task, error);
1711 xpcError = SecCreateXPCObjectWithCFError(error);
1712 replyMessage = xpc_create_reply_with_format(event, "{%string: %value}", kSecXPCKeyError, xpcError);
1713 }
1714
1715 if (replyMessage) {
1716 xpc_connection_send_message(connection, replyMessage);
1717 xpc_release(replyMessage);
1718 }
1719 if (xpcError)
1720 xpc_release(xpcError);
1721 #if TARGET_OS_IPHONE
1722 pthread_setspecific(taskThreadKey, NULL);
1723 #endif
1724 CFReleaseSafe(error);
1725 CFReleaseSafe(client.accessGroups);
1726 CFReleaseSafe(client.musr);
1727 CFReleaseSafe(client.task);
1728 CFReleaseSafe(domains);
1729 CFReleaseSafe(clientAuditToken);
1730 }
1731
1732 static void securityd_xpc_init(const char *service_name)
1733 {
1734 #if TARGET_OS_IPHONE
1735 pthread_key_create(&taskThreadKey, NULL);
1736 SecTaskDiagnoseEntitlements = secTaskDiagnoseEntitlements;
1737 #endif
1738
1739 secdebug("serverxpc", "start");
1740 xpc_connection_t listener = xpc_connection_create_mach_service(service_name, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER);
1741 if (!listener) {
1742 seccritical("security failed to register xpc listener for %s, exiting", service_name);
1743 abort();
1744 }
1745
1746 xpc_connection_set_event_handler(listener, ^(xpc_object_t connection) {
1747 if (xpc_get_type(connection) == XPC_TYPE_CONNECTION) {
1748 xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
1749 if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) {
1750 xpc_retain(connection);
1751 xpc_retain(event);
1752 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
1753 securityd_xpc_dictionary_handler(connection, event);
1754 xpc_release(event);
1755 xpc_release(connection);
1756 });
1757 }
1758 });
1759 xpc_connection_resume(connection);
1760 }
1761 });
1762 xpc_connection_resume(listener);
1763
1764 #if OCTAGON
1765 xpc_activity_register("com.apple.securityd.daily", XPC_ACTIVITY_CHECK_IN, ^(xpc_activity_t activity) {
1766 xpc_activity_state_t activityState = xpc_activity_get_state(activity);
1767 if (activityState == XPC_ACTIVITY_STATE_RUN) {
1768 SecCKKS24hrNotification();
1769 }
1770 });
1771 #endif
1772 }
1773
1774
1775 // <rdar://problem/22425706> 13B104+Roots:Device never moved past spinner after using approval to ENABLE icdp
1776
1777 #if TARGET_OS_EMBEDDED
1778 static void securityd_soscc_lock_hack() {
1779 dispatch_queue_t soscc_lock_queue = dispatch_queue_create("soscc_lock_queue", DISPATCH_QUEUE_PRIORITY_DEFAULT);
1780 int soscc_tok;
1781
1782 // <rdar://problem/22500239> Prevent securityd from quitting while holding a keychain assertion
1783 // FIXME: securityd isn't currently registering for any other notifyd events. If/when it does,
1784 // this code will need to be generalized / migrated away from just this specific purpose.
1785 xpc_set_event_stream_handler("com.apple.notifyd.matching", dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(xpc_object_t object) {
1786 char *event_description = xpc_copy_description(object);
1787 secnotice("events", "%s", event_description);
1788 free(event_description);
1789 });
1790
1791 secnotice("lockassertion", "notify_register_dispatch(kSOSCCHoldLockForInitialSync)");
1792 notify_register_dispatch(kSOSCCHoldLockForInitialSync, &soscc_tok, soscc_lock_queue, ^(int token __unused) {
1793 secnotice("lockassertion", "kSOSCCHoldLockForInitialSync: grabbing the lock");
1794 CFErrorRef error = NULL;
1795
1796 uint64_t one_minute = 60ull;
1797 if(SecAKSLockUserKeybag(one_minute, &error)){
1798 // <rdar://problem/22500239> Prevent securityd from quitting while holding a keychain assertion
1799 xpc_transaction_begin();
1800
1801 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, one_minute*NSEC_PER_SEC), soscc_lock_queue, ^{
1802 CFErrorRef localError = NULL;
1803 if(!SecAKSUnLockUserKeybag(&localError))
1804 secerror("failed to unlock: %@", localError);
1805 CFReleaseNull(localError);
1806 xpc_transaction_end();
1807 });
1808 } else {
1809 secerror("Failed to take device lock assertion: %@", error);
1810 }
1811 CFReleaseNull(error);
1812 secnotice("lockassertion", "kSOSCCHoldLockForInitialSync => done");
1813 });
1814 }
1815 #endif
1816
1817 #if TARGET_OS_OSX
1818
1819 static char *
1820 homedirPath(void)
1821 {
1822 static char homeDir[PATH_MAX] = {};
1823
1824 if (homeDir[0] == '\0') {
1825 struct passwd* pwd = getpwuid(getuid());
1826 if (pwd == NULL)
1827 return NULL;
1828
1829 if (realpath(pwd->pw_dir, homeDir) == NULL) {
1830 strlcpy(homeDir, pwd->pw_dir, sizeof(homeDir));
1831 }
1832 }
1833 return homeDir;
1834 }
1835 #endif
1836
1837
1838 int main(int argc, char *argv[])
1839 {
1840 char *wait4debugger = getenv("WAIT4DEBUGGER");
1841 if (wait4debugger && !strcasecmp("YES", wait4debugger)) {
1842 seccritical("SIGSTOPing self, awaiting debugger");
1843 kill(getpid(), SIGSTOP);
1844 seccritical("Again, for good luck (or bad debuggers)");
1845 kill(getpid(), SIGSTOP);
1846 }
1847
1848 /* <rdar://problem/15792007> Users with network home folders are unable to use/save password for Mail/Cal/Contacts/websites
1849 Secd doesn't realize DB connections get invalidated when network home directory users logout
1850 and their home gets unmounted. Exit secd, start fresh when user logs back in.
1851 */
1852 #if TARGET_OS_OSX
1853 int sessionstatechanged_tok;
1854 notify_register_dispatch(kSA_SessionStateChangedNotification, &sessionstatechanged_tok, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(int token __unused) {
1855 // we could be a process running as root.
1856 // However, since root never logs out this isn't an issue.
1857 if (SASSessionStateForUser(getuid()) == kSA_state_loggingout_pointofnoreturn) {
1858 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
1859 xpc_transaction_exit_clean();
1860 });
1861 }
1862 });
1863 #endif
1864
1865 #if TARGET_OS_OSX
1866 #define SECD_PROFILE_NAME "com.apple.secd"
1867 const char *homedir = homedirPath();
1868 if (homedir == NULL)
1869 errx(1, "failed to get home directory for secd");
1870
1871 char *errorbuf = NULL;
1872 const char *sandbox_params[] = {
1873 "_HOME", homedir,
1874 NULL
1875 };
1876 int32_t rc;
1877
1878 rc = sandbox_init_with_parameters(SECD_PROFILE_NAME, SANDBOX_NAMED, sandbox_params, &errorbuf);
1879 if (rc)
1880 err(1, "Failed to process in a sandbox: %d %s", rc, errorbuf);
1881 #endif /* TARGET_OS_OSX */
1882
1883 const char *serviceName = kSecuritydXPCServiceName;
1884 /* setup SQDLite before some other component have a chance to create a database connection */
1885 _SecDbServerSetup();
1886
1887 securityd_init_server();
1888 securityd_xpc_init(serviceName);
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: */