1 /************************************************************
3 Author: Eamon Walsh <ewalsh@tycho.nsa.gov>
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
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.
18 ********************************************************/
20 #ifdef HAVE_DIX_CONFIG_H
21 #include <dix-config.h>
25 #include "scrnintstr.h"
26 #include "extnsionst.h"
27 #include "pixmapstr.h"
28 #include "regionstr.h"
34 #include <X11/Xtrans/Xtrans.h>
35 #include "../os/osdep.h"
37 _X_EXPORT CallbackListPtr XaceHooks
[XACE_NUM_HOOKS
] = { 0 };
39 /* Special-cased hook functions. Called by Xserver.
42 XaceHookDispatch(ClientPtr client
, int major
)
44 /* Call the audit begin callback, there is no return value. */
45 XaceAuditRec rec
= { client
, 0 };
46 CallCallbacks(&XaceHooks
[XACE_AUDIT_BEGIN
], &rec
);
49 /* Call the core dispatch hook */
50 XaceCoreDispatchRec drec
= { client
, Success
/* default allow */ };
51 CallCallbacks(&XaceHooks
[XACE_CORE_DISPATCH
], &drec
);
55 /* Call the extension dispatch hook */
56 ExtensionEntry
*ext
= GetExtensionEntry(major
);
57 XaceExtAccessRec erec
= { client
, ext
, DixUseAccess
, Success
};
59 CallCallbacks(&XaceHooks
[XACE_EXT_DISPATCH
], &erec
);
60 /* On error, pretend extension doesn't exist */
61 return (erec
.status
== Success
) ? Success
: BadRequest
;
66 XaceHookPropertyAccess(ClientPtr client
, WindowPtr pWin
,
67 PropertyPtr
*ppProp
, Mask access_mode
)
69 XacePropertyAccessRec rec
= { client
, pWin
, ppProp
, access_mode
, Success
};
70 CallCallbacks(&XaceHooks
[XACE_PROPERTY_ACCESS
], &rec
);
75 XaceHookSelectionAccess(ClientPtr client
, Selection
** ppSel
, Mask access_mode
)
77 XaceSelectionAccessRec rec
= { client
, ppSel
, access_mode
, Success
};
78 CallCallbacks(&XaceHooks
[XACE_SELECTION_ACCESS
], &rec
);
83 XaceHookAuditEnd(ClientPtr ptr
, int result
)
85 XaceAuditRec rec
= { ptr
, result
};
86 /* call callbacks, there is no return value. */
87 CallCallbacks(&XaceHooks
[XACE_AUDIT_END
], &rec
);
90 /* Entry point for hook functions. Called by Xserver.
93 XaceHook(int hook
, ...)
96 XaceResourceAccessRec res
;
97 XaceDeviceAccessRec dev
;
98 XaceSendAccessRec send
;
99 XaceReceiveAccessRec recv
;
100 XaceClientAccessRec client
;
101 XaceExtAccessRec ext
;
102 XaceServerAccessRec server
;
103 XaceScreenAccessRec screen
;
104 XaceAuthAvailRec auth
;
107 int *prv
= NULL
; /* points to return value from callback */
108 va_list ap
; /* argument list */
110 if (!XaceHooks
[hook
])
115 /* Marshal arguments for passing to callback.
116 * Each callback has its own case, which sets up a structure to hold
117 * the arguments and integer return parameter, or in some cases just
118 * sets calldata directly to a single argument (with no return result)
121 case XACE_RESOURCE_ACCESS
:
122 u
.res
.client
= va_arg(ap
, ClientPtr
);
123 u
.res
.id
= va_arg(ap
, XID
);
124 u
.res
.rtype
= va_arg(ap
, RESTYPE
);
125 u
.res
.res
= va_arg(ap
, pointer
);
126 u
.res
.ptype
= va_arg(ap
, RESTYPE
);
127 u
.res
.parent
= va_arg(ap
, pointer
);
128 u
.res
.access_mode
= va_arg(ap
, Mask
);
130 u
.res
.status
= Success
; /* default allow */
133 case XACE_DEVICE_ACCESS
:
134 u
.dev
.client
= va_arg(ap
, ClientPtr
);
135 u
.dev
.dev
= va_arg(ap
, DeviceIntPtr
);
136 u
.dev
.access_mode
= va_arg(ap
, Mask
);
138 u
.dev
.status
= Success
; /* default allow */
141 case XACE_SEND_ACCESS
:
142 u
.send
.client
= va_arg(ap
, ClientPtr
);
143 u
.send
.dev
= va_arg(ap
, DeviceIntPtr
);
144 u
.send
.pWin
= va_arg(ap
, WindowPtr
);
146 u
.send
.events
= va_arg(ap
, xEventPtr
);
147 u
.send
.count
= va_arg(ap
, int);
149 u
.send
.status
= Success
; /* default allow */
150 prv
= &u
.send
.status
;
152 case XACE_RECEIVE_ACCESS
:
153 u
.recv
.client
= va_arg(ap
, ClientPtr
);
154 u
.recv
.pWin
= va_arg(ap
, WindowPtr
);
156 u
.recv
.events
= va_arg(ap
, xEventPtr
);
157 u
.recv
.count
= va_arg(ap
, int);
159 u
.recv
.status
= Success
; /* default allow */
160 prv
= &u
.recv
.status
;
162 case XACE_CLIENT_ACCESS
:
163 u
.client
.client
= va_arg(ap
, ClientPtr
);
164 u
.client
.target
= va_arg(ap
, ClientPtr
);
165 u
.client
.access_mode
= va_arg(ap
, Mask
);
167 u
.client
.status
= Success
; /* default allow */
168 prv
= &u
.client
.status
;
170 case XACE_EXT_ACCESS
:
171 u
.ext
.client
= va_arg(ap
, ClientPtr
);
173 u
.ext
.ext
= va_arg(ap
, ExtensionEntry
*);
174 u
.ext
.access_mode
= DixGetAttrAccess
;
175 u
.ext
.status
= Success
; /* default allow */
178 case XACE_SERVER_ACCESS
:
179 u
.server
.client
= va_arg(ap
, ClientPtr
);
180 u
.server
.access_mode
= va_arg(ap
, Mask
);
182 u
.server
.status
= Success
; /* default allow */
183 prv
= &u
.server
.status
;
185 case XACE_SCREEN_ACCESS
:
186 case XACE_SCREENSAVER_ACCESS
:
187 u
.screen
.client
= va_arg(ap
, ClientPtr
);
188 u
.screen
.screen
= va_arg(ap
, ScreenPtr
);
189 u
.screen
.access_mode
= va_arg(ap
, Mask
);
191 u
.screen
.status
= Success
; /* default allow */
192 prv
= &u
.screen
.status
;
194 case XACE_AUTH_AVAIL
:
195 u
.auth
.client
= va_arg(ap
, ClientPtr
);
196 u
.auth
.authId
= va_arg(ap
, XID
);
200 u
.key
.event
= va_arg(ap
, xEventPtr
);
201 u
.key
.keybd
= va_arg(ap
, DeviceIntPtr
);
202 u
.key
.count
= va_arg(ap
, int);
207 return 0; /* unimplemented hook number */
211 /* call callbacks and return result, if any. */
212 CallCallbacks(&XaceHooks
[hook
], &u
);
213 return prv
? *prv
: Success
;
218 * Called after pScreen->GetImage to prevent pieces or trusted windows from
219 * being returned in image data from an untrusted window.
222 * client is the client doing the GetImage.
223 * pVisibleRegion is the visible region of the window.
224 * widthBytesLine is the width in bytes of one horizontal line in pBuf.
225 * pDraw is the source window.
226 * x, y, w, h is the rectangle of image data from pDraw in pBuf.
227 * format is the format of the image data in pBuf: ZPixmap or XYPixmap.
228 * pBuf is the image data.
233 * Any part of the rectangle (x, y, w, h) that is outside the visible
234 * region of the window will be destroyed (overwritten) in pBuf.
237 XaceCensorImage(ClientPtr client
,
238 RegionPtr pVisibleRegion
,
241 int x
, int y
, int w
, int h
, unsigned int format
, char *pBuf
)
243 RegionRec imageRegion
; /* region representing x,y,w,h */
244 RegionRec censorRegion
; /* region to obliterate */
252 RegionInit(&imageRegion
, &imageBox
, 1);
253 RegionNull(&censorRegion
);
255 /* censorRegion = imageRegion - visibleRegion */
256 RegionSubtract(&censorRegion
, &imageRegion
, pVisibleRegion
);
257 nRects
= RegionNumRects(&censorRegion
);
258 if (nRects
> 0) { /* we have something to censor */
259 GCPtr pScratchGC
= NULL
;
260 PixmapPtr pPix
= NULL
;
261 xRectangle
*pRects
= NULL
;
264 int bitsPerPixel
= 1;
268 /* convert region to list-of-rectangles for PolyFillRect */
270 pRects
= malloc(nRects
* sizeof(xRectangle
));
275 for (pBox
= RegionRects(&censorRegion
), i
= 0; i
< nRects
; i
++, pBox
++) {
276 pRects
[i
].x
= pBox
->x1
;
277 pRects
[i
].y
= pBox
->y1
- imageBox
.y1
;
278 pRects
[i
].width
= pBox
->x2
- pBox
->x1
;
279 pRects
[i
].height
= pBox
->y2
- pBox
->y1
;
282 /* use pBuf as a fake pixmap */
284 if (format
== ZPixmap
) {
285 depth
= pDraw
->depth
;
286 bitsPerPixel
= pDraw
->bitsPerPixel
;
289 pPix
= GetScratchPixmapHeader(pDraw
->pScreen
, w
, h
,
291 widthBytesLine
, (pointer
) pBuf
);
297 pScratchGC
= GetScratchGC(depth
, pPix
->drawable
.pScreen
);
303 ValidateGC(&pPix
->drawable
, pScratchGC
);
304 (*pScratchGC
->ops
->PolyFillRect
) (&pPix
->drawable
,
305 pScratchGC
, nRects
, pRects
);
309 /* Censoring was not completed above. To be safe, wipe out
310 * all the image data so that nothing trusted gets out.
312 memset(pBuf
, 0, (int) (widthBytesLine
* h
));
316 FreeScratchGC(pScratchGC
);
318 FreeScratchPixmapHeader(pPix
);
320 RegionUninit(&imageRegion
);
321 RegionUninit(&censorRegion
);
322 } /* XaceCensorImage */
325 * Xtrans wrappers for use by modules
328 XaceGetConnectionNumber(ClientPtr client
)
330 XtransConnInfo ci
= ((OsCommPtr
) client
->osPrivate
)->trans_conn
;
332 return _XSERVTransGetConnectionNumber(ci
);
336 XaceIsLocal(ClientPtr client
)
338 XtransConnInfo ci
= ((OsCommPtr
) client
->osPrivate
)->trans_conn
;
340 return _XSERVTransIsLocal(ci
);