2  * Copyright (c) 2000-2004,2008-2009 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" 
  50 #define EQUIVALENCEDBPATH "/var/db/CodeEquivalenceDatabase" 
  54 // The authority itself. You will usually only have one of these. 
  56 class Authority 
: public Authorization::Engine 
{ 
  58         Authority(const char *configFile
); 
  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(). 
  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<>. 
  73 class Server 
: public PerGlobal
, 
  74                            public MachPlusPlus::MachServer
, 
  75                public UniformRandomBlobs
<DevRandomGenerator
> { 
  77         Server(Authority 
&myAuthority
, CodeSignatures 
&signatures
, const char *bootstrapName
); 
  80     // run the server until it shuts down 
  84     // Retrieve pieces of the Server's object web. 
  85     // These are all static methods that use the active() Server of this thread. 
  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
; } 
  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 
  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 
 101         // Process and session of the active Connection 
 103         static Process 
&process(); 
 104         static Session 
&session(); 
 107         // Find objects from their client handles. 
 108         // These will all throw on invalid handles, and the RefPointer<> results are always non-NULL. 
 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
); 
 117         // Generic version of handle lookup 
 118         template <class ProcessBearer
> 
 119     static RefPointer
<ProcessBearer
> find(uint32_t handle
, CSSM_RETURN notFoundError
) 
 121                 RefPointer
<ProcessBearer
> object 
=  
 122                         U32HandleObject::findRef
<ProcessBearer
>(handle
, notFoundError
); 
 123                 if (object
->process() != Server::process()) 
 124                         CssmError::throwMe(notFoundError
); 
 129         // publicly accessible components of the active server 
 131     static Authority 
&authority() { return active().mAuthority
; } 
 132         static CodeSignatures 
&codeSignatures() { return active().mCodeSignatures
; } 
 133         static CssmClient::CSP 
&csp() { return active().mCSP
; } 
 137         // Initialize CSSM and MDS 
 139         void loadCssm(bool mdsIsInstalled
); 
 142         // set up a new connection 
 147         void setupConnection(ConnectLevel type
, Port replyPort
, Port taskPort
, const audit_token_t 
&auditToken
, 
 148                 const ClientSetupInfo 
*info 
= NULL
); 
 150         void endConnection(Port replyPort
); 
 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
); } 
 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
); 
 166         class SleepWatcher 
: public MachPlusPlus::PortPowerWatcher 
{ 
 168                 void systemWillSleep(); 
 169                 void systemIsWaking(); 
 170                 void systemWillPowerOn(); 
 172                 void add(PowerWatcher 
*client
); 
 173                 void remove(PowerWatcher 
*client
); 
 176                 set
<PowerWatcher 
*> mPowerClients
; 
 179         SleepWatcher sleepWatcher
; 
 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
); } 
 188         Process 
*findPid(pid_t pid
) const; 
 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 
 197         // mach bootstrap registration name 
 198         std::string mBootstrapName
; 
 200         // connection map (by client reply port) 
 201         PortMap
<Connection
> mConnections
; 
 203         // process map (by process task port) 
 204         typedef std::map
<pid_t
, Process 
*> PidMap
; 
 205         PortMap
<Process
> mProcesses
;                                    // strong reference 
 206         PidMap mPids
;                                                                   // weak reference (subsidiary to mProcesses) 
 208         // Current connection, if any (per thread). 
 209         // Set as a side effect of calling connection(mach_port_t) 
 210         // and returned by connection(bool). 
 211         ThreadNexus
<RefPointer
<Connection
> > mCurrentConnection
; 
 214     CssmClient::Cssm mCssm
;                             // CSSM instance 
 215     CssmClient::Module mCSPModule
;              // CSP module 
 216         CssmClient::CSP mCSP
;                           // CSP attachment 
 218         Authority 
&mAuthority
; 
 219         CodeSignatures 
&mCodeSignatures
; 
 221         // busy state for primary state authority 
 222         unsigned int mVerbosity
; 
 223         bool mWaitForClients
; 
 229 // A StLock that (also) declares a longTermActivity (only) once it's been entered. 
 231 class LongtermStLock 
: public StLock
<Mutex
> { 
 233         LongtermStLock(Mutex 
&lck
); 
 234         // destructor inherited