+++ /dev/null
-#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) != '*') {
-
- /* Not a wildcard, must be an exact match */
- allowed = CFStringCompare(item, value, 0) == kCFCompareEqualTo;
- } else {
-
- /* Last character is a wildcard - do some matching */
- CFStringRef wildcardPrefix = CFStringCreateWithSubstring(kCFAllocatorDefault, item, CFRangeMake(0, len-1));
- allowed = CFStringHasPrefix(value, wildcardPrefix);
- CFRelease(wildcardPrefix);
- }
- }
- } else {
-
- /* Unexpected item in whitelist - bail */
- break;
- }
- }
-
- return allowed;
-}
-
-Boolean MISEntitlementDictionaryAllowsEntitlementValue(CFDictionaryRef entitlements, CFStringRef entitlement, CFTypeRef value)
-{
- Boolean allowsEntitlement = false;
-
- /* NULL is never a valid entitlement value */
- if (value != NULL) {
-
- /* Make sure the entitlement is present */
- CFTypeRef storedValue = CFDictionaryGetValue(entitlements, entitlement);
- if (storedValue != NULL) {
-
- /*
- * Handling depends on the type
- * If the value matches our constant, the entitlement is permitted
- * to have any value.
- * If the value in the dictionary is a boolean, then the entitlement
- * value must be a boolean with the same value
- * If the value in the dictionary is an array (of strings), then the
- * entitlement must be either one of those strings OR an array that
- * includes only present strings
- */
- if (CFEqual(storedValue, kEntitlementAllValuesAllowed) == true) {
-
- /* XXX: Does this need to restrict the value to some types */
- 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()) {
-
- /* value is either a single string or array of strings */
- if (CFGetTypeID(value) == CFStringGetTypeID()) {
- allowsEntitlement = whitelistArrayAllowsEntitlementValue((CFArrayRef) storedValue, (CFStringRef) value);
- } else if (CFGetTypeID(value) == CFArrayGetTypeID()) {
-
- /*
- * Assume allowed, will set back to false if we encounter
- * elements that are not permitted
- */
- allowsEntitlement = true;
-
- /* Make sure each element is a string and in the array */
- 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;
-}