added per-handle security (untested)

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40534
This commit is contained in:
David Anderson 2007-02-26 02:47:03 +00:00
parent 8567d140d2
commit e4fdaede32
4 changed files with 83 additions and 6 deletions

View File

@ -283,6 +283,7 @@ HandleError HandleSystem::MakePrimHandle(HandleType_t type,
pHandle->serial = m_HSerial;
pHandle->owner = owner;
pHandle->ch_next = 0;
pHandle->access_special = false;
/* Create the hash value */
Handle_t hash = pHandle->serial;
@ -336,8 +337,25 @@ void HandleSystem::SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pTok
m_Types[type].typeSec.ident = pToken;
}
Handle_t HandleSystem::CreateHandleEx(HandleType_t type, void *object, IdentityToken_t *owner, IdentityToken_t *ident, HandleError *err, bool identity)
Handle_t HandleSystem::CreateHandleInt(HandleType_t type,
void *object,
const HandleSecurity *pSec,
HandleError *err,
const HandleAccess *pAccess,
bool identity)
{
IdentityToken_t *ident;
IdentityToken_t *owner;
if (pSec)
{
ident = pSec->pIdentity;
owner = pSec->pOwner;
} else {
ident = NULL;
owner = NULL;
}
if (!type
|| type >= HANDLESYS_TYPEARRAY_SIZE
|| m_Types[type].dispatch == NULL)
@ -376,15 +394,31 @@ Handle_t HandleSystem::CreateHandleEx(HandleType_t type, void *object, IdentityT
return 0;
}
if (pAccess)
{
pHandle->access_special = true;
pHandle->sec = *pAccess;
}
pHandle->object = object;
pHandle->clone = 0;
return handle;
}
Handle_t HandleSystem::CreateHandleEx(HandleType_t type, void *object, const HandleSecurity *pSec, const HandleAccess *pAccess, HandleError *err)
{
return CreateHandleInt(type, object, pSec, err, pAccess, false);
}
Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityToken_t *owner, IdentityToken_t *ident, HandleError *err)
{
return CreateHandleEx(type, object, owner, ident, err, false);
HandleSecurity sec;
sec.pIdentity = ident;
sec.pOwner = owner;
return CreateHandleEx(type, object, &sec, NULL, err);
}
bool HandleSystem::TypeCheck(HandleType_t intype, HandleType_t outtype)
@ -447,7 +481,14 @@ HandleError HandleSystem::GetHandle(Handle_t handle,
bool HandleSystem::CheckAccess(QHandle *pHandle, HandleAccessRight right, const HandleSecurity *pSecurity)
{
QHandleType *pType = &m_Types[pHandle->type];
unsigned int access = pType->hndlSec.access[right];
unsigned int access;
if (pHandle->access_special)
{
access = pHandle->sec.access[right];
} else {
access = pType->hndlSec.access[right];
}
/* Check if the type's identity matches */
if (access & HANDLE_RESTRICT_IDENTITY)
@ -487,6 +528,13 @@ HandleError HandleSystem::CloneHandle(QHandle *pHandle, unsigned int index, Hand
return err;
}
/* Assign permissions from parent */
if (pHandle->access_special)
{
pNewHandle->access_special = true;
pNewHandle->sec = pHandle->sec;
}
pNewHandle->clone = index;
pHandle->refcount++;

View File

@ -63,6 +63,8 @@ struct QHandle
unsigned int refcount; /* Reference count for safe destruction */
unsigned int clone; /* If non-zero, this is our cloned parent index */
HandleSet set; /* Information about the handle's state */
bool access_special; /* Whether or not access rules are special or type-derived */
HandleAccess sec; /* Security rules */
/* The following variables are unrelated to the Handle array, and used
* as an inlined chain of information */
unsigned int freeID; /* ID of a free handle in the free handle chain */
@ -126,6 +128,12 @@ public: //IHandleSystem
bool InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess);
bool TypeCheck(HandleType_t intype, HandleType_t outtype);
virtual Handle_t CreateHandleEx(HandleType_t type,
void *object,
const HandleSecurity *pSec,
const HandleAccess *pAccess,
HandleError *err);
protected:
/**
* Decodes a handle with sanity and security checking.
@ -170,7 +178,7 @@ protected:
HandleError FreeHandle(QHandle *pHandle, unsigned int index);
void UnlinkHandleFromOwner(QHandle *pHandle, unsigned int index);
HandleError CloneHandle(QHandle *pHandle, unsigned int index, Handle_t *newhandle, IdentityToken_t *newOwner);
Handle_t CreateHandleEx(HandleType_t type, void *object, IdentityToken_t *owner, IdentityToken_t *ident, HandleError *err, bool identity);
Handle_t CreateHandleInt(HandleType_t type, void *object, const HandleSecurity *pSec, HandleError *err, const HandleAccess *pAccess, bool identity);
private:
QHandle *m_Handles;
QHandleType *m_Types;

View File

@ -104,7 +104,11 @@ IdentityToken_t *ShareSystem::CreateIdentity(IdentityType_t type)
/* :TODO: Cache? */
IdentityToken_t *pToken = new IdentityToken_t;
pToken->ident = g_HandleSys.CreateHandleEx(type, NULL, GetIdentRoot(), GetIdentRoot(), NULL, true);
HandleSecurity sec;
sec.pOwner = sec.pIdentity = GetIdentRoot();
pToken->ident = g_HandleSys.CreateHandleInt(type, NULL, &sec, NULL, NULL, true);
return pToken;
}

View File

@ -39,7 +39,7 @@
#include <sp_vm_types.h>
#define SMINTERFACE_HANDLESYSTEM_NAME "IHandleSys"
#define SMINTERFACE_HANDLESYSTEM_VERSION 1
#define SMINTERFACE_HANDLESYSTEM_VERSION 2
/** Specifies no Identity */
#define DEFAULT_IDENTITY NULL
@ -303,6 +303,23 @@ namespace SourceMod
* @return True on success, false if version is unsupported.
*/
virtual bool InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess) =0;
/**
* @brief Creates a new handle.
*
* @param type Type to use on the handle.
* @param object Object to bind to the handle.
* @param pSec Security pointer; pOwner is written as the owner,
* pIdent is used as the parent identity for authorization.
* @param pAccess Access right descriptor for the Handle; NULL for type defaults.
* @param err Optional pointer to store an error code.
* @return A new Handle_t, or 0 on failure.
*/
virtual Handle_t CreateHandleEx(HandleType_t type,
void *object,
const HandleSecurity *pSec,
const HandleAccess *pAccess,
HandleError *err) =0;
};
}