X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_cdsa_utilities/lib/AuthorizationData.cpp diff --git a/Security/libsecurity_cdsa_utilities/lib/AuthorizationData.cpp b/Security/libsecurity_cdsa_utilities/lib/AuthorizationData.cpp new file mode 100644 index 00000000..26ccdea1 --- /dev/null +++ b/Security/libsecurity_cdsa_utilities/lib/AuthorizationData.cpp @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2000-2006,2011-2012,2014 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include + + +// checkpw() that uses provided struct passwd +extern "C" +{ +int checkpw_internal( const struct passwd *pw, const char* password ); +} + + +namespace Authorization { + + +AuthValueRef::AuthValueRef(const AuthValue &value) : + RefPointer(new AuthValue(value)) {} + +AuthValueRef::AuthValueRef(const AuthorizationValue &value) : + RefPointer(new AuthValue(value)) {} + +AuthValue::AuthValue(const AuthorizationValue &value) : + mOwnsValue(false) +{ + mValue.length = value.length; + mValue.data = value.data; +} + +AuthValueRef::AuthValueRef(UInt32 length, void *data) : + RefPointer(new AuthValue(length, data)) {} + +AuthValue::AuthValue(UInt32 length, void *data) : + mOwnsValue(true) +{ + mValue.length = length; + mValue.data = new uint8_t[length]; + if (length) + memcpy(mValue.data, data, length); +} + +AuthValue::~AuthValue() +{ + if (mOwnsValue) + { + memset(mValue.data, 0, mValue.length); + delete[] reinterpret_cast(mValue.data); + } +} + +AuthValue & +AuthValue::operator = (const AuthValue &other) +{ + if (mOwnsValue) + { + memset(mValue.data, 0 , mValue.length); + delete[] reinterpret_cast(mValue.data); + } + + mValue = other.mValue; + mOwnsValue = other.mOwnsValue; + other.mOwnsValue = false; + return *this; +} + +void +AuthValue::fillInAuthorizationValue(AuthorizationValue &value) +{ + value.length = mValue.length; + value.data = mValue.data; +} + +AuthValueVector & +AuthValueVector::operator = (const AuthorizationValueVector& valueVector) +{ + clear(); + for (unsigned int i=0; i < valueVector.count; i++) + push_back(AuthValueRef(valueVector.values[i])); + return *this; +} + +void +AuthValueVector::copy(AuthorizationValueVector **data, size_t *length) const +{ + AuthorizationValueVector valueVector; + valueVector.count = (UInt32)size(); + valueVector.values = new AuthorizationValue[valueVector.count]; + int i = 0; + for (const_iterator it = begin(); it != end(); ++it, ++i) + { + (*it)->fillInAuthorizationValue(valueVector.values[i]); + } + + DataWalkers::Copier flatValueVector(&valueVector); + *length = flatValueVector.length(); + *data = flatValueVector.keep(); + + delete[] valueVector.values; +} + +AuthItem::AuthItem(const AuthorizationItem &item) : + mFlags(item.flags), + mOwnsName(true), + mOwnsValue(true) +{ + if (!item.name) + MacOSError::throwMe(errAuthorizationInternal); + size_t nameLen = strlen(item.name) + 1; + mName = new char[nameLen]; + memcpy(const_cast(mName), item.name, nameLen); + + mValue.length = item.valueLength; + mValue.data = new uint8_t[item.valueLength]; + if (mValue.length) + memcpy(mValue.data, item.value, item.valueLength); +} + + +AuthItem::AuthItem(AuthorizationString name) : + mName(name), + mFlags(0), + mOwnsName(false), + mOwnsValue(false) +{ + mValue.length = 0; + mValue.data = NULL; +} + +AuthItem::AuthItem(AuthorizationString name, AuthorizationValue value, AuthorizationFlags flags) : + mFlags(flags), + mOwnsName(true), + mOwnsValue(true) +{ + if (!name) + MacOSError::throwMe(errAuthorizationInternal); + size_t nameLen = strlen(name) + 1; + mName = new char[nameLen]; + memcpy(const_cast(mName), name, nameLen); + + mValue.length = value.length; + mValue.data = new uint8_t[value.length]; + if (mValue.length) + memcpy(mValue.data, value.data, value.length); +} + +AuthItem::~AuthItem() +{ + if (mOwnsName) + delete[] mName; + if (mOwnsValue) + { + memset(mValue.data, 0, mValue.length); + delete[] reinterpret_cast(mValue.data); + } +} + +bool +AuthItem::operator < (const AuthItem &other) const +{ + return strcmp(mName, other.mName) < 0; +} + +AuthItem & +AuthItem::operator = (const AuthItem &other) +{ + if (mOwnsName) + delete[] mName; + if (mOwnsValue) + { + memset(mValue.data, 0, mValue.length); + delete[] reinterpret_cast(mValue.data); + } + + mName = other.mName; + mValue = other.mValue; + mFlags = other.mFlags; + mOwnsName = other.mOwnsName; + other.mOwnsName = false; + mOwnsValue = other.mOwnsValue; + other.mOwnsValue = false; + return *this; +} + +void +AuthItem::fillInAuthorizationItem(AuthorizationItem &item) +{ + item.name = mName; + item.valueLength = mValue.length; + item.value = mValue.data; + item.flags = mFlags; +} + +bool +AuthItem::getBool(bool &value) +{ + if (mValue.length == sizeof(bool)) + { + bool *tmpValue = (bool *)mValue.data; + + if (tmpValue) + { + value = *tmpValue; + return true; + } + } + + return false; +} + +bool +AuthItem::getString(string &value) +{ + value = string(static_cast(mValue.data), mValue.length); + return true; +} + +bool +AuthItem::getCssmData(CssmAutoData &value) +{ + value = CssmData(static_cast(mValue.data), mValue.length); + return true; +} + + +AuthItemRef::AuthItemRef(const AuthorizationItem &item) : RefPointer(new AuthItem(item)) {} + +AuthItemRef::AuthItemRef(AuthorizationString name) : RefPointer(new AuthItem(name)) {} + +AuthItemRef::AuthItemRef(AuthorizationString name, AuthorizationValue value, AuthorizationFlags flags) : RefPointer(new AuthItem(name, value, flags)) {} + + +// +// AuthItemSet +// +AuthItemSet::AuthItemSet() +: firstItemName(NULL) +{ +} + +AuthItemSet::~AuthItemSet() +{ + if (NULL != firstItemName) + free(firstItemName); +} + +AuthItemSet & +AuthItemSet::operator = (const AuthorizationItemSet& itemSet) +{ + clear(); + + for (unsigned int i=0; i < itemSet.count; i++) + insert(AuthItemRef(itemSet.items[i])); + + return *this; +} + +AuthItemSet& +AuthItemSet::operator=(const AuthItemSet& itemSet) +{ + std::set::operator=(itemSet); + + if (this != &itemSet) { + duplicate(itemSet); + } + + return *this; +} + +AuthItemSet::AuthItemSet(const AuthorizationItemSet *itemSet) +: firstItemName(NULL) +{ + if (NULL != itemSet && NULL != itemSet->items) + { + if (0 < itemSet->count && NULL != itemSet->items[0].name) + firstItemName = strdup(itemSet->items[0].name); + + for (unsigned int i=0; i < itemSet->count; i++) + insert(AuthItemRef(itemSet->items[i])); + } +} + +AuthItemSet::AuthItemSet(const AuthItemSet& itemSet) +: std::set(itemSet) +{ + duplicate(itemSet); +} + +void +AuthItemSet::duplicate(const AuthItemSet& itemSet) +{ + if (itemSet.firstItemName != NULL) + firstItemName = strdup(itemSet.firstItemName); + else + firstItemName = NULL; +} + +void +AuthItemSet::copy(AuthorizationItemSet *&data, size_t &length, Allocator &alloc) const +{ + AuthorizationItemSet itemSet; + itemSet.count = (UInt32)size(); + itemSet.items = new AuthorizationItem[itemSet.count]; + int i = 0; + for (const_iterator it = begin(); it != end(); ++it, ++i) + { + (*it)->fillInAuthorizationItem(itemSet.items[i]); + } + + DataWalkers::Copier flatItemSet(&itemSet, alloc); + length = flatItemSet.length(); + + data = flatItemSet.keep(); + // else flatItemSet disappears again + + delete[] itemSet.items; +} + +AuthorizationItemSet * +AuthItemSet::copy() const +{ + AuthorizationItemSet *aCopy; + size_t aLength; + copy(aCopy, aLength); + return aCopy; +} + +AuthItem * +AuthItemSet::find(const char *name) +{ + AuthItemSet::const_iterator found = find_if(this->begin(), this->end(), FindAuthItemByRightName(name) ); + if (found != this->end()) + return *found; + + return NULL; +} + +} // end namespace Authorization