]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 A |
1 | /* |
2 | * Copyright (c) 2000-2004 Apple Computer, 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 | // | |
41 | Attachment::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 | // | |
109 | void 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 | // | |
130 | Attachment::~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 | // | |
146 | void *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 | ||
153 | void 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 | ||
160 | void *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 | ||
167 | void *Attachment::upcallCalloc(CSSM_HANDLE handle, size_t num, size_t size) | |
168 | { | |
169 | BEGIN_API | |
427c49bc | 170 | return HandleObject::find<Attachment>(handle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).calloc(size, num); |
b1ab9ed8 A |
171 | END_API1(NULL) |
172 | } | |
173 | ||
174 | CSSM_RETURN Attachment::upcallCcToHandle(CSSM_CC_HANDLE handle, | |
175 | CSSM_MODULE_HANDLE *modHandle) | |
176 | { | |
177 | BEGIN_API | |
427c49bc A |
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(); | |
b1ab9ed8 A |
180 | END_API(CSP) |
181 | } | |
182 | ||
183 | CSSM_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 | } |