]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_cdsa_utilities/lib/AuthorizationData.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / 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 (file)
index 0000000..26ccdea
--- /dev/null
@@ -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 <security_cdsa_utilities/AuthorizationData.h>
+#include <security_cdsa_utilities/AuthorizationWalkers.h>
+#include <security_cdsa_utilities/walkers.h>
+#include <Security/checkpw.h>
+#include <grp.h>
+#include <pwd.h>
+
+
+// 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<AuthValue>(new AuthValue(value)) {}
+
+AuthValueRef::AuthValueRef(const AuthorizationValue &value) : 
+       RefPointer<AuthValue>(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<AuthValue>(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<uint8_t*>(mValue.data);
+       }
+}
+
+AuthValue &
+AuthValue::operator = (const AuthValue &other)
+{
+    if (mOwnsValue)
+       {
+               memset(mValue.data, 0 , mValue.length);
+        delete[] reinterpret_cast<uint8_t*>(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<AuthorizationValueVector> 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<char *>(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<char *>(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<uint8_t*>(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<uint8_t*>(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<char*>(mValue.data), mValue.length);
+       return true;
+}
+
+bool
+AuthItem::getCssmData(CssmAutoData &value)
+{
+       value = CssmData(static_cast<uint8_t*>(mValue.data), mValue.length);
+       return true;
+}      
+
+
+AuthItemRef::AuthItemRef(const AuthorizationItem &item) : RefPointer<AuthItem>(new AuthItem(item)) {}
+
+AuthItemRef::AuthItemRef(AuthorizationString name) : RefPointer<AuthItem>(new AuthItem(name)) {}
+
+AuthItemRef::AuthItemRef(AuthorizationString name, AuthorizationValue value, AuthorizationFlags flags) : RefPointer<AuthItem>(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<AuthItemRef>::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<AuthItemRef>(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<AuthorizationItemSet> 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