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
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
