1/*
2 * Copyright (c) 2000-2009,2012-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25//
26// server - securityd main server object
27//
28#ifndef _H_SERVER
29#define _H_SERVER
30
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"
42#include "key.h"
43#include "database.h"
44#include "localdatabase.h"
45#include "kcdatabase.h"
46#include "authority.h"
47#include "AuthorizationEngine.h"
48#include <map>
49
50#define EQUIVALENCEDBPATH "/var/db/CodeEquivalenceDatabase"
51
52
53//
54// The authority itself. You will usually only have one of these.
55//
56class Authority : public Authorization::Engine {
57public:
58	Authority(const char *configFile);
59	~Authority();
60};
61
62//
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().
66//
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<>.
72//
73class Server : public PerGlobal,
74			   public MachPlusPlus::MachServer,
75               public UniformRandomBlobs<DevRandomGenerator> {
76public:
77	Server(Authority &myAuthority, CodeSignatures &signatures, const char *bootstrapName);
78	~Server();
79
80    // run the server until it shuts down
81	void run();
82
83    //
84    // Retrieve pieces of the Server's object web.
85    // These are all static methods that use the active() Server of this thread.
86    //
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; }
90
91	//
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
94	// there is none.
95	//
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
99
100	//
101	// Process and session of the active Connection
102	//
103	static Process &process();
104	static Session &session();
105
106	//
107	// Find objects from their client handles.
108	// These will all throw on invalid handles, and the RefPointer<> results are always non-NULL.
109	//
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);
116
117	// Generic version of handle lookup
118	template <class ProcessBearer>
119    static RefPointer<ProcessBearer> find(uint32_t handle, CSSM_RETURN notFoundError)
120	{
121		RefPointer<ProcessBearer> object =
122			U32HandleObject::findRef<ProcessBearer>(handle, notFoundError);
123		if (object->process() != Server::process())
124			CssmError::throwMe(notFoundError);
125		return object;
126	}
127
128	//
129	// publicly accessible components of the active server
130	//
131    static Authority &authority() { return active().mAuthority; }
132	static CodeSignatures &codeSignatures() { return active().mCodeSignatures; }
133	static CssmClient::CSP &csp() { return active().mCSP; }
134
135public:
136	//
137	// Initialize CSSM and MDS
138	//
139	void loadCssm(bool mdsIsInstalled);
140
141public:
142	// set up a new connection
143	enum ConnectLevel {
144		connectNewProcess,
145		connectNewThread
146	};
147	void setupConnection(ConnectLevel type, Port replyPort, Port taskPort, const audit_token_t &auditToken,
148		const ClientSetupInfo *info = NULL);
149
150	void endConnection(Port replyPort);
151
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); }
156
157protected:
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);
163	void eventDone();
164
165private:
166	class SleepWatcher : public MachPlusPlus::PortPowerWatcher {
167	public:
168		void systemWillSleep();
169		void systemIsWaking();
170		void systemWillPowerOn();
171
172		void add(PowerWatcher *client);
173		void remove(PowerWatcher *client);
174
175	private:
176		set<PowerWatcher *> mPowerClients;
177	};
178
179	SleepWatcher sleepWatcher;
180
181public:
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); }
186
187public:
188	Process *findPid(pid_t pid) const;
189
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
195	bool inDarkWake();
196    void associateThread() { perThread().server = this; }
197
198private:
199	// mach bootstrap registration name
200	std::string mBootstrapName;
201
202	// connection map (by client reply port)
203	PortMap<Connection> mConnections;
204
205	// process map (by process task port)
206	typedef std::map<pid_t, Process *> PidMap;
207	PortMap<Process> mProcesses;					// strong reference
208	PidMap mPids;									// weak reference (subsidiary to mProcesses)
209
210	// Current connection, if any (per thread).
211	// Set as a side effect of calling connection(mach_port_t)
212	// and returned by connection(bool).
213	ThreadNexus<RefPointer<Connection> > mCurrentConnection;
214
215    // CSSM components
216    CssmClient::Cssm mCssm;				// CSSM instance
217    CssmClient::Module mCSPModule;		// CSP module
218	CssmClient::CSP mCSP;				// CSP attachment
219
220	Authority &mAuthority;
221	CodeSignatures &mCodeSignatures;
222
223	// busy state for primary state authority
224	unsigned int mVerbosity;
225	bool mWaitForClients;
226	bool mShuttingDown;
227};
228
229
230//
231// A StLock that (also) declares a longTermActivity (only) once it's been entered.
232//
233class LongtermStLock : public StLock<Mutex> {
234public:
235	LongtermStLock(Mutex &lck);
236	// destructor inherited
237};
238
239#endif //_H_SERVER
240