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@
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.
33 #ifndef _SEC_SOSDATASOURCE_H_
34 #define _SEC_SOSDATASOURCE_H_
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>
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
;
52 // MARK: - SOSDataSourceFactory protocol
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
);
61 static inline CFStringRef
SOSDataSourceFactoryCopyName(SOSDataSourceFactoryRef dsf
) {
62 return dsf
->copy_name(dsf
);
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
;
70 static inline void SOSDataSourceFactoryRelease(SOSDataSourceFactoryRef dsf
) {
74 static inline void SOSDataSourceFactoryCircleChanged(SOSDataSourceFactoryRef dsf
, CFStringRef myPeerID
, CFArrayRef trustedPeerIDs
, CFArrayRef untrustedPeerIDs
) {
75 dsf
->circle_changed(dsf
, myPeerID
, trustedPeerIDs
, untrustedPeerIDs
);
80 // MARK: - SOSDataSource protocol
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. */
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
92 typedef CFIndex SOSMergeResult
;
95 // MARK: SOSDataSourceTransactionType
97 enum SOSDataSourceTransactionType
{
98 kSOSDataSourceNoneTransactionType
= 0,
99 kSOSDataSourceImmediateTransactionType
,
100 kSOSDataSourceExclusiveTransactionType
,
101 kSOSDataSourceNormalTransactionType
,
102 kSOSDataSourceExclusiveRemoteTransactionType
,
104 typedef CFOptionFlags SOSDataSourceTransactionType
;
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.
111 typedef CFOptionFlags SOSDataSourceTransactionPhase
;
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.
119 typedef CFOptionFlags SOSDataSourceTransactionSource
;
121 typedef void (^SOSDataSourceNotifyBlock
)(SOSDataSourceRef ds
, SOSTransactionRef txn
, SOSDataSourceTransactionPhase phase
, SOSDataSourceTransactionSource source
, CFArrayRef changes
);
124 // MARK: - SOSDataSource struct
127 struct SOSDataSource
{
128 // SOSEngine - every datasource has an engine that is notified of changes
129 // to the datasource.
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
);
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
));
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
);
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
);
159 // MARK: - SOSDataSource protocol implementation
161 static inline SOSEngineRef
SOSDataSourceGetSharedEngine(SOSDataSourceRef ds
, CFErrorRef
*error
) {
165 static inline CFStringRef
SOSDataSourceGetName(SOSDataSourceRef ds
) {
166 return ds
->dsGetName(ds
);
169 static inline void SOSDataSourceAddNotifyPhaseBlock(SOSDataSourceRef ds
, SOSDataSourceNotifyBlock notifyBlock
) {
170 ds
->dsAddNotifyPhaseBlock(ds
, notifyBlock
);
173 static inline SOSManifestRef
SOSDataSourceCopyManifestWithViewNameSet(SOSDataSourceRef ds
, CFSetRef viewNameSet
, CFErrorRef
*error
) {
174 return ds
->dsCopyManifestWithViewNameSet(ds
, viewNameSet
, error
);
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
);
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
);
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
);
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
);
196 static inline bool SOSDataSourceReadWithCommitQueue(SOSDataSourceRef ds
, CFErrorRef
*error
,
197 void(^perform
)(SOSTransactionRef txn
)) {
198 return ds
->dsReadWith(ds
, error
, kSOSDataSourceSOSTransaction
, perform
);
202 static inline CFDataRef
SOSDataSourceCopyStateWithKey(SOSDataSourceRef ds
, CFStringRef key
, CFStringRef pdmn
, SOSTransactionRef txn
, CFErrorRef
*error
)
204 return ds
->dsCopyStateWithKey(ds
, key
, pdmn
, txn
, error
);
207 static inline CFDataRef
SOSDataSourceCopyItemDataWithKeys(SOSDataSourceRef ds
, CFDictionaryRef keys
, CFErrorRef
*error
) {
208 return ds
->dsCopyItemDataWithKeys(ds
, keys
, error
);
211 static inline bool SOSDataSourceDeleteStateWithKey(SOSDataSourceRef ds
, CFStringRef key
, CFStringRef pdmn
, SOSTransactionRef txn
, CFErrorRef
*error
)
213 return ds
->dsDeleteStateWithKey(ds
, key
, pdmn
, txn
, error
);
216 static inline bool SOSDataSourceRelease(SOSDataSourceRef ds
, CFErrorRef
*error
) {
217 return !ds
|| ds
->dsRelease(ds
, error
);
221 // MARK: - SOSTransaction
224 static inline SOSMergeResult
SOSDataSourceMergeObject(SOSDataSourceRef ds
, SOSTransactionRef txn
, SOSObjectRef peersObject
, SOSObjectRef
*mergedObject
, CFErrorRef
*error
) {
225 return ds
->dsMergeObject(txn
, peersObject
, mergedObject
, error
);
228 static inline bool SOSDataSourceSetStateWithKey(SOSDataSourceRef ds
, SOSTransactionRef txn
, CFStringRef key
, CFStringRef pdmn
, CFDataRef state
, CFErrorRef
*error
)
230 return ds
->dsSetStateWithKey(ds
, txn
, key
, pdmn
, state
, error
);
235 // MARK: - SOSObject methods
237 static inline CFDataRef
SOSObjectCopyDigest(SOSDataSourceRef ds
, SOSObjectRef object
, CFErrorRef
*error
) {
238 return ds
->objectCopyDigest(object
, error
);
241 static inline CFDateRef
SOSObjectCopyModificationDate(SOSDataSourceRef ds
, SOSObjectRef object
, CFErrorRef
*error
) {
242 return ds
->objectCopyModDate(object
, error
);
245 static inline SOSObjectRef
SOSObjectCreateWithPropertyList(SOSDataSourceRef ds
, CFDictionaryRef plist
, CFErrorRef
*error
) {
246 return ds
->objectCreateWithPropertyList(plist
, error
);
249 static inline CFDictionaryRef
SOSObjectCopyPropertyList(SOSDataSourceRef ds
, SOSObjectRef object
, CFErrorRef
*error
) {
250 return ds
->objectCopyPropertyList(object
, error
);
253 static inline CFDictionaryRef
SOSObjectCopyBackup(SOSDataSourceRef ds
, SOSObjectRef object
, uint64_t handle
, CFErrorRef
*error
) {
254 return ds
->objectCopyBackup(object
, handle
, error
);
257 static inline bool SOSObjectRestoreObject(SOSDataSourceRef ds
, SOSTransactionRef txn
, uint64_t handle
, CFDictionaryRef item
, CFErrorRef
*error
) {
258 return ds
->dsRestoreObject(txn
, handle
, item
, error
);
263 // MARK: SOSDataSourceFactory helpers
266 static inline SOSEngineRef
SOSDataSourceFactoryGetEngineForDataSourceName(SOSDataSourceFactoryRef factory
, CFStringRef dataSourceName
, CFErrorRef
*error
)
268 SOSDataSourceRef ds
= SOSDataSourceFactoryCreateDataSource(factory
, dataSourceName
, error
);
269 SOSEngineRef engine
= ds
? SOSDataSourceGetSharedEngine(ds
, error
) : (SOSEngineRef
) NULL
;
270 SOSDataSourceRelease(ds
, NULL
); // TODO: Log this error?!
277 #endif /* !_SEC_SOSDATASOURCE_H_ */