/ OSX / libsecurity_keychain / lib / StorageManager.h
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_