2 * Copyright (c) 2000-2004 Apple Computer, 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@
23 #define SHUTDOWN_SNITCH
27 // server - securityd main server object
32 #include "structure.h"
33 #include <security_utilities/machserver.h>
34 #include <security_utilities/powerwatch.h>
35 #include <security_utilities/ccaudit.h>
36 #include <security_cdsa_client/cssmclient.h>
37 #include <security_cdsa_client/cspclient.h>
38 #include <security_utilities/devrandom.h>
39 #include <security_cdsa_utilities/uniformrandom.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(); }
91 // Each thread has at most one "active connection". If the server is currently
92 // servicing a request received through a Connection, that's it. Otherwise
95 static Connection
&connection(mach_port_t replyPort
); // find by reply port and make active
96 static Connection
&connection(bool tolerant
= false); // return active (or fail unless tolerant)
97 static void requestComplete(CSSM_RETURN
&rcode
); // de-activate active connection
100 // Process and session of the active Connection
102 static Process
&process();
103 static Session
&session();
106 // Find objects from their client handles.
107 // These will all throw on invalid handles, and the RefPointer<> results are always non-NULL.
109 static RefPointer
<Key
> key(KeyHandle key
);
110 static RefPointer
<Key
> optionalKey(KeyHandle k
) { return (k
== noKey
) ? NULL
: key(k
); }
111 static RefPointer
<Database
> database(DbHandle db
);
112 static RefPointer
<KeychainDatabase
> keychain(DbHandle db
);
113 static RefPointer
<Database
> optionalDatabase(DbHandle db
, bool persistent
= true);
114 static AclSource
&aclBearer(AclKind kind
, CSSM_HANDLE handle
);
116 // Generic version of handle lookup
117 template <class ProcessBearer
>
118 static RefPointer
<ProcessBearer
> find(CSSM_HANDLE handle
, CSSM_RETURN notFoundError
)
120 RefPointer
<ProcessBearer
> object
=
121 HandleObject::findRef
<ProcessBearer
>(handle
, notFoundError
);
122 if (object
->process() != Server::process())
123 CssmError::throwMe(notFoundError
);
128 // publicly accessible components of the active server
130 static Authority
&authority() { return active().mAuthority
; }
131 static CodeSignatures
&codeSignatures() { return active().mCodeSignatures
; }
132 static CssmClient::CSP
&csp() { return active().mCSP
; }
136 // Initialize CSSM and MDS
141 // set up a new connection
147 void setupConnection(ConnectLevel type
, Port servicePort
, Port replyPort
, Port taskPort
,
148 const audit_token_t
&auditToken
,
149 const ClientSetupInfo
*info
= NULL
, const char *executablePath
= NULL
);
151 void endConnection(Port replyPort
);
153 static void releaseWhenDone(Allocator
&alloc
, void *memory
)
154 { MachServer::active().releaseWhenDone(alloc
, memory
); }
155 static void releaseWhenDone(void *memory
)
156 { releaseWhenDone(Allocator::standard(), memory
); }
159 // implementation methods of MachServer
160 boolean_t
handle(mach_msg_header_t
*in
, mach_msg_header_t
*out
);
161 void notifyDeadName(Port port
);
162 void notifyNoSenders(Port port
, mach_port_mscount_t
);
163 void threadLimitReached(UInt32 count
);
167 class SleepWatcher
: public MachPlusPlus::PortPowerWatcher
{
169 void systemWillSleep();
170 void systemIsWaking();
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 waitForClients(bool waiting
); // set waiting behavior
191 bool beginShutdown(); // start delayed shutdown if configured
194 // mach bootstrap registration name
195 std::string mBootstrapName
;
197 // connection map (by client reply port)
198 PortMap
<Connection
> mConnections
;
200 // process map (by process task port)
201 typedef std::map
<pid_t
, Process
*> PidMap
;
202 PortMap
<Process
> mProcesses
; // strong reference
203 PidMap mPids
; // weak reference (subsidiary to mProcesses)
206 shutdownImmediately
, // shut down immediately on SIGTERM
207 shutdownDelayed
, // wait for clients on SIGTERM
208 shuttingDown
// delayed shutdown in progress
209 } mShutdown
; // shutdown mode
210 void shutdownSnitch(); // rat out lingering clients (to syslog)
212 // Current connection, if any (per thread).
213 // Set as a side effect of calling connection(mach_port_t)
214 // and returned by connection(bool).
215 ThreadNexus
<RefPointer
<Connection
> > mCurrentConnection
;
218 CssmClient::Cssm mCssm
; // CSSM instance
219 CssmClient::Module mCSPModule
; // CSP module
220 CssmClient::CSP mCSP
; // CSP attachment
222 Authority
&mAuthority
;
223 CodeSignatures
&mCodeSignatures
;
225 // Per-process audit initialization
226 CommonCriteria::AuditSession mAudit
;
231 // A StLock that (also) declares a longTermActivity (only) once it's been entered.
233 class LongtermStLock
: public StLock
<Mutex
> {
235 LongtermStLock(Mutex
&lck
);
236 // destructor inherited