Xi: Add access control request handling.
dix: New file access.c to handle all access control for devices.
This commit is contained in:
parent
cd0af7a785
commit
4b8b0e377a
|
@ -21,6 +21,8 @@ libXi_la_SOURCES = \
|
|||
chgptr.h \
|
||||
chpkpair.c \
|
||||
chpkpair.h \
|
||||
chaccess.c \
|
||||
chaccess.h \
|
||||
closedev.c \
|
||||
closedev.h \
|
||||
devbell.c \
|
||||
|
@ -46,6 +48,8 @@ libXi_la_SOURCES = \
|
|||
getselev.h \
|
||||
getvers.c \
|
||||
getvers.h \
|
||||
grabacc.c \
|
||||
grabacc.h \
|
||||
grabdev.c \
|
||||
grabdev.h \
|
||||
grabdevb.c \
|
||||
|
@ -62,6 +66,8 @@ libXi_la_SOURCES = \
|
|||
querydp.h \
|
||||
queryst.c \
|
||||
queryst.h \
|
||||
qryacces.c \
|
||||
qryacces.h \
|
||||
regpair.c \
|
||||
regpair.h \
|
||||
selectev.c \
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
|
||||
Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au>
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
|
||||
*/
|
||||
|
||||
#define NEED_EVENTS
|
||||
#define NEED_REPLIES
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h> /* for inputstr.h */
|
||||
#include <X11/Xproto.h> /* Request macro */
|
||||
#include "inputstr.h" /* DeviceIntPtr */
|
||||
#include "windowstr.h" /* window structure */
|
||||
#include "scrnintstr.h" /* screen structure */
|
||||
#include <X11/extensions/XI.h>
|
||||
#include <X11/extensions/XIproto.h>
|
||||
#include "extnsionst.h"
|
||||
#include "extinit.h" /* LookupDeviceIntRec */
|
||||
#include "exevents.h"
|
||||
#include "exglobals.h"
|
||||
|
||||
#include "chaccess.h"
|
||||
|
||||
/***********************************************************************
|
||||
* This procedure allows a client to change window access control.
|
||||
*/
|
||||
|
||||
int
|
||||
SProcXChangeWindowAccess(ClientPtr client)
|
||||
{
|
||||
char n;
|
||||
REQUEST(xChangeWindowAccessReq);
|
||||
|
||||
swaps(&stuff->length, n);
|
||||
swapl(&stuff->win, n);
|
||||
return ProcXChangeWindowAccess(client);
|
||||
}
|
||||
|
||||
int
|
||||
ProcXChangeWindowAccess(ClientPtr client)
|
||||
{
|
||||
int padding, err, i;
|
||||
CARD8* deviceids = NULL;
|
||||
WindowPtr win;
|
||||
DeviceIntPtr* perm_devices = NULL;
|
||||
DeviceIntPtr* deny_devices = NULL;
|
||||
REQUEST(xChangeWindowAccessReq);
|
||||
REQUEST_AT_LEAST_SIZE(xChangeWindowAccessReq);
|
||||
|
||||
|
||||
padding = (4 - ((stuff->npermit + stuff->ndeny) % 4)) % 4;
|
||||
|
||||
if (stuff->length != ((sizeof(xChangeWindowAccessReq) +
|
||||
(stuff->npermit + stuff->ndeny + padding)) >> 2))
|
||||
{
|
||||
SendErrorToClient(client, IReqCode, X_ChangeWindowAccess,
|
||||
0, BadLength);
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
err = dixLookupWindow(&win, stuff->win, client, DixWriteAccess);
|
||||
if (err != Success)
|
||||
{
|
||||
SendErrorToClient(client, IReqCode, X_ChangeWindowAccess,
|
||||
stuff->win, err);
|
||||
return Success;
|
||||
}
|
||||
|
||||
/* Are we clearing? if so, ignore the rest */
|
||||
if (stuff->clear)
|
||||
{
|
||||
err = ACClearWindowAccess(client, win, stuff->clear);
|
||||
if (err != Success)
|
||||
SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, 0, err);
|
||||
return Success;
|
||||
}
|
||||
|
||||
if (stuff->npermit || stuff->ndeny)
|
||||
deviceids = (CARD8*)&stuff[1];
|
||||
|
||||
if (stuff->npermit)
|
||||
{
|
||||
perm_devices =
|
||||
(DeviceIntPtr*)xalloc(stuff->npermit * sizeof(DeviceIntPtr));
|
||||
if (!perm_devices)
|
||||
{
|
||||
ErrorF("ProcXChangeWindowAccess: alloc failure.\n");
|
||||
SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, 0,
|
||||
BadImplementation);
|
||||
return Success;
|
||||
}
|
||||
|
||||
/* if one of the devices cannot be accessed, we don't do anything.*/
|
||||
for (i = 0; i < stuff->npermit; i++)
|
||||
{
|
||||
perm_devices[i] = LookupDeviceIntRec(deviceids[i]);
|
||||
if (!perm_devices[i])
|
||||
{
|
||||
xfree(perm_devices);
|
||||
SendErrorToClient(client, IReqCode, X_ChangeWindowAccess,
|
||||
deviceids[i], BadDevice);
|
||||
return Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stuff->ndeny)
|
||||
{
|
||||
deny_devices =
|
||||
(DeviceIntPtr*)xalloc(stuff->ndeny * sizeof(DeviceIntPtr));
|
||||
if (!deny_devices)
|
||||
{
|
||||
ErrorF("ProcXChangeWindowAccecss: alloc failure.\n");
|
||||
SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, 0,
|
||||
BadImplementation);
|
||||
|
||||
xfree(perm_devices);
|
||||
return Success;
|
||||
}
|
||||
|
||||
for (i = 0; i < stuff->ndeny; i++)
|
||||
{
|
||||
deny_devices[i] =
|
||||
LookupDeviceIntRec(deviceids[i+stuff->npermit]);
|
||||
|
||||
if (!deny_devices[i])
|
||||
{
|
||||
xfree(perm_devices);
|
||||
xfree(deny_devices);
|
||||
SendErrorToClient(client, IReqCode, X_ChangeWindowAccess,
|
||||
deviceids[i + stuff->npermit], BadDevice);
|
||||
return Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = ACChangeWindowAccess(client, win, stuff->defaultRule,
|
||||
perm_devices, stuff->npermit,
|
||||
deny_devices, stuff->ndeny);
|
||||
if (err != Success)
|
||||
{
|
||||
SendErrorToClient(client, IReqCode, X_ChangeWindowAccess,
|
||||
stuff->win, err);
|
||||
return Success;
|
||||
}
|
||||
|
||||
xfree(perm_devices);
|
||||
xfree(deny_devices);
|
||||
return Success;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
|
||||
Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au>
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef CHACCESS_H
|
||||
#define CHACCESS_H 1
|
||||
|
||||
int SProcXChangeWindowAccess(ClientPtr /* client */);
|
||||
int ProcXChangeWindowAccess(ClientPtr /* client */);
|
||||
|
||||
#endif /* CHACCESS_H */
|
25
Xi/extinit.c
25
Xi/extinit.c
|
@ -74,6 +74,7 @@ SOFTWARE.
|
|||
|
||||
/* modules local to Xi */
|
||||
#include "allowev.h"
|
||||
#include "chaccess.h"
|
||||
#include "chdevcur.h"
|
||||
#include "chgdctl.h"
|
||||
#include "chgfctl.h"
|
||||
|
@ -94,12 +95,14 @@ SOFTWARE.
|
|||
#include "getselev.h"
|
||||
#include "getvers.h"
|
||||
#include "getvers.h"
|
||||
#include "grabacc.h"
|
||||
#include "grabdev.h"
|
||||
#include "grabdevb.h"
|
||||
#include "grabdevk.h"
|
||||
#include "gtmotion.h"
|
||||
#include "listdev.h"
|
||||
#include "opendev.h"
|
||||
#include "qryacces.c"
|
||||
#include "querydp.h"
|
||||
#include "queryst.h"
|
||||
#include "regpair.h"
|
||||
|
@ -358,6 +361,12 @@ ProcIDispatch(register ClientPtr client)
|
|||
return (ProcXChangePointerKeyboardPairing(client));
|
||||
else if (stuff->data == X_RegisterPairingClient)
|
||||
return (ProcXRegisterPairingClient(client));
|
||||
else if (stuff->data == X_GrabAccessControl)
|
||||
return (ProcXGrabAccessControl(client));
|
||||
else if (stuff->data == X_ChangeWindowAccess)
|
||||
return (ProcXChangeWindowAccess(client));
|
||||
else if (stuff->data == X_QueryWindowAccess)
|
||||
return ProcXQueryWindowAccess(client);
|
||||
else {
|
||||
SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest);
|
||||
}
|
||||
|
@ -457,6 +466,12 @@ SProcIDispatch(register ClientPtr client)
|
|||
return (SProcXChangePointerKeyboardPairing(client));
|
||||
else if (stuff->data == X_RegisterPairingClient)
|
||||
return (SProcXRegisterPairingClient(client));
|
||||
else if (stuff->data == X_GrabAccessControl)
|
||||
return (SProcXGrabAccessControl(client));
|
||||
else if (stuff->data == X_ChangeWindowAccess)
|
||||
return (SProcXChangeWindowAccess(client));
|
||||
else if (stuff->data == X_QueryWindowAccess)
|
||||
return SProcXQueryWindowAccess(client);
|
||||
else {
|
||||
SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest);
|
||||
}
|
||||
|
@ -531,10 +546,16 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
|
|||
(xChangeDeviceControlReply *) rep);
|
||||
else if (rep->RepType == X_QueryDevicePointer)
|
||||
SRepXQueryDevicePointer(client, len,
|
||||
(xQueryDevicePointerReply *) rep);
|
||||
(xQueryDevicePointerReply *) rep);
|
||||
else if (rep->RepType == X_RegisterPairingClient)
|
||||
SRepXRegisterPairingClient(client, len,
|
||||
(xRegisterPairingClientReply *) rep);
|
||||
(xRegisterPairingClientReply *) rep);
|
||||
else if (rep->RepType == X_GrabAccessControl)
|
||||
SRepXGrabAccessControl(client, len,
|
||||
(xGrabAccessControlReply*) rep);
|
||||
else if (rep->RepType == X_QueryWindowAccess)
|
||||
SRepXQueryWindowAccess(client, len,
|
||||
(xQueryWindowAccessReply*) rep);
|
||||
else {
|
||||
FatalError("XINPUT confused sending swapped reply");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
|
||||
Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au>
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
|
||||
*/
|
||||
|
||||
#define NEED_EVENTS
|
||||
#define NEED_REPLIES
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h> /* for inputstr.h */
|
||||
#include <X11/Xproto.h> /* Request macro */
|
||||
#include "inputstr.h" /* DeviceIntPtr */
|
||||
#include "windowstr.h" /* window structure */
|
||||
#include "scrnintstr.h" /* screen structure */
|
||||
#include <X11/extensions/XI.h>
|
||||
#include <X11/extensions/XIproto.h>
|
||||
#include "extnsionst.h"
|
||||
#include "extinit.h" /* LookupDeviceIntRec */
|
||||
#include "exevents.h"
|
||||
#include "exglobals.h"
|
||||
|
||||
#include "grabacc.h"
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* This procedure allows a client to register as the global client to control
|
||||
* any window access.
|
||||
*
|
||||
*/
|
||||
int
|
||||
SProcXGrabAccessControl(ClientPtr client)
|
||||
{
|
||||
char n;
|
||||
REQUEST(xGrabAccessControlReq);
|
||||
|
||||
swaps(&stuff->length, n);
|
||||
return ProcXGrabAccessControl(client);
|
||||
}
|
||||
|
||||
int
|
||||
ProcXGrabAccessControl(ClientPtr client)
|
||||
{
|
||||
xGrabAccessControlReply rep;
|
||||
REQUEST(xGrabAccessControlReq);
|
||||
REQUEST_SIZE_MATCH(xGrabAccessControlReq);
|
||||
|
||||
if (stuff->ungrab)
|
||||
ACUnregisterClient(client);
|
||||
|
||||
rep.repType = X_Reply;
|
||||
rep.RepType = X_GrabAccessControl;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.success = stuff->ungrab || ACRegisterClient(client);
|
||||
|
||||
WriteReplyToClient(client, sizeof(xGrabAccessControlReply), &rep);
|
||||
return Success;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* This procedure writes the reply for the XGrabAccessControl function,
|
||||
* if the client and server have a different byte ordering.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
SRepXGrabAccessControl(ClientPtr client, int size,
|
||||
xGrabAccessControlReply* rep)
|
||||
{
|
||||
register char n;
|
||||
|
||||
swaps(&rep->sequenceNumber, n);
|
||||
swapl(&rep->length, n);
|
||||
WriteToClient(client, size, (char *)rep);
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
|
||||
Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au>
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef GRABACC_H
|
||||
#define GRABACC_H 1
|
||||
|
||||
int SProcXGrabAccessControl(ClientPtr /* client */);
|
||||
|
||||
int ProcXGrabAccessControl(ClientPtr /* client */);
|
||||
void SRepXGrabAccessControl(ClientPtr client, int size,
|
||||
xGrabAccessControlReply* rep);
|
||||
#endif /* GRABACC_H */
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
|
||||
Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au>
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
|
||||
*/
|
||||
|
||||
#define NEED_EVENTS
|
||||
#define NEED_REPLIES
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h> /* for inputstr.h */
|
||||
#include <X11/Xproto.h> /* Request macro */
|
||||
#include "inputstr.h" /* DeviceIntPtr */
|
||||
#include "windowstr.h" /* window structure */
|
||||
#include "scrnintstr.h" /* screen structure */
|
||||
#include <X11/extensions/XI.h>
|
||||
#include <X11/extensions/XIproto.h>
|
||||
#include "extnsionst.h"
|
||||
#include "extinit.h" /* LookupDeviceIntRec */
|
||||
#include "exevents.h"
|
||||
#include "exglobals.h"
|
||||
|
||||
#include "qryacces.h"
|
||||
|
||||
/***********************************************************************
|
||||
* This procedure allows a client to query window access control.
|
||||
*/
|
||||
|
||||
int
|
||||
SProcXQueryWindowAccess(ClientPtr client)
|
||||
{
|
||||
char n;
|
||||
REQUEST(xQueryWindowAccessReq);
|
||||
|
||||
swaps(&stuff->length, n);
|
||||
swapl(&stuff->win, n);
|
||||
return ProcXQueryWindowAccess(client);
|
||||
}
|
||||
|
||||
int
|
||||
ProcXQueryWindowAccess(ClientPtr client)
|
||||
{
|
||||
int err;
|
||||
WindowPtr win;
|
||||
DeviceIntPtr *perm, *deny;
|
||||
int nperm, ndeny, i;
|
||||
int defaultRule;
|
||||
CARD8* deviceids;
|
||||
xQueryWindowAccessReply rep;
|
||||
|
||||
REQUEST(xQueryWindowAccessReq);
|
||||
REQUEST_SIZE_MATCH(xQueryWindowAccessReq);
|
||||
|
||||
err = dixLookupWindow(&win, stuff->win, client, DixReadAccess);
|
||||
if (err != Success)
|
||||
{
|
||||
SendErrorToClient(client, IReqCode, X_QueryWindowAccess,
|
||||
stuff->win, err);
|
||||
return Success;
|
||||
}
|
||||
|
||||
ACQueryWindowAccess(win, &defaultRule, &perm, &nperm, &deny, &ndeny);
|
||||
|
||||
rep.repType = X_Reply;
|
||||
rep.RepType = X_QueryWindowAccess;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.length = (nperm + ndeny + 3) >> 2;
|
||||
rep.defaultRule = defaultRule;
|
||||
rep.npermit = nperm;
|
||||
rep.ndeny = ndeny;
|
||||
WriteReplyToClient(client, sizeof(xQueryWindowAccessReply), &rep);
|
||||
|
||||
if (nperm + ndeny)
|
||||
{
|
||||
deviceids = (CARD8*)xalloc((nperm + ndeny) * sizeof(CARD8));
|
||||
if (!deviceids)
|
||||
{
|
||||
ErrorF("ProcXQueryWindowAccess: xalloc failure.\n");
|
||||
SendErrorToClient(client, IReqCode, X_QueryWindowAccess,
|
||||
0, BadImplementation);
|
||||
return Success;
|
||||
}
|
||||
|
||||
for (i = 0; i < nperm; i++)
|
||||
deviceids[i] = perm[i]->id;
|
||||
for (i = 0; i < ndeny; i++)
|
||||
deviceids[i + nperm] = deny[i]->id;
|
||||
|
||||
WriteToClient(client, nperm + ndeny, (char*)deviceids);
|
||||
xfree(deviceids);
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
|
||||
void
|
||||
SRepXQueryWindowAccess(ClientPtr client,
|
||||
int size,
|
||||
xQueryWindowAccessReply* rep)
|
||||
{
|
||||
char n;
|
||||
swaps(&rep->sequenceNumber, n);
|
||||
swapl(&rep->length, n);
|
||||
WriteToClient(client, size, (char*)rep);
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
|
||||
Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au>
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef QRYACCES_H
|
||||
#define QRYACCES_H 1
|
||||
|
||||
int SProcXQueryWindowAccess(ClientPtr /* client */);
|
||||
int ProcXQueryWindowAccess(ClientPtr /* client */);
|
||||
void SRepXQueryWindowAccess(ClientPtr /* client */,
|
||||
int /* size */,
|
||||
xQueryWindowAccessReply* /* rep */);
|
||||
#endif
|
|
@ -5,6 +5,7 @@ AM_CFLAGS = $(DIX_CFLAGS) \
|
|||
-DVENDOR_RELEASE="@VENDOR_RELEASE@"
|
||||
|
||||
libdix_la_SOURCES = \
|
||||
access.c \
|
||||
atom.c \
|
||||
colormap.c \
|
||||
cursor.c \
|
||||
|
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
|
||||
Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au>
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and 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.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
|
||||
*/
|
||||
|
||||
/* This file controls the access control lists for each window.
|
||||
* Each device can be explicitely allowed or denied access to a given window.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XI.h>
|
||||
|
||||
#include "input.h"
|
||||
#include "inputstr.h"
|
||||
#include "windowstr.h"
|
||||
|
||||
|
||||
/* Only one single client can be responsible for window access control. */
|
||||
static ClientPtr ACClient = NULL;
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
static void acReplaceList(DeviceIntPtr** list,
|
||||
int* count,
|
||||
DeviceIntPtr* devices,
|
||||
int ndevices);
|
||||
|
||||
/* Register global window access control client
|
||||
* Return True on success or False otherwise.
|
||||
*/
|
||||
|
||||
Bool
|
||||
ACRegisterClient(ClientPtr client)
|
||||
{
|
||||
if (ACClient && ACClient != client)
|
||||
return False;
|
||||
|
||||
ACClient = client;
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/* Unregister global client. If client is not the registered client, nothing
|
||||
* happens and False is returned. If no client is registered, return True.
|
||||
* Returns True if client was registred and is now unregistered.
|
||||
*/
|
||||
|
||||
Bool
|
||||
ACUnregisterClient(ClientPtr client)
|
||||
{
|
||||
if (ACClient && ACClient != client)
|
||||
return False;
|
||||
|
||||
ACClient = NULL;
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Clears all access control for the window and remove the default rule,
|
||||
* depending on what is set. */
|
||||
int ACClearWindowAccess(ClientPtr client,
|
||||
WindowPtr win,
|
||||
int what)
|
||||
{
|
||||
if (client != ACClient && client != wClient(win))
|
||||
return BadAccess;
|
||||
|
||||
if (!win->optional)
|
||||
{
|
||||
/* we shouldn't get here if programmers know what they're doing.
|
||||
* A client should not request to clear a window's access controls
|
||||
* if they've never been set before anyway. If they do, do nothing and
|
||||
* let the client figure out what to do next.
|
||||
*/
|
||||
return Success;
|
||||
}
|
||||
|
||||
if (what & WindowAccessClearPerm)
|
||||
{
|
||||
xfree(win->optional->access.perm);
|
||||
win->optional->access.perm = NULL;
|
||||
win->optional->access.nperm = 0;
|
||||
}
|
||||
|
||||
if (what & WindowAccessClearDeny)
|
||||
{
|
||||
xfree(win->optional->access.deny);
|
||||
win->optional->access.deny = NULL;
|
||||
win->optional->access.ndeny = 0;
|
||||
}
|
||||
|
||||
if (what & WindowAccessClearRule)
|
||||
win->optional->access.defaultRule = WindowAccessNoRule;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Changes window access control.
|
||||
*
|
||||
* Returns Success or BadAccess if the client is not allowed to change
|
||||
* anything.
|
||||
*/
|
||||
|
||||
int
|
||||
ACChangeWindowAccess(ClientPtr client,
|
||||
WindowPtr win,
|
||||
int defaultRule,
|
||||
DeviceIntPtr* perm_devices,
|
||||
int nperm,
|
||||
DeviceIntPtr* deny_devices,
|
||||
int ndeny)
|
||||
{
|
||||
if (client != ACClient && client != wClient(win))
|
||||
return BadAccess;
|
||||
|
||||
if (!win->optional && !MakeWindowOptional(win))
|
||||
{
|
||||
ErrorF("ACChangeWindowAcccess: Failed to make window optional.\n");
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
if (defaultRule != WindowAccessKeepRule)
|
||||
win->optional->access.defaultRule = defaultRule;
|
||||
|
||||
if (nperm)
|
||||
{
|
||||
acReplaceList(&win->optional->access.perm,
|
||||
&win->optional->access.nperm,
|
||||
perm_devices, nperm);
|
||||
}
|
||||
|
||||
if (ndeny)
|
||||
{
|
||||
acReplaceList(&win->optional->access.deny,
|
||||
&win->optional->access.ndeny,
|
||||
deny_devices, ndeny);
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
acReplaceList(DeviceIntPtr** list,
|
||||
int* count,
|
||||
DeviceIntPtr* devices,
|
||||
int ndevices)
|
||||
{
|
||||
xfree(*list);
|
||||
*list = NULL;
|
||||
*count = 0;
|
||||
|
||||
if (ndevices)
|
||||
{
|
||||
*list =
|
||||
xalloc(ndevices * sizeof(DeviceIntPtr*));
|
||||
if (!*list)
|
||||
{
|
||||
ErrorF("ACChangeWindowAccess: out of memory\n");
|
||||
return;
|
||||
}
|
||||
memcpy(*list,
|
||||
devices,
|
||||
ndevices * sizeof(DeviceIntPtr));
|
||||
*count = ndevices;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Query the given window for the devices allowed to access a window.
|
||||
* The caller is responsible for freeing perm and deny.
|
||||
*/
|
||||
void
|
||||
ACQueryWindowAccess(WindowPtr win,
|
||||
int* defaultRule,
|
||||
DeviceIntPtr** perm,
|
||||
int* nperm,
|
||||
DeviceIntPtr** deny,
|
||||
int* ndeny)
|
||||
{
|
||||
*defaultRule = WindowAccessNoRule;
|
||||
*perm = NULL;
|
||||
*nperm = 0;
|
||||
*deny = NULL;
|
||||
*ndeny = 0;
|
||||
|
||||
if (!win->optional)
|
||||
return;
|
||||
|
||||
*defaultRule = win->optional->access.defaultRule;
|
||||
|
||||
if (win->optional->access.nperm)
|
||||
{
|
||||
*nperm = win->optional->access.nperm;
|
||||
*perm = (DeviceIntPtr*)xalloc(*nperm * sizeof(DeviceIntPtr));
|
||||
if (!*perm)
|
||||
{
|
||||
ErrorF("ACQuerywinAccess: xalloc failure\n");
|
||||
return;
|
||||
}
|
||||
memcpy(*perm,
|
||||
win->optional->access.perm,
|
||||
*nperm * sizeof(DeviceIntPtr));
|
||||
}
|
||||
|
||||
if (win->optional->access.ndeny)
|
||||
{
|
||||
*ndeny = win->optional->access.ndeny;
|
||||
*deny = (DeviceIntPtr*)xalloc(*ndeny * sizeof(DeviceIntPtr));
|
||||
if (!*deny)
|
||||
{
|
||||
ErrorF("ACQuerywinAccess: xalloc failure\n");
|
||||
return;
|
||||
}
|
||||
memcpy(*deny,
|
||||
win->optional->access.deny,
|
||||
*ndeny * sizeof(DeviceIntPtr));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the given device is allowed to send events to the window. Returns
|
||||
* true if device is allowed or false otherwise.
|
||||
*
|
||||
* Checks are done in the following order until a result is found:
|
||||
* If the device is explicitely permitted, allow.
|
||||
* If the window has a default of DenyAll, do not allow.
|
||||
* If the device is explicitely denied, do not allow.
|
||||
* Check parent window. Rinse, wash, repeat.
|
||||
* If no rule could be found, allow.
|
||||
*/
|
||||
Bool
|
||||
ACDeviceAllowed(WindowPtr win, DeviceIntPtr dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!win) /* happens for parent of RootWindow */
|
||||
return True;
|
||||
|
||||
if (!win->optional) /* no list, check parent */
|
||||
return ACDeviceAllowed(win->parent, dev);
|
||||
|
||||
for (i = 0; i < win->optional->access.nperm; i++)
|
||||
{
|
||||
if (win->optional->access.perm[i]->id == dev->id)
|
||||
return True;
|
||||
}
|
||||
|
||||
if (win->optional->access.defaultRule == WindowAccessDenyAll)
|
||||
return False;
|
||||
|
||||
for (i = 0; i < win->optional->access.ndeny; i++)
|
||||
{
|
||||
if (win->optional->access.deny[i]->id == dev->id)
|
||||
return False;
|
||||
}
|
||||
|
||||
return ACDeviceAllowed(win->parent, dev);
|
||||
}
|
||||
|
|
@ -3568,6 +3568,7 @@ CloseDownClient(register ClientPtr client)
|
|||
DeleteClientFromAnySelections(client);
|
||||
ReleaseActiveGrabs(client);
|
||||
DeleteClientFontStuff(client);
|
||||
ACUnregisterClient(client);
|
||||
UnregisterPairingClient(client); /* other clients can pair devices */
|
||||
if (!really_close_down)
|
||||
{
|
||||
|
|
23
dix/events.c
23
dix/events.c
|
@ -1664,6 +1664,9 @@ DeliverEventsToWindow(DeviceIntPtr pDev, register WindowPtr pWin, xEvent
|
|||
this mask is the mask of the grab. */
|
||||
int type = pEvents->u.u.type;
|
||||
|
||||
if (!ACDeviceAllowed(pWin, pDev))
|
||||
return 0;
|
||||
|
||||
/* CantBeFiltered means only window owner gets the event */
|
||||
if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
|
||||
{
|
||||
|
@ -2748,16 +2751,20 @@ DeliverGrabbedEvent(register xEvent *xE, register DeviceIntPtr thisDev,
|
|||
}
|
||||
if (!deliveries)
|
||||
{
|
||||
FixUpEventFromWindow(thisDev, xE, grab->window, None, TRUE);
|
||||
deliveries = TryClientEvents(rClient(grab), xE, count,
|
||||
(Mask)grab->eventMask,
|
||||
filters[xE->u.u.type], grab);
|
||||
if (deliveries && (xE->u.u.type == MotionNotify
|
||||
if (ACDeviceAllowed(grab->window, thisDev))
|
||||
{
|
||||
|
||||
FixUpEventFromWindow(thisDev, xE, grab->window, None, TRUE);
|
||||
deliveries = TryClientEvents(rClient(grab), xE, count,
|
||||
(Mask)grab->eventMask,
|
||||
filters[xE->u.u.type], grab);
|
||||
if (deliveries && (xE->u.u.type == MotionNotify
|
||||
#ifdef XINPUT
|
||||
|| xE->u.u.type == DeviceMotionNotify
|
||||
|| xE->u.u.type == DeviceMotionNotify
|
||||
#endif
|
||||
))
|
||||
thisDev->valuator->motionHintWindow = grab->window;
|
||||
))
|
||||
thisDev->valuator->motionHintWindow = grab->window;
|
||||
}
|
||||
}
|
||||
if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
|
||||
#ifdef XINPUT
|
||||
|
|
21
dix/window.c
21
dix/window.c
|
@ -452,6 +452,13 @@ CreateRootWindow(ScreenPtr pScreen)
|
|||
pWin->optional->inputMasks = NULL;
|
||||
pWin->optional->deviceCursors = NULL;
|
||||
#endif
|
||||
|
||||
pWin->optional->access.perm = NULL;
|
||||
pWin->optional->access.deny = NULL;
|
||||
pWin->optional->access.nperm = 0;
|
||||
pWin->optional->access.ndeny = 0;
|
||||
pWin->optional->access.defaultRule = 0;
|
||||
|
||||
pWin->optional->colormap = pScreen->defColormap;
|
||||
pWin->optional->visual = pScreen->rootVisual;
|
||||
|
||||
|
@ -505,7 +512,6 @@ CreateRootWindow(ScreenPtr pScreen)
|
|||
|
||||
if (disableSaveUnders)
|
||||
pScreen->saveUnderSupport = NotUseful;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -523,6 +529,7 @@ InitRootWindow(WindowPtr pWin)
|
|||
pWin->optional->cursor = rootCursor;
|
||||
rootCursor->refcnt++;
|
||||
|
||||
|
||||
if (!blackRoot && !whiteRoot) {
|
||||
MakeRootTile(pWin);
|
||||
backFlag |= CWBackPixmap;
|
||||
|
@ -3660,6 +3667,9 @@ CheckWindowOptionalNeed (register WindowPtr w)
|
|||
pNode = pNode->next;
|
||||
}
|
||||
}
|
||||
if (optional->access.nperm != 0 ||
|
||||
optional->access.ndeny != 0)
|
||||
return;
|
||||
|
||||
parentOptional = FindWindowWithOptional(w)->optional;
|
||||
if (optional->visual != parentOptional->visual)
|
||||
|
@ -3705,8 +3715,12 @@ MakeWindowOptional (register WindowPtr pWin)
|
|||
#endif
|
||||
#ifdef XINPUT
|
||||
optional->inputMasks = NULL;
|
||||
optional->deviceCursors = NULL;
|
||||
#endif
|
||||
optional->deviceCursors = NULL;
|
||||
optional->access.nperm = 0;
|
||||
optional->access.ndeny = 0;
|
||||
optional->access.perm = NULL;
|
||||
optional->access.deny = NULL;
|
||||
parentOptional = FindWindowWithOptional(pWin)->optional;
|
||||
optional->visual = parentOptional->visual;
|
||||
if (!pWin->cursorIsNone)
|
||||
|
@ -3771,6 +3785,9 @@ DisposeWindowOptional (register WindowPtr pWin)
|
|||
pWin->optional->deviceCursors = NULL;
|
||||
}
|
||||
|
||||
xfree(pWin->optional->access.perm);
|
||||
xfree(pWin->optional->access.deny);
|
||||
|
||||
xfree (pWin->optional);
|
||||
pWin->optional = NULL;
|
||||
}
|
||||
|
|
|
@ -445,6 +445,37 @@ extern void SwitchCorePointer(DeviceIntPtr pDev);
|
|||
extern DeviceIntPtr LookupDeviceIntRec(
|
||||
CARD8 deviceid);
|
||||
|
||||
/* Pairing input devices */
|
||||
extern int PairDevices(ClientPtr client,
|
||||
DeviceIntPtr pointer,
|
||||
DeviceIntPtr keyboard);
|
||||
|
||||
extern Bool RegisterPairingClient(ClientPtr client);
|
||||
extern Bool UnregisterPairingClient(ClientPtr client);
|
||||
|
||||
/* Window/device based access control */
|
||||
extern Bool ACRegisterClient(ClientPtr client);
|
||||
extern Bool ACUnregisterClient(ClientPtr client);
|
||||
extern int ACClearWindowAccess(ClientPtr client,
|
||||
WindowPtr win,
|
||||
int what);
|
||||
extern int ACChangeWindowAccess(ClientPtr client,
|
||||
WindowPtr win,
|
||||
int defaultRule,
|
||||
DeviceIntPtr* perm_devices,
|
||||
int npermit,
|
||||
DeviceIntPtr* deny_devices,
|
||||
int ndeny);
|
||||
extern void ACQueryWindowAccess(WindowPtr win,
|
||||
int* defaultRule,
|
||||
DeviceIntPtr** perm,
|
||||
int* nperm,
|
||||
DeviceIntPtr** deny,
|
||||
int* ndeny);
|
||||
|
||||
extern Bool ACDeviceAllowed(WindowPtr win,
|
||||
DeviceIntPtr dev);
|
||||
|
||||
/* Implemented by the DDX. */
|
||||
extern int NewInputDeviceRequest(
|
||||
InputOption *options);
|
||||
|
@ -454,11 +485,4 @@ extern void DDXRingBell(
|
|||
int pitch,
|
||||
int duration);
|
||||
|
||||
extern int PairDevices(ClientPtr client,
|
||||
DeviceIntPtr pointer,
|
||||
DeviceIntPtr keyboard);
|
||||
|
||||
extern Bool RegisterPairingClient(ClientPtr client);
|
||||
extern Bool UnregisterPairingClient(ClientPtr client);
|
||||
|
||||
#endif /* INPUT_H */
|
||||
|
|
|
@ -77,6 +77,14 @@ typedef struct _DevCursorNode {
|
|||
struct _DevCursorNode* next;
|
||||
} DevCursNodeRec, *DevCursNodePtr, *DevCursorList;
|
||||
|
||||
typedef struct _WindowAccessRec {
|
||||
int defaultRule; /* WindowAccessDenyAll */
|
||||
DeviceIntPtr* perm;
|
||||
int nperm;
|
||||
DeviceIntPtr* deny;
|
||||
int ndeny;
|
||||
} WindowAccessRec, *WindowAccessPtr;
|
||||
|
||||
typedef struct _WindowOpt {
|
||||
VisualID visual; /* default: same as parent */
|
||||
CursorPtr cursor; /* default: window.cursorNone */
|
||||
|
@ -97,6 +105,7 @@ typedef struct _WindowOpt {
|
|||
struct _OtherInputMasks *inputMasks; /* default: NULL */
|
||||
#endif
|
||||
DevCursorList deviceCursors; /* default: NULL */
|
||||
WindowAccessRec access;
|
||||
} WindowOptRec, *WindowOptPtr;
|
||||
|
||||
#define BackgroundPixel 2L
|
||||
|
|
Loading…
Reference in New Issue