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