#include <Security/aclclient.h>
#include <Security/keychainacl.h>
#include <Security/cssmwalkers.h>
#include <Security/cssmdata.h>
#include <Security/cssmclient.h>
namespace Security {
namespace CssmClient {
static inline void check(CSSM_RETURN rc)
{
ObjectImpl::check(rc);
}
AclBearer::~AclBearer()
{ }
void AclBearer::addAcl(const AclEntryInput &input, const CSSM_ACCESS_CREDENTIALS *cred)
{
changeAcl(AclEdit(input), cred);
}
void AclBearer::changeAcl(CSSM_ACL_HANDLE handle, const AclEntryInput &input,
const CSSM_ACCESS_CREDENTIALS *cred)
{
changeAcl(AclEdit(handle, input), cred);
}
void AclBearer::deleteAcl(CSSM_ACL_HANDLE handle, const CSSM_ACCESS_CREDENTIALS *cred)
{
changeAcl(AclEdit(handle), cred);
}
void AclBearer::deleteAcl(const char *tag, const CSSM_ACCESS_CREDENTIALS *cred)
{
AutoAclEntryInfoList entries;
getAcl(entries, tag);
for (uint32 n = 0; n < entries.count(); n++)
deleteAcl(entries[n].handle(), cred);
}
void KeyAclBearer::getAcl(AutoAclEntryInfoList &aclInfos, const char *selectionTag) const
{
aclInfos.allocator(allocator);
check(CSSM_GetKeyAcl(csp, &key, reinterpret_cast<const CSSM_STRING *>(selectionTag), aclInfos, aclInfos));
}
void KeyAclBearer::changeAcl(const CSSM_ACL_EDIT &aclEdit, const CSSM_ACCESS_CREDENTIALS *cred)
{
check(CSSM_ChangeKeyAcl(csp, AccessCredentials::needed(cred), &aclEdit, &key));
}
void KeyAclBearer::getOwner(AutoAclOwnerPrototype &owner) const
{
owner.allocator(allocator);
check(CSSM_GetKeyOwner(csp, &key, owner));
}
void KeyAclBearer::changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner,
const CSSM_ACCESS_CREDENTIALS *cred)
{
check(CSSM_ChangeKeyOwner(csp, AccessCredentials::needed(cred), &key, &newOwner));
}
struct Statics {
Statics();
CssmAllocator &alloc;
AutoCredentials nullCred;
AutoCredentials promptCred;
AutoCredentials unlockCred;
};
namespace {
ModuleNexus<Statics> statics;
}
Statics::Statics()
: alloc(CssmAllocator::standard()),
nullCred(alloc, 1),
promptCred(alloc, 2),
unlockCred(alloc, 1)
{
nullCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_THRESHOLD);
promptCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT);
promptCred.sample(1) = TypedList(alloc, CSSM_SAMPLE_TYPE_THRESHOLD,
new(alloc) ListElement(TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT)));
unlockCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
new(alloc) ListElement(CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT));
}
AclFactory::AclFactory()
{ }
AclFactory::~AclFactory()
{ }
const AccessCredentials *AclFactory::nullCred() const
{ return &statics().nullCred; }
const AccessCredentials *AclFactory::promptCred() const
{ return &statics().promptCred; }
const AccessCredentials *AclFactory::unlockCred() const
{ return &statics().unlockCred; }
AclFactory::KeychainCredentials::~KeychainCredentials ()
{
DataWalkers::chunkFree (mCredentials, allocator);
}
AclFactory::PassphraseUnlockCredentials::PassphraseUnlockCredentials (const CssmData& password,
CssmAllocator& allocator) : KeychainCredentials(allocator)
{
mCredentials->sample(0) = TypedList(allocator, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
new (allocator) ListElement (CSSM_SAMPLE_TYPE_PASSWORD),
new (allocator) ListElement (CssmAutoData(allocator, password).release()));
}
AclFactory::PasswordChangeCredentials::PasswordChangeCredentials (const CssmData& password,
CssmAllocator& allocator) : KeychainCredentials(allocator)
{
mCredentials->sample(0) = TypedList(allocator, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK,
new (allocator) ListElement (CSSM_SAMPLE_TYPE_PASSWORD),
new (allocator) ListElement (CssmAutoData(allocator, password).release()));
}
AclFactory::AnyResourceContext::AnyResourceContext(const CSSM_ACCESS_CREDENTIALS *cred)
: mAny(CSSM_ACL_SUBJECT_TYPE_ANY), mTag(CSSM_ACL_AUTHORIZATION_ANY)
{
input().proto().subject() += &mAny;
AuthorizationGroup &authGroup = input().proto().authorization();
authGroup.NumberOfAuthTags = 1;
authGroup.AuthTags = &mTag;
credentials(cred);
}
} }