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