xref: /xnu-12377.41.6/EXTERNAL_HEADERS/CoreEntitlements/QueryHelpers.h (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
1*bbb1b6f9SApple OSS Distributions //
2*bbb1b6f9SApple OSS Distributions //  QueryHelpers.h
3*bbb1b6f9SApple OSS Distributions //  CoreEntitlements
4*bbb1b6f9SApple OSS Distributions //
5*bbb1b6f9SApple OSS Distributions 
6*bbb1b6f9SApple OSS Distributions #ifndef CORE_ENTITLEMENTS_HELPERS_H
7*bbb1b6f9SApple OSS Distributions #define CORE_ENTITLEMENTS_HELPERS_H
8*bbb1b6f9SApple OSS Distributions 
9*bbb1b6f9SApple OSS Distributions #include <sys/cdefs.h>
10*bbb1b6f9SApple OSS Distributions __ptrcheck_abi_assume_single();
11*bbb1b6f9SApple OSS Distributions 
12*bbb1b6f9SApple OSS Distributions /*!
13*bbb1b6f9SApple OSS Distributions  * @function CEDynamic
14*bbb1b6f9SApple OSS Distributions  * Marks an opcode as being dynamic
15*bbb1b6f9SApple OSS Distributions  *
16*bbb1b6f9SApple OSS Distributions  * @param op
17*bbb1b6f9SApple OSS Distributions  * Opcode
18*bbb1b6f9SApple OSS Distributions  */
19*bbb1b6f9SApple OSS Distributions #define CEDynamic(op) (CEQueryOpOpcode_t)((op) | kCEOpDynamic)
20*bbb1b6f9SApple OSS Distributions 
21*bbb1b6f9SApple OSS Distributions /*!
22*bbb1b6f9SApple OSS Distributions  * @function CESelectIndex
23*bbb1b6f9SApple OSS Distributions  * Returns an operation that when executed will modify the context such that any subsequent operation is performed on the entitlement object at the specified index
24*bbb1b6f9SApple OSS Distributions  *
25*bbb1b6f9SApple OSS Distributions  * @param index
26*bbb1b6f9SApple OSS Distributions  * The index of the object within a container
27*bbb1b6f9SApple OSS Distributions  *
28*bbb1b6f9SApple OSS Distributions  * @discussion
29*bbb1b6f9SApple OSS Distributions  * Using an index that is past the container's size will result in an invalid context
30*bbb1b6f9SApple OSS Distributions  */
31*bbb1b6f9SApple OSS Distributions #define CESelectIndex(index) (CEQueryOperation_t){.opcode = kCEOpSelectIndex, .parameters = {.numericParameter = index}}
32*bbb1b6f9SApple OSS Distributions 
33*bbb1b6f9SApple OSS Distributions /*!
34*bbb1b6f9SApple OSS Distributions  * @function CESelectKey
35*bbb1b6f9SApple OSS Distributions  * Returns an operation that when executed will modify the context such that any subsequent operation is performed on the key of the dictionary pair
36*bbb1b6f9SApple OSS Distributions  * @discussion
37*bbb1b6f9SApple OSS Distributions  * Selecting a key on a non-dictionary-pair object is undefined behavior (i..e. it is implementation defined)
38*bbb1b6f9SApple OSS Distributions  */
39*bbb1b6f9SApple OSS Distributions #define CESelectKey() CESelectIndex(0)
40*bbb1b6f9SApple OSS Distributions 
41*bbb1b6f9SApple OSS Distributions /*!
42*bbb1b6f9SApple OSS Distributions  * @function CESelectValue
43*bbb1b6f9SApple OSS Distributions  * Returns an operation that when executed will modify the context such that any subsequent operation is performed on the value of the dictionary pair
44*bbb1b6f9SApple OSS Distributions  * @discussion
45*bbb1b6f9SApple OSS Distributions  * Selecting a value on a non-dictionary-pair object is undefined behavior (i..e. it is implementation defined)
46*bbb1b6f9SApple OSS Distributions  */
47*bbb1b6f9SApple OSS Distributions #define CESelectValue() CESelectIndex(1)
48*bbb1b6f9SApple OSS Distributions 
49*bbb1b6f9SApple OSS Distributions 
50*bbb1b6f9SApple OSS Distributions /*!
51*bbb1b6f9SApple OSS Distributions  * @function CESelectDictValue
52*bbb1b6f9SApple OSS Distributions  * Returns an operation that when executed will modify the context such that any subsequent operation is performed on the object that corresponds
53*bbb1b6f9SApple OSS Distributions  * to the value pointed to by the specified key
54*bbb1b6f9SApple OSS Distributions  *
55*bbb1b6f9SApple OSS Distributions  * @param key
56*bbb1b6f9SApple OSS Distributions  * The key of the object within a container
57*bbb1b6f9SApple OSS Distributions  *
58*bbb1b6f9SApple OSS Distributions  * @discussion
59*bbb1b6f9SApple OSS Distributions  * Using a key that is not found in the container will result in an invalid context
60*bbb1b6f9SApple OSS Distributions  */
61*bbb1b6f9SApple OSS Distributions #define CESelectDictValue(key) (CEQueryOperation_t){.opcode = kCEOpSelectKey, .parameters = {.stringParameter = {.data = key, .length = sizeof(key) - 1}}}
62*bbb1b6f9SApple OSS Distributions #define CESelectDictValueDynamic(key, len) (CEQueryOperation_t){.opcode = CEDynamic(kCEOpSelectKey), .parameters = {.dynamicParameter = {.data = key, .length = len}}}
63*bbb1b6f9SApple OSS Distributions 
64*bbb1b6f9SApple OSS Distributions /*!
65*bbb1b6f9SApple OSS Distributions  * @function CEMatchString
66*bbb1b6f9SApple OSS Distributions  * Returns an operation that will return a valid context if and only if the context corresponds to a valid string and matches the string exactly
67*bbb1b6f9SApple OSS Distributions  *
68*bbb1b6f9SApple OSS Distributions  * @param string
69*bbb1b6f9SApple OSS Distributions  * The string to match against (MUST BE A STRING LITERAL)
70*bbb1b6f9SApple OSS Distributions  *
71*bbb1b6f9SApple OSS Distributions  * @discussion
72*bbb1b6f9SApple OSS Distributions  * If a valid context is returned it will be in the same state as the execution context
73*bbb1b6f9SApple OSS Distributions  */
74*bbb1b6f9SApple OSS Distributions #define CEMatchString(string) (CEQueryOperation_t){.opcode = kCEOpMatchString, .parameters = {.stringParameter = {.data = string, .length = sizeof(string) - 1}}}
75*bbb1b6f9SApple OSS Distributions #define CEMatchDynamicString(string, len) (CEQueryOperation_t){.opcode = CEDynamic(kCEOpMatchString), .parameters = {.dynamicParameter = {.data = string, .length = len}}}
76*bbb1b6f9SApple OSS Distributions 
77*bbb1b6f9SApple OSS Distributions /*!
78*bbb1b6f9SApple OSS Distributions  * @function CEMatchPrefix
79*bbb1b6f9SApple OSS Distributions  * Returns an operation that will return a valid context if and only if the context corresponds to a valid string and it's prefix matched the passed in prefix
80*bbb1b6f9SApple OSS Distributions  *
81*bbb1b6f9SApple OSS Distributions  * @param prefix
82*bbb1b6f9SApple OSS Distributions  * The prefix to match against (MUST BE A STRING LITERAL)
83*bbb1b6f9SApple OSS Distributions  *
84*bbb1b6f9SApple OSS Distributions  * @discussion
85*bbb1b6f9SApple OSS Distributions  * If a valid context is returned it will be in the same state as the execution context
86*bbb1b6f9SApple OSS Distributions  */
87*bbb1b6f9SApple OSS Distributions #define CEMatchPrefix(prefix) (CEQueryOperation_t){.opcode = kCEOpMatchStringPrefix, .parameters = {.stringParameter = {.data = prefix, .length = sizeof(prefix) - 1}}}
88*bbb1b6f9SApple OSS Distributions #define CEMatchDynamicPrefix(prefix, len) (CEQueryOperation_t){.opcode = CEDynamic(kCEOpMatchStringPrefix), .parameters = {.dynamicParameter = {.data = prefix, .length = len}}}
89*bbb1b6f9SApple OSS Distributions 
90*bbb1b6f9SApple OSS Distributions /*!
91*bbb1b6f9SApple OSS Distributions  * @function CEMatchType
92*bbb1b6f9SApple OSS Distributions  * Returns an operation that will return a valid context if and only if the type selected by the context corresponds to the one passed in.
93*bbb1b6f9SApple OSS Distributions  *
94*bbb1b6f9SApple OSS Distributions  * @param type
95*bbb1b6f9SApple OSS Distributions  * The type to match against
96*bbb1b6f9SApple OSS Distributions  *
97*bbb1b6f9SApple OSS Distributions  * @discussion
98*bbb1b6f9SApple OSS Distributions  * If a valid context is returned it will be in the same state as the execution context
99*bbb1b6f9SApple OSS Distributions  */
100*bbb1b6f9SApple OSS Distributions #define CEMatchType(type) (CEQueryOperation_t){.opcode = kCEOpMatchType, .parameters = {.numericParameter = (int64_t)type}}
101*bbb1b6f9SApple OSS Distributions 
102*bbb1b6f9SApple OSS Distributions /*!
103*bbb1b6f9SApple OSS Distributions  * @function CEMatchBool
104*bbb1b6f9SApple OSS Distributions  * Returns an operation that will return a valid context if and only if the context corresponds to a valid boolean and matches the boolean exactly
105*bbb1b6f9SApple OSS Distributions  *
106*bbb1b6f9SApple OSS Distributions  * @param val
107*bbb1b6f9SApple OSS Distributions  * The bool to match against
108*bbb1b6f9SApple OSS Distributions  *
109*bbb1b6f9SApple OSS Distributions  * @discussion
110*bbb1b6f9SApple OSS Distributions  * If a valid context is returned it will be in the same state as the execution context
111*bbb1b6f9SApple OSS Distributions  */
112*bbb1b6f9SApple OSS Distributions #define CEMatchBool(val) (CEQueryOperation_t){.opcode = kCEOpMatchBool, .parameters = {.numericParameter = !!val}}
113*bbb1b6f9SApple OSS Distributions 
114*bbb1b6f9SApple OSS Distributions /*!
115*bbb1b6f9SApple OSS Distributions  * @function CEMatchInteger
116*bbb1b6f9SApple OSS Distributions  * Returns an operation that will return a valid context if and only if the context corresponds to a valid integer and matches the integer exactly
117*bbb1b6f9SApple OSS Distributions  *
118*bbb1b6f9SApple OSS Distributions  * @param val
119*bbb1b6f9SApple OSS Distributions  * The integer to match against
120*bbb1b6f9SApple OSS Distributions  *
121*bbb1b6f9SApple OSS Distributions  * @discussion
122*bbb1b6f9SApple OSS Distributions  * If a valid context is returned it will be in the same state as the execution context
123*bbb1b6f9SApple OSS Distributions  */
124*bbb1b6f9SApple OSS Distributions #define CEMatchInteger(val) (CEQueryOperation_t){.opcode = kCEOpMatchInteger, .parameters = {.numericParameter = val}}
125*bbb1b6f9SApple OSS Distributions 
126*bbb1b6f9SApple OSS Distributions /*!
127*bbb1b6f9SApple OSS Distributions  * @function CEIsIntegerAllowed
128*bbb1b6f9SApple OSS Distributions  * Returns an operation that will return a valid context if 1) the current context is an integer and allows the integer, or 2) the context is an array of integers that allows the integer
129*bbb1b6f9SApple OSS Distributions  *
130*bbb1b6f9SApple OSS Distributions  * @param integer
131*bbb1b6f9SApple OSS Distributions  * The integer to match against
132*bbb1b6f9SApple OSS Distributions  *
133*bbb1b6f9SApple OSS Distributions  * @discussion
134*bbb1b6f9SApple OSS Distributions  * If a valid context is returned it will be in the same state as the execution context
135*bbb1b6f9SApple OSS Distributions  */
136*bbb1b6f9SApple OSS Distributions #define CEIsIntegerAllowed(integer) (CEQueryOperation_t){.opcode = kCEOpIntegerValueAllowed, .parameters = {.numericParameter = integer}}
137*bbb1b6f9SApple OSS Distributions 
138*bbb1b6f9SApple OSS Distributions /*!
139*bbb1b6f9SApple OSS Distributions  * @function CEIsStringAllowed
140*bbb1b6f9SApple OSS Distributions  * Returns an operation that will return a valid context if 1) the current context is a string and allows the string via wildcard rules, or 2) the context is an array of strings that allows the string
141*bbb1b6f9SApple OSS Distributions  *
142*bbb1b6f9SApple OSS Distributions  * @param string
143*bbb1b6f9SApple OSS Distributions  * The string to match against (MUST BE A STRING LITERAL)
144*bbb1b6f9SApple OSS Distributions  *
145*bbb1b6f9SApple OSS Distributions  * @discussion
146*bbb1b6f9SApple OSS Distributions  * If a valid context is returned it will be in the same state as the execution context
147*bbb1b6f9SApple OSS Distributions  */
148*bbb1b6f9SApple OSS Distributions #define CEIsStringAllowed(string) (CEQueryOperation_t){.opcode = kCEOpStringValueAllowed, .parameters = {.stringParameter = {.data = string, .length = sizeof(string) - 1}}}
149*bbb1b6f9SApple OSS Distributions #define CEIsDynamicStringAllowed(string, len) (CEQueryOperation_t){.opcode = CEDynamic(kCEOpStringValueAllowed), .parameters = {.dynamicParameter = {.data = string, .length = len}}}
150*bbb1b6f9SApple OSS Distributions 
151*bbb1b6f9SApple OSS Distributions /*!
152*bbb1b6f9SApple OSS Distributions  * @function CEIsStringPrefixAllowed
153*bbb1b6f9SApple OSS Distributions  * Returns an operation that will return a valid context if 1) the current context is a string and matches the prefix or 2) has an array that has the matches the prefix
154*bbb1b6f9SApple OSS Distributions  *
155*bbb1b6f9SApple OSS Distributions  * @param string
156*bbb1b6f9SApple OSS Distributions  * The string to match against (MUST BE A STRING LITERAL)
157*bbb1b6f9SApple OSS Distributions  *
158*bbb1b6f9SApple OSS Distributions  * @discussion
159*bbb1b6f9SApple OSS Distributions  * If a valid context is returned it will be in the same state as the execution context
160*bbb1b6f9SApple OSS Distributions  */
161*bbb1b6f9SApple OSS Distributions #define CEIsStringPrefixAllowed(string) (CEQueryOperation_t){.opcode = kCEOpStringPrefixValueAllowed, .parameters = {.stringParameter = {.data = string, .length = sizeof(string) - 1}}}
162*bbb1b6f9SApple OSS Distributions #define CEIsDynamicStringPrefixAllowed(string, len) (CEQueryOperation_t){.opcode = CEDynamic(kCEOpStringPrefixValueAllowed), .parameters = {.dynamicParameter = {.data = (const uint8_t*)(string), .length = len}}}
163*bbb1b6f9SApple OSS Distributions 
164*bbb1b6f9SApple OSS Distributions /*!
165*bbb1b6f9SApple OSS Distributions  * @function CEMatchData
166*bbb1b6f9SApple OSS Distributions  * Returns an operation that will return a valid context if and only if the context corresponds to valid data and matches the data exactly
167*bbb1b6f9SApple OSS Distributions  *
168*bbb1b6f9SApple OSS Distributions  * @param string
169*bbb1b6f9SApple OSS Distributions  * The data to match against (MUST BE A BYTE ARRAY)
170*bbb1b6f9SApple OSS Distributions  *
171*bbb1b6f9SApple OSS Distributions  * @discussion
172*bbb1b6f9SApple OSS Distributions  * If a valid context is returned it will be in the same state as the execution context
173*bbb1b6f9SApple OSS Distributions  */
174*bbb1b6f9SApple OSS Distributions #define CEMatchDynamicData(d, len) (CEQueryOperation_t){.opcode = CEDynamic(kCEOpMatchData), .parameters = {.dynamicParameter = {.data = d, .length = len}}}
175*bbb1b6f9SApple OSS Distributions 
176*bbb1b6f9SApple OSS Distributions /*!
177*bbb1b6f9SApple OSS Distributions  * @function CEIsDataAllowed
178*bbb1b6f9SApple OSS Distributions  * Returns an operation that will return a valid context if 1) the current context is data and allows the data, or 2) the context is an array of data elements that allows the data
179*bbb1b6f9SApple OSS Distributions  *
180*bbb1b6f9SApple OSS Distributions  * @param string
181*bbb1b6f9SApple OSS Distributions  * The data to match against (MUST BE A BYTE ARRAY)
182*bbb1b6f9SApple OSS Distributions  *
183*bbb1b6f9SApple OSS Distributions  * @discussion
184*bbb1b6f9SApple OSS Distributions  * If a valid context is returned it will be in the same state as the execution context
185*bbb1b6f9SApple OSS Distributions  */
186*bbb1b6f9SApple OSS Distributions #define CEIsDynamicDataAllowed(d, len) (CEQueryOperation_t){.opcode = CEDynamic(kCEOpMatchDataValueAllowed), .parameters = {.dynamicParameter = {.data = d, .length = len}}}
187*bbb1b6f9SApple OSS Distributions 
188*bbb1b6f9SApple OSS Distributions #pragma mark Helpers
189*bbb1b6f9SApple OSS Distributions /*
190*bbb1b6f9SApple OSS Distributions  Macro magic
191*bbb1b6f9SApple OSS Distributions  */
192*bbb1b6f9SApple OSS Distributions #define _SELECT_NTH_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
193*bbb1b6f9SApple OSS Distributions 
194*bbb1b6f9SApple OSS Distributions #define _mc_1(_call, x) _call(x),
195*bbb1b6f9SApple OSS Distributions #define _mc_2(_call, x, ...) _call(x), _mc_1(_call, __VA_ARGS__)
196*bbb1b6f9SApple OSS Distributions #define _mc_3(_call, x, ...) _call(x), _mc_2(_call, __VA_ARGS__)
197*bbb1b6f9SApple OSS Distributions #define _mc_4(_call, x, ...) _call(x), _mc_3(_call, __VA_ARGS__)
198*bbb1b6f9SApple OSS Distributions #define _mc_5(_call, x, ...) _call(x), _mc_4(_call, __VA_ARGS__)
199*bbb1b6f9SApple OSS Distributions #define _mc_6(_call, x, ...) _call(x), _mc_5(_call, __VA_ARGS__)
200*bbb1b6f9SApple OSS Distributions #define _mc_7(_call, x, ...) _call(x), _mc_6(_call, __VA_ARGS__)
201*bbb1b6f9SApple OSS Distributions #define _mc_8(_call, x, ...) _call(x), _mc_7(_call, __VA_ARGS__)
202*bbb1b6f9SApple OSS Distributions #define _mc_9(_call, x, ...) _call(x), _mc_8(_call, __VA_ARGS__)
203*bbb1b6f9SApple OSS Distributions #define _mc_10(_call, x, ...) _call(x), _mc_9(_call, __VA_ARGS__)
204*bbb1b6f9SApple OSS Distributions 
205*bbb1b6f9SApple OSS Distributions #define _MACRO_ITER(macro, ...) _SELECT_NTH_ARG(__VA_ARGS__, _mc_10, _mc_9, _mc_8 _mc_7, _mc_6, _mc_5, _mc_4, _mc_3, _mc_2, _mc_1)(macro, __VA_ARGS__)
206*bbb1b6f9SApple OSS Distributions 
207*bbb1b6f9SApple OSS Distributions /*!
208*bbb1b6f9SApple OSS Distributions  Macro to automatically generate a query path from a list of string sub components
209*bbb1b6f9SApple OSS Distributions  So
210*bbb1b6f9SApple OSS Distributions  @code
211*bbb1b6f9SApple OSS Distributions  CE_SELECT_PATH("hello, "world") will select a key "hello" and then look up "world" in the dictionary stored in the value of "hello"
212*bbb1b6f9SApple OSS Distributions  @endcode
213*bbb1b6f9SApple OSS Distributions  */
214*bbb1b6f9SApple OSS Distributions #define CE_SELECT_PATH(...) _MACRO_ITER(CESelectDictValue, __VA_ARGS__)
215*bbb1b6f9SApple OSS Distributions 
216*bbb1b6f9SApple OSS Distributions // Macro for string equals
217*bbb1b6f9SApple OSS Distributions #define CE_STRING_EQUALS(str) CEMatchString(str)
218*bbb1b6f9SApple OSS Distributions 
219*bbb1b6f9SApple OSS Distributions /*
220*bbb1b6f9SApple OSS Distributions  A macro that checks if the passed in context grants (via an explicit true boolean) the entitlement at the passed in path.
221*bbb1b6f9SApple OSS Distributions  */
222*bbb1b6f9SApple OSS Distributions #define CE_CONTEXT_GRANTS_ENTITLEMENT(ctx, ...) (CEContextQuery(ctx, (CEQuery_t){CE_SELECT_PATH(__VA_ARGS__) CEMatchBool(true)}, sizeof((CEQuery_t){CE_SELECT_PATH(__VA_ARGS__) CEMatchBool(true)}) / sizeof(CEQueryOperation_t)) == kCENoError)
223*bbb1b6f9SApple OSS Distributions 
224*bbb1b6f9SApple OSS Distributions #endif
225