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 enum SOSDataSourceTransactionSource 
{ 
 114     kSOSDataSourceSOSTransaction
,        // A remotely initated transaction. 
 115     kSOSDataSourceAPITransaction
,        // A user initated transaction. 
 117 typedef CFOptionFlags SOSDataSourceTransactionSource
; 
 119 typedef void (^SOSDataSourceNotifyBlock
)(SOSDataSourceRef ds
, SOSTransactionRef txn
, SOSDataSourceTransactionPhase phase
, SOSDataSourceTransactionSource source
, CFArrayRef changes
); 
 122 // MARK: - SOSDataSource struct 
 125 struct SOSDataSource 
{ 
 126     // SOSEngine - every datasource has an engine that is notified of changes 
 127     // to the datasource. 
 130     // General SOSDataSource methods 
 131     CFStringRef (*dsGetName
)(SOSDataSourceRef ds
); 
 132     void (*dsAddNotifyPhaseBlock
)(SOSDataSourceRef ds
, SOSDataSourceNotifyBlock notifyBlock
); 
 133     SOSManifestRef (*dsCopyManifestWithViewNameSet
)(SOSDataSourceRef ds
, CFSetRef viewNameSet
, CFErrorRef 
*error
); 
 134     bool (*dsForEachObject
)(SOSDataSourceRef ds
, SOSTransactionRef txn
, SOSManifestRef manifest
, CFErrorRef 
*error
, void (^handleObject
)(CFDataRef key
, SOSObjectRef object
, bool *stop
)); 
 135     CFDataRef (*dsCopyStateWithKey
)(SOSDataSourceRef ds
, CFStringRef key
, CFStringRef pdmn
, SOSTransactionRef txn
, CFErrorRef 
*error
); 
 136     CFDataRef (*dsCopyItemDataWithKeys
)(SOSDataSourceRef ds
, CFDictionaryRef keys
, CFErrorRef 
*error
); 
 137     bool (*dsDeleteStateWithKey
)(SOSDataSourceRef ds
, CFStringRef key
, CFStringRef pdmn
, SOSTransactionRef txn
, CFErrorRef 
*error
); 
 139     bool (*dsWith
)(SOSDataSourceRef ds
, CFErrorRef 
*error
, SOSDataSourceTransactionSource source
, bool onCommitQueue
, void(^transaction
)(SOSTransactionRef txn
, bool *commit
)); 
 140     bool (*dsRelease
)(SOSDataSourceRef ds
, CFErrorRef 
*error
); // Destructor 
 141     bool (*dsReadWith
)(SOSDataSourceRef ds
, CFErrorRef 
*error
, SOSDataSourceTransactionSource source
, void(^perform
)(SOSTransactionRef txn
)); 
 143     // SOSTransaction methods, writes to a dataSource require a transaction. 
 144     SOSMergeResult (*dsMergeObject
)(SOSTransactionRef txn
, SOSObjectRef object
, SOSObjectRef 
*createdObject
, CFErrorRef 
*error
); 
 145     bool (*dsSetStateWithKey
)(SOSDataSourceRef ds
, SOSTransactionRef txn
, CFStringRef pdmn
, CFStringRef key
, CFDataRef state
, CFErrorRef 
*error
); 
 146     bool (*dsRestoreObject
)(SOSTransactionRef txn
, uint64_t handle
, CFDictionaryRef item
, CFErrorRef 
*error
); 
 149     CFDataRef (*objectCopyDigest
)(SOSObjectRef object
, CFErrorRef 
*error
); 
 150     CFDateRef (*objectCopyModDate
)(SOSObjectRef object
, CFErrorRef 
*error
); 
 151     SOSObjectRef (*objectCreateWithPropertyList
)(CFDictionaryRef plist
, CFErrorRef 
*error
); 
 152     CFDictionaryRef (*objectCopyPropertyList
)(SOSObjectRef object
, CFErrorRef 
*error
); 
 153     CFDictionaryRef (*objectCopyBackup
)(SOSObjectRef object
, uint64_t handle
, CFErrorRef 
*error
); 
 157 // MARK: - SOSDataSource protocol implementation 
 159 static inline SOSEngineRef 
SOSDataSourceGetSharedEngine(SOSDataSourceRef ds
, CFErrorRef 
*error
) { 
 163 static inline CFStringRef 
SOSDataSourceGetName(SOSDataSourceRef ds
) { 
 164     return ds
->dsGetName(ds
); 
 167 static inline void SOSDataSourceAddNotifyPhaseBlock(SOSDataSourceRef ds
, SOSDataSourceNotifyBlock notifyBlock
) { 
 168     ds
->dsAddNotifyPhaseBlock(ds
, notifyBlock
); 
 171 static inline SOSManifestRef 
SOSDataSourceCopyManifestWithViewNameSet(SOSDataSourceRef ds
, CFSetRef viewNameSet
, CFErrorRef 
*error
) { 
 172     return ds
->dsCopyManifestWithViewNameSet(ds
, viewNameSet
, error
); 
 175 static inline bool SOSDataSourceForEachObject(SOSDataSourceRef ds
, SOSTransactionRef txn
, SOSManifestRef manifest
, CFErrorRef 
*error
, void (^handleObject
)(CFDataRef digest
, SOSObjectRef object
, bool *stop
)) { 
 176     return ds
->dsForEachObject(ds
, txn
, manifest
, error
, handleObject
); 
 179 static inline bool SOSDataSourceWith(SOSDataSourceRef ds
, CFErrorRef 
*error
, 
 180                                      void(^transaction
)(SOSTransactionRef txn
, bool *commit
)) { 
 181     return ds
->dsWith(ds
, error
, kSOSDataSourceSOSTransaction
, false, transaction
); 
 184 static inline bool SOSDataSourceWithCommitQueue(SOSDataSourceRef ds
, CFErrorRef 
*error
, 
 185                                      void(^transaction
)(SOSTransactionRef txn
, bool *commit
)) { 
 186     return ds
->dsWith(ds
, error
, kSOSDataSourceSOSTransaction
, true, transaction
); 
 189 static inline bool SOSDataSourceWithAPI(SOSDataSourceRef ds
, bool isAPI
, CFErrorRef 
*error
, 
 190                                      void(^transaction
)(SOSTransactionRef txn
, bool *commit
)) { 
 191     return ds
->dsWith(ds
, error
, isAPI 
? kSOSDataSourceAPITransaction 
: kSOSDataSourceSOSTransaction
, false, transaction
); 
 194 static inline bool SOSDataSourceReadWithCommitQueue(SOSDataSourceRef ds
, CFErrorRef 
*error
, 
 195                                                 void(^perform
)(SOSTransactionRef txn
)) { 
 196     return ds
->dsReadWith(ds
, error
, kSOSDataSourceSOSTransaction
, perform
); 
 200 static inline CFDataRef 
SOSDataSourceCopyStateWithKey(SOSDataSourceRef ds
, CFStringRef key
, CFStringRef pdmn
, SOSTransactionRef txn
, CFErrorRef 
*error
) 
 202     return ds
->dsCopyStateWithKey(ds
, key
, pdmn
, txn
, error
); 
 205 static inline CFDataRef 
SOSDataSourceCopyItemDataWithKeys(SOSDataSourceRef ds
, CFDictionaryRef keys
, CFErrorRef 
*error
) { 
 206     return ds
->dsCopyItemDataWithKeys(ds
, keys
, error
); 
 209 static inline bool SOSDataSourceDeleteStateWithKey(SOSDataSourceRef ds
, CFStringRef key
, CFStringRef pdmn
, SOSTransactionRef txn
, CFErrorRef 
*error
) 
 211     return ds
->dsDeleteStateWithKey(ds
, key
, pdmn
, txn
, error
); 
 214 static inline bool SOSDataSourceRelease(SOSDataSourceRef ds
, CFErrorRef 
*error
) { 
 215     return !ds 
|| ds
->dsRelease(ds
, error
); 
 219 // MARK: - SOSTransaction 
 222 static inline SOSMergeResult 
SOSDataSourceMergeObject(SOSDataSourceRef ds
, SOSTransactionRef txn
, SOSObjectRef peersObject
, SOSObjectRef 
*mergedObject
, CFErrorRef 
*error
) { 
 223     return ds
->dsMergeObject(txn
, peersObject
, mergedObject
, error
); 
 226 static inline bool SOSDataSourceSetStateWithKey(SOSDataSourceRef ds
, SOSTransactionRef txn
, CFStringRef key
, CFStringRef pdmn
, CFDataRef state
, CFErrorRef 
*error
) 
 228     return ds
->dsSetStateWithKey(ds
, txn
, key
, pdmn
, state
, error
); 
 233 // MARK: - SOSObject methods 
 235 static inline CFDataRef 
SOSObjectCopyDigest(SOSDataSourceRef ds
, SOSObjectRef object
, CFErrorRef 
*error
) { 
 236     return ds
->objectCopyDigest(object
, error
); 
 239 static inline CFDateRef 
SOSObjectCopyModificationDate(SOSDataSourceRef ds
, SOSObjectRef object
, CFErrorRef 
*error
) { 
 240     return ds
->objectCopyModDate(object
, error
); 
 243 static inline SOSObjectRef 
SOSObjectCreateWithPropertyList(SOSDataSourceRef ds
, CFDictionaryRef plist
, CFErrorRef 
*error
) { 
 244     return ds
->objectCreateWithPropertyList(plist
, error
); 
 247 static inline CFDictionaryRef 
SOSObjectCopyPropertyList(SOSDataSourceRef ds
, SOSObjectRef object
, CFErrorRef 
*error
) { 
 248     return ds
->objectCopyPropertyList(object
, error
); 
 251 static inline CFDictionaryRef 
SOSObjectCopyBackup(SOSDataSourceRef ds
, SOSObjectRef object
, uint64_t handle
, CFErrorRef 
*error
) { 
 252     return ds
->objectCopyBackup(object
, handle
, error
); 
 255 static inline bool SOSObjectRestoreObject(SOSDataSourceRef ds
, SOSTransactionRef txn
, uint64_t handle
, CFDictionaryRef item
, CFErrorRef 
*error
) { 
 256     return ds
->dsRestoreObject(txn
, handle
, item
, error
); 
 261 // MARK: SOSDataSourceFactory helpers 
 264 static inline SOSEngineRef 
SOSDataSourceFactoryGetEngineForDataSourceName(SOSDataSourceFactoryRef factory
, CFStringRef dataSourceName
, CFErrorRef 
*error
) 
 266     SOSDataSourceRef ds 
= SOSDataSourceFactoryCreateDataSource(factory
, dataSourceName
, error
); 
 267     SOSEngineRef engine 
= ds 
? SOSDataSourceGetSharedEngine(ds
, error
) : (SOSEngineRef
) NULL
; 
 268     SOSDataSourceRelease(ds
, NULL
); // TODO: Log this error?! 
 275 #endif /* !_SEC_SOSDATASOURCE_H_ */