1/* 2 * Copyright (c) 2000-2004,2011-2012,2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// attachment - CSSM module attachment objects 27// 28#include "attachment.h" 29#include "module.h" 30#include "manager.h" 31#include "cssmcontext.h" 32#include <security_cdsa_utilities/cssmbridge.h> 33 34// 35// Construct an Attachment object. 36// This constructor does almost all the work: it initializes the Attachment 37// object, calls the plugin's attach function, and initializes everything. 38// The only job left for the subclass's constructor is to take the spiFunctionTable 39// field and extract from it the plugin's dispatch table in suitable form. 40// 41Attachment::Attachment(Module *parent, 42 const CSSM_VERSION &version, 43 uint32 ssId, 44 CSSM_SERVICE_TYPE ssType, 45 const CSSM_API_MEMORY_FUNCS &memoryOps, 46 CSSM_ATTACH_FLAGS attachFlags, 47 CSSM_KEY_HIERARCHY keyHierarchy) 48 : CssmMemoryFunctionsAllocator(memoryOps), module(*parent) 49{ 50 // record our origins 51 mVersion = version; 52 mSubserviceId = ssId; 53 mSubserviceType = ssType; 54 mAttachFlags = attachFlags; 55 mKeyHierarchy = keyHierarchy; 56 57 // we are not (yet) attached to our plugin 58 mIsActive = false; 59 60 // build the upcalls table 61 // (we could do this once in a static, but then we'd have to lock on it) 62 upcalls.malloc_func = upcallMalloc; 63 upcalls.free_func = upcallFree; 64 upcalls.realloc_func = upcallRealloc; 65 upcalls.calloc_func = upcallCalloc; 66 upcalls.CcToHandle_func = upcallCcToHandle; 67 upcalls.GetModuleInfo_func = upcallGetModuleInfo; 68 69 // tell the module to create an attachment 70 spiFunctionTable = NULL; // preset invalid 71 if (CSSM_RETURN err = module.plugin->attach(&module.myGuid(), 72 &mVersion, 73 mSubserviceId, 74 mSubserviceType, 75 mAttachFlags, 76 handle(), 77 mKeyHierarchy, 78 &gGuidCssm, // CSSM's Guid 79 &gGuidCssm, // module manager Guid 80 &module.cssm.callerGuid(), // caller Guid 81 &upcalls, 82 &spiFunctionTable)) { 83 // attach rejected by module 84 secdebug("cssm", "attach of module %p(%s) failed", 85 &module, module.name().c_str()); 86 CssmError::throwMe(err); 87 } 88 try { 89 if (spiFunctionTable == NULL || spiFunctionTable->ServiceType != subserviceType()) 90 CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_FUNCTION_TABLE); 91 mIsActive = true; // now officially attached to plugin 92 secdebug("cssm", "%p attached module %p(%s) (ssid %ld type %ld)", 93 this, parent, parent->name().c_str(), (long)ssId, (long)ssType); 94 // subclass is responsible for taking spiFunctionTable and build 95 // whatever dispatch is needed 96 } catch (...) { 97 module.plugin->detach(handle()); // with extreme prejudice 98 throw; 99 } 100} 101 102 103// 104// Detach an attachment. 105// This is the polite way to detach from the plugin. It may be refused safely 106// (though perhaps not meaningfully). 107// THREADS: mLock is locked on entry IFF isLocked, and will be unlocked on exit. 108// 109void Attachment::detach(bool isLocked) 110{ 111 StLock<Mutex> locker(*this, isLocked); // pre-state locker 112 locker.lock(); // make sure it's locked 113 114 if (mIsActive) { 115 if (!isIdle()) 116 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_FAILED); //@#attachment busy 117 if (CSSM_RETURN error = module.plugin->detach(handle())) 118 CssmError::throwMe(error); // I'm sorry Dave, ... 119 secdebug("cssm", "%p detach module %p(%s)", this, 120 &module, module.name().c_str()); 121 mIsActive = false; 122 module.detach(this); 123 } 124} 125 126 127// 128// Destroy the Attachment object 129// 130Attachment::~Attachment() 131{ 132 try { 133 detach(false); 134 } catch (...) { 135 // too bad - you're dead 136 } 137} 138 139 140// 141// Upcall relays. 142// These do not lock the attachment object. The attachment can't go away 143// because we incremented the busy count on entry to the plugin; and these 144// fields are quite constant for the life of the Attachment. 145// 146void *Attachment::upcallMalloc(CSSM_HANDLE handle, size_t size) 147{ 148 BEGIN_API 149 return HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).malloc(size); 150 END_API1(NULL) 151} 152 153void Attachment::upcallFree(CSSM_HANDLE handle, void *mem) 154{ 155 BEGIN_API 156 return HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).free(mem); 157 END_API0 158} 159 160void *Attachment::upcallRealloc(CSSM_HANDLE handle, void *mem, size_t size) 161{ 162 BEGIN_API 163 return HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).realloc(mem, size); 164 END_API1(NULL) 165} 166 167void *Attachment::upcallCalloc(CSSM_HANDLE handle, size_t num, size_t size) 168{ 169 BEGIN_API 170 return HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).calloc(size, num); 171 END_API1(NULL) 172} 173 174CSSM_RETURN Attachment::upcallCcToHandle(CSSM_CC_HANDLE handle, 175 CSSM_MODULE_HANDLE *modHandle) 176{ 177 BEGIN_API 178#warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE 179 Required(modHandle) = HandleObject::find<HandleContext>((CSSM_HANDLE)handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).attachment.handle(); 180 END_API(CSP) 181} 182 183CSSM_RETURN Attachment::upcallGetModuleInfo(CSSM_MODULE_HANDLE handle, 184 CSSM_GUID_PTR guid, 185 CSSM_VERSION_PTR version, 186 uint32 *subserviceId, 187 CSSM_SERVICE_TYPE *subserviceType, 188 CSSM_ATTACH_FLAGS *attachFlags, 189 CSSM_KEY_HIERARCHY *keyHierarchy, 190 CSSM_API_MEMORY_FUNCS_PTR memoryOps, 191 CSSM_FUNC_NAME_ADDR_PTR FunctionTable, 192 uint32 NumFunctions) 193{ 194 BEGIN_API 195 Attachment &attachment = HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE); 196 Required(guid) = attachment.myGuid(); 197 Required(version) = attachment.mVersion; 198 Required(subserviceId) = attachment.mSubserviceId; 199 Required(subserviceType) = attachment.mSubserviceType; 200 Required(attachFlags) = attachment.mAttachFlags; 201 Required(keyHierarchy) = attachment.mKeyHierarchy; 202 Required(memoryOps) = attachment; 203 if (FunctionTable) 204 attachment.resolveSymbols(FunctionTable, NumFunctions); 205 END_API(CSSM) 206} 207