]> git.saurik.com Git - apple/security.git/blob - OSX/sec/ProjectHeaders/Security/SecureObjectSync/SOSCloudCircle.c
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / sec / ProjectHeaders / Security / SecureObjectSync / SOSCloudCircle.c
1 /*
2 * Copyright (c) 2012-2014 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 //
25 // SOSCloudCircle.m
26 //
27
28 #include <stdio.h>
29 #include <AssertMacros.h>
30 #include <Security/SecureObjectSync/SOSCloudCircle.h>
31 #include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
32 #include <Security/SecureObjectSync/SOSCircle.h>
33 #include <Security/SecureObjectSync/SOSAccount.h>
34 #include <Security/SecureObjectSync/SOSAccountPriv.h>
35 #include <Security/SecureObjectSync/SOSFullPeerInfo.h>
36 #include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
37 #include <Security/SecureObjectSync/SOSInternal.h>
38 #include <Security/SecureObjectSync/SOSRing.h>
39 #include <Security/SecureObjectSync/SOSBackupSliceKeyBag.h>
40
41 #include <Security/SecKeyPriv.h>
42 #include <Security/SecFramework.h>
43 #include <CoreFoundation/CFXPCBridge.h>
44
45 #include <securityd/SecItemServer.h>
46
47 #include <utilities/SecDispatchRelease.h>
48 #include <utilities/SecCFRelease.h>
49 #include <utilities/SecCFWrappers.h>
50 #include <utilities/SecXPCError.h>
51
52 #include <utilities/debugging.h>
53
54 #include <CoreFoundation/CoreFoundation.h>
55
56 #include <xpc/xpc.h>
57 #define MINIMIZE_INCLUDES MINIMIZE_INCLUDES
58 #include <ipc/securityd_client.h>
59 #include <securityd/spi.h>
60
61 #include "SOSRegressionUtilities.h"
62 #include <Security/SecuritydXPC.h>
63 #include <SOSPeerInfoDER.h>
64 #include <SOSCloudKeychainClient.h>
65
66 const char * kSOSCCCircleChangedNotification = "com.apple.security.secureobjectsync.circlechanged";
67 const char * kSOSCCViewMembershipChangedNotification = "com.apple.security.secureobjectsync.viewschanged";
68 const char * kSOSCCInitialSyncChangedNotification = "com.apple.security.secureobjectsync.initialsyncchanged";
69
70 #define do_if_registered(sdp, ...) if (gSecurityd && gSecurityd->sdp) { return gSecurityd->sdp(__VA_ARGS__); }
71
72 static bool xpc_dictionary_entry_is_type(xpc_object_t dictionary, const char *key, xpc_type_t type)
73 {
74 xpc_object_t value = xpc_dictionary_get_value(dictionary, key);
75
76 return value && (xpc_get_type(value) == type);
77 }
78
79 SOSCCStatus SOSCCThisDeviceIsInCircle(CFErrorRef *error)
80 {
81 sec_trace_enter_api(NULL);
82 sec_trace_return_api(SOSCCStatus, ^{
83 SOSCCStatus result = kSOSCCError;
84
85 do_if_registered(soscc_ThisDeviceIsInCircle, error);
86
87 xpc_object_t message = securityd_create_message(kSecXPCOpDeviceInCircle, error);
88 if (message) {
89 xpc_object_t response = securityd_message_with_reply_sync(message, error);
90
91 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
92 result = (SOSCCStatus) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
93 } else {
94 result = kSOSCCError;
95 }
96
97 if (result < 0) {
98 if (response && securityd_message_no_error(response, error))
99 {
100 char *desc = xpc_copy_description(response);
101 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc);
102 free((void *)desc);
103 }
104 }
105 if(response)
106 xpc_release(response);
107 if(message)
108 xpc_release(message);
109 }
110
111
112 return result;
113 }, CFSTR("SOSCCStatus=%d"))
114 }
115
116 static bool cfstring_to_error_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
117 {
118 __block bool result = false;
119
120 secdebug("sosops","enter - operation: %d", op);
121 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
122 xpc_object_t xString = _CFXPCCreateXPCObjectFromCFObject(string);
123 bool success = false;
124 if (xString){
125 xpc_dictionary_set_value(message, kSecXPCKeyString, xString);
126 success = true;
127 xpc_release(xString);
128 }
129 return success;
130 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
131 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
132 return result;
133 });
134 return result;
135 }
136
137 static SOSRingStatus cfstring_to_uint64_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
138 {
139 __block bool result = false;
140
141 secdebug("sosops","enter - operation: %d", op);
142 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
143 xpc_object_t xString = _CFXPCCreateXPCObjectFromCFObject(string);
144 bool success = false;
145 if (xString){
146 xpc_dictionary_set_value(message, kSecXPCKeyString, xString);
147 success = true;
148 xpc_release(xString);
149 }
150 return success;
151 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
152 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
153 return result;
154 });
155 return result;
156 }
157
158 static CFStringRef simple_cfstring_error_request(enum SecXPCOperation op, CFErrorRef* error)
159 {
160 __block CFStringRef result = NULL;
161
162 secdebug("sosops","enter - operation: %d", op);
163 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
164 const char *c_string = xpc_dictionary_get_string(response, kSecXPCKeyResult);
165
166 if (c_string) {
167 result = CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8*)c_string, strlen(c_string), kCFStringEncodingUTF8, false);
168 }
169
170 return c_string != NULL;
171 });
172 return result;
173 }
174
175 static bool simple_bool_error_request(enum SecXPCOperation op, CFErrorRef* error)
176 {
177 __block bool result = false;
178
179 secdebug("sosops","enter - operation: %d", op);
180 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
181 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
182 return result;
183 });
184 return result;
185 }
186
187 static CFArrayRef simple_array_error_request(enum SecXPCOperation op, CFErrorRef* error)
188 {
189 __block CFArrayRef result = NULL;
190
191 secdebug("sosops","enter - operation: %d", op);
192 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
193 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
194 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
195 return result != NULL;
196 })) {
197 if (!isArray(result)) {
198 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
199 CFReleaseNull(result);
200 }
201 }
202 return result;
203 }
204
205 static int simple_int_error_request(enum SecXPCOperation op, CFErrorRef* error)
206 {
207 __block int result = 0;
208
209 secdebug("sosops","enter - operation: %d", op);
210 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
211 int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
212 if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
213 result = (int)temp_result;
214 }
215 return result;
216 });
217 return result;
218 }
219
220 static SOSPeerInfoRef peer_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
221 {
222 SOSPeerInfoRef result = NULL;
223 __block CFDataRef data = NULL;
224
225 secdebug("sosops","enter - operation: %d", op);
226 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
227 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
228 if (response && (NULL != temp_result)) {
229 data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
230 }
231 return data != NULL;
232 });
233
234 if (!isData(data)) {
235 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
236 }
237
238 if (data) {
239 result = SOSPeerInfoCreateFromData(kCFAllocatorDefault, error, data);
240 }
241 CFReleaseNull(data);
242 return result;
243 }
244
245 static CFArrayRef array_of_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
246 {
247 __block CFArrayRef result = NULL;
248
249 secdebug("sosops","enter - operation: %d", op);
250 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
251 xpc_object_t encoded_array = xpc_dictionary_get_value(response, kSecXPCKeyResult);
252 if (response && (NULL != encoded_array)) {
253 result = CreateArrayOfPeerInfoWithXPCObject(encoded_array, error);
254 }
255 return result != NULL;
256 });
257
258 if (!isArray(result)) {
259 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
260 CFReleaseNull(result);
261 }
262 return result;
263 }
264
265 static SOSPeerInfoRef data_to_peer_info_error_request(enum SecXPCOperation op, CFDataRef secret, CFErrorRef* error)
266 {
267 __block SOSPeerInfoRef result = false;
268 __block CFDataRef data = NULL;
269
270 secdebug("sosops", "enter - operation: %d", op);
271 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
272 xpc_object_t xsecretData = _CFXPCCreateXPCObjectFromCFObject(secret);
273 bool success = false;
274 if (xsecretData){
275 xpc_dictionary_set_value(message, kSecXPCKeyNewPublicBackupKey, xsecretData);
276 success = true;
277 xpc_release(xsecretData);
278 }
279 return success;
280 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
281 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
282 if (response && (NULL != temp_result)) {
283 data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
284 }
285 return result != NULL;
286 });
287
288 if (!isData(data)) {
289 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
290 }
291
292 if (data) {
293 result = SOSPeerInfoCreateFromData(kCFAllocatorDefault, error, data);
294 }
295 CFReleaseNull(data);
296 return result;
297 }
298
299 static bool keybag_and_bool_to_bool_error_request(enum SecXPCOperation op, CFDataRef data, bool include, CFErrorRef* error)
300 {
301 secdebug("sosops", "enter - operation: %d", op);
302 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
303 xpc_object_t xData = _CFXPCCreateXPCObjectFromCFObject(data);
304 bool success = false;
305 if (xData){
306 xpc_dictionary_set_value(message, kSecXPCKeyKeybag, xData);
307 xpc_release(xData);
308 success = true;
309 }
310 xpc_dictionary_set_bool(message, kSecXPCKeyIncludeV0, include);
311 return success;
312 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
313 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
314 });
315 }
316
317
318 static bool info_array_to_bool_error_request(enum SecXPCOperation op, CFArrayRef peer_infos, CFErrorRef* error)
319 {
320 __block bool result = false;
321
322 secdebug("sosops", "enter - operation: %d", op);
323 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
324 xpc_object_t encoded_peers = CreateXPCObjectWithArrayOfPeerInfo(peer_infos, error);
325 if (encoded_peers)
326 xpc_dictionary_set_value(message, kSecXPCKeyPeerInfos, encoded_peers);
327 return encoded_peers != NULL;
328 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
329 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
330 return result;
331 });
332 return result;
333 }
334
335 static bool uint64_t_to_bool_error_request(enum SecXPCOperation op,
336 uint64_t number,
337 CFErrorRef* error)
338 {
339 __block bool result = false;
340
341 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
342 xpc_dictionary_set_uint64(message, kSecXPCLimitInMinutes, number);
343 return true;
344 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
345 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
346 return result;
347 });
348
349 return result;
350 }
351
352 static bool set_hsa2_autoaccept_error_request(enum SecXPCOperation op, CFDataRef pubKey, CFErrorRef *error)
353 {
354 __block bool result = false;
355
356 sec_trace_enter_api(NULL);
357 securityd_send_sync_and_do(op, error, ^(xpc_object_t message,
358 CFErrorRef *error) {
359 xpc_object_t xpubkey = _CFXPCCreateXPCObjectFromCFObject(pubKey);
360 bool success = false;
361 if (xpubkey) {
362 xpc_dictionary_set_value(message,
363 kSecXPCKeyHSA2AutoAcceptInfo, xpubkey);
364 success = true;
365 xpc_release(xpubkey);
366 }
367
368 return success;
369 }, ^(xpc_object_t response, __unused CFErrorRef *error) {
370 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
371 return (bool)true;
372 });
373
374 return result;
375 }
376
377 bool SOSCCRequestToJoinCircle(CFErrorRef* error)
378 {
379 sec_trace_enter_api(NULL);
380 sec_trace_return_bool_api(^{
381 do_if_registered(soscc_RequestToJoinCircle, error);
382
383 return simple_bool_error_request(kSecXPCOpRequestToJoin, error);
384 }, NULL)
385 }
386
387 bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error)
388 {
389 sec_trace_enter_api(NULL);
390 sec_trace_return_bool_api(^{
391 do_if_registered(soscc_RequestToJoinCircleAfterRestore, error);
392
393 return simple_bool_error_request(kSecXPCOpRequestToJoinAfterRestore, error);
394 }, NULL)
395 }
396
397
398 bool SOSCCWaitForInitialSync(CFErrorRef* error)
399 {
400 sec_trace_enter_api(NULL);
401 sec_trace_return_bool_api(^{
402 do_if_registered(soscc_WaitForInitialSync, error);
403
404 return simple_bool_error_request(kSecXPCOpWaitForInitialSync, error);
405 }, NULL)
406 }
407
408 CFArrayRef SOSCCCopyYetToSyncViewsList(CFErrorRef* error)
409 {
410 sec_trace_enter_api(NULL);
411 sec_trace_return_api(CFArrayRef, ^{
412 do_if_registered(soscc_CopyYetToSyncViewsList, error);
413
414 return simple_array_error_request(kSecXPCOpCopyYetToSyncViews, error);
415 }, NULL)
416 }
417
418 bool SOSCCRequestEnsureFreshParameters(CFErrorRef* error)
419 {
420 sec_trace_enter_api(NULL);
421 sec_trace_return_bool_api(^{
422 do_if_registered(soscc_RequestEnsureFreshParameters, error);
423
424 return simple_bool_error_request(kSecXPCOpRequestEnsureFreshParameters, error);
425 }, NULL)
426 }
427
428 CFStringRef SOSCCGetAllTheRings(CFErrorRef *error){
429 sec_trace_enter_api(NULL);
430 sec_trace_return_api(CFStringRef, ^{
431 do_if_registered(soscc_GetAllTheRings, error);
432
433
434 return simple_cfstring_error_request(kSecXPCOpGetAllTheRings, error);
435 }, NULL)
436 }
437 bool SOSCCApplyToARing(CFStringRef ringName, CFErrorRef* error)
438 {
439 sec_trace_enter_api(NULL);
440 sec_trace_return_bool_api(^{
441 do_if_registered(soscc_ApplyToARing, ringName, error);
442
443 return cfstring_to_error_request(kSecXPCOpApplyToARing, ringName, error);
444 }, NULL)
445 }
446
447 bool SOSCCWithdrawlFromARing(CFStringRef ringName, CFErrorRef* error)
448 {
449 sec_trace_enter_api(NULL);
450 sec_trace_return_bool_api(^{
451 do_if_registered(soscc_WithdrawlFromARing, ringName, error);
452
453 return cfstring_to_error_request(kSecXPCOpWithdrawlFromARing, ringName, error);
454 }, NULL)
455 }
456
457 SOSRingStatus SOSCCRingStatus(CFStringRef ringName, CFErrorRef* error)
458 {
459 sec_trace_enter_api(NULL);
460 sec_trace_return_api(SOSRingStatus, ^{
461 do_if_registered(soscc_RingStatus, ringName, error);
462
463 return cfstring_to_uint64_request(kSecXPCOpRingStatus, ringName, error);
464 }, CFSTR("SOSCCStatus=%d"))
465 }
466
467 bool SOSCCEnableRing(CFStringRef ringName, CFErrorRef* error)
468 {
469 sec_trace_enter_api(NULL);
470 sec_trace_return_bool_api(^{
471 do_if_registered(soscc_EnableRing, ringName, error);
472
473 return cfstring_to_error_request(kSecXPCOpEnableRing, ringName, error);
474 }, NULL)
475 }
476
477 bool SOSCCAccountSetToNew(CFErrorRef *error)
478 {
479 secwarning("SOSCCAccountSetToNew called");
480 sec_trace_enter_api(NULL);
481 sec_trace_return_bool_api(^{
482 do_if_registered(soscc_SetToNew, error);
483 return simple_bool_error_request(kSecXPCOpAccountSetToNew, error);
484 }, NULL)
485 }
486
487 bool SOSCCResetToOffering(CFErrorRef* error)
488 {
489 secwarning("SOSCCResetToOffering called");
490 sec_trace_enter_api(NULL);
491 sec_trace_return_bool_api(^{
492 do_if_registered(soscc_ResetToOffering, error);
493
494 return simple_bool_error_request(kSecXPCOpResetToOffering, error);
495 }, NULL)
496 }
497
498 bool SOSCCResetToEmpty(CFErrorRef* error)
499 {
500 secwarning("SOSCCResetToEmpty called");
501 sec_trace_enter_api(NULL);
502 sec_trace_return_bool_api(^{
503 do_if_registered(soscc_ResetToEmpty, error);
504
505 return simple_bool_error_request(kSecXPCOpResetToEmpty, error);
506 }, NULL)
507 }
508
509 bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error)
510 {
511 sec_trace_enter_api(NULL);
512 sec_trace_return_bool_api(^{
513 do_if_registered(soscc_RemoveThisDeviceFromCircle, error);
514
515 return simple_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircle, error);
516 }, NULL)
517 }
518
519 bool SOSCCLoggedOutOfAccount(CFErrorRef* error)
520 {
521 sec_trace_enter_api(NULL);
522 sec_trace_return_bool_api(^{
523 do_if_registered(soscc_LoggedOutOfAccount, error);
524
525 return simple_bool_error_request(kSecXPCOpLoggedOutOfAccount, error);
526 }, NULL)
527 }
528
529 bool SOSCCBailFromCircle_BestEffort(uint64_t limit_in_seconds, CFErrorRef* error)
530 {
531 sec_trace_enter_api(NULL);
532 sec_trace_return_bool_api(^{
533 do_if_registered(soscc_BailFromCircle, limit_in_seconds, error);
534
535 return uint64_t_to_bool_error_request(kSecXPCOpBailFromCircle, limit_in_seconds, error);
536 }, NULL)
537 }
538
539 bool SOSCCSignedOut(bool immediate, CFErrorRef* error)
540 {
541 uint64_t limit = strtoul(optarg, NULL, 10);
542
543 if(immediate)
544 return SOSCCRemoveThisDeviceFromCircle(error);
545 else
546 return SOSCCBailFromCircle_BestEffort(limit, error);
547
548 }
549
550 CFArrayRef SOSCCCopyPeerPeerInfo(CFErrorRef* error)
551 {
552 sec_trace_enter_api(NULL);
553 sec_trace_return_api(CFArrayRef, ^{
554 do_if_registered(soscc_CopyPeerInfo, error);
555
556 return array_of_info_error_request(kSecXPCOpCopyPeerPeerInfo, error);
557 }, CFSTR("return=%@"));
558 }
559
560 bool SOSCCSetAutoAcceptInfo(CFDataRef autoaccept, CFErrorRef *error)
561 {
562 sec_trace_return_bool_api(^{
563 do_if_registered(soscc_SetHSA2AutoAcceptInfo, autoaccept, error);
564
565 return set_hsa2_autoaccept_error_request(kSecXPCOpSetHSA2AutoAcceptInfo, autoaccept, error);
566 }, NULL)
567 }
568
569 CFArrayRef SOSCCCopyConcurringPeerPeerInfo(CFErrorRef* error)
570 {
571 sec_trace_enter_api(NULL);
572 sec_trace_return_api(CFArrayRef, ^{
573 do_if_registered(soscc_CopyConcurringPeerInfo, error);
574
575 return array_of_info_error_request(kSecXPCOpCopyConcurringPeerPeerInfo, error);
576 }, CFSTR("return=%@"));
577 }
578
579 CFArrayRef SOSCCCopyGenerationPeerInfo(CFErrorRef* error)
580 {
581 sec_trace_enter_api(NULL);
582 sec_trace_return_api(CFArrayRef, ^{
583 do_if_registered(soscc_CopyGenerationPeerInfo, error);
584
585 return simple_array_error_request(kSecXPCOpCopyGenerationPeerInfo, error);
586 }, CFSTR("return=%@"));
587 }
588
589 CFArrayRef SOSCCCopyApplicantPeerInfo(CFErrorRef* error)
590 {
591 sec_trace_enter_api(NULL);
592 sec_trace_return_api(CFArrayRef, ^{
593 do_if_registered(soscc_CopyApplicantPeerInfo, error);
594
595 return array_of_info_error_request(kSecXPCOpCopyApplicantPeerInfo, error);
596 }, CFSTR("return=%@"));
597 }
598
599 bool SOSCCValidateUserPublic(CFErrorRef* error){
600 sec_trace_enter_api(NULL);
601 sec_trace_return_api(bool, ^{
602 do_if_registered(soscc_ValidateUserPublic, error);
603
604 return simple_bool_error_request(kSecXPCOpValidateUserPublic, error);
605 }, NULL);
606 }
607
608 CFArrayRef SOSCCCopyValidPeerPeerInfo(CFErrorRef* error)
609 {
610 sec_trace_enter_api(NULL);
611 sec_trace_return_api(CFArrayRef, ^{
612 do_if_registered(soscc_CopyValidPeerPeerInfo, error);
613
614 return array_of_info_error_request(kSecXPCOpCopyValidPeerPeerInfo, error);
615 }, CFSTR("return=%@"));
616 }
617
618 CFArrayRef SOSCCCopyNotValidPeerPeerInfo(CFErrorRef* error)
619 {
620 sec_trace_enter_api(NULL);
621 sec_trace_return_api(CFArrayRef, ^{
622 do_if_registered(soscc_CopyNotValidPeerPeerInfo, error);
623
624 return array_of_info_error_request(kSecXPCOpCopyNotValidPeerPeerInfo, error);
625 }, CFSTR("return=%@"));
626 }
627
628 CFArrayRef SOSCCCopyRetirementPeerInfo(CFErrorRef* error)
629 {
630 sec_trace_enter_api(NULL);
631 sec_trace_return_api(CFArrayRef, ^{
632 do_if_registered(soscc_CopyRetirementPeerInfo, error);
633
634 return array_of_info_error_request(kSecXPCOpCopyRetirementPeerInfo, error);
635 }, CFSTR("return=%@"));
636 }
637
638 SOSPeerInfoRef SOSCCCopyMyPeerInfo(CFErrorRef *error)
639 {
640 sec_trace_enter_api(NULL);
641 sec_trace_return_api(SOSPeerInfoRef, ^{
642 do_if_registered(soscc_CopyMyPeerInfo, error);
643
644 return peer_info_error_request(kSecXPCOpCopyMyPeerInfo, error);
645 }, CFSTR("return=%@"));
646 }
647
648 CFArrayRef SOSCCCopyEngineState(CFErrorRef* error)
649 {
650 sec_trace_enter_api(NULL);
651 sec_trace_return_api(CFArrayRef, ^{
652 do_if_registered(soscc_CopyEngineState, error);
653
654 return simple_array_error_request(kSecXPCOpCopyEngineState, error);
655 }, CFSTR("return=%@"));
656 }
657
658 bool SOSCCAcceptApplicants(CFArrayRef applicants, CFErrorRef* error)
659 {
660 sec_trace_enter_api(NULL);
661 sec_trace_return_bool_api(^{
662 do_if_registered(soscc_AcceptApplicants, applicants, error);
663
664 return info_array_to_bool_error_request(kSecXPCOpAcceptApplicants, applicants, error);
665 }, NULL)
666 }
667
668 bool SOSCCRejectApplicants(CFArrayRef applicants, CFErrorRef *error)
669 {
670 sec_trace_enter_api(CFSTR("applicants=%@"), applicants);
671 sec_trace_return_bool_api(^{
672 do_if_registered(soscc_RejectApplicants, applicants, error);
673
674 return info_array_to_bool_error_request(kSecXPCOpRejectApplicants, applicants, error);
675 }, NULL)
676 }
677
678 static SOSPeerInfoRef SOSSetNewPublicBackupKey(CFDataRef pubKey, CFErrorRef *error)
679 {
680 sec_trace_enter_api(NULL);
681 sec_trace_return_api(SOSPeerInfoRef, ^{
682 do_if_registered(soscc_SetNewPublicBackupKey, pubKey, error);
683
684 return data_to_peer_info_error_request(kSecXPCOpSetNewPublicBackupKey, pubKey, error);
685 }, CFSTR("return=%@"));
686 }
687
688 SOSPeerInfoRef SOSCCCopyMyPeerWithNewDeviceRecoverySecret(CFDataRef secret, CFErrorRef *error){
689 CFDataRef publicKeyData = SOSCopyDeviceBackupPublicKey(secret, error);
690
691 return SOSSetNewPublicBackupKey(publicKeyData, error);
692 }
693
694 bool SOSCCRegisterSingleRecoverySecret(CFDataRef aks_bag, bool includeV0Backups, CFErrorRef *error){
695 sec_trace_enter_api(NULL);
696 sec_trace_return_bool_api(^{
697 do_if_registered(soscc_RegisterSingleRecoverySecret, aks_bag, includeV0Backups, error);
698 return keybag_and_bool_to_bool_error_request(kSecXPCOpSetBagForAllSlices, aks_bag, includeV0Backups, error);
699 }, NULL);
700 }
701
702
703 static bool label_and_password_to_bool_error_request(enum SecXPCOperation op,
704 CFStringRef user_label, CFDataRef user_password,
705 CFErrorRef* error)
706 {
707 __block bool result = false;
708
709 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
710 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
711 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
712 });
713 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
714 return true;
715 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
716 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
717 return result;
718 });
719
720 return result;
721 }
722
723 static bool label_and_password_and_dsid_to_bool_error_request(enum SecXPCOperation op,
724 CFStringRef user_label, CFDataRef user_password,
725 CFStringRef dsid, CFErrorRef* error)
726 {
727 __block bool result = false;
728
729 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
730 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
731 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
732 });
733 CFStringPerformWithCString(dsid, ^(const char *utr8StrDSID) {
734 xpc_dictionary_set_string(message, kSecXPCKeyDSID, utr8StrDSID);
735 });
736 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
737 return true;
738 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
739 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
740 return result;
741 });
742
743 return result;
744 }
745
746 static bool deviceid_to_bool_error_request(enum SecXPCOperation op,
747 CFStringRef IDS,
748 CFErrorRef* error)
749 {
750 __block bool result = false;
751
752 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
753 CFStringPerformWithCString(IDS, ^(const char *utf8Str) {
754 xpc_dictionary_set_string(message, kSecXPCKeyDeviceID, utf8Str);
755 });
756 return true;
757 }, ^bool(xpc_object_t response, CFErrorRef *error) {
758 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
759 if(result == false){
760 xpc_object_t xpc_error = xpc_dictionary_get_value(response, kSecXPCKeyError);
761 if (xpc_error && error) {
762 *error = SecCreateCFErrorWithXPCObject(xpc_error);
763 }
764 }
765 return result;
766 });
767
768 return result;
769 }
770
771 static int idsDict_to_bool_error_request(enum SecXPCOperation op,
772 CFDictionaryRef IDS,
773 CFErrorRef* error)
774 {
775 __block int result = false;
776
777 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
778 SecXPCDictionarySetPListOptional(message, kSecXPCKeyIDSMessage, IDS, error);
779 return true;
780 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
781 int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
782 if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
783 result = (int)temp_result;
784 }
785 return result;
786 });
787
788 return result;
789 }
790
791 static bool idscommand_to_bool_error_request(enum SecXPCOperation op,
792 CFStringRef idsMessage,
793 CFErrorRef* error)
794 {
795 __block bool result = false;
796
797 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
798 CFStringPerformWithCString(idsMessage, ^(const char *utf8Str) {
799 xpc_dictionary_set_string(message, kSecXPCKeySendIDSMessage, utf8Str);
800 });
801 return true;
802 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
803 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
804 return result;
805 });
806
807 return result;
808 }
809
810 bool SOSCCRegisterUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
811 {
812 secnotice("sosops", "SOSCCRegisterUserCredentials - calling SOSCCSetUserCredentials!! %@\n", user_label);
813 return SOSCCSetUserCredentials(user_label, user_password, error);
814 }
815
816 bool SOSCCSetUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
817 {
818 secnotice("sosops", "SOSCCSetUserCredentials!! %@\n", user_label);
819 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
820 sec_trace_return_bool_api(^{
821 do_if_registered(soscc_SetUserCredentials, user_label, user_password, error);
822
823 return label_and_password_to_bool_error_request(kSecXPCOpSetUserCredentials, user_label, user_password, error);
824 }, NULL)
825 }
826
827 bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error)
828 {
829 secnotice("sosops", "SOSCCSetUserCredentialsAndDSID!! %@\n", user_label);
830 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
831 sec_trace_return_bool_api(^{
832 do_if_registered(soscc_SetUserCredentialsAndDSID, user_label, user_password, dsid, error);
833 if(dsid == NULL){
834 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, CFSTR(""), error);
835 }
836 else{
837 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, dsid, error);
838 }
839 }, NULL)
840
841 }
842 bool SOSCCSetDeviceID(CFStringRef IDS, CFErrorRef* error)
843 {
844 secnotice("sosops", "SOSCCSetDeviceID!! %@\n", IDS);
845 sec_trace_enter_api(NULL);
846 sec_trace_return_bool_api(^{
847 CFErrorRef localError = NULL;
848 do_if_registered(soscc_SetDeviceID, IDS, &localError);
849 bool result = deviceid_to_bool_error_request(kSecXPCOpSetDeviceID, IDS, &localError);
850 if(localError){
851 *error = CFRetainSafe(localError);
852 }
853 return result;
854 }, NULL)
855 }
856
857 bool SOSCCIDSServiceRegistrationTest(CFStringRef message, CFErrorRef *error)
858 {
859 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message);
860 sec_trace_enter_api(NULL);
861 sec_trace_return_bool_api(^{
862 do_if_registered(soscc_CheckIDSRegistration, message, error);
863 return idscommand_to_bool_error_request(kSecXPCOpSendIDSMessage, message, error);
864 }, NULL)
865 }
866
867 bool SOSCCIDSPingTest(CFStringRef message, CFErrorRef *error)
868 {
869 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message);
870 sec_trace_enter_api(NULL);
871 sec_trace_return_bool_api(^{
872 do_if_registered(soscc_PingTest, message, error);
873 return idscommand_to_bool_error_request(kSecXPCOpPingTest, message, error);
874 }, NULL)
875 }
876
877 bool SOSCCIDSDeviceIDIsAvailableTest(CFErrorRef *error)
878 {
879 secnotice("sosops", "SOSCCIDSDeviceIDIsAvailableTest!!\n");
880 sec_trace_enter_api(NULL);
881 sec_trace_return_bool_api(^{
882 do_if_registered(soscc_GetIDSIDFromIDS, error);
883 return simple_bool_error_request(kSecXPCOpIDSDeviceID, error);
884 }, NULL)
885 }
886
887 HandleIDSMessageReason SOSCCHandleIDSMessage(CFDictionaryRef IDS, CFErrorRef* error)
888 {
889 secnotice("sosops", "SOSCCHandleIDSMessage!! %@\n", IDS);
890 sec_trace_enter_api(NULL);
891 sec_trace_return_api(HandleIDSMessageReason, ^{
892 do_if_registered(soscc_HandleIDSMessage, IDS, error);
893 return (HandleIDSMessageReason) idsDict_to_bool_error_request(kSecXPCOpHandleIDSMessage, IDS, error);
894 }, NULL)
895 }
896
897 bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
898 {
899 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
900 sec_trace_return_bool_api(^{
901 do_if_registered(soscc_TryUserCredentials, user_label, user_password, error);
902
903 return label_and_password_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, error);
904 }, NULL)
905 }
906
907
908 bool SOSCCCanAuthenticate(CFErrorRef* error) {
909 sec_trace_enter_api(NULL);
910 sec_trace_return_bool_api(^{
911 do_if_registered(soscc_CanAuthenticate, error);
912
913 return simple_bool_error_request(kSecXPCOpCanAuthenticate, error);
914 }, NULL)
915 }
916
917 bool SOSCCPurgeUserCredentials(CFErrorRef* error) {
918 sec_trace_enter_api(NULL);
919 sec_trace_return_bool_api(^{
920 do_if_registered(soscc_PurgeUserCredentials, error);
921
922 return simple_bool_error_request(kSecXPCOpPurgeUserCredentials, error);
923 }, NULL)
924 }
925
926 enum DepartureReason SOSCCGetLastDepartureReason(CFErrorRef *error) {
927 sec_trace_enter_api(NULL);
928 sec_trace_return_api(enum DepartureReason, ^{
929 do_if_registered(soscc_GetLastDepartureReason, error);
930
931 return (enum DepartureReason) simple_int_error_request(kSecXPCOpGetLastDepartureReason, error);
932 }, NULL)
933 }
934
935 bool SOSCCSetLastDepartureReason(enum DepartureReason reason, CFErrorRef *error) {
936 sec_trace_enter_api(NULL);
937 sec_trace_return_api(bool, ^{
938 do_if_registered(soscc_SetLastDepartureReason, reason, error);
939 return securityd_send_sync_and_do(kSecXPCOpSetLastDepartureReason, error,
940 ^bool(xpc_object_t message, CFErrorRef *error) {
941 xpc_dictionary_set_int64(message, kSecXPCKeyReason, reason);
942 return true;
943 },
944 ^bool(xpc_object_t response, __unused CFErrorRef *error) {
945 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
946 }
947 );
948 }, NULL)
949 }
950
951 CFStringRef SOSCCCopyIncompatibilityInfo(CFErrorRef* error) {
952 sec_trace_enter_api(NULL);
953 sec_trace_return_api(CFStringRef, ^{
954 do_if_registered(soscc_CopyIncompatibilityInfo, error);
955
956 return simple_cfstring_error_request(kSecXPCOpCopyIncompatibilityInfo, error);
957 }, NULL)
958 }
959
960 CFStringRef SOSCCRequestDeviceID(CFErrorRef* error)
961 {
962 sec_trace_enter_api(NULL);
963 sec_trace_return_api(CFStringRef, ^{
964 do_if_registered(soscc_RequestDeviceID, error);
965 CFStringRef deviceID = simple_cfstring_error_request(kSecXPCOpRequestDeviceID, error);
966 return deviceID;
967 }, NULL)
968 }
969
970 bool SOSCCProcessEnsurePeerRegistration(CFErrorRef* error){
971 secnotice("updates", "enter SOSCCProcessEnsurePeerRegistration");
972 sec_trace_enter_api(NULL);
973 sec_trace_return_bool_api(^{
974 do_if_registered(soscc_EnsurePeerRegistration, error);
975
976 return simple_bool_error_request(soscc_EnsurePeerRegistration_id, error);
977 }, NULL)
978 }
979
980
981 SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers(CFErrorRef* error)
982 {
983 sec_trace_enter_api(NULL);
984 sec_trace_return_api(SyncWithAllPeersReason, ^{
985 do_if_registered(soscc_ProcessSyncWithAllPeers, error);
986
987 return (SyncWithAllPeersReason) simple_int_error_request(kSecXPCOpProcessSyncWithAllPeers, error);
988 }, NULL)
989 }
990
991 CFStringRef SOSCCGetStatusDescription(SOSCCStatus status)
992 {
993 switch (status) {
994 case kSOSCCInCircle:
995 return CFSTR("InCircle");
996 case kSOSCCNotInCircle:
997 return CFSTR("NotInCircle");
998 case kSOSCCRequestPending:
999 return CFSTR("RequestPending");
1000 case kSOSCCCircleAbsent:
1001 return CFSTR("CircleAbsent");
1002 case kSOSCCError:
1003 return CFSTR("InternalError");
1004 default:
1005 return CFSTR("Unknown Status (%d)");
1006 };
1007 }
1008
1009 #if 0
1010 kSOSCCGeneralViewError = -1,
1011 kSOSCCViewMember = 0,
1012 kSOSCCViewNotMember = 1,
1013 kSOSCCViewNotQualified = 2,
1014 kSOSCCNoSuchView = 3,
1015 #endif
1016
1017 static int64_t name_action_to_code_request(enum SecXPCOperation op, uint16_t error_result,
1018 CFStringRef name, uint64_t action, CFErrorRef *error) {
1019 __block int64_t result = error_result;
1020
1021 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1022 CFStringPerformWithCString(name, ^(const char *utf8Str) {
1023 xpc_dictionary_set_string(message, kSecXPCKeyViewName, utf8Str);
1024 });
1025 xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, action);
1026 return true;
1027 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1028 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
1029 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1030 }
1031 return result != error_result;
1032 });
1033
1034 return result;
1035 }
1036
1037 SOSViewResultCode SOSCCView(CFStringRef view, SOSViewActionCode actionCode, CFErrorRef *error) {
1038 sec_trace_enter_api(NULL);
1039 sec_trace_return_api(SOSViewResultCode, ^{
1040 do_if_registered(soscc_View, view, actionCode, error);
1041
1042 return (SOSViewResultCode) name_action_to_code_request(kSecXPCOpView, kSOSCCGeneralViewError, view, actionCode, error);
1043 }, CFSTR("SOSViewResultCode=%d"))
1044 }
1045
1046
1047 bool SOSCCViewSet(CFSetRef enabledViews, CFSetRef disabledViews) {
1048 CFErrorRef *error = NULL;
1049 __block bool result = false;
1050
1051 sec_trace_enter_api(NULL);
1052 sec_trace_return_bool_api(^{
1053 do_if_registered(soscc_ViewSet, enabledViews, disabledViews);
1054 return securityd_send_sync_and_do(kSecXPCOpViewSet, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1055 xpc_object_t enabledSetXpc = CreateXPCObjectWithCFSetRef(enabledViews, error);
1056 xpc_object_t disabledSetXpc = CreateXPCObjectWithCFSetRef(disabledViews, error);
1057 if (enabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyEnabledViewsKey, enabledSetXpc);
1058 if (disabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyDisabledViewsKey, disabledSetXpc);
1059 return (enabledSetXpc != NULL) || (disabledSetXpc != NULL) ;
1060 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1061 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1062 return result;
1063 });
1064 }, NULL)
1065 }
1066
1067 SOSSecurityPropertyResultCode SOSCCSecurityProperty(CFStringRef property, SOSSecurityPropertyActionCode actionCode, CFErrorRef *error) {
1068 sec_trace_enter_api(NULL);
1069 sec_trace_return_api(SOSSecurityPropertyResultCode, ^{
1070 SOSSecurityPropertyResultCode result = kSOSCCGeneralSecurityPropertyError;
1071 do_if_registered(soscc_SecurityProperty, property, actionCode, error);
1072 xpc_object_t message = securityd_create_message(kSecXPCOpSecurityProperty, error);
1073 if (message) {
1074 int64_t bigac = actionCode;
1075 xpc_dictionary_set_string(message, kSecXPCKeyViewName, CFStringGetCStringPtr(property, kCFStringEncodingUTF8));
1076 xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, bigac);
1077
1078 xpc_object_t response = securityd_message_with_reply_sync(message, error);
1079
1080 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
1081 result = (SOSSecurityPropertyResultCode) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1082 }
1083
1084 if (result == kSOSCCGeneralSecurityPropertyError) {
1085 if (response && securityd_message_no_error(response, error)) {
1086 char *desc = xpc_copy_description(response);
1087 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc);
1088 free((void *)desc);
1089 }
1090 }
1091 if(response)
1092 xpc_release(response);
1093 if(message)
1094 xpc_release(message);
1095 }
1096
1097 return result;
1098 }, CFSTR("SOSSecurityPropertyResultCode=%d"))
1099 }
1100
1101
1102 static bool sosIsViewSetSyncing(size_t n, CFStringRef *views) {
1103 __block bool retval = true;
1104
1105 SOSCCStatus cstatus = SOSCCThisDeviceIsInCircle(NULL);
1106 if(cstatus == kSOSCCInCircle) {
1107 for(size_t i = 0; i < n; i++) {
1108 SOSViewResultCode vstatus = SOSCCView(views[i], kSOSCCViewQuery, NULL);
1109 if(vstatus != kSOSCCViewMember) retval = false;
1110 }
1111 } else {
1112 retval = false;
1113 }
1114 return retval;
1115 }
1116
1117 bool SOSCCIsIcloudKeychainSyncing(void) {
1118 CFStringRef views[] = { kSOSViewKeychainV0 };
1119 return sosIsViewSetSyncing(1, views);
1120 }
1121
1122 bool SOSCCIsSafariSyncing(void) {
1123 CFStringRef views[] = { kSOSViewAutofillPasswords, kSOSViewSafariCreditCards };
1124 return sosIsViewSetSyncing(2, views);
1125 }
1126
1127 bool SOSCCIsAppleTVSyncing(void) {
1128 CFStringRef views[] = { kSOSViewAppleTV };
1129 return sosIsViewSetSyncing(1, views);
1130 }
1131
1132 bool SOSCCIsHomeKitSyncing(void) {
1133 CFStringRef views[] = { kSOSViewHomeKit };
1134 return sosIsViewSetSyncing(1, views);
1135 }
1136
1137 bool SOSCCIsWiFiSyncing(void) {
1138 CFStringRef views[] = { kSOSViewWiFi };
1139 return sosIsViewSetSyncing(1, views);
1140 }