1 /* Copyright (c) 2012-2013 Apple Inc. All Rights Reserved. */
3 #include "authutilities.h"
4 #include "authd_private.h"
7 #include <AssertMacros.h>
12 SerializeItemSet(const AuthorizationItemSet
* itemSet
)
14 xpc_object_t set
= NULL
;
15 require_quiet(itemSet
!= NULL
, done
);
16 require_quiet(itemSet
->count
!= 0, done
);
18 set
= xpc_array_create(NULL
, 0);
19 require(set
!= NULL
, done
);
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
);
25 if (itemSet
->items
[i
].name
== NULL
) {
26 os_log_error(AUTHD_LOG
, "ItemSet - item #%d name is NULL", i
);
30 xpc_dictionary_set_string(item
, AUTH_XPC_ITEM_NAME
, itemSet
->items
[i
].name
);
31 xpc_dictionary_set_uint64(item
, AUTH_XPC_ITEM_FLAGS
, itemSet
->items
[i
].flags
);
32 xpc_dictionary_set_data(item
, AUTH_XPC_ITEM_VALUE
, itemSet
->items
[i
].value
, itemSet
->items
[i
].valueLength
);
33 xpc_array_set_value(set
, XPC_ARRAY_APPEND
, item
);
41 AuthorizationItemSet
*
42 DeserializeItemSet(const xpc_object_t data
)
44 AuthorizationItemSet
* set
= NULL
;
45 require_quiet(data
!= NULL
, done
);
47 require(xpc_get_type(data
) == XPC_TYPE_ARRAY
, done
);
49 set
= (AuthorizationItemSet
*)calloc(1u, sizeof(AuthorizationItemSet
));
50 require(set
!= NULL
, done
);
52 set
->count
= (uint32_t)xpc_array_get_count(data
);
54 set
->items
= (AuthorizationItem
*)calloc(set
->count
, sizeof(AuthorizationItem
));
55 require_action(set
->items
!= NULL
, done
, set
->count
= 0);
57 xpc_array_apply(data
, ^bool(size_t index
, xpc_object_t value
) {
59 require(xpc_get_type(value
) == XPC_TYPE_DICTIONARY
, done
);
61 const char * name
= xpc_dictionary_get_string(value
, AUTH_XPC_ITEM_NAME
);
63 nameLen
= strlen(name
) + 1;
64 set
->items
[index
].name
= calloc(1u, nameLen
);
65 require(set
->items
[index
].name
!= NULL
, done
);
67 strlcpy((char*)set
->items
[index
].name
, name
, nameLen
);
69 set
->items
[index
].flags
= (uint32_t)xpc_dictionary_get_uint64(value
, AUTH_XPC_ITEM_FLAGS
);
71 const void * valueData
= xpc_dictionary_get_data(value
, AUTH_XPC_ITEM_VALUE
, &len
);
73 // <rdar://problem/13033889> authd is holding on to multiple copies of my password in the clear
74 if (xpc_dictionary_get_value(value
, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH
) != NULL
) {
75 size_t sensitiveLength
= (size_t)xpc_dictionary_get_uint64(value
, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH
);
76 if (sensitiveLength
> len
) {
77 os_log_error(AUTHD_LOG
, "Sensitive data len %zu is not valid", sensitiveLength
);
80 dataCopy
= malloc(sensitiveLength
);
81 require(dataCopy
!= NULL
, done
);
82 memcpy(dataCopy
, valueData
, sensitiveLength
);
83 memset_s((void *)valueData
, len
, 0, sensitiveLength
); // clear the sensitive data, memset_s is never optimized away
84 len
= sensitiveLength
;
86 dataCopy
= malloc(len
);
87 require(dataCopy
!= NULL
, done
);
88 memcpy(dataCopy
, valueData
, len
);
91 set
->items
[index
].valueLength
= len
;
93 set
->items
[index
].value
= calloc(1u, len
);
94 require(set
->items
[index
].value
!= NULL
, done
);
96 memcpy(set
->items
[index
].value
, dataCopy
, len
);
113 void FreeItemSet(AuthorizationItemSet
* itemSet
)
115 if (!itemSet
) { return; }
117 for(uint32_t i
= 0; i
< itemSet
->count
; i
++ ) {
118 if (itemSet
->items
[i
].name
) {
119 free((void*)itemSet
->items
[i
].name
);
121 if (itemSet
->items
[i
].value
) {
122 free(itemSet
->items
[i
].value
);
125 if (itemSet
->items
) {
126 free(itemSet
->items
);
133 _copy_cf_string(CFTypeRef str
, const char * defaultValue
)
135 char * result
= NULL
;
136 require(str
!= NULL
, done
);
137 require(CFGetTypeID(str
) == CFStringGetTypeID(), done
);
139 CFIndex length
= CFStringGetLength(str
);
140 CFIndex size
= CFStringGetMaximumSizeForEncoding(length
, kCFStringEncodingUTF8
) + 1;
142 result
= (char*)calloc(1u, (size_t)size
);
143 check(result
!= NULL
);
145 if (!CFStringGetCString(str
, result
, size
, kCFStringEncodingUTF8
)) {
150 if (result
== NULL
&& defaultValue
) {
151 size_t len
= strlen(defaultValue
);
152 result
= (char*)calloc(1u, len
);
153 check(result
!= NULL
);
155 strlcpy(result
, defaultValue
, len
);
162 _get_cf_int(CFTypeRef num
, int64_t defaultValue
)
164 int64_t result
= defaultValue
;
165 require(num
!= NULL
, done
);
166 require(CFGetTypeID(num
) == CFNumberGetTypeID(), done
);
168 if (!CFNumberGetValue(num
, kCFNumberSInt64Type
, &result
)) {
169 result
= defaultValue
;
177 _get_cf_bool(CFTypeRef value
, bool defaultValue
)
179 bool result
= defaultValue
;
180 require(value
!= NULL
, done
);
181 require(CFGetTypeID(value
) == CFBooleanGetTypeID(), done
);
183 result
= CFBooleanGetValue(value
);
190 _compare_string(const char * str1
, const char * str2
)
192 if (!(str1
== str2
)) { // compare null or same pointer
193 if (str1
&& str2
) { // check both are non null
194 if (strcasecmp(str1
, str2
) != 0) { // compare strings
195 return false; // return false if not equal
198 return false; // return false if one null
206 _copy_string(const char * str
)
208 char * result
= NULL
;
209 require(str
!= NULL
, done
);
211 size_t len
= strlen(str
) + 1;
212 result
= calloc(1u, len
);
213 require(result
!= NULL
, done
);
215 strlcpy(result
, str
, len
);
222 _copy_data(const void * data
, size_t dataLen
)
224 void * result
= NULL
;
225 require(data
!= NULL
, done
);
227 result
= calloc(1u, dataLen
);
228 require(result
!= NULL
, done
);
230 memcpy(result
, data
, dataLen
);
236 bool _cf_set_iterate(CFSetRef set
, bool(^iterator
)(CFTypeRef value
))
239 CFTypeRef
* values
= NULL
;
241 require(set
!= NULL
, done
);
243 CFIndex count
= CFSetGetCount(set
);
244 values
= calloc((size_t)count
, sizeof(CFTypeRef
));
245 require(values
!= NULL
, done
);
247 CFSetGetValues(set
, values
);
248 for (CFIndex i
= 0; i
< count
; i
++) {
249 result
= iterator(values
[i
]);
260 bool _cf_bag_iterate(CFBagRef bag
, bool(^iterator
)(CFTypeRef value
))
263 CFTypeRef
* values
= NULL
;
265 require(bag
!= NULL
, done
);
267 CFIndex count
= CFBagGetCount(bag
);
268 values
= calloc((size_t)count
, sizeof(CFTypeRef
));
269 require(values
!= NULL
, done
);
271 CFBagGetValues(bag
, values
);
272 for (CFIndex i
= 0; i
< count
; i
++) {
273 result
= iterator(values
[i
]);
284 bool _cf_dictionary_iterate(CFDictionaryRef dict
, bool(^iterator
)(CFTypeRef key
, CFTypeRef value
))
287 CFTypeRef
* keys
= NULL
;
288 CFTypeRef
* values
= NULL
;
290 require(dict
!= NULL
, done
);
292 CFIndex count
= CFDictionaryGetCount(dict
);
293 keys
= calloc((size_t)count
, sizeof(CFTypeRef
));
294 require(keys
!= NULL
, done
);
296 values
= calloc((size_t)count
, sizeof(CFTypeRef
));
297 require(values
!= NULL
, done
);
299 CFDictionaryGetKeysAndValues(dict
, keys
, values
);
300 for (CFIndex i
= 0; i
< count
; i
++) {
301 result
= iterator(keys
[i
], values
[i
]);
315 // temporary solution until we find a better way
316 return getenv("__OSINSTALL_ENVIRONMENT") != NULL
;