]>
Commit | Line | Data |
---|---|---|
d8f41ccd A |
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" | |
d8f41ccd A |
46 | #include <map> |
47 | ||
d8f41ccd A |
48 | // |
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(). | |
52 | // | |
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<>. | |
58 | // | |
59 | class Server : public PerGlobal, | |
60 | public MachPlusPlus::MachServer, | |
61 | public UniformRandomBlobs<DevRandomGenerator> { | |
62 | public: | |
fa7225c8 | 63 | Server(CodeSignatures &signatures, const char *bootstrapName); |
d8f41ccd A |
64 | ~Server(); |
65 | ||
66 | // run the server until it shuts down | |
67 | void run(); | |
68 | ||
69 | // | |
70 | // Retrieve pieces of the Server's object web. | |
71 | // These are all static methods that use the active() Server of this thread. | |
72 | // | |
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; } | |
76 | ||
77 | // | |
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 | |
80 | // there is none. | |
81 | // | |
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 | |
85 | ||
86 | // | |
87 | // Process and session of the active Connection | |
88 | // | |
89 | static Process &process(); | |
90 | static Session &session(); | |
91 | ||
92 | // | |
93 | // Find objects from their client handles. | |
94 | // These will all throw on invalid handles, and the RefPointer<> results are always non-NULL. | |
95 | // | |
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); | |
102 | ||
103 | // Generic version of handle lookup | |
104 | template <class ProcessBearer> | |
105 | static RefPointer<ProcessBearer> find(uint32_t handle, CSSM_RETURN notFoundError) | |
106 | { | |
107 | RefPointer<ProcessBearer> object = | |
108 | U32HandleObject::findRef<ProcessBearer>(handle, notFoundError); | |
109 | if (object->process() != Server::process()) | |
110 | CssmError::throwMe(notFoundError); | |
111 | return object; | |
112 | } | |
113 | ||
114 | // | |
115 | // publicly accessible components of the active server | |
116 | // | |
d8f41ccd A |
117 | static CodeSignatures &codeSignatures() { return active().mCodeSignatures; } |
118 | static CssmClient::CSP &csp() { return active().mCSP; } | |
119 | ||
120 | public: | |
121 | // | |
122 | // Initialize CSSM and MDS | |
123 | // | |
124 | void loadCssm(bool mdsIsInstalled); | |
125 | ||
126 | public: | |
127 | // set up a new connection | |
128 | enum ConnectLevel { | |
129 | connectNewProcess, | |
130 | connectNewThread | |
131 | }; | |
132 | void setupConnection(ConnectLevel type, Port replyPort, Port taskPort, const audit_token_t &auditToken, | |
133 | const ClientSetupInfo *info = NULL); | |
134 | ||
135 | void endConnection(Port replyPort); | |
136 | ||
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); } | |
141 | ||
142 | protected: | |
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); | |
148 | void eventDone(); | |
149 | ||
150 | private: | |
151 | class SleepWatcher : public MachPlusPlus::PortPowerWatcher { | |
152 | public: | |
153 | void systemWillSleep(); | |
154 | void systemIsWaking(); | |
155 | void systemWillPowerOn(); | |
156 | ||
157 | void add(PowerWatcher *client); | |
158 | void remove(PowerWatcher *client); | |
159 | ||
160 | private: | |
161 | set<PowerWatcher *> mPowerClients; | |
162 | }; | |
163 | ||
164 | SleepWatcher sleepWatcher; | |
165 | ||
166 | public: | |
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); } | |
171 | ||
172 | public: | |
173 | Process *findPid(pid_t pid) const; | |
174 | ||
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 | |
180 | bool inDarkWake(); | |
181 | void associateThread() { perThread().server = this; } | |
182 | ||
183 | private: | |
184 | // mach bootstrap registration name | |
185 | std::string mBootstrapName; | |
186 | ||
187 | // connection map (by client reply port) | |
188 | PortMap<Connection> mConnections; | |
189 | ||
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) | |
194 | ||
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; | |
199 | ||
200 | // CSSM components | |
201 | CssmClient::Cssm mCssm; // CSSM instance | |
202 | CssmClient::Module mCSPModule; // CSP module | |
203 | CssmClient::CSP mCSP; // CSP attachment | |
204 | ||
d8f41ccd A |
205 | CodeSignatures &mCodeSignatures; |
206 | ||
207 | // busy state for primary state authority | |
208 | unsigned int mVerbosity; | |
209 | bool mWaitForClients; | |
210 | bool mShuttingDown; | |
211 | }; | |
212 | ||
213 | ||
214 | // | |
215 | // A StLock that (also) declares a longTermActivity (only) once it's been entered. | |
216 | // | |
217 | class LongtermStLock : public StLock<Mutex> { | |
218 | public: | |
219 | LongtermStLock(Mutex &lck); | |
220 | // destructor inherited | |
221 | }; | |
222 | ||
fa7225c8 A |
223 | |
224 | // | |
225 | // Handling signals. | |
226 | // These are sent as Mach messages from ourselves to escape the limitations of | |
227 | // the signal handler environment. | |
228 | // | |
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); | |
231 | ||
d8f41ccd | 232 | #endif //_H_SERVER |