StorageManager.h
1 /* 2 * Copyright (c) 2000-2012 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 // StorageManager.h -- Working with multiple keychains 27 // 28 #ifndef _SECURITY_STORAGEMANAGER_H_ 29 #define _SECURITY_STORAGEMANAGER_H_ 30 31 #include <list> 32 #include <set> 33 #include <security_keychain/DLDBListCFPref.h> 34 #include <security_keychain/DynamicDLDBList.h> 35 #include <security_keychain/Keychains.h> 36 #include <security_keychain/KeyItem.h> 37 #include <Security/Authorization.h> 38 39 #define kLegacyKeychainRenamedSuffix "_renamed" 40 #define kKeychainRenamedSuffix "_renamed_" 41 42 namespace Security 43 { 44 45 namespace KeychainCore 46 { 47 48 class StorageManager 49 { 50 NOCOPY(StorageManager) 51 public: 52 typedef vector<Keychain> KeychainList; 53 typedef vector<DLDbIdentifier> DLDbList; 54 55 StorageManager(); 56 ~StorageManager() {} 57 58 Mutex* getStorageManagerMutex(); 59 60 //bool onlist(const Keychain & keychain); 61 62 // These will call addAndNotify() if the specified keychain already exists 63 Keychain make(const char *fullPathName); 64 Keychain make(const char *fullPathName, bool add); 65 Keychain make(const char *fullPathName, bool add, bool isReset); 66 Keychain makeLoginAuthUI(const Item *item, bool isReset); 67 void created(const Keychain &keychain); // Be notified a Keychain just got created. 68 69 // Misc 70 void lockAll(); 71 72 void add(const Keychain& keychainToAdd); // Only add if not there yet. Doesn't write out CFPref 73 74 // Vector-like methods. 75 size_t size(); 76 Keychain at(unsigned int ix); 77 Keychain operator[](unsigned int ix); 78 79 KCCursor createCursor(const SecKeychainAttributeList *attrList); 80 KCCursor createCursor(SecItemClass itemClass, const SecKeychainAttributeList *attrList); 81 82 // Lookup a keychain object in the cache. If it doesn't exist, create a 83 // new one and add to cache. Doesn't modify search lists. 84 // Note this doesn't create an actual database just a reference to one 85 // that may or may not exist. 86 Keychain keychain(const DLDbIdentifier &dLDbIdentifier); 87 88 // Remove a keychain from the cache if it's in it. 89 void removeKeychain(const DLDbIdentifier &dLDbIdentifier, KeychainImpl *keychainImpl); 90 // Be notified a (smart card) keychain was removed. 91 void didRemoveKeychain(const DLDbIdentifier &dLDbIdentifier); 92 93 // Create KC if it doesn't exist, add it to the search list if it exists and is not already on it. 94 Keychain makeKeychain(const DLDbIdentifier &dLDbIdentifier, bool add, bool isReset); 95 96 // Reload a keychain from the on-disk database 97 void reloadKeychain(Keychain keychain); 98 99 // Register a keychain in the keychain cache 100 void registerKeychain(Keychain& kc); 101 void registerKeychainImpl(KeychainImpl* kc); 102 103 // Keychain list maintenance 104 105 // remove kcsToRemove from the search list 106 void remove(const KeychainList &kcsToRemove, bool deleteDb = false); 107 108 void getSearchList(KeychainList &keychainList); 109 void setSearchList(const KeychainList &keychainList); 110 void forceUserSearchListReread (); 111 112 void getSearchList(SecPreferencesDomain domain, KeychainList &keychainList); 113 void setSearchList(SecPreferencesDomain domain, const KeychainList &keychainList); 114 115 void rename(Keychain keychain, const char* newName); 116 void renameUnique(Keychain keychain, CFStringRef oldName, CFStringRef newName, bool appendDbSuffix); 117 118 // Iff keychainOrArray is NULL return the default KeychainList in keychainList otherwise 119 // if keychainOrArray is a CFArrayRef containing SecKeychainRef's convernt it to KeychainList, 120 // if keychainOrArray is a SecKeychainRef return a KeychainList with one element. 121 void optionalSearchList(CFTypeRef keychainOrArray, KeychainList &keychainList); 122 123 // Convert CFArrayRef of SecKeychainRef's a KeychainList. The array must not be NULL 124 static void convertToKeychainList(CFArrayRef keychainArray, KeychainList &keychainList); 125 126 // Convert KeychainList to a CFArrayRef of SecKeychainRef's. 127 static CFArrayRef convertFromKeychainList(const KeychainList &keychainList); 128 129 // Login keychain support 130 void login(AuthorizationRef authRef, UInt32 nameLength, const char* name, bool isReset); 131 void login(ConstStringPtr name, ConstStringPtr password); 132 void login(UInt32 nameLength, const void *name, UInt32 passwordLength, const void *password, bool isReset); 133 void stashLogin(); 134 void stashKeychain(); 135 void logout(); 136 void changeLoginPassword(ConstStringPtr oldPassword, ConstStringPtr newPassword); 137 void changeLoginPassword(UInt32 oldPasswordLength, const void *oldPassword, UInt32 newPasswordLength, const void *newPassword); 138 139 // Token login support 140 CFDataRef getTokenLoginMasterKey(UInt32 passwordLength, const void *password); 141 CFDataRef unwrapTokenLoginMasterKey(CFDictionaryRef masterKeyData, CFStringRef tokenID, CFStringRef pin); 142 143 void resetKeychain(Boolean resetSearchList); 144 145 Keychain defaultKeychain(); 146 Keychain defaultKeychainUI(Item &item); 147 void defaultKeychain(const Keychain &keychain); 148 149 Keychain loginKeychain(); 150 DLDbIdentifier loginKeychainDLDbIdentifer(); 151 152 void loginKeychain(Keychain keychain); 153 154 Keychain defaultKeychain(SecPreferencesDomain domain); 155 void defaultKeychain(SecPreferencesDomain domain, const Keychain &keychain); 156 157 SecPreferencesDomain domain() { return mDomain; } 158 void domain(SecPreferencesDomain newDomain); 159 160 bool keychainOwnerPermissionsValidForDomain(const char* path, SecPreferencesDomain domain); 161 162 // non-file based Keychain manipulation 163 void addToDomainList(SecPreferencesDomain domain, const char* dbName, const CSSM_GUID &guid, uint32 subServiceType); 164 void isInDomainList(SecPreferencesDomain domain, const char* dbName, const CSSM_GUID &guid, uint32 subServiceType); 165 void removeFromDomainList(SecPreferencesDomain domain, const char* dbName, const CSSM_GUID &guid, uint32 subServiceType); 166 167 private: 168 static void convertList(DLDbList &ids, const KeychainList &kcs); 169 void convertList(KeychainList &kcs, const DLDbList &ids); 170 171 DLDbIdentifier makeDLDbIdentifier(const char* pathName); 172 CssmClient::Db makeDb(DLDbIdentifier dLDbIdentifier); 173 174 // Use this when you want to be extra sure this keychain is removed from the 175 // cache. Iterates over the whole cache to find all instances. This function 176 // will take the cache map mutex. 177 void forceRemoveFromCache(KeychainImpl* inItemImpl); 178 179 public: 180 // Change the DLDBIdentifier to reflect the files on-disk. Currently: 181 // If the keychain is in ~/Library/Keychains and either 182 // the .keychain-db version of the file exists or 183 // (global integrity protection is on AND isReset is true) 184 // then change the filename to include ".keychain-db". 185 // 186 // Otherwise, leave it alone. 187 static DLDbIdentifier mungeDLDbIdentifier(const DLDbIdentifier& dLDbIdentifier, bool isReset); 188 189 // Change the DLDbIdentifier to always use the pattern ending with "-db". 190 static DLDbIdentifier forceMungeDLDbIDentifier(const DLDbIdentifier& dLDbIdentifier); 191 192 // Due to compatibility requirements, we need the DLDbListCFPref lists to 193 // never see a ".keychain-db" filename. Call this function to give them what 194 // they need. 195 static DLDbIdentifier demungeDLDbIdentifier(const DLDbIdentifier& dLDbIdentifier); 196 197 // Take a filename, and give it the extension .keychain-db 198 static string makeKeychainDbFilename(const string& filename); 199 200 // Check if a keychain path is in some user's ~/Library/Keychains/ folder. 201 static bool pathInHomeLibraryKeychains(const string& path); 202 203 // Notify the StorageManager that you're accessing this keychain. Used for 204 // time-based caching purposes. 205 void tickleKeychain(KeychainImpl *keychainImpl); 206 207 private: 208 // Only add if not there yet. Writes out CFPref and broadcasts KCPrefListChanged notification 209 void addAndNotify(const Keychain& keychainToAdd); 210 211 // remove a keychain from the sync list 212 void removeKeychainFromSyncList (const DLDbIdentifier &id); 213 214 typedef map<DLDbIdentifier, KeychainImpl *> KeychainMap; 215 // Reference map of all keychains we know about that aren't deleted 216 // or removed 217 KeychainMap mKeychainMap; 218 219 // The dynamic search list. 220 DynamicDLDBList mDynamicList; 221 222 DLDbListCFPref mSavedList; 223 DLDbListCFPref mCommonList; 224 SecPreferencesDomain mDomain; // current domain (in mSavedList and cache fields) 225 Mutex mMutex; 226 RecursiveMutex mKeychainMapMutex; 227 }; 228 229 } // end namespace KeychainCore 230 231 } // end namespace Security 232 233 #endif // !_SECURITY_STORAGEMANAGER_H_