]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/SecureObjectSync/SOSDataSource.h
Security-58286.60.28.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSDataSource.h
1 /*
2 * Copyright (c) 2013-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 /*!
26 @header SOSDataSource.h
27 The functions provided in SOSDataSource.h provide the protocol to a
28 secure object syncing data source. This is something than can produce
29 manifests and manifest digests and query objects by digest and merge
30 objects into the data source.
31 */
32
33 #ifndef _SEC_SOSDATASOURCE_H_
34 #define _SEC_SOSDATASOURCE_H_
35
36 #include <Security/SecureObjectSync/SOSManifest.h>
37 #include <Security/SecureObjectSync/SOSCloudCircle.h>
38 #include <utilities/array_size.h>
39 #include <utilities/SecCFRelease.h>
40 #include <utilities/SecCFError.h>
41
42 __BEGIN_DECLS
43
44 /* SOSDataSource protocol (non opaque). */
45 typedef struct SOSDataSourceFactory *SOSDataSourceFactoryRef;
46 typedef struct SOSDataSource *SOSDataSourceRef;
47 typedef struct __OpaqueSOSEngine *SOSEngineRef;
48 typedef struct __OpaqueSOSObject *SOSObjectRef;
49 typedef struct __OpaqueSOSTransaction *SOSTransactionRef;
50
51 //
52 // MARK: - SOSDataSourceFactory protocol
53 //
54 struct SOSDataSourceFactory {
55 CFStringRef (*copy_name)(SOSDataSourceFactoryRef factory);
56 SOSDataSourceRef (*create_datasource)(SOSDataSourceFactoryRef factory, CFStringRef dataSourceName, CFErrorRef *error);
57 void (*release)(SOSDataSourceFactoryRef factory);
58 void (*circle_changed)(SOSDataSourceFactoryRef factory, CFStringRef myPeerID, CFArrayRef trustedPeerIDs, CFArrayRef untrustedPeerIDs);
59 };
60
61 static inline CFStringRef SOSDataSourceFactoryCopyName(SOSDataSourceFactoryRef dsf) {
62 return dsf->copy_name(dsf);
63 }
64
65 static inline SOSDataSourceRef SOSDataSourceFactoryCreateDataSource(SOSDataSourceFactoryRef dsf, CFStringRef dataSourceName, CFErrorRef *error) {
66 SecRequirementError(dsf != NULL, error, CFSTR("No datasource"));
67 return dsf ? dsf->create_datasource(dsf, dataSourceName, error) : NULL;
68 }
69
70 static inline void SOSDataSourceFactoryRelease(SOSDataSourceFactoryRef dsf) {
71 dsf->release(dsf);
72 }
73
74 static inline void SOSDataSourceFactoryCircleChanged(SOSDataSourceFactoryRef dsf, CFStringRef myPeerID, CFArrayRef trustedPeerIDs, CFArrayRef untrustedPeerIDs) {
75 dsf->circle_changed(dsf, myPeerID, trustedPeerIDs, untrustedPeerIDs);
76 }
77
78
79 //
80 // MARK: - SOSDataSource protocol
81 //
82
83 /* Implement this if you want to create a new type of sync client.
84 Currently we support keychains, but the engine should scale to
85 entire filesystems. */
86 enum SOSMergeResult {
87 kSOSMergeFailure = 0, // CFErrorRef returned, no error returned in any other case
88 kSOSMergeLocalObject, // We choose the current object in the dataSource the manifest is still valid.
89 kSOSMergePeersObject, // We chose the peers object over our own, manifest is now dirty.
90 kSOSMergeCreatedObject, // *createdObject is returned and should be released
91 };
92 typedef CFIndex SOSMergeResult;
93
94 //
95 // MARK: SOSDataSourceTransactionType
96 //
97 enum SOSDataSourceTransactionType {
98 kSOSDataSourceNoneTransactionType = 0,
99 kSOSDataSourceImmediateTransactionType,
100 kSOSDataSourceExclusiveTransactionType,
101 kSOSDataSourceNormalTransactionType,
102 kSOSDataSourceExclusiveRemoteTransactionType,
103 };
104 typedef CFOptionFlags SOSDataSourceTransactionType;
105
106 enum SOSDataSourceTransactionPhase {
107 kSOSDataSourceTransactionDidRollback = 0, // A transaction just got rolled back
108 kSOSDataSourceTransactionWillCommit, // A transaction is about to commit.
109 kSOSDataSourceTransactionDidCommit, // A transaction sucessfully committed.
110 };
111 typedef CFOptionFlags SOSDataSourceTransactionPhase;
112
113 // These must match the values in SecDbTransactionSource
114 enum SOSDataSourceTransactionSource {
115 kSOSDataSourceSOSTransaction = 0, // A remotely initated transaction.
116 kSOSDataSourceCKKSTransaction = 3, // A transaction initiated by CKKS.
117 kSOSDataSourceAPITransaction = 1, // A user initated transaction.
118 };
119 typedef CFOptionFlags SOSDataSourceTransactionSource;
120
121 typedef void (^SOSDataSourceNotifyBlock)(SOSDataSourceRef ds, SOSTransactionRef txn, SOSDataSourceTransactionPhase phase, SOSDataSourceTransactionSource source, CFArrayRef changes);
122
123 //
124 // MARK: - SOSDataSource struct
125 //
126
127 struct SOSDataSource {
128 // SOSEngine - every datasource has an engine that is notified of changes
129 // to the datasource.
130 SOSEngineRef engine;
131
132 // General SOSDataSource methods
133 CFStringRef (*dsGetName)(SOSDataSourceRef ds);
134 void (*dsAddNotifyPhaseBlock)(SOSDataSourceRef ds, SOSDataSourceNotifyBlock notifyBlock);
135 SOSManifestRef (*dsCopyManifestWithViewNameSet)(SOSDataSourceRef ds, CFSetRef viewNameSet, CFErrorRef *error);
136 bool (*dsForEachObject)(SOSDataSourceRef ds, SOSTransactionRef txn, SOSManifestRef manifest, CFErrorRef *error, void (^handleObject)(CFDataRef key, SOSObjectRef object, bool *stop));
137 CFDataRef (*dsCopyStateWithKey)(SOSDataSourceRef ds, CFStringRef key, CFStringRef pdmn, SOSTransactionRef txn, CFErrorRef *error);
138 CFDataRef (*dsCopyItemDataWithKeys)(SOSDataSourceRef ds, CFDictionaryRef keys, CFErrorRef *error);
139 bool (*dsDeleteStateWithKey)(SOSDataSourceRef ds, CFStringRef key, CFStringRef pdmn, SOSTransactionRef txn, CFErrorRef *error);
140
141 bool (*dsWith)(SOSDataSourceRef ds, CFErrorRef *error, SOSDataSourceTransactionSource source, bool onCommitQueue, void(^transaction)(SOSTransactionRef txn, bool *commit));
142 bool (*dsRelease)(SOSDataSourceRef ds, CFErrorRef *error); // Destructor
143 bool (*dsReadWith)(SOSDataSourceRef ds, CFErrorRef *error, SOSDataSourceTransactionSource source, void(^perform)(SOSTransactionRef txn));
144
145 // SOSTransaction methods, writes to a dataSource require a transaction.
146 SOSMergeResult (*dsMergeObject)(SOSTransactionRef txn, SOSObjectRef object, SOSObjectRef *createdObject, CFErrorRef *error);
147 bool (*dsSetStateWithKey)(SOSDataSourceRef ds, SOSTransactionRef txn, CFStringRef pdmn, CFStringRef key, CFDataRef state, CFErrorRef *error);
148 bool (*dsRestoreObject)(SOSTransactionRef txn, uint64_t handle, CFDictionaryRef item, CFErrorRef *error);
149
150 // SOSObject methods
151 CFDataRef (*objectCopyDigest)(SOSObjectRef object, CFErrorRef *error);
152 CFDateRef (*objectCopyModDate)(SOSObjectRef object, CFErrorRef *error);
153 SOSObjectRef (*objectCreateWithPropertyList)(CFDictionaryRef plist, CFErrorRef *error);
154 CFDictionaryRef (*objectCopyPropertyList)(SOSObjectRef object, CFErrorRef *error);
155 CFDictionaryRef (*objectCopyBackup)(SOSObjectRef object, uint64_t handle, CFErrorRef *error);
156 };
157
158 //
159 // MARK: - SOSDataSource protocol implementation
160 //
161 static inline SOSEngineRef SOSDataSourceGetSharedEngine(SOSDataSourceRef ds, CFErrorRef *error) {
162 return ds->engine;
163 }
164
165 static inline CFStringRef SOSDataSourceGetName(SOSDataSourceRef ds) {
166 return ds->dsGetName(ds);
167 }
168
169 static inline void SOSDataSourceAddNotifyPhaseBlock(SOSDataSourceRef ds, SOSDataSourceNotifyBlock notifyBlock) {
170 ds->dsAddNotifyPhaseBlock(ds, notifyBlock);
171 }
172
173 static inline SOSManifestRef SOSDataSourceCopyManifestWithViewNameSet(SOSDataSourceRef ds, CFSetRef viewNameSet, CFErrorRef *error) {
174 return ds->dsCopyManifestWithViewNameSet(ds, viewNameSet, error);
175 }
176
177 static inline bool SOSDataSourceForEachObject(SOSDataSourceRef ds, SOSTransactionRef txn, SOSManifestRef manifest, CFErrorRef *error, void (^handleObject)(CFDataRef digest, SOSObjectRef object, bool *stop)) {
178 return ds->dsForEachObject(ds, txn, manifest, error, handleObject);
179 }
180
181 static inline bool SOSDataSourceWith(SOSDataSourceRef ds, CFErrorRef *error,
182 void(^transaction)(SOSTransactionRef txn, bool *commit)) {
183 return ds->dsWith(ds, error, kSOSDataSourceSOSTransaction, false, transaction);
184 }
185
186 static inline bool SOSDataSourceWithCommitQueue(SOSDataSourceRef ds, CFErrorRef *error,
187 void(^transaction)(SOSTransactionRef txn, bool *commit)) {
188 return ds->dsWith(ds, error, kSOSDataSourceSOSTransaction, true, transaction);
189 }
190
191 static inline bool SOSDataSourceWithAPI(SOSDataSourceRef ds, bool isAPI, CFErrorRef *error,
192 void(^transaction)(SOSTransactionRef txn, bool *commit)) {
193 return ds->dsWith(ds, error, isAPI ? kSOSDataSourceAPITransaction : kSOSDataSourceSOSTransaction, false, transaction);
194 }
195
196 static inline bool SOSDataSourceReadWithCommitQueue(SOSDataSourceRef ds, CFErrorRef *error,
197 void(^perform)(SOSTransactionRef txn)) {
198 return ds->dsReadWith(ds, error, kSOSDataSourceSOSTransaction, perform);
199 }
200
201
202 static inline CFDataRef SOSDataSourceCopyStateWithKey(SOSDataSourceRef ds, CFStringRef key, CFStringRef pdmn, SOSTransactionRef txn, CFErrorRef *error)
203 {
204 return ds->dsCopyStateWithKey(ds, key, pdmn, txn, error);
205 }
206
207 static inline CFDataRef SOSDataSourceCopyItemDataWithKeys(SOSDataSourceRef ds, CFDictionaryRef keys, CFErrorRef *error) {
208 return ds->dsCopyItemDataWithKeys(ds, keys, error);
209 }
210
211 static inline bool SOSDataSourceDeleteStateWithKey(SOSDataSourceRef ds, CFStringRef key, CFStringRef pdmn, SOSTransactionRef txn, CFErrorRef *error)
212 {
213 return ds->dsDeleteStateWithKey(ds, key, pdmn, txn, error);
214 }
215
216 static inline bool SOSDataSourceRelease(SOSDataSourceRef ds, CFErrorRef *error) {
217 return !ds || ds->dsRelease(ds, error);
218 }
219
220 //
221 // MARK: - SOSTransaction
222 //
223
224 static inline SOSMergeResult SOSDataSourceMergeObject(SOSDataSourceRef ds, SOSTransactionRef txn, SOSObjectRef peersObject, SOSObjectRef *mergedObject, CFErrorRef *error) {
225 return ds->dsMergeObject(txn, peersObject, mergedObject, error);
226 }
227
228 static inline bool SOSDataSourceSetStateWithKey(SOSDataSourceRef ds, SOSTransactionRef txn, CFStringRef key, CFStringRef pdmn, CFDataRef state, CFErrorRef *error)
229 {
230 return ds->dsSetStateWithKey(ds, txn, key, pdmn, state, error);
231 }
232
233
234 //
235 // MARK: - SOSObject methods
236 //
237 static inline CFDataRef SOSObjectCopyDigest(SOSDataSourceRef ds, SOSObjectRef object, CFErrorRef *error) {
238 return ds->objectCopyDigest(object, error);
239 }
240
241 static inline CFDateRef SOSObjectCopyModificationDate(SOSDataSourceRef ds, SOSObjectRef object, CFErrorRef *error) {
242 return ds->objectCopyModDate(object, error);
243 }
244
245 static inline SOSObjectRef SOSObjectCreateWithPropertyList(SOSDataSourceRef ds, CFDictionaryRef plist, CFErrorRef *error) {
246 return ds->objectCreateWithPropertyList(plist, error);
247 }
248
249 static inline CFDictionaryRef SOSObjectCopyPropertyList(SOSDataSourceRef ds, SOSObjectRef object, CFErrorRef *error) {
250 return ds->objectCopyPropertyList(object, error);
251 }
252
253 static inline CFDictionaryRef SOSObjectCopyBackup(SOSDataSourceRef ds, SOSObjectRef object, uint64_t handle, CFErrorRef *error) {
254 return ds->objectCopyBackup(object, handle, error);
255 }
256
257 static inline bool SOSObjectRestoreObject(SOSDataSourceRef ds, SOSTransactionRef txn, uint64_t handle, CFDictionaryRef item, CFErrorRef *error) {
258 return ds->dsRestoreObject(txn, handle, item, error);
259 }
260
261
262 //
263 // MARK: SOSDataSourceFactory helpers
264 //
265
266 static inline SOSEngineRef SOSDataSourceFactoryGetEngineForDataSourceName(SOSDataSourceFactoryRef factory, CFStringRef dataSourceName, CFErrorRef *error)
267 {
268 SOSDataSourceRef ds = SOSDataSourceFactoryCreateDataSource(factory, dataSourceName, error);
269 SOSEngineRef engine = ds ? SOSDataSourceGetSharedEngine(ds, error) : (SOSEngineRef) NULL;
270 SOSDataSourceRelease(ds, NULL); // TODO: Log this error?!
271
272 return engine;
273 }
274
275 __END_DECLS
276
277 #endif /* !_SEC_SOSDATASOURCE_H_ */