]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_cssm/lib/module.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / Security / libsecurity_cssm / lib / module.cpp
1 /*
2 * Copyright (c) 2000-2001,2003-2004,2011,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 // module - CSSM Module objects
27 //
28 #include "module.h"
29 #include "manager.h"
30 #include "attachment.h"
31 #include <security_cdsa_utilities/cssmbridge.h>
32
33
34 //
35 // Module object construction.
36 //
37 Module::Module(CssmManager *mgr, const MdsComponent &info, Plugin *plug)
38 : MdsComponent(info), cssm(*mgr), plugin(plug)
39 {
40 // invoke module's load entry (tell it it's being loaded)
41 if (CSSM_RETURN err = plugin->load(&gGuidCssm, // CSSM's Guid
42 &myGuid(), // module's Guid
43 spiEventRelay, this)) {
44 plugin->unload();
45 CssmError::throwMe(err); // self-destruct this module
46 }
47 }
48
49
50 //
51 // Destroy the module object.
52 // The unload() method must have succeeded and returned true before
53 // you get to delete a Module. A destructor is too precarious a place
54 // to negotiate with a plugin...
55 //
56 Module::~Module()
57 {
58 }
59
60
61 bool Module::unload(const ModuleCallback &callback)
62 {
63 StLock<Mutex> _(mLock);
64 // locked module - no more attachment creations possible
65 if (callbackCount() == 1) {
66 // would be last callback if successful, check for actual unload
67 if (attachmentCount() > 0)
68 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_FAILED); // @# module is busy
69 // no attachments active - we are idle and ready to unload
70 if (CSSM_RETURN err = plugin->unload(&gGuidCssm, // CSSM's Guid
71 &myGuid(), // module's Guid
72 spiEventRelay, this)) // our callback
73 CssmError::throwMe(err); // tough...
74 // okay, commit
75 remove(callback);
76 plugin->unload();
77 return true;
78 } else {
79 // more callbacks - we're not going to unload
80 remove(callback);
81 return false;
82 }
83 }
84
85
86 //
87 // Create a new attachment for this module
88 //
89 CSSM_HANDLE Module::attach(const CSSM_VERSION &version,
90 uint32 subserviceId,
91 CSSM_SERVICE_TYPE subserviceType,
92 const CSSM_API_MEMORY_FUNCS &memoryOps,
93 CSSM_ATTACH_FLAGS attachFlags,
94 CSSM_KEY_HIERARCHY keyHierarchy,
95 CSSM_FUNC_NAME_ADDR *functionTable,
96 uint32 functionTableSize)
97 {
98 StLock<Mutex> _(mLock);
99
100 // check if the module can do this kind of service
101 if (!supportsService(subserviceType))
102 CssmError::throwMe(CSSMERR_CSSM_INVALID_SERVICE_MASK);
103
104 Attachment *attachment = cssm.attachmentMakerFor(subserviceType)->make(this,
105 version,
106 subserviceId, subserviceType,
107 memoryOps,
108 attachFlags,
109 keyHierarchy,
110 functionTable, functionTableSize);
111
112 try {
113 // add to module's attachment map
114 attachmentMap.insert(AttachmentMap::value_type(attachment->handle(), attachment));
115 } catch (...) {
116 delete attachment;
117 throw;
118 }
119
120 // all done
121 return attachment->handle();
122 }
123
124
125 //
126 // Detach an Attachment from this module.
127 // THREADS: Requires the attachment to be idled out, i.e. caller
128 // is responsible for keeping more users from entering it.
129 //
130 void Module::detach(Attachment *attachment)
131 {
132 StLock<Mutex> _(mLock);
133 attachmentMap.erase(attachment->handle());
134 }
135
136
137 //
138 // Handle events sent by the loaded module.
139 //
140 void Module::spiEvent(CSSM_MODULE_EVENT event,
141 const Guid &guid,
142 uint32 subserviceId,
143 CSSM_SERVICE_TYPE serviceType)
144 {
145 StLock<Mutex> _(mLock);
146 if (guid != myGuid())
147 CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
148 callbackSet(event, guid, subserviceId, serviceType);
149 }
150
151 // static shim
152 CSSM_RETURN Module::spiEventRelay(const CSSM_GUID *ModuleGuid,
153 void *Context,
154 uint32 SubserviceId,
155 CSSM_SERVICE_TYPE ServiceType,
156 CSSM_MODULE_EVENT EventType)
157 {
158 BEGIN_API
159 static_cast<Module *>(Context)->spiEvent(EventType,
160 Guid::required(ModuleGuid),
161 SubserviceId,
162 ServiceType);
163 END_API(CSSM)
164 }