#include "MISEntitlement.h"
static const CFStringRef kEntitlementAllValuesAllowed = CFSTR("*");
static Boolean whitelistArrayAllowsEntitlementValue(CFArrayRef whitelist, CFStringRef value)
{
Boolean allowed = false;
CFIndex i, count = CFArrayGetCount(whitelist);
for (i = 0; (i < count) && (allowed == false); i++) {
CFStringRef item = (CFStringRef) CFArrayGetValueAtIndex(whitelist, i);
if (CFGetTypeID(item) == CFStringGetTypeID()) {
CFIndex len = CFStringGetLength(item);
if (len > 0) {
if (CFStringGetCharacterAtIndex(item, len-1) != '*') {
allowed = CFStringCompare(item, value, 0) == kCFCompareEqualTo;
} else {
CFStringRef wildcardPrefix = CFStringCreateWithSubstring(kCFAllocatorDefault, item, CFRangeMake(0, len-1));
allowed = CFStringHasPrefix(value, wildcardPrefix);
CFRelease(wildcardPrefix);
}
}
} else {
break;
}
}
return allowed;
}
Boolean MISEntitlementDictionaryAllowsEntitlementValue(CFDictionaryRef entitlements, CFStringRef entitlement, CFTypeRef value)
{
Boolean allowsEntitlement = false;
if (value != NULL) {
CFTypeRef storedValue = CFDictionaryGetValue(entitlements, entitlement);
if (storedValue != NULL) {
if (CFEqual(storedValue, kEntitlementAllValuesAllowed) == true) {
allowsEntitlement = true;
} else if (CFGetTypeID(storedValue) == CFBooleanGetTypeID()) {
allowsEntitlement = CFEqual(storedValue, value);
} else if (CFGetTypeID(storedValue) == CFStringGetTypeID()) {
if (CFGetTypeID(value) == CFStringGetTypeID()) {
CFArrayRef array = CFArrayCreate(kCFAllocatorDefault, (const void **) &storedValue, 1, &kCFTypeArrayCallBacks);
allowsEntitlement = whitelistArrayAllowsEntitlementValue(array, (CFStringRef) value);
CFRelease(array);
}
} else if (CFGetTypeID(storedValue) == CFArrayGetTypeID()) {
if (CFGetTypeID(value) == CFStringGetTypeID()) {
allowsEntitlement = whitelistArrayAllowsEntitlementValue((CFArrayRef) storedValue, (CFStringRef) value);
} else if (CFGetTypeID(value) == CFArrayGetTypeID()) {
allowsEntitlement = true;
CFIndex i, count = CFArrayGetCount((CFArrayRef) value);
for (i = 0; (i < count) && (allowsEntitlement == true); i++) {
CFTypeRef element = CFArrayGetValueAtIndex((CFArrayRef) value, i);
if (CFGetTypeID(element) == CFStringGetTypeID()) {
allowsEntitlement = whitelistArrayAllowsEntitlementValue((CFArrayRef) storedValue, (CFStringRef) element);
} else {
allowsEntitlement = false;
}
}
}
}
}
}
return allowsEntitlement;
}