summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xext/Makefile.am17
-rw-r--r--Xext/appgroup.c82
-rw-r--r--Xext/appgroup.h4
-rw-r--r--Xext/security.c403
-rw-r--r--Xext/securitysrv.h35
-rw-r--r--Xext/xace.c496
-rw-r--r--Xext/xace.h103
-rw-r--r--Xext/xacestr.h135
-rw-r--r--configure.ac20
-rw-r--r--dix/devices.c21
-rw-r--r--dix/dispatch.c69
-rw-r--r--dix/dixutils.c35
-rw-r--r--dix/events.c28
-rw-r--r--dix/extension.c94
-rw-r--r--dix/main.c1
-rw-r--r--dix/privates.c58
-rw-r--r--dix/property.c24
-rw-r--r--dix/resource.c74
-rw-r--r--dix/window.c32
-rw-r--r--hw/xfree86/dixmods/extmod/modinit.h5
-rw-r--r--hw/xfree86/loader/dixsym.c6
-rw-r--r--include/dix-config.h.in3
-rw-r--r--include/dix.h19
-rw-r--r--include/dixstruct.h10
-rw-r--r--include/extension.h8
-rw-r--r--include/extnsionst.h6
-rw-r--r--include/resource.h11
-rw-r--r--mi/miinitext.c18
-rw-r--r--os/access.c18
-rw-r--r--os/connection.c8
30 files changed, 1277 insertions, 566 deletions
diff --git a/Xext/Makefile.am b/Xext/Makefile.am
index 3a48109bc..6ea3d7445 100644
--- a/Xext/Makefile.am
+++ b/Xext/Makefile.am
@@ -33,6 +33,10 @@ MODULE_SRCS = \
sync.c \
xcmisc.c
+# Extra configuration files ship with some extensions
+SERVERCONFIGdir = $(libdir)/xserver
+SERVERCONFIG_DATA =
+
# Optional sources included if extension enabled by configure.ac rules
# MIT Shared Memory extension
@@ -65,13 +69,19 @@ if XINERAMA
BUILTIN_SRCS += $(XINERAMA_SRCS)
endif
+# X-ACE extension: provides hooks for building security policy extensions
+# like XC-Security, X-SELinux & XTSol
+XACE_SRCS = xace.c xace.h xacestr.h
+if XACE
+BUILTIN_SRCS += $(XACE_SRCS)
+endif
+
# Security extension: multi-level security to protect clients from each other
XCSECURITY_SRCS = security.c securitysrv.h
if XCSECURITY
BUILTIN_SRCS += $(XCSECURITY_SRCS)
-SERVERCONFIGdir = $(libdir)/xserver
-SERVERCONFIG_DATA = SecurityPolicy
+SERVERCONFIG_DATA += SecurityPolicy
AM_CFLAGS += -DDEFAULTPOLICYFILE=\"$(SERVERCONFIGdir)/SecurityPolicy\"
endif
@@ -150,11 +160,12 @@ libXextmodule_la_SOURCES = $(MODULE_SRCS)
endif
EXTRA_DIST = \
- SecurityPolicy \
+ $(SERVERCONFIG_DATA) \
$(MITSHM_SRCS) \
$(XV_SRCS) \
$(RES_SRCS) \
$(SCREENSAVER_SRCS) \
+ $(XACE_SRCS) \
$(XCSECURITY_SRCS) \
$(XCALIBRATE_SRCS) \
$(XINERAMA_SRCS) \
diff --git a/Xext/appgroup.c b/Xext/appgroup.c
index b047945c0..650dc0ab8 100644
--- a/Xext/appgroup.c
+++ b/Xext/appgroup.c
@@ -41,6 +41,7 @@ from The Open Group.
#include "servermd.h"
#define _XAG_SERVER_
#include <X11/extensions/Xagstr.h>
+#include "xacestr.h"
#include "securitysrv.h"
#include <X11/Xfuncproto.h>
@@ -121,62 +122,11 @@ void XagClientStateChange(
pointer nulldata,
pointer calldata)
{
- SecurityAuthorizationPtr pAuth;
NewClientInfoRec* pci = (NewClientInfoRec*) calldata;
ClientPtr pClient = pci->client;
- AppGroupPtr pAppGrp;
- XID authId = 0;
+ AppGroupPtr pAppGrp = pClient->appgroup;
int slot;
- 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;
- }
-
if (!pAppGrp)
return;
@@ -233,6 +183,7 @@ XagExtensionInit(INITARGS)
XagResetProc,
StandardMinorOpcode)) {
RT_APPGROUP = CreateNewResourceType (XagAppGroupFree);
+ XaceRegisterCallback(XACE_AUTH_AVAIL, XagCallClientStateChange, NULL);
}
}
@@ -799,12 +750,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);
}
}
diff --git a/Xext/appgroup.h b/Xext/appgroup.h
index 39087fe8e..a875068fc 100644
--- a/Xext/appgroup.h
+++ b/Xext/appgroup.h
@@ -51,7 +51,9 @@ extern ClientPtr XagLeader(
);
extern void XagCallClientStateChange(
- ClientPtr /* client */
+ CallbackListPtr * /* pcbl */,
+ pointer /* nulldata */,
+ pointer /* calldata */
);
extern Bool XagIsControlledRoot (
diff --git a/Xext/security.c b/Xext/security.c
index 4684d783b..54a2b3e3f 100644
--- a/Xext/security.c
+++ b/Xext/security.c
@@ -36,6 +36,7 @@ in this Software without prior written authorization from The Open Group.
#include "gcstruct.h"
#include "colormapst.h"
#include "propertyst.h"
+#include "xacestr.h"
#include "securitysrv.h"
#include <X11/extensions/securstr.h>
#include <assert.h>
@@ -58,6 +59,23 @@ in this Software without prior written authorization from The Open Group.
static int SecurityErrorBase; /* first Security error number */
static int SecurityEventBase; /* first Security event number */
+static int securityClientPrivateIndex;
+static int securityExtnsnPrivateIndex;
+
+/* this is what we store as client security state */
+typedef struct {
+ unsigned int trustLevel;
+ XID authId;
+} SecurityClientStateRec;
+
+#define STATEVAL(extnsn) \
+ ((extnsn)->devPrivates[securityExtnsnPrivateIndex].val)
+#define STATEPTR(client) \
+ ((client)->devPrivates[securityClientPrivateIndex].ptr)
+#define TRUSTLEVEL(client) \
+ (((SecurityClientStateRec*)STATEPTR(client))->trustLevel)
+#define AUTHID(client) \
+ (((SecurityClientStateRec*)STATEPTR(client))->authId)
CallbackListPtr SecurityValidateGroupCallback = NULL; /* see security.h */
@@ -65,19 +83,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
*
@@ -91,7 +98,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;
@@ -164,7 +171,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]);
}
@@ -318,7 +325,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);
@@ -404,7 +411,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 */
@@ -587,7 +594,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);
@@ -772,12 +779,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;
@@ -785,12 +792,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 */
@@ -805,7 +812,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;
}
@@ -817,7 +825,7 @@ SecurityCheckDeviceAccess(client, dev, fromRequest)
if (dev->grab)
{
untrusted_got_event =
- ((rClient(dev->grab))->trustLevel != XSecurityClientTrusted);
+ (TRUSTLEVEL(rClient(dev->grab)) != XSecurityClientTrusted);
}
else
{
@@ -832,7 +840,7 @@ SecurityCheckDeviceAccess(client, dev, fromRequest)
{
found_event_window = TRUE;
client = wClient(pWin);
- if (client->trustLevel != XSecurityClientTrusted)
+ if (TRUSTLEVEL(client) != XSecurityClientTrusted)
{
untrusted_got_event = TRUE;
}
@@ -845,7 +853,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;
@@ -873,8 +881,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 */
@@ -946,20 +955,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;
-
- if (SecurityUnknownAccess == access_mode)
- return rval; /* for compatibility, we have to allow access */
-
+ 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 (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:
@@ -971,7 +982,7 @@ SecurityCheckResourceIDAccess(
case X_DeleteProperty:
case X_RotateProperties:
case X_ListProperties:
- return rval;
+ return;
default:
break;
}
@@ -991,15 +1002,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 */
{
@@ -1035,7 +1046,7 @@ SecurityCheckResourceIDAccess(
)
)
{ /* not an ICCCM event */
- return SecurityAuditResourceIDAccess(client, id);
+ goto deny;
}
break;
} /* case X_SendEvent on root */
@@ -1053,28 +1064,31 @@ SecurityCheckResourceIDAccess(
~(PropertyChangeMask|StructureNotifyMask)) == 0)
break;
}
- return SecurityAuditResourceIDAccess(client, id);
+ goto deny;
} /* case X_ChangeWindowAttributes on root */
default:
{
/* 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 */
@@ -1093,30 +1107,32 @@ 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;
switch (client->clientState)
{
+ case ClientStateInitial:
+ TRUSTLEVEL(serverClient) = XSecurityClientTrusted;
+ AUTHID(serverClient) = None;
+ break;
+
case ClientStateRunning:
{
XID authId = AuthorizationIDOfClient(client);
SecurityAuthorizationPtr pAuth;
- client->authId = authId;
+ TRUSTLEVEL(client) = XSecurityClientTrusted;
+ AUTHID(client) = authId;
pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId,
SecurityAuthorizationResType);
if (pAuth)
@@ -1126,23 +1142,20 @@ 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;
- 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 */
@@ -1158,124 +1171,68 @@ SecurityClientStateCallback(
}
} /* SecurityClientStateCallback */
-/* 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;
+CALLBACK(SecurityCheckDrawableAccess)
{
- 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;
- }
+ XaceDrawableAccessRec *rec = (XaceDrawableAccessRec*)calldata;
- /* use pBuf as a fake pixmap */
+ if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted)
+ rec->rval = FALSE;
+}
- if (format == ZPixmap)
- {
- depth = pDraw->depth;
- bitsPerPixel = pDraw->bitsPerPixel;
- }
+CALLBACK(SecurityCheckMapAccess)
+{
+ XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata;
+ WindowPtr pWin = rec->pWin;
- pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h,
- depth, bitsPerPixel,
- widthBytesLine, (pointer)pBuf);
- if (!pPix)
- {
- failed = TRUE;
- goto failSafe;
- }
+ if (STATEPTR(rec->client) &&
+ (TRUSTLEVEL(rec->client) != XSecurityClientTrusted) &&
+ (pWin->drawable.class == InputOnly) &&
+ (TRUSTLEVEL(wClient(pWin->parent)) == XSecurityClientTrusted))
- pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen);
- if (!pScratchGC)
- {
- failed = TRUE;
- goto failSafe;
- }
+ rec->rval = FALSE;
+}
- ValidateGC(&pPix->drawable, pScratchGC);
- (* pScratchGC->ops->PolyFillRect)(&pPix->drawable,
- pScratchGC, nRects, pRects);
+CALLBACK(SecurityCheckBackgrndAccess)
+{
+ XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata;
- 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);
+ if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted)
+ rec->rval = FALSE;
+}
+
+CALLBACK(SecurityCheckExtAccess)
+{
+ XaceExtAccessRec *rec = (XaceExtAccessRec*)calldata;
+
+ if ((TRUSTLEVEL(rec->client) != XSecurityClientTrusted) &&
+ !STATEVAL(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);
}
- REGION_UNINIT(pScreen, &imageRegion);
- REGION_UNINIT(pScreen, &censorRegion);
-} /* SecurityCensorImage */
+}
+
+CALLBACK(SecurityDeclareExtSecure)
+{
+ XaceDeclareExtSecureRec *rec = (XaceDeclareExtSecureRec*)calldata;
+
+ /* security state for extensions is simply a boolean trust value */
+ STATEVAL(rec->ext) = rec->secure;
+}
/**********************************************************************/
@@ -1734,21 +1691,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
@@ -1861,7 +1818,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 */
@@ -1901,6 +1860,46 @@ 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 the client private index */
+ securityClientPrivateIndex = AllocateClientPrivateIndex();
+ if (!AllocateClientPrivate(securityClientPrivateIndex,
+ sizeof (SecurityClientStateRec)))
+ FatalError("SecurityExtensionSetup: Can't allocate client private.\n");
+
+ /* Allocate the extension private index */
+ securityExtnsnPrivateIndex = AllocateExtensionPrivateIndex();
+ if (!AllocateExtensionPrivate(securityExtnsnPrivateIndex, 0))
+ FatalError("SecurityExtensionSetup: Can't allocate extnsn private.\n");
+
+ /* 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);
+} /* SecurityExtensionSetup */
+
/* SecurityExtensionInit
*
@@ -1916,7 +1915,6 @@ void
SecurityExtensionInit(INITARGS)
{
ExtensionEntry *extEntry;
- int i;
SecurityAuthorizationResType =
CreateNewResourceType(SecurityDeleteAuthorization);
@@ -1943,25 +1941,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 */
diff --git a/Xext/securitysrv.h b/Xext/securitysrv.h
index 596eead0d..7c6f432fe 100644
--- a/Xext/securitysrv.h
+++ b/Xext/securitysrv.h
@@ -86,46 +86,11 @@ typedef struct {
Bool valid; /* did anyone recognize it? if so, set to TRUE */
} SecurityValidateGroupInfoRec;
-/* 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.
- */
-extern int (*UntrustedProcVector[256])(ClientPtr client);
-extern int (*SwappedUntrustedProcVector[256])(ClientPtr client);
-
-extern Bool SecurityCheckDeviceAccess(ClientPtr client, DeviceIntPtr dev,
- Bool fromRequest);
-
-extern void SecurityAudit(char *format, ...);
-
extern int XSecurityOptions(int argc, char **argv, int i);
/* Give this value or higher to the -audit option to get security messages */
#define SECURITY_AUDIT_LEVEL 4
-extern void SecurityCensorImage(
- ClientPtr client,
- RegionPtr pVisibleRegion,
- long widthBytesLine,
- DrawablePtr pDraw,
- int x, int y, int w, int h,
- unsigned int format,
- char * pBuf);
-
-#define SecurityAllowOperation 0
-#define SecurityIgnoreOperation 1
-#define SecurityErrorOperation 2
-
-extern char
-SecurityCheckPropertyAccess(
- ClientPtr client,
- WindowPtr pWin,
- ATOM propertyName,
- Mask access_mode);
-
#define SECURITY_POLICY_FILE_VERSION "version-1"
extern char **SecurityGetSitePolicyStrings(int *n);
diff --git a/Xext/xace.c b/Xext/xace.c
new file mode 100644
index 000000000..14a5e7963
--- /dev/null
+++ b/Xext/xace.c
@@ -0,0 +1,496 @@
+/************************************************************
+
+Author: Eamon Walsh <ewalsh@epoch.ncsc.mil>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+this permission notice appear in supporting documentation. This permission
+notice shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdarg.h>
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "xacestr.h"
+#include "modinit.h"
+
+CallbackListPtr XaceHooks[XACE_NUM_HOOKS] = {0};
+
+/* 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*/
+);
+
+/* Entry point for hook functions. Called by Xserver.
+ */
+int XaceHook(int hook, ...)
+{
+ pointer calldata; /* data passed to callback */
+ int *prv = NULL; /* points to return value from callback */
+ va_list ap; /* argument list */
+ va_start(ap, hook);
+
+ /* Marshal arguments for passing to callback.
+ * Each callback has its own case, which sets up a structure to hold
+ * the arguments and integer return parameter, or in some cases just
+ * sets calldata directly to a single argument (with no return result)
+ */
+ switch (hook)
+ {
+ case XACE_CORE_DISPATCH: {
+ XaceCoreDispatchRec rec = {
+ va_arg(ap, ClientPtr),
+ TRUE /* default allow */
+ };
+ calldata = &rec;
+ prv = &rec.rval;
+ break;
+ }
+ case XACE_RESOURCE_ACCESS: {
+ XaceResourceAccessRec rec = {
+ va_arg(ap, ClientPtr),
+ va_arg(ap, XID),
+ va_arg(ap, RESTYPE),
+ va_arg(ap, Mask),
+ va_arg(ap, pointer),
+ TRUE /* default allow */
+ };
+ calldata = &rec;
+ prv = &rec.rval;
+ break;
+ }
+ case XACE_DEVICE_ACCESS: {
+ XaceDeviceAccessRec rec = {
+ va_arg(ap, ClientPtr),
+ va_arg(ap, DeviceIntPtr),
+ va_arg(ap, Bool),
+ TRUE /* default allow */
+ };
+ calldata = &rec;
+ prv = &rec.rval;
+ break;
+ }
+ case XACE_PROPERTY_ACCESS: {
+ XacePropertyAccessRec rec = {
+ va_arg(ap, ClientPtr),
+ va_arg(ap, WindowPtr),
+ va_arg(ap, Atom),
+ va_arg(ap, Mask),
+ SecurityAllowOperation /* default allow */
+ };
+ calldata = &rec;
+ prv = &rec.rval;
+ break;
+ }
+ case XACE_DRAWABLE_ACCESS: {
+ XaceDrawableAccessRec rec = {
+ va_arg(ap, ClientPtr),
+ va_arg(ap, DrawablePtr),
+ TRUE /* default allow */
+ };
+ calldata = &rec;
+ prv = &rec.rval;
+ break;
+ }
+ case XACE_MAP_ACCESS:
+ case XACE_BACKGRND_ACCESS: {
+ XaceMapAccessRec rec = {
+ va_arg(ap, ClientPtr),
+ va_arg(ap, WindowPtr),
+ TRUE /* default allow */
+ };
+ calldata = &rec;
+ prv = &rec.rval;
+ break;
+ }
+ case XACE_EXT_DISPATCH:
+ case XACE_EXT_ACCESS: {
+ XaceExtAccessRec rec = {
+ va_arg(ap, ClientPtr),
+ va_arg(ap, ExtensionEntry*),
+ TRUE /* default allow */
+ };
+ calldata = &rec;
+ prv = &rec.rval;
+ break;
+ }
+ case XACE_HOSTLIST_ACCESS: {
+ XaceHostlistAccessRec rec = {
+ va_arg(ap, ClientPtr),
+ va_arg(ap, Mask),
+ TRUE /* default allow */
+ };
+ calldata = &rec;
+ prv = &rec.rval;
+ break;
+ }
+ case XACE_SITE_POLICY: {
+ XaceSitePolicyRec rec = {
+ va_arg(ap, char*),
+ va_arg(ap, int),
+ FALSE /* default unrecognized */
+ };
+ calldata = &rec;
+ prv = &rec.rval;
+ break;
+ }
+ case XACE_DECLARE_EXT_SECURE: {
+ XaceDeclareExtSecureRec rec = {
+ va_arg(ap, ExtensionEntry*),
+ va_arg(ap, Bool)
+ };
+ calldata = &rec;
+ break;
+ }
+ case XACE_AUTH_AVAIL: {
+ XaceAuthAvailRec rec = {
+ va_arg(ap, ClientPtr),
+ va_arg(ap, XID)
+ };
+ calldata = &rec;
+ break;
+ }
+ case XACE_KEY_AVAIL: {
+ XaceKeyAvailRec rec = {
+ va_arg(ap, xEventPtr),
+ va_arg(ap, DeviceIntPtr),
+ va_arg(ap, int)
+ };
+ calldata = &rec;
+ break;
+ }
+ case XACE_WINDOW_INIT: {
+ XaceWindowRec rec = {
+ va_arg(ap, ClientPtr),
+ va_arg(ap, WindowPtr)
+ };
+ calldata = &rec;
+ break;
+ }
+ case XACE_AUDIT_BEGIN: {
+ XaceAuditRec rec = {
+ va_arg(ap, ClientPtr),
+ 0
+ };
+ calldata = &rec;
+ break;
+ }
+ case XACE_AUDIT_END: {
+ XaceAuditRec rec = {
+ va_arg(ap, ClientPtr),
+ va_arg(ap, int)
+ };
+ calldata = &rec;
+ break;
+ }
+ default: {
+ va_end(ap);
+ return 0; /* unimplemented hook number */
+ }
+ }
+ va_end(ap);
+
+ /* call callbacks and return result, if any. */
+ CallCallbacks(&XaceHooks[hook], calldata);
+ return prv ? *prv : 0;
+}
+
+static int
+ProcXaceDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ default:
+ return BadRequest;
+ }
+} /* ProcXaceDispatch */
+
+static int
+SProcXaceDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ default:
+ return BadRequest;
+ }
+} /* SProcXaceDispatch */
+
+
+/* XaceResetProc
+ *
+ * Arguments:
+ * extEntry is the extension information for the XACE extension.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Performs any cleanup needed by XACE at server shutdown time.
+ */
+static void
+XaceResetProc(ExtensionEntry *extEntry)
+{
+ int i;
+
+ for (i=0; i<XACE_NUM_HOOKS; i++)
+ {
+ DeleteCallbackList(&XaceHooks[i]);
+ XaceHooks[i] = NULL;
+ }
+} /* XaceResetProc */
+
+
+static int
+XaceCatchDispatchProc(ClientPtr client)
+{
+ REQUEST(xReq);
+ int major = stuff->reqType;
+
+ if (!ProcVector[major])
+ return (BadRequest);
+
+ if (!XaceHook(XACE_CORE_DISPATCH, client))
+ return (BadAccess);
+
+ return client->swapped ?
+ (* SwappedProcVector[major])(client) :
+ (* ProcVector[major])(client);
+}
+
+static int
+XaceCatchExtProc(ClientPtr client)
+{
+ REQUEST(xReq);
+ int major = stuff->reqType;
+ ExtensionEntry *ext = GetExtensionEntry(major);
+
+ if (!ext || !ProcVector[major])
+ return (BadRequest);
+
+ if (!XaceHook(XACE_EXT_DISPATCH, client, ext))
+ return (BadRequest); /* pretend extension doesn't exist */
+
+ return client->swapped ?
+ (* SwappedProcVector[major])(client) :
+ (* ProcVector[major])(client);
+}
+
+
+/* SecurityClientStateCallback
+ *
+ * Arguments:
+ * pcbl is &ClientStateCallback.
+ * nullata is NULL.
+ * calldata is a pointer to a NewClientInfoRec (include/dixstruct.h)
+ * which contains information about client state changes.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *
+ * 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 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
+XaceClientStateCallback(
+ CallbackListPtr *pcbl,
+ pointer nulldata,
+ pointer calldata)
+{
+ NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
+ ClientPtr client = pci->client;
+
+ switch (client->clientState)
+ {
+ case ClientStateRunning:
+ {
+ client->requestVector = client->swapped ?
+ SwappedUntrustedProcVector : UntrustedProcVector;
+ break;
+ }
+ default: break;
+ }
+} /* XaceClientStateCallback */
+
+/* XaceExtensionInit
+ *
+ * Initialize the XACE Extension
+ */
+void XaceExtensionInit(INITARGS)
+{
+ ExtensionEntry *extEntry;
+ int i;
+
+ if (!AddCallback(&ClientStateCallback, XaceClientStateCallback, NULL))
+ return;
+
+ extEntry = AddExtension(XACE_EXTENSION_NAME,
+ XaceNumberEvents, XaceNumberErrors,
+ ProcXaceDispatch, SProcXaceDispatch,
+ XaceResetProc, StandardMinorOpcode);
+
+ /* initialize dispatching intercept functions */
+ for (i = 0; i < 128; i++)
+ {
+ UntrustedProcVector[i] = XaceCatchDispatchProc;
+ SwappedUntrustedProcVector[i] = XaceCatchDispatchProc;
+ }
+ for (i = 128; i < 256; i++)
+ {
+ UntrustedProcVector[i] = XaceCatchExtProc;
+ SwappedUntrustedProcVector[i] = XaceCatchExtProc;
+ }
+}
+
+/* XaceCensorImage
+ *
+ * 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
+XaceCensorImage(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);
+} /* XaceCensorImage */
diff --git a/Xext/xace.h b/Xext/xace.h
new file mode 100644
index 000000000..6cb4b4f5d
--- /dev/null
+++ b/Xext/xace.h
@@ -0,0 +1,103 @@
+/************************************************************
+
+Author: Eamon Walsh <ewalsh@epoch.ncsc.mil>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+this permission notice appear in supporting documentation. This permission
+notice shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+********************************************************/
+
+#ifndef _XACE_H
+#define _XACE_H
+
+#define XACE_EXTENSION_NAME "XAccessControlExtension"
+#define XACE_MAJOR_VERSION 1
+#define XACE_MINOR_VERSION 0
+
+#include "pixmap.h" /* for DrawablePtr */
+#include "regionstr.h" /* for RegionPtr */
+
+#define XaceNumberEvents 0
+#define XaceNumberErrors 0
+
+/* security hooks */
+/* Constants used to identify the available security hooks
+ */
+#define XACE_CORE_DISPATCH 0
+#define XACE_EXT_DISPATCH 1
+#define XACE_RESOURCE_ACCESS 2
+#define XACE_DEVICE_ACCESS 3
+#define XACE_PROPERTY_ACCESS 4
+#define XACE_DRAWABLE_ACCESS 5
+#define XACE_MAP_ACCESS 6
+#define XACE_BACKGRND_ACCESS 7
+#define XACE_EXT_ACCESS 8
+#define XACE_HOSTLIST_ACCESS 9
+#define XACE_SITE_POLICY 10
+#define XACE_DECLARE_EXT_SECURE 11
+#define XACE_AUTH_AVAIL 12
+#define XACE_KEY_AVAIL 13
+#define XACE_WINDOW_INIT 14
+#define XACE_AUDIT_BEGIN 15
+#define XACE_AUDIT_END 16
+#define XACE_NUM_HOOKS 17
+
+extern CallbackListPtr XaceHooks[XACE_NUM_HOOKS];
+
+/* Entry point for hook functions. Called by Xserver.
+ */
+extern int XaceHook(
+ int /*hook*/,
+ ... /*appropriate args for hook*/
+ );
+
+/* Register a callback for a given hook.
+ */
+#define XaceRegisterCallback(hook,callback,data) \
+ AddCallback(XaceHooks+(hook), callback, data)
+
+/* Unregister an existing callback for a given hook.
+ */
+#define XaceDeleteCallback(hook,callback,data) \
+ DeleteCallback(XaceHooks+(hook), callback, data)
+
+
+/* From the original Security extension...
+ */
+
+/* Hook return codes */
+#define SecurityAllowOperation 0
+#define SecurityIgnoreOperation 1
+#define SecurityErrorOperation 2
+
+/* 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.
+ */
+extern int (*UntrustedProcVector[256])(ClientPtr client);
+extern int (*SwappedUntrustedProcVector[256])(ClientPtr client);
+
+extern void XaceCensorImage(
+ ClientPtr client,
+ RegionPtr pVisibleRegion,
+ long widthBytesLine,
+ DrawablePtr pDraw,
+ int x, int y, int w, int h,
+ unsigned int format,
+ char * pBuf
+ );
+
+#endif /* _XACE_H */
diff --git a/Xext/xacestr.h b/Xext/xacestr.h
new file mode 100644
index 000000000..7114d066b
--- /dev/null
+++ b/Xext/xacestr.h
@@ -0,0 +1,135 @@
+/************************************************************
+
+Author: Eamon Walsh <ewalsh@epoch.ncsc.mil>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+this permission notice appear in supporting documentation. This permission
+notice shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+********************************************************/
+
+#ifndef _XACESTR_H
+#define _XACESTR_H
+
+#include <X11/Xdefs.h>
+#include "dixstruct.h"
+#include "resource.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "inputstr.h"
+#include "xace.h"
+
+/* XACE_CORE_DISPATCH */
+typedef struct {
+ ClientPtr client;
+ int rval;
+} XaceCoreDispatchRec;
+
+/* XACE_RESOURCE_ACCESS */
+/* XACE_RESOURCE_CREATE */
+typedef struct {
+ ClientPtr client;
+ XID id;
+ RESTYPE rtype;
+ Mask access_mode;
+ pointer res;
+ int rval;
+} XaceResourceAccessRec;
+
+/* XACE_DEVICE_ACCESS */
+typedef struct {
+ ClientPtr client;
+ DeviceIntPtr dev;
+ Bool fromRequest;
+ int rval;
+} XaceDeviceAccessRec;
+
+/* XACE_PROPERTY_ACCESS */
+typedef struct {
+ ClientPtr client;
+ WindowPtr pWin;
+ Atom propertyName;
+ Mask access_mode;
+ int rval;
+} XacePropertyAccessRec;
+
+/* XACE_DRAWABLE_ACCESS */
+typedef struct {
+ ClientPtr client;
+ DrawablePtr pDraw;
+ int rval;
+} XaceDrawableAccessRec;
+
+/* XACE_MAP_ACCESS */
+/* XACE_BACKGRND_ACCESS */
+typedef struct {
+ ClientPtr client;
+ WindowPtr pWin;
+ int rval;
+} XaceMapAccessRec;
+
+/* XACE_EXT_DISPATCH_ACCESS */
+/* XACE_EXT_ACCESS */
+typedef struct {
+ ClientPtr client;
+ ExtensionEntry *ext;
+ int rval;
+} XaceExtAccessRec;
+
+/* XACE_HOSTLIST_ACCESS */
+typedef struct {
+ ClientPtr client;
+ Mask access_mode;
+ int rval;
+} XaceHostlistAccessRec;
+
+/* XACE_SITE_POLICY */
+typedef struct {
+ char *policyString;
+ int len;
+ int rval;
+} XaceSitePolicyRec;
+
+/* XACE_DECLARE_EXT_SECURE */
+typedef struct {
+ ExtensionEntry *ext;
+ Bool secure;
+} XaceDeclareExtSecureRec;
+
+/* XACE_AUTH_AVAIL */
+typedef struct {
+ ClientPtr client;
+ XID authId;
+} XaceAuthAvailRec;
+
+/* XACE_KEY_AVAIL */
+typedef struct {
+ xEventPtr event;
+ DeviceIntPtr keybd;
+ int count;
+} XaceKeyAvailRec;
+
+/* XACE_WINDOW_INIT */
+typedef struct {
+ ClientPtr client;
+ WindowPtr pWin;
+} XaceWindowRec;
+
+/* XACE_AUDIT_BEGIN */
+/* XACE_AUDIT_END */
+typedef struct {
+ ClientPtr client;
+ int requestResult;
+} XaceAuditRec;
+
+#endif /* _XACESTR_H */
diff --git a/configure.ac b/configure.ac
index 798c8f0da..49dfad2d3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -413,11 +413,12 @@ AC_ARG_ENABLE(dri, AS_HELP_STRING([--enable-dri], [Build DRI extensio
AC_ARG_ENABLE(xinerama, AS_HELP_STRING([--disable-xinerama], [Build Xinerama extension (default: enabled)]), [XINERAMA=$enableval], [XINERAMA=yes])
AC_ARG_ENABLE(xf86vidmode, AS_HELP_STRING([--disable-xf86vidmode], [Build XF86VidMode extension (default: enabled)]), [XF86VIDMODE=$enableval], [XF86VIDMODE=yes])
AC_ARG_ENABLE(xf86misc, AS_HELP_STRING([--disable-xf86misc], [Build XF86Misc extension (default: enabled)]), [XF86MISC=$enableval], [XF86MISC=yes])
-AC_ARG_ENABLE(xcsecurity, AS_HELP_STRING([--disable-xcsecurity], [Build Security extension (default: enabled)]), [XCSECURITY=$enableval], [XCSECURITY=yes])
+AC_ARG_ENABLE(xace, AS_HELP_STRING([--disable-xace], [Build X-ACE extension (default: enabled)]), [XACE=$enableval], [XACE=yes])
+AC_ARG_ENABLE(xcsecurity, AS_HELP_STRING([--disable-xcsecurity], [Build Security extension (default: enabled)]), [XCSECURITY=$enableval], [XCSECURITY=$XACE])
+AC_ARG_ENABLE(appgroup, AS_HELP_STRING([--disable-appgroup], [Build XC-APPGROUP extension (default: enabled)]), [APPGROUP=$enableval], [APPGROUP=$XCSECURITY])
AC_ARG_ENABLE(xcalibrate, AS_HELP_STRING([--enable-xcalibrate], [Build XCalibrate extension (default: disabled)]), [XCALIBRATE=$enableval], [XCALIBRATE=no])
AC_ARG_ENABLE(tslib, AS_HELP_STRING([--enable-tslib], [Build kdrive tslib touchscreen support (default: disabled)]), [TSLIB=$enableval], [TSLIB=no])
AC_ARG_ENABLE(xevie, AS_HELP_STRING([--disable-xevie], [Build XEvIE extension (default: enabled)]), [XEVIE=$enableval], [XEVIE=yes])
-AC_ARG_ENABLE(appgroup, AS_HELP_STRING([--disable-appgroup], [Build XC-APPGROUP extension (default: enabled)]), [APPGROUP=$enableval], [APPGROUP=yes])
AC_ARG_ENABLE(cup, AS_HELP_STRING([--disable-cup], [Build TOG-CUP extension (default: enabled)]), [CUP=$enableval], [CUP=yes])
AC_ARG_ENABLE(evi, AS_HELP_STRING([--disable-evi], [Build Extended-Visual-Information extension (default: enabled)]), [EVI=$enableval], [EVI=yes])
AC_ARG_ENABLE(multibuffer, AS_HELP_STRING([--enable-multibuffer], [Build Multibuffer extension (default: disabled)]), [MULTIBUFFER=$enableval], [MULTIBUFFER=no])
@@ -621,8 +622,16 @@ if test "x$XINERAMA" = xyes; then
REQUIRED_MODULES="$REQUIRED_MODULES xineramaproto"
fi
+AM_CONDITIONAL(XACE, [test "x$XACE" = xyes])
+if test "x$XACE" = xyes; then
+ AC_DEFINE(XACE, 1, [Build X-ACE extension])
+fi
+
AM_CONDITIONAL(XCSECURITY, [test "x$XCSECURITY" = xyes])
if test "x$XCSECURITY" = xyes; then
+ if test "x$XACE" != xyes; then
+ AC_MSG_ERROR([cannot build Security extension without X-ACE])
+ fi
AC_DEFINE(XCSECURITY, 1, [Build Security extension])
fi
@@ -632,12 +641,11 @@ if test "x$XEVIE" = xyes; then
REQUIRED_MODULES="$REQUIRED_MODULES evieproto"
fi
-if test "x$APPGROUP" = xyes && test "x$XCSECURITY" != xyes; then
- AC_MSG_NOTICE([Disabling APPGROUP extension])
- APPGROUP=no
-fi
AM_CONDITIONAL(APPGROUP, [test "x$APPGROUP" = xyes])
if test "x$APPGROUP" = xyes; then
+ if test "x$XACE" != xyes || test "x$XCSECURITY" != xyes; then
+ AC_MSG_ERROR([cannot build APPGROUP extension without X-ACE and XC-SECURITY])
+ fi
AC_DEFINE(XAPPGROUP, 1, [Build APPGROUP extension])
fi
diff --git a/dix/devices.c b/dix/devices.c
index bcf8f4fa6..607510203 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -69,8 +69,8 @@ SOFTWARE.
#ifdef XKB
#include <X11/extensions/XKBsrv.h>
#endif
-#ifdef XCSECURITY
-#include "securitysrv.h"
+#ifdef XACE
+#include "xace.h"
#endif
#include "dispatch.h"
@@ -946,8 +946,8 @@ ProcSetModifierMapping(ClientPtr client)
}
}
-#ifdef XCSECURITY
- if (!SecurityCheckDeviceAccess(client, keybd, TRUE))
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, keybd, TRUE))
return BadAccess;
#endif
@@ -1063,9 +1063,8 @@ ProcChangeKeyboardMapping(ClientPtr client)
client->errorValue = stuff->keySymsPerKeyCode;
return BadValue;
}
-#ifdef XCSECURITY
- if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard,
- TRUE))
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
return BadAccess;
#endif
keysyms.minKeyCode = stuff->firstKeyCode;
@@ -1211,8 +1210,8 @@ ProcChangeKeyboardControl (ClientPtr client)
vmask = stuff->mask;
if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask))
return BadLength;
-#ifdef XCSECURITY
- if (!SecurityCheckDeviceAccess(client, keybd, TRUE))
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, keybd, TRUE))
return BadAccess;
#endif
vlist = (XID *)&stuff[1]; /* first word of values */
@@ -1600,8 +1599,8 @@ ProcQueryKeymap(ClientPtr client)
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 2;
-#ifdef XCSECURITY
- if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
{
bzero((char *)&rep.map[0], 32);
}
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 08b015991..7c4d539fa 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -104,8 +104,8 @@ int ProcInitialConnection();
#include "panoramiX.h"
#include "panoramiXsrv.h"
#endif
-#ifdef XCSECURITY
-#include "securitysrv.h"
+#ifdef XACE
+#include "xace.h"
#endif
#ifdef XAPPGROUP
#include "appgroup.h"
@@ -451,7 +451,15 @@ Dispatch(void)
if (result > (maxBigRequestSize << 2))
result = BadLength;
else
+#ifdef XACE
+ {
+ XaceHook(XACE_AUDIT_BEGIN, client);
result = (* client->requestVector[MAJOROP])(client);
+ XaceHook(XACE_AUDIT_END, client, result);
+ }
+#else
+ result = (* client->requestVector[MAJOROP])(client);
+#endif /* XACE */
if (result != Success)
{
@@ -1099,11 +1107,10 @@ ProcConvertSelection(register ClientPtr client)
CurrentSelections[i].selection != stuff->selection) i++;
if ((i < NumCurrentSelections) &&
(CurrentSelections[i].window != None)
-#ifdef XCSECURITY
- && (!client->CheckAccess ||
- (* client->CheckAccess)(client, CurrentSelections[i].window,
- RT_WINDOW, SecurityReadAccess,
- CurrentSelections[i].pWin))
+#ifdef XACE
+ && XaceHook(XACE_RESOURCE_ACCESS, client,
+ CurrentSelections[i].window, RT_WINDOW,
+ SecurityReadAccess, CurrentSelections[i].pWin)
#endif
)
{
@@ -2095,7 +2102,7 @@ DoGetImage(register ClientPtr client, int format, Drawable drawable,
Mask plane = 0;
char *pBuf;
xGetImageReply xgi;
-#ifdef XCSECURITY
+#ifdef XACE
RegionPtr pVisibleRegion = NULL;
#endif
@@ -2201,9 +2208,9 @@ DoGetImage(register ClientPtr client, int format, Drawable drawable,
WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
}
-#ifdef XCSECURITY
- if (client->trustLevel != XSecurityClientTrusted &&
- pDraw->type == DRAWABLE_WINDOW)
+#ifdef XACE
+ if (pDraw->type == DRAWABLE_WINDOW &&
+ !XaceHook(XACE_DRAWABLE_ACCESS, client, pDraw))
{
pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
if (pVisibleRegion)
@@ -2231,9 +2238,9 @@ DoGetImage(register ClientPtr client, int format, Drawable drawable,
format,
planemask,
(pointer) pBuf);
-#ifdef XCSECURITY
+#ifdef XACE
if (pVisibleRegion)
- SecurityCensorImage(client, pVisibleRegion, widthBytesLine,
+ XaceCensorImage(client, pVisibleRegion, widthBytesLine,
pDraw, x, y + linesDone, width,
nlines, format, pBuf);
#endif
@@ -2272,9 +2279,9 @@ DoGetImage(register ClientPtr client, int format, Drawable drawable,
format,
plane,
(pointer)pBuf);
-#ifdef XCSECURITY
+#ifdef XACE
if (pVisibleRegion)
- SecurityCensorImage(client, pVisibleRegion,
+ XaceCensorImage(client, pVisibleRegion,
widthBytesLine,
pDraw, x, y + linesDone, width,
nlines, format, pBuf);
@@ -2300,7 +2307,7 @@ DoGetImage(register ClientPtr client, int format, Drawable drawable,
}
}
}
-#ifdef XCSECURITY
+#ifdef XACE
if (pVisibleRegion)
REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
#endif
@@ -3274,11 +3281,10 @@ ProcListHosts(register ClientPtr client)
/* REQUEST(xListHostsReq); */
REQUEST_SIZE_MATCH(xListHostsReq);
-#ifdef XCSECURITY
+#ifdef XACE
/* untrusted clients can't list hosts */
- if (client->trustLevel != XSecurityClientTrusted)
+ if (!XaceHook(XACE_HOSTLIST_ACCESS, client, SecurityReadAccess))
{
- SecurityAudit("client %d attempted to list hosts\n", client->index);
return BadAccess;
}
#endif
@@ -3606,8 +3612,13 @@ CloseDownRetainedResources()
}
}
+extern int clientPrivateLen;
+extern unsigned *clientPrivateSizes;
+extern unsigned totalClientSize;
+
void InitClient(ClientPtr client, int i, pointer ospriv)
{
+ bzero(client, totalClientSize);
client->index = i;
client->sequence = 0;
client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
@@ -3646,11 +3657,6 @@ void InitClient(ClientPtr client, int i, pointer ospriv)
}
#endif
client->replyBytesRemaining = 0;
-#ifdef XCSECURITY
- client->trustLevel = XSecurityClientTrusted;
- client->CheckAccess = NULL;
- client->authId = 0;
-#endif
#ifdef XAPPGROUP
client->appgroup = NULL;
#endif
@@ -3663,10 +3669,6 @@ void InitClient(ClientPtr client, int i, pointer ospriv)
#endif
}
-extern int clientPrivateLen;
-extern unsigned *clientPrivateSizes;
-extern unsigned totalClientSize;
-
int
InitClientPrivates(ClientPtr client)
{
@@ -3699,6 +3701,17 @@ InitClientPrivates(ClientPtr client)
else
ppriv->ptr = (pointer)NULL;
}
+
+ /* Allow registrants to initialize the serverClient devPrivates */
+ if (!client->index && ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
return 1;
}
diff --git a/dix/dixutils.c b/dix/dixutils.c
index b35754dbb..a395d4474 100644
--- a/dix/dixutils.c
+++ b/dix/dixutils.c
@@ -95,8 +95,8 @@ Author: Adobe Systems Incorporated
#include "scrnintstr.h"
#define XK_LATIN1
#include <X11/keysymdef.h>
-#ifdef XCSECURITY
-#include "securitysrv.h"
+#ifdef XACE
+#include "xace.h"
#endif
/*
@@ -196,7 +196,7 @@ CompareISOLatin1Lowered(unsigned char *s1, int s1len,
return (int) c1 - (int) c2;
}
-#ifdef XCSECURITY
+#ifdef XACE
/* SecurityLookupWindow and SecurityLookupDrawable:
* Look up the window/drawable taking into account the client doing
@@ -204,32 +204,16 @@ CompareISOLatin1Lowered(unsigned char *s1, int s1len,
* if it exists and the client is allowed access, else return NULL.
* Most Proc* functions should be calling these instead of
* LookupWindow and LookupDrawable, which do no access checks.
+ * XACE note: need to see if client->lastDrawableID can still be used here.
*/
_X_EXPORT WindowPtr
SecurityLookupWindow(XID rid, ClientPtr client, Mask access_mode)
{
- WindowPtr pWin;
-
client->errorValue = rid;
if(rid == INVALID)
return NULL;
- if (client->trustLevel != XSecurityClientTrusted)
- return (WindowPtr)SecurityLookupIDByType(client, rid, RT_WINDOW, access_mode);
- if (client->lastDrawableID == rid)
- {
- if (client->lastDrawable->type == DRAWABLE_WINDOW)
- return ((WindowPtr) client->lastDrawable);
- return (WindowPtr) NULL;
- }
- pWin = (WindowPtr)SecurityLookupIDByType(client, rid, RT_WINDOW, access_mode);
- if (pWin && pWin->drawable.type == DRAWABLE_WINDOW) {
- client->lastDrawable = (DrawablePtr) pWin;
- client->lastDrawableID = rid;
- client->lastGCID = INVALID;
- client->lastGC = (GCPtr)NULL;
- }
- return pWin;
+ return (WindowPtr)SecurityLookupIDByType(client, rid, RT_WINDOW, access_mode);
}
@@ -240,11 +224,6 @@ SecurityLookupDrawable(XID rid, ClientPtr client, Mask access_mode)
if(rid == INVALID)
return (pointer) NULL;
- if (client->trustLevel != XSecurityClientTrusted)
- return (DrawablePtr)SecurityLookupIDByClass(client, rid, RC_DRAWABLE,
- access_mode);
- if (client->lastDrawableID == rid)
- return ((pointer) client->lastDrawable);
pDraw = (DrawablePtr)SecurityLookupIDByClass(client, rid, RC_DRAWABLE,
access_mode);
if (pDraw && (pDraw->type != UNDRAWABLE_WINDOW))
@@ -268,7 +247,7 @@ LookupDrawable(XID rid, ClientPtr client)
return SecurityLookupDrawable(rid, client, SecurityUnknownAccess);
}
-#else /* not XCSECURITY */
+#else /* not XACE */
WindowPtr
LookupWindow(XID rid, ClientPtr client)
@@ -310,7 +289,7 @@ LookupDrawable(XID rid, ClientPtr client)
return (pointer)NULL;
}
-#endif /* XCSECURITY */
+#endif /* XACE */
_X_EXPORT ClientPtr
LookupClient(XID rid, ClientPtr client)
diff --git a/dix/events.c b/dix/events.c
index 7225543a3..c57a30ed8 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -135,8 +135,8 @@ of the copyright holder.
extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
#endif
-#ifdef XCSECURITY
-#include "securitysrv.h"
+#ifdef XACE
+#include "xace.h"
#endif
#ifdef XEVIE
@@ -2476,8 +2476,8 @@ CheckPassiveGrabsOnWindow(
(grab->confineTo->realized &&
BorderSizeNotEmpty(grab->confineTo))))
{
-#ifdef XCSECURITY
- if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, wClient(pWin), device, FALSE))
return FALSE;
#endif
#ifdef XKB
@@ -2846,6 +2846,10 @@ drawable.id:0;
DeliverFocusedEvent(keybd, xE, sprite.win, count);
if (deactivateGrab)
(*keybd->DeactivateGrab)(keybd);
+
+#ifdef XACE
+ XaceHook(XACE_KEY_AVAIL, xE, keybd, count);
+#endif
}
#ifdef XKB
@@ -3279,10 +3283,10 @@ EnterLeaveEvent(
{
xKeymapEvent ke;
-#ifdef XCSECURITY
+#ifdef XACE
ClientPtr client = grab ? rClient(grab)
: clients[CLIENT_ID(pWin->drawable.id)];
- if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, keybd, FALSE))
{
bzero((char *)&ke.map[0], 31);
}
@@ -3374,9 +3378,9 @@ FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr
((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
{
xKeymapEvent ke;
-#ifdef XCSECURITY
+#ifdef XACE
ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
- if (!SecurityCheckDeviceAccess(client, dev, FALSE))
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, dev, FALSE))
{
bzero((char *)&ke.map[0], 31);
}
@@ -3645,8 +3649,8 @@ ProcSetInputFocus(client)
REQUEST(xSetInputFocusReq);
REQUEST_SIZE_MATCH(xSetInputFocusReq);
-#ifdef XCSECURITY
- if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
return Success;
#endif
return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
@@ -3910,8 +3914,8 @@ ProcGrabKeyboard(ClientPtr client)
int result;
REQUEST_SIZE_MATCH(xGrabKeyboardReq);
-#ifdef XCSECURITY
- if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+#ifdef XACE
+ if (!XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
{
result = Success;
rep.status = AlreadyGrabbed;
diff --git a/dix/extension.c b/dix/extension.c
index 5ad457940..f58c73138 100644
--- a/dix/extension.c
+++ b/dix/extension.c
@@ -59,8 +59,8 @@ SOFTWARE.
#include "gcstruct.h"
#include "scrnintstr.h"
#include "dispatch.h"
-#ifdef XCSECURITY
-#include "securitysrv.h"
+#ifdef XACE
+#include "xace.h"
#endif
#define EXTENSION_BASE 128
@@ -76,6 +76,39 @@ int lastEvent = EXTENSION_EVENT_BASE;
static int lastError = FirstExtensionError;
static unsigned int NumExtensions = 0;
+extern int extensionPrivateLen;
+extern unsigned *extensionPrivateSizes;
+extern unsigned totalExtensionSize;
+
+static void
+InitExtensionPrivates(ExtensionEntry *ext)
+{
+ register char *ptr;
+ DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ if (totalExtensionSize == sizeof(ExtensionEntry))
+ ppriv = (DevUnion *)NULL;
+ else
+ ppriv = (DevUnion *)(ext + 1);
+
+ ext->devPrivates = ppriv;
+ sizes = extensionPrivateSizes;
+ ptr = (char *)(ppriv + extensionPrivateLen);
+ for (i = extensionPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+}
+
_X_EXPORT ExtensionEntry *
AddExtension(char *name, int NumEvents, int NumErrors,
int (*MainProc)(ClientPtr c1),
@@ -92,9 +125,11 @@ AddExtension(char *name, int NumEvents, int NumErrors,
(unsigned)(lastError + NumErrors > LAST_ERROR))
return((ExtensionEntry *) NULL);
- ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
+ ext = (ExtensionEntry *) xalloc(totalExtensionSize);
if (!ext)
return((ExtensionEntry *) NULL);
+ bzero(ext, totalExtensionSize);
+ InitExtensionPrivates(ext);
ext->name = (char *)xalloc(strlen(name) + 1);
ext->num_aliases = 0;
ext->aliases = (char **)NULL;
@@ -144,9 +179,6 @@ AddExtension(char *name, int NumEvents, int NumErrors,
ext->errorBase = 0;
ext->errorLast = 0;
}
-#ifdef XCSECURITY
- ext->secure = FALSE;
-#endif
return(ext);
}
@@ -207,26 +239,27 @@ CheckExtension(const char *extname)
return NULL;
}
+/*
+ * Added as part of Xace.
+ */
+ExtensionEntry *
+GetExtensionEntry(int major)
+{
+ if (major < EXTENSION_BASE)
+ return NULL;
+ major -= EXTENSION_BASE;
+ if (major >= NumExtensions)
+ return NULL;
+ return extensions[major];
+}
+
_X_EXPORT void
DeclareExtensionSecurity(char *extname, Bool secure)
{
-#ifdef XCSECURITY
+#ifdef XACE
int i = FindExtension(extname, strlen(extname));
if (i >= 0)
- {
- int majorop = extensions[i]->base;
- extensions[i]->secure = secure;
- if (secure)
- {
- UntrustedProcVector[majorop] = ProcVector[majorop];
- SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
- }
- else
- {
- UntrustedProcVector[majorop] = ProcBadRequest;
- SwappedUntrustedProcVector[majorop] = ProcBadRequest;
- }
- }
+ XaceHook(XACE_DECLARE_EXT_SECURE, extensions[i], secure);
#endif
}
@@ -304,10 +337,9 @@ ProcQueryExtension(ClientPtr client)
{
i = FindExtension((char *)&stuff[1], stuff->nbytes);
if (i < 0
-#ifdef XCSECURITY
- /* don't show insecure extensions to untrusted clients */
- || (client->trustLevel == XSecurityClientUntrusted &&
- !extensions[i]->secure)
+#ifdef XACE
+ /* call callbacks to find out whether to show extension */
+ || !XaceHook(XACE_EXT_ACCESS, client, extensions[i])
#endif
)
reply.present = xFalse;
@@ -344,10 +376,9 @@ ProcListExtensions(ClientPtr client)
for (i=0; i<NumExtensions; i++)
{
-#ifdef XCSECURITY
- /* don't show insecure extensions to untrusted clients */
- if (client->trustLevel == XSecurityClientUntrusted &&
- !extensions[i]->secure)
+#ifdef XACE
+ /* call callbacks to find out whether to show extension */
+ if (!XaceHook(XACE_EXT_ACCESS, client, extensions[i]))
continue;
#endif
total_length += strlen(extensions[i]->name) + 1;
@@ -362,9 +393,8 @@ ProcListExtensions(ClientPtr client)
for (i=0; i<NumExtensions; i++)
{
int len;
-#ifdef XCSECURITY
- if (client->trustLevel == XSecurityClientUntrusted &&
- !extensions[i]->secure)
+#ifdef XACE
+ if (!XaceHook(XACE_EXT_ACCESS, client, extensions[i]))
continue;
#endif
*bufptr++ = len = strlen(extensions[i]->name);
diff --git a/dix/main.c b/dix/main.c
index 3fb4cdd9c..f3cde189c 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -354,6 +354,7 @@ main(int argc, char *argv[], char *envp[])
InitAtoms();
InitEvents();
InitGlyphCaching();
+ ResetExtensionPrivates();
ResetClientPrivates();
ResetScreenPrivates();
ResetWindowPrivates();
diff --git a/dix/privates.c b/dix/privates.c
index 46b696416..b20a1dbf0 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -42,6 +42,7 @@ from The Open Group.
#include "servermd.h"
#include "site.h"
#include "inputstr.h"
+#include "extnsionst.h"
/*
* See the Wrappers and devPrivates section in "Definition of the
@@ -50,6 +51,63 @@ from The Open Group.
*/
/*
+ * extension private machinery
+ */
+
+static int extensionPrivateCount;
+int extensionPrivateLen;
+unsigned *extensionPrivateSizes;
+unsigned totalExtensionSize;
+
+void
+ResetExtensionPrivates()
+{
+ extensionPrivateCount = 0;
+ extensionPrivateLen = 0;
+ xfree(extensionPrivateSizes);
+ extensionPrivateSizes = (unsigned *)NULL;
+ totalExtensionSize =
+ ((sizeof(ExtensionEntry) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
+}
+
+_X_EXPORT int
+AllocateExtensionPrivateIndex()
+{
+ return extensionPrivateCount++;
+}
+
+_X_EXPORT Bool
+AllocateExtensionPrivate(int index2, unsigned amount)
+{
+ unsigned oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= extensionPrivateLen)
+ {
+ unsigned *nsizes;
+ nsizes = (unsigned *)xrealloc(extensionPrivateSizes,
+ (index2 + 1) * sizeof(unsigned));
+ if (!nsizes)
+ return FALSE;
+ while (extensionPrivateLen <= index2)
+ {
+ nsizes[extensionPrivateLen++] = 0;
+ totalExtensionSize += sizeof(DevUnion);
+ }
+ extensionPrivateSizes = nsizes;
+ }
+ oldamount = extensionPrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ extensionPrivateSizes[index2] = amount;
+ totalExtensionSize += (amount - oldamount);
+ }
+ return TRUE;
+}
+
+/*
* client private machinery
*/
diff --git a/dix/property.c b/dix/property.c
index 5588a90b0..da983838f 100644
--- a/dix/property.c
+++ b/dix/property.c
@@ -58,8 +58,8 @@ SOFTWARE.
#include "dixstruct.h"
#include "dispatch.h"
#include "swaprep.h"
-#ifdef XCSECURITY
-#include "securitysrv.h"
+#ifdef XACE
+#include "xace.h"
#endif
/*****************************************************************
@@ -118,12 +118,12 @@ ProcRotateProperties(ClientPtr client)
return(BadAlloc);
for (i = 0; i < stuff->nAtoms; i++)
{
-#ifdef XCSECURITY
- char action = SecurityCheckPropertyAccess(client, pWin, atoms[i],
+#ifdef XACE
+ char action = XaceHook(XACE_PROPERTY_ACCESS, client, pWin, atoms[i],
SecurityReadAccess|SecurityWriteAccess);
#endif
if (!ValidAtom(atoms[i])
-#ifdef XCSECURITY
+#ifdef XACE
|| (SecurityErrorOperation == action)
#endif
)
@@ -132,7 +132,7 @@ ProcRotateProperties(ClientPtr client)
client->errorValue = atoms[i];
return BadAtom;
}
-#ifdef XCSECURITY
+#ifdef XACE
if (SecurityIgnoreOperation == action)
{
DEALLOCATE_LOCAL(props);
@@ -233,8 +233,8 @@ ProcChangeProperty(ClientPtr client)
return(BadAtom);
}
-#ifdef XCSECURITY
- switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+#ifdef XACE
+ switch (XaceHook(XACE_PROPERTY_ACCESS, client, pWin, stuff->property,
SecurityWriteAccess))
{
case SecurityErrorOperation:
@@ -501,13 +501,13 @@ ProcGetProperty(ClientPtr client)
if (!pProp)
return NullPropertyReply(client, None, 0, &reply);
-#ifdef XCSECURITY
+#ifdef XACE
{
Mask access_mode = SecurityReadAccess;
if (stuff->delete)
access_mode |= SecurityDestroyAccess;
- switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ switch(XaceHook(XACE_PROPERTY_ACCESS, client, pWin, stuff->property,
access_mode))
{
case SecurityErrorOperation:
@@ -663,8 +663,8 @@ ProcDeleteProperty(register ClientPtr client)
return (BadAtom);
}
-#ifdef XCSECURITY
- switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+#ifdef XACE
+ switch(XaceHook(XACE_PROPERTY_ACCESS, client, pWin, stuff->property,
SecurityDestroyAccess))
{
case SecurityErrorOperation:
diff --git a/dix/resource.c b/dix/resource.c
index 39374cc8d..b2d01c8f3 100644
--- a/dix/resource.c
+++ b/dix/resource.c
@@ -120,6 +120,9 @@ Equipment Corporation.
#include "panoramiX.h"
#include "panoramiXsrv.h"
#endif
+#ifdef XACE
+#include "xace.h"
+#endif
#include <assert.h>
static void RebuildTable(
@@ -818,8 +821,6 @@ LegalNewID(XID id, register ClientPtr client)
!LookupIDByClass(id, RC_ANY)));
}
-#ifdef XCSECURITY
-
/* SecurityLookupIDByType and SecurityLookupIDByClass:
* These are the heart of the resource ID security system. They take
* two additional arguments compared to the old LookupID functions:
@@ -835,10 +836,6 @@ SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
register ResourcePtr res;
pointer retval = NULL;
- assert(client == NullClient ||
- (client->index <= currentMaxClients && clients[client->index] == client));
- assert( (rtype & TypeMask) <= lastResourceType);
-
if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
clientTable[cid].buckets)
{
@@ -851,8 +848,11 @@ SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
break;
}
}
- if (retval && client && client->CheckAccess)
- retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
+#ifdef XACE
+ if (retval && client &&
+ !XaceHook(XACE_RESOURCE_ACCESS, client, id, rtype, mode, retval))
+ retval = NULL;
+#endif
return retval;
}
@@ -864,10 +864,6 @@ SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
register ResourcePtr res = NULL;
pointer retval = NULL;
- assert(client == NullClient ||
- (client->index <= currentMaxClients && clients[client->index] == client));
- assert (classes >= lastResourceClass);
-
if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
clientTable[cid].buckets)
{
@@ -880,8 +876,11 @@ SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
break;
}
}
- if (retval && client && client->CheckAccess)
- retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
+#ifdef XACE
+ if (retval && client &&
+ !XaceHook(XACE_RESOURCE_ACCESS, client, id, res->type, mode, retval))
+ retval = NULL;
+#endif
return retval;
}
@@ -902,50 +901,3 @@ LookupIDByClass(XID id, RESTYPE classes)
return SecurityLookupIDByClass(NullClient, id, classes,
SecurityUnknownAccess);
}
-
-#else /* not XCSECURITY */
-
-/*
- * LookupIDByType returns the object with the given id and type, else NULL.
- */
-pointer
-LookupIDByType(XID id, RESTYPE rtype)
-{
- int cid;
- register ResourcePtr res;
-
- if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
- clientTable[cid].buckets)
- {
- res = clientTable[cid].resources[Hash(cid, id)];
-
- for (; res; res = res->next)
- if ((res->id == id) && (res->type == rtype))
- return res->value;
- }
- return (pointer)NULL;
-}
-
-/*
- * LookupIDByClass returns the object with the given id and any one of the
- * given classes, else NULL.
- */
-pointer
-LookupIDByClass(XID id, RESTYPE classes)
-{
- int cid;
- register ResourcePtr res;
-
- if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
- clientTable[cid].buckets)
- {
- res = clientTable[cid].resources[Hash(cid, id)];
-
- for (; res; res = res->next)
- if ((res->id == id) && (res->type & classes))
- return res->value;
- }
- return (pointer)NULL;
-}
-
-#endif /* XCSECURITY */
diff --git a/dix/window.c b/dix/window.c
index 0beeb3a4d..3dfeda36e 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -126,8 +126,8 @@ Equipment Corporation.
#ifdef XAPPGROUP
#include "appgroup.h"
#endif
-#ifdef XCSECURITY
-#include "securitysrv.h"
+#ifdef XACE
+#include "xace.h"
#endif
/******
@@ -530,6 +530,10 @@ InitRootWindow(WindowPtr pWin)
/* We SHOULD check for an error value here XXX */
(*pScreen->ChangeWindowAttributes)(pWin, backFlag);
+#ifdef XACE
+ XaceHook(XACE_WINDOW_INIT, serverClient, pWin);
+#endif
+
MapWindow(pWin, serverClient);
}
@@ -731,11 +735,11 @@ CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
}
pWin->borderWidth = bw;
-#ifdef XCSECURITY
+#ifdef XACE
/* can't let untrusted clients have background None windows;
* they make it too easy to steal window contents
*/
- if (client->trustLevel != XSecurityClientTrusted)
+ if (!XaceHook(XACE_BACKGRND_ACCESS, client, pWin))
{
pWin->backgroundState = BackgroundPixel;
pWin->background.pixel = 0;
@@ -762,6 +766,10 @@ CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
REGION_NULL(pScreen, &pWin->winSize);
REGION_NULL(pScreen, &pWin->borderSize);
+#ifdef XACE
+ XaceHook(XACE_WINDOW_INIT, client, pWin);
+#endif
+
pHead = RealChildHead(pParent);
if (pHead)
{
@@ -1025,9 +1033,9 @@ ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPt
borderRelative = TRUE;
if (pixID == None)
{
-#ifdef XCSECURITY
+#ifdef XACE
/* can't let untrusted clients have background None windows */
- if (client->trustLevel == XSecurityClientTrusted)
+ if (XaceHook(XACE_BACKGRND_ACCESS, client, pWin))
{
#endif
if (pWin->backgroundState == BackgroundPixmap)
@@ -1036,7 +1044,7 @@ ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPt
MakeRootTile(pWin);
else
pWin->backgroundState = None;
-#ifdef XCSECURITY
+#ifdef XACE
}
else
{ /* didn't change the background to None, so don't tell ddx */
@@ -2724,13 +2732,9 @@ MapWindow(register WindowPtr pWin, ClientPtr client)
if (pWin->mapped)
return(Success);
-#ifdef XCSECURITY
- /* don't let an untrusted client map a child-of-trusted-window, InputOnly
- * window; too easy to steal device input
- */
- if ( (client->trustLevel != XSecurityClientTrusted) &&
- (pWin->drawable.class == InputOnly) &&
- (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
+#ifdef XACE
+ /* general check for permission to map window */
+ if (!XaceHook(XACE_MAP_ACCESS, client, pWin))
return Success;
#endif
diff --git a/hw/xfree86/dixmods/extmod/modinit.h b/hw/xfree86/dixmods/extmod/modinit.h
index bb68bcb9d..41f060b2a 100644
--- a/hw/xfree86/dixmods/extmod/modinit.h
+++ b/hw/xfree86/dixmods/extmod/modinit.h
@@ -125,7 +125,12 @@ extern void ShmRegisterFuncs(
ShmFuncsPtr funcs);
#endif
+#ifdef XACE
+extern void XaceExtensionInit(INITARGS);
+#endif
+
#if 1
+extern void SecurityExtensionSetup(INITARGS);
extern void SecurityExtensionInit(INITARGS);
#endif
diff --git a/hw/xfree86/loader/dixsym.c b/hw/xfree86/loader/dixsym.c
index 22fe501f3..27a3093b1 100644
--- a/hw/xfree86/loader/dixsym.c
+++ b/hw/xfree86/loader/dixsym.c
@@ -162,7 +162,7 @@ _X_HIDDEN void *dixLookupTab[] = {
SYMFUNC(QueueWorkProc)
SYMFUNC(RegisterBlockAndWakeupHandlers)
SYMFUNC(RemoveBlockAndWakeupHandlers)
-#ifdef XCSECURITY
+#ifdef XACE
SYMFUNC(SecurityLookupDrawable)
SYMFUNC(SecurityLookupWindow)
#endif
@@ -255,6 +255,8 @@ _X_HIDDEN void *dixLookupTab[] = {
SYMFUNC(GetScratchPixmapHeader)
SYMFUNC(FreeScratchPixmapHeader)
/* privates.c */
+ SYMFUNC(AllocateExtensionPrivate)
+ SYMFUNC(AllocateExtensionPrivateIndex)
SYMFUNC(AllocateClientPrivate)
SYMFUNC(AllocateClientPrivateIndex)
SYMFUNC(AllocateGCPrivate)
@@ -282,10 +284,8 @@ _X_HIDDEN void *dixLookupTab[] = {
SYMFUNC(LookupIDByType)
SYMFUNC(LookupIDByClass)
SYMFUNC(LegalNewID)
-#ifdef XCSECURITY
SYMFUNC(SecurityLookupIDByClass)
SYMFUNC(SecurityLookupIDByType)
-#endif
SYMFUNC(FindClientResourcesByType)
SYMFUNC(FindAllClientResources)
SYMVAR(lastResourceType)
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 69dc674a9..571a86719 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -308,6 +308,9 @@
/* unaligned word accesses behave as expected */
#undef WORKING_UNALIGNED_INT
+/* Build X-ACE extension */
+#undef XACE
+
/* Support XCMisc extension */
#undef XCMISC
diff --git a/include/dix.h b/include/dix.h
index 99f77f404..f346b43a2 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -87,12 +87,9 @@ SOFTWARE.
((client->lastDrawableID == did) ? \
client->lastDrawable : (DrawablePtr)LookupDrawable(did, client))
-#ifdef XCSECURITY
+#ifdef XACE
#define SECURITY_VERIFY_DRAWABLE(pDraw, did, client, mode)\
- if (client->lastDrawableID == did && !client->trustLevel)\
- pDraw = client->lastDrawable;\
- else \
{\
pDraw = (DrawablePtr) SecurityLookupIDByClass(client, did, \
RC_DRAWABLE, mode);\
@@ -106,9 +103,6 @@ SOFTWARE.
}
#define SECURITY_VERIFY_GEOMETRABLE(pDraw, did, client, mode)\
- if (client->lastDrawableID == did && !client->trustLevel)\
- pDraw = client->lastDrawable;\
- else \
{\
pDraw = (DrawablePtr) SecurityLookupIDByClass(client, did, \
RC_DRAWABLE, mode);\
@@ -120,9 +114,6 @@ SOFTWARE.
}
#define SECURITY_VERIFY_GC(pGC, rid, client, mode)\
- if (client->lastGCID == rid && !client->trustLevel)\
- pGC = client->lastGC;\
- else\
pGC = (GC *) SecurityLookupIDByType(client, rid, RT_GC, mode);\
if (!pGC)\
{\
@@ -139,7 +130,7 @@ SOFTWARE.
#define VERIFY_GC(pGC, rid, client)\
SECURITY_VERIFY_GC(pGC, rid, client, SecurityUnknownAccess)
-#else /* not XCSECURITY */
+#else /* not XACE */
#define VERIFY_DRAWABLE(pDraw, did, client)\
if (client->lastDrawableID == did)\
@@ -189,7 +180,7 @@ SOFTWARE.
#define SECURITY_VERIFY_GC(pGC, rid, client, mode)\
VERIFY_GC(pGC, rid, client)
-#endif /* XCSECURITY */
+#endif /* XACE */
/*
* We think that most hardware implementations of DBE will want
@@ -384,7 +375,7 @@ extern int CompareISOLatin1Lowered(
unsigned char * /*b*/,
int blen);
-#ifdef XCSECURITY
+#ifdef XACE
extern WindowPtr SecurityLookupWindow(
XID /*rid*/,
@@ -420,7 +411,7 @@ extern pointer LookupDrawable(
#define SecurityLookupDrawable(rid, client, access_mode) \
LookupDrawable(rid, client)
-#endif /* XCSECURITY */
+#endif /* XACE */
extern ClientPtr LookupClient(
XID /*rid*/,
diff --git a/include/dixstruct.h b/include/dixstruct.h
index 9645a9be3..b5ffcca49 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -128,16 +128,6 @@ typedef struct _Client {
int requestLogIndex;
#endif
unsigned long replyBytesRemaining;
-#ifdef XCSECURITY
- XID authId;
- unsigned int trustLevel;
- pointer (* CheckAccess)(
- ClientPtr /*pClient*/,
- XID /*id*/,
- RESTYPE /*classes*/,
- Mask /*access_mode*/,
- pointer /*resourceval*/);
-#endif
#ifdef XAPPGROUP
struct _AppGroupRec* appgroup;
#endif
diff --git a/include/extension.h b/include/extension.h
index 6e6081740..74975c50b 100644
--- a/include/extension.h
+++ b/include/extension.h
@@ -58,6 +58,14 @@ extern Bool EnableDisableExtension(char *name, Bool enable);
extern void EnableDisableExtensionError(char *name, Bool enable);
+extern void ResetExtensionPrivates(void);
+
+extern int AllocateExtensionPrivateIndex(void);
+
+extern Bool AllocateExtensionPrivate(
+ int /*index*/,
+ unsigned /*amount*/);
+
extern void InitExtensions(int argc, char **argv);
extern void InitVisualWrap(void);
diff --git a/include/extnsionst.h b/include/extnsionst.h
index 8873f0cf9..38d4bd7d9 100644
--- a/include/extnsionst.h
+++ b/include/extnsionst.h
@@ -48,6 +48,7 @@ SOFTWARE.
#ifndef EXTENSIONSTRUCT_H
#define EXTENSIONSTRUCT_H
+#include "dix.h"
#include "misc.h"
#include "screenint.h"
#include "extension.h"
@@ -68,9 +69,7 @@ typedef struct _ExtensionEntry {
pointer extPrivate;
unsigned short (* MinorOpcode)( /* called for errors */
ClientPtr /* client */);
-#ifdef XCSECURITY
- Bool secure; /* extension visible to untrusted clients? */
-#endif
+ DevUnion *devPrivates;
} ExtensionEntry;
/*
@@ -127,6 +126,7 @@ extern Bool AddExtensionAlias(
ExtensionEntry * /*extension*/);
extern ExtensionEntry *CheckExtension(const char *extname);
+extern ExtensionEntry *GetExtensionEntry(int major);
extern ExtensionLookupProc LookupProc(
char* /*name*/,
diff --git a/include/resource.h b/include/resource.h
index f513141c0..fd0caaeb5 100644
--- a/include/resource.h
+++ b/include/resource.h
@@ -225,8 +225,6 @@ extern pointer LookupClientResourceComplex(
#define SecurityWriteAccess (1<<1) /* changing the object */
#define SecurityDestroyAccess (1<<2) /* destroying the object */
-#ifdef XCSECURITY
-
extern pointer SecurityLookupIDByType(
ClientPtr /*client*/,
XID /*id*/,
@@ -239,15 +237,6 @@ extern pointer SecurityLookupIDByClass(
RESTYPE /*classes*/,
Mask /*access_mode*/);
-#else /* not XCSECURITY */
-
-#define SecurityLookupIDByType(client, id, rtype, access_mode) \
- LookupIDByType(id, rtype)
-
-#define SecurityLookupIDByClass(client, id, classes, access_mode) \
- LookupIDByClass(id, classes)
-
-#endif /* XCSECURITY */
extern void GetXIDRange(
int /*client*/,
diff --git a/mi/miinitext.c b/mi/miinitext.c
index 80bacaa7a..aafd014ae 100644
--- a/mi/miinitext.c
+++ b/mi/miinitext.c
@@ -241,6 +241,9 @@ typedef void (*InitExtension)(INITARGS);
#define _XAG_SERVER_
#include <X11/extensions/Xagstr.h>
#endif
+#ifdef XACE
+#include "xace.h"
+#endif
#ifdef XCSECURITY
#include "securitysrv.h"
#include <X11/extensions/securstr.h>
@@ -311,7 +314,11 @@ extern void DbeExtensionInit(INITARGS);
#ifdef XAPPGROUP
extern void XagExtensionInit(INITARGS);
#endif
+#ifdef XACE
+extern void XaceExtensionInit(INITARGS);
+#endif
#ifdef XCSECURITY
+extern void SecurityExtensionSetup(INITARGS);
extern void SecurityExtensionInit(INITARGS);
#endif
#ifdef XPRINT
@@ -522,6 +529,9 @@ InitExtensions(argc, argv)
int argc;
char *argv[];
{
+#ifdef XCSECURITY
+ SecurityExtensionSetup();
+#endif
#ifdef PANORAMIX
# if !defined(PRINT_ONLY_SERVER) && !defined(NO_PANORAMIX)
if (!noPanoramiXExtension) PanoramiXExtensionInit();
@@ -584,6 +594,9 @@ InitExtensions(argc, argv)
#ifdef XAPPGROUP
if (!noXagExtension) XagExtensionInit();
#endif
+#ifdef XACE
+ XaceExtensionInit();
+#endif
#ifdef XCSECURITY
if (!noSecurityExtension) SecurityExtensionInit();
#endif
@@ -686,8 +699,11 @@ static ExtensionModule staticExtensions[] = {
#ifdef XAPPGROUP
{ XagExtensionInit, XAGNAME, &noXagExtension, NULL, NULL },
#endif
+#ifdef XACE
+ { XaceExtensionInit, XACE_EXTENSION_NAME, NULL, NULL, NULL },
+#endif
#ifdef XCSECURITY
- { SecurityExtensionInit, SECURITY_EXTENSION_NAME, &noSecurityExtension, NULL, NULL },
+ { SecurityExtensionInit, SECURITY_EXTENSION_NAME, &noSecurityExtension, SecurityExtensionSetup, NULL },
#endif
#ifdef XPRINT
{ XpExtensionInit, XP_PRINTNAME, NULL, NULL, NULL },
diff --git a/os/access.c b/os/access.c
index 69e305182..cdb17589c 100644
--- a/os/access.c
+++ b/os/access.c
@@ -202,8 +202,8 @@ SOFTWARE.
#include "dixstruct.h"
#include "osdep.h"
-#ifdef XCSECURITY
-#include "securitysrv.h"
+#ifdef XACE
+#include "xace.h"
#endif
#ifndef PATH_MAX
@@ -1386,15 +1386,6 @@ _X_EXPORT Bool LocalClient(ClientPtr client)
pointer addr;
register HOST *host;
-#ifdef XCSECURITY
- /* untrusted clients can't change host access */
- if (client->trustLevel != XSecurityClientTrusted)
- {
- SecurityAudit("client %d attempted to change host access\n",
- client->index);
- return FALSE;
- }
-#endif
if (!_XSERVTransGetPeerAddr (((OsCommPtr)client->osPrivate)->trans_conn,
&notused, &alen, &from))
{
@@ -1537,6 +1528,11 @@ AuthorizedClient(ClientPtr client)
{
if (!client || defeatAccessControl)
return TRUE;
+#ifdef XACE
+ /* untrusted clients can't change host access */
+ if (!XaceHook(XACE_HOSTLIST_ACCESS, client, SecurityWriteAccess))
+ return FALSE;
+#endif
return LocalClient(client);
}
diff --git a/os/connection.c b/os/connection.c
index b64cda196..571ba58ab 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -148,6 +148,9 @@ extern __const__ int _nfiles;
#ifdef XAPPGROUP
#include "appgroup.h"
#endif
+#ifdef XACE
+#include "xace.h"
+#endif
#ifdef XCSECURITY
#include "securitysrv.h"
#endif
@@ -690,9 +693,8 @@ ClientAuthorized(ClientPtr client,
/* indicate to Xdmcp protocol that we've opened new client */
XdmcpOpenDisplay(priv->fd);
#endif /* XDMCP */
-#ifdef XAPPGROUP
- if (ClientStateCallback)
- XagCallClientStateChange (client);
+#ifdef XACE
+ XaceHook(XACE_AUTH_AVAIL, client, auth_id);
#endif
/* At this point, if the client is authorized to change the access control
* list, we should getpeername() information, and add the client to