2  * Copyright (c) 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@ 
  23 #include "piddiskrep.h" 
  25 #include <sys/param.h> 
  26 #include <sys/utsname.h> 
  27 #include <System/sys/codesign.h> 
  32 namespace CodeSigning 
{ 
  34 using namespace UnixPlusPlus
; 
  38 PidDiskRep::setCredentials(const Security::CodeSigning::CodeDirectory 
*cd
) 
  40         // save the Info.plist slot 
  41         if (cd
->slotIsPresent(cdInfoSlot
)) { 
  42                 mInfoPlistHash
.take(makeCFData(cd
->getSlot(cdInfoSlot
, false), cd
->hashSize
)); 
  47 PidDiskRep::fetchData(void) 
  49         if (mDataFetched
)       // once 
  52         xpc_connection_t conn 
= xpc_connection_create("com.apple.CodeSigningHelper", 
  53                                                       dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0)); 
  54         xpc_connection_set_event_handler(conn
, ^(xpc_object_t object
){ }); 
  55         xpc_connection_resume(conn
); 
  57         xpc_object_t request 
= xpc_dictionary_create(NULL
, NULL
, 0); 
  58         assert(request 
!= NULL
); 
  59         xpc_dictionary_set_string(request
, "command", "fetchData"); 
  60         xpc_dictionary_set_int64(request
, "pid", mPid
); 
  61         xpc_dictionary_set_data(request
, "infohash", CFDataGetBytePtr(mInfoPlistHash
), CFDataGetLength(mInfoPlistHash
)); 
  63         xpc_object_t reply 
= xpc_connection_send_message_with_reply_sync(conn
, request
); 
  64         if (reply 
&& xpc_get_type(reply
) == XPC_TYPE_DICTIONARY
) { 
  69                         data 
= xpc_dictionary_get_data(reply
, "infoPlist", &size
); 
  70                         if (data 
&& size 
> 0 && size 
< 50 * 1024) 
  71                                 mInfoPlist
.take(CFDataCreate(NULL
, (const UInt8 
*)data
, (CFIndex
)size
)); 
  74                         data 
= xpc_dictionary_get_data(reply
, "bundleURL", &size
); 
  75                         if (data 
&& size 
> 0 && size 
< 50 * 1024) 
  76                                 mBundleURL
.take(CFURLCreateWithBytes(NULL
, (const UInt8 
*)data
, (CFIndex
)size
, kCFStringEncodingUTF8
, NULL
)); 
  86         MacOSError::throwMe(errSecCSNoSuchCode
); 
  92 PidDiskRep::PidDiskRep(pid_t pid
, CFDataRef infoPlist
) 
  96         CODESIGN_DISKREP_CREATE_KERNEL(this); 
  99         mInfoPlist 
= infoPlist
; 
 103         int rcent 
= ::csops(pid
, CS_OPS_BLOB
, &header
, sizeof(header
)); 
 105                 MacOSError::throwMe(errSecCSNoSuchCode
); 
 108                 UnixError::throwMe(errno
); 
 110         if (header
.length() > 1024 * 1024) 
 111                 MacOSError::throwMe(errSecCSNoSuchCode
); 
 113         uint32_t bufferLen 
= (uint32_t)header
.length(); 
 114         mBuffer 
= new uint8_t [bufferLen
]; 
 116         UnixError::check(::csops(pid
, CS_OPS_BLOB
, mBuffer
, bufferLen
)); 
 118         const EmbeddedSignatureBlob 
*b 
= (const EmbeddedSignatureBlob 
*)mBuffer
; 
 119         if (!b
->validateBlob(bufferLen
)) 
 120                 MacOSError::throwMe(errSecCSSignatureInvalid
); 
 123 PidDiskRep::~PidDiskRep() 
 130 bool PidDiskRep::supportInfoPlist() 
 137 CFDataRef 
PidDiskRep::component(CodeDirectory::SpecialSlot slot
) 
 139         if (slot 
== cdInfoSlot
) { 
 141                 return mInfoPlist
.retain(); 
 144         EmbeddedSignatureBlob 
*b 
= (EmbeddedSignatureBlob 
*)this->blob(); 
 145         return b
->component(slot
); 
 148 CFDataRef 
PidDiskRep::identification() 
 154 CFURLRef 
PidDiskRep::copyCanonicalPath() 
 157         return mBundleURL
.retain(); 
 160 string 
PidDiskRep::recommendedIdentifier(const SigningContext 
&) 
 162         return string("pid") + to_string(mPid
); 
 165 size_t PidDiskRep::signingLimit() 
 170 size_t PidDiskRep::execSegLimit(const Architecture 
*) 
 175 string 
PidDiskRep::format() 
 177         return "pid diskrep"; 
 180 UnixPlusPlus::FileDesc 
&PidDiskRep::fd() 
 182         UnixError::throwMe(EINVAL
); 
 185 string 
PidDiskRep::mainExecutablePath() 
 187         char path
[MAXPATHLEN 
* 2]; 
 188         if(::proc_pidpath(mPid
, path
, sizeof(path
)) == 0) 
 189                 UnixError::throwMe(errno
); 
 195 } // end namespace CodeSigning 
 196 } // end namespace Security