2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 // manager - CSSM manager/supervisor objects.
27 #include <Security/debugging.h>
32 // Constructing a CssmManager instance.
33 // This does almost nothing - the actual intialization happens in the initialize() method.
35 CssmManager::CssmManager() : MdsComponent(gGuidCssm
)
37 initCount
= 0; // not yet initialized
40 CssmManager::~CssmManager()
43 secdebug("cssm", "CSSM forcibly shutting down");
48 // CSSM initialization.
49 // THREADS: This function must run in an uncontested environment.
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
)
57 StLock
<Mutex
> _(mLock
);
59 // check version first
60 checkVersion(version
);
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
);
69 secdebug("cssm", "re-initializing CSSM (%d levels)", initCount
);
73 // we don't support thread scope privileges
74 if (scope
== CSSM_PRIVILEGE_SCOPE_THREAD
)
75 CssmError::throwMe(CSSMERR_CSSM_SCOPE_NOT_SUPPORTED
);
77 // keep the init arguments for future use - these become instance constants
78 mPrivilegeScope
= scope
;
79 mKeyHierarchy
= keyHierarchy
;
80 mPvcPolicy
= pvcPolicy
;
81 mCallerGuid
= callerGuid
;
85 secdebug("cssm", "CSSM initialized");
90 // CSSM Termination processing.
91 // Returns true if this was the final (true) termination, false if a nested Init was undone.
93 bool CssmManager::terminate()
95 StLock
<Mutex
> _(mLock
);
98 CssmError::throwMe(CSSMERR_CSSM_NOT_INITIALIZED
);
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
106 initCount
--; // nested INIT, just count down
107 secdebug("cssm", "CSSM nested termination (%d remaining)", initCount
);
113 #if defined(RESTRICTED_CSP_LOADING)
114 static char *allowedCSPs
[] = {
115 "/System/Library/Security/AppleCSP.bundle",
116 "/System/Library/Security/AppleCSPDL.bundle",
123 // Load a module (well, try).
125 void CssmManager::loadModule(const Guid
&guid
,
127 const ModuleCallback
&callback
)
129 StLock
<Mutex
> _(mLock
);
130 ModuleMap::iterator it
= moduleMap
.find(guid
);
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
++)
141 CssmError::throwMe(CSSM_ERRCODE_MODULE_MANIFEST_VERIFY_FAILED
);
145 module = new Module(this, info
, loader(info
.path()));
146 moduleMap
[guid
] = module;
150 module->add(callback
);
151 //@@@ verify against keyHierarchy
157 // THREADS: Locking Manager(1), Module(2).
159 void CssmManager::unloadModule(const Guid
&guid
,
160 const ModuleCallback
&callback
)
162 StLock
<Mutex
> _(mLock
);
163 Module
*module = getModule(guid
);
164 if (module->unload(callback
)) {
165 moduleMap
.erase(guid
);
174 void CssmManager::introduce(const Guid
&,
177 StLock
<Mutex
> _(mLock
);
178 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED
);
181 void CssmManager::unIntroduce(const Guid
&)
183 StLock
<Mutex
> _(mLock
);
184 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED
);
190 // THREADS: These utilities run under lock protection by the caller.
192 void CssmManager::checkVersion(const CSSM_VERSION
&version
)
194 if (version
.Major
!= 2)
195 CssmError::throwMe(CSSM_ERRCODE_INCOMPATIBLE_VERSION
);
196 if (version
.Minor
!= 0)
197 CssmError::throwMe(CSSM_ERRCODE_INCOMPATIBLE_VERSION
);
200 Module
*CssmManager::getModule(const Guid
&guid
)
202 ModuleMap::iterator it
= moduleMap
.find(guid
);
203 if (it
== moduleMap
.end())
204 CssmError::throwMe(CSSMERR_CSSM_MODULE_NOT_LOADED
);