2  * Copyright (c) 2006-2008,2010 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 // csproxy - Code Signing Hosting Proxy 
  31 #include <security_utilities/casts.h> 
  32 #include <security_utilities/cfutilities.h> 
  33 #include <security_utilities/debugging_internal.h> 
  34 #include <security_cdsa_utilities/handleobject.h> 
  35 #include <security_utilities/mach++.h> 
  36 #include <security_utilities/machserver.h> 
  37 #include <security_cdsa_utilities/cssmdata.h> 
  38 #include <securityd_client/cshosting.h> 
  39 #include <Security/SecCodeHost.h> 
  43 using MachPlusPlus::Port
; 
  44 using MachPlusPlus::MachServer
; 
  48 // CodeSigningHost is a mix-in for an object representing a primary 
  49 // Code Signing host object. It performs two notionally separate functions: 
  50 //  (1) Register a hosting port. 
  51 //  (2) Optionally, maintain a guest registry to offload the host's work. 
  53 class CodeSigningHost 
: private MachServer::Handler 
{ 
  60                 noHosting
,                                      // is not a host (yet), could go either way 
  61                 dynamicHosting
,                         // gave us its own hosting port to keep 
  62                 proxyHosting                            
// we act as a proxy for it 
  66                 strict
,                                         // direct guest relationship required 
  67                 loose                                           
// indirect or identity is okay (prefix check) 
  70         struct Guest 
: public RefCount
, public HandleObject 
{ 
  74                 std::vector
<SecGuestRef
> guestPath
; // guest chain to this guest 
  75                 uint32_t status
;                        // dynamic status 
  76                 std::string path
;                       // canonical code path 
  77                 CFRef
<CFDictionaryRef
> attributes
; // matching attributes set 
  78                 CFRef
<CFDataRef
> cdhash
;        // hash of CodeDirectory as specified by host 
  79                 bool dedicated
;                         // host is dedicated (and this is the only guest) 
  81                 operator bool() const { return attributes
; }  // exists 
  82                 SecGuestRef 
guestRef() const { return int_cast
<long, SecGuestRef
>(handle()); } 
  83                 void setAttributes(const CssmData 
&attrData
); 
  84         uint8_t const *attrData() const  { createAttrData(); return mAttrData
; }; 
  85         CFIndex 
attrDataLength() const { createAttrData(); return mAttrDataLength
; }; 
  86                 void setHash(const CssmData 
&given
, bool generate
); 
  88                 bool isGuestOf(Guest 
*host
, GuestCheck check
) const; 
  89                 bool matches(CFIndex count
, CFTypeRef keys
[], CFTypeRef values
[]) const; 
  91                 IFDUMP(void dump() const); 
  94         void createAttrData() const; 
  96                 mutable uint8_t *mAttrData
; // XML form of attributes (vm_allocate'd, must live until guest destruction) 
  97         mutable CFIndex mAttrDataLength
; 
 100         void registerCodeSigning(mach_port_t hostingPort
, SecCSFlags flags
); 
 101         Port 
hostingPort() const { return mHostingPort
; } 
 103         SecGuestRef 
createGuest(SecGuestRef guest
, 
 104                 uint32_t status
, const char *path
, 
 105                 const CssmData 
&cdhash
, const CssmData 
&attributes
, SecCSFlags flags
); 
 106         void setGuestStatus(SecGuestRef guest
, uint32_t status
, const CssmData 
&attributes
); 
 107         void removeGuest(SecGuestRef host
, SecGuestRef guest
); 
 110         IFDUMP(void dump() const); 
 113         // internal use only (public for use by MIG handlers) 
 114         Guest 
*findHost(SecGuestRef hostRef
); // find most dedicated guest of this host 
 115         Guest 
*findGuest(Guest 
*host
, const CssmData 
&attrData
); // by host and attributes 
 116         Guest 
*findGuest(SecGuestRef guestRef
, bool hostOk 
= false); // by guest reference 
 117         Guest 
*findGuest(Guest 
*host
);          // any guest of this host 
 123         boolean_t 
handle(mach_msg_header_t 
*in
, mach_msg_header_t 
*out
); 
 124         void eraseGuest(Guest 
*guest
); 
 127         mutable Mutex mLock
;                            // protects everything below 
 129         // host port registry 
 130         HostingState mHostingState
;                     // status of hosting support 
 131         Port mHostingPort
;                                      // his or ours or NULL 
 133         // guest map (only used if mHostingState == proxyHosting) 
 134         typedef std::map
<SecGuestRef
, RefPointer
<Guest
> > GuestMap
; 
 140 // Proxy implementation of Code Signing Hosting protocol 
 142 #define CSH_ARGS        mach_port_t servicePort, mach_port_t replyPort, OSStatus *rcode 
 144 #define DATA_IN(base)   void *base, mach_msg_type_number_t base##Length 
 145 #define DATA_OUT(base)  void **base, mach_msg_type_number_t *base##Length 
 146 #define DATA(base)              CssmData(base, base##Length) 
 149 // Find a guest by arbitrary attribute set. 
 151 // This returns an array of canonical guest references describing the path 
 152 // from the host given to the guest found. If the host itself is returned 
 153 // as a guest, this will be an empty array (zero length). 
 155 // The subhost return argument may in the future return the hosting port for 
 156 // a guest who dynamically manages its hosting (thus breaking out of proxy mode), 
 157 // but this is not yet implemented. 
 159 kern_return_t 
cshosting_server_findGuest(CSH_ARGS
, SecGuestRef hostRef
, 
 161                                          GuestChain 
*foundGuest
, mach_msg_type_number_t 
*depth
, mach_port_t 
*subhost
); 
 164 // Retrieve the path to a guest specified by canonical reference. 
 166 kern_return_t 
cshosting_server_identifyGuest(CSH_ARGS
, SecGuestRef guestRef
, 
 167                                              char *path
, char *hash
, uint32_t *hashLength
, DATA_OUT(attributes
)); 
 170 // Retrieve the status word for a guest specified by canonical reference. 
 172 kern_return_t 
cshosting_server_guestStatus(CSH_ARGS
, SecGuestRef guestRef
, uint32_t *status
);