/* * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. * * The contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please obtain * a copy of the License at http://www.apple.com/publicsource and read it before * using this file. * * This Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the * specific language governing rights and limitations under the License. */ // // cssmclient - common client interface to CSSM and MDS // #ifndef _H_CDSA_CLIENT_CSSMCLIENT #define _H_CDSA_CLIENT_CSSMCLIENT 1 #include #include #include #include #include #include #include // debug namespace Security { namespace CssmClient { // // Forward declarations // class Cssm; class Module; class Attachment; // // An mixin for objects that have (store) GUIDs. // The GUID value is meant to be set-once constant, and can be locked handled accordingly. // class HasGuid { public: HasGuid(const Guid &guid) { mGuid = guid; } HasGuid() { } const Guid &guid() const { return mGuid; } protected: void setGuid(const Guid &guid) { mGuid = guid; } private: Guid mGuid; }; // // Exceptions are based on the CssmError utility class. We add our own class of client-side exceptions. // class Error : public CssmError { public: Error(int err) : CssmError(err) { } CSSM_RETURN cssmError() const; virtual const char *what () const throw(); enum { objectBusy = -1, }; }; // // The CssmObject abstract class models features common to different Cssm objects. // It handles a tree hierarchy of objects (parent/children) safely. // class Object; class ObjectImpl : virtual public RefCount { public: explicit ObjectImpl(); // Constructor for Impl objects without a parent. explicit ObjectImpl(const Object &parent); virtual ~ObjectImpl(); bool isActive() const { return mActive; } virtual CssmAllocator &allocator() const; virtual void allocator(CssmAllocator &alloc); // Pointer comparison by default. Subclasses may override. virtual bool operator <(const ObjectImpl &other) const; virtual bool operator ==(const ObjectImpl &other) const; static void check(CSSM_RETURN status); protected: bool mActive; // loaded, attached, etc. mutable CssmAllocator *mAllocator; // allocator hierarchy (NULL => TBD) template Obj parent() const { assert(mParent); return Obj(static_cast(&(*mParent))); } void addChild(); void removeChild(); bool isIdle() const { return mChildCount == 0; } // {de,}activate() assume you have locked *this virtual void activate() = 0; virtual void deactivate() = 0; private: RefPointer mParent; // parent object AtomicCounter mChildCount; }; class Object { friend class ObjectImpl; public: typedef ObjectImpl Impl; explicit Object(Impl *impl) : mImpl(impl) {} protected: // @@@ CSPDL subclass breaks if the is a static_cast template _Impl &impl() const { return dynamic_cast<_Impl &>(*mImpl); } public: Impl *operator ->() const { return &(*mImpl); } Impl &operator *() const { return *mImpl; } // @@@ Why is this needed. DbCursor which inheirits from Object wants to call this. template _Impl &checkedImpl() const { return dynamic_cast<_Impl &>(*mImpl); } bool operator !() const { return !mImpl; } operator bool() const { return mImpl; } bool isActive() const { return mImpl && mImpl->isActive(); } CssmAllocator &allocator() const { return mImpl->allocator(); } bool operator <(const Object &other) const { return mImpl && other.mImpl ? *mImpl < *other.mImpl : mImpl < other.mImpl; } bool operator ==(const Object &other) const { return mImpl && other.mImpl ? *mImpl == *other.mImpl : mImpl == other.mImpl; } private: RefPointer mImpl; }; // // A CSSM loadable module. // You rarely directly interact with these objects, but if you need to, // here they are. // class ModuleImpl : public ObjectImpl, public HasGuid { public: ModuleImpl(const Guid &guid); ModuleImpl(const Guid &guid, const Cssm &session); virtual ~ModuleImpl(); void load() { activate(); } void unload() { deactivate(); } bool isLoaded() const { return isActive(); } Cssm session() const; protected: void activate(); void deactivate(); }; class Module : public Object { public: typedef ModuleImpl Impl; explicit Module(Impl *impl) : Object(impl) {} Module() : Object(NULL) {} // XXX This might break operator < Module(const Guid &guid) : Object(new Impl(guid)) {} Module(const Guid &guid, const Cssm &session) : Object(new Impl(guid, session)) {} Impl *operator ->() const { return &impl(); } Impl &operator *() const { return impl(); } }; // // An Attachment object. This is the base class of all typed attachment classes. // class AttachmentImpl : public ObjectImpl { public: AttachmentImpl(const Guid &guid, CSSM_SERVICE_TYPE subserviceType); AttachmentImpl(const Module &module, CSSM_SERVICE_TYPE subserviceType); //AttachmentImpl(... mds reference ...); virtual ~AttachmentImpl(); // Virtual so that subclasses can return there true mask. virtual CSSM_SERVICE_MASK subserviceMask() const; CSSM_SERVICE_TYPE subserviceType() const { return mSubserviceType; } CSSM_VERSION version() const { return mVersion; } void version(const CSSM_VERSION &v) { mVersion = v; } uint32 subserviceId() const { return mSubserviceId; } virtual void subserviceId(uint32 id); CSSM_ATTACH_FLAGS flags() const { return mAttachFlags; } void flags(CSSM_ATTACH_FLAGS f) { mAttachFlags = f; } void attach() { activate(); } void detach() { deactivate(); } bool attached() const { return isActive(); } Module module() const; const Guid &guid() const { return module()->guid(); } CSSM_MODULE_HANDLE handle() { attach(); return mHandle; } CssmSubserviceUid subserviceUid() const; protected: void activate(); void deactivate(); private: void make(CSSM_SERVICE_TYPE subserviceType); // common constructor CSSM_MODULE_HANDLE mHandle; CSSM_SERVICE_TYPE mSubserviceType; // set by constructor CSSM_VERSION mVersion; uint32 mSubserviceId; CSSM_ATTACH_FLAGS mAttachFlags; CssmAllocatorMemoryFunctions mMemoryFunctions; // set on attach() }; class Attachment : public Object { public: typedef AttachmentImpl Impl; explicit Attachment(Impl *impl) : Object(impl) {} Attachment(const Guid &guid, CSSM_SERVICE_TYPE subserviceType) : Object(new Impl(guid, subserviceType)) {} Attachment(const Module &module, CSSM_SERVICE_TYPE subserviceType) : Object(new Impl(module, subserviceType)) {} //Attachment(... mds reference ...); Impl *operator ->() const { return &impl(); } Impl &operator *() const { return impl(); } }; // // A CSSM session object. // You usually only have one per program, or library, or what-not. // class Cssm; class CssmImpl : public ObjectImpl { class StandardCssm; friend class StandardCssm; public: CssmImpl(); virtual ~CssmImpl(); void init() { activate(); } void terminate() { deactivate(); } CSSM_PRIVILEGE_SCOPE scope() const { return mScope; } void scope(CSSM_PRIVILEGE_SCOPE sc) { mScope = sc; } const Guid &callerGuid() const { return mCallerGuid; } void callerGuid(const CSSM_GUID &guid) { mCallerGuid = Guid::overlay(guid); } Module autoModule(const Guid &guid); protected: explicit CssmImpl(bool); // internal constructor void setup(); // constructor setup void activate(); void deactivate(); private: // CSSM global configuration -- picked up on each Init CSSM_VERSION mVersion; CSSM_PRIVILEGE_SCOPE mScope; Guid mCallerGuid; // module repository: modules by guid (protected by self) typedef map ModuleMap; ModuleMap moduleMap; Mutex mapLock; public: static Cssm standard(); static void catchExit(); private: static void atExitHandler(); class StandardCssm : public Mutex { public: StandardCssm() : mCssm(NULL) { } ~StandardCssm(); void setCssm(CssmImpl *cssm); void unsetCssm(CssmImpl *cssm); CssmImpl *get(); private: CssmImpl *mCssm; }; static ModuleNexus mStandard; }; class Cssm : public Object { public: typedef CssmImpl Impl; explicit Cssm(Impl *impl) : Object(impl) {} explicit Cssm() : Object(new Impl()) {} Impl *operator ->() const { return &impl(); } Impl &operator *() const { return impl(); } static Cssm standard() { return CssmImpl::standard(); } }; } // end namespace CssmClient } // end namespace Security #endif // _H_CDSA_CLIENT_CSSMCLIENT