summaryrefslogtreecommitdiff
path: root/Xext
diff options
context:
space:
mode:
Diffstat (limited to 'Xext')
-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
8 files changed, 969 insertions, 306 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 */