]> git.saurik.com Git - apple/security.git/blob - SecurityServer/xdatabase.h
Security-54.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 <time.h>
34 #include <string>
35 #include <map>
36
37
38 class Key;
39 class Connection;
40 class Process;
41 using MachPlusPlus::MachServer;
42
43
44 //
45 // A Database object represents an Apple CSP/DL open database (DL/DB) object.
46 // It maintains its protected semantic state (including keys) and provides controlled
47 // access.
48 //
49 class Database : public HandleObject, public SecurityServerAcl {
50 static const Listener::Event lockedEvent = Listener::lockedEvent;
51 static const Listener::Event unlockedEvent = Listener::unlockedEvent;
52 static const Listener::Event passphraseChangedEvent = Listener::passphraseChangedEvent;
53
54 public:
55 class Common; friend class Common;
56
57 Database(const DLDbIdentifier &id, const DBParameters &params, Process &proc,
58 const AccessCredentials *cred, const AclEntryPrototype *owner);
59 virtual ~Database();
60
61 Process &process;
62
63 static const int maxUnlockTryCount = 3;
64
65 public:
66 typedef DbBlob::Signature Signature;
67
68 class DbIdentifier {
69 public:
70 DbIdentifier(const DLDbIdentifier &id, Signature sig)
71 : mIdent(id), mSig(sig) { }
72
73 operator const DLDbIdentifier &() const { return mIdent; }
74 operator const Signature &() const { return mSig; }
75 const char *dbName() const { return mIdent.dbName(); }
76
77 bool operator < (const DbIdentifier &id) const // simple lexicographic
78 {
79 if (mIdent < id.mIdent) return true;
80 if (id.mIdent < mIdent) return false;
81 return mSig < id.mSig;
82 }
83
84 private:
85 DLDbIdentifier mIdent;
86 Signature mSig;
87 };
88
89 public:
90 //
91 // A Database::Common is the "common core" of all Database objects that
92 // represent the same client database (on disk, presumably).
93 // NOTE: Common obeys exterior locking protocol: the caller (always Database)
94 // must lock it before operating on its non-const members. In practice,
95 // most Database methods lock down their Common first thing.
96 //
97 class Common : public DatabaseCryptoCore, public MachServer::Timer, public Mutex {
98 public:
99 Common(const DbIdentifier &id);
100 ~Common();
101
102 bool unlock(DbBlob *blob, const CssmData &passphrase,
103 void **privateAclBlob = NULL);
104 bool unlock(const CssmData &passphrase);
105 void lock(bool holdingCommonLock = false, bool forSleep = false); // versatile lock primitive
106 bool isLocked() const { return mIsLocked; } // lock status
107 void activity(); // reset lock timeout
108
109 const DbIdentifier &identifier() const {return mIdentifier; }
110 const DLDbIdentifier &dlDbIdent() const { return identifier(); }
111 const char *dbName() const { return dlDbIdent().dbName(); }
112
113 DbBlob *encode(Database &db);
114 void setupKeys(const AccessCredentials *cred);
115
116 void notify(Listener::Event event);
117
118 protected:
119 void action(); // timer queue action to lock keychain
120
121 public:
122 DbIdentifier mIdentifier; // database external identifier [const]
123 // all following data locked with object lock
124 uint32 sequence; // change sequence number
125 DBParameters mParams; // database parameters (arbitrated copy)
126
127 CssmAutoData passphrase; // passphrase if available, or NULL data
128
129 uint32 useCount; // database sessions we belong to
130 uint32 version; // version stamp for change tracking
131
132 private:
133 bool mIsLocked; // database is LOGICALLY locked
134 };
135
136 const DbIdentifier &identifier() const { return common->identifier(); }
137 const char *dbName() const { return common->dbName(); }
138
139 public:
140 // encoding/decoding databases
141 DbBlob *encode();
142 Database(const DLDbIdentifier &id, const DbBlob *blob, Process &proc,
143 const AccessCredentials *cred);
144 void authenticate(const AccessCredentials *cred);
145 void changePassphrase(const AccessCredentials *cred);
146
147 // lock/unlock processing
148 void lock(); // unconditional lock
149 void unlock(); // full-feature unlock
150 void unlock(const CssmData &passphrase); // unlock with passphrase
151 bool decode(const CssmData &passphrase); // try unlock/don't fail
152 bool validatePassphrase(const CssmData &passphrase) const; // validate passphrase (no status change)
153 bool isLocked() const { return common->isLocked(); } // lock status
154
155 void activity() const { common->activity(); } // reset timeout clock
156 static void lockAllDatabases(bool forSleep = false); // lock them all
157
158 // encoding/decoding keys
159 void decodeKey(KeyBlob *blob, CssmKey &key, void * &pubAcl, void * &privAcl);
160 KeyBlob *encodeKey(const CssmKey &key, const CssmData &pubAcl, const CssmData &privAcl);
161
162 bool validBlob() const { return mBlob && version == common->version; }
163
164 // manage database parameters
165 void setParameters(const DBParameters &params);
166 void getParameters(DBParameters &params);
167
168 // ACL state management hooks
169 void instantiateAcl();
170 void noticeAclChange();
171 const Database *relatedDatabase() const; // "self", for SecurityServerAcl's sake
172
173 // notifications
174 void notify(Listener::Event event) { common->notify(event); }
175
176 // debugging
177 IFDUMP(void debugDump(const char *msg));
178
179 protected:
180 void makeUnlocked(); // interior version of unlock()
181 void makeUnlocked(const CssmData &passphrase); // interior version of unlock(CssmData)
182 static void discard(Common *common);
183
184 private:
185 Common *common; // shared features of all instances of this database [const]
186
187 // all following data is locked by the common lock
188 bool mValidData; // valid ACL and params (blob decoded)
189
190 uint32 version; // version stamp for blob validity
191 DbBlob *mBlob; // database blob (encoded)
192
193 AccessCredentials *mCred; // local access credentials (always valid)
194
195 private:
196 // @@@ Arguably, this should be a member of the Server or Session.
197 // @@@ If we do this, encapsulate it as a DatabaseMap object of sorts.
198 static Mutex commonLock; // lock for commons map (only)
199 typedef map<DbIdentifier, Common *> CommonMap;
200 static CommonMap commons; // map of extant database objects
201 };
202
203
204 #endif //_H_DATABASE