2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 // cssmclient - common client interface to CSSM and MDS.
22 // Locking Strategy (preliminary):
23 // XXX This is obsolete update this --mb
24 // A CssmObject is a CountingMutex. Its count represents the number of children that have registered
25 // themselves (using addChild/removeChild). The lock controls the internal management fields of the
26 // various subclasses to protect them against corruption. It does NOT control attribute and argument
27 // fields and operations, not does it control object-constant fields.
28 // This means that if you use an object from multiple threads, you (the caller) must lock the object
29 // during set/get calls of attributes. Note that the CSSM operations themselves are safely multithreaded
30 // and thus don't need to be interlocked explicitly.
32 #include <Security/cssmclient.h>
33 #include <Security/cssmerrno.h>
36 using namespace CssmClient
;
42 Error::cssmError() const
44 //@@@ munge in client-side error codes here?
45 return CssmError::cssmError();
49 Error::what () const throw()
51 return "CSSM client library error";
59 ObjectImpl::check(CSSM_RETURN status
)
61 if (status
!= CSSM_OK
)
63 CssmError::throwMe(status
);
69 // Common features of Objects
71 ObjectImpl::ObjectImpl() : mParent(), mChildCount(0)
73 mActive
= false; // not activated
74 mAllocator
= NULL
; // allocator to be determined
77 ObjectImpl::ObjectImpl(const Object
&mommy
) : mParent(mommy
.mImpl
), mChildCount(0)
79 mActive
= false; // not activated
80 mAllocator
= NULL
; // allocator to be determined
85 ObjectImpl::~ObjectImpl()
87 assert(!mActive
); // subclass must have deactivated us
89 Error::throwMe(Error::objectBusy
);
91 // release parent from her obligations (if we still have one)
93 mParent
->removeChild();
97 ObjectImpl::addChild()
99 mChildCount
++; // atomic
103 ObjectImpl::removeChild()
105 mChildCount
--; // atomic
110 // Manage allocators in the Object tree
113 ObjectImpl::allocator() const
115 if (mAllocator
== NULL
)
119 mAllocator
= &mParent
->allocator();
121 mAllocator
= &CssmAllocator::standard();
128 ObjectImpl::allocator(CssmAllocator
&alloc
)
130 assert(mAllocator
== NULL
); // cannot redefine allocator once set
134 // Comparison operators use pointer comparison by default. Subclasses may override.
136 ObjectImpl::operator <(const ObjectImpl
&other
) const
138 return this < &other
;
142 ObjectImpl::operator ==(const ObjectImpl
&other
) const
144 return this == &other
;
149 // CSSMSession objects.
150 // parent ::= NULL (none)
151 // active ::= CSSM initialized
153 ModuleNexus
<CssmImpl::StandardCssm
> CssmImpl::mStandard
;
155 CssmImpl::CssmImpl() : ObjectImpl()
158 mStandard().setCssm(this);
161 CssmImpl::CssmImpl(bool) : ObjectImpl()
164 // implicitly constructed - caller responsible for standard session management
167 CssmImpl::~CssmImpl()
175 // this may be the standard session...
176 mStandard().unsetCssm(this);
183 // set default configuration
186 mScope
= CSSM_PRIVILEGE_SCOPE_PROCESS
;
193 return Cssm(mStandard().get());
202 // currently, no choices on PVC mode and key hierarchy
203 CSSM_PVC_MODE pvc
= CSSM_PVC_NONE
;
204 switch (CSSM_RETURN rc
= CSSM_Init(&mVersion
,
205 mScope
, &mCallerGuid
,
206 CSSM_KEY_HIERARCHY_NONE
, &pvc
, NULL
)) {
207 case CSSMERR_CSSM_PVC_ALREADY_CONFIGURED
:
218 CssmImpl::deactivate()
224 // clear module map (all gone now)
225 moduleMap
.erase(moduleMap
.begin(), moduleMap
.end());
227 // now terminate CSSM
228 check(CSSM_Terminate());
233 CssmImpl::atExitHandler()
242 CssmImpl::catchExit()
244 // @@@ Even though this is the "right thing" to do. This only causes
245 // exceptions during exit and doesn't really help cleanup correctly.
247 if (::atexit(atExitHandler
))
248 UnixError::throwMe();
254 // Manage the automatic Cssm object.
255 // This is a program global.
257 void CssmImpl::StandardCssm::setCssm(CssmImpl
*cssm
)
259 StLock
<Mutex
> _(*this);
264 void CssmImpl::StandardCssm::unsetCssm(CssmImpl
*cssm
)
266 StLock
<Mutex
> _(*this);
271 CssmImpl
*CssmImpl::StandardCssm::get()
273 StLock
<Mutex
> _(*this);
274 if (mCssm
== NULL
) { // make the default instance
275 mCssm
= new CssmImpl(true);
280 CssmImpl::StandardCssm::~StandardCssm()
290 // Auto-module management
293 CssmImpl::autoModule(const Guid
&guid
)
295 StLock
<Mutex
> _(mapLock
);
296 ModuleMap::iterator it
= moduleMap
.find(guid
);
297 if (it
== moduleMap
.end())
299 // no automodule for this guid yet, create one
300 Module
module(guid
, Cssm(this));
301 moduleMap
.insert(ModuleMap::value_type(guid
, module));
306 // existing automodule - use it
314 // parent ::= the session object (usually Cssm::standard)
315 // active ::= module is loaded.
317 ModuleImpl::ModuleImpl(const Guid
&guid
) : ObjectImpl(Cssm::standard())
322 ModuleImpl::ModuleImpl(const Guid
&guid
, const Cssm
&session
) : ObjectImpl(session
)
327 ModuleImpl::~ModuleImpl()
334 ModuleImpl::activate()
339 // @@@ install handler here (use central dispatch with override)
340 check(CSSM_ModuleLoad(&guid(), CSSM_KEY_HIERARCHY_NONE
, NULL
, NULL
));
342 session()->catchExit();
347 ModuleImpl::deactivate()
350 Error::throwMe(Error::objectBusy
);
354 check(CSSM_ModuleUnload(&guid(), NULL
, NULL
));
359 ModuleImpl::session() const
361 return parent
<Cssm
>();
366 // CssmAttachment objects.
367 // parent ::= the loaded module object.
368 // active ::= attached.
370 AttachmentImpl::AttachmentImpl(const Guid
&guid
, CSSM_SERVICE_TYPE subserviceType
)
371 : ObjectImpl(CssmImpl::standard()->autoModule(guid
))
373 make(subserviceType
);
376 AttachmentImpl::AttachmentImpl(const Module
&module, CSSM_SERVICE_TYPE subserviceType
)
379 make(subserviceType
);
382 AttachmentImpl::~AttachmentImpl()
388 AttachmentImpl::make(CSSM_SERVICE_TYPE subserviceType
)
390 // default configuration
393 mSubserviceType
= subserviceType
;
399 AttachmentImpl::activate()
404 mMemoryFunctions
= CssmAllocatorMemoryFunctions(allocator());
405 check(CSSM_ModuleAttach(&guid(), &mVersion
,
410 CSSM_KEY_HIERARCHY_NONE
,
411 NULL
, 0, // no function pointer table return
419 AttachmentImpl::deactivate()
424 check(CSSM_ModuleDetach(mHandle
));
429 AttachmentImpl::subserviceMask() const
431 return mSubserviceType
;
435 AttachmentImpl::subserviceId(uint32 id
)
441 AttachmentImpl::subserviceUid() const
443 return CssmSubserviceUid(guid(), &mVersion
, mSubserviceId
, subserviceMask());
447 AttachmentImpl::module() const
449 return parent
<Module
>();