]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_client/cssmclient.h
Security-179.tar.gz
[apple/security.git] / cdsa / cdsa_client / cssmclient.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 // cssmclient - common client interface to CSSM and MDS
21 //
22 #ifndef _H_CDSA_CLIENT_CSSMCLIENT
23 #define _H_CDSA_CLIENT_CSSMCLIENT 1
24
25 #include <Security/utilities.h>
26 #include <Security/threading.h>
27 #include <Security/globalizer.h>
28 #include <Security/cssmalloc.h>
29 #include <Security/refcount.h>
30 #include <map>
31 #include <stdio.h> // debug
32
33 namespace Security
34 {
35
36 namespace CssmClient
37 {
38
39 //
40 // Forward declarations
41 //
42 class Cssm;
43 class Module;
44 class Attachment;
45
46
47 //
48 // An mixin for objects that have (store) GUIDs.
49 // The GUID value is meant to be set-once constant, and can be locked handled accordingly.
50 //
51 class HasGuid {
52 public:
53 HasGuid(const Guid &guid) { mGuid = guid; }
54 HasGuid() { }
55
56 const Guid &guid() const { return mGuid; }
57
58 protected:
59 void setGuid(const Guid &guid) { mGuid = guid; }
60
61 private:
62 Guid mGuid;
63 };
64
65
66 //
67 // Exceptions are based on the CssmError utility class. We add our own class of client-side exceptions.
68 //
69 class Error : public CssmError {
70 public:
71 Error(int err) : CssmError(err) { }
72 CSSM_RETURN cssmError() const;
73 virtual const char *what () const throw();
74
75 enum {
76 objectBusy = -1,
77 };
78 };
79
80
81 //
82 // The CssmObject abstract class models features common to different Cssm objects.
83 // It handles a tree hierarchy of objects (parent/children) safely.
84 //
85 class Object;
86
87 class ObjectImpl : virtual public RefCount
88 {
89 public:
90 explicit ObjectImpl(); // Constructor for Impl objects without a parent.
91 explicit ObjectImpl(const Object &parent);
92 virtual ~ObjectImpl();
93
94 bool isActive() const { return mActive; }
95
96 virtual CssmAllocator &allocator() const;
97 virtual void allocator(CssmAllocator &alloc);
98
99 // Pointer comparison by default. Subclasses may override.
100 virtual bool operator <(const ObjectImpl &other) const;
101 virtual bool operator ==(const ObjectImpl &other) const;
102
103 static void check(CSSM_RETURN status);
104
105 protected:
106 bool mActive; // loaded, attached, etc.
107 mutable CssmAllocator *mAllocator; // allocator hierarchy (NULL => TBD)
108
109 template <class Obj> Obj parent() const
110 { assert(mParent); return Obj(static_cast<typename Obj::Impl *>(&(*mParent))); }
111
112 void addChild();
113 void removeChild();
114 bool isIdle() const { return mChildCount == 0; }
115
116 // {de,}activate() assume you have locked *this
117 virtual void activate() = 0;
118 virtual void deactivate() = 0;
119
120 private:
121 RefPointer<ObjectImpl> mParent; // parent object
122 AtomicCounter<uint32> mChildCount;
123 };
124
125
126 class Object
127 {
128 friend class ObjectImpl;
129 public:
130 typedef ObjectImpl Impl;
131 explicit Object(Impl *impl) : mImpl(impl) {}
132
133 protected:
134 // @@@ CSPDL subclass breaks if the is a static_cast
135 template <class _Impl> _Impl &impl() const
136 { return dynamic_cast<_Impl &>(*mImpl); }
137
138 public:
139 Impl *operator ->() const { return &(*mImpl); }
140 Impl &operator *() const { return *mImpl; }
141
142 // @@@ Why is this needed. DbCursor which inheirits from Object wants to call this.
143 template <class _Impl> _Impl &checkedImpl() const
144 { return dynamic_cast<_Impl &>(*mImpl); }
145
146 bool operator !() const { return !mImpl; }
147 operator bool() const { return mImpl; }
148
149 bool isActive() const { return mImpl && mImpl->isActive(); }
150 CssmAllocator &allocator() const { return mImpl->allocator(); }
151 void release() { mImpl = NULL; }
152
153 bool operator <(const Object &other) const
154 { return mImpl && other.mImpl ? *mImpl < *other.mImpl : mImpl < other.mImpl; }
155 bool operator ==(const Object &other) const
156 { return mImpl && other.mImpl ? *mImpl == *other.mImpl : mImpl == other.mImpl; }
157
158 private:
159 RefPointer<Impl> mImpl;
160 };
161
162
163 //
164 // A CSSM loadable module.
165 // You rarely directly interact with these objects, but if you need to,
166 // here they are.
167 //
168 class ModuleImpl : public ObjectImpl, public HasGuid
169 {
170 public:
171 ModuleImpl(const Guid &guid);
172 ModuleImpl(const Guid &guid, const Cssm &session);
173 virtual ~ModuleImpl();
174
175 void load() { activate(); }
176 void unload() { deactivate(); }
177 bool isLoaded() const { return isActive(); }
178
179 Cssm session() const;
180
181 protected:
182 void activate();
183 void deactivate();
184 };
185
186 class Module : public Object
187 {
188 public:
189 typedef ModuleImpl Impl;
190 explicit Module(Impl *impl) : Object(impl) {}
191 Module() : Object(NULL) {} // XXX This might break operator <
192 Module(const Guid &guid) : Object(new Impl(guid)) {}
193 Module(const Guid &guid, const Cssm &session) : Object(new Impl(guid, session)) {}
194
195 Impl *operator ->() const { return &impl<Impl>(); }
196 Impl &operator *() const { return impl<Impl>(); }
197 };
198
199
200 //
201 // An Attachment object. This is the base class of all typed attachment classes.
202 //
203 class AttachmentImpl : public ObjectImpl
204 {
205 public:
206 AttachmentImpl(const Guid &guid, CSSM_SERVICE_TYPE subserviceType);
207 AttachmentImpl(const Module &module, CSSM_SERVICE_TYPE subserviceType);
208 //AttachmentImpl(... mds reference ...);
209 virtual ~AttachmentImpl();
210
211 // Virtual so that subclasses can return there true mask.
212 virtual CSSM_SERVICE_MASK subserviceMask() const;
213
214 CSSM_SERVICE_TYPE subserviceType() const { return mSubserviceType; }
215 CSSM_VERSION version() const { return mVersion; }
216 void version(const CSSM_VERSION &v) { mVersion = v; }
217 uint32 subserviceId() const { return mSubserviceId; }
218 virtual void subserviceId(uint32 id);
219 CSSM_ATTACH_FLAGS flags() const { return mAttachFlags; }
220 void flags(CSSM_ATTACH_FLAGS f) { mAttachFlags = f; }
221
222 void attach() { activate(); }
223 void detach() { deactivate(); }
224 bool attached() const { return isActive(); }
225
226 Module module() const;
227 const Guid &guid() const { return module()->guid(); }
228 CSSM_MODULE_HANDLE handle() { attach(); return mHandle; }
229
230 CssmSubserviceUid subserviceUid() const;
231
232 protected:
233 void activate();
234 void deactivate();
235
236 private:
237 void make(CSSM_SERVICE_TYPE subserviceType); // common constructor
238
239 CSSM_MODULE_HANDLE mHandle;
240
241 CSSM_SERVICE_TYPE mSubserviceType; // set by constructor
242 CSSM_VERSION mVersion;
243 uint32 mSubserviceId;
244 CSSM_ATTACH_FLAGS mAttachFlags;
245
246 CssmAllocatorMemoryFunctions mMemoryFunctions; // set on attach()
247 };
248
249 class Attachment : public Object
250 {
251 public:
252 typedef AttachmentImpl Impl;
253 explicit Attachment(Impl *impl) : Object(impl) {}
254 Attachment(const Guid &guid, CSSM_SERVICE_TYPE subserviceType)
255 : Object(new Impl(guid, subserviceType)) {}
256 Attachment(const Module &module, CSSM_SERVICE_TYPE subserviceType)
257 : Object(new Impl(module, subserviceType)) {}
258 //Attachment(... mds reference ...);
259
260 Impl *operator ->() const { return &impl<Impl>(); }
261 Impl &operator *() const { return impl<Impl>(); }
262 };
263
264
265 //
266 // A CSSM session object.
267 // You usually only have one per program, or library, or what-not.
268 //
269 class Cssm;
270
271 class CssmImpl : public ObjectImpl {
272 class StandardCssm; friend class StandardCssm;
273 public:
274 CssmImpl();
275 virtual ~CssmImpl();
276
277 void init() { activate(); }
278 void terminate() { deactivate(); }
279
280 CSSM_PRIVILEGE_SCOPE scope() const { return mScope; }
281 void scope(CSSM_PRIVILEGE_SCOPE sc) { mScope = sc; }
282 const Guid &callerGuid() const { return mCallerGuid; }
283 void callerGuid(const CSSM_GUID &guid) { mCallerGuid = Guid::overlay(guid); }
284
285 Module autoModule(const Guid &guid);
286
287 protected:
288 explicit CssmImpl(bool); // internal constructor
289
290 void setup(); // constructor setup
291
292 void activate();
293 void deactivate();
294
295 private:
296 // CSSM global configuration -- picked up on each Init
297 CSSM_VERSION mVersion;
298 CSSM_PRIVILEGE_SCOPE mScope;
299 Guid mCallerGuid;
300
301 // module repository: modules by guid (protected by self)
302 typedef map<Guid, Module> ModuleMap;
303 ModuleMap moduleMap;
304 Mutex mapLock;
305
306 public:
307 static Cssm standard();
308 static void catchExit();
309
310 private:
311 static void atExitHandler();
312
313 class StandardCssm : public Mutex {
314 public:
315 StandardCssm() : mCssm(NULL) { }
316 ~StandardCssm();
317 void setCssm(CssmImpl *cssm);
318 void unsetCssm(CssmImpl *cssm);
319 CssmImpl *get();
320
321 private:
322 CssmImpl *mCssm;
323 };
324 static ModuleNexus<StandardCssm> mStandard;
325 };
326
327 class Cssm : public Object
328 {
329 public:
330 typedef CssmImpl Impl;
331 explicit Cssm(Impl *impl) : Object(impl) {}
332 explicit Cssm() : Object(new Impl()) {}
333
334 Impl *operator ->() const { return &impl<Impl>(); }
335 Impl &operator *() const { return impl<Impl>(); }
336
337 static Cssm standard() { return CssmImpl::standard(); }
338 };
339
340 } // end namespace CssmClient
341
342 } // end namespace Security
343
344 #endif // _H_CDSA_CLIENT_CSSMCLIENT