2  * Copyright (c) 2000-2009,2012-2014 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   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 
  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. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  26 // server - securityd main server object 
  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" 
  44 #include "localdatabase.h" 
  45 #include "kcdatabase.h" 
  46 #include "authority.h" 
  47 #include "AuthorizationEngine.h" 
  51 // The authority itself. You will usually only have one of these. 
  53 class Authority 
: public Authorization::Engine 
{ 
  55         Authority(const char *configFile
); 
  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(). 
  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<>. 
  70 class Server 
: public PerGlobal
, 
  71                            public MachPlusPlus::MachServer
, 
  72                public UniformRandomBlobs
<DevRandomGenerator
> { 
  74         Server(Authority 
&myAuthority
, CodeSignatures 
&signatures
, const char *bootstrapName
); 
  77     // run the server until it shuts down 
  81     // Retrieve pieces of the Server's object web. 
  82     // These are all static methods that use the active() Server of this thread. 
  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
; } 
  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 
  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 
  98         // Process and session of the active Connection 
 100         static Process 
&process(); 
 101         static Session 
&session(); 
 104         // Find objects from their client handles. 
 105         // These will all throw on invalid handles, and the RefPointer<> results are always non-NULL. 
 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
); 
 114         // Generic version of handle lookup 
 115         template <class ProcessBearer
> 
 116     static RefPointer
<ProcessBearer
> find(uint32_t handle
, CSSM_RETURN notFoundError
) 
 118                 RefPointer
<ProcessBearer
> object 
=  
 119                         U32HandleObject::findRef
<ProcessBearer
>(handle
, notFoundError
); 
 120                 if (object
->process() != Server::process()) 
 121                         CssmError::throwMe(notFoundError
); 
 126         // publicly accessible components of the active server 
 128     static Authority 
&authority() { return active().mAuthority
; } 
 129         static CodeSignatures 
&codeSignatures() { return active().mCodeSignatures
; } 
 130         static CssmClient::CSP 
&csp() { return active().mCSP
; } 
 134         // Initialize CSSM and MDS 
 136         void loadCssm(bool mdsIsInstalled
); 
 139         // set up a new connection 
 144         void setupConnection(ConnectLevel type
, Port replyPort
, Port taskPort
, const audit_token_t 
&auditToken
, 
 145                 const ClientSetupInfo 
*info 
= NULL
); 
 147         void endConnection(Port replyPort
); 
 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
); } 
 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
); 
 163         class SleepWatcher 
: public MachPlusPlus::PortPowerWatcher 
{ 
 165                 void systemWillSleep(); 
 166                 void systemIsWaking(); 
 167                 void systemWillPowerOn(); 
 169                 void add(PowerWatcher 
*client
); 
 170                 void remove(PowerWatcher 
*client
); 
 173                 set
<PowerWatcher 
*> mPowerClients
; 
 176         SleepWatcher sleepWatcher
; 
 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
); } 
 185         Process 
*findPid(pid_t pid
) const; 
 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 
 193     void associateThread() { perThread().server 
= this; } 
 196         // mach bootstrap registration name 
 197         std::string mBootstrapName
; 
 199         // connection map (by client reply port) 
 200         PortMap
<Connection
> mConnections
; 
 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) 
 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
; 
 213     CssmClient::Cssm mCssm
;                             // CSSM instance 
 214     CssmClient::Module mCSPModule
;              // CSP module 
 215         CssmClient::CSP mCSP
;                           // CSP attachment 
 217         Authority 
&mAuthority
; 
 218         CodeSignatures 
&mCodeSignatures
; 
 220         // busy state for primary state authority 
 221         unsigned int mVerbosity
; 
 222         bool mWaitForClients
; 
 228 // A StLock that (also) declares a longTermActivity (only) once it's been entered. 
 230 class LongtermStLock 
: public StLock
<Mutex
> { 
 232         LongtermStLock(Mutex 
&lck
); 
 233         // destructor inherited