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> 
  43 /* SOSDataSource protocol (non opaque). */ 
  44 typedef struct SOSDataSourceFactory 
*SOSDataSourceFactoryRef
; 
  45 typedef struct SOSDataSource 
*SOSDataSourceRef
; 
  46 typedef struct __OpaqueSOSEngine 
*SOSEngineRef
; 
  47 typedef struct __OpaqueSOSObject 
*SOSObjectRef
; 
  48 typedef struct __OpaqueSOSTransaction 
*SOSTransactionRef
; 
  51 // MARK: - SOSDataSourceFactory protocol 
  53 struct SOSDataSourceFactory 
{ 
  54     CFStringRef      (*copy_name
)(SOSDataSourceFactoryRef factory
); 
  55     SOSDataSourceRef (*create_datasource
)(SOSDataSourceFactoryRef factory
, CFStringRef dataSourceName
, CFErrorRef 
*error
); 
  56     void             (*release
)(SOSDataSourceFactoryRef factory
); 
  57     void             (*circle_changed
)(SOSDataSourceFactoryRef factory
, CFStringRef myPeerID
, CFArrayRef trustedPeerIDs
, CFArrayRef untrustedPeerIDs
); 
  60 static inline CFStringRef 
SOSDataSourceFactoryCopyName(SOSDataSourceFactoryRef dsf
) { 
  61     return dsf
->copy_name(dsf
); 
  64 static inline SOSDataSourceRef 
SOSDataSourceFactoryCreateDataSource(SOSDataSourceFactoryRef dsf
, CFStringRef dataSourceName
, CFErrorRef 
*error
) { 
  65     return dsf
->create_datasource(dsf
, dataSourceName
, error
); 
  68 static inline void SOSDataSourceFactoryRelease(SOSDataSourceFactoryRef dsf
) { 
  72 static inline void SOSDataSourceFactoryCircleChanged(SOSDataSourceFactoryRef dsf
, CFStringRef myPeerID
, CFArrayRef trustedPeerIDs
, CFArrayRef untrustedPeerIDs
) { 
  73     dsf
->circle_changed(dsf
, myPeerID
, trustedPeerIDs
, untrustedPeerIDs
); 
  78 // MARK: - SOSDataSource protocol 
  81 /* Implement this if you want to create a new type of sync client. 
  82    Currently we support keychains, but the engine should scale to 
  83    entire filesystems. */ 
  85     kSOSMergeFailure 
= 0,   // CFErrorRef returned, no error returned in any other case 
  86     kSOSMergeLocalObject
,   // We choose the current object in the dataSource the manifest is still valid. 
  87     kSOSMergePeersObject
,   // We chose the peers object over our own, manifest is now dirty. 
  88     kSOSMergeCreatedObject
, // *createdObject is returned and should be released 
  90 typedef CFIndex SOSMergeResult
; 
  93 // MARK: SOSDataSourceTransactionType 
  95 enum SOSDataSourceTransactionType 
{ 
  96     kSOSDataSourceNoneTransactionType 
= 0, 
  97     kSOSDataSourceImmediateTransactionType
, 
  98     kSOSDataSourceExclusiveTransactionType
, 
  99     kSOSDataSourceNormalTransactionType
, 
 100     kSOSDataSourceExclusiveRemoteTransactionType
, 
 102 typedef CFOptionFlags SOSDataSourceTransactionType
; 
 104 enum SOSDataSourceTransactionPhase 
{ 
 105     kSOSDataSourceTransactionDidRollback 
= 0,   // A transaction just got rolled back 
 106     kSOSDataSourceTransactionWillCommit
,        // A transaction is about to commit. 
 107     kSOSDataSourceTransactionDidCommit
,         // A transnaction sucessfully committed. 
 109 typedef CFOptionFlags SOSDataSourceTransactionPhase
; 
 111 enum SOSDataSourceTransactionSource 
{ 
 112     kSOSDataSourceSOSTransaction
,        // A remotely initated transaction. 
 113     kSOSDataSourceAPITransaction
,        // A user initated transaction. 
 115 typedef CFOptionFlags SOSDataSourceTransactionSource
; 
 117 typedef void (^SOSDataSourceNotifyBlock
)(SOSDataSourceRef ds
, SOSTransactionRef txn
, SOSDataSourceTransactionPhase phase
, SOSDataSourceTransactionSource source
, CFArrayRef changes
); 
 120 // MARK: - SOSDataSource struct 
 123 struct SOSDataSource 
{ 
 124     // SOSEngine - every datasource has an engine that is notified of changes 
 125     // to the datasource. 
 128     // General SOSDataSource methods 
 129     CFStringRef (*dsGetName
)(SOSDataSourceRef ds
); 
 130     void (*dsSetNotifyPhaseBlock
)(SOSDataSourceRef ds
, dispatch_queue_t queue
, SOSDataSourceNotifyBlock notifyBlock
); 
 131     SOSManifestRef (*dsCopyManifestWithViewNameSet
)(SOSDataSourceRef ds
, CFSetRef viewNameSet
, CFErrorRef 
*error
); 
 132     bool (*dsForEachObject
)(SOSDataSourceRef ds
, SOSManifestRef manifest
, CFErrorRef 
*error
, void (^handleObject
)(CFDataRef key
, SOSObjectRef object
, bool *stop
)); 
 133     CFDataRef (*dsCopyStateWithKey
)(SOSDataSourceRef ds
, CFStringRef key
, CFStringRef pdmn
, CFErrorRef 
*error
); 
 134     CFDataRef (*dsCopyItemDataWithKeys
)(SOSDataSourceRef ds
, CFDictionaryRef keys
, CFErrorRef 
*error
); 
 136     bool (*dsWith
)(SOSDataSourceRef ds
, CFErrorRef 
*error
, SOSDataSourceTransactionSource source
, void(^transaction
)(SOSTransactionRef txn
, bool *commit
)); 
 137     bool (*dsRelease
)(SOSDataSourceRef ds
, CFErrorRef 
*error
); // Destructor 
 139     // SOSTransaction methods, writes to a dataSource require a transaction. 
 140     SOSMergeResult (*dsMergeObject
)(SOSTransactionRef txn
, SOSObjectRef object
, SOSObjectRef 
*createdObject
, CFErrorRef 
*error
); 
 141     bool (*dsSetStateWithKey
)(SOSDataSourceRef ds
, SOSTransactionRef txn
, CFStringRef pdmn
, CFStringRef key
, CFDataRef state
, CFErrorRef 
*error
); 
 142     bool (*dsRestoreObject
)(SOSTransactionRef txn
, uint64_t handle
, CFDictionaryRef item
, CFErrorRef 
*error
); 
 145     CFDataRef (*objectCopyDigest
)(SOSObjectRef object
, CFErrorRef 
*error
); 
 146     CFDataRef (*objectCopyPrimaryKey
)(SOSObjectRef object
, CFErrorRef 
*error
); 
 147     SOSObjectRef (*objectCreateWithPropertyList
)(CFDictionaryRef plist
, CFErrorRef 
*error
); 
 148     CFDictionaryRef (*objectCopyPropertyList
)(SOSObjectRef object
, CFErrorRef 
*error
); 
 149     CFDictionaryRef (*objectCopyBackup
)(SOSObjectRef object
, uint64_t handle
, CFErrorRef 
*error
); 
 153 // MARK: - SOSDataSource protocol implementation 
 155 static inline SOSEngineRef 
SOSDataSourceGetSharedEngine(SOSDataSourceRef ds
, CFErrorRef 
*error
) { 
 159 static inline CFStringRef 
SOSDataSourceGetName(SOSDataSourceRef ds
) { 
 160     return ds
->dsGetName(ds
); 
 163 static inline void SOSDataSourceSetNotifyPhaseBlock(SOSDataSourceRef ds
, dispatch_queue_t queue
, SOSDataSourceNotifyBlock notifyBlock
) { 
 164     ds
->dsSetNotifyPhaseBlock(ds
, queue
, notifyBlock
); 
 167 static inline SOSManifestRef 
SOSDataSourceCopyManifestWithViewNameSet(SOSDataSourceRef ds
, CFSetRef viewNameSet
, CFErrorRef 
*error
) { 
 168     return ds
->dsCopyManifestWithViewNameSet(ds
, viewNameSet
, error
); 
 171 static inline bool SOSDataSourceForEachObject(SOSDataSourceRef ds
, SOSManifestRef manifest
, CFErrorRef 
*error
, void (^handleObject
)(CFDataRef digest
, SOSObjectRef object
, bool *stop
)) { 
 172     return ds
->dsForEachObject(ds
, manifest
, error
, handleObject
); 
 175 static inline bool SOSDataSourceWith(SOSDataSourceRef ds
, CFErrorRef 
*error
, 
 176                                      void(^transaction
)(SOSTransactionRef txn
, bool *commit
)) { 
 177     return ds
->dsWith(ds
, error
, kSOSDataSourceSOSTransaction
, transaction
); 
 180 static inline bool SOSDataSourceWithAPI(SOSDataSourceRef ds
, bool isAPI
, CFErrorRef 
*error
, 
 181                                      void(^transaction
)(SOSTransactionRef txn
, bool *commit
)) { 
 182     return ds
->dsWith(ds
, error
, isAPI 
? kSOSDataSourceAPITransaction 
: kSOSDataSourceSOSTransaction
, transaction
); 
 185 static inline CFDataRef 
SOSDataSourceCopyStateWithKey(SOSDataSourceRef ds
, CFStringRef key
, CFStringRef pdmn
, CFErrorRef 
*error
) 
 187     return ds
->dsCopyStateWithKey(ds
, key
, pdmn
, error
); 
 190 static inline CFDataRef 
SOSDataSourceCopyItemDataWithKeys(SOSDataSourceRef ds
, CFDictionaryRef keys
, CFErrorRef 
*error
) { 
 191     return ds
->dsCopyItemDataWithKeys(ds
, keys
, error
); 
 194 static inline bool SOSDataSourceRelease(SOSDataSourceRef ds
, CFErrorRef 
*error
) { 
 195     return !ds 
|| ds
->dsRelease(ds
, error
); 
 199 // MARK: - SOSTransaction 
 202 static inline SOSMergeResult 
SOSDataSourceMergeObject(SOSDataSourceRef ds
, SOSTransactionRef txn
, SOSObjectRef peersObject
, SOSObjectRef 
*mergedObject
, CFErrorRef 
*error
) { 
 203     return ds
->dsMergeObject(txn
, peersObject
, mergedObject
, error
); 
 206 static inline bool SOSDataSourceSetStateWithKey(SOSDataSourceRef ds
, SOSTransactionRef txn
, CFStringRef key
, CFStringRef pdmn
, CFDataRef state
, CFErrorRef 
*error
) 
 208     return ds
->dsSetStateWithKey(ds
, txn
, key
, pdmn
, state
, error
); 
 213 // MARK: - SOSObject methods 
 215 static inline CFDataRef 
SOSObjectCopyDigest(SOSDataSourceRef ds
, SOSObjectRef object
, CFErrorRef 
*error
) { 
 216     return ds
->objectCopyDigest(object
, error
); 
 219 static inline CFDataRef 
SOSObjectCopyPrimaryKey(SOSDataSourceRef ds
, SOSObjectRef object
, CFErrorRef 
*error
) { 
 220     return ds
->objectCopyPrimaryKey(object
, error
); 
 223 static inline SOSObjectRef 
SOSObjectCreateWithPropertyList(SOSDataSourceRef ds
, CFDictionaryRef plist
, CFErrorRef 
*error
) { 
 224     return ds
->objectCreateWithPropertyList(plist
, error
); 
 227 static inline CFDictionaryRef 
SOSObjectCopyPropertyList(SOSDataSourceRef ds
, SOSObjectRef object
, CFErrorRef 
*error
) { 
 228     return ds
->objectCopyPropertyList(object
, error
); 
 231 static inline CFDictionaryRef 
SOSObjectCopyBackup(SOSDataSourceRef ds
, SOSObjectRef object
, uint64_t handle
, CFErrorRef 
*error
) { 
 232     return ds
->objectCopyBackup(object
, handle
, error
); 
 235 static inline bool SOSObjectRestoreObject(SOSDataSourceRef ds
, SOSTransactionRef txn
, uint64_t handle
, CFDictionaryRef item
, CFErrorRef 
*error
) { 
 236     return ds
->dsRestoreObject(txn
, handle
, item
, error
); 
 241 // MARK: SOSDataSourceFactory helpers 
 244 static inline SOSEngineRef 
SOSDataSourceFactoryGetEngineForDataSourceName(SOSDataSourceFactoryRef factory
, CFStringRef dataSourceName
, CFErrorRef 
*error
) 
 246     SOSDataSourceRef ds 
= SOSDataSourceFactoryCreateDataSource(factory
, dataSourceName
, error
); 
 247     SOSEngineRef engine 
= ds 
? SOSDataSourceGetSharedEngine(ds
, error
) : (SOSEngineRef
) NULL
; 
 248     SOSDataSourceRelease(ds
, NULL
); // TODO: Log this error?! 
 255 #endif /* !_SEC_SOSDATASOURCE_H_ */