]> git.saurik.com Git - apple/security.git/blob - SecurityServer/xdatabase.h
Security-164.1.tar.gz
[apple/security.git] / SecurityServer / xdatabase.h
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 // database - database session management
21 //
22 #ifndef _H_DATABASE
23 #define _H_DATABASE
24
25 #include "securityserver.h"
26 #include "acls.h"
27 #include "dbcrypto.h"
28 #include "notifications.h"
29 #include <Security/utilities.h>
30 #include <Security/handleobject.h>
31 #include <Security/cssmdb.h>
32 #include <Security/machserver.h>
33 #include "SecurityAgentClient.h"
34 #include <Security/timeflow.h>
35 #include <string>
36 #include <map>
37
38
39 class Key;
40 class Connection;
41 class Process;
42 using MachPlusPlus::MachServer;
43
44
45 //
46 // A Database object represents an Apple CSP/DL open database (DL/DB) object.
47 // It maintains its protected semantic state (including keys) and provides controlled
48 // access.
49 //
50 class Database : public HandleObject, public SecurityServerAcl {
51 static const Listener::Event lockedEvent = Listener::lockedEvent;
52 static const Listener::Event unlockedEvent = Listener::unlockedEvent;
53 static const Listener::Event passphraseChangedEvent = Listener::passphraseChangedEvent;
54
55 public:
56 class Common; friend class Common;
57
58 Database(const DLDbIdentifier &id, const DBParameters &params, Process &proc,
59 const AccessCredentials *cred, const AclEntryPrototype *owner);
60 virtual ~Database();
61
62 Process &process;
63
64 static const int maxUnlockTryCount = 3;
65
66 public:
67 typedef DbBlob::Signature Signature;
68
69 class DbIdentifier {
70 public:
71 DbIdentifier(const DLDbIdentifier &id, Signature sig)
72 : mIdent(id), mSig(sig) { }
73
74 operator const DLDbIdentifier &() const { return mIdent; }
75 operator const Signature &() const { return mSig; }
76 const char *dbName() const { return mIdent.dbName(); }
77
78 bool operator < (const DbIdentifier &id) const // simple lexicographic
79 {
80 if (mIdent < id.mIdent) return true;
81 if (id.mIdent < mIdent) return false;
82 return mSig < id.mSig;
83 }
84
85 private:
86 DLDbIdentifier mIdent;
87 Signature mSig;
88 };
89
90 public:
91 class CommonMap : public map<DbIdentifier, Common *>, public Mutex {
92 };
93
94 public:
95 //
96 // A Database::Common is the "common core" of all Database objects that
97 // represent the same client database (on disk, presumably).
98 // NOTE: Common obeys exterior locking protocol: the caller (always Database)
99 // must lock it before operating on its non-const members. In practice,
100 // most Database methods lock down their Common first thing.
101 //
102 class Common : public DatabaseCryptoCore, public MachServer::Timer, public Mutex {
103 public:
104 Common(const DbIdentifier &id, CommonMap &pool);
105 ~Common();
106
107 bool unlock(DbBlob *blob, void **privateAclBlob = NULL);
108 void lock(bool holdingCommonLock, bool forSleep = false); // versatile lock primitive
109 bool isLocked() const { return mIsLocked; } // lock status
110 void activity(); // reset lock timeout
111
112 void makeNewSecrets();
113
114 const DbIdentifier &identifier() const {return mIdentifier; }
115 const DLDbIdentifier &dlDbIdent() const { return identifier(); }
116 const char *dbName() const { return dlDbIdent().dbName(); }
117
118 DbBlob *encode(Database &db);
119
120 protected:
121 void action(); // timer queue action to lock keychain
122
123 public:
124 CommonMap &pool; // the CommonMap we belong to
125
126 DbIdentifier mIdentifier; // database external identifier [const]
127 // all following data locked with object lock
128 uint32 sequence; // change sequence number
129 DBParameters mParams; // database parameters (arbitrated copy)
130
131 uint32 useCount; // database sessions we belong to
132 uint32 version; // version stamp for change tracking
133
134 private:
135 bool mIsLocked; // database is LOGICALLY locked
136 bool mValidParams; // mParams has been set
137 };
138
139 const DbIdentifier &identifier() const { return common->identifier(); }
140 const char *dbName() const { return common->dbName(); }
141
142 public:
143 // encoding/decoding databases
144 DbBlob *blob();
145 Database(const DLDbIdentifier &id, const DbBlob *blob, Process &proc,
146 const AccessCredentials *cred);
147 void authenticate(const AccessCredentials *cred);
148 void changePassphrase(const AccessCredentials *cred);
149 Key *extractMasterKey(Database *db,
150 const AccessCredentials *cred, const AclEntryPrototype *owner,
151 uint32 usage, uint32 attrs);
152 void getDbIndex(CssmData &indexData);
153
154 // lock/unlock processing
155 void lock(); // unconditional lock
156 void unlock(); // full-feature unlock
157 void unlock(const CssmData &passphrase); // unlock with passphrase
158
159 bool decode(); // unlock given established master key
160 bool decode(const CssmData &passphrase); // set master key from PP, try unlock
161
162 bool validatePassphrase(const CssmData &passphrase) const; // nonthrowing validation
163 bool isLocked() const { return common->isLocked(); } // lock status
164
165 void activity() const { common->activity(); } // reset timeout clock
166 static void lockAllDatabases(CommonMap &commons, bool forSleep = false); // lock all in session
167
168 // encoding/decoding keys
169 void decodeKey(KeyBlob *blob, CssmKey &key, void * &pubAcl, void * &privAcl);
170 KeyBlob *encodeKey(const CssmKey &key, const CssmData &pubAcl, const CssmData &privAcl);
171
172 bool validBlob() const { return mBlob && version == common->version; }
173
174 // manage database parameters
175 void setParameters(const DBParameters &params);
176 void getParameters(DBParameters &params);
177
178 // ACL state management hooks
179 void instantiateAcl();
180 void changedAcl();
181 const Database *relatedDatabase() const; // "self", for SecurityServerAcl's sake
182
183 // debugging
184 IFDUMP(void debugDump(const char *msg));
185
186 protected:
187 void makeUnlocked(); // interior version of unlock()
188 void makeUnlocked(const AccessCredentials *cred); // like () with explicit cred
189 void makeUnlocked(const CssmData &passphrase); // interior version of unlock(CssmData)
190
191 void establishOldSecrets(const AccessCredentials *creds);
192 void establishNewSecrets(const AccessCredentials *creds, SecurityAgent::Reason reason);
193
194 static CssmClient::Key keyFromCreds(const TypedList &sample);
195
196 void encode(); // (re)generate mBlob if needed
197
198 static void discard(Common *common); // safely kill a Common
199
200 private:
201 Common *common; // shared features of all instances of this database [const]
202
203 // all following data is locked by the common lock
204 bool mValidData; // valid ACL and params (blob decoded)
205
206 uint32 version; // version stamp for blob validity
207 DbBlob *mBlob; // database blob (encoded)
208
209 AccessCredentials *mCred; // local access credentials (always valid)
210 };
211
212
213 //
214 // This class implements a "system keychaiin unlock record" store
215 //
216 class SystemKeychainKey {
217 public:
218 SystemKeychainKey(const char *path);
219 ~SystemKeychainKey();
220
221 bool matches(const DbBlob::Signature &signature);
222 CssmKey &key() { return mKey; }
223
224 private:
225 std::string mPath; // path to file
226 CssmKey mKey; // proper CssmKey with data in mBlob
227
228 bool mValid; // mBlob was validly read from mPath
229 UnlockBlob mBlob; // contents of mPath as last read
230
231 Time::Absolute mCachedDate; // modify date of file when last read
232 Time::Absolute mUpdateThreshold; // cutoff threshold for checking again
233
234 static const int checkDelay = 1; // seconds minimum delay between update checks
235
236 bool update();
237 };
238
239 #endif //_H_DATABASE