]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_keychain/lib/Keychains.h
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / lib / Keychains.h
index 7931313e3a9ad4215f1c0b86d6f4214e357d60eb..b33ae6a4b28ad07ac6a65e5d2f11bf980a15a4f3 100644 (file)
@@ -120,6 +120,9 @@ public:
 
        friend class Keychain;
        friend class ItemImpl;
+       friend class KeyItem;
+    friend class KCCursorImpl;
+    friend class StorageManager;
 protected:
     KeychainImpl(const CssmClient::Db &db);
 
@@ -133,7 +136,8 @@ public:
     virtual ~KeychainImpl();
 
        Mutex* getKeychainMutex();
-       Mutex* getMutexForObject();
+       Mutex* getMutexForObject() const;
+
        void aboutToDestruct();
 
        bool operator ==(const KeychainImpl &) const;
@@ -178,12 +182,16 @@ public:
 
        KCCursor createCursor(const SecKeychainAttributeList *attrList);
        KCCursor createCursor(SecItemClass itemClass, const SecKeychainAttributeList *attrList);
-       CssmClient::Db database() { return mDb; }
+       CssmClient::Db database() { StLock<Mutex>_(mDbMutex); return mDb; }
+    void changeDatabase(CssmClient::Db db);
        DLDbIdentifier dlDbIdentifier() const { return mDb->dlDbIdentifier(); }
 
        CssmClient::CSP csp();
 
        PrimaryKey makePrimaryKey(CSSM_DB_RECORDTYPE recordType, CssmClient::DbUniqueRecord &uniqueId);
+
+    // This will make a primary key for this record type, and populate it completely from the given attributes
+       PrimaryKey makePrimaryKey(CSSM_DB_RECORDTYPE recordType, CssmClient::DbAttributes *currentAttributes);
        void gatherPrimaryKeyAttributes(CssmClient::DbAttributes& primaryKeyAttrs);
        
        const CssmAutoDbRecordAttributeInfo &primaryKeyInfosFor(CSSM_DB_RECORDTYPE recordType);
@@ -191,6 +199,9 @@ public:
     Item item(const PrimaryKey& primaryKey);
     Item item(CSSM_DB_RECORDTYPE recordType, CssmClient::DbUniqueRecord &uniqueId);
 
+    // Check for an item that may have been deleted.
+    Item itemdeleted(const PrimaryKey& primaryKey);
+
        CssmDbAttributeInfo attributeInfoFor(CSSM_DB_RECORDTYPE recordType, UInt32 tag);
        void getAttributeInfoForItemID(CSSM_DB_RECORDTYPE itemID, SecKeychainAttributeInfo **Info);
        static void freeAttributeInfo(SecKeychainAttributeInfo *Info);
@@ -207,24 +218,93 @@ public:
        const AccessCredentials *defaultCredentials();
 
        // Only call these functions while holding globals().apiLock.
-       bool inCache() const throw() { return mInCache; }
-       void inCache(bool inCache) throw() { mInCache = inCache; }
+       bool inCache() const _NOEXCEPT { return mInCache; }
+       void inCache(bool inCache) _NOEXCEPT { mInCache = inCache; }
        
        void postEvent(SecKeychainEvent kcEvent, ItemImpl* item);
+    void postEvent(SecKeychainEvent kcEvent, ItemImpl* item, PrimaryKey pk);
        
        void addItem(const PrimaryKey &primaryKey, ItemImpl *dbItemImpl);
 
     bool mayDelete();
 
+    // Returns true if this keychain supports the attribute integrity and
+    // partition ID protections
+    bool hasIntegrityProtection();
+
 private:
+    // Checks for and triggers a keychain database upgrade
+    // DO NOT hold any of the keychain locks when you call this
+    bool performKeychainUpgradeIfNeeded();
+
+    // Notify the keychain that you're accessing it. Used in conjunction with
+    // the StorageManager for time-based caching.
+    void tickle();
+
+    // Used by StorageManager to remember the timer->keychain pairing
+    dispatch_source_t mCacheTimer;
+
+    // Set this to true to make tickling do nothing.
+    bool mSuppressTickle;
+
+public:
+    // Grab the locks and then call attemptKeychainMigration
+    // The access credentials are only used when downgrading version, and will be passed along with ACL edits
+    bool keychainMigration(const string oldPath, const uint32 dbBlobVersion, const string newPath, const uint32 newBlobVersion, const AccessCredentials *cred = NULL);
+
+private:
+    // Attempt to upgrade this keychain's database
+    uint32 attemptKeychainMigration(const string oldPath, const uint32 oldBlobVersion, const string newPath, const uint32 newBlobVersion, const AccessCredentials *cred);
+
+    // Attempt to rename this keychain, if someone hasn't beaten us to it
+    void attemptKeychainRename(const string oldPath, const string newPath, uint32 blobVersion);
+
+    // Remember if we've attempted to upgrade this keychain's database
+    bool mAttemptedUpgrade;
+
        void removeItem(const PrimaryKey &primaryKey, ItemImpl *inItemImpl);
+
+    // Use this when you want to be extra sure this item is removed from the
+    // cache. Iterates over the whole cache to find all instances. This function
+    // will take both cache map mutexes, so you must not hold only the
+    // mDbDeletedItemMapMutex when you call this function.
+    void forceRemoveFromCache(ItemImpl* inItemImpl);
+
+    // Looks up an item in the item cache.
+    //
+    // To use this in a thread-safe manner, you must hold this keychain's mutex
+    // from before you begin this operation until you have safely completed a
+    // CFRetain on the resulting ItemImpl.
        ItemImpl *_lookupItem(const PrimaryKey &primaryKey);
 
+    // Looks up a deleted item in the deleted item map. Does not check the normal map.
+    //
+    // To use this in a thread-safe manner, you must hold this keychain's mutex
+    // from before you begin this operation until you have safely completed a
+    // CFRetain on the resulting ItemImpl.
+    ItemImpl *_lookupDeletedItemOnly(const PrimaryKey &primaryKey);
+
        const AccessCredentials *makeCredentials();
 
-    typedef map<PrimaryKey, __weak ItemImpl *> DbItemMap;
-       // Weak reference map of all items we know about that have a primaryKey
+    typedef map<PrimaryKey, ItemImpl *> DbItemMap;
+       // Reference map of all items we know about that have a primaryKey
     DbItemMap mDbItemMap;
+    Mutex mDbItemMapMutex;
+
+    // Reference map of all items we know about that have been deleted
+    // but we haven't yet received a deleted notification about.
+    // We need this for when we delete an item (and so don't want it anymore)
+    // but stil need the item around to pass along to the client process with the
+    // deletion notification (if they've registered for such things).
+    DbItemMap mDbDeletedItemMap;
+    Mutex mDbDeletedItemMapMutex;
+
+    // Note on ItemMapMutexes: STL maps are not thread-safe, so you must hold the
+    // mutex for the entire duration of your access/modification to the map.
+    // Otherwise, other processes might interrupt your iterator by adding/removing
+    // items. If you must hold both mutexes, you must take mDbItemMapMutex before
+    // mDbDeletedItemMapMutex.
+
        // True iff we are in the cache of keychains in StorageManager
        bool mInCache;
 
@@ -236,7 +316,12 @@ private:
        DefaultCredentials mCustomUnlockCreds;
        bool mIsInBatchMode;
        EventBuffer *mEventBuffer;
-       Mutex mMutex;
+    mutable Mutex mMutex;
+
+    // Now that we sometimes change the database object, Db object
+    // creation/returning needs a mutex. You should only hold this if you're
+    // copying or changing the mDb object.
+    Mutex mDbMutex;
 };
 
 
@@ -253,6 +338,8 @@ public:
 
 private:
        friend class StorageManager;
+    friend class KeychainImpl;
+    friend class TrustKeychains;
     Keychain(const CssmClient::Db &db)
        : SecPointer<KeychainImpl>(new KeychainImpl(db)) {}