2 * Copyright (c) 2000-2004,2008-2009 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 // server - securityd main server object
31 #include "structure.h"
32 #include <security_utilities/machserver.h>
33 #include <security_utilities/powerwatch.h>
34 #include <security_utilities/ccaudit.h>
35 #include <security_cdsa_client/cssmclient.h>
36 #include <security_cdsa_client/cspclient.h>
37 #include <security_utilities/devrandom.h>
38 #include <security_cdsa_utilities/uniformrandom.h>
39 #include <security_utilities/vproc++.h>
40 #include "codesigdb.h"
41 #include "connection.h"
44 #include "localdatabase.h"
45 #include "kcdatabase.h"
46 #include "authority.h"
47 #include "AuthorizationEngine.h"
50 #define EQUIVALENCEDBPATH "/var/db/CodeEquivalenceDatabase"
54 // The authority itself. You will usually only have one of these.
56 class Authority
: public Authorization::Engine
{
58 Authority(const char *configFile
);
63 // The server object itself. This is the "go to" object for anyone who wants
64 // to access the server's global state. It runs the show.
65 // There is only one Server, and its name is Server::active().
67 // Server also acts as the global-scope nexus of securityd's object mesh.
68 // Sessions have Server as their parent, and global-scope objects have it
69 // as their referent. The Server is never kill()ed; though kill(globalObject)
70 // may make sense. Also, we can search for global-scope objects by using the
71 // findFirst/allReferences feature of Node<>.
73 class Server
: public PerGlobal
,
74 public MachPlusPlus::MachServer
,
75 public UniformRandomBlobs
<DevRandomGenerator
> {
77 Server(Authority
&myAuthority
, CodeSignatures
&signatures
, const char *bootstrapName
);
80 // run the server until it shuts down
84 // Retrieve pieces of the Server's object web.
85 // These are all static methods that use the active() Server of this thread.
87 static Server
&active() { return safer_cast
<Server
&>(MachServer::active()); }
88 static const char *bootstrapName() { return active().mBootstrapName
.c_str(); }
89 static unsigned int verbosity() { return active().mVerbosity
; }
92 // Each thread has at most one "active connection". If the server is currently
93 // servicing a request received through a Connection, that's it. Otherwise
96 static Connection
&connection(mach_port_t replyPort
, audit_token_t
&auditToken
); // find by reply port and make active
97 static Connection
&connection(bool tolerant
= false); // return active (or fail unless tolerant)
98 static void requestComplete(CSSM_RETURN
&rcode
); // de-activate active connection
101 // Process and session of the active Connection
103 static Process
&process();
104 static Session
&session();
107 // Find objects from their client handles.
108 // These will all throw on invalid handles, and the RefPointer<> results are always non-NULL.
110 static RefPointer
<Key
> key(KeyHandle key
);
111 static RefPointer
<Key
> optionalKey(KeyHandle k
) { return (k
== noKey
) ? NULL
: key(k
); }
112 static RefPointer
<Database
> database(DbHandle db
);
113 static RefPointer
<KeychainDatabase
> keychain(DbHandle db
);
114 static RefPointer
<Database
> optionalDatabase(DbHandle db
, bool persistent
= true);
115 static AclSource
&aclBearer(AclKind kind
, U32HandleObject::Handle handle
);
117 // Generic version of handle lookup
118 template <class ProcessBearer
>
119 static RefPointer
<ProcessBearer
> find(uint32_t handle
, CSSM_RETURN notFoundError
)
121 RefPointer
<ProcessBearer
> object
=
122 U32HandleObject::findRef
<ProcessBearer
>(handle
, notFoundError
);
123 if (object
->process() != Server::process())
124 CssmError::throwMe(notFoundError
);
129 // publicly accessible components of the active server
131 static Authority
&authority() { return active().mAuthority
; }
132 static CodeSignatures
&codeSignatures() { return active().mCodeSignatures
; }
133 static CssmClient::CSP
&csp() { return active().mCSP
; }
137 // Initialize CSSM and MDS
139 void loadCssm(bool mdsIsInstalled
);
142 // set up a new connection
147 void setupConnection(ConnectLevel type
, Port replyPort
, Port taskPort
, const audit_token_t
&auditToken
,
148 const ClientSetupInfo
*info
= NULL
);
150 void endConnection(Port replyPort
);
152 static void releaseWhenDone(Allocator
&alloc
, void *memory
)
153 { MachServer::active().releaseWhenDone(alloc
, memory
); }
154 static void releaseWhenDone(void *memory
)
155 { releaseWhenDone(Allocator::standard(), memory
); }
158 // implementation methods of MachServer
159 boolean_t
handle(mach_msg_header_t
*in
, mach_msg_header_t
*out
);
160 void notifyDeadName(Port port
);
161 void notifyNoSenders(Port port
, mach_port_mscount_t
);
162 void threadLimitReached(UInt32 count
);
166 class SleepWatcher
: public MachPlusPlus::PortPowerWatcher
{
168 void systemWillSleep();
169 void systemIsWaking();
170 void systemWillPowerOn();
172 void add(PowerWatcher
*client
);
173 void remove(PowerWatcher
*client
);
176 set
<PowerWatcher
*> mPowerClients
;
179 SleepWatcher sleepWatcher
;
182 using MachServer::add
;
183 using MachServer::remove
;
184 void add(MachPlusPlus::PowerWatcher
*client
) { StLock
<Mutex
> _(*this); sleepWatcher
.add(client
); }
185 void remove(MachPlusPlus::PowerWatcher
*client
) { StLock
<Mutex
> _(*this); sleepWatcher
.remove(client
); }
188 Process
*findPid(pid_t pid
) const;
190 void verbosity(unsigned int v
) { mVerbosity
= v
; }
191 void waitForClients(bool waiting
); // set waiting behavior
192 void beginShutdown(); // start delayed shutdown if configured
193 bool shuttingDown() const { return mShuttingDown
; }
194 void shutdownSnitch(); // report lingering clients
197 // mach bootstrap registration name
198 std::string mBootstrapName
;
200 // connection map (by client reply port)
201 PortMap
<Connection
> mConnections
;
203 // process map (by process task port)
204 typedef std::map
<pid_t
, Process
*> PidMap
;
205 PortMap
<Process
> mProcesses
; // strong reference
206 PidMap mPids
; // weak reference (subsidiary to mProcesses)
208 // Current connection, if any (per thread).
209 // Set as a side effect of calling connection(mach_port_t)
210 // and returned by connection(bool).
211 ThreadNexus
<RefPointer
<Connection
> > mCurrentConnection
;
214 CssmClient::Cssm mCssm
; // CSSM instance
215 CssmClient::Module mCSPModule
; // CSP module
216 CssmClient::CSP mCSP
; // CSP attachment
218 Authority
&mAuthority
;
219 CodeSignatures
&mCodeSignatures
;
221 // busy state for primary state authority
222 unsigned int mVerbosity
;
223 bool mWaitForClients
;
229 // A StLock that (also) declares a longTermActivity (only) once it's been entered.
231 class LongtermStLock
: public StLock
<Mutex
> {
233 LongtermStLock(Mutex
&lck
);
234 // destructor inherited