]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_cdsa_utilities/lib/cssmaclpod.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / Security / libsecurity_cdsa_utilities / lib / cssmaclpod.cpp
diff --git a/Security/libsecurity_cdsa_utilities/lib/cssmaclpod.cpp b/Security/libsecurity_cdsa_utilities/lib/cssmaclpod.cpp
new file mode 100644 (file)
index 0000000..96a32b5
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2000-2004,2006-2007,2011-2012 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@
+ */
+
+
+//
+// cssmaclpod - enhanced PodWrappers for ACL-related CSSM data structures
+//
+#include <security_cdsa_utilities/cssmaclpod.h>
+#include <security_cdsa_utilities/cssmwalkers.h>
+#include <cstdarg>
+
+
+namespace Security {
+
+
+//
+// AclAuthorizationSets
+//
+AclAuthorizationSet::AclAuthorizationSet(AclAuthorization auth0, AclAuthorization auth, ...)
+{
+       insert(auth0);
+
+       va_list args;
+       va_start(args, auth);
+       while (auth) {
+               insert(auth);
+               auth = va_arg(args, AclAuthorization);
+       }
+       va_end(args);
+}
+
+
+//
+// AclAuthorizationGroups
+//
+AuthorizationGroup::AuthorizationGroup(const AclAuthorizationSet &auths, Allocator &alloc)
+{
+       NumberOfAuthTags = (uint32)auths.size();
+       AuthTags = alloc.alloc<CSSM_ACL_AUTHORIZATION_TAG>(NumberOfAuthTags);
+       copy(auths.begin(), auths.end(), AuthTags);     // happens to be sorted
+}
+
+AuthorizationGroup::AuthorizationGroup(CSSM_ACL_AUTHORIZATION_TAG tag, Allocator &alloc)
+{
+       AuthTags = alloc.alloc<CSSM_ACL_AUTHORIZATION_TAG>(1);
+       AuthTags[0] = tag;
+       NumberOfAuthTags = 1;
+}
+
+void AuthorizationGroup::destroy(Allocator &alloc)
+{
+       alloc.free(AuthTags);
+}
+
+bool AuthorizationGroup::contains(CSSM_ACL_AUTHORIZATION_TAG tag) const
+{
+       return find(AuthTags, &AuthTags[NumberOfAuthTags], tag) != &AuthTags[NumberOfAuthTags];
+}
+
+
+AuthorizationGroup::operator AclAuthorizationSet() const
+{
+       return AclAuthorizationSet(AuthTags, &AuthTags[NumberOfAuthTags]);
+}
+
+AclEntryPrototype::AclEntryPrototype(const AclOwnerPrototype &proto)
+{
+       memset(this, 0, sizeof(*this));
+       TypedSubject = proto.subject(); Delegate = proto.delegate();
+       //@@@ set authorization to "is owner" pseudo-auth? See cssmacl.h
+}
+
+void AclEntryPrototype::tag(const char *tagString)
+{
+       if (tagString == NULL)
+               EntryTag[0] = '\0';
+       else if (strlen(tagString) > CSSM_MODULE_STRING_SIZE)
+               CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG);
+       else
+               strcpy(EntryTag, tagString);
+}
+
+void AclEntryPrototype::tag(const string &tagString)
+{
+       if (tagString.length() > CSSM_MODULE_STRING_SIZE)
+               CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG);
+       else
+               memcpy(EntryTag, tagString.c_str(), tagString.length() + 1);
+}
+
+
+AclOwnerPrototype *AutoAclOwnerPrototype::make()
+{
+       if (!mAclOwnerPrototype) {
+               mAclOwnerPrototype = (AclOwnerPrototype*) mAllocator->malloc(sizeof(AclOwnerPrototype));
+        new (mAclOwnerPrototype) AclOwnerPrototype;
+               mAclOwnerPrototype->clearPod();
+       }
+       return mAclOwnerPrototype;
+}
+
+AutoAclOwnerPrototype::~AutoAclOwnerPrototype()
+{
+       if (mAllocator)
+               DataWalkers::chunkFree(mAclOwnerPrototype, *mAllocator);
+}
+
+void
+AutoAclOwnerPrototype::allocator(Allocator &allocator)
+{
+       mAllocator = &allocator;
+}
+
+
+void AutoAclEntryInfoList::size(uint32 newSize)
+{
+       assert(mAllocator);
+       mEntries = mAllocator->alloc<AclEntryInfo>(mEntries, newSize);
+       for (uint32 n = mCount; n < newSize; n++)
+               mEntries[n].clearPod();
+       mCount = newSize;
+}
+
+
+AclEntryInfo &AutoAclEntryInfoList::at(uint32 ix)
+{
+       if (ix >= mCount)
+               size(ix + 1);   // expand vector
+       return mEntries[ix];
+}
+
+
+void AutoAclEntryInfoList::clear()
+{
+       if (mAllocator)
+       {
+               DataWalkers::ChunkFreeWalker w(*mAllocator);
+               for (uint32 ix = 0; ix < mCount; ix++)
+                       walk(w, mEntries[ix]);
+               mAllocator->free(mEntries);
+               mEntries = NULL;
+               mCount = 0;
+       }
+}
+
+void AutoAclEntryInfoList::allocator(Allocator &allocator)
+{
+       mAllocator = &allocator;
+}
+
+
+void AutoAclEntryInfoList::add(const TypedList &subj, const AclAuthorizationSet &auths, const char *tag /* = NULL */)
+{
+       AclEntryInfo &info = at(size());
+       info.proto() = AclEntryPrototype(subj);
+       info.proto().authorization() = AuthorizationGroup(auths, allocator());
+       info.proto().tag(tag);
+       info.handle(size());
+}
+
+void AutoAclEntryInfoList::addPin(const TypedList &subj, uint32 slot)
+{
+       char tag[20];
+       snprintf(tag, sizeof(tag), "PIN%d", slot);
+       add(subj, CSSM_ACL_AUTHORIZATION_PREAUTH(slot), tag);
+}
+
+void AutoAclEntryInfoList::addPinState(uint32 slot, uint32 status)
+{
+       char tag[20];
+       snprintf(tag, sizeof(tag), "PIN%d?", slot);
+       TypedList subj(allocator(), CSSM_WORDID_PIN,
+               new(allocator()) ListElement(slot),
+               new(allocator()) ListElement(status));
+       add(subj, CSSM_WORDID_PIN, tag);
+}
+
+void AutoAclEntryInfoList::addPinState(uint32 slot, uint32 status, uint32 count)
+{
+       char tag[20];
+       snprintf(tag, sizeof(tag), "PIN%d?", slot);
+       TypedList subj(allocator(), CSSM_WORDID_PIN,
+               new(allocator()) ListElement(slot),
+               new(allocator()) ListElement(status),
+               new(allocator()) ListElement(count));
+       add(subj, CSSM_WORDID_PIN, tag);
+}
+
+uint32 pinFromAclTag(const char *tag, const char *suffix /* = NULL */)
+{
+       if (tag) {
+               char format[20];
+               snprintf(format, sizeof(format), "PIN%%d%s%%n", suffix ? suffix : "");
+               uint32 pin;
+               unsigned consumed;
+               sscanf(tag, format, &pin, &consumed);
+               if (consumed == strlen(tag))    // complete and sufficient
+                       return pin;
+       }
+       return 0;
+}
+
+}      // namespace Security