#ifndef _CSSMCRED
#define _CSSMCRED
#include <security_utilities/utilities.h>
#include <security_cdsa_utilities/cssmlist.h>
#include <security_cdsa_utilities/cssmalloc.h>
#include <list>
namespace Security {
class CssmSample : public PodWrapper<CssmSample, CSSM_SAMPLE> {
public:
CssmSample(const TypedList &list)
{ TypedSample = list; Verifier = NULL; }
CssmSample(const TypedList &list, const CssmSubserviceUid &ver)
{ TypedSample = list; Verifier = &ver; }
TypedList &value() { return TypedList::overlay(TypedSample); }
const TypedList &value() const { return TypedList::overlay(TypedSample); }
operator TypedList & () { return value(); }
const CssmSubserviceUid *verifier() const { return CssmSubserviceUid::overlay(Verifier); }
CssmSubserviceUid * &verifier()
{ return const_cast<CssmSubserviceUid * &>(CssmSubserviceUid::overlayVar(Verifier)); }
};
class SampleGroup : public PodWrapper<SampleGroup, CSSM_SAMPLEGROUP> {
public:
SampleGroup() { clearPod(); }
SampleGroup(CssmSample &single) { NumberOfSamples = 1; Samples = &single; }
uint32 size() const { return NumberOfSamples; }
uint32 length() const { return size(); } CssmSample *&samples() { return CssmSample::overlayVar(const_cast<CSSM_SAMPLE *&>(Samples)); }
CssmSample *samples() const { return CssmSample::overlay(const_cast<CSSM_SAMPLE *>(Samples)); }
CssmSample &operator [] (uint32 ix) const
{ assert(ix < size()); return samples()[ix]; }
public:
bool collect(CSSM_SAMPLE_TYPE sampleType, list<CssmSample> &samples) const;
};
class AccessCredentials : public PodWrapper<AccessCredentials, CSSM_ACCESS_CREDENTIALS> {
public:
AccessCredentials() { clearPod(); }
explicit AccessCredentials(const SampleGroup &samples, const char *tag = NULL)
{ this->samples() = samples; this->tag(tag); }
explicit AccessCredentials(const SampleGroup &samples, const std::string &tag)
{ this->samples() = samples; this->tag(tag); }
const char *tag() const { return EntryTag[0] ? EntryTag : NULL; }
std::string s_tag() const { return EntryTag; }
void tag(const char *tagString);
void tag(const std::string &tagString) { return tag(tagString.c_str()); }
SampleGroup &samples() { return SampleGroup::overlay(Samples); }
const SampleGroup &samples() const { return SampleGroup::overlay(Samples); }
uint32 size() const { return samples().size(); }
CssmSample &operator [] (uint32 ix) const { return samples()[ix]; }
public:
static const AccessCredentials &null;
static const AccessCredentials *needed(const CSSM_ACCESS_CREDENTIALS *cred)
{ return cred ? overlay(cred) : &null; }
};
class AutoCredentials : public AccessCredentials {
public:
AutoCredentials(Allocator &alloc);
AutoCredentials(Allocator &alloc, uint32 nSamples);
Allocator &allocator;
CssmSample &sample(uint32 n) { return getSample(n); }
CssmSample &append(const CssmSample &sample)
{ return getSample(samples().length()) = sample; }
TypedList &append(const TypedList &exhibit)
{ return (getSample(samples().length()) = exhibit).value(); }
CssmSample &operator += (const CssmSample &sample) { return append(sample); }
TypedList &operator += (const TypedList &exhibit) { return append(exhibit); }
private:
void init();
CssmSample &getSample(uint32 n);
CssmSample *sampleArray;
uint32 nSamples;
};
namespace DataWalkers
{
template <class Action>
void walk(Action &operate, CssmSample &sample)
{
operate(sample);
walk(operate, sample.value());
if (sample.verifier())
walk(operate, sample.verifier());
}
template <class Action>
void walk(Action &operate, SampleGroup &samples)
{
operate(samples);
enumerateArray(operate, samples, &SampleGroup::samples);
}
template <class Action>
AccessCredentials *walk(Action &operate, AccessCredentials * &cred)
{
operate(cred);
walk(operate, cred->samples());
return cred;
}
template <class Action>
CSSM_ACCESS_CREDENTIALS *walk(Action &operate, CSSM_ACCESS_CREDENTIALS * &cred)
{ return walk(operate, AccessCredentials::overlayVar(cred)); }
template <class Action>
AutoCredentials *walk(Action &operate, AutoCredentials * &cred)
{ return (AutoCredentials *)walk(operate, (AccessCredentials * &)cred); }
} }
#endif //_CSSMCRED