#ifndef _CSSMACL
#define _CSSMACL
#include <Security/cssmaclpod.h>
#include <Security/cssmcred.h>
#include <Security/refcount.h>
#include <Security/globalizer.h>
#include <Security/memutils.h>
#include <map>
#include <set>
#include <string>
#include <limits.h>
#ifdef _CPP_CSSMACL
#pragma export on
#endif
namespace Security
{
class AclValidationContext;
class AclSubject : public RefCount {
typedef LowLevelMemoryUtilities::Writer Writer;
typedef LowLevelMemoryUtilities::Reader Reader;
public:
AclSubject(uint32 type) : mType(type) { }
virtual ~AclSubject();
uint32 type() const { return mType; }
virtual bool validate(const AclValidationContext &ctx) const = 0;
virtual CssmList toList(CssmAllocator &alloc) const = 0;
virtual void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
virtual void exportBlob(Writer &pub, Writer &priv);
virtual void importBlob(Reader &pub, Reader &priv);
IFDUMP(virtual void debugDump() const);
private:
CSSM_ACL_SUBJECT_TYPE mType;
public:
class Maker {
public:
Maker(CSSM_ACL_SUBJECT_TYPE type);
virtual ~Maker();
uint32 type() const { return myType; }
virtual AclSubject *make(const TypedList &list) const = 0;
virtual AclSubject *make(Reader &pub, Reader &priv) const = 0;
protected:
static void crack(const CssmList &list, uint32 count,
ListElement **array = NULL, ...);
static CSSM_WORDID_TYPE getWord(const ListElement &list,
int min = 0, int max = INT_MAX);
private:
CSSM_ACL_SUBJECT_TYPE myType;
};
};
class SimpleAclSubject : public AclSubject {
public:
SimpleAclSubject(CSSM_ACL_SUBJECT_TYPE su, CSSM_SAMPLE_TYPE sa)
: AclSubject(su), acceptingSamples(sa) { }
bool validate(const AclValidationContext &ctx) const;
virtual bool validate(const AclValidationContext &baseCtx,
const TypedList &sample) const = 0;
const CSSM_SAMPLE_TYPE acceptingSamples;
};
class AclValidationEnvironment {
public:
virtual ~AclValidationEnvironment(); };
class AclValidationContext {
public:
AclValidationContext(const AccessCredentials *cred,
AclAuthorization auth, AclValidationEnvironment *env = NULL)
: mCred(cred), mAuth(auth), mEnv(env) { }
AclValidationContext(const AclValidationContext &ctx)
: mCred(ctx.mCred), mAuth(ctx.mAuth), mEnv(ctx.mEnv) { }
virtual ~AclValidationContext();
virtual uint32 count() const = 0; virtual const TypedList &sample(uint32 n) const = 0; const TypedList &operator [] (uint32 n) const { return sample(n); }
AclAuthorization authorization() const { return mAuth; }
template <class Env>
Env *environment() const { return dynamic_cast<Env *>(mEnv); }
protected:
const AccessCredentials *mCred; AclAuthorization mAuth; AclValidationEnvironment *mEnv; };
class ObjectAcl {
friend AclSubject::Maker::Maker(CSSM_ACL_SUBJECT_TYPE);
public:
typedef RefPointer<AclSubject> AclSubjectPointer;
typedef LowLevelMemoryUtilities::Writer Writer;
typedef LowLevelMemoryUtilities::Reader Reader;
public:
ObjectAcl(CssmAllocator &alloc);
ObjectAcl(const AclEntryPrototype &proto, CssmAllocator &alloc);
virtual ~ObjectAcl();
CssmAllocator &allocator;
void validate(AclAuthorization auth, const AccessCredentials *cred,
AclValidationEnvironment *env = NULL) const;
void validateOwner(AclAuthorization authorizationHint, const AccessCredentials *cred,
AclValidationEnvironment *env = NULL) const;
void cssmGetAcl(const char *tag, uint32 &count, AclEntryInfo * &acls);
void cssmChangeAcl(const AclEdit &edit, const AccessCredentials *cred,
AclValidationEnvironment *env = NULL);
void cssmGetOwner(AclOwnerPrototype &owner);
void cssmChangeOwner(const AclOwnerPrototype &newOwner, const AccessCredentials *cred,
AclValidationEnvironment *env = NULL);
void cssmSetInitial(const AclEntryPrototype &proto);
void cssmSetInitial(const AclSubjectPointer &subject);
void exportBlob(CssmData &publicBlob, CssmData &privateBlob);
void importBlob(const void *publicBlob, const void *privateBlob);
IFDUMP(virtual void debugDump(const char *what = NULL) const);
public:
class Entry {
public:
AclSubjectPointer subject; bool delegate;
Entry() { }
void toOwnerInfo(CSSM_ACL_OWNER_PROTOTYPE &info,
CssmAllocator &alloc) const;
virtual bool authorizes(AclAuthorization auth) const = 0;
virtual bool validate(const AclValidationContext &ctx) const = 0;
template <class Action>
void exportBlob(Action &pub, Action &priv)
{
pub(delegate);
CSSM_ACL_SUBJECT_TYPE type = subject->type(); pub(type);
subject->exportBlob(pub, priv);
}
void importBlob(Reader &pub, Reader &priv);
IFDUMP(virtual void debugDump() const);
private:
void init(const AclSubjectPointer &subject, bool delegate = false);
void init(const TypedList &subject, bool delegate = false) { init(make(subject), delegate); }
protected:
Entry(const AclEntryPrototype &proto) { init(proto.subject(), proto.delegate()); }
Entry(const AclOwnerPrototype &proto) { init(proto.subject()); }
Entry(const AclSubjectPointer &subject) { init(subject); }
virtual ~Entry();
};
class OwnerEntry : public Entry {
public:
OwnerEntry() { } template <class Input>
OwnerEntry(const Input &owner) : Entry(owner) { }
OwnerEntry(const AclSubjectPointer &subject) : Entry(subject) { }
bool authorizes(AclAuthorization auth) const;
bool validate(const AclValidationContext &ctx) const;
};
class AclEntry : public Entry {
public:
string tag; AclAuthorizationSet authorizations; bool authorizesAnything; uint32 handle;
AclEntry() { } AclEntry(const AclSubjectPointer &subject);
AclEntry(const AclEntryPrototype &proto);
void toEntryInfo(CSSM_ACL_ENTRY_PROTOTYPE &info,
CssmAllocator &alloc) const;
bool authorizes(AclAuthorization auth) const;
bool validate(const AclValidationContext &ctx) const;
template <class Action>
void exportBlob(Action &pub, Action &priv)
{
Entry::exportBlob(pub, priv);
const char *s = tag.c_str(); pub(s);
pub(authorizesAnything);
if (!authorizesAnything) {
uint32 count = authorizations.size(); pub(count);
for (AclAuthorizationSet::iterator it = authorizations.begin();
it != authorizations.end(); it++) {
AclAuthorization auth = *it; pub(auth);
}
}
}
void importBlob(Reader &pub, Reader &priv);
IFDUMP(void debugDump() const);
};
typedef multimap<string, AclEntry> EntryMap;
typedef EntryMap::iterator Iterator;
typedef EntryMap::const_iterator ConstIterator;
Iterator begin() { return entries.begin(); }
Iterator end() { return entries.end(); }
ConstIterator begin() const { return entries.begin(); }
ConstIterator end() const { return entries.end(); }
unsigned int getRange(const char *tag, pair<ConstIterator, ConstIterator> &range) const;
Iterator findEntryHandle(CSSM_ACL_HANDLE handle);
static AclSubject *make(const TypedList &list); static AclSubject *make(CSSM_ACL_SUBJECT_TYPE type,
Reader &pub, Reader &priv);
private:
EntryMap entries; OwnerEntry owner; uint32 nextHandle;
private:
typedef map<CSSM_ACL_SUBJECT_TYPE, AclSubject::Maker *> MakerMap;
static ModuleNexus<MakerMap> makers;
static AclSubject::Maker &makerFor(CSSM_ACL_SUBJECT_TYPE type);
};
class ResourceControlContext : public PodWrapper<ResourceControlContext, CSSM_RESOURCE_CONTROL_CONTEXT> {
public:
ResourceControlContext() { }
ResourceControlContext(const AclEntryInput &initial, AccessCredentials *cred = NULL)
{ InitialAclEntry = initial; AccessCred = cred; }
operator AclEntryInput &() { return AclEntryInput::overlay(InitialAclEntry); }
AccessCredentials *credentials() { return AccessCredentials::overlay(AccessCred); }
};
}
#ifdef _CPP_CSSMACL
#pragma export off
#endif
#endif //_CSSMACL