Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement secure password entry on linux (X11 server) #7

Closed
roman-modelist-dev opened this issue Apr 28, 2018 · 9 comments
Closed

Implement secure password entry on linux (X11 server) #7

roman-modelist-dev opened this issue Apr 28, 2018 · 9 comments
Assignees
Labels
enhancement New feature or request

Comments

@roman-modelist-dev
Copy link
Contributor

No description provided.

@roman-modelist-dev
Copy link
Contributor Author

Some x11 manuals about this: https://www.x.org/archive/X11R7.5/doc/security/XACE-Spec.pdf

@roman-modelist-dev roman-modelist-dev added the enhancement New feature or request label Apr 28, 2018
@sinev-valentine
Copy link
Contributor

X11 protocol have extention XTEST. It can intercepted and synthesize events.
Keystrokes can also be intercepted by the application that caused the XGrabKeyboard.
It is necessary make call xGrabKeboards, so that no one else cause it.
Also, it is necessary look field send_event of structure XAnyEvent (or any other, that have larger size, such as XKeyEvent), to avoid the effects of synthesized events.
Another way to solve problem safety input password - start a new instance of the xserver, ask for password, and then to do VT switch back. But it is harder to implement, that this would be looks nice for the user.

@sinev-valentine
Copy link
Contributor

Sample project "input PIN-code" fo X11:
https://github.com/msharov/pinentry-xlib

Discussion of problem:
https://www.linux.org.ru/forum/development/481313

A Brief intro to X11 Programming:
http://math.msu.su/~vvb/2course/Borisenko/CppProjects/GWindow/xintro.html
http://yenolam.com/writings/xlibbook-0.5.pdf

As can be seen from sample project and discussion of the problem, also it is necessary cause xGrabServer().

@sinev-valentine
Copy link
Contributor

sinev-valentine commented May 17, 2018

XGrabKeyboard and XGrabServer() is not blocking keyboard intercept.
Example of secure input password with XGrabKeyboard() and XGrabServer():
https://github.com/sinev-valentine/passentry
Grabber:
https://www.thregr.org/~wavexx/software/screenkey
Аfter starting XGrabServer window "Promt for password", stdout and window of grabber isn't refreshing.
But after program is terminated, stdout and grabber window prints password.

Structure XSetWindowAttributes have field override_redirect.
If it set to true, indicates that a window should not be managed by window managers.
Setting this to true has no effect (after that, the window did not displayed).

@sinev-valentine
Copy link
Contributor

sinev-valentine commented May 17, 2018

Can try xcb library. It contains functions xcb_grab_keyboard(), xcb_grab_server().

@sinev-valentine
Copy link
Contributor

sinev-valentine commented May 18, 2018

Ways to solve the problem:

  1. working without compositor и non-reparenting window manager.

  2. starting secondary x-server

  3. disable ability Xorg processing keypress. This can be done through synthesis of the events of disabling the device via a uevent . For this, run the unbind operation on the evdev and atkbd drivers. Then call bind (but with a different set of udev rules that prevent the user from opening the device).
    The program "Prompt for password" can open the device /dev/input/event*
    (either all at once, or by selecting the desired device from /proc/bus/input/devices) and read from there structure input_event.

  1. More "hacking" but an easy way to prevent Xorg from being able to read the keyboard:
  • connect to the process using ptrace,
  • allocate an executable memory page,
  • put there code that performs " close;open(/dev/null); dup2;int 3",
  • move $pc to this page,
  • stop at int3,
  • free page
  • give the $ pc back.
  1. another strange variant:
  • send Xorg to a separate cgroup with freezer controller,
  • disable keyboard via XINPUT (Xchangeproperty on property "DeviceEnabled") and then freeze Xorg,
  • work with the keyboard via evdev, and with the screen via fb

@sinev-valentine
Copy link
Contributor

sinev-valentine commented May 24, 2018

Problem solution:

  • call XIChangeProperty() to set property "Device Enabled" to 0
  • call ioctl(fevdev, EVIOCGRAB, 1)
  • read password from evdev
  • call XIChangeProperty() to set property "Device Enabled" to 1

Password consist of keyscans, that defined in file /usr/include/linux/input-event-codes.h
To getting password in unicode format it is necessary:
keyscans -> keycode(Xorg) -> keysym(Xorg) -> unicode

For this:

  • keyscans + 8 (see str. 280 in evdev.c: https://cgit.freedesktop.org/xorg/driver/xf86-input-evdev/tree/src/evdev.c)
  • use XkbGetState() to define keyboard layout
    use XkbKeycodeToKeysym() for convert keycode(Xorg) to keysym(Xorg).
  • use keysym2ucs() to convert keysym(Xorg) to unicode.
    Note: Unacceptably convert keycode(Xorg) to keysym(Xorg) after each key pressed.
    Instead of this, it is necessary convert keycodes for all keysym of keyboard layout before password entry.

Contorl keys (Enter, Backspace, Delete, Esc) is defined as keycode evdev drives.

It is necessary identity correctly device "keyboard" for it grabbing.

For this:

  • disable all devices, that "slave keyboard" in xinput list.
  • to correcty define evdev-ID: parse /proc/bus/input/devices using regular expression:
    "H: Handlers=.kbd. event[0-9]+".
  • read selected devices with checking event type and event code. To choose keyboard by event type=EV_KEY and by event code<=255.

To geting correctly symbols it is necessary consider modificators (Shift, Capslock, ... ).
Also, it is need to implement read of symbols , that require press more one key for input. (For example, French layout).

For enhanced security, program "password entry" should not have GUI. It is proposed to implement GUI in another programm, that started and controlled through pipe.

@sinev-valentine
Copy link
Contributor

sinev-valentine commented Jun 5, 2018

All items completed except:

Source files:
https://github.com/arrayio/array-io-keychain/tree/research
GUI: https://github.com/arrayio/array-io-keychain/tree/research/app/linux

@sinev-valentine
Copy link
Contributor

depended task #10 is need to implement in future

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants