]>
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" | |
46 | #include "authority.h" | |
47 | #include "AuthorizationEngine.h" | |
48 | #include <map> | |
49 | ||
d8f41ccd A |
50 | // |
51 | // The authority itself. You will usually only have one of these. | |
52 | // | |
53 | class Authority : public Authorization::Engine { | |
54 | public: | |
55 | Authority(const char *configFile); | |
56 | ~Authority(); | |
57 | }; | |
58 | ||
59 | // | |
60 | // The server object itself. This is the "go to" object for anyone who wants | |
61 | // to access the server's global state. It runs the show. | |
62 | // There is only one Server, and its name is Server::active(). | |
63 | // | |
64 | // Server also acts as the global-scope nexus of securityd's object mesh. | |
65 | // Sessions have Server as their parent, and global-scope objects have it | |
66 | // as their referent. The Server is never kill()ed; though kill(globalObject) | |
67 | // may make sense. Also, we can search for global-scope objects by using the | |
68 | // findFirst/allReferences feature of Node<>. | |
69 | // | |
70 | class Server : public PerGlobal, | |
71 | public MachPlusPlus::MachServer, | |
72 | public UniformRandomBlobs<DevRandomGenerator> { | |
73 | public: | |
74 | Server(Authority &myAuthority, CodeSignatures &signatures, const char *bootstrapName); | |
75 | ~Server(); | |
76 | ||
77 | // run the server until it shuts down | |
78 | void run(); | |
79 | ||
80 | // | |
81 | // Retrieve pieces of the Server's object web. | |
82 | // These are all static methods that use the active() Server of this thread. | |
83 | // | |
84 | static Server &active() { return safer_cast<Server &>(MachServer::active()); } | |
85 | static const char *bootstrapName() { return active().mBootstrapName.c_str(); } | |
86 | static unsigned int verbosity() { return active().mVerbosity; } | |
87 | ||
88 | // | |
89 | // Each thread has at most one "active connection". If the server is currently | |
90 | // servicing a request received through a Connection, that's it. Otherwise | |
91 | // there is none. | |
92 | // | |
93 | static Connection &connection(mach_port_t replyPort, audit_token_t &auditToken); // find by reply port and make active | |
94 | static Connection &connection(bool tolerant = false); // return active (or fail unless tolerant) | |
95 | static void requestComplete(CSSM_RETURN &rcode); // de-activate active connection | |
96 | ||
97 | // | |
98 | // Process and session of the active Connection | |
99 | // | |
100 | static Process &process(); | |
101 | static Session &session(); | |
102 | ||
103 | // | |
104 | // Find objects from their client handles. | |
105 | // These will all throw on invalid handles, and the RefPointer<> results are always non-NULL. | |
106 | // | |
107 | static RefPointer<Key> key(KeyHandle key); | |
108 | static RefPointer<Key> optionalKey(KeyHandle k) { return (k == noKey) ? NULL : key(k); } | |
109 | static RefPointer<Database> database(DbHandle db); | |
110 | static RefPointer<KeychainDatabase> keychain(DbHandle db); | |
111 | static RefPointer<Database> optionalDatabase(DbHandle db, bool persistent = true); | |
112 | static AclSource &aclBearer(AclKind kind, U32HandleObject::Handle handle); | |
113 | ||
114 | // Generic version of handle lookup | |
115 | template <class ProcessBearer> | |
116 | static RefPointer<ProcessBearer> find(uint32_t handle, CSSM_RETURN notFoundError) | |
117 | { | |
118 | RefPointer<ProcessBearer> object = | |
119 | U32HandleObject::findRef<ProcessBearer>(handle, notFoundError); | |
120 | if (object->process() != Server::process()) | |
121 | CssmError::throwMe(notFoundError); | |
122 | return object; | |
123 | } | |
124 | ||
125 | // | |
126 | // publicly accessible components of the active server | |
127 | // | |
128 | static Authority &authority() { return active().mAuthority; } | |
129 | static CodeSignatures &codeSignatures() { return active().mCodeSignatures; } | |
130 | static CssmClient::CSP &csp() { return active().mCSP; } | |
131 | ||
132 | public: | |
133 | // | |
134 | // Initialize CSSM and MDS | |
135 | // | |
136 | void loadCssm(bool mdsIsInstalled); | |
137 | ||
138 | public: | |
139 | // set up a new connection | |
140 | enum ConnectLevel { | |
141 | connectNewProcess, | |
142 | connectNewThread | |
143 | }; | |
144 | void setupConnection(ConnectLevel type, Port replyPort, Port taskPort, const audit_token_t &auditToken, | |
145 | const ClientSetupInfo *info = NULL); | |
146 | ||
147 | void endConnection(Port replyPort); | |
148 | ||
149 | static void releaseWhenDone(Allocator &alloc, void *memory) | |
150 | { MachServer::active().releaseWhenDone(alloc, memory); } | |
151 | static void releaseWhenDone(void *memory) | |
152 | { releaseWhenDone(Allocator::standard(), memory); } | |
153 | ||
154 | protected: | |
155 | // implementation methods of MachServer | |
156 | boolean_t handle(mach_msg_header_t *in, mach_msg_header_t *out); | |
157 | void notifyDeadName(Port port); | |
158 | void notifyNoSenders(Port port, mach_port_mscount_t); | |
159 | void threadLimitReached(UInt32 count); | |
160 | void eventDone(); | |
161 | ||
162 | private: | |
163 | class SleepWatcher : public MachPlusPlus::PortPowerWatcher { | |
164 | public: | |
165 | void systemWillSleep(); | |
166 | void systemIsWaking(); | |
167 | void systemWillPowerOn(); | |
168 | ||
169 | void add(PowerWatcher *client); | |
170 | void remove(PowerWatcher *client); | |
171 | ||
172 | private: | |
173 | set<PowerWatcher *> mPowerClients; | |
174 | }; | |
175 | ||
176 | SleepWatcher sleepWatcher; | |
177 | ||
178 | public: | |
179 | using MachServer::add; | |
180 | using MachServer::remove; | |
181 | void add(MachPlusPlus::PowerWatcher *client) { StLock<Mutex> _(*this); sleepWatcher.add(client); } | |
182 | void remove(MachPlusPlus::PowerWatcher *client) { StLock<Mutex> _(*this); sleepWatcher.remove(client); } | |
183 | ||
184 | public: | |
185 | Process *findPid(pid_t pid) const; | |
186 | ||
187 | void verbosity(unsigned int v) { mVerbosity = v; } | |
188 | void waitForClients(bool waiting); // set waiting behavior | |
189 | void beginShutdown(); // start delayed shutdown if configured | |
190 | bool shuttingDown() const { return mShuttingDown; } | |
191 | void shutdownSnitch(); // report lingering clients | |
192 | bool inDarkWake(); | |
193 | void associateThread() { perThread().server = this; } | |
194 | ||
195 | private: | |
196 | // mach bootstrap registration name | |
197 | std::string mBootstrapName; | |
198 | ||
199 | // connection map (by client reply port) | |
200 | PortMap<Connection> mConnections; | |
201 | ||
202 | // process map (by process task port) | |
203 | typedef std::map<pid_t, Process *> PidMap; | |
204 | PortMap<Process> mProcesses; // strong reference | |
205 | PidMap mPids; // weak reference (subsidiary to mProcesses) | |
206 | ||
207 | // Current connection, if any (per thread). | |
208 | // Set as a side effect of calling connection(mach_port_t) | |
209 | // and returned by connection(bool). | |
210 | ThreadNexus<RefPointer<Connection> > mCurrentConnection; | |
211 | ||
212 | // CSSM components | |
213 | CssmClient::Cssm mCssm; // CSSM instance | |
214 | CssmClient::Module mCSPModule; // CSP module | |
215 | CssmClient::CSP mCSP; // CSP attachment | |
216 | ||
217 | Authority &mAuthority; | |
218 | CodeSignatures &mCodeSignatures; | |
219 | ||
220 | // busy state for primary state authority | |
221 | unsigned int mVerbosity; | |
222 | bool mWaitForClients; | |
223 | bool mShuttingDown; | |
224 | }; | |
225 | ||
226 | ||
227 | // | |
228 | // A StLock that (also) declares a longTermActivity (only) once it's been entered. | |
229 | // | |
230 | class LongtermStLock : public StLock<Mutex> { | |
231 | public: | |
232 | LongtermStLock(Mutex &lck); | |
233 | // destructor inherited | |
234 | }; | |
235 | ||
236 | #endif //_H_SERVER |