]> git.saurik.com Git - apple/security.git/blob - Security/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.c
Security-57031.1.35.tar.gz
[apple/security.git] / Security / sec / SOSCircle / SecureObjectSync / SOSTransportMessage.c
1 #include <SecureObjectSync/SOSTransport.h>
2 #include <SecureObjectSync/SOSTransportMessage.h>
3 #include <SecureObjectSync/SOSKVSKeys.h>
4 #include <SecureObjectSync/SOSPeerCoder.h>
5 #include <SecureObjectSync/SOSEngine.h>
6 #include <utilities/SecCFWrappers.h>
7 #include <SOSInternal.h>
8 #include <SecureObjectSync/SOSAccountPriv.h>
9 #include <SOSCloudKeychainClient.h>
10
11 CFGiblisWithHashFor(SOSTransportMessage);
12
13 SOSTransportMessageRef SOSTransportMessageCreateForSubclass(size_t size,
14 SOSAccountRef account, CFStringRef circleName,
15 CFErrorRef *error)
16 {
17 SOSTransportMessageRef tpt = CFTypeAllocateWithSpace(SOSTransportMessage, size, kCFAllocatorDefault);
18
19 SOSEngineRef engine = SOSDataSourceFactoryGetEngineForDataSourceName(account->factory, circleName, error);
20
21 tpt->engine = CFRetainSafe(engine);
22 tpt->account = CFRetainSafe(account);
23 return tpt;
24 }
25
26
27 static CFStringRef SOSTransportMessageCopyDescription(CFTypeRef aObj){
28 SOSTransportMessageRef t = (SOSTransportMessageRef) aObj;
29
30 return t->copyDescription ? t->copyDescription(t)
31 : CFStringCreateWithFormat(NULL, NULL, CFSTR("<SOSTransportMessage@%p\n>"), t);
32 }
33
34 static void SOSTransportMessageDestroy(CFTypeRef aObj){
35 SOSTransportMessageRef transport = (SOSTransportMessageRef) aObj;
36
37 if (transport->destroy)
38 transport->destroy(transport);
39
40 CFReleaseSafe(transport->engine);
41 }
42
43 SOSAccountRef SOSTransportMessageGetAccount(SOSTransportMessageRef transport){
44 return transport->account;
45 }
46
47 static CFHashCode SOSTransportMessageHash(CFTypeRef obj){
48 return (intptr_t) obj;
49 }
50
51 static Boolean SOSTransportMessageCompare(CFTypeRef lhs, CFTypeRef rhs){
52 return SOSTransportMessageHash(lhs) == SOSTransportMessageHash(rhs);
53 }
54
55 bool SOSTransportMessageSendMessages(SOSTransportMessageRef transport, CFDictionaryRef circle_messages, CFErrorRef *error) {
56 return transport->sendMessages(transport, circle_messages, error);
57 }
58
59 bool SOSTransportMessageFlushChanges(SOSTransportMessageRef transport, CFErrorRef *error){
60 return transport->flushChanges(transport, error);
61 }
62
63 bool SOSTransportMessageSyncWithPeers(SOSTransportMessageRef transport, CFDictionaryRef circleToPeerIDs, CFErrorRef *error){
64 return transport->syncWithPeers(transport, circleToPeerIDs, error);
65 }
66
67 bool SOSTransportMessageCleanupAfterPeerMessages(SOSTransportMessageRef transport, CFDictionaryRef circleToPeerIDs, CFErrorRef* error){
68 return transport->cleanupAfterPeerMessages(transport, circleToPeerIDs, error);
69 }
70
71 CF_RETURNS_RETAINED
72 CFDictionaryRef SOSTransportMessageHandleMessages(SOSTransportMessageRef transport, CFMutableDictionaryRef circle_peer_messages_table, CFErrorRef *error){
73 return transport->handleMessages(transport, circle_peer_messages_table, error);
74 }
75
76 SOSEngineRef SOSTransportMessageGetEngine(SOSTransportMessageRef transport){
77 return transport->engine;
78 }
79
80
81 bool SOSTransportMessageHandlePeerMessage(SOSTransportMessageRef transport, CFStringRef peer_id, CFDataRef codedMessage, CFErrorRef *error){
82
83 CFDataRef decodedMessage = NULL;
84 bool result = false;
85
86 SOSPeerRef peer = SOSPeerCreateWithEngine(SOSTransportMessageGetEngine(transport), peer_id);
87
88 enum SOSCoderUnwrapStatus uwstatus = SOSPeerHandleCoderMessage(peer, peer_id, codedMessage, &decodedMessage, error);
89
90 if (uwstatus == SOSCoderUnwrapDecoded) {
91 result = SOSEngineHandleMessage(SOSTransportMessageGetEngine(transport), peer_id, decodedMessage, error);
92 } else {
93 result = uwstatus != SOSCoderUnwrapError;
94 }
95 CFReleaseNull(decodedMessage);
96 CFReleaseNull(peer);
97 return result;
98 }
99
100 bool SOSTransportMessageSendMessageIfNeeded(SOSTransportMessageRef transport, CFStringRef circle_id, CFStringRef peer_id, CFErrorRef *error) {
101
102 SOSEnginePeerMessageSentBlock sent = NULL;
103 CFDataRef message_to_send = NULL;
104 bool ok = false;
105 SOSPeerRef peer = SOSPeerCreateWithEngine(SOSTransportMessageGetEngine(transport), peer_id);
106 CFDataRef coderData = SOSEngineGetCoderData(SOSTransportMessageGetEngine(transport), peer_id);
107 require(coderData, fail);
108
109 SOSCoderRef coder = SOSCoderCreateFromData(coderData, error);
110 require(coder, fail);
111 SOSPeerSetCoder(peer, coder);
112
113 ok = SOSPeerCoderSendMessageIfNeeded(peer, &message_to_send, circle_id, peer_id, &sent, error);
114 coder = SOSPeerGetCoder(peer);
115
116 if (message_to_send) {
117 CFDictionaryRef peer_dict = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
118 peer_id, message_to_send,
119 NULL);
120 CFDictionaryRef circle_peers = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
121 circle_id, peer_dict,
122 NULL);
123
124 ok = ok && SOSTransportMessageSendMessages(transport, circle_peers, error);
125
126 SOSPeerCoderConsume(&sent, ok);
127
128 CFReleaseSafe(peer_dict);
129 CFReleaseSafe(circle_peers);
130 }
131
132
133 Block_release(sent);
134
135
136 CFReleaseSafe(message_to_send);
137
138 coderData = SOSCoderCopyDER(coder, error);
139
140 if(!SOSEngineSetCoderData(SOSTransportMessageGetEngine(transport), peer_id, coderData, error)){
141 secerror("SOSTransportMessageSendMessageIfNeeded, Could not save peer state");
142 }
143 CFReleaseNull(coderData);
144
145 if (coder)
146 SOSCoderDispose(coder);
147
148 fail:
149 CFReleaseNull(peer);
150 return ok;
151 }
152
153 bool SOSTransportMessageSendMessagesIfNeeded(SOSTransportMessageRef transport, CFStringRef circle_id, CFArrayRef handledPeers, CFErrorRef *error) {
154 CFArrayForEach(handledPeers, ^(const void *value) {
155 if (isString(value)) {
156 CFStringRef peer_id = (CFStringRef) value;
157 CFErrorRef sendError = NULL;
158
159 if (!SOSTransportMessageSendMessageIfNeeded(transport, circle_id, peer_id, &sendError)) {
160 secerror("Error sending message in circle %@ to peer %@ (%@)", circle_id, peer_id, sendError);
161 };
162
163 CFReleaseNull(sendError);
164 }
165 });
166
167 return true;
168 }
169
170
171
172