]> git.saurik.com Git - apple/security.git/blob - OSX/include/security_cdsa_utilities/AuthorizationData.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / include / security_cdsa_utilities / AuthorizationData.cpp
1 /*
2 * Copyright (c) 2000-2006,2011-2012,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <security_cdsa_utilities/AuthorizationData.h>
25 #include <security_cdsa_utilities/AuthorizationWalkers.h>
26 #include <security_cdsa_utilities/walkers.h>
27 #include <Security/checkpw.h>
28 #include <grp.h>
29 #include <pwd.h>
30
31
32 // checkpw() that uses provided struct passwd
33 extern "C"
34 {
35 int checkpw_internal( const struct passwd *pw, const char* password );
36 }
37
38
39 namespace Authorization {
40
41
42 AuthValueRef::AuthValueRef(const AuthValue &value) :
43 RefPointer<AuthValue>(new AuthValue(value)) {}
44
45 AuthValueRef::AuthValueRef(const AuthorizationValue &value) :
46 RefPointer<AuthValue>(new AuthValue(value)) {}
47
48 AuthValue::AuthValue(const AuthorizationValue &value) :
49 mOwnsValue(false)
50 {
51 mValue.length = value.length;
52 mValue.data = value.data;
53 }
54
55 AuthValueRef::AuthValueRef(UInt32 length, void *data) :
56 RefPointer<AuthValue>(new AuthValue(length, data)) {}
57
58 AuthValue::AuthValue(UInt32 length, void *data) :
59 mOwnsValue(true)
60 {
61 mValue.length = length;
62 mValue.data = new uint8_t[length];
63 if (length)
64 memcpy(mValue.data, data, length);
65 }
66
67 AuthValue::~AuthValue()
68 {
69 if (mOwnsValue)
70 {
71 memset(mValue.data, 0, mValue.length);
72 delete[] reinterpret_cast<uint8_t*>(mValue.data);
73 }
74 }
75
76 AuthValue &
77 AuthValue::operator = (const AuthValue &other)
78 {
79 if (mOwnsValue)
80 {
81 memset(mValue.data, 0 , mValue.length);
82 delete[] reinterpret_cast<uint8_t*>(mValue.data);
83 }
84
85 mValue = other.mValue;
86 mOwnsValue = other.mOwnsValue;
87 other.mOwnsValue = false;
88 return *this;
89 }
90
91 void
92 AuthValue::fillInAuthorizationValue(AuthorizationValue &value)
93 {
94 value.length = mValue.length;
95 value.data = mValue.data;
96 }
97
98 AuthValueVector &
99 AuthValueVector::operator = (const AuthorizationValueVector& valueVector)
100 {
101 clear();
102 for (unsigned int i=0; i < valueVector.count; i++)
103 push_back(AuthValueRef(valueVector.values[i]));
104 return *this;
105 }
106
107 void
108 AuthValueVector::copy(AuthorizationValueVector **data, size_t *length) const
109 {
110 AuthorizationValueVector valueVector;
111 valueVector.count = (UInt32)size();
112 valueVector.values = new AuthorizationValue[valueVector.count];
113 int i = 0;
114 for (const_iterator it = begin(); it != end(); ++it, ++i)
115 {
116 (*it)->fillInAuthorizationValue(valueVector.values[i]);
117 }
118
119 DataWalkers::Copier<AuthorizationValueVector> flatValueVector(&valueVector);
120 *length = flatValueVector.length();
121 *data = flatValueVector.keep();
122
123 delete[] valueVector.values;
124 }
125
126 AuthItem::AuthItem(const AuthorizationItem &item) :
127 mFlags(item.flags),
128 mOwnsName(true),
129 mOwnsValue(true)
130 {
131 if (!item.name)
132 MacOSError::throwMe(errAuthorizationInternal);
133 size_t nameLen = strlen(item.name) + 1;
134 mName = new char[nameLen];
135 memcpy(const_cast<char *>(mName), item.name, nameLen);
136
137 mValue.length = item.valueLength;
138 mValue.data = new uint8_t[item.valueLength];
139 if (mValue.length)
140 memcpy(mValue.data, item.value, item.valueLength);
141 }
142
143
144 AuthItem::AuthItem(AuthorizationString name) :
145 mName(name),
146 mFlags(0),
147 mOwnsName(false),
148 mOwnsValue(false)
149 {
150 mValue.length = 0;
151 mValue.data = NULL;
152 }
153
154 AuthItem::AuthItem(AuthorizationString name, AuthorizationValue value, AuthorizationFlags flags) :
155 mFlags(flags),
156 mOwnsName(true),
157 mOwnsValue(true)
158 {
159 if (!name)
160 MacOSError::throwMe(errAuthorizationInternal);
161 size_t nameLen = strlen(name) + 1;
162 mName = new char[nameLen];
163 memcpy(const_cast<char *>(mName), name, nameLen);
164
165 mValue.length = value.length;
166 mValue.data = new uint8_t[value.length];
167 if (mValue.length)
168 memcpy(mValue.data, value.data, value.length);
169 }
170
171 AuthItem::~AuthItem()
172 {
173 if (mOwnsName)
174 delete[] mName;
175 if (mOwnsValue)
176 {
177 memset(mValue.data, 0, mValue.length);
178 delete[] reinterpret_cast<uint8_t*>(mValue.data);
179 }
180 }
181
182 bool
183 AuthItem::operator < (const AuthItem &other) const
184 {
185 return strcmp(mName, other.mName) < 0;
186 }
187
188 AuthItem &
189 AuthItem::operator = (const AuthItem &other)
190 {
191 if (mOwnsName)
192 delete[] mName;
193 if (mOwnsValue)
194 {
195 memset(mValue.data, 0, mValue.length);
196 delete[] reinterpret_cast<uint8_t*>(mValue.data);
197 }
198
199 mName = other.mName;
200 mValue = other.mValue;
201 mFlags = other.mFlags;
202 mOwnsName = other.mOwnsName;
203 other.mOwnsName = false;
204 mOwnsValue = other.mOwnsValue;
205 other.mOwnsValue = false;
206 return *this;
207 }
208
209 void
210 AuthItem::fillInAuthorizationItem(AuthorizationItem &item)
211 {
212 item.name = mName;
213 item.valueLength = mValue.length;
214 item.value = mValue.data;
215 item.flags = mFlags;
216 }
217
218 bool
219 AuthItem::getBool(bool &value)
220 {
221 if (mValue.length == sizeof(bool))
222 {
223 bool *tmpValue = (bool *)mValue.data;
224
225 if (tmpValue)
226 {
227 value = *tmpValue;
228 return true;
229 }
230 }
231
232 return false;
233 }
234
235 bool
236 AuthItem::getString(string &value)
237 {
238 value = string(static_cast<char*>(mValue.data), mValue.length);
239 return true;
240 }
241
242 bool
243 AuthItem::getCssmData(CssmAutoData &value)
244 {
245 value = CssmData(static_cast<uint8_t*>(mValue.data), mValue.length);
246 return true;
247 }
248
249
250 AuthItemRef::AuthItemRef(const AuthorizationItem &item) : RefPointer<AuthItem>(new AuthItem(item)) {}
251
252 AuthItemRef::AuthItemRef(AuthorizationString name) : RefPointer<AuthItem>(new AuthItem(name)) {}
253
254 AuthItemRef::AuthItemRef(AuthorizationString name, AuthorizationValue value, AuthorizationFlags flags) : RefPointer<AuthItem>(new AuthItem(name, value, flags)) {}
255
256
257 //
258 // AuthItemSet
259 //
260 AuthItemSet::AuthItemSet()
261 : firstItemName(NULL)
262 {
263 }
264
265 AuthItemSet::~AuthItemSet()
266 {
267 if (NULL != firstItemName)
268 free(firstItemName);
269 }
270
271 AuthItemSet &
272 AuthItemSet::operator = (const AuthorizationItemSet& itemSet)
273 {
274 clear();
275
276 for (unsigned int i=0; i < itemSet.count; i++)
277 insert(AuthItemRef(itemSet.items[i]));
278
279 return *this;
280 }
281
282 AuthItemSet&
283 AuthItemSet::operator=(const AuthItemSet& itemSet)
284 {
285 std::set<AuthItemRef>::operator=(itemSet);
286
287 if (this != &itemSet) {
288 duplicate(itemSet);
289 }
290
291 return *this;
292 }
293
294 AuthItemSet::AuthItemSet(const AuthorizationItemSet *itemSet)
295 : firstItemName(NULL)
296 {
297 if (NULL != itemSet && NULL != itemSet->items)
298 {
299 if (0 < itemSet->count && NULL != itemSet->items[0].name)
300 firstItemName = strdup(itemSet->items[0].name);
301
302 for (unsigned int i=0; i < itemSet->count; i++)
303 insert(AuthItemRef(itemSet->items[i]));
304 }
305 }
306
307 AuthItemSet::AuthItemSet(const AuthItemSet& itemSet)
308 : std::set<AuthItemRef>(itemSet)
309 {
310 duplicate(itemSet);
311 }
312
313 void
314 AuthItemSet::duplicate(const AuthItemSet& itemSet)
315 {
316 if (itemSet.firstItemName != NULL)
317 firstItemName = strdup(itemSet.firstItemName);
318 else
319 firstItemName = NULL;
320 }
321
322 void
323 AuthItemSet::copy(AuthorizationItemSet *&data, size_t &length, Allocator &alloc) const
324 {
325 AuthorizationItemSet itemSet;
326 itemSet.count = (UInt32)size();
327 itemSet.items = new AuthorizationItem[itemSet.count];
328 int i = 0;
329 for (const_iterator it = begin(); it != end(); ++it, ++i)
330 {
331 (*it)->fillInAuthorizationItem(itemSet.items[i]);
332 }
333
334 DataWalkers::Copier<AuthorizationItemSet> flatItemSet(&itemSet, alloc);
335 length = flatItemSet.length();
336
337 data = flatItemSet.keep();
338 // else flatItemSet disappears again
339
340 delete[] itemSet.items;
341 }
342
343 AuthorizationItemSet *
344 AuthItemSet::copy() const
345 {
346 AuthorizationItemSet *aCopy;
347 size_t aLength;
348 copy(aCopy, aLength);
349 return aCopy;
350 }
351
352 AuthItem *
353 AuthItemSet::find(const char *name)
354 {
355 AuthItemSet::const_iterator found = find_if(this->begin(), this->end(), FindAuthItemByRightName(name) );
356 if (found != this->end())
357 return *found;
358
359 return NULL;
360 }
361
362 } // end namespace Authorization