]> git.saurik.com Git - apple/security.git/blame_incremental - OSX/libsecurity_cssm/lib/module.cpp
Security-58286.51.6.tar.gz
[apple/security.git] / OSX / libsecurity_cssm / lib / module.cpp
... / ...
CommitLineData
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//
37Module::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//
56Module::~Module()
57{
58}
59
60
61bool 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//
89CSSM_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//
130void 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//
140void 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
152CSSM_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}