]> git.saurik.com Git - apple/security.git/blob - cdsa/cssm/manager.cpp
Security-163.tar.gz
[apple/security.git] / cdsa / cssm / manager.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 // manager - CSSM manager/supervisor objects.
21 //
22 #ifdef __MWERKS__
23 #define _CPP_MANAGER
24 #endif
25 #include "manager.h"
26 #include "module.h"
27 #include <Security/debugging.h>
28 //#include <memory>
29
30
31 //
32 // Constructing a CssmManager instance.
33 // This does almost nothing - the actual intialization happens in the initialize() method.
34 //
35 CssmManager::CssmManager() : MdsComponent(gGuidCssm)
36 {
37 initCount = 0; // not yet initialized
38 }
39
40 CssmManager::~CssmManager()
41 {
42 if (initCount > 0)
43 secdebug("cssm", "CSSM forcibly shutting down");
44 }
45
46
47 //
48 // CSSM initialization.
49 // THREADS: This function must run in an uncontested environment.
50 //
51 void CssmManager::initialize (const CSSM_VERSION &version,
52 CSSM_PRIVILEGE_SCOPE scope,
53 const Guid &callerGuid,
54 CSSM_KEY_HIERARCHY keyHierarchy,
55 CSSM_PVC_MODE &pvcPolicy)
56 {
57 StLock<Mutex> _(mLock);
58
59 // check version first
60 checkVersion(version);
61
62 if (initCount) {
63 // re-initialization processing as per CSSM spec
64 if (pvcPolicy != mPvcPolicy) {
65 pvcPolicy = mPvcPolicy; // return old value
66 CssmError::throwMe(CSSMERR_CSSM_PVC_ALREADY_CONFIGURED);
67 }
68 initCount++;
69 secdebug("cssm", "re-initializing CSSM (%d levels)", initCount);
70 return;
71 }
72
73 // we don't support thread scope privileges
74 if (scope == CSSM_PRIVILEGE_SCOPE_THREAD)
75 CssmError::throwMe(CSSMERR_CSSM_SCOPE_NOT_SUPPORTED);
76
77 // keep the init arguments for future use - these become instance constants
78 mPrivilegeScope = scope;
79 mKeyHierarchy = keyHierarchy;
80 mPvcPolicy = pvcPolicy;
81 mCallerGuid = callerGuid;
82
83 // we are ready now
84 initCount = 1;
85 secdebug("cssm", "CSSM initialized");
86 }
87
88
89 //
90 // CSSM Termination processing.
91 // Returns true if this was the final (true) termination, false if a nested Init was undone.
92 //
93 bool CssmManager::terminate()
94 {
95 StLock<Mutex> _(mLock);
96 switch (initCount) {
97 case 0:
98 CssmError::throwMe(CSSMERR_CSSM_NOT_INITIALIZED);
99 case 1:
100 secdebug("cssm", "Terminating CSSM");
101 if (!moduleMap.empty())
102 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_FAILED); // @#can't terminate with modules loaded
103 initCount = 0; // mark uninitialized
104 return true;
105 default:
106 initCount--; // nested INIT, just count down
107 secdebug("cssm", "CSSM nested termination (%d remaining)", initCount);
108 return false;
109 }
110 }
111
112
113 #if defined(RESTRICTED_CSP_LOADING)
114 static char *allowedCSPs[] = {
115 "/System/Library/Security/AppleCSP.bundle",
116 "/System/Library/Security/AppleCSPDL.bundle",
117 NULL
118 };
119 #endif
120
121
122 //
123 // Load a module (well, try).
124 //
125 void CssmManager::loadModule(const Guid &guid,
126 CSSM_KEY_HIERARCHY,
127 const ModuleCallback &callback)
128 {
129 StLock<Mutex> _(mLock);
130 ModuleMap::iterator it = moduleMap.find(guid);
131 Module *module;
132 if (it == moduleMap.end()) {
133 MdsComponent info(guid);
134 #if defined(RESTRICTED_CSP_LOADING)
135 // An abominable temporary hack for legal reasons. They made me do it!
136 if (info.supportsService(CSSM_SERVICE_CSP)) {
137 string loadPath = info.path();
138 for (char **pp = allowedCSPs; *pp; pp++)
139 if (loadPath == *pp)
140 goto allowed;
141 CssmError::throwMe(CSSM_ERRCODE_MODULE_MANIFEST_VERIFY_FAILED);
142 allowed: ;
143 }
144 #endif
145 module = new Module(this, info, loader(info.path()));
146 moduleMap[guid] = module;
147 } else {
148 module = it->second;
149 }
150 module->add(callback);
151 //@@@ verify against keyHierarchy
152 }
153
154
155 //
156 // Unload a module.
157 // THREADS: Locking Manager(1), Module(2).
158 //
159 void CssmManager::unloadModule(const Guid &guid,
160 const ModuleCallback &callback)
161 {
162 StLock<Mutex> _(mLock);
163 Module *module = getModule(guid);
164 if (module->unload(callback)) {
165 moduleMap.erase(guid);
166 delete module;
167 }
168 }
169
170
171 //
172 // Introductions
173 //
174 void CssmManager::introduce(const Guid &,
175 CSSM_KEY_HIERARCHY)
176 {
177 StLock<Mutex> _(mLock);
178 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
179 }
180
181 void CssmManager::unIntroduce(const Guid &)
182 {
183 StLock<Mutex> _(mLock);
184 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
185 }
186
187
188 //
189 // Support.
190 // THREADS: These utilities run under lock protection by the caller.
191 //
192 void CssmManager::checkVersion(const CSSM_VERSION &version)
193 {
194 if (version.Major != 2)
195 CssmError::throwMe(CSSM_ERRCODE_INCOMPATIBLE_VERSION);
196 if (version.Minor != 0)
197 CssmError::throwMe(CSSM_ERRCODE_INCOMPATIBLE_VERSION);
198 }
199
200 Module *CssmManager::getModule(const Guid &guid)
201 {
202 ModuleMap::iterator it = moduleMap.find(guid);
203 if (it == moduleMap.end())
204 CssmError::throwMe(CSSMERR_CSSM_MODULE_NOT_LOADED);
205 return it->second;
206 }