Adam Jackson <[email protected]> writes:

> On Mon, 2015-11-23 at 11:04 -0800, Keith Packard wrote:
>> One of the many security holes in X is that any application can monitor
>> the state of the keyboard device by querying the list of pressed keys on
>> a regular basis. Here's a simple patch which makes that request report
>> only key state which the client itself has already seen through X
>> events.
>> 
>> With this patch in place, grabbing the keyboard should be sufficient to
>> hide key presses from other clients.
>> 
>> I think we need to try to fix some of these issues, even if the fixes
>> break existing applications.
>
> Better unbefuckinglievably late than never.  This gets xterm's Secure
> Keyboard mode to be secure against xspy, which is nice.  If we're going
> to go down this path, we should also update the protocol spec to say
> it's a legal move for the implementation.

"as seen by the client by means of the protocol", which is part of the
spec for the QueryKeys request seems big enough to drive this through,
but yeah, explicit new wording seems like a good plan.

> I assume the offset here is because of the dumb "keys 0-7 don't really
> exist" bug, right?  If so,

Yes. I was hoping that was actually correct, and decided that I'd have
to write a program to verify it.

/*
 * Copyright © 2015 Keith Packard <[email protected]>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <strings.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

static void
Error (char *s, char *a)
{
    fprintf (stderr, s, a);
    fprintf (stderr, "\n");
    exit (1);
}

static void
HandleKeyPress(Display *dpy, Window win, XEvent *ev)
{
	XKeyEvent	*kev = (XKeyEvent *) ev;
	char		quit_string[10];

	printf ("press %d\n", kev->keycode);
	if (XLookupString (kev, quit_string, sizeof (quit_string), 0, 0) == 1) {
		switch (quit_string[0]) {
		case 'q':
			exit (0);
		case 'c':
			XClearArea (dpy, kev->window, 0, 0, 0, 0, True);
			break;
		}
	}
}

static void
HandleKeyRelease(Display *dpy, Window win, XEvent *ev)
{
	XKeyEvent	*kev = (XKeyEvent *) ev;

	printf ("release %d\n", kev->keycode);
}

static void
HandleKeymapEvent(Display *dpy, Window win, XEvent *ev)
{
	XKeymapEvent	*kev = (XKeymapEvent *) ev;
	int		k;

	for (k = 0; k < 248; k++) {
		int	bit = k & 7;
		int	byte = k >> 3;
		if (kev->key_vector[byte] & (1 << bit))
			printf ("down %d\n", k);
	}
}

static void
HandleExpose(Display *dpy, Window win)
{
	char	keys[32];
	int	k;

	XQueryKeymap(dpy, keys);
	for (k = 0; k < 256; k++) {
		int	bit = k & 7;
		int	byte = k >> 3;
		if (keys[byte] & (1 << bit))
			printf ("query down %d\n", k);
	}
}

static void
PingWindow(Window win)
{
	Display	*dpy;
	dpy = XOpenDisplay(NULL);
	for (;;) {
		sleep(1);
		XClearArea(dpy, win, 0, 0, 0, 0, True);
		XFlush(dpy);
	}
}

static int ping_pid;

static void
StopPing(void)
{
	printf ("stop ping\n");
	kill(ping_pid, SIGINT);
}

int
main (argc, argv)
    int	    argc;
    char    **argv;
{
    Display *dpy;
    Window  win;
    XSetWindowAttributes    attr;
    XEvent ev;

    dpy = XOpenDisplay (NULL);
    if (!dpy)
	Error ("Can't open display", "");

    attr.background_pixel = WhitePixel(dpy, DefaultScreen(dpy));
    attr.border_pixel = BlackPixel(dpy, DefaultScreen(dpy));
    attr.event_mask = KeyPressMask|KeyReleaseMask|KeymapStateMask|ExposureMask;
    win = XCreateWindow (dpy, RootWindow(dpy, DefaultScreen(dpy)),
			 0, 0, 200, 200, 1,
			 CopyFromParent, InputOutput,
			 DefaultVisual(dpy, DefaultScreen(dpy)),
			 CWEventMask|CWBorderPixel|CWBackPixel,
			 &attr);
    XMapWindow (dpy, win);
    XFlush(dpy);

    switch ((ping_pid = fork())) {
    case 0:
	    PingWindow(win);
	    break;
    case -1:
	    Error("Can't fork", "");
	    break;
    }
    atexit(StopPing);

    for (;;) {
	    while (XEventsQueued(dpy, QueuedAfterFlush)) {
		    XNextEvent (dpy, &ev);
		    switch (ev.type) {
		    case Expose:
			    HandleExpose (dpy, ev.xexpose.window);
			    break;
		    case KeyPress:
			    HandleKeyPress (dpy, ev.xkey.window, &ev);
			    break;
		    case KeyRelease:
			    HandleKeyRelease (dpy, ev.xkey.window, &ev);
			    break;
		    case KeymapNotify:
			    HandleKeymapEvent (dpy, win, &ev);
			    break;
		    }
	    }
    }
}
-- 
-keith

Attachment: signature.asc
Description: PGP signature

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to