]> git.saurik.com Git - apple/security.git/blob - OSX/authd/authutilities.c
Security-57337.60.2.tar.gz
[apple/security.git] / OSX / authd / authutilities.c
1 /* Copyright (c) 2012-2013 Apple Inc. All Rights Reserved. */
2
3 #include "authutilities.h"
4 #include "authd_private.h"
5 #include "debugging.h"
6
7 #include <AssertMacros.h>
8 #include <assert.h>
9 #include <syslog.h>
10
11 xpc_object_t
12 SerializeItemSet(const AuthorizationItemSet * itemSet)
13 {
14 xpc_object_t set = NULL;
15 require_quiet(itemSet != NULL, done);
16 require_quiet(itemSet->count != 0, done);
17
18 set = xpc_array_create(NULL, 0);
19 require(set != NULL, done);
20
21 for (uint32_t i = 0; i < itemSet->count; i++) {
22 xpc_object_t item = xpc_dictionary_create(NULL, NULL, 0);
23 require(item != NULL, done);
24
25 xpc_dictionary_set_string(item, AUTH_XPC_ITEM_NAME, itemSet->items[i].name);
26 xpc_dictionary_set_uint64(item, AUTH_XPC_ITEM_FLAGS, itemSet->items[i].flags);
27 xpc_dictionary_set_data(item, AUTH_XPC_ITEM_VALUE, itemSet->items[i].value, itemSet->items[i].valueLength);
28 xpc_array_set_value(set, XPC_ARRAY_APPEND, item);
29 xpc_release(item);
30 }
31
32 done:
33 return set;
34 }
35
36 AuthorizationItemSet *
37 DeserializeItemSet(const xpc_object_t data)
38 {
39 AuthorizationItemSet * set = NULL;
40 require_quiet(data != NULL, done);
41 xpc_retain(data);
42 require(xpc_get_type(data) == XPC_TYPE_ARRAY, done);
43
44 set = (AuthorizationItemSet*)calloc(1u, sizeof(AuthorizationItemSet));
45 require(set != NULL, done);
46
47 set->count = (uint32_t)xpc_array_get_count(data);
48 if (set->count) {
49 set->items = (AuthorizationItem*)calloc(set->count, sizeof(AuthorizationItem));
50 require_action(set->items != NULL, done, set->count = 0);
51
52 xpc_array_apply(data, ^bool(size_t index, xpc_object_t value) {
53 require(xpc_get_type(value) == XPC_TYPE_DICTIONARY, done);
54 size_t nameLen = 0;
55 const char * name = xpc_dictionary_get_string(value, AUTH_XPC_ITEM_NAME);
56 if (name) {
57 nameLen = strlen(name) + 1;
58 set->items[index].name = calloc(1u, nameLen);
59 require(set->items[index].name != NULL, done);
60
61 strlcpy((char*)set->items[index].name, name, nameLen);
62 }
63 set->items[index].flags = (uint32_t)xpc_dictionary_get_uint64(value, AUTH_XPC_ITEM_FLAGS);
64 size_t len;
65 const void * valueData = xpc_dictionary_get_data(value, AUTH_XPC_ITEM_VALUE, &len);
66 set->items[index].valueLength = len;
67 if (len) {
68 set->items[index].value = calloc(1u, len);
69 require(set->items[index].value != NULL, done);
70
71 memcpy(set->items[index].value, valueData, len);
72 }
73 done:
74 return true;
75 });
76 }
77
78 done:
79 if (data != NULL) {
80 xpc_release(data);
81 }
82 return set;
83 }
84
85 void FreeItemSet(AuthorizationItemSet * itemSet)
86 {
87 if (!itemSet) { return; }
88
89 for(uint32_t i = 0; i < itemSet->count; i++ ) {
90 if (itemSet->items[i].name) {
91 free((void*)itemSet->items[i].name);
92 }
93 if (itemSet->items[i].value) {
94 free(itemSet->items[i].value);
95 }
96 }
97 if (itemSet->items) {
98 free(itemSet->items);
99 }
100
101 free(itemSet);
102 }
103
104 char *
105 _copy_cf_string(CFTypeRef str, const char * defaultValue)
106 {
107 char * result = NULL;
108 require(str != NULL, done);
109 require(CFGetTypeID(str) == CFStringGetTypeID(), done);
110
111 CFIndex length = CFStringGetLength(str);
112 CFIndex size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
113
114 result = (char*)calloc(1u, (size_t)size);
115 check(result != NULL);
116
117 if (!CFStringGetCString(str, result, size, kCFStringEncodingUTF8)) {
118 free_safe(result);
119 }
120
121 done:
122 if (result == NULL && defaultValue) {
123 size_t len = strlen(defaultValue);
124 result = (char*)calloc(1u, len);
125 check(result != NULL);
126
127 strlcpy(result, defaultValue, len);
128 }
129
130 return result;
131 }
132
133 int64_t
134 _get_cf_int(CFTypeRef num, int64_t defaultValue)
135 {
136 int64_t result = defaultValue;
137 require(num != NULL, done);
138 require(CFGetTypeID(num) == CFNumberGetTypeID(), done);
139
140 if (!CFNumberGetValue(num, kCFNumberSInt64Type, &result)) {
141 result = defaultValue;
142 }
143
144 done:
145 return result;
146 }
147
148 bool
149 _get_cf_bool(CFTypeRef value, bool defaultValue)
150 {
151 bool result = defaultValue;
152 require(value != NULL, done);
153 require(CFGetTypeID(value) == CFBooleanGetTypeID(), done);
154
155 result = CFBooleanGetValue(value);
156
157 done:
158 return result;
159 }
160
161 bool
162 _compare_string(const char * str1, const char * str2)
163 {
164 if (!(str1 == str2)) { // compare null or same pointer
165 if (str1 && str2) { // check both are non null
166 if (strcasecmp(str1, str2) != 0) { // compare strings
167 return false; // return false if not equal
168 }
169 } else {
170 return false; // return false if one null
171 }
172 }
173
174 return true;
175 }
176
177 char *
178 _copy_string(const char * str)
179 {
180 char * result = NULL;
181 require(str != NULL, done);
182
183 size_t len = strlen(str) + 1;
184 result = calloc(1u, len);
185 require(result != NULL, done);
186
187 strlcpy(result, str, len);
188
189 done:
190 return result;
191 }
192
193 void *
194 _copy_data(const void * data, size_t dataLen)
195 {
196 void * result = NULL;
197 require(data != NULL, done);
198
199 result = calloc(1u, dataLen);
200 require(result != NULL, done);
201
202 memcpy(result, data, dataLen);
203
204 done:
205 return result;
206 }
207
208 bool _cf_set_iterate(CFSetRef set, bool(^iterator)(CFTypeRef value))
209 {
210 bool result = false;
211 CFTypeRef* values = NULL;
212
213 require(set != NULL, done);
214
215 CFIndex count = CFSetGetCount(set);
216 values = calloc((size_t)count, sizeof(CFTypeRef));
217 require(values != NULL, done);
218
219 CFSetGetValues(set, values);
220 for (CFIndex i = 0; i < count; i++) {
221 result = iterator(values[i]);
222 if (!result) {
223 break;
224 }
225 }
226
227 done:
228 free_safe(values);
229 return result;
230 }
231
232 bool _cf_bag_iterate(CFBagRef bag, bool(^iterator)(CFTypeRef value))
233 {
234 bool result = false;
235 CFTypeRef* values = NULL;
236
237 require(bag != NULL, done);
238
239 CFIndex count = CFBagGetCount(bag);
240 values = calloc((size_t)count, sizeof(CFTypeRef));
241 require(values != NULL, done);
242
243 CFBagGetValues(bag, values);
244 for (CFIndex i = 0; i < count; i++) {
245 result = iterator(values[i]);
246 if (!result) {
247 break;
248 }
249 }
250
251 done:
252 free_safe(values);
253 return result;
254 }
255
256 bool _cf_dictionary_iterate(CFDictionaryRef dict, bool(^iterator)(CFTypeRef key, CFTypeRef value))
257 {
258 bool result = false;
259 CFTypeRef* keys = NULL;
260 CFTypeRef* values = NULL;
261
262 require(dict != NULL, done);
263
264 CFIndex count = CFDictionaryGetCount(dict);
265 keys = calloc((size_t)count, sizeof(CFTypeRef));
266 require(keys != NULL, done);
267
268 values = calloc((size_t)count, sizeof(CFTypeRef));
269 require(values != NULL, done);
270
271 CFDictionaryGetKeysAndValues(dict, keys, values);
272 for (CFIndex i = 0; i < count; i++) {
273 result = iterator(keys[i], values[i]);
274 if (!result) {
275 break;
276 }
277 }
278
279 done:
280 free_safe(keys);
281 free_safe(values);
282 return result;
283 }