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 33extern "C" 34{ 35int checkpw_internal( const struct passwd *pw, const char* password ); 36} 37 38 39namespace Authorization { 40 41 42AuthValueRef::AuthValueRef(const AuthValue &value) : 43 RefPointer<AuthValue>(new AuthValue(value)) {} 44 45AuthValueRef::AuthValueRef(const AuthorizationValue &value) : 46 RefPointer<AuthValue>(new AuthValue(value)) {} 47 48AuthValue::AuthValue(const AuthorizationValue &value) : 49 mOwnsValue(false) 50{ 51 mValue.length = value.length; 52 mValue.data = value.data; 53} 54 55AuthValueRef::AuthValueRef(UInt32 length, void *data) : 56 RefPointer<AuthValue>(new AuthValue(length, data)) {} 57 58AuthValue::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 67AuthValue::~AuthValue() 68{ 69 if (mOwnsValue) 70 { 71 memset(mValue.data, 0, mValue.length); 72 delete[] reinterpret_cast<uint8_t*>(mValue.data); 73 } 74} 75 76AuthValue & 77AuthValue::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 91void 92AuthValue::fillInAuthorizationValue(AuthorizationValue &value) 93{ 94 value.length = mValue.length; 95 value.data = mValue.data; 96} 97 98AuthValueVector & 99AuthValueVector::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 107void 108AuthValueVector::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 126AuthItem::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 144AuthItem::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 154AuthItem::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 171AuthItem::~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 182bool 183AuthItem::operator < (const AuthItem &other) const 184{ 185 return strcmp(mName, other.mName) < 0; 186} 187 188AuthItem & 189AuthItem::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 209void 210AuthItem::fillInAuthorizationItem(AuthorizationItem &item) 211{ 212 item.name = mName; 213 item.valueLength = mValue.length; 214 item.value = mValue.data; 215 item.flags = mFlags; 216} 217 218bool 219AuthItem::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 235bool 236AuthItem::getString(string &value) 237{ 238 value = string(static_cast<char*>(mValue.data), mValue.length); 239 return true; 240} 241 242bool 243AuthItem::getCssmData(CssmAutoData &value) 244{ 245 value = CssmData(static_cast<uint8_t*>(mValue.data), mValue.length); 246 return true; 247} 248 249 250AuthItemRef::AuthItemRef(const AuthorizationItem &item) : RefPointer<AuthItem>(new AuthItem(item)) {} 251 252AuthItemRef::AuthItemRef(AuthorizationString name) : RefPointer<AuthItem>(new AuthItem(name)) {} 253 254AuthItemRef::AuthItemRef(AuthorizationString name, AuthorizationValue value, AuthorizationFlags flags) : RefPointer<AuthItem>(new AuthItem(name, value, flags)) {} 255 256 257// 258// AuthItemSet 259// 260AuthItemSet::AuthItemSet() 261: firstItemName(NULL) 262{ 263} 264 265AuthItemSet::~AuthItemSet() 266{ 267 if (NULL != firstItemName) 268 free(firstItemName); 269} 270 271AuthItemSet & 272AuthItemSet::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 282AuthItemSet& 283AuthItemSet::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 294AuthItemSet::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 307AuthItemSet::AuthItemSet(const AuthItemSet& itemSet) 308: std::set<AuthItemRef>(itemSet) 309{ 310 duplicate(itemSet); 311} 312 313void 314AuthItemSet::duplicate(const AuthItemSet& itemSet) 315{ 316 if (itemSet.firstItemName != NULL) 317 firstItemName = strdup(itemSet.firstItemName); 318 else 319 firstItemName = NULL; 320} 321 322void 323AuthItemSet::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 343AuthorizationItemSet * 344AuthItemSet::copy() const 345{ 346 AuthorizationItemSet *aCopy; 347 size_t aLength; 348 copy(aCopy, aLength); 349 return aCopy; 350} 351 352AuthItem * 353AuthItemSet::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 363