diff options
-rw-r--r-- | Xext/Makefile.am | 17 | ||||
-rw-r--r-- | Xext/appgroup.c | 82 | ||||
-rw-r--r-- | Xext/appgroup.h | 4 | ||||
-rw-r--r-- | Xext/security.c | 403 | ||||
-rw-r--r-- | Xext/securitysrv.h | 35 | ||||
-rw-r--r-- | Xext/xace.c | 496 | ||||
-rw-r--r-- | Xext/xace.h | 103 | ||||
-rw-r--r-- | Xext/xacestr.h | 135 | ||||
-rw-r--r-- | configure.ac | 20 | ||||
-rw-r--r-- | dix/devices.c | 21 | ||||
-rw-r--r-- | dix/dispatch.c | 69 | ||||
-rw-r--r-- | dix/dixutils.c | 35 | ||||
-rw-r--r-- | dix/events.c | 28 | ||||
-rw-r--r-- | dix/extension.c | 94 | ||||
-rw-r--r-- | dix/main.c | 1 | ||||
-rw-r--r-- | dix/privates.c | 58 | ||||
-rw-r--r-- | dix/property.c | 24 | ||||
-rw-r--r-- | dix/resource.c | 74 | ||||
-rw-r--r-- | dix/window.c | 32 | ||||
-rw-r--r-- | hw/xfree86/dixmods/extmod/modinit.h | 5 | ||||
-rw-r--r-- | hw/xfree86/loader/dixsym.c | 6 | ||||
-rw-r--r-- | include/dix-config.h.in | 3 | ||||
-rw-r--r-- | include/dix.h | 19 | ||||
-rw-r--r-- | include/dixstruct.h | 10 | ||||
-rw-r--r-- | include/extension.h | 8 | ||||
-rw-r--r-- | include/extnsionst.h | 6 | ||||
-rw-r--r-- | include/resource.h | 11 | ||||
-rw-r--r-- | mi/miinitext.c | 18 | ||||
-rw-r--r-- | os/access.c | 18 | ||||
-rw-r--r-- | os/connection.c | 8 |
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, ¬used, &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 |