Logo Search packages:      
Sourcecode: coreutils version File versions  Download package

cssmclient.h

/*
 * 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 <security_utilities/threading.h>
#include <security_utilities/globalizer.h>
#include <security_utilities/refcount.h>
#include <security_cdsa_utilities/cssmalloc.h>
#include <security_cdsa_utilities/cssmpods.h>
#include <map>

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 lock-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(CSSM_RETURN err) : CssmError(err) { }
      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 Allocator &allocator() const;
      virtual void allocator(Allocator &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 Allocator *mAllocator; // allocator hierarchy (NULL => TBD)
      
      template <class Obj> Obj parent() const
      { assert(mParent); return Obj(static_cast<typename Obj::Impl *>(&(*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<ObjectImpl> mParent;           // parent object
      AtomicCounter<uint32> 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 <class _Impl> _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 <class _Impl> _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(); }
    Allocator &allocator() const    { return mImpl->allocator(); }
      void release()                                  { mImpl = NULL; }

      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<Impl> mImpl;
};


//
// Event callback mix-in class
//
class ModuleImpl;

class RawModuleEvents {
      friend class ModuleImpl;
public:
      virtual ~RawModuleEvents();

      virtual void notify(uint32 subService,
            CSSM_SERVICE_TYPE type, CSSM_MODULE_EVENT event) = 0;

private:
      static CSSM_RETURN sendNotify(const CSSM_GUID *, void *context, uint32 subService,
            CSSM_SERVICE_TYPE type, CSSM_MODULE_EVENT event);
};

class ModuleEvents : public RawModuleEvents {
public:
      virtual void insertion(uint32 subService, CSSM_SERVICE_TYPE type);
      virtual void removal(uint32 subService, CSSM_SERVICE_TYPE type);
      virtual void fault(uint32 subService, CSSM_SERVICE_TYPE type);

protected:
      void notify(uint32 subService, CSSM_SERVICE_TYPE type, CSSM_MODULE_EVENT event);
};


//
// 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;

      void appNotifyCallback(CSSM_API_ModuleEventHandler appNotifyCallback, void *appNotifyCallbackCtx);
      void appNotifyCallback(RawModuleEvents *handler);

protected:
      void activate();
      void deactivate();

      CSSM_API_ModuleEventHandler mAppNotifyCallback;
      void *mAppNotifyCallbackCtx;
};

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>(); }
      Impl &operator *() const { return impl<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>(); }
      Impl &operator *() const { return impl<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<Guid, Module> 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<StandardCssm> 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>(); }
      Impl &operator *() const { return impl<Impl>(); }

      static Cssm standard() { return CssmImpl::standard(); }
};

} // end namespace CssmClient 

} // end namespace Security

#endif // _H_CDSA_CLIENT_CSSMCLIENT

Generated by  Doxygen 1.6.0   Back to index