Modify XC-SECURITY and XC-APPGROUP extensions to work with XACE
This commit is contained in:
parent
8526cd6395
commit
0106715000
|
@ -40,6 +40,7 @@ from The Open Group.
|
|||
#define _XAG_SERVER_
|
||||
#include "Xagstr.h"
|
||||
#include "Xagsrv.h"
|
||||
#include "xacestr.h"
|
||||
#define _SECURITY_SERVER
|
||||
#include "security.h"
|
||||
#include "Xfuncproto.h"
|
||||
|
@ -125,60 +126,9 @@ void XagClientStateChange(
|
|||
pointer nulldata,
|
||||
pointer calldata)
|
||||
{
|
||||
SecurityAuthorizationPtr pAuth;
|
||||
NewClientInfoRec* pci = (NewClientInfoRec*) calldata;
|
||||
ClientPtr pClient = pci->client;
|
||||
AppGroupPtr pAppGrp;
|
||||
XID authId = 0;
|
||||
|
||||
if (!pClient->appgroup) {
|
||||
switch (pClient->clientState) {
|
||||
|
||||
case ClientStateAuthenticating:
|
||||
case ClientStateRunning:
|
||||
case ClientStateCheckingSecurity:
|
||||
return;
|
||||
|
||||
case ClientStateInitial:
|
||||
case ClientStateCheckedSecurity:
|
||||
/*
|
||||
* If the client is connecting via a firewall proxy (which
|
||||
* uses XC-QUERY-SECURITY-1, then the authId is available
|
||||
* during ClientStateCheckedSecurity, otherwise it's
|
||||
* available during ClientStateInitial.
|
||||
*
|
||||
* Don't get it from pClient because can't guarantee the order
|
||||
* of the callbacks and the security extension might not have
|
||||
* plugged it in yet.
|
||||
*/
|
||||
authId = AuthorizationIDOfClient(pClient);
|
||||
break;
|
||||
|
||||
case ClientStateGone:
|
||||
case ClientStateRetained:
|
||||
/*
|
||||
* Don't get if from AuthorizationIDOfClient because can't
|
||||
* guarantee the order of the callbacks and the security
|
||||
* extension may have torn down the client's private data
|
||||
*/
|
||||
authId = pClient->authId;
|
||||
break;
|
||||
}
|
||||
|
||||
if (authId == None)
|
||||
return;
|
||||
|
||||
pAuth = (SecurityAuthorizationPtr)SecurityLookupIDByType(pClient,
|
||||
authId, SecurityAuthorizationResType, SecurityReadAccess);
|
||||
|
||||
if (pAuth == NULL)
|
||||
return;
|
||||
|
||||
for (pAppGrp = appGrpList; pAppGrp != NULL; pAppGrp = pAppGrp->next)
|
||||
if (pAppGrp->appgroupId == pAuth->group) break;
|
||||
} else {
|
||||
pAppGrp = pClient->appgroup;
|
||||
}
|
||||
AppGroupPtr pAppGrp = pClient->appgroup;
|
||||
|
||||
if (!pAppGrp)
|
||||
return;
|
||||
|
@ -248,6 +198,7 @@ XagExtensionInit(INITARGS)
|
|||
StandardMinorOpcode)) {
|
||||
#endif
|
||||
RT_APPGROUP = CreateNewResourceType (XagAppGroupFree);
|
||||
XaceRegisterCallback(XACE_AUTH_AVAIL, XagCallClientStateChange, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -814,12 +765,33 @@ void XagGetDeltaInfo(
|
|||
}
|
||||
|
||||
void XagCallClientStateChange(
|
||||
ClientPtr client)
|
||||
CallbackListPtr *pcbl,
|
||||
pointer nulldata,
|
||||
pointer calldata)
|
||||
{
|
||||
if (appGrpList) {
|
||||
XaceAuthAvailRec* rec = (XaceAuthAvailRec*) calldata;
|
||||
ClientPtr pClient = rec->client;
|
||||
|
||||
if (!pClient->appgroup) {
|
||||
SecurityAuthorizationPtr pAuth;
|
||||
XID authId = rec->authId;
|
||||
|
||||
/* can't use SecurityLookupIDByType here -- client
|
||||
* security state hasn't been setup yet.
|
||||
*/
|
||||
pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId,
|
||||
SecurityAuthorizationResType);
|
||||
if (!pAuth)
|
||||
return;
|
||||
|
||||
pClient->appgroup = (AppGroupPtr)LookupIDByType(pAuth->group,
|
||||
RT_APPGROUP);
|
||||
}
|
||||
|
||||
if (pClient->appgroup) {
|
||||
NewClientInfoRec clientinfo;
|
||||
|
||||
clientinfo.client = client;
|
||||
clientinfo.client = pClient;
|
||||
XagClientStateChange (NULL, NULL, (pointer)&clientinfo);
|
||||
}
|
||||
}
|
||||
|
|
468
Xext/security.c
468
Xext/security.c
|
@ -1,4 +1,4 @@
|
|||
/* $XdotOrg: xc/programs/Xserver/Xext/security.c,v 1.2 2004/04/23 18:44:41 eich Exp $ */
|
||||
/* $XdotOrg: xc/programs/Xserver/Xext/security.c,v 1.1.4.4.4.1 2004/05/04 19:43:00 ewalsh Exp $ */
|
||||
/* $Xorg: security.c,v 1.4 2001/02/09 02:04:32 xorgcvs Exp $ */
|
||||
/*
|
||||
|
||||
|
@ -35,13 +35,13 @@ in this Software without prior written authorization from The Open Group.
|
|||
#include "gcstruct.h"
|
||||
#include "colormapst.h"
|
||||
#include "propertyst.h"
|
||||
#include "xacestr.h"
|
||||
#define _SECURITY_SERVER
|
||||
#include "securstr.h"
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef LBX
|
||||
#define _XLBX_SERVER_
|
||||
#include "XLbx.h"
|
||||
#include "lbxserve.h"
|
||||
extern unsigned char LbxReqCode;
|
||||
#endif
|
||||
#ifdef XAPPGROUP
|
||||
|
@ -62,6 +62,17 @@ extern unsigned char LbxReqCode;
|
|||
|
||||
static int SecurityErrorBase; /* first Security error number */
|
||||
static int SecurityEventBase; /* first Security event number */
|
||||
static int slot; /* Xace security state number */
|
||||
|
||||
/* this is what we store as client security state */
|
||||
typedef struct {
|
||||
unsigned int trustLevel;
|
||||
XID authId;
|
||||
} SecurityClientStateRec;
|
||||
|
||||
#define STATEPTR(obj) ((obj)->securityState[slot])
|
||||
#define TRUSTLEVEL(obj) (((SecurityClientStateRec*)STATEPTR(obj))->trustLevel)
|
||||
#define AUTHID(obj) (((SecurityClientStateRec*)STATEPTR(obj))->authId)
|
||||
|
||||
CallbackListPtr SecurityValidateGroupCallback = NULL; /* see security.h */
|
||||
|
||||
|
@ -69,19 +80,8 @@ RESTYPE SecurityAuthorizationResType; /* resource type for authorizations */
|
|||
|
||||
static RESTYPE RTEventClient;
|
||||
|
||||
/* Proc vectors for untrusted clients, swapped and unswapped versions.
|
||||
* These are the same as the normal proc vectors except that extensions
|
||||
* that haven't declared themselves secure will have ProcBadRequest plugged
|
||||
* in for their major opcode dispatcher. This prevents untrusted clients
|
||||
* from guessing extension major opcodes and using the extension even though
|
||||
* the extension can't be listed or queried.
|
||||
*/
|
||||
int (*UntrustedProcVector[256])(
|
||||
ClientPtr /*client*/
|
||||
);
|
||||
int (*SwappedUntrustedProcVector[256])(
|
||||
ClientPtr /*client*/
|
||||
);
|
||||
#define CALLBACK(name) static void \
|
||||
name(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
|
||||
|
||||
/* SecurityAudit
|
||||
*
|
||||
|
@ -95,7 +95,7 @@ int (*SwappedUntrustedProcVector[256])(
|
|||
* Writes the message to the log file if security logging is on.
|
||||
*/
|
||||
|
||||
void
|
||||
static void
|
||||
SecurityAudit(char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
@ -168,7 +168,7 @@ SecurityDeleteAuthorization(
|
|||
|
||||
for (i = 1; i<currentMaxClients; i++)
|
||||
{
|
||||
if (clients[i] && (clients[i]->authId == pAuth->id))
|
||||
if (clients[i] && (AUTHID(clients[i]) == pAuth->id))
|
||||
CloseDownClient(clients[i]);
|
||||
}
|
||||
|
||||
|
@ -322,7 +322,7 @@ ProcSecurityQueryVersion(
|
|||
/* paranoia: this "can't happen" because this extension is hidden
|
||||
* from untrusted clients, but just in case...
|
||||
*/
|
||||
if (client->trustLevel != XSecurityClientTrusted)
|
||||
if (TRUSTLEVEL(client) != XSecurityClientTrusted)
|
||||
return BadRequest;
|
||||
|
||||
REQUEST_SIZE_MATCH(xSecurityQueryVersionReq);
|
||||
|
@ -408,7 +408,7 @@ ProcSecurityGenerateAuthorization(
|
|||
/* paranoia: this "can't happen" because this extension is hidden
|
||||
* from untrusted clients, but just in case...
|
||||
*/
|
||||
if (client->trustLevel != XSecurityClientTrusted)
|
||||
if (TRUSTLEVEL(client) != XSecurityClientTrusted)
|
||||
return BadRequest;
|
||||
|
||||
/* check request length */
|
||||
|
@ -591,7 +591,7 @@ ProcSecurityRevokeAuthorization(
|
|||
/* paranoia: this "can't happen" because this extension is hidden
|
||||
* from untrusted clients, but just in case...
|
||||
*/
|
||||
if (client->trustLevel != XSecurityClientTrusted)
|
||||
if (TRUSTLEVEL(client) != XSecurityClientTrusted)
|
||||
return BadRequest;
|
||||
|
||||
REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq);
|
||||
|
@ -776,12 +776,12 @@ SecurityDetermineEventPropogationLimits(
|
|||
* An audit message is generated if access is denied.
|
||||
*/
|
||||
|
||||
Bool
|
||||
SecurityCheckDeviceAccess(client, dev, fromRequest)
|
||||
ClientPtr client;
|
||||
DeviceIntPtr dev;
|
||||
Bool fromRequest;
|
||||
CALLBACK(SecurityCheckDeviceAccess)
|
||||
{
|
||||
XaceDeviceAccessRec *rec = (XaceDeviceAccessRec*)calldata;
|
||||
ClientPtr client = rec->client;
|
||||
DeviceIntPtr dev = rec->dev;
|
||||
Bool fromRequest = rec->fromRequest;
|
||||
WindowPtr pWin, pStopWin;
|
||||
Bool untrusted_got_event;
|
||||
Bool found_event_window;
|
||||
|
@ -789,12 +789,12 @@ SecurityCheckDeviceAccess(client, dev, fromRequest)
|
|||
int reqtype = 0;
|
||||
|
||||
/* trusted clients always allowed to do anything */
|
||||
if (client->trustLevel == XSecurityClientTrusted)
|
||||
return TRUE;
|
||||
if (TRUSTLEVEL(client) == XSecurityClientTrusted)
|
||||
return;
|
||||
|
||||
/* device security other than keyboard is not implemented yet */
|
||||
if (dev != inputInfo.keyboard)
|
||||
return TRUE;
|
||||
return;
|
||||
|
||||
/* some untrusted client wants access */
|
||||
|
||||
|
@ -809,7 +809,8 @@ SecurityCheckDeviceAccess(client, dev, fromRequest)
|
|||
case X_SetModifierMapping:
|
||||
SecurityAudit("client %d attempted request %d\n",
|
||||
client->index, reqtype);
|
||||
return FALSE;
|
||||
rec->rval = FALSE;
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -821,7 +822,7 @@ SecurityCheckDeviceAccess(client, dev, fromRequest)
|
|||
if (dev->grab)
|
||||
{
|
||||
untrusted_got_event =
|
||||
((rClient(dev->grab))->trustLevel != XSecurityClientTrusted);
|
||||
(TRUSTLEVEL(rClient(dev->grab)) != XSecurityClientTrusted);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -836,7 +837,7 @@ SecurityCheckDeviceAccess(client, dev, fromRequest)
|
|||
{
|
||||
found_event_window = TRUE;
|
||||
client = wClient(pWin);
|
||||
if (client->trustLevel != XSecurityClientTrusted)
|
||||
if (TRUSTLEVEL(client) != XSecurityClientTrusted)
|
||||
{
|
||||
untrusted_got_event = TRUE;
|
||||
}
|
||||
|
@ -849,7 +850,7 @@ SecurityCheckDeviceAccess(client, dev, fromRequest)
|
|||
if (other->mask & eventmask)
|
||||
{
|
||||
client = rClient(other);
|
||||
if (client->trustLevel != XSecurityClientTrusted)
|
||||
if (TRUSTLEVEL(client) != XSecurityClientTrusted)
|
||||
{
|
||||
untrusted_got_event = TRUE;
|
||||
break;
|
||||
|
@ -877,8 +878,9 @@ SecurityCheckDeviceAccess(client, dev, fromRequest)
|
|||
else
|
||||
SecurityAudit("client %d attempted to access device %d (%s)\n",
|
||||
client->index, dev->id, devname);
|
||||
rec->rval = FALSE;
|
||||
}
|
||||
return untrusted_got_event;
|
||||
return;
|
||||
} /* SecurityCheckDeviceAccess */
|
||||
|
||||
|
||||
|
@ -950,20 +952,22 @@ SecurityAuditResourceIDAccess(
|
|||
* Disallowed resource accesses are audited.
|
||||
*/
|
||||
|
||||
static pointer
|
||||
SecurityCheckResourceIDAccess(
|
||||
ClientPtr client,
|
||||
XID id,
|
||||
RESTYPE rtype,
|
||||
Mask access_mode,
|
||||
pointer rval)
|
||||
CALLBACK(SecurityCheckResourceIDAccess)
|
||||
{
|
||||
int cid = CLIENT_ID(id);
|
||||
int reqtype = ((xReq *)client->requestBuffer)->reqType;
|
||||
XaceResourceAccessRec *rec = (XaceResourceAccessRec*)calldata;
|
||||
ClientPtr client = rec->client;
|
||||
XID id = rec->id;
|
||||
RESTYPE rtype = rec->rtype;
|
||||
Mask access_mode = rec->access_mode;
|
||||
pointer rval = rec->res;
|
||||
int cid, reqtype;
|
||||
|
||||
if (SecurityUnknownAccess == access_mode)
|
||||
return rval; /* for compatibility, we have to allow access */
|
||||
if (TRUSTLEVEL(client) == XSecurityClientTrusted ||
|
||||
SecurityUnknownAccess == access_mode)
|
||||
return; /* for compatibility, we have to allow access */
|
||||
|
||||
cid = CLIENT_ID(id);
|
||||
reqtype = ((xReq *)client->requestBuffer)->reqType;
|
||||
switch (reqtype)
|
||||
{ /* these are always allowed */
|
||||
case X_QueryTree:
|
||||
|
@ -975,7 +979,7 @@ SecurityCheckResourceIDAccess(
|
|||
case X_DeleteProperty:
|
||||
case X_RotateProperties:
|
||||
case X_ListProperties:
|
||||
return rval;
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -995,15 +999,15 @@ SecurityCheckResourceIDAccess(
|
|||
* competing alternative for grouping clients for security purposes is to
|
||||
* use app groups. dpw
|
||||
*/
|
||||
if (client->trustLevel == clients[cid]->trustLevel
|
||||
if (TRUSTLEVEL(client) == TRUSTLEVEL(clients[cid])
|
||||
#ifdef XAPPGROUP
|
||||
|| (RT_COLORMAP == rtype &&
|
||||
XagDefaultColormap (client) == (Colormap) id)
|
||||
#endif
|
||||
)
|
||||
return rval;
|
||||
return;
|
||||
else
|
||||
return SecurityAuditResourceIDAccess(client, id);
|
||||
goto deny;
|
||||
}
|
||||
else /* server-owned resource - probably a default colormap or root window */
|
||||
{
|
||||
|
@ -1039,7 +1043,7 @@ SecurityCheckResourceIDAccess(
|
|||
)
|
||||
)
|
||||
{ /* not an ICCCM event */
|
||||
return SecurityAuditResourceIDAccess(client, id);
|
||||
goto deny;
|
||||
}
|
||||
break;
|
||||
} /* case X_SendEvent on root */
|
||||
|
@ -1057,7 +1061,7 @@ SecurityCheckResourceIDAccess(
|
|||
~(PropertyChangeMask|StructureNotifyMask)) == 0)
|
||||
break;
|
||||
}
|
||||
return SecurityAuditResourceIDAccess(client, id);
|
||||
goto deny;
|
||||
} /* case X_ChangeWindowAttributes on root */
|
||||
|
||||
default:
|
||||
|
@ -1068,29 +1072,32 @@ SecurityCheckResourceIDAccess(
|
|||
switch (((xReq *)client->requestBuffer)->data) {
|
||||
case X_LbxGetProperty:
|
||||
case X_LbxChangeProperty:
|
||||
return rval;
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* others not allowed */
|
||||
return SecurityAuditResourceIDAccess(client, id);
|
||||
goto deny;
|
||||
}
|
||||
}
|
||||
} /* end server-owned window or drawable */
|
||||
else if (SecurityAuthorizationResType == rtype)
|
||||
{
|
||||
SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)rval;
|
||||
if (pAuth->trustLevel != client->trustLevel)
|
||||
return SecurityAuditResourceIDAccess(client, id);
|
||||
if (pAuth->trustLevel != TRUSTLEVEL(client))
|
||||
goto deny;
|
||||
}
|
||||
else if (RT_COLORMAP != rtype)
|
||||
{ /* don't allow anything else besides colormaps */
|
||||
return SecurityAuditResourceIDAccess(client, id);
|
||||
goto deny;
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
return;
|
||||
deny:
|
||||
SecurityAuditResourceIDAccess(client, id);
|
||||
rec->rval = FALSE; /* deny access */
|
||||
} /* SecurityCheckResourceIDAccess */
|
||||
|
||||
|
||||
|
@ -1109,18 +1116,14 @@ SecurityCheckResourceIDAccess(
|
|||
* If a new client is connecting, its authorization ID is copied to
|
||||
* client->authID. If this is a generated authorization, its reference
|
||||
* count is bumped, its timer is cancelled if it was running, and its
|
||||
* trustlevel is copied to client->trustLevel.
|
||||
* trustlevel is copied to TRUSTLEVEL(client).
|
||||
*
|
||||
* If a client is disconnecting and the client was using a generated
|
||||
* authorization, the authorization's reference count is decremented, and
|
||||
* if it is now zero, the timer for this authorization is started.
|
||||
*/
|
||||
|
||||
static void
|
||||
SecurityClientStateCallback(
|
||||
CallbackListPtr *pcbl,
|
||||
pointer nulldata,
|
||||
pointer calldata)
|
||||
CALLBACK(SecurityClientStateCallback)
|
||||
{
|
||||
NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
|
||||
ClientPtr client = pci->client;
|
||||
|
@ -1132,7 +1135,14 @@ SecurityClientStateCallback(
|
|||
XID authId = AuthorizationIDOfClient(client);
|
||||
SecurityAuthorizationPtr pAuth;
|
||||
|
||||
client->authId = authId;
|
||||
/* allocate space for security state */
|
||||
STATEPTR(client) = xalloc(sizeof(SecurityClientStateRec));
|
||||
if (!STATEPTR(client))
|
||||
FatalError("Client %d: couldn't allocate security state\n",
|
||||
client->index);
|
||||
|
||||
TRUSTLEVEL(client) = XSecurityClientTrusted;
|
||||
AUTHID(client) = authId;
|
||||
pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId,
|
||||
SecurityAuthorizationResType);
|
||||
if (pAuth)
|
||||
|
@ -1142,23 +1152,21 @@ SecurityClientStateCallback(
|
|||
{
|
||||
if (pAuth->timer) TimerCancel(pAuth->timer);
|
||||
}
|
||||
client->trustLevel = pAuth->trustLevel;
|
||||
if (client->trustLevel != XSecurityClientTrusted)
|
||||
{
|
||||
client->CheckAccess = SecurityCheckResourceIDAccess;
|
||||
client->requestVector = client->swapped ?
|
||||
SwappedUntrustedProcVector : UntrustedProcVector;
|
||||
}
|
||||
TRUSTLEVEL(client) = pAuth->trustLevel;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ClientStateGone:
|
||||
case ClientStateRetained: /* client disconnected */
|
||||
{
|
||||
XID authId = client->authId;
|
||||
SecurityAuthorizationPtr pAuth;
|
||||
pointer freeit;
|
||||
|
||||
pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId,
|
||||
/* client may not have any state (bad authorization) */
|
||||
if (!STATEPTR(client))
|
||||
break;
|
||||
|
||||
pAuth = (SecurityAuthorizationPtr)LookupIDByType(AUTHID(client),
|
||||
SecurityAuthorizationResType);
|
||||
if (pAuth)
|
||||
{ /* it is a generated authorization */
|
||||
|
@ -1168,148 +1176,114 @@ SecurityClientStateCallback(
|
|||
SecurityStartAuthorizationTimer(pAuth);
|
||||
}
|
||||
}
|
||||
/* free security state */
|
||||
freeit = STATEPTR(client);
|
||||
STATEPTR(client) = NULL;
|
||||
xfree(freeit);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
} /* SecurityClientStateCallback */
|
||||
|
||||
#ifdef LBX
|
||||
Bool
|
||||
SecuritySameLevel(client, authId)
|
||||
ClientPtr client;
|
||||
XID authId;
|
||||
CALLBACK(SecurityCheckDrawableAccess)
|
||||
{
|
||||
XaceDrawableAccessRec *rec = (XaceDrawableAccessRec*)calldata;
|
||||
|
||||
if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted)
|
||||
rec->rval = FALSE;
|
||||
}
|
||||
|
||||
CALLBACK(SecurityCheckMapAccess)
|
||||
{
|
||||
XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata;
|
||||
WindowPtr pWin = rec->pWin;
|
||||
|
||||
if (STATEPTR(rec->client) &&
|
||||
(TRUSTLEVEL(rec->client) != XSecurityClientTrusted) &&
|
||||
(pWin->drawable.class == InputOnly) &&
|
||||
(TRUSTLEVEL(wClient(pWin->parent)) == XSecurityClientTrusted))
|
||||
|
||||
rec->rval = FALSE;
|
||||
}
|
||||
|
||||
CALLBACK(SecurityCheckBackgrndAccess)
|
||||
{
|
||||
XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata;
|
||||
|
||||
if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted)
|
||||
rec->rval = FALSE;
|
||||
}
|
||||
|
||||
CALLBACK(SecurityCheckExtAccess)
|
||||
{
|
||||
XaceExtAccessRec *rec = (XaceExtAccessRec*)calldata;
|
||||
|
||||
if ((TRUSTLEVEL(rec->client) != XSecurityClientTrusted) &&
|
||||
!STATEPTR(rec->ext))
|
||||
|
||||
rec->rval = FALSE;
|
||||
}
|
||||
|
||||
CALLBACK(SecurityCheckHostlistAccess)
|
||||
{
|
||||
XaceHostlistAccessRec *rec = (XaceHostlistAccessRec*)calldata;
|
||||
|
||||
if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted)
|
||||
{
|
||||
rec->rval = FALSE;
|
||||
if (rec->access_mode == SecurityWriteAccess)
|
||||
SecurityAudit("client %d attempted to change host access\n",
|
||||
rec->client->index);
|
||||
else
|
||||
SecurityAudit("client %d attempted to list hosts\n",
|
||||
rec->client->index);
|
||||
}
|
||||
}
|
||||
|
||||
CALLBACK(SecurityDeclareExtSecure)
|
||||
{
|
||||
XaceDeclareExtSecureRec *rec = (XaceDeclareExtSecureRec*)calldata;
|
||||
|
||||
/* security state for extensions is simply a boolean trust value */
|
||||
STATEPTR(rec->ext) = (pointer)rec->secure;
|
||||
}
|
||||
|
||||
#ifdef LBX
|
||||
CALLBACK(SecuritySameLevel)
|
||||
{
|
||||
XaceLbxProxyAccessRec *rec = (XaceLbxProxyAccessRec*)calldata;
|
||||
ClientPtr client = rec->client;
|
||||
XID authId = rec->authId;
|
||||
SecurityAuthorizationPtr pAuth;
|
||||
|
||||
pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId,
|
||||
SecurityAuthorizationResType);
|
||||
if (pAuth)
|
||||
return client->trustLevel == pAuth->trustLevel;
|
||||
return client->trustLevel == XSecurityClientTrusted;
|
||||
if ((pAuth && TRUSTLEVEL(client) != pAuth->trustLevel) ||
|
||||
(TRUSTLEVEL(client) != XSecurityClientTrusted))
|
||||
rec->rval = FALSE;
|
||||
}
|
||||
|
||||
CALLBACK(SecurityCheckLbxExtAccess)
|
||||
{
|
||||
XaceLbxExtAccessRec *rec = (XaceLbxExtAccessRec*)calldata;
|
||||
|
||||
if ((TRUSTLEVEL(rec->client) != XSecurityClientTrusted) &&
|
||||
!STATEPTR(rec->ext))
|
||||
|
||||
rec->rval = FALSE;
|
||||
}
|
||||
|
||||
CALLBACK(SecurityDeclareLbxExtSecure)
|
||||
{
|
||||
XaceDeclareLbxExtSecureRec *rec =
|
||||
(XaceDeclareLbxExtSecureRec*)calldata;
|
||||
|
||||
/* security state for extensions is simply a boolean trust value */
|
||||
STATEPTR(rec->ext) = (pointer)rec->secure;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* SecurityCensorImage
|
||||
*
|
||||
* Called after pScreen->GetImage to prevent pieces or trusted windows from
|
||||
* being returned in image data from an untrusted window.
|
||||
*
|
||||
* Arguments:
|
||||
* client is the client doing the GetImage.
|
||||
* pVisibleRegion is the visible region of the window.
|
||||
* widthBytesLine is the width in bytes of one horizontal line in pBuf.
|
||||
* pDraw is the source window.
|
||||
* x, y, w, h is the rectangle of image data from pDraw in pBuf.
|
||||
* format is the format of the image data in pBuf: ZPixmap or XYPixmap.
|
||||
* pBuf is the image data.
|
||||
*
|
||||
* Returns: nothing.
|
||||
*
|
||||
* Side Effects:
|
||||
* Any part of the rectangle (x, y, w, h) that is outside the visible
|
||||
* region of the window will be destroyed (overwritten) in pBuf.
|
||||
*/
|
||||
void
|
||||
SecurityCensorImage(client, pVisibleRegion, widthBytesLine, pDraw, x, y, w, h,
|
||||
format, pBuf)
|
||||
ClientPtr client;
|
||||
RegionPtr pVisibleRegion;
|
||||
long widthBytesLine;
|
||||
DrawablePtr pDraw;
|
||||
int x, y, w, h;
|
||||
unsigned int format;
|
||||
char * pBuf;
|
||||
{
|
||||
ScreenPtr pScreen = pDraw->pScreen;
|
||||
RegionRec imageRegion; /* region representing x,y,w,h */
|
||||
RegionRec censorRegion; /* region to obliterate */
|
||||
BoxRec imageBox;
|
||||
int nRects;
|
||||
|
||||
imageBox.x1 = x;
|
||||
imageBox.y1 = y;
|
||||
imageBox.x2 = x + w;
|
||||
imageBox.y2 = y + h;
|
||||
REGION_INIT(pScreen, &imageRegion, &imageBox, 1);
|
||||
REGION_NULL(pScreen, &censorRegion);
|
||||
|
||||
/* censorRegion = imageRegion - visibleRegion */
|
||||
REGION_SUBTRACT(pScreen, &censorRegion, &imageRegion, pVisibleRegion);
|
||||
nRects = REGION_NUM_RECTS(&censorRegion);
|
||||
if (nRects > 0)
|
||||
{ /* we have something to censor */
|
||||
GCPtr pScratchGC = NULL;
|
||||
PixmapPtr pPix = NULL;
|
||||
xRectangle *pRects = NULL;
|
||||
Bool failed = FALSE;
|
||||
int depth = 1;
|
||||
int bitsPerPixel = 1;
|
||||
int i;
|
||||
BoxPtr pBox;
|
||||
|
||||
/* convert region to list-of-rectangles for PolyFillRect */
|
||||
|
||||
pRects = (xRectangle *)ALLOCATE_LOCAL(nRects * sizeof(xRectangle *));
|
||||
if (!pRects)
|
||||
{
|
||||
failed = TRUE;
|
||||
goto failSafe;
|
||||
}
|
||||
for (pBox = REGION_RECTS(&censorRegion), i = 0;
|
||||
i < nRects;
|
||||
i++, pBox++)
|
||||
{
|
||||
pRects[i].x = pBox->x1;
|
||||
pRects[i].y = pBox->y1 - imageBox.y1;
|
||||
pRects[i].width = pBox->x2 - pBox->x1;
|
||||
pRects[i].height = pBox->y2 - pBox->y1;
|
||||
}
|
||||
|
||||
/* use pBuf as a fake pixmap */
|
||||
|
||||
if (format == ZPixmap)
|
||||
{
|
||||
depth = pDraw->depth;
|
||||
bitsPerPixel = pDraw->bitsPerPixel;
|
||||
}
|
||||
|
||||
pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h,
|
||||
depth, bitsPerPixel,
|
||||
widthBytesLine, (pointer)pBuf);
|
||||
if (!pPix)
|
||||
{
|
||||
failed = TRUE;
|
||||
goto failSafe;
|
||||
}
|
||||
|
||||
pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen);
|
||||
if (!pScratchGC)
|
||||
{
|
||||
failed = TRUE;
|
||||
goto failSafe;
|
||||
}
|
||||
|
||||
ValidateGC(&pPix->drawable, pScratchGC);
|
||||
(* pScratchGC->ops->PolyFillRect)(&pPix->drawable,
|
||||
pScratchGC, nRects, pRects);
|
||||
|
||||
failSafe:
|
||||
if (failed)
|
||||
{
|
||||
/* Censoring was not completed above. To be safe, wipe out
|
||||
* all the image data so that nothing trusted gets out.
|
||||
*/
|
||||
bzero(pBuf, (int)(widthBytesLine * h));
|
||||
}
|
||||
if (pRects) DEALLOCATE_LOCAL(pRects);
|
||||
if (pScratchGC) FreeScratchGC(pScratchGC);
|
||||
if (pPix) FreeScratchPixmapHeader(pPix);
|
||||
}
|
||||
REGION_UNINIT(pScreen, &imageRegion);
|
||||
REGION_UNINIT(pScreen, &censorRegion);
|
||||
} /* SecurityCensorImage */
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
typedef struct _PropertyAccessRec {
|
||||
|
@ -1767,21 +1741,21 @@ SecurityMatchString(
|
|||
#endif
|
||||
|
||||
|
||||
char
|
||||
SecurityCheckPropertyAccess(client, pWin, propertyName, access_mode)
|
||||
ClientPtr client;
|
||||
WindowPtr pWin;
|
||||
ATOM propertyName;
|
||||
Mask access_mode;
|
||||
CALLBACK(SecurityCheckPropertyAccess)
|
||||
{
|
||||
XacePropertyAccessRec *rec = (XacePropertyAccessRec*)calldata;
|
||||
ClientPtr client = rec->client;
|
||||
WindowPtr pWin = rec->pWin;
|
||||
ATOM propertyName = rec->propertyName;
|
||||
Mask access_mode = rec->access_mode;
|
||||
PropertyAccessPtr pacl;
|
||||
char action = SecurityDefaultAction;
|
||||
|
||||
/* if client trusted or window untrusted, allow operation */
|
||||
|
||||
if ( (client->trustLevel == XSecurityClientTrusted) ||
|
||||
(wClient(pWin)->trustLevel != XSecurityClientTrusted) )
|
||||
return SecurityAllowOperation;
|
||||
if ( (TRUSTLEVEL(client) == XSecurityClientTrusted) ||
|
||||
(TRUSTLEVEL(wClient(pWin)) != XSecurityClientTrusted) )
|
||||
return;
|
||||
|
||||
#ifdef PROPDEBUG
|
||||
/* For testing, it's more convenient if the property rules file gets
|
||||
|
@ -1894,7 +1868,9 @@ SecurityCheckPropertyAccess(client, pWin, propertyName, access_mode)
|
|||
client->index, reqtype, pWin->drawable.id,
|
||||
NameForAtom(propertyName), propertyName, cid, actionstr);
|
||||
}
|
||||
return action;
|
||||
/* return codes increase with strictness */
|
||||
if (action > rec->rval)
|
||||
rec->rval = action;
|
||||
} /* SecurityCheckPropertyAccess */
|
||||
|
||||
|
||||
|
@ -1913,6 +1889,10 @@ static void
|
|||
SecurityResetProc(
|
||||
ExtensionEntry *extEntry)
|
||||
{
|
||||
pointer freeit = STATEPTR(serverClient);
|
||||
STATEPTR(serverClient) = NULL;
|
||||
xfree(freeit);
|
||||
XaceUnregisterExtension(slot);
|
||||
SecurityFreePropertyAccessList();
|
||||
SecurityFreeSitePolicyStrings();
|
||||
} /* SecurityResetProc */
|
||||
|
@ -1934,6 +1914,48 @@ XSecurityOptions(argc, argv, i)
|
|||
} /* XSecurityOptions */
|
||||
|
||||
|
||||
/* SecurityExtensionSetup
|
||||
*
|
||||
* Arguments: none.
|
||||
*
|
||||
* Returns: nothing.
|
||||
*
|
||||
* Side Effects:
|
||||
* Sets up the Security extension if possible.
|
||||
* This function contains things that need to be done
|
||||
* before any other extension init functions get called.
|
||||
*/
|
||||
|
||||
void
|
||||
SecurityExtensionSetup(INITARGS)
|
||||
{
|
||||
/* allocate space for security state (freed in SecurityResetProc) */
|
||||
STATEPTR(serverClient) = xalloc(sizeof(SecurityClientStateRec));
|
||||
if (!STATEPTR(serverClient))
|
||||
FatalError("serverClient: couldn't allocate security state\n");
|
||||
|
||||
TRUSTLEVEL(serverClient) = XSecurityClientTrusted;
|
||||
AUTHID(serverClient) = None;
|
||||
|
||||
/* register callbacks */
|
||||
#define XaceRC XaceRegisterCallback
|
||||
XaceRC(XACE_RESOURCE_ACCESS, SecurityCheckResourceIDAccess, NULL);
|
||||
XaceRC(XACE_DEVICE_ACCESS, SecurityCheckDeviceAccess, NULL);
|
||||
XaceRC(XACE_PROPERTY_ACCESS, SecurityCheckPropertyAccess, NULL);
|
||||
XaceRC(XACE_DRAWABLE_ACCESS, SecurityCheckDrawableAccess, NULL);
|
||||
XaceRC(XACE_MAP_ACCESS, SecurityCheckMapAccess, NULL);
|
||||
XaceRC(XACE_BACKGRND_ACCESS, SecurityCheckBackgrndAccess, NULL);
|
||||
XaceRC(XACE_EXT_DISPATCH, SecurityCheckExtAccess, NULL);
|
||||
XaceRC(XACE_EXT_ACCESS, SecurityCheckExtAccess, NULL);
|
||||
XaceRC(XACE_HOSTLIST_ACCESS, SecurityCheckHostlistAccess, NULL);
|
||||
XaceRC(XACE_DECLARE_EXT_SECURE, SecurityDeclareExtSecure, NULL);
|
||||
#ifdef LBX
|
||||
XaceRC(XACE_LBX_EXT_ACCESS, SecurityCheckLbxExtAccess, NULL);
|
||||
XaceRC(XACE_DECLARE_LBX_EXT_SECURE, SecurityDeclareLbxExtSecure, NULL);
|
||||
XaceRC(XACE_LBX_PROXY_ACCESS, SecuritySameLevel, NULL);
|
||||
#endif
|
||||
} /* SecurityExtensionSetup */
|
||||
|
||||
|
||||
/* SecurityExtensionInit
|
||||
*
|
||||
|
@ -1949,7 +1971,6 @@ void
|
|||
SecurityExtensionInit(INITARGS)
|
||||
{
|
||||
ExtensionEntry *extEntry;
|
||||
int i;
|
||||
|
||||
SecurityAuthorizationResType =
|
||||
CreateNewResourceType(SecurityDeleteAuthorization);
|
||||
|
@ -1965,6 +1986,10 @@ SecurityExtensionInit(INITARGS)
|
|||
if (!AddCallback(&ClientStateCallback, SecurityClientStateCallback, NULL))
|
||||
return;
|
||||
|
||||
slot = XaceRegisterExtension(SECURITY_EXTENSION_NAME);
|
||||
if (slot < 0)
|
||||
return;
|
||||
|
||||
extEntry = AddExtension(SECURITY_EXTENSION_NAME,
|
||||
XSecurityNumberEvents, XSecurityNumberErrors,
|
||||
ProcSecurityDispatch, SProcSecurityDispatch,
|
||||
|
@ -1976,25 +2001,6 @@ SecurityExtensionInit(INITARGS)
|
|||
EventSwapVector[SecurityEventBase + XSecurityAuthorizationRevoked] =
|
||||
(EventSwapPtr)SwapSecurityAuthorizationRevokedEvent;
|
||||
|
||||
/* initialize untrusted proc vectors */
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
UntrustedProcVector[i] = ProcVector[i];
|
||||
SwappedUntrustedProcVector[i] = SwappedProcVector[i];
|
||||
}
|
||||
|
||||
/* make sure insecure extensions are not allowed */
|
||||
|
||||
for (i = 128; i < 256; i++)
|
||||
{
|
||||
if (!UntrustedProcVector[i])
|
||||
{
|
||||
UntrustedProcVector[i] = ProcBadRequest;
|
||||
SwappedUntrustedProcVector[i] = ProcBadRequest;
|
||||
}
|
||||
}
|
||||
|
||||
SecurityLoadPropertyAccessList();
|
||||
|
||||
} /* SecurityExtensionInit */
|
||||
|
|
Loading…
Reference in New Issue
Block a user