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
);
100 if (whichTransportType
== kSOSTransportIDS
|| whichTransportType
== kSOSTransportFuture
|| whichTransportType
== kSOSTransportPresent
) {
101 tidsMessage
= (SOSTransportMessageRef
)SOSTransportMessageIDSCreate(account
, circleName
, error
);
102 require_quiet(tidsMessage
, fail
);
104 CFRetainAssign(account
->ids_message_transport
, tidsMessage
);
106 secnotice("transport", "We are going to use an IDS transport");
109 tkvsMessage
= (SOSTransportMessageRef
)SOSTransportMessageKVSCreate(account
, circleName
, error
);
110 require_quiet(tkvsMessage
, fail
);
112 CFRetainAssign(account
->kvs_message_transport
, tkvsMessage
);
114 CFRetainAssign(account
->key_transport
, (SOSTransportKeyParameterRef
)tKey
);
115 CFRetainAssign(account
->circle_transport
, tCircle
);
121 CFReleaseNull(tCircle
);
122 CFReleaseNull(tidsMessage
);
123 CFReleaseNull(tkvsMessage
);
127 SOSCircleRef
SOSAccountEnsureCircle(SOSAccountRef a
, CFStringRef name
, CFErrorRef
*error
)
129 CFErrorRef localError
= NULL
;
131 if (a
->trusted_circle
== NULL
) {
132 a
->trusted_circle
= SOSCircleCreate(NULL
, name
, NULL
);
133 SOSUpdateKeyInterest();
137 SOSCircleRef circle
= SOSAccountGetCircle(a
, &localError
);
139 require_action_quiet(circle
|| !isSOSErrorCoded(localError
, kSOSErrorIncompatibleCircle
), fail
,
140 if (error
) { *error
= localError
; localError
= NULL
; });
142 require_quiet(SOSAccountInflateTransportsForCircle(a
, name
, error
), fail
);
145 CFReleaseNull(localError
);
150 bool SOSAccountUpdateCircleFromRemote(SOSAccountRef account
, SOSCircleRef newCircle
, CFErrorRef
*error
)
152 return SOSAccountHandleUpdateCircle(account
, newCircle
, false, error
);
155 bool SOSAccountUpdateCircle(SOSAccountRef account
, SOSCircleRef newCircle
, CFErrorRef
*error
)
157 return SOSAccountHandleUpdateCircle(account
, newCircle
, true, error
);
160 bool SOSAccountModifyCircle(SOSAccountRef account
,
162 bool (^action
)(SOSCircleRef circle
))
164 bool success
= false;
166 SOSCircleRef circle
= NULL
;
167 require_action_quiet(account
->trusted_circle
, fail
, SOSErrorCreate(kSOSErrorNoCircle
, error
, NULL
, CFSTR("No circle to get peer key from")));
169 circle
= SOSCircleCopyCircle(kCFAllocatorDefault
, account
->trusted_circle
, error
);
170 require_quiet(circle
, fail
);
173 require_quiet(action(circle
), fail
);
175 success
= SOSAccountUpdateCircle(account
, circle
, error
);
178 CFReleaseSafe(circle
);