added per-handle security (untested)
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40534
This commit is contained in:
parent
8567d140d2
commit
e4fdaede32
@ -283,6 +283,7 @@ HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
|||||||
pHandle->serial = m_HSerial;
|
pHandle->serial = m_HSerial;
|
||||||
pHandle->owner = owner;
|
pHandle->owner = owner;
|
||||||
pHandle->ch_next = 0;
|
pHandle->ch_next = 0;
|
||||||
|
pHandle->access_special = false;
|
||||||
|
|
||||||
/* Create the hash value */
|
/* Create the hash value */
|
||||||
Handle_t hash = pHandle->serial;
|
Handle_t hash = pHandle->serial;
|
||||||
@ -336,8 +337,25 @@ void HandleSystem::SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pTok
|
|||||||
m_Types[type].typeSec.ident = pToken;
|
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
|
if (!type
|
||||||
|| type >= HANDLESYS_TYPEARRAY_SIZE
|
|| type >= HANDLESYS_TYPEARRAY_SIZE
|
||||||
|| m_Types[type].dispatch == NULL)
|
|| m_Types[type].dispatch == NULL)
|
||||||
@ -376,15 +394,31 @@ Handle_t HandleSystem::CreateHandleEx(HandleType_t type, void *object, IdentityT
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pAccess)
|
||||||
|
{
|
||||||
|
pHandle->access_special = true;
|
||||||
|
pHandle->sec = *pAccess;
|
||||||
|
}
|
||||||
|
|
||||||
pHandle->object = object;
|
pHandle->object = object;
|
||||||
pHandle->clone = 0;
|
pHandle->clone = 0;
|
||||||
|
|
||||||
return handle;
|
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)
|
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)
|
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)
|
bool HandleSystem::CheckAccess(QHandle *pHandle, HandleAccessRight right, const HandleSecurity *pSecurity)
|
||||||
{
|
{
|
||||||
QHandleType *pType = &m_Types[pHandle->type];
|
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 */
|
/* Check if the type's identity matches */
|
||||||
if (access & HANDLE_RESTRICT_IDENTITY)
|
if (access & HANDLE_RESTRICT_IDENTITY)
|
||||||
@ -487,6 +528,13 @@ HandleError HandleSystem::CloneHandle(QHandle *pHandle, unsigned int index, Hand
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Assign permissions from parent */
|
||||||
|
if (pHandle->access_special)
|
||||||
|
{
|
||||||
|
pNewHandle->access_special = true;
|
||||||
|
pNewHandle->sec = pHandle->sec;
|
||||||
|
}
|
||||||
|
|
||||||
pNewHandle->clone = index;
|
pNewHandle->clone = index;
|
||||||
pHandle->refcount++;
|
pHandle->refcount++;
|
||||||
|
|
||||||
|
@ -63,6 +63,8 @@ struct QHandle
|
|||||||
unsigned int refcount; /* Reference count for safe destruction */
|
unsigned int refcount; /* Reference count for safe destruction */
|
||||||
unsigned int clone; /* If non-zero, this is our cloned parent index */
|
unsigned int clone; /* If non-zero, this is our cloned parent index */
|
||||||
HandleSet set; /* Information about the handle's state */
|
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
|
/* The following variables are unrelated to the Handle array, and used
|
||||||
* as an inlined chain of information */
|
* as an inlined chain of information */
|
||||||
unsigned int freeID; /* ID of a free handle in the free handle chain */
|
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 InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess);
|
||||||
|
|
||||||
bool TypeCheck(HandleType_t intype, HandleType_t outtype);
|
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:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Decodes a handle with sanity and security checking.
|
* Decodes a handle with sanity and security checking.
|
||||||
@ -170,7 +178,7 @@ protected:
|
|||||||
HandleError FreeHandle(QHandle *pHandle, unsigned int index);
|
HandleError FreeHandle(QHandle *pHandle, unsigned int index);
|
||||||
void UnlinkHandleFromOwner(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);
|
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:
|
private:
|
||||||
QHandle *m_Handles;
|
QHandle *m_Handles;
|
||||||
QHandleType *m_Types;
|
QHandleType *m_Types;
|
||||||
|
@ -104,7 +104,11 @@ IdentityToken_t *ShareSystem::CreateIdentity(IdentityType_t type)
|
|||||||
|
|
||||||
/* :TODO: Cache? */
|
/* :TODO: Cache? */
|
||||||
IdentityToken_t *pToken = new IdentityToken_t;
|
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;
|
return pToken;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#include <sp_vm_types.h>
|
#include <sp_vm_types.h>
|
||||||
|
|
||||||
#define SMINTERFACE_HANDLESYSTEM_NAME "IHandleSys"
|
#define SMINTERFACE_HANDLESYSTEM_NAME "IHandleSys"
|
||||||
#define SMINTERFACE_HANDLESYSTEM_VERSION 1
|
#define SMINTERFACE_HANDLESYSTEM_VERSION 2
|
||||||
|
|
||||||
/** Specifies no Identity */
|
/** Specifies no Identity */
|
||||||
#define DEFAULT_IDENTITY NULL
|
#define DEFAULT_IDENTITY NULL
|
||||||
@ -303,6 +303,23 @@ namespace SourceMod
|
|||||||
* @return True on success, false if version is unsupported.
|
* @return True on success, false if version is unsupported.
|
||||||
*/
|
*/
|
||||||
virtual bool InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess) =0;
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user