]> git.saurik.com Git - apple/security.git/blob - libsecurity_cdsa_client/lib/cssmclient.h
43fb3141c717617b82a94d1858ac8a9fa001289b
[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
101 protected:
102 bool mActive; // loaded, attached, etc.
103 RecursiveMutex mActivateMutex;
104 mutable Allocator *mAllocator; // allocator hierarchy (NULL => TBD)
105
106 template <class Obj> Obj parent() const
107 { assert(mParent); return Obj(static_cast<typename Obj::Impl *>(&(*mParent))); }
108
109 void addChild();
110 void removeChild();
111 bool isIdle() const { return mChildCount == 0; }
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 private:
156 RefPointer<Impl> mImpl;
157 };
158
159
160 //
161 // Event callback mix-in class
162 //
163 class ModuleImpl;
164
165 class RawModuleEvents {
166 friend class ModuleImpl;
167 public:
168 virtual ~RawModuleEvents();
169
170 virtual void notify(uint32 subService,
171 CSSM_SERVICE_TYPE type, CSSM_MODULE_EVENT event) = 0;
172
173 private:
174 static CSSM_RETURN sendNotify(const CSSM_GUID *, void *context, uint32 subService,
175 CSSM_SERVICE_TYPE type, CSSM_MODULE_EVENT event);
176 };
177
178 class ModuleEvents : public RawModuleEvents {
179 public:
180 virtual void insertion(uint32 subService, CSSM_SERVICE_TYPE type);
181 virtual void removal(uint32 subService, CSSM_SERVICE_TYPE type);
182 virtual void fault(uint32 subService, CSSM_SERVICE_TYPE type);
183
184 protected:
185 void notify(uint32 subService, CSSM_SERVICE_TYPE type, CSSM_MODULE_EVENT event);
186 };
187
188
189 //
190 // A CSSM loadable module.
191 // You rarely directly interact with these objects, but if you need to,
192 // here they are.
193 //
194 class ModuleImpl : public ObjectImpl, public HasGuid
195 {
196 public:
197 ModuleImpl(const Guid &guid);
198 ModuleImpl(const Guid &guid, const Cssm &session);
199 virtual ~ModuleImpl();
200
201 void load() { activate(); }
202 void unload() { deactivate(); }
203 bool isLoaded() const { return isActive(); }
204
205 Cssm session() const;
206
207 void appNotifyCallback(CSSM_API_ModuleEventHandler appNotifyCallback, void *appNotifyCallbackCtx);
208 void appNotifyCallback(RawModuleEvents *handler);
209
210 protected:
211 void activate();
212 void deactivate();
213
214 CSSM_API_ModuleEventHandler mAppNotifyCallback;
215 void *mAppNotifyCallbackCtx;
216 };
217
218 class Module : public Object
219 {
220 public:
221 typedef ModuleImpl Impl;
222 explicit Module(Impl *impl) : Object(impl) {}
223 Module() : Object(NULL) {} // XXX This might break operator <
224 Module(const Guid &guid) : Object(new Impl(guid)) {}
225 Module(const Guid &guid, const Cssm &session) : Object(new Impl(guid, session)) {}
226
227 Impl *operator ->() const { return &impl<Impl>(); }
228 Impl &operator *() const { return impl<Impl>(); }
229 };
230
231
232 //
233 // An Attachment object. This is the base class of all typed attachment classes.
234 //
235 class AttachmentImpl : public ObjectImpl
236 {
237 public:
238 AttachmentImpl(const Guid &guid, CSSM_SERVICE_TYPE subserviceType);
239 AttachmentImpl(const Module &module, CSSM_SERVICE_TYPE subserviceType);
240 //AttachmentImpl(... mds reference ...);
241 virtual ~AttachmentImpl();
242
243 // Virtual so that subclasses can return there true mask.
244 virtual CSSM_SERVICE_MASK subserviceMask() const;
245
246 CSSM_SERVICE_TYPE subserviceType() const { return mSubserviceType; }
247 CSSM_VERSION version() const { return mVersion; }
248 void version(const CSSM_VERSION &v) { mVersion = v; }
249 uint32 subserviceId() const { return mSubserviceId; }
250 virtual void subserviceId(uint32 id);
251 CSSM_ATTACH_FLAGS flags() const { return mAttachFlags; }
252 void flags(CSSM_ATTACH_FLAGS f) { mAttachFlags = f; }
253
254 void attach() { activate(); }
255 void detach() { deactivate(); }
256 bool attached() const { return isActive(); }
257
258 Module module() const;
259 const Guid &guid() const { return module()->guid(); }
260 CSSM_MODULE_HANDLE handle() { attach(); return mHandle; }
261
262 CssmSubserviceUid subserviceUid() const;
263
264 protected:
265 void activate();
266 void deactivate();
267
268 private:
269 void make(CSSM_SERVICE_TYPE subserviceType); // common constructor
270
271 CSSM_MODULE_HANDLE mHandle;
272
273 CSSM_SERVICE_TYPE mSubserviceType; // set by constructor
274 CSSM_VERSION mVersion;
275 uint32 mSubserviceId;
276 CSSM_ATTACH_FLAGS mAttachFlags;
277
278 CssmAllocatorMemoryFunctions mMemoryFunctions; // set on attach()
279 };
280
281 class Attachment : public Object
282 {
283 public:
284 typedef AttachmentImpl Impl;
285 explicit Attachment(Impl *impl) : Object(impl) {}
286 Attachment(const Guid &guid, CSSM_SERVICE_TYPE subserviceType)
287 : Object(new Impl(guid, subserviceType)) {}
288 Attachment(const Module &module, CSSM_SERVICE_TYPE subserviceType)
289 : Object(new Impl(module, subserviceType)) {}
290 //Attachment(... mds reference ...);
291
292 Impl *operator ->() const { return &impl<Impl>(); }
293 Impl &operator *() const { return impl<Impl>(); }
294 };
295
296
297 //
298 // A CSSM session object.
299 // You usually only have one per program, or library, or what-not.
300 //
301 class Cssm;
302
303 class CssmImpl : public ObjectImpl {
304 class StandardCssm; friend class StandardCssm;
305 public:
306 CssmImpl();
307 virtual ~CssmImpl();
308
309 void init() { activate(); }
310 void terminate() { deactivate(); }
311
312 CSSM_PRIVILEGE_SCOPE scope() const { return mScope; }
313 void scope(CSSM_PRIVILEGE_SCOPE sc) { mScope = sc; }
314 const Guid &callerGuid() const { return mCallerGuid; }
315 void callerGuid(const CSSM_GUID &guid) { mCallerGuid = Guid::overlay(guid); }
316
317 Module autoModule(const Guid &guid);
318
319 protected:
320 explicit CssmImpl(bool); // internal constructor
321
322 void setup(); // constructor setup
323
324 void activate();
325 void deactivate();
326
327 private:
328 // CSSM global configuration -- picked up on each Init
329 CSSM_VERSION mVersion;
330 CSSM_PRIVILEGE_SCOPE mScope;
331 Guid mCallerGuid;
332
333 // module repository: modules by guid (protected by self)
334 typedef map<Guid, Module> ModuleMap;
335 ModuleMap moduleMap;
336 Mutex mapLock;
337
338 public:
339 static Cssm standard();
340 static void catchExit();
341
342 private:
343 static void atExitHandler();
344
345 class StandardCssm : public Mutex {
346 public:
347 StandardCssm() : mCssm(NULL) { }
348 ~StandardCssm();
349 void setCssm(CssmImpl *cssm);
350 void unsetCssm(CssmImpl *cssm);
351 CssmImpl *get();
352
353 private:
354 CssmImpl *mCssm;
355 };
356 static ModuleNexus<StandardCssm> mStandard;
357 };
358
359 class Cssm : public Object
360 {
361 public:
362 typedef CssmImpl Impl;
363 explicit Cssm(Impl *impl) : Object(impl) {}
364 explicit Cssm() : Object(new Impl()) {}
365
366 Impl *operator ->() const { return &impl<Impl>(); }
367 Impl &operator *() const { return impl<Impl>(); }
368
369 static Cssm standard() { return CssmImpl::standard(); }
370 };
371
372 } // end namespace CssmClient
373
374 } // end namespace Security
375
376 #endif // _H_CDSA_CLIENT_CSSMCLIENT