AuthorizationEngine.h [plain text]
#if !defined(__AuthorizationEngine__)
#define __AuthorizationEngine__ 1
#include <Security/Authorization.h>
#include <Security/refcount.h>
#include <Security/osxsigning.h>
#include "agentquery.h"
#include <CoreFoundation/CFDate.h>
#include <CoreFoundation/CFDictionary.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <map>
#include <set>
#include <string>
class AuthorizationToken;
namespace Authorization
{
class Error : public CssmCommonError {
protected:
Error(int err);
public:
const int error;
virtual CSSM_RETURN cssmError() const;
virtual OSStatus osStatus() const;
virtual const char *what () const;
static void throwMe(int err = -1) __attribute((noreturn));
};
class CredentialImpl : public RefCount
{
public:
CredentialImpl(const string &username, const uid_t uid, gid_t gid, bool shared);
CredentialImpl(const string &username, const string &password, bool shared);
~CredentialImpl();
bool operator < (const CredentialImpl &other) const;
bool isShared() const;
void merge(const CredentialImpl &other);
CFAbsoluteTime creationTime() const;
bool isValid() const;
void invalidate();
inline const string& username() const { return mUsername; }
inline const uid_t uid() const { return mUid; }
inline const gid_t gid() const { return mGid; }
private:
string mUsername;
bool mShared;
uid_t mUid;
gid_t mGid;
CFAbsoluteTime mCreationTime;
bool mValid;
};
class Credential : public RefPointer<CredentialImpl>
{
public:
Credential();
Credential(CredentialImpl *impl);
Credential(const string &username, const uid_t uid, gid_t gid, bool shared);
Credential(const string &username, const string &password, bool shared);
~Credential();
bool operator < (const Credential &other) const;
};
class MutableRightSet;
class RightSet;
class Right : protected AuthorizationItem
{
friend MutableRightSet;
friend RightSet;
public:
static Right &overlay(AuthorizationItem &item);
static Right *overlay(AuthorizationItem *item);
Right();
Right(AuthorizationString name, size_t valueLength, const void *value);
~Right();
bool operator < (const Right &other) const;
AuthorizationString rightName() const { return name; }
size_t argumentLength() const { return valueLength; }
const void *argument() const { return value; }
};
class RightSet
{
friend class MutableRightSet;
public:
typedef Right value_type;
typedef const Right &const_reference;
typedef const Right *const_pointer;
typedef const_pointer const_iterator;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
RightSet(const AuthorizationRights *rights = NULL);
RightSet(const RightSet &other);
~RightSet();
size_type size() const { return mRights->count; }
size_type max_size() const { return INT_MAX; }
const_iterator begin() const { return static_cast<const_pointer>(mRights->items); }
const_iterator end() const { return static_cast<const_pointer>(&mRights->items[mRights->count]); }
bool empty() const { return size() == 0; }
const_reference back() const;
operator const AuthorizationRights *() const { return mRights; }
private:
RightSet &operator = (const RightSet &other);
protected:
static const AuthorizationRights gEmptyRights;
AuthorizationRights *mRights;
};
class MutableRightSet : public RightSet
{
public:
typedef Right &reference;
typedef Right *pointer;
typedef pointer iterator;
MutableRightSet(size_t count = 0, const Right &element = Right());
MutableRightSet(const RightSet &other);
~MutableRightSet();
MutableRightSet &operator = (const RightSet &other);
iterator begin() { return static_cast<pointer>(mRights->items); }
iterator end() { return static_cast<pointer>(&mRights->items[mRights->count]); }
void swap(MutableRightSet &other);
reference back();
void push_back(const_reference right);
void pop_back();
size_type capacity() const { return mCapacity; }
private:
void grow(size_type min_capacity);
size_type mCapacity;
};
typedef set<Credential> CredentialSet;
class Rule
{
public:
Rule();
Rule(CFTypeRef cfRule);
Rule(const Rule &other);
Rule &operator = (const Rule &other);
~Rule();
OSStatus evaluate(const Right &inRight, const AuthorizationEnvironment *environment,
AuthorizationFlags flags, CFAbsoluteTime now,
const CredentialSet *inCredentials, CredentialSet &credentials,
const AuthorizationToken &auth);
private:
OSStatus evaluate(const Right &inRight, const AuthorizationEnvironment *environment,
CFAbsoluteTime now, const Credential &credential, bool ignoreShared);
OSStatus obtainCredential(QueryAuthorizeByGroup &client, const Right &inRight,
const AuthorizationEnvironment *environment, const char *usernameHint,
Credential &outCredential, SecurityAgent::Reason reason);
enum Type
{
kDeny,
kAllow,
kUserInGroup
} mType;
string mGroupName;
CFTimeInterval mMaxCredentialAge;
bool mShared;
bool mAllowRoot;
static CFStringRef kUserInGroupID;
static CFStringRef kTimeoutID;
static CFStringRef kSharedID;
static CFStringRef kAllowRootID;
static CFStringRef kDenyID;
static CFStringRef kAllowID;
};
class Engine
{
public:
Engine(const char *configFile);
~Engine();
OSStatus authorize(const RightSet &inRights, const AuthorizationEnvironment *environment,
AuthorizationFlags flags, const CredentialSet *inCredentials, CredentialSet *outCredentials,
MutableRightSet *outRights, const AuthorizationToken &auth);
private:
void updateRules(CFAbsoluteTime now);
void readRules();
void parseRules(CFDictionaryRef rules);
static void parseRuleCallback(const void *key, const void *value, void *context);
void parseRule(CFStringRef right, CFTypeRef rule);
Rule getRule(const Right &inRight) const;
char *mRulesFileName;
CFAbsoluteTime mLastChecked;
struct timespec mRulesFileMtimespec;
typedef map<Right, Rule> RightMap;
typedef map<string, Rule> RuleMap;
RuleMap mRules;
};
};
#endif