1 #include "MISEntitlement.h"
3 static const CFStringRef kEntitlementAllValuesAllowed
= CFSTR("*");
5 static Boolean
whitelistArrayAllowsEntitlementValue(CFArrayRef whitelist
, CFStringRef value
)
7 Boolean allowed
= false;
9 CFIndex i
, count
= CFArrayGetCount(whitelist
);
10 for (i
= 0; (i
< count
) && (allowed
== false); i
++) {
11 CFStringRef item
= (CFStringRef
) CFArrayGetValueAtIndex(whitelist
, i
);
12 if (CFGetTypeID(item
) == CFStringGetTypeID()) {
14 CFIndex len
= CFStringGetLength(item
);
16 if (CFStringGetCharacterAtIndex(item
, len
-1) != '*') {
18 /* Not a wildcard, must be an exact match */
19 allowed
= CFStringCompare(item
, value
, 0) == kCFCompareEqualTo
;
22 /* Last character is a wildcard - do some matching */
23 CFStringRef wildcardPrefix
= CFStringCreateWithSubstring(kCFAllocatorDefault
, item
, CFRangeMake(0, len
-1));
24 allowed
= CFStringHasPrefix(value
, wildcardPrefix
);
25 CFRelease(wildcardPrefix
);
30 /* Unexpected item in whitelist - bail */
38 Boolean
MISEntitlementDictionaryAllowsEntitlementValue(CFDictionaryRef entitlements
, CFStringRef entitlement
, CFTypeRef value
)
40 Boolean allowsEntitlement
= false;
42 /* NULL is never a valid entitlement value */
45 /* Make sure the entitlement is present */
46 CFTypeRef storedValue
= CFDictionaryGetValue(entitlements
, entitlement
);
47 if (storedValue
!= NULL
) {
50 * Handling depends on the type
51 * If the value matches our constant, the entitlement is permitted
53 * If the value in the dictionary is a boolean, then the entitlement
54 * value must be a boolean with the same value
55 * If the value in the dictionary is an array (of strings), then the
56 * entitlement must be either one of those strings OR an array that
57 * includes only present strings
59 if (CFEqual(storedValue
, kEntitlementAllValuesAllowed
) == true) {
61 /* XXX: Does this need to restrict the value to some types */
62 allowsEntitlement
= true;
63 } else if (CFGetTypeID(storedValue
) == CFBooleanGetTypeID()) {
64 allowsEntitlement
= CFEqual(storedValue
, value
);
65 } else if (CFGetTypeID(storedValue
) == CFStringGetTypeID()) {
66 if (CFGetTypeID(value
) == CFStringGetTypeID()) {
67 CFArrayRef array
= CFArrayCreate(kCFAllocatorDefault
, (const void **) &storedValue
, 1, &kCFTypeArrayCallBacks
);
68 allowsEntitlement
= whitelistArrayAllowsEntitlementValue(array
, (CFStringRef
) value
);
71 } else if (CFGetTypeID(storedValue
) == CFArrayGetTypeID()) {
73 /* value is either a single string or array of strings */
74 if (CFGetTypeID(value
) == CFStringGetTypeID()) {
75 allowsEntitlement
= whitelistArrayAllowsEntitlementValue((CFArrayRef
) storedValue
, (CFStringRef
) value
);
76 } else if (CFGetTypeID(value
) == CFArrayGetTypeID()) {
79 * Assume allowed, will set back to false if we encounter
80 * elements that are not permitted
82 allowsEntitlement
= true;
84 /* Make sure each element is a string and in the array */
85 CFIndex i
, count
= CFArrayGetCount((CFArrayRef
) value
);
86 for (i
= 0; (i
< count
) && (allowsEntitlement
== true); i
++) {
87 CFTypeRef element
= CFArrayGetValueAtIndex((CFArrayRef
) value
, i
);
88 if (CFGetTypeID(element
) == CFStringGetTypeID()) {
89 allowsEntitlement
= whitelistArrayAllowsEntitlementValue((CFArrayRef
) storedValue
, (CFStringRef
) element
);
91 allowsEntitlement
= false;
99 return allowsEntitlement
;