+++ /dev/null
-/*
- * Copyright (c) 2000-2001,2003-2004 Apple Computer, Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The 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.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-//
-// attachment - CSSM module attachment objects
-//
-#ifndef _H_ATTACHMENT
-#define _H_ATTACHMENT
-
-#include "cssmint.h"
-#include "module.h"
-#include <security_cdsa_utilities/handleobject.h>
-#include <security_cdsa_utilities/cssmalloc.h>
-
-
-//
-// This type represents a single Attachment of any kind.
-// Attachments are formed by the CSSM_ModuleAttach call and represent a "session"
-// between a caller client and a particular plugin module. Any number of attachments
-// can exist for a particular caller and a particular module.
-// Attachment is an abstract class. You must subclass it to implement a concrete
-// type of plugin. For the standard ones, see the end of this header.
-// Key recovery does not use Attachments.
-// EMMs are not Attachments, but the plugins they manage are.
-// And yes, an Attachment *is* a lock. The API transition layer functions need
-// to lock Attachments from the "outside", so there's no point in being coy about it.
-// Locking the Attachment is equivalent to locking all its members except for
-// instance-constant ones.
-//
-class Attachment : public HandleObject, // has a handle
- public CssmMemoryFunctionsAllocator, // is an allocator
- public CountingMutex { // is a counting lock
- NOCOPY(Attachment)
-public:
- Attachment(Module *theModule,
- const CSSM_VERSION &version,
- uint32 subserviceId,
- CSSM_SERVICE_TYPE subserviceType,
- const CSSM_API_MEMORY_FUNCS &memoryOps,
- CSSM_ATTACH_FLAGS attachFlags,
- CSSM_KEY_HIERARCHY keyHierarchy);
- virtual ~Attachment();
-
- Module &module;
-
- // feature inquiries. These features are constant for the life of the Attachment
- const Guid &myGuid() const { return module.myGuid(); }
- CSSM_SERVICE_TYPE subserviceType() const { return mSubserviceType; }
- uint32 subserviceId() const { return mSubserviceId; }
- const CSSM_VERSION &pluginVersion() const { return mVersion; }
- CSSM_ATTACH_FLAGS attachFlags() const { return mAttachFlags; }
-
- bool isThreadSafe() const { return module.isThreadSafe(); }
-
- // service a symbol table inquiry against our attachment
- virtual void resolveSymbols(CSSM_FUNC_NAME_ADDR *FunctionTable,
- uint32 NumFunctions) = 0;
-
- // terminate the live attachment and prepare to die
- void detach(bool isLocked);
-
- template <class Sub> friend Sub &enterAttachment(CSSM_HANDLE);
-
- // need to redefine lock/trylock to implement HandleObject protocol
- void lock() { CountingMutex::lock(); }
- bool tryLock() { return CountingMutex::tryLock(); }
-
-private:
- bool mIsActive; // successfully attached to plugin
-
- uint32 mSubserviceId; // subservice ID in use
- CSSM_SERVICE_TYPE mSubserviceType; // service type
-
- // how we were created
- CSSM_VERSION mVersion; // plugin version requested
- CSSM_ATTACH_FLAGS mAttachFlags; // attach flags requested
- CSSM_KEY_HIERARCHY mKeyHierarchy; // key hierarchy verified
-
-protected:
- CSSM_MODULE_FUNCS *spiFunctionTable; // entry table as returned by plugin on attach
-
-private:
- CSSM_UPCALLS upcalls; // upcall functions for our module
-
- // upcall implementors - these are handed to the plugin in `upcalls'
- static void *upcallMalloc(CSSM_HANDLE handle, size_t size);
- static void upcallFree(CSSM_HANDLE handle, void *mem);
- static void *upcallRealloc(CSSM_HANDLE handle, void *mem, size_t size);
- static void *upcallCalloc(CSSM_HANDLE handle, size_t num, size_t size);
- static CSSM_RETURN upcallCcToHandle(CSSM_CC_HANDLE handle, CSSM_MODULE_HANDLE *modHandle);
- static CSSM_RETURN upcallGetModuleInfo(CSSM_MODULE_HANDLE Module,
- CSSM_GUID_PTR Guid,
- CSSM_VERSION_PTR Version,
- uint32 *SubServiceId,
- CSSM_SERVICE_TYPE *SubServiceType,
- CSSM_ATTACH_FLAGS *AttachFlags,
- CSSM_KEY_HIERARCHY *KeyHierarchy,
- CSSM_API_MEMORY_FUNCS_PTR AttachedMemFuncs,
- CSSM_FUNC_NAME_ADDR_PTR FunctionTable,
- uint32 NumFunctions);
-};
-
-// this should be a member template, but egcs barfs on its invocation
-// @@@ pass module code in to get better "invalid handle" diag?
-// @@@ or use template specializations here?
-template <class AttachmentSubclass>
-inline AttachmentSubclass &enterAttachment(CSSM_HANDLE h)
-{
- AttachmentSubclass &attachment = HandleObject::findAndLock<AttachmentSubclass>(h, CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
- attachment.finishEnter();
- return attachment;
-}
-
-
-//
-// For the standard attachment types, function dispatch to the plugin
-// is done based on the CSSM_SPI_xxx_FUNCS structures describing the
-// types and ordering of entry points. The StandardAttachment class
-// implements this by holding a copy of these tables for the use of
-// the transition layer.
-// You are free to subclass from Attachment directly if that makes better
-// sense to your kind of plugin.
-//
-template <CSSM_SERVICE_TYPE type, class FunctionTable>
-class StandardAttachment : public Attachment {
-public:
- typedef map<const char *, unsigned int> NameMap;
-
- StandardAttachment(Module *theModule,
- const NameMap &names,
- const CSSM_VERSION &version,
- uint32 subserviceId,
- CSSM_SERVICE_TYPE subserviceType,
- const CSSM_API_MEMORY_FUNCS &memoryOps,
- CSSM_ATTACH_FLAGS attachFlags,
- CSSM_KEY_HIERARCHY keyHierarchy)
- : Attachment(theModule, version, subserviceId, subserviceType,
- memoryOps, attachFlags, keyHierarchy),
- nameMap(names)
- {
- try {
- if (spiFunctionTable->NumberOfServiceFuncs <
- sizeof(FunctionTable) / sizeof(CSSM_PROC_ADDR))
- CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_FUNCTION_TABLE);
- // tolerate a table that's TOO large - perhaps it's a newer version
- // @@@ with the new spec, we could just store the pointer
- memcpy(&downcalls, spiFunctionTable->ServiceFuncs, sizeof(downcalls));
- } catch (...) {
- // we are attached to the plugin, so tell it the show is off
- detach(false);
- throw;
- }
- }
-
- void resolveSymbols(CSSM_FUNC_NAME_ADDR *inFunctionTable,
- uint32 NumFunctions)
- {
- for (unsigned n = 0; n < NumFunctions; n++) {
- NameMap::const_iterator it = nameMap.find(inFunctionTable[n].Name);
- inFunctionTable[n].Address =
- (it == nameMap.end()) ? NULL : downcallNumber(it->second);
- }
- }
-
- FunctionTable downcalls;
-
- CSSM_PROC_ADDR downcallNumber(uint32 index) const
- {
- assert(index < sizeof(downcalls) / sizeof(CSSM_PROC_ADDR));
- return reinterpret_cast<const CSSM_PROC_ADDR *>(&downcalls)[index];
- }
-
-private:
- const NameMap &nameMap;
-};
-
-
-#endif //_H_ATTACHMENT