]> git.saurik.com Git - apple/securityd.git/blob - src/server.h
securityd-36489.tar.gz
[apple/securityd.git] / src / server.h
1 /*
2 * Copyright (c) 2000-2004 Apple Computer, 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 #define SHUTDOWN_SNITCH
24
25
26 //
27 // server - securityd main server object
28 //
29 #ifndef _H_SERVER
30 #define _H_SERVER
31
32 #include "structure.h"
33 #include <security_utilities/machserver.h>
34 #include <security_utilities/powerwatch.h>
35 #include <security_utilities/ccaudit.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 "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 //
56 class Authority : public Authorization::Engine {
57 public:
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 //
73 class Server : public PerGlobal,
74 public MachPlusPlus::MachServer,
75 public UniformRandomBlobs<DevRandomGenerator> {
76 public:
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
90 //
91 // Each thread has at most one "active connection". If the server is currently
92 // servicing a request received through a Connection, that's it. Otherwise
93 // there is none.
94 //
95 static Connection &connection(mach_port_t replyPort); // find by reply port and make active
96 static Connection &connection(bool tolerant = false); // return active (or fail unless tolerant)
97 static void requestComplete(CSSM_RETURN &rcode); // de-activate active connection
98
99 //
100 // Process and session of the active Connection
101 //
102 static Process &process();
103 static Session &session();
104
105 //
106 // Find objects from their client handles.
107 // These will all throw on invalid handles, and the RefPointer<> results are always non-NULL.
108 //
109 static RefPointer<Key> key(KeyHandle key);
110 static RefPointer<Key> optionalKey(KeyHandle k) { return (k == noKey) ? NULL : key(k); }
111 static RefPointer<Database> database(DbHandle db);
112 static RefPointer<KeychainDatabase> keychain(DbHandle db);
113 static RefPointer<Database> optionalDatabase(DbHandle db, bool persistent = true);
114 static AclSource &aclBearer(AclKind kind, CSSM_HANDLE handle);
115
116 // Generic version of handle lookup
117 template <class ProcessBearer>
118 static RefPointer<ProcessBearer> find(CSSM_HANDLE handle, CSSM_RETURN notFoundError)
119 {
120 RefPointer<ProcessBearer> object =
121 HandleObject::findRef<ProcessBearer>(handle, notFoundError);
122 if (object->process() != Server::process())
123 CssmError::throwMe(notFoundError);
124 return object;
125 }
126
127 //
128 // publicly accessible components of the active server
129 //
130 static Authority &authority() { return active().mAuthority; }
131 static CodeSignatures &codeSignatures() { return active().mCodeSignatures; }
132 static CssmClient::CSP &csp() { return active().mCSP; }
133
134 public:
135 //
136 // Initialize CSSM and MDS
137 //
138 void loadCssm();
139
140 public:
141 // set up a new connection
142 enum ConnectLevel {
143 connectNewSession,
144 connectNewProcess,
145 connectNewThread
146 };
147 void setupConnection(ConnectLevel type, Port servicePort, Port replyPort, Port taskPort,
148 const audit_token_t &auditToken,
149 const ClientSetupInfo *info = NULL, const char *executablePath = NULL);
150
151 void endConnection(Port replyPort);
152
153 static void releaseWhenDone(Allocator &alloc, void *memory)
154 { MachServer::active().releaseWhenDone(alloc, memory); }
155 static void releaseWhenDone(void *memory)
156 { releaseWhenDone(Allocator::standard(), memory); }
157
158 protected:
159 // implementation methods of MachServer
160 boolean_t handle(mach_msg_header_t *in, mach_msg_header_t *out);
161 void notifyDeadName(Port port);
162 void notifyNoSenders(Port port, mach_port_mscount_t);
163 void threadLimitReached(UInt32 count);
164 void eventDone();
165
166 private:
167 class SleepWatcher : public MachPlusPlus::PortPowerWatcher {
168 public:
169 void systemWillSleep();
170 void systemIsWaking();
171
172 void add(PowerWatcher *client);
173 void remove(PowerWatcher *client);
174
175 private:
176 set<PowerWatcher *> mPowerClients;
177 };
178
179 SleepWatcher sleepWatcher;
180
181 public:
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
187 public:
188 Process *findPid(pid_t pid) const;
189
190 void waitForClients(bool waiting); // set waiting behavior
191 bool beginShutdown(); // start delayed shutdown if configured
192
193 private:
194 // mach bootstrap registration name
195 std::string mBootstrapName;
196
197 // connection map (by client reply port)
198 PortMap<Connection> mConnections;
199
200 // process map (by process task port)
201 typedef std::map<pid_t, Process *> PidMap;
202 PortMap<Process> mProcesses; // strong reference
203 PidMap mPids; // weak reference (subsidiary to mProcesses)
204
205 enum ShutdownMode {
206 shutdownImmediately, // shut down immediately on SIGTERM
207 shutdownDelayed, // wait for clients on SIGTERM
208 shuttingDown // delayed shutdown in progress
209 } mShutdown; // shutdown mode
210 void shutdownSnitch(); // rat out lingering clients (to syslog)
211
212 // Current connection, if any (per thread).
213 // Set as a side effect of calling connection(mach_port_t)
214 // and returned by connection(bool).
215 ThreadNexus<RefPointer<Connection> > mCurrentConnection;
216
217 // CSSM components
218 CssmClient::Cssm mCssm; // CSSM instance
219 CssmClient::Module mCSPModule; // CSP module
220 CssmClient::CSP mCSP; // CSP attachment
221
222 Authority &mAuthority;
223 CodeSignatures &mCodeSignatures;
224
225 // Per-process audit initialization
226 CommonCriteria::AuditSession mAudit;
227 };
228
229
230 //
231 // A StLock that (also) declares a longTermActivity (only) once it's been entered.
232 //
233 class LongtermStLock : public StLock<Mutex> {
234 public:
235 LongtermStLock(Mutex &lck);
236 // destructor inherited
237 };
238
239 #endif //_H_SERVER