#include <Security/SecACL.h>
#include <Security/ACL.h>
#include <Security/Access.h>
#include "SecBridge.h"
static void setApplications(ACL *acl, CFArrayRef applicationList);
CFTypeID
SecACLGetTypeID(void)
{
BEGIN_SECAPI
return gTypes().ACL.typeID;
END_SECAPI1(_kCFRuntimeNotATypeID)
}
OSStatus SecACLCreateFromSimpleContents(SecAccessRef accessRef,
CFArrayRef applicationList,
CFStringRef description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR *promptSelector,
SecACLRef *newAcl)
{
BEGIN_SECAPI
SecPointer<Access> access = Access::required(accessRef);
SecPointer<ACL> acl = new ACL(*access, cfString(description), *promptSelector);
if (applicationList) {
acl->form(ACL::appListForm);
setApplications(acl, applicationList);
} else {
acl->form(ACL::allowAllForm);
}
access->add(acl.get());
Required(newAcl) = acl->handle();
END_SECAPI
}
OSStatus SecACLRemove(SecACLRef aclRef)
{
BEGIN_SECAPI
ACL::required(aclRef)->remove();
END_SECAPI
}
static SecTrustedApplicationRef
convert(const SecPointer<TrustedApplication> &trustedApplication)
{
return *trustedApplication;
}
OSStatus SecACLCopySimpleContents(SecACLRef aclRef,
CFArrayRef *applicationList,
CFStringRef *promptDescription, CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR *promptSelector)
{
BEGIN_SECAPI
SecPointer<ACL> acl = ACL::required(aclRef);
switch (acl->form()) {
case ACL::allowAllForm:
Required(applicationList) = NULL;
Required(promptDescription) =
acl->promptDescription().empty() ? NULL
: makeCFString(acl->promptDescription());
Required(promptSelector) = acl->promptSelector();
break;
case ACL::appListForm:
Required(applicationList) =
makeCFArray(convert, acl->applications());
Required(promptDescription) = makeCFString(acl->promptDescription());
Required(promptSelector) = acl->promptSelector();
break;
default:
return errSecACLNotSimple; }
END_SECAPI
}
OSStatus SecACLSetSimpleContents(SecACLRef aclRef,
CFArrayRef applicationList,
CFStringRef description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR *promptSelector)
{
BEGIN_SECAPI
SecPointer<ACL> acl = ACL::required(aclRef);
acl->promptDescription() = description ? cfString(description) : "";
acl->promptSelector() = promptSelector ? *promptSelector : ACL::defaultSelector;
if (applicationList) {
acl->form(ACL::appListForm);
setApplications(acl, applicationList);
} else {
acl->form(ACL::allowAllForm);
}
acl->modify();
END_SECAPI
}
static void setApplications(ACL *acl, CFArrayRef applicationList)
{
ACL::ApplicationList &appList = acl->applications();
appList.clear();
CFIndex count = CFArrayGetCount(applicationList);
for (CFIndex n = 0; n < count; n++)
appList.push_back(TrustedApplication::required(
SecTrustedApplicationRef(CFArrayGetValueAtIndex(applicationList, n))));
}
OSStatus SecACLGetAuthorizations(SecACLRef acl,
CSSM_ACL_AUTHORIZATION_TAG *tags, uint32 *tagCount)
{
BEGIN_SECAPI
AclAuthorizationSet auths = ACL::required(acl)->authorizations();
if (Required(tagCount) < auths.size()) { *tagCount = auths.size(); CssmError::throwMe(paramErr);
}
*tagCount = auths.size();
copy(auths.begin(), auths.end(), tags);
END_SECAPI
}
OSStatus SecACLSetAuthorizations(SecACLRef aclRef,
CSSM_ACL_AUTHORIZATION_TAG *tags, uint32 tagCount)
{
BEGIN_SECAPI
SecPointer<ACL> acl = ACL::required(aclRef);
if (acl->isOwner()) MacOSError::throwMe(errSecInvalidOwnerEdit);
AclAuthorizationSet &auths = acl->authorizations();
auths.clear();
copy(tags, tags + tagCount, insert_iterator<AclAuthorizationSet>(auths, auths.begin()));
acl->modify();
END_SECAPI
}