2 * Copyright (c) 2013-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 #include "SOSAccountPriv.h"
25 #include "SOSAccount.h"
26 #include "keychain/SecureObjectSync/SOSPeerInfoCollections.h"
27 #include "keychain/SecureObjectSync/SOSTransportMessage.h"
28 #include "keychain/SecureObjectSync/SOSPeerInfoV2.h"
29 #import "keychain/SecureObjectSync/SOSAccountTrust.h"
30 #include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h"
32 bool SOSAccountIsMyPeerActive(SOSAccount* account, CFErrorRef* error) {
33 SOSFullPeerInfoRef identity = NULL;
34 SOSCircleRef circle = NULL;
36 SOSAccountTrustClassic *trust = account.trust;
37 identity = trust.fullPeerInfo;
38 circle = trust.trustedCircle;
40 SOSPeerInfoRef me = SOSFullPeerInfoGetPeerInfo(identity);
41 return me ? SOSCircleHasActivePeer(circle, me, error) : false;
45 // MARK: Peer Querying
49 static void sosArrayAppendPeerCopy(CFMutableArrayRef appendPeersTo, SOSPeerInfoRef peer) {
50 SOSPeerInfoRef peerInfo = SOSPeerInfoCreateCopy(kCFAllocatorDefault, peer, NULL);
51 CFArrayAppendValue(appendPeersTo, peerInfo);
55 static CFArrayRef SOSAccountCopySortedPeerArray(SOSAccount* account,
57 void (^action)(SOSCircleRef circle, CFMutableArrayRef appendPeersTo)) {
58 if (!SOSAccountHasPublicKey(account, error))
61 CFMutableArrayRef peers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
62 SOSCircleRef circle = NULL;
64 SOSAccountTrustClassic *trust = account.trust;
65 circle = trust.trustedCircle;
66 action(circle, peers);
68 CFArrayOfSOSPeerInfosSortByID(peers);
74 CFArrayRef SOSAccountCopyNotValidPeers(SOSAccount* account, CFErrorRef *error) {
75 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
76 SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
77 if(!SOSPeerInfoApplicationVerify(peer, account.accountKey, NULL)) {
78 sosArrayAppendPeerCopy(appendPeersTo, peer);
85 CFArrayRef SOSAccountCopyValidPeers(SOSAccount* account, CFErrorRef *error) {
86 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
87 SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
88 if(SOSPeerInfoApplicationVerify(peer, account.accountKey, NULL)) {
89 sosArrayAppendPeerCopy(appendPeersTo, peer);
97 CFArrayRef SOSAccountCopyPeersToListenTo(SOSAccount* account, CFErrorRef *error) {
98 SOSFullPeerInfoRef identity = NULL;
100 SOSAccountTrustClassic *trust = account.trust;
101 identity = trust.fullPeerInfo;
102 SOSPeerInfoRef myPeerInfo = SOSFullPeerInfoGetPeerInfo(identity);
103 CFStringRef myID = myPeerInfo ? SOSPeerInfoGetPeerID(myPeerInfo) : NULL;
104 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
105 SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
106 if(!CFEqualSafe(myID, SOSPeerInfoGetPeerID(peer)) &&
107 SOSPeerInfoApplicationVerify(peer, account.accountKey, NULL) &&
108 !SOSPeerInfoIsRetirementTicket(peer)) {
109 CFArrayAppendValue(appendPeersTo, peer);
115 CFArrayRef SOSAccountCopyRetired(SOSAccount* account, CFErrorRef *error) {
116 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
117 SOSCircleForEachRetiredPeer(circle, ^(SOSPeerInfoRef peer) {
118 sosArrayAppendPeerCopy(appendPeersTo, peer);
123 CFArrayRef SOSAccountCopyViewUnaware(SOSAccount* account, CFErrorRef *error) {
124 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
125 SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
126 if (!SOSPeerInfoVersionHasV2Data(peer) ) {
127 sosArrayAppendPeerCopy(appendPeersTo, peer);
129 CFSetRef peerEnabledViews = SOSPeerInfoCopyEnabledViews(peer);
130 CFSetRef enabledV0Views = CFSetCreateIntersection(kCFAllocatorDefault, peerEnabledViews, SOSViewsGetV0ViewSet());
131 if(CFSetGetCount(enabledV0Views) != 0) {
132 sosArrayAppendPeerCopy(appendPeersTo, peer);
134 CFReleaseNull(peerEnabledViews);
135 CFReleaseNull(enabledV0Views);
141 CFArrayRef SOSAccountCopyApplicants(SOSAccount* account, CFErrorRef *error) {
142 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
143 SOSCircleForEachApplicant(circle, ^(SOSPeerInfoRef peer) {
144 sosArrayAppendPeerCopy(appendPeersTo, peer);
149 CFArrayRef SOSAccountCopyPeers(SOSAccount* account, CFErrorRef *error) {
150 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
151 SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
152 sosArrayAppendPeerCopy(appendPeersTo, peer);
157 CFArrayRef SOSAccountCopyActivePeers(SOSAccount* account, CFErrorRef *error) {
158 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
159 SOSCircleForEachActivePeer(circle, ^(SOSPeerInfoRef peer) {
160 sosArrayAppendPeerCopy(appendPeersTo, peer);
165 CFArrayRef CF_RETURNS_RETAINED SOSAccountCopyActiveValidPeers(SOSAccount* account, CFErrorRef *error) {
166 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
167 SOSCircleForEachActiveValidPeer(circle, account.accountKey, ^(SOSPeerInfoRef peer) {
168 sosArrayAppendPeerCopy(appendPeersTo, peer);
173 CFArrayRef SOSAccountCopyConcurringPeers(SOSAccount* account, CFErrorRef *error)
175 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
176 SOSCircleAppendConcurringPeers(circle, appendPeersTo, NULL);
180 SOSPeerInfoRef SOSAccountCopyPeerWithID(SOSAccount* account, CFStringRef peerid, CFErrorRef *error) {
181 SOSCircleRef circle = NULL;
183 SOSAccountTrustClassic *trust = account.trust;
184 circle = trust.trustedCircle;
185 if(!circle) return NULL;
186 return SOSCircleCopyPeerWithID(circle, peerid, error);
189 CFBooleanRef SOSAccountPeersHaveViewsEnabled(SOSAccount* account, CFArrayRef viewNames, CFErrorRef *error) {
190 CFBooleanRef result = NULL;
191 CFMutableSetRef viewsRemaining = NULL;
192 CFSetRef viewsToLookFor = NULL;
194 if(![account isInCircle:error]) {
195 CFReleaseNull(viewsToLookFor);
196 CFReleaseNull(viewsRemaining);
200 viewsToLookFor = CFSetCreateCopyOfArrayForCFTypes(viewNames);
201 viewsRemaining = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, viewsToLookFor);
202 CFReleaseNull(viewsToLookFor);
204 SOSAccountForEachCirclePeerExceptMe(account, ^(SOSPeerInfoRef peer) {
205 if (SOSPeerInfoApplicationVerify(peer, account.accountKey, NULL)) {
206 CFSetRef peerViews = SOSPeerInfoCopyEnabledViews(peer);
207 CFSetSubtract(viewsRemaining, peerViews);
208 CFReleaseNull(peerViews);
212 result = CFSetIsEmpty(viewsRemaining) ? kCFBooleanTrue : kCFBooleanFalse;
214 CFReleaseNull(viewsToLookFor);
215 CFReleaseNull(viewsRemaining);