#include <security_cdsa_utilities/cssmaclpod.h>
#include <security_cdsa_utilities/cssmwalkers.h>
#include <cstdarg>
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);
}
AuthorizationGroup::AuthorizationGroup(const AclAuthorizationSet &auths, Allocator &alloc)
{
NumberOfAuthTags = auths.size();
AuthTags = alloc.alloc<CSSM_ACL_AUTHORIZATION_TAG>(NumberOfAuthTags);
copy(auths.begin(), auths.end(), AuthTags); }
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();
}
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 = new 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); return mEntries[ix];
}
AutoAclEntryInfoList::~AutoAclEntryInfoList()
{
if (mAllocator)
{
DataWalkers::ChunkFreeWalker w(*mAllocator);
for (uint32 ix = 0; ix < mCount; ix++)
walk(w, mEntries[ix]);
mAllocator->free(mEntries);
}
}
void AutoAclEntryInfoList::allocator(Allocator &allocator)
{
mAllocator = &allocator;
}
void AutoAclEntryInfoList::add(const TypedList &subj, const AclAuthorizationSet &auths, const char *tag )
{
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[10];
snprintf(tag, sizeof(tag), "PIN%ld", slot);
add(subj, CSSM_ACL_AUTHORIZATION_PREAUTH(slot), tag);
}