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 "codesigdb.h"
38 #include "connection.h"
41 #include "localdatabase.h"
42 #include "kcdatabase.h"
46 // The server object itself. This is the "go to" object for anyone who wants
47 // to access the server's global state. It runs the show.
48 // There is only one Server, and its name is Server::active().
50 // Server also acts as the global-scope nexus of securityd's object mesh.
51 // Sessions have Server as their parent, and global-scope objects have it
52 // as their referent. The Server is never kill()ed; though kill(globalObject)
53 // may make sense. Also, we can search for global-scope objects by using the
54 // findFirst/allReferences feature of Node<>.
56 class Server
: public PerGlobal
,
57 public MachPlusPlus::MachServer
{
59 Server(CodeSignatures
&signatures
, const char *bootstrapName
);
62 // run the server until it shuts down
66 // Retrieve pieces of the Server's object web.
67 // These are all static methods that use the active() Server of this thread.
69 static Server
&active() { return safer_cast
<Server
&>(MachServer::active()); }
70 static const char *bootstrapName() { return active().mBootstrapName
.c_str(); }
71 static unsigned int verbosity() { return active().mVerbosity
; }
74 // Each thread has at most one "active connection". If the server is currently
75 // servicing a request received through a Connection, that's it. Otherwise
78 static Connection
&connection(mach_port_t replyPort
, audit_token_t
&auditToken
); // find by reply port and make active
79 static Connection
&connection(bool tolerant
= false); // return active (or fail unless tolerant)
80 static void requestComplete(CSSM_RETURN
&rcode
); // de-activate active connection
83 // Process and session of the active Connection
85 static Process
&process();
86 static Session
&session();
89 // Find objects from their client handles.
90 // These will all throw on invalid handles, and the RefPointer<> results are always non-NULL.
92 static RefPointer
<Key
> key(KeyHandle key
);
93 static RefPointer
<Key
> optionalKey(KeyHandle k
) { return (k
== noKey
) ? NULL
: key(k
); }
94 static RefPointer
<Database
> database(DbHandle db
);
95 static RefPointer
<KeychainDatabase
> keychain(DbHandle db
);
96 static RefPointer
<Database
> optionalDatabase(DbHandle db
, bool persistent
= true);
97 static AclSource
&aclBearer(AclKind kind
, U32HandleObject::Handle handle
);
99 // Generic version of handle lookup
100 template <class ProcessBearer
>
101 static RefPointer
<ProcessBearer
> find(uint32_t handle
, CSSM_RETURN notFoundError
)
103 RefPointer
<ProcessBearer
> object
=
104 U32HandleObject::findRef
<ProcessBearer
>(handle
, notFoundError
);
105 if (object
->process() != Server::process())
106 CssmError::throwMe(notFoundError
);
111 // publicly accessible components of the active server
113 static CodeSignatures
&codeSignatures() { return active().mCodeSignatures
; }
114 static CssmClient::CSP
&csp() { return active().mCSP
; }
118 // Initialize CSSM and MDS
120 void loadCssm(bool mdsIsInstalled
);
123 // set up a new connection
128 void setupConnection(ConnectLevel type
, Port replyPort
, Port taskPort
, const audit_token_t
&auditToken
,
129 const ClientSetupInfo
*info
= NULL
);
131 void endConnection(Port replyPort
);
133 static void releaseWhenDone(Allocator
&alloc
, void *memory
)
134 { MachServer::active().releaseWhenDone(alloc
, memory
); }
135 static void releaseWhenDone(void *memory
)
136 { releaseWhenDone(Allocator::standard(), memory
); }
139 // implementation methods of MachServer
140 boolean_t
handle(mach_msg_header_t
*in
, mach_msg_header_t
*out
);
141 void notifyDeadName(Port port
);
142 void notifyNoSenders(Port port
, mach_port_mscount_t
);
143 void threadLimitReached(UInt32 count
);
147 class SleepWatcher
: public MachPlusPlus::PortPowerWatcher
{
149 void systemWillSleep();
150 void systemIsWaking();
151 void systemWillPowerOn();
153 void add(PowerWatcher
*client
);
154 void remove(PowerWatcher
*client
);
157 set
<PowerWatcher
*> mPowerClients
;
160 SleepWatcher sleepWatcher
;
163 using MachServer::add
;
164 using MachServer::remove
;
165 void add(MachPlusPlus::PowerWatcher
*client
) { StLock
<Mutex
> _(*this); sleepWatcher
.add(client
); }
166 void remove(MachPlusPlus::PowerWatcher
*client
) { StLock
<Mutex
> _(*this); sleepWatcher
.remove(client
); }
169 Process
*findPid(pid_t pid
) const;
171 void verbosity(unsigned int v
) { mVerbosity
= v
; }
172 void waitForClients(bool waiting
); // set waiting behavior
173 void beginShutdown(); // start delayed shutdown if configured
174 bool shuttingDown() const { return mShuttingDown
; }
175 void shutdownReport(); // report lingering clients to the log
176 void shutdownReport_file(); // report lingering clients to file
178 void associateThread() { perThread().server
= this; }
181 // mach bootstrap registration name
182 std::string mBootstrapName
;
184 // connection map (by client reply port)
185 PortMap
<Connection
> mConnections
;
187 // process map (by process task port)
188 typedef std::map
<pid_t
, Process
*> PidMap
;
189 PortMap
<Process
> mProcesses
; // strong reference
190 PidMap mPids
; // weak reference (subsidiary to mProcesses)
192 // Current connection, if any (per thread).
193 // Set as a side effect of calling connection(mach_port_t)
194 // and returned by connection(bool).
195 ThreadNexus
<RefPointer
<Connection
> > mCurrentConnection
;
198 CssmClient::Cssm mCssm
; // CSSM instance
199 CssmClient::Module mCSPModule
; // CSP module
200 CssmClient::CSP mCSP
; // CSP attachment
202 CodeSignatures
&mCodeSignatures
;
204 // busy state for primary state authority
205 unsigned int mVerbosity
;
206 bool mWaitForClients
;
212 // A StLock that (also) declares a longTermActivity (only) once it's been entered.
214 class LongtermStLock
: public StLock
<Mutex
> {
216 LongtermStLock(Mutex
&lck
);
217 // destructor inherited
223 // These are sent as Mach messages from ourselves to escape the limitations of
224 // the signal handler environment.
226 kern_return_t
self_server_handleSignal(mach_port_t sport
, mach_port_t taskPort
, int sig
);
227 kern_return_t
self_server_handleSession(mach_port_t sport
, mach_port_t taskPort
, uint32_t event
, uint64_t ident
);