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 #ifndef _H_CDSA_CLIENT_CSSMCLIENT 
  23 #define _H_CDSA_CLIENT_CSSMCLIENT  1 
  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> 
  33 namespace CssmClient 
{ 
  37 // Forward declarations 
  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. 
  50         HasGuid(const Guid 
&guid
) { mGuid 
= guid
; } 
  53         const Guid 
&guid() const { return mGuid
; } 
  56         void setGuid(const Guid 
&guid
) { mGuid 
= guid
; } 
  64 // Exceptions are based on the CssmError utility class. We add our own class of client-side exceptions. 
  66 class Error 
: public CssmError 
{ 
  68         Error(CSSM_RETURN err
) : CssmError(err
) { } 
  69         virtual const char *what () const throw(); 
  78 // The CssmObject abstract class models features common to different Cssm objects. 
  79 // It handles a tree hierarchy of objects (parent/children) safely. 
  83 class ObjectImpl 
: virtual public RefCount
 
  86         explicit ObjectImpl(); // Constructor for Impl objects without a parent. 
  87         explicit ObjectImpl(const Object 
&parent
); 
  88         virtual ~ObjectImpl(); 
  90         bool isActive() const { return mActive
; } 
  92         virtual Allocator 
&allocator() const; 
  93         virtual void allocator(Allocator 
&alloc
); 
  95         // Pointer comparison by default.  Subclasses may override. 
  96         virtual bool operator <(const ObjectImpl 
&other
) const; 
  97         virtual bool operator ==(const ObjectImpl 
&other
) const; 
  99         static void check(CSSM_RETURN status
); 
 102         bool mActive
;                                   // loaded, attached, etc. 
 103         mutable Allocator 
*mAllocator
; // allocator hierarchy (NULL => TBD) 
 105         template <class Obj
> Obj 
parent() const 
 106         { assert(mParent
); return Obj(static_cast<typename 
Obj::Impl 
*>(&(*mParent
))); } 
 110         bool isIdle() const { return mChildCount 
== 0; } 
 112         // {de,}activate() assume you have locked *this 
 113         virtual void activate() = 0; 
 114         virtual void deactivate() = 0; 
 117         RefPointer
<ObjectImpl
> mParent
;         // parent object 
 118         AtomicCounter
<uint32
> mChildCount
; 
 124         friend class ObjectImpl
; 
 126         typedef ObjectImpl Impl
; 
 127         explicit Object(Impl 
*impl
) : mImpl(impl
) {} 
 130         // @@@ CSPDL subclass breaks if the is a static_cast 
 131         template <class _Impl
> _Impl 
&impl() const 
 132         { return dynamic_cast<_Impl 
&>(*mImpl
); } 
 135         Impl 
*operator ->() const { return &(*mImpl
); } 
 136         Impl 
&operator *() const { return *mImpl
; } 
 138         // @@@ Why is this needed.  DbCursor which inheirits from Object wants to call this. 
 139         template <class _Impl
> _Impl 
&checkedImpl() const 
 140         { return dynamic_cast<_Impl 
&>(*mImpl
); } 
 142         bool operator !() const { return !mImpl
; } 
 143         operator bool() const { return mImpl
; } 
 145     bool isActive() const                               { return mImpl 
&& mImpl
->isActive(); } 
 146     Allocator 
&allocator() const        { return mImpl
->allocator(); } 
 147         void release()                                          { mImpl 
= NULL
; } 
 149         bool operator <(const Object 
&other
) const 
 150         { return mImpl 
&& other
.mImpl 
? *mImpl 
< *other
.mImpl 
: mImpl 
< other
.mImpl
; } 
 151         bool operator ==(const Object 
&other
) const 
 152         { return mImpl 
&& other
.mImpl 
? *mImpl 
== *other
.mImpl 
: mImpl 
== other
.mImpl
; } 
 155         RefPointer
<Impl
> mImpl
; 
 160 // Event callback mix-in class 
 164 class RawModuleEvents 
{ 
 165         friend class ModuleImpl
; 
 167         virtual ~RawModuleEvents(); 
 169         virtual void notify(uint32 subService
, 
 170                 CSSM_SERVICE_TYPE type
, CSSM_MODULE_EVENT event
) = 0; 
 173         static CSSM_RETURN 
sendNotify(const CSSM_GUID 
*, void *context
, uint32 subService
, 
 174                 CSSM_SERVICE_TYPE type
, CSSM_MODULE_EVENT event
); 
 177 class ModuleEvents 
: public RawModuleEvents 
{ 
 179         virtual void insertion(uint32 subService
, CSSM_SERVICE_TYPE type
); 
 180         virtual void removal(uint32 subService
, CSSM_SERVICE_TYPE type
); 
 181         virtual void fault(uint32 subService
, CSSM_SERVICE_TYPE type
); 
 184         void notify(uint32 subService
, CSSM_SERVICE_TYPE type
, CSSM_MODULE_EVENT event
); 
 189 // A CSSM loadable module. 
 190 // You rarely directly interact with these objects, but if you need to, 
 193 class ModuleImpl 
: public ObjectImpl
, public HasGuid
 
 196         ModuleImpl(const Guid 
&guid
); 
 197         ModuleImpl(const Guid 
&guid
, const Cssm 
&session
); 
 198         virtual ~ModuleImpl(); 
 200         void load() { activate(); } 
 201         void unload() { deactivate(); } 
 202         bool isLoaded() const { return isActive(); } 
 204         Cssm 
session() const; 
 206         void appNotifyCallback(CSSM_API_ModuleEventHandler appNotifyCallback
, void *appNotifyCallbackCtx
); 
 207         void appNotifyCallback(RawModuleEvents 
*handler
); 
 213         CSSM_API_ModuleEventHandler mAppNotifyCallback
; 
 214         void *mAppNotifyCallbackCtx
; 
 217 class Module 
: public Object
 
 220         typedef ModuleImpl Impl
; 
 221         explicit Module(Impl 
*impl
) : Object(impl
) {} 
 222         Module() : Object(NULL
) {} // XXX This might break operator < 
 223         Module(const Guid 
&guid
) : Object(new Impl(guid
)) {} 
 224         Module(const Guid 
&guid
, const Cssm 
&session
) : Object(new Impl(guid
, session
)) {} 
 226         Impl 
*operator ->() const { return &impl
<Impl
>(); } 
 227         Impl 
&operator *() const { return impl
<Impl
>(); } 
 232 // An Attachment object. This is the base class of all typed attachment classes. 
 234 class AttachmentImpl 
: public ObjectImpl
 
 237         AttachmentImpl(const Guid 
&guid
, CSSM_SERVICE_TYPE subserviceType
); 
 238         AttachmentImpl(const Module 
&module, CSSM_SERVICE_TYPE subserviceType
); 
 239         //AttachmentImpl(... mds reference ...); 
 240         virtual ~AttachmentImpl(); 
 242         // Virtual so that subclasses can return there true mask. 
 243         virtual CSSM_SERVICE_MASK 
subserviceMask() const; 
 245         CSSM_SERVICE_TYPE 
subserviceType() const { return mSubserviceType
; } 
 246         CSSM_VERSION 
version() const { return mVersion
; } 
 247         void version(const CSSM_VERSION 
&v
) { mVersion 
= v
; } 
 248         uint32 
subserviceId() const { return mSubserviceId
; } 
 249         virtual void subserviceId(uint32 id
); 
 250         CSSM_ATTACH_FLAGS 
flags() const { return mAttachFlags
; } 
 251         void flags(CSSM_ATTACH_FLAGS f
) { mAttachFlags 
= f
; } 
 253         void attach() { activate(); } 
 254         void detach() { deactivate(); } 
 255         bool attached() const { return isActive(); } 
 257         Module 
module() const; 
 258         const Guid 
&guid() const { return module()->guid(); } 
 259         CSSM_MODULE_HANDLE 
handle() { attach(); return mHandle
; } 
 261         CssmSubserviceUid 
subserviceUid() const; 
 268         void make(CSSM_SERVICE_TYPE subserviceType
);    // common constructor 
 270         CSSM_MODULE_HANDLE mHandle
; 
 272         CSSM_SERVICE_TYPE mSubserviceType
;                              // set by constructor 
 273         CSSM_VERSION mVersion
; 
 274         uint32 mSubserviceId
; 
 275         CSSM_ATTACH_FLAGS mAttachFlags
; 
 277         CssmAllocatorMemoryFunctions mMemoryFunctions
;  // set on attach() 
 280 class Attachment 
: public Object
 
 283         typedef AttachmentImpl Impl
; 
 284         explicit Attachment(Impl 
*impl
) : Object(impl
) {} 
 285         Attachment(const Guid 
&guid
, CSSM_SERVICE_TYPE subserviceType
) 
 286         : Object(new Impl(guid
, subserviceType
)) {} 
 287         Attachment(const Module 
&module, CSSM_SERVICE_TYPE subserviceType
) 
 288         : Object(new Impl(module, subserviceType
)) {} 
 289         //Attachment(... mds reference ...); 
 291         Impl 
*operator ->() const { return &impl
<Impl
>(); } 
 292         Impl 
&operator *() const { return impl
<Impl
>(); } 
 297 // A CSSM session object. 
 298 // You usually only have one per program, or library, or what-not. 
 302 class CssmImpl 
: public ObjectImpl 
{ 
 303     class StandardCssm
; friend class StandardCssm
; 
 308         void init() { activate(); } 
 309         void terminate() { deactivate(); } 
 311         CSSM_PRIVILEGE_SCOPE 
scope() const { return mScope
; } 
 312         void scope(CSSM_PRIVILEGE_SCOPE sc
) { mScope 
= sc
; } 
 313         const Guid 
&callerGuid() const { return mCallerGuid
; } 
 314         void callerGuid(const CSSM_GUID 
&guid
) { mCallerGuid 
= Guid::overlay(guid
); } 
 316         Module 
autoModule(const Guid 
&guid
); 
 319         explicit CssmImpl(bool);                                // internal constructor 
 321         void setup();                                                   // constructor setup 
 327         // CSSM global configuration -- picked up on each Init 
 328         CSSM_VERSION mVersion
; 
 329         CSSM_PRIVILEGE_SCOPE mScope
; 
 332         // module repository: modules by guid (protected by self) 
 333         typedef map
<Guid
, Module
> ModuleMap
; 
 338         static Cssm 
standard(); 
 339         static void catchExit(); 
 342         static void atExitHandler(); 
 344     class StandardCssm 
: public Mutex 
{ 
 346         StandardCssm() : mCssm(NULL
) { } 
 348         void setCssm(CssmImpl 
*cssm
); 
 349         void unsetCssm(CssmImpl 
*cssm
); 
 355     static ModuleNexus
<StandardCssm
> mStandard
; 
 358 class Cssm 
: public Object
 
 361         typedef CssmImpl Impl
; 
 362         explicit Cssm(Impl 
*impl
) : Object(impl
) {} 
 363         explicit Cssm() : Object(new Impl()) {} 
 365         Impl 
*operator ->() const { return &impl
<Impl
>(); } 
 366         Impl 
&operator *() const { return impl
<Impl
>(); } 
 368         static Cssm 
standard() { return CssmImpl::standard(); } 
 371 } // end namespace CssmClient  
 373 } // end namespace Security 
 375 #endif // _H_CDSA_CLIENT_CSSMCLIENT