6 #include "SOSAccountPriv.h"
7 #include <Security/SecureObjectSync/SOSTransport.h>
8 #include <Security/SecureObjectSync/SOSTransportKeyParameterKVS.h>
9 #include <Security/SecureObjectSync/SOSTransportCircleKVS.h>
10 #include <Security/SecureObjectSync/SOSTransportMessageKVS.h>
11 #include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
12 #include "SOSCloudKeychainClient.h"
16 // MARK: Circle management
19 CFIndex whichTransportType
;
22 SecKeyRef
SOSAccountCopyPublicKeyForPeer(SOSAccountRef account
, CFStringRef peer_id
, CFErrorRef
*error
) {
23 SecKeyRef publicKey
= NULL
;
24 SOSPeerInfoRef peer
= NULL
;
26 require_action_quiet(account
->trusted_circle
, fail
, SOSErrorCreate(kSOSErrorNoCircle
, error
, NULL
, CFSTR("No circle to get peer key from")));
28 peer
= SOSCircleCopyPeerWithID(account
->trusted_circle
, peer_id
, error
);
29 require_quiet(peer
, fail
);
31 publicKey
= SOSPeerInfoCopyPubKey(peer
);
39 SOSCircleRef
SOSAccountGetCircle(SOSAccountRef a
, CFErrorRef
*error
)
41 CFTypeRef entry
= a
->trusted_circle
;
43 require_action_quiet(!isNull(entry
), fail
,
44 SOSCreateError(kSOSErrorIncompatibleCircle
, CFSTR("Incompatible circle in KVS"), NULL
, error
));
46 require_action_quiet(entry
, fail
,
47 SOSCreateError(kSOSErrorNoCircle
, CFSTR("No circle found"), NULL
, error
));
50 return (SOSCircleRef
) entry
;
56 static void setup_defaults_settings(){
58 Boolean keyExistsAndHasValue
= false;
60 whichTransportType
= CFPreferencesGetAppIntegerValue(CFSTR("Transport"), CFSTR("com.apple.security"), &keyExistsAndHasValue
);
61 if(whichTransportType
== kSOSTransportFuture
)
62 secdebug("IDS", "Successfully retrieved value: %d, We are a Galarch + 1 device: %ld", keyExistsAndHasValue
, whichTransportType
);
63 else if (whichTransportType
== kSOSTransportPresent
)
64 secdebug("IDS", "Successfully retrieved value: %d, We are a Galarch device: %ld", keyExistsAndHasValue
, whichTransportType
);
66 else if (whichTransportType
== kSOSTransportIDS
)
67 secdebug("IDS", "Successfully retrieved value: %d, We are an IDS device: %ld", keyExistsAndHasValue
, whichTransportType
);
69 else if (whichTransportType
== kSOSTransportKVS
)
70 secdebug("IDS", "Successfully retrieved value: %d, We are a KVS device: %ld", keyExistsAndHasValue
, whichTransportType
);
72 secdebug("IDS", "Successfully retrieved value: %d, We are a KVS device: %ld", keyExistsAndHasValue
, whichTransportType
);
76 static void SOSTransportInit(void) {
77 static dispatch_once_t sdOnceToken
;
78 dispatch_once(&sdOnceToken
, ^{
79 setup_defaults_settings();
83 static bool SOSAccountInflateTransportsForCircle(SOSAccountRef account
, CFStringRef circleName
, CFErrorRef
*error
){
86 SOSTransportKeyParameterRef tKey
= NULL
;
87 SOSTransportCircleRef tCircle
= NULL
;
88 SOSTransportMessageRef tidsMessage
= NULL
;
89 SOSTransportMessageRef tkvsMessage
= NULL
;
93 tKey
= (SOSTransportKeyParameterRef
)SOSTransportKeyParameterKVSCreate(account
, error
);
94 tCircle
= (SOSTransportCircleRef
)SOSTransportCircleKVSCreate(account
, circleName
, error
);
96 require_quiet(tKey
, fail
);
97 require_quiet(tCircle
, fail
);
99 tidsMessage
= (SOSTransportMessageRef
)SOSTransportMessageIDSCreate(account
, circleName
, error
);
100 require_quiet(tidsMessage
, fail
);
102 CFRetainAssign(account
->ids_message_transport
, tidsMessage
);
103 tkvsMessage
= (SOSTransportMessageRef
)SOSTransportMessageKVSCreate(account
, circleName
, error
);
104 require_quiet(tkvsMessage
, fail
);
106 CFRetainAssign(account
->kvs_message_transport
, tkvsMessage
);
108 CFRetainAssign(account
->key_transport
, (SOSTransportKeyParameterRef
)tKey
);
109 CFRetainAssign(account
->circle_transport
, tCircle
);
115 CFReleaseNull(tCircle
);
116 CFReleaseNull(tidsMessage
);
117 CFReleaseNull(tkvsMessage
);
121 SOSCircleRef
SOSAccountEnsureCircle(SOSAccountRef a
, CFStringRef name
, CFErrorRef
*error
)
123 CFErrorRef localError
= NULL
;
125 if (a
->trusted_circle
== NULL
) {
126 a
->trusted_circle
= SOSCircleCreate(NULL
, name
, NULL
);
127 SOSUpdateKeyInterest(a
);
131 SOSCircleRef circle
= SOSAccountGetCircle(a
, &localError
);
133 require_action_quiet(circle
|| !isSOSErrorCoded(localError
, kSOSErrorIncompatibleCircle
), fail
,
134 if (error
) { *error
= localError
; localError
= NULL
; });
136 require_quiet(SOSAccountInflateTransportsForCircle(a
, name
, error
), fail
);
139 CFReleaseNull(localError
);
144 bool SOSAccountUpdateCircleFromRemote(SOSAccountRef account
, SOSCircleRef newCircle
, CFErrorRef
*error
)
146 return SOSAccountHandleUpdateCircle(account
, newCircle
, false, error
);
149 bool SOSAccountUpdateCircle(SOSAccountRef account
, SOSCircleRef newCircle
, CFErrorRef
*error
)
151 return SOSAccountHandleUpdateCircle(account
, newCircle
, true, error
);
154 bool SOSAccountModifyCircle(SOSAccountRef account
,
156 bool (^action
)(SOSCircleRef circle
))
158 bool success
= false;
160 SOSCircleRef circle
= NULL
;
161 require_action_quiet(account
->trusted_circle
, fail
, SOSErrorCreate(kSOSErrorNoCircle
, error
, NULL
, CFSTR("No circle to get peer key from")));
163 circle
= SOSCircleCopyCircle(kCFAllocatorDefault
, account
->trusted_circle
, error
);
164 require_quiet(circle
, fail
);
167 require_quiet(action(circle
), fail
);
169 success
= SOSAccountUpdateCircle(account
, circle
, error
);
172 CFReleaseSafe(circle
);