#include "attachment.h"
#include "module.h"
#include "manager.h"
#include "cssmcontext.h"
#include <security_cdsa_utilities/cssmbridge.h>
Attachment::Attachment(Module *parent,
const CSSM_VERSION &version,
uint32 ssId,
CSSM_SERVICE_TYPE ssType,
const CSSM_API_MEMORY_FUNCS &memoryOps,
CSSM_ATTACH_FLAGS attachFlags,
CSSM_KEY_HIERARCHY keyHierarchy)
: CssmMemoryFunctionsAllocator(memoryOps), module(*parent)
{
mVersion = version;
mSubserviceId = ssId;
mSubserviceType = ssType;
mAttachFlags = attachFlags;
mKeyHierarchy = keyHierarchy;
mIsActive = false;
upcalls.malloc_func = upcallMalloc;
upcalls.free_func = upcallFree;
upcalls.realloc_func = upcallRealloc;
upcalls.calloc_func = upcallCalloc;
upcalls.CcToHandle_func = upcallCcToHandle;
upcalls.GetModuleInfo_func = upcallGetModuleInfo;
spiFunctionTable = NULL; if (CSSM_RETURN err = module.plugin->attach(&module.myGuid(),
&mVersion,
mSubserviceId,
mSubserviceType,
mAttachFlags,
handle(),
mKeyHierarchy,
&gGuidCssm, &gGuidCssm, &module.cssm.callerGuid(), &upcalls,
&spiFunctionTable)) {
secdebug("cssm", "attach of module %p(%s) failed",
&module, module.name().c_str());
CssmError::throwMe(err);
}
try {
if (spiFunctionTable == NULL || spiFunctionTable->ServiceType != subserviceType())
CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_FUNCTION_TABLE);
mIsActive = true; secdebug("cssm", "%p attached module %p(%s) (ssid %ld type %ld)",
this, parent, parent->name().c_str(), (long)ssId, (long)ssType);
} catch (...) {
module.plugin->detach(handle()); throw;
}
}
void Attachment::detach(bool isLocked)
{
StLock<Mutex> locker(*this, isLocked); locker.lock();
if (mIsActive) {
if (!isIdle())
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_FAILED); if (CSSM_RETURN error = module.plugin->detach(handle()))
CssmError::throwMe(error); secdebug("cssm", "%p detach module %p(%s)", this,
&module, module.name().c_str());
mIsActive = false;
module.detach(this);
}
}
Attachment::~Attachment()
{
try {
detach(false);
} catch (...) {
}
}
void *Attachment::upcallMalloc(CSSM_HANDLE handle, size_t size)
{
BEGIN_API
return HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).malloc(size);
END_API1(NULL)
}
void Attachment::upcallFree(CSSM_HANDLE handle, void *mem)
{
BEGIN_API
return HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).free(mem);
END_API0
}
void *Attachment::upcallRealloc(CSSM_HANDLE handle, void *mem, size_t size)
{
BEGIN_API
return HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).realloc(mem, size);
END_API1(NULL)
}
void *Attachment::upcallCalloc(CSSM_HANDLE handle, size_t num, size_t size)
{
BEGIN_API
return HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).calloc(size, num);
END_API1(NULL)
}
CSSM_RETURN Attachment::upcallCcToHandle(CSSM_CC_HANDLE handle,
CSSM_MODULE_HANDLE *modHandle)
{
BEGIN_API
#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE
Required(modHandle) = HandleObject::find<HandleContext>((CSSM_HANDLE)handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).attachment.handle();
END_API(CSP)
}
CSSM_RETURN Attachment::upcallGetModuleInfo(CSSM_MODULE_HANDLE handle,
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 memoryOps,
CSSM_FUNC_NAME_ADDR_PTR FunctionTable,
uint32 NumFunctions)
{
BEGIN_API
Attachment &attachment = HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
Required(guid) = attachment.myGuid();
Required(version) = attachment.mVersion;
Required(subserviceId) = attachment.mSubserviceId;
Required(subserviceType) = attachment.mSubserviceType;
Required(attachFlags) = attachment.mAttachFlags;
Required(keyHierarchy) = attachment.mKeyHierarchy;
Required(memoryOps) = attachment;
if (FunctionTable)
attachment.resolveSymbols(FunctionTable, NumFunctions);
END_API(CSSM)
}