xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

xace.c (10295B)


      1 /************************************************************
      2 
      3 Author: Eamon Walsh <ewalsh@tycho.nsa.gov>
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 this permission notice appear in supporting documentation.  This permission
      8 notice shall be included in all copies or substantial portions of the
      9 Software.
     10 
     11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     12 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     14 AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     15 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     16 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     17 
     18 ********************************************************/
     19 
     20 #ifdef HAVE_DIX_CONFIG_H
     21 #include <dix-config.h>
     22 #endif
     23 
     24 #include <stdarg.h>
     25 #include "scrnintstr.h"
     26 #include "extnsionst.h"
     27 #include "pixmapstr.h"
     28 #include "regionstr.h"
     29 #include "gcstruct.h"
     30 #include "xacestr.h"
     31 
     32 _X_EXPORT CallbackListPtr XaceHooks[XACE_NUM_HOOKS] = { 0 };
     33 
     34 /* Special-cased hook functions.  Called by Xserver.
     35  */
     36 #undef XaceHookDispatch
     37 int
     38 XaceHookDispatch(ClientPtr client, int major)
     39 {
     40     /* Call the extension dispatch hook */
     41     ExtensionEntry *ext = GetExtensionEntry(major);
     42     XaceExtAccessRec erec = { client, ext, DixUseAccess, Success };
     43     if (ext)
     44         CallCallbacks(&XaceHooks[XACE_EXT_DISPATCH], &erec);
     45     /* On error, pretend extension doesn't exist */
     46     return (erec.status == Success) ? Success : BadRequest;
     47 }
     48 
     49 int
     50 XaceHookPropertyAccess(ClientPtr client, WindowPtr pWin,
     51                        PropertyPtr *ppProp, Mask access_mode)
     52 {
     53     XacePropertyAccessRec rec = { client, pWin, ppProp, access_mode, Success };
     54     CallCallbacks(&XaceHooks[XACE_PROPERTY_ACCESS], &rec);
     55     return rec.status;
     56 }
     57 
     58 int
     59 XaceHookSelectionAccess(ClientPtr client, Selection ** ppSel, Mask access_mode)
     60 {
     61     XaceSelectionAccessRec rec = { client, ppSel, access_mode, Success };
     62     CallCallbacks(&XaceHooks[XACE_SELECTION_ACCESS], &rec);
     63     return rec.status;
     64 }
     65 
     66 /* Entry point for hook functions.  Called by Xserver.
     67  */
     68 int
     69 XaceHook(int hook, ...)
     70 {
     71     union {
     72         XaceResourceAccessRec res;
     73         XaceDeviceAccessRec dev;
     74         XaceSendAccessRec send;
     75         XaceReceiveAccessRec recv;
     76         XaceClientAccessRec client;
     77         XaceExtAccessRec ext;
     78         XaceServerAccessRec server;
     79         XaceScreenAccessRec screen;
     80         XaceAuthAvailRec auth;
     81         XaceKeyAvailRec key;
     82     } u;
     83     int *prv = NULL;            /* points to return value from callback */
     84     va_list ap;                 /* argument list */
     85 
     86     if (!XaceHooks[hook])
     87         return Success;
     88 
     89     va_start(ap, hook);
     90 
     91     /* Marshal arguments for passing to callback.
     92      * Each callback has its own case, which sets up a structure to hold
     93      * the arguments and integer return parameter, or in some cases just
     94      * sets calldata directly to a single argument (with no return result)
     95      */
     96     switch (hook) {
     97     case XACE_RESOURCE_ACCESS:
     98         u.res.client = va_arg(ap, ClientPtr);
     99         u.res.id = va_arg(ap, XID);
    100         u.res.rtype = va_arg(ap, RESTYPE);
    101         u.res.res = va_arg(ap, void *);
    102         u.res.ptype = va_arg(ap, RESTYPE);
    103         u.res.parent = va_arg(ap, void *);
    104         u.res.access_mode = va_arg(ap, Mask);
    105 
    106         u.res.status = Success; /* default allow */
    107         prv = &u.res.status;
    108         break;
    109     case XACE_DEVICE_ACCESS:
    110         u.dev.client = va_arg(ap, ClientPtr);
    111         u.dev.dev = va_arg(ap, DeviceIntPtr);
    112         u.dev.access_mode = va_arg(ap, Mask);
    113 
    114         u.dev.status = Success; /* default allow */
    115         prv = &u.dev.status;
    116         break;
    117     case XACE_SEND_ACCESS:
    118         u.send.client = va_arg(ap, ClientPtr);
    119         u.send.dev = va_arg(ap, DeviceIntPtr);
    120         u.send.pWin = va_arg(ap, WindowPtr);
    121 
    122         u.send.events = va_arg(ap, xEventPtr);
    123         u.send.count = va_arg(ap, int);
    124 
    125         u.send.status = Success;        /* default allow */
    126         prv = &u.send.status;
    127         break;
    128     case XACE_RECEIVE_ACCESS:
    129         u.recv.client = va_arg(ap, ClientPtr);
    130         u.recv.pWin = va_arg(ap, WindowPtr);
    131 
    132         u.recv.events = va_arg(ap, xEventPtr);
    133         u.recv.count = va_arg(ap, int);
    134 
    135         u.recv.status = Success;        /* default allow */
    136         prv = &u.recv.status;
    137         break;
    138     case XACE_CLIENT_ACCESS:
    139         u.client.client = va_arg(ap, ClientPtr);
    140         u.client.target = va_arg(ap, ClientPtr);
    141         u.client.access_mode = va_arg(ap, Mask);
    142 
    143         u.client.status = Success;      /* default allow */
    144         prv = &u.client.status;
    145         break;
    146     case XACE_EXT_ACCESS:
    147         u.ext.client = va_arg(ap, ClientPtr);
    148 
    149         u.ext.ext = va_arg(ap, ExtensionEntry *);
    150         u.ext.access_mode = DixGetAttrAccess;
    151         u.ext.status = Success; /* default allow */
    152         prv = &u.ext.status;
    153         break;
    154     case XACE_SERVER_ACCESS:
    155         u.server.client = va_arg(ap, ClientPtr);
    156         u.server.access_mode = va_arg(ap, Mask);
    157 
    158         u.server.status = Success;      /* default allow */
    159         prv = &u.server.status;
    160         break;
    161     case XACE_SCREEN_ACCESS:
    162     case XACE_SCREENSAVER_ACCESS:
    163         u.screen.client = va_arg(ap, ClientPtr);
    164         u.screen.screen = va_arg(ap, ScreenPtr);
    165         u.screen.access_mode = va_arg(ap, Mask);
    166 
    167         u.screen.status = Success;      /* default allow */
    168         prv = &u.screen.status;
    169         break;
    170     case XACE_AUTH_AVAIL:
    171         u.auth.client = va_arg(ap, ClientPtr);
    172         u.auth.authId = va_arg(ap, XID);
    173 
    174         break;
    175     case XACE_KEY_AVAIL:
    176         u.key.event = va_arg(ap, xEventPtr);
    177         u.key.keybd = va_arg(ap, DeviceIntPtr);
    178         u.key.count = va_arg(ap, int);
    179 
    180         break;
    181     default:
    182         va_end(ap);
    183         return 0;               /* unimplemented hook number */
    184     }
    185     va_end(ap);
    186 
    187     /* call callbacks and return result, if any. */
    188     CallCallbacks(&XaceHooks[hook], &u);
    189     return prv ? *prv : Success;
    190 }
    191 
    192 /* XaceHookIsSet
    193  *
    194  * Utility function to determine whether there are any callbacks listening on a
    195  * particular XACE hook.
    196  *
    197  * Returns non-zero if there is a callback, zero otherwise.
    198  */
    199 int
    200 XaceHookIsSet(int hook)
    201 {
    202     if (hook < 0 || hook >= XACE_NUM_HOOKS)
    203         return 0;
    204     return XaceHooks[hook] != NULL;
    205 }
    206 
    207 /* XaceCensorImage
    208  *
    209  * Called after pScreen->GetImage to prevent pieces or trusted windows from
    210  * being returned in image data from an untrusted window.
    211  *
    212  * Arguments:
    213  *	client is the client doing the GetImage.
    214  *      pVisibleRegion is the visible region of the window.
    215  *	widthBytesLine is the width in bytes of one horizontal line in pBuf.
    216  *	pDraw is the source window.
    217  *	x, y, w, h is the rectangle of image data from pDraw in pBuf.
    218  *	format is the format of the image data in pBuf: ZPixmap or XYPixmap.
    219  *	pBuf is the image data.
    220  *
    221  * Returns: nothing.
    222  *
    223  * Side Effects:
    224  *	Any part of the rectangle (x, y, w, h) that is outside the visible
    225  *	region of the window will be destroyed (overwritten) in pBuf.
    226  */
    227 void
    228 XaceCensorImage(ClientPtr client,
    229                 RegionPtr pVisibleRegion,
    230                 long widthBytesLine,
    231                 DrawablePtr pDraw,
    232                 int x, int y, int w, int h, unsigned int format, char *pBuf)
    233 {
    234     RegionRec imageRegion;      /* region representing x,y,w,h */
    235     RegionRec censorRegion;     /* region to obliterate */
    236     BoxRec imageBox;
    237     int nRects;
    238 
    239     imageBox.x1 = pDraw->x + x;
    240     imageBox.y1 = pDraw->y + y;
    241     imageBox.x2 = pDraw->x + x + w;
    242     imageBox.y2 = pDraw->y + y + h;
    243     RegionInit(&imageRegion, &imageBox, 1);
    244     RegionNull(&censorRegion);
    245 
    246     /* censorRegion = imageRegion - visibleRegion */
    247     RegionSubtract(&censorRegion, &imageRegion, pVisibleRegion);
    248     nRects = RegionNumRects(&censorRegion);
    249     if (nRects > 0) {           /* we have something to censor */
    250         GCPtr pScratchGC = NULL;
    251         PixmapPtr pPix = NULL;
    252         xRectangle *pRects = NULL;
    253         Bool failed = FALSE;
    254         int depth = 1;
    255         int bitsPerPixel = 1;
    256         int i;
    257         BoxPtr pBox;
    258 
    259         /* convert region to list-of-rectangles for PolyFillRect */
    260 
    261         pRects = malloc(nRects * sizeof(xRectangle));
    262         if (!pRects) {
    263             failed = TRUE;
    264             goto failSafe;
    265         }
    266         for (pBox = RegionRects(&censorRegion), i = 0; i < nRects; i++, pBox++) {
    267             pRects[i].x = pBox->x1 - imageBox.x1;
    268             pRects[i].y = pBox->y1 - imageBox.y1;
    269             pRects[i].width = pBox->x2 - pBox->x1;
    270             pRects[i].height = pBox->y2 - pBox->y1;
    271         }
    272 
    273         /* use pBuf as a fake pixmap */
    274 
    275         if (format == ZPixmap) {
    276             depth = pDraw->depth;
    277             bitsPerPixel = pDraw->bitsPerPixel;
    278         }
    279 
    280         pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h,
    281                                       depth, bitsPerPixel,
    282                                       widthBytesLine, (void *) pBuf);
    283         if (!pPix) {
    284             failed = TRUE;
    285             goto failSafe;
    286         }
    287 
    288         pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen);
    289         if (!pScratchGC) {
    290             failed = TRUE;
    291             goto failSafe;
    292         }
    293 
    294         ValidateGC(&pPix->drawable, pScratchGC);
    295         (*pScratchGC->ops->PolyFillRect) (&pPix->drawable,
    296                                           pScratchGC, nRects, pRects);
    297 
    298  failSafe:
    299         if (failed) {
    300             /* Censoring was not completed above.  To be safe, wipe out
    301              * all the image data so that nothing trusted gets out.
    302              */
    303             memset(pBuf, 0, (int) (widthBytesLine * h));
    304         }
    305         free(pRects);
    306         if (pScratchGC)
    307             FreeScratchGC(pScratchGC);
    308         if (pPix)
    309             FreeScratchPixmapHeader(pPix);
    310     }
    311     RegionUninit(&imageRegion);
    312     RegionUninit(&censorRegion);
    313 }                               /* XaceCensorImage */
    314 
    315 /*
    316  * Xtrans wrappers for use by modules
    317  */
    318 int
    319 XaceGetConnectionNumber(ClientPtr client)
    320 {
    321     return GetClientFd(client);
    322 }
    323 
    324 int
    325 XaceIsLocal(ClientPtr client)
    326 {
    327     return ClientIsLocal(client);
    328 }