]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_pluginlib/cssmplugin.cpp
Security-179.tar.gz
[apple/security.git] / cdsa / cdsa_pluginlib / cssmplugin.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 // cssmplugin - adapter framework for C++-based CDSA plugin modules
21 //
22 // A note on locking: Attachments are effectively reference counted in CSSM.
23 // CSSM will not let a client detach an attachment that has a(nother) thread
24 // active in its code. Thus, our locks merely protect global maps; they do not
25 // need (or try) to close the classic use-and-delete window.
26 //
27 #ifdef __MWERKS__
28 #define _CPP_CSSMPLUGIN
29 #endif
30 #include <Security/cssmplugin.h>
31 #include <Security/pluginsession.h>
32
33
34 ModuleNexus<CssmPlugin::SessionMap> CssmPlugin::sessionMap;
35
36
37 CssmPlugin::CssmPlugin()
38 {
39 haveCallback = false;
40 }
41
42 CssmPlugin::~CssmPlugin()
43 {
44 // Note: if haveCallback, we're being unloaded forcibly.
45 // (CSSM wouldn't do this to us in normal operation.)
46 }
47
48
49 void CssmPlugin::moduleLoad(const Guid &cssmGuid,
50 const Guid &moduleGuid,
51 const ModuleCallback &newCallback)
52 {
53 // add the callback vector
54 if (haveCallback) // re-entering moduleLoad - not currently supported
55 CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
56
57 mMyGuid = moduleGuid;
58
59 // let the implementation know that we're loading
60 load();
61
62 // commit
63 callback = newCallback;
64 haveCallback = true;
65 }
66
67
68 void CssmPlugin::moduleUnload(const Guid &cssmGuid,
69 const Guid &moduleGuid,
70 const ModuleCallback &oldCallback)
71 {
72 // check the callback vector
73 if (!haveCallback || oldCallback != callback)
74 CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
75
76 // tell our subclass that we're closing down
77 unload();
78
79 // commit closure
80 haveCallback = false;
81 }
82
83
84 void CssmPlugin::moduleAttach(CSSM_MODULE_HANDLE theHandle,
85 const Guid &newCssmGuid,
86 const Guid &moduleGuid,
87 const Guid &moduleManagerGuid,
88 const Guid &callerGuid,
89 const CSSM_VERSION &version,
90 uint32 subserviceId,
91 CSSM_SERVICE_TYPE subserviceType,
92 CSSM_ATTACH_FLAGS attachFlags,
93 CSSM_KEY_HIERARCHY keyHierarchy,
94 const CSSM_UPCALLS &upcalls,
95 CSSM_MODULE_FUNCS_PTR &funcTbl)
96 {
97 // insanity checks
98 // @@@ later
99
100 // make the new session object, hanging in thin air
101 PluginSession *session = makeSession(theHandle,
102 version,
103 subserviceId, subserviceType,
104 attachFlags,
105 upcalls);
106
107 try {
108 // haggle with the implementor
109 funcTbl = session->construct();
110
111 // commit this session creation
112 StLock<Mutex> _(sessionMap());
113 sessionMap()[theHandle] = session;
114 } catch (...) {
115 delete session;
116 throw;
117 }
118 }
119
120 void CssmPlugin::moduleDetach(CSSM_MODULE_HANDLE handle)
121 {
122 // locate the plugin and hold the sessionMapLock
123 PluginSession *session;
124 {
125 StLock<Mutex> _(sessionMap());
126 SessionMap::iterator it = sessionMap().find(handle);
127 if (it == sessionMap().end())
128 CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
129 session = it->second;
130 sessionMap().erase(it);
131 }
132
133 // let the session know it is going away
134 try {
135 session->detach();
136 } catch (...) {
137 // session detach failed - put the plugin back and fail
138 StLock<Mutex> _(sessionMap());
139 sessionMap()[handle] = session;
140 throw;
141 }
142
143 // everything's fine, delete the session
144 delete session;
145 }
146
147 void CssmPlugin::sendCallback(CSSM_MODULE_EVENT event, uint32 subId,
148 CSSM_SERVICE_TYPE serviceType) const
149 {
150 assert(haveCallback);
151 callback(event, mMyGuid, subId, serviceType);
152 }
153
154
155 //
156 // Default subclass hooks.
157 // The default implementations succeed without doing anything
158 //
159 void CssmPlugin::load() { }
160
161 void CssmPlugin::unload() { }