]> git.saurik.com Git - apple/security.git/blob - securityd/src/server.h
Security-59306.11.20.tar.gz
[apple/security.git] / securityd / src / server.h
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 "codesigdb.h"
38 #include "connection.h"
39 #include "key.h"
40 #include "database.h"
41 #include "localdatabase.h"
42 #include "kcdatabase.h"
43 #include <map>
44
45 //
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().
49 //
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<>.
55 //
56 class Server : public PerGlobal,
57 public MachPlusPlus::MachServer {
58 public:
59 Server(CodeSignatures &signatures, const char *bootstrapName);
60 ~Server();
61
62 // run the server until it shuts down
63 void run();
64
65 //
66 // Retrieve pieces of the Server's object web.
67 // These are all static methods that use the active() Server of this thread.
68 //
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; }
72
73 //
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
76 // there is none.
77 //
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
81
82 //
83 // Process and session of the active Connection
84 //
85 static Process &process();
86 static Session &session();
87
88 //
89 // Find objects from their client handles.
90 // These will all throw on invalid handles, and the RefPointer<> results are always non-NULL.
91 //
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);
98
99 // Generic version of handle lookup
100 template <class ProcessBearer>
101 static RefPointer<ProcessBearer> find(uint32_t handle, CSSM_RETURN notFoundError)
102 {
103 RefPointer<ProcessBearer> object =
104 U32HandleObject::findRef<ProcessBearer>(handle, notFoundError);
105 if (object->process() != Server::process())
106 CssmError::throwMe(notFoundError);
107 return object;
108 }
109
110 //
111 // publicly accessible components of the active server
112 //
113 static CodeSignatures &codeSignatures() { return active().mCodeSignatures; }
114 static CssmClient::CSP &csp() { return active().mCSP; }
115
116 public:
117 //
118 // Initialize CSSM and MDS
119 //
120 void loadCssm(bool mdsIsInstalled);
121
122 public:
123 // set up a new connection
124 enum ConnectLevel {
125 connectNewProcess,
126 connectNewThread
127 };
128 void setupConnection(ConnectLevel type, Port replyPort, Port taskPort, const audit_token_t &auditToken,
129 const ClientSetupInfo *info = NULL);
130
131 void endConnection(Port replyPort);
132
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); }
137
138 protected:
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);
144 void eventDone();
145
146 private:
147 class SleepWatcher : public MachPlusPlus::PortPowerWatcher {
148 public:
149 void systemWillSleep();
150 void systemIsWaking();
151 void systemWillPowerOn();
152
153 void add(PowerWatcher *client);
154 void remove(PowerWatcher *client);
155
156 private:
157 set<PowerWatcher *> mPowerClients;
158 };
159
160 SleepWatcher sleepWatcher;
161
162 public:
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); }
167
168 public:
169 Process *findPid(pid_t pid) const;
170
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
177 bool inDarkWake();
178 void associateThread() { perThread().server = this; }
179
180 private:
181 // mach bootstrap registration name
182 std::string mBootstrapName;
183
184 // connection map (by client reply port)
185 PortMap<Connection> mConnections;
186
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)
191
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;
196
197 // CSSM components
198 CssmClient::Cssm mCssm; // CSSM instance
199 CssmClient::Module mCSPModule; // CSP module
200 CssmClient::CSP mCSP; // CSP attachment
201
202 CodeSignatures &mCodeSignatures;
203
204 // busy state for primary state authority
205 unsigned int mVerbosity;
206 bool mWaitForClients;
207 bool mShuttingDown;
208 };
209
210
211 //
212 // A StLock that (also) declares a longTermActivity (only) once it's been entered.
213 //
214 class LongtermStLock : public StLock<Mutex> {
215 public:
216 LongtermStLock(Mutex &lck);
217 // destructor inherited
218 };
219
220
221 //
222 // Handling signals.
223 // These are sent as Mach messages from ourselves to escape the limitations of
224 // the signal handler environment.
225 //
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);
228
229 #endif //_H_SERVER