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;
CFArrayRef keychainAccessGroups, appleSecurityApplicationGroups;
CFStringRef appID;
CFArrayRef associatedAppIDs;
keychainAccessGroups = SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementKeychainAccessGroups);
appleSecurityApplicationGroups = SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementAppleSecurityApplicationGroups);
appID = SecTaskCopyApplicationIdentifier(task);
associatedAppIDs = SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementAssociatedApplicationIdentifier);
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 (associatedAppIDs) {
CFArrayAppendAll(groups, associatedAppIDs);
}
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(associatedAppIDs);
CFReleaseNull(appID);
CFReleaseNull(keychainAccessGroups);
CFReleaseNull(appleSecurityApplicationGroups);
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;
}