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
; 
  37 PidDiskRep::fetchData(void) 
  39         xpc_connection_t conn 
= xpc_connection_create("com.apple.CodeSigningHelper", 
  40                                                       dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0)); 
  41         xpc_connection_set_event_handler(conn
, ^(xpc_object_t object
){ }); 
  42         xpc_connection_resume(conn
); 
  44         xpc_object_t request 
= xpc_dictionary_create(NULL
, NULL
, 0); 
  45         assert(request 
!= NULL
); 
  46         xpc_dictionary_set_string(request
, "command", "fetchData"); 
  47         xpc_dictionary_set_int64(request
, "pid", mPid
); 
  49         xpc_object_t reply 
= xpc_connection_send_message_with_reply_sync(conn
, request
); 
  50         if (reply 
&& xpc_get_type(reply
) == XPC_TYPE_DICTIONARY
) { 
  55                         data 
= xpc_dictionary_get_data(reply
, "infoPlist", &size
); 
  56                         if (data 
&& size 
> 0 && size 
< 50 * 1024) 
  57                                 mInfoPlist
.take(CFDataCreate(NULL
, (const UInt8 
*)data
, (CFIndex
)size
)); 
  60                         data 
= xpc_dictionary_get_data(reply
, "bundleURL", &size
); 
  61                         if (data 
&& size 
> 0 && size 
< 50 * 1024) 
  62                                 mBundleURL
.take(CFURLCreateWithBytes(NULL
, (const UInt8 
*)data
, (CFIndex
)size
, kCFStringEncodingUTF8
, NULL
)); 
  72         MacOSError::throwMe(errSecCSNoSuchCode
); 
  76 PidDiskRep::PidDiskRep(pid_t pid
, CFDataRef infoPlist
) 
  79         CODESIGN_DISKREP_CREATE_KERNEL(this); 
  82         mInfoPlist 
= infoPlist
; 
  86         int rcent 
= ::csops(pid
, CS_OPS_BLOB
, &header
, sizeof(header
)); 
  88                 MacOSError::throwMe(errSecCSNoSuchCode
); 
  91                 UnixError::throwMe(errno
); 
  93         if (header
.length() > 1024 * 1024) 
  94                 MacOSError::throwMe(errSecCSNoSuchCode
); 
  96         uint32_t bufferLen 
= (uint32_t)header
.length(); 
  97         mBuffer 
= new uint8_t [bufferLen
]; 
  99         UnixError::check(::csops(pid
, CS_OPS_BLOB
, mBuffer
, bufferLen
)); 
 101         const EmbeddedSignatureBlob 
*b 
= (const EmbeddedSignatureBlob 
*)mBuffer
; 
 102         if (!b
->validateBlob(bufferLen
)) 
 103                 MacOSError::throwMe(errSecCSSignatureInvalid
); 
 106 PidDiskRep::~PidDiskRep() 
 113 bool PidDiskRep::supportInfoPlist() 
 119 CFDataRef 
PidDiskRep::component(CodeDirectory::SpecialSlot slot
) 
 121         if (slot 
== cdInfoSlot
) 
 122                 return mInfoPlist
.retain(); 
 124         EmbeddedSignatureBlob 
*b 
= (EmbeddedSignatureBlob 
*)this->blob(); 
 125         return b
->component(slot
); 
 128 CFDataRef 
PidDiskRep::identification() 
 134 CFURLRef 
PidDiskRep::copyCanonicalPath() 
 136         return mBundleURL
.retain(); 
 139 string 
PidDiskRep::recommendedIdentifier(const SigningContext 
&) 
 141         return string("pid") + to_string(mPid
); 
 144 size_t PidDiskRep::signingLimit() 
 149 string 
PidDiskRep::format() 
 151         return "pid diskrep"; 
 154 UnixPlusPlus::FileDesc 
&PidDiskRep::fd() 
 156         UnixError::throwMe(EINVAL
); 
 159 string 
PidDiskRep::mainExecutablePath() 
 161         char path
[MAXPATHLEN 
* 2]; 
 162         if(::proc_pidpath(mPid
, path
, sizeof(path
)) == 0) 
 163                 UnixError::throwMe(errno
); 
 169 } // end namespace CodeSigning 
 170 } // end namespace Security