2 * Copyright (c) 2000-2009,2012-2014 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"
49 // The server object itself. This is the "go to" object for anyone who wants
50 // to access the server's global state. It runs the show.
51 // There is only one Server, and its name is Server::active().
53 // Server also acts as the global-scope nexus of securityd's object mesh.
54 // Sessions have Server as their parent, and global-scope objects have it
55 // as their referent. The Server is never kill()ed; though kill(globalObject)
56 // may make sense. Also, we can search for global-scope objects by using the
57 // findFirst/allReferences feature of Node<>.
59 class Server
: public PerGlobal
,
60 public MachPlusPlus::MachServer
,
61 public UniformRandomBlobs
<DevRandomGenerator
> {
63 Server(CodeSignatures
&signatures
, const char *bootstrapName
);
66 // run the server until it shuts down
70 // Retrieve pieces of the Server's object web.
71 // These are all static methods that use the active() Server of this thread.
73 static Server
&active() { return safer_cast
<Server
&>(MachServer::active()); }
74 static const char *bootstrapName() { return active().mBootstrapName
.c_str(); }
75 static unsigned int verbosity() { return active().mVerbosity
; }
78 // Each thread has at most one "active connection". If the server is currently
79 // servicing a request received through a Connection, that's it. Otherwise
82 static Connection
&connection(mach_port_t replyPort
, audit_token_t
&auditToken
); // find by reply port and make active
83 static Connection
&connection(bool tolerant
= false); // return active (or fail unless tolerant)
84 static void requestComplete(CSSM_RETURN
&rcode
); // de-activate active connection
87 // Process and session of the active Connection
89 static Process
&process();
90 static Session
&session();
93 // Find objects from their client handles.
94 // These will all throw on invalid handles, and the RefPointer<> results are always non-NULL.
96 static RefPointer
<Key
> key(KeyHandle key
);
97 static RefPointer
<Key
> optionalKey(KeyHandle k
) { return (k
== noKey
) ? NULL
: key(k
); }
98 static RefPointer
<Database
> database(DbHandle db
);
99 static RefPointer
<KeychainDatabase
> keychain(DbHandle db
);
100 static RefPointer
<Database
> optionalDatabase(DbHandle db
, bool persistent
= true);
101 static AclSource
&aclBearer(AclKind kind
, U32HandleObject::Handle handle
);
103 // Generic version of handle lookup
104 template <class ProcessBearer
>
105 static RefPointer
<ProcessBearer
> find(uint32_t handle
, CSSM_RETURN notFoundError
)
107 RefPointer
<ProcessBearer
> object
=
108 U32HandleObject::findRef
<ProcessBearer
>(handle
, notFoundError
);
109 if (object
->process() != Server::process())
110 CssmError::throwMe(notFoundError
);
115 // publicly accessible components of the active server
117 static CodeSignatures
&codeSignatures() { return active().mCodeSignatures
; }
118 static CssmClient::CSP
&csp() { return active().mCSP
; }
122 // Initialize CSSM and MDS
124 void loadCssm(bool mdsIsInstalled
);
127 // set up a new connection
132 void setupConnection(ConnectLevel type
, Port replyPort
, Port taskPort
, const audit_token_t
&auditToken
,
133 const ClientSetupInfo
*info
= NULL
);
135 void endConnection(Port replyPort
);
137 static void releaseWhenDone(Allocator
&alloc
, void *memory
)
138 { MachServer::active().releaseWhenDone(alloc
, memory
); }
139 static void releaseWhenDone(void *memory
)
140 { releaseWhenDone(Allocator::standard(), memory
); }
143 // implementation methods of MachServer
144 boolean_t
handle(mach_msg_header_t
*in
, mach_msg_header_t
*out
);
145 void notifyDeadName(Port port
);
146 void notifyNoSenders(Port port
, mach_port_mscount_t
);
147 void threadLimitReached(UInt32 count
);
151 class SleepWatcher
: public MachPlusPlus::PortPowerWatcher
{
153 void systemWillSleep();
154 void systemIsWaking();
155 void systemWillPowerOn();
157 void add(PowerWatcher
*client
);
158 void remove(PowerWatcher
*client
);
161 set
<PowerWatcher
*> mPowerClients
;
164 SleepWatcher sleepWatcher
;
167 using MachServer::add
;
168 using MachServer::remove
;
169 void add(MachPlusPlus::PowerWatcher
*client
) { StLock
<Mutex
> _(*this); sleepWatcher
.add(client
); }
170 void remove(MachPlusPlus::PowerWatcher
*client
) { StLock
<Mutex
> _(*this); sleepWatcher
.remove(client
); }
173 Process
*findPid(pid_t pid
) const;
175 void verbosity(unsigned int v
) { mVerbosity
= v
; }
176 void waitForClients(bool waiting
); // set waiting behavior
177 void beginShutdown(); // start delayed shutdown if configured
178 bool shuttingDown() const { return mShuttingDown
; }
179 void shutdownSnitch(); // report lingering clients
181 void associateThread() { perThread().server
= this; }
184 // mach bootstrap registration name
185 std::string mBootstrapName
;
187 // connection map (by client reply port)
188 PortMap
<Connection
> mConnections
;
190 // process map (by process task port)
191 typedef std::map
<pid_t
, Process
*> PidMap
;
192 PortMap
<Process
> mProcesses
; // strong reference
193 PidMap mPids
; // weak reference (subsidiary to mProcesses)
195 // Current connection, if any (per thread).
196 // Set as a side effect of calling connection(mach_port_t)
197 // and returned by connection(bool).
198 ThreadNexus
<RefPointer
<Connection
> > mCurrentConnection
;
201 CssmClient::Cssm mCssm
; // CSSM instance
202 CssmClient::Module mCSPModule
; // CSP module
203 CssmClient::CSP mCSP
; // CSP attachment
205 CodeSignatures
&mCodeSignatures
;
207 // busy state for primary state authority
208 unsigned int mVerbosity
;
209 bool mWaitForClients
;
215 // A StLock that (also) declares a longTermActivity (only) once it's been entered.
217 class LongtermStLock
: public StLock
<Mutex
> {
219 LongtermStLock(Mutex
&lck
);
220 // destructor inherited
226 // These are sent as Mach messages from ourselves to escape the limitations of
227 // the signal handler environment.
229 kern_return_t
self_server_handleSignal(mach_port_t sport
, mach_port_t taskPort
, int sig
);
230 kern_return_t
self_server_handleSession(mach_port_t sport
, mach_port_t taskPort
, uint32_t event
, uint64_t ident
);