namespace CodeSigning {
using namespace UnixPlusPlus;
-
+
+
+void
+PidDiskRep::setCredentials(const Security::CodeSigning::CodeDirectory *cd)
+{
+ // save the Info.plist slot
+ if (cd->slotIsPresent(cdInfoSlot)) {
+ mInfoPlistHash.take(makeCFData(cd->getSlot(cdInfoSlot, false), cd->hashSize));
+ }
+}
+
void
PidDiskRep::fetchData(void)
{
+ if (mDataFetched) // once
+ return;
+
xpc_connection_t conn = xpc_connection_create("com.apple.CodeSigningHelper",
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
xpc_connection_set_event_handler(conn, ^(xpc_object_t object){ });
assert(request != NULL);
xpc_dictionary_set_string(request, "command", "fetchData");
xpc_dictionary_set_int64(request, "pid", mPid);
-
+
+ if (mAudit) {
+ xpc_dictionary_set_data(request, "audit", mAudit.get(), sizeof(audit_token_t));
+ }
+ xpc_dictionary_set_data(request, "infohash", CFDataGetBytePtr(mInfoPlistHash), CFDataGetLength(mInfoPlistHash));
+
xpc_object_t reply = xpc_connection_send_message_with_reply_sync(conn, request);
if (reply && xpc_get_type(reply) == XPC_TYPE_DICTIONARY) {
const void *data;
if (!mBundleURL)
MacOSError::throwMe(errSecCSNoSuchCode);
+
+ mDataFetched = true;
}
-PidDiskRep::PidDiskRep(pid_t pid, CFDataRef infoPlist)
+PidDiskRep::PidDiskRep(pid_t pid, audit_token_t *audit, CFDataRef infoPlist)
+ : mDataFetched(false)
{
BlobCore header;
- CODESIGN_DISKREP_CREATE_KERNEL(this);
-
+
mPid = pid;
mInfoPlist = infoPlist;
-
- fetchData();
- int rcent = ::csops(pid, CS_OPS_BLOB, &header, sizeof(header));
+ if (audit != NULL) {
+ mAudit.reset(new audit_token_t);
+ memcpy(mAudit.get(), audit, sizeof(audit_token_t));
+ }
+
+ // fetchData();
+
+ int rcent = EINVAL;
+
+ if (audit != NULL) {
+ rcent = ::csops_audittoken(pid, CS_OPS_BLOB, &header, sizeof(header), mAudit.get());
+ } else {
+ rcent = ::csops(pid, CS_OPS_BLOB, &header, sizeof(header));
+ }
if (rcent == 0)
- MacOSError::throwMe(errSecCSNoSuchCode);
+ MacOSError::throwMe(errSecCSNoSuchCode);
if (errno != ERANGE)
UnixError::throwMe(errno);
uint32_t bufferLen = (uint32_t)header.length();
mBuffer = new uint8_t [bufferLen];
-
- UnixError::check(::csops(pid, CS_OPS_BLOB, mBuffer, bufferLen));
+
+ if (audit != NULL) {
+ UnixError::check(::csops_audittoken(pid, CS_OPS_BLOB, mBuffer, bufferLen, mAudit.get()));
+ } else {
+ UnixError::check(::csops(pid, CS_OPS_BLOB, mBuffer, bufferLen));
+ }
const EmbeddedSignatureBlob *b = (const EmbeddedSignatureBlob *)mBuffer;
if (!b->validateBlob(bufferLen))
bool PidDiskRep::supportInfoPlist()
{
+ fetchData();
return mInfoPlist;
}
CFDataRef PidDiskRep::component(CodeDirectory::SpecialSlot slot)
{
- if (slot == cdInfoSlot)
- return mInfoPlist.retain();
+ if (slot == cdInfoSlot) {
+ fetchData();
+ return mInfoPlist.retain();
+ }
- EmbeddedSignatureBlob *b = (EmbeddedSignatureBlob *)this->blob();
- return b->component(slot);
+ EmbeddedSignatureBlob *b = (EmbeddedSignatureBlob *)this->blob();
+ return b->component(slot);
}
CFDataRef PidDiskRep::identification()
CFURLRef PidDiskRep::copyCanonicalPath()
{
- return mBundleURL.retain();
+ fetchData();
+ return mBundleURL.retain();
}
string PidDiskRep::recommendedIdentifier(const SigningContext &)
return 0;
}
+size_t PidDiskRep::execSegLimit(const Architecture *)
+{
+ return 0;
+}
+
string PidDiskRep::format()
{
return "pid diskrep";
string PidDiskRep::mainExecutablePath()
{
char path[MAXPATHLEN * 2];
+ // This is unsafe by pid only, but so is using that path in general.
if(::proc_pidpath(mPid, path, sizeof(path)) == 0)
UnixError::throwMe(errno);
return path;
}
-
+
+bool PidDiskRep::appleInternalForcePlatform() const
+{
+ uint32_t flags = 0;
+ int rcent = EINVAL;
+
+ if (mAudit != NULL) {
+ rcent = ::csops_audittoken(mPid, CS_OPS_STATUS, &flags, sizeof(flags),
+ mAudit.get());
+ } else {
+ rcent = ::csops(mPid, CS_OPS_STATUS, &flags, sizeof(flags));
+ }
+
+ if (rcent != 0) {
+ MacOSError::throwMe(errSecCSNoSuchCode);
+ }
+
+ return (flags & CS_PLATFORM_BINARY) == CS_PLATFORM_BINARY;
+}
} // end namespace CodeSigning
} // end namespace Security