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_utilities/threading.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 <security_utilities/vproc++.h>
41 #include "codesigdb.h"
42 #include "connection.h"
45 #include "localdatabase.h"
46 #include "kcdatabase.h"
47 #include "authority.h"
48 #include "AuthorizationEngine.h"
52 // The authority itself. You will usually only have one of these.
54 class Authority
: public Authorization::Engine
{
56 Authority(const char *configFile
);
61 // The server object itself. This is the "go to" object for anyone who wants
62 // to access the server's global state. It runs the show.
63 // There is only one Server, and its name is Server::active().
65 // Server also acts as the global-scope nexus of securityd's object mesh.
66 // Sessions have Server as their parent, and global-scope objects have it
67 // as their referent. The Server is never kill()ed; though kill(globalObject)
68 // may make sense. Also, we can search for global-scope objects by using the
69 // findFirst/allReferences feature of Node<>.
71 class Server
: public PerGlobal
,
72 public MachPlusPlus::MachServer
,
73 public UniformRandomBlobs
<DevRandomGenerator
> {
75 Server(Authority
&myAuthority
, CodeSignatures
&signatures
, const char *bootstrapName
);
78 // run the server until it shuts down
82 // Retrieve pieces of the Server's object web.
83 // These are all static methods that use the active() Server of this thread.
85 static Server
&active() { return safer_cast
<Server
&>(MachServer::active()); }
86 static const char *bootstrapName() { return active().mBootstrapName
.c_str(); }
87 static unsigned int verbosity() { return active().mVerbosity
; }
90 // Each thread has at most one "active connection". If the server is currently
91 // servicing a request received through a Connection, that's it. Otherwise
94 static Connection
&connection(mach_port_t replyPort
, audit_token_t
&auditToken
); // find by reply port and make active
95 static Connection
&connection(bool tolerant
= false); // return active (or fail unless tolerant)
96 static void requestComplete(CSSM_RETURN
&rcode
); // de-activate active connection
99 // Process and session of the active Connection
101 static Process
&process();
102 static Session
&session();
105 // Find objects from their client handles.
106 // These will all throw on invalid handles, and the RefPointer<> results are always non-NULL.
108 static RefPointer
<Key
> key(KeyHandle key
);
109 static RefPointer
<Key
> optionalKey(KeyHandle k
) { return (k
== noKey
) ? NULL
: key(k
); }
110 static RefPointer
<Database
> database(DbHandle db
);
111 static RefPointer
<KeychainDatabase
> keychain(DbHandle db
);
112 static RefPointer
<Database
> optionalDatabase(DbHandle db
, bool persistent
= true);
113 static AclSource
&aclBearer(AclKind kind
, U32HandleObject::Handle handle
);
115 // Generic version of handle lookup
116 template <class ProcessBearer
>
117 static RefPointer
<ProcessBearer
> find(uint32_t handle
, CSSM_RETURN notFoundError
)
119 RefPointer
<ProcessBearer
> object
=
120 U32HandleObject::findRef
<ProcessBearer
>(handle
, notFoundError
);
121 if (object
->process() != Server::process())
122 CssmError::throwMe(notFoundError
);
127 // publicly accessible components of the active server
129 static Authority
&authority() { return active().mAuthority
; }
130 static CodeSignatures
&codeSignatures() { return active().mCodeSignatures
; }
131 static CssmClient::CSP
&csp() { return active().mCSP
; }
135 // Initialize CSSM and MDS
137 void loadCssm(bool mdsIsInstalled
);
140 // set up a new connection
145 void setupConnection(ConnectLevel type
, Port replyPort
, Port taskPort
, const audit_token_t
&auditToken
,
146 const ClientSetupInfo
*info
= NULL
);
148 void endConnection(Port replyPort
);
150 static void releaseWhenDone(Allocator
&alloc
, void *memory
)
151 { MachServer::active().releaseWhenDone(alloc
, memory
); }
152 static void releaseWhenDone(void *memory
)
153 { releaseWhenDone(Allocator::standard(), memory
); }
156 // implementation methods of MachServer
157 boolean_t
handle(mach_msg_header_t
*in
, mach_msg_header_t
*out
);
158 void notifyDeadName(Port port
);
159 void notifyNoSenders(Port port
, mach_port_mscount_t
);
160 void threadLimitReached(UInt32 count
);
164 class SleepWatcher
: public MachPlusPlus::PortPowerWatcher
{
166 void systemWillSleep();
167 void systemIsWaking();
168 void systemWillPowerOn();
170 void add(PowerWatcher
*client
);
171 void remove(PowerWatcher
*client
);
174 set
<PowerWatcher
*> mPowerClients
;
177 SleepWatcher sleepWatcher
;
180 using MachServer::add
;
181 using MachServer::remove
;
182 void add(MachPlusPlus::PowerWatcher
*client
) { StLock
<Mutex
> _(*this); sleepWatcher
.add(client
); }
183 void remove(MachPlusPlus::PowerWatcher
*client
) { StLock
<Mutex
> _(*this); sleepWatcher
.remove(client
); }
186 Process
*findPid(pid_t pid
) const;
188 void verbosity(unsigned int v
) { mVerbosity
= v
; }
189 void waitForClients(bool waiting
); // set waiting behavior
190 void beginShutdown(); // start delayed shutdown if configured
191 bool shuttingDown() const { return mShuttingDown
; }
192 void shutdownSnitch(); // report lingering clients
194 void associateThread() { perThread().server
= this; }
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