server_entitlement_helpers.c [plain text]
#include <pthread/pthread.h>
#include "server_entitlement_helpers.h"
#include <Security/SecTask.h>
#include <Security/SecTaskPriv.h>
#include <ipc/securityd_client.h>
#include <Security/SecEntitlements.h>
#include <Security/SecItem.h>
#include <utilities/SecCFRelease.h>
#include <utilities/SecCFWrappers.h>
#include <utilities/debugging.h>
CFStringRef SecTaskCopyStringForEntitlement(SecTaskRef task,
CFStringRef entitlement)
{
CFStringRef value = (CFStringRef)SecTaskCopyValueForEntitlement(task,
entitlement, NULL);
if (value && CFGetTypeID(value) != CFStringGetTypeID()) {
CFReleaseNull(value);
}
return value;
}
CFArrayRef SecTaskCopyArrayOfStringsForEntitlement(SecTaskRef task,
CFStringRef entitlement)
{
CFArrayRef value = (CFArrayRef)SecTaskCopyValueForEntitlement(task,
entitlement, NULL);
if (value) {
if (CFGetTypeID(value) == CFArrayGetTypeID()) {
CFIndex ix, count = CFArrayGetCount(value);
for (ix = 0; ix < count; ++ix) {
CFStringRef string = (CFStringRef)CFArrayGetValueAtIndex(value, ix);
if (CFGetTypeID(string) != CFStringGetTypeID()) {
CFReleaseNull(value);
break;
}
}
} else {
CFReleaseNull(value);
}
}
return value;
}
CFStringRef SecTaskCopyApplicationIdentifier(SecTaskRef task) {
return SecTaskCopyStringForEntitlement(task,
kSecEntitlementApplicationIdentifier);
}
#if TARGET_OS_IOS
CFArrayRef SecTaskCopySharedWebCredentialDomains(SecTaskRef task) {
return SecTaskCopyArrayOfStringsForEntitlement(task,
kSecEntitlementAssociatedDomains);
}
#endif
CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task)
{
CFMutableArrayRef groups = NULL;
#if TARGET_SIMULATOR
groups = (CFMutableArrayRef)CFRetainSafe(SecAccessGroupsGetCurrent());
#else
CFArrayRef keychainAccessGroups, appleSecurityApplicationGroups;
CFStringRef appID;
keychainAccessGroups = SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementKeychainAccessGroups);
appleSecurityApplicationGroups = SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementAppleSecurityApplicationGroups);
appID = SecTaskCopyApplicationIdentifier(task);
groups = CFArrayCreateMutableForCFTypes(NULL);
if (keychainAccessGroups) {
CFArrayAppendArray(groups, keychainAccessGroups, CFRangeMake(0, CFArrayGetCount(keychainAccessGroups)));
}
#if TARGET_OS_OSX
const bool entitlementsValidated = SecTaskEntitlementsValidated(task);
#else
const bool entitlementsValidated = true;
#endif
if (entitlementsValidated) {
if (appID) {
CFArrayAppendValue(groups, appID);
}
if (appleSecurityApplicationGroups) {
CFArrayAppendArray(groups, appleSecurityApplicationGroups, CFRangeMake(0, CFArrayGetCount(appleSecurityApplicationGroups)));
}
} else {
if (CFArrayGetCount(groups) == 0) {
if (appID) {
secwarning("Entitlement %@=%@ is ignored because of invalid application signature or incorrect provisioning profile",
kSecEntitlementApplicationIdentifier, appID);
}
if (appleSecurityApplicationGroups) {
secwarning("Entitlement %@=%@ is ignored because of invalid application signature or incorrect provisioning profile",
kSecEntitlementAppleSecurityApplicationGroups, appleSecurityApplicationGroups);
}
}
}
bool entitlementsFailure = (CFArrayGetCount(groups) == 0 && appID != NULL);
if (!entitlementsFailure) {
CFArrayAppendValue(groups, kSecAttrAccessGroupToken);
}
CFReleaseNull(appID);
CFReleaseNull(keychainAccessGroups);
CFReleaseNull(appleSecurityApplicationGroups);
#endif
return groups;
}
bool
SecTaskGetBooleanValueForEntitlement(SecTaskRef task, CFStringRef entitlement)
{
CFTypeRef value = SecTaskCopyValueForEntitlement(task, entitlement, NULL);
bool ok = false;
if (value && CFBooleanGetTypeID() == CFGetTypeID(value)) {
ok = CFBooleanGetValue(value);
}
CFReleaseNull(value);
return ok;
}