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

keyboard linux with no-root user, but in "input" group #312

Open
segalion opened this issue Nov 25, 2019 · 16 comments
Open

keyboard linux with no-root user, but in "input" group #312

segalion opened this issue Nov 25, 2019 · 16 comments

Comments

@segalion
Copy link

segalion commented Nov 25, 2019

Its supposed that keyboard linux only work with root user, and this situation cant never be a solution.

I want to modify system to give access to a generic user (example pi user), to execute python from this user instead root, changing permissions...

pi@rpi4:/ $ groups
pi adm dialout cdrom sudo audio video plugdev games users input netdev lpadmin gpio i2c spi
pi@rpi4:/ $ ls -la  /dev/input/event1
crw-rw---- 1 root input 13, 65 nov 24 20:44 

As you can see, 'pi' user is supposed to have read and write access to /dev/input/event1, because
it belongs to 'input' group, and /dev/input/event* files are assigned to group 'input', with rw access for users belonging to that group.

I have changed your code to bypass ensure_root() , but even with this, I get this error:

 python3 -m keyboard
/home/pi/.local/lib/python3.7/site-packages/keyboard/_nixkeyboard.py:110: UserWarning: Failed to create a device file using `uinput` module. Sending of events may be limited or unavailable depending on plugged-in devices.
  device = aggregate_devices('kbd')
Couldn't get a file descriptor referring to the console

Any clue?

@Rawleenc
Copy link

Rawleenc commented Feb 6, 2020

I've checked for this issue too and I've seen that when you ignore the ensure_root() function, there is this line :

device = aggregate_devices('kbd')

which need to access the /dev/uinput file, and this file have a strictly restricted access crw------- only for root...

It's quite disappointing since I wanted to use this library in a docker based continuous integration process, and when using the software as a user, it would be annoying to have to launch the app as root each time... I though first that if your user is in the input group it have access to /dev/input files and only these files are required to listen to keyboard events but obviously I was wrong.

@d4v3y0rk
Copy link

i am trying to figure out how to do this as well. I have created a udev rules file in

/etc/udev/rules.d/12-input.rules

with the following content

SUBSYSTEM=="input", MODE="0666" GROUP="plugdev"

this allows me (as expected) to cat /dev/input/eventX and see keyboard raw input data.
i am running into another problem though, it seems this library might be creating a "fake" catchall device for the various keyboard devices. this device that is created is not getting the same permissions as the rest of the input event devices.

I am hoping this further info will help us figure out how to use this without sudo.
thoughts?

@d4v3y0rk
Copy link

I actually figured this out. comment out the two calls to ensure_sudo()
and place this content into

/etc/udev/rules.d/12-input.rules

content:

SUBSYSTEM=="input", MODE="0666" GROUP="plugdev"
SUBSYSTEM=="misc", MODE="0666" GROUP="plugdev"
SUBSYSTEM=="tty", MODE="0666" GROUP="plugdev"

I am not sure of the security implications of allowing 0666 w+r for everyone on those devices. I would think that doing that will allow anyone (in a multiuser env) to "listen" to keystrokes from other users... so be careful with this.

@d4v3y0rk
Copy link

sadly my fix does not seem to work on a raspberry pi
the creation of /dev/input/event3 for some reason is not taking the permissions from the SUBSYSTEM=="input" entry.

@boppreh
Copy link
Owner

boppreh commented Sep 27, 2021

Copying my comment from #489:

I agree that requiring root is a big, big requirement, and invalidates the use of this library in many cases.

But It's not just /dev/input that requires special privileges, it's also dumpkeys. And I couldn't find any specific group that allows dumpkeys usage without literally being root, and not using this external program means there's no way to map scan codes to key names.

The only way forward I see is to enable an alternative X-based input event manager, but that's also a (partially) doomed proposition due to the rise of Wayland.

Suggestions welcome.

@lyiriyah
Copy link

Uhh I can run dumpkeys fine without root. Here's my groups output: tty games network power users video uucp storage optical input audio wheel lyiriyah uaccess

@boppreh
Copy link
Owner

boppreh commented Sep 29, 2021

Thank you @lyiriyah , you're the first one to report being able to run dumpkeys without root, and your list of groups helped me drill down into what was missing: the tty group.

There are three special groups a user needs to be in to use all keyboard features on Linux:

The first two are easy enough to fix and report, so I've removed the ensure_root function and replaced with warnings and instructions on how to add yourself to the required groups: 7f03a3d .

I'm not comfortable telling users to mess with their uinput rules at the moment.

Can you give the newest version a run to see if it helps with your issue?

@lyiriyah
Copy link

I'll try when I get home

@TTWNO
Copy link

TTWNO commented Nov 16, 2021

Has anything changed since last time somebody commented on this?

I found this issue while looking into libinput, which I believe uses the same /dev/input/event* files.

@boppreh
Copy link
Owner

boppreh commented Nov 16, 2021

My previous comment here summarizes the situation, no news since then.

@linux-man
Copy link

I can run "pressed_keys.py" just fine on Linux Mint 20.2, adding tty and input groups.
Just a typo, at _nixkeyboard.py line 76 warning; change "useradd" to "usermod".
Can the same be done on boppreh/mouse library?

@Avasam
Copy link
Contributor

Avasam commented Jul 20, 2022

Following the discussion here and the linked stackoverflow answer, I ran the following:

sudo usermod -a -G tty,input $USER
sudo chmod +0666 /dev/uinput
echo 'KERNEL=="uinput", TAG+="uaccess""' > /etc/udev/rules.d/50-uinput.rules
echo 'SUBSYSTEM=="input", MODE="0666" GROUP="plugdev"' > /etc/udev/rules.d/12-input.rules
echo 'SUBSYSTEM=="misc", MODE="0666" GROUP="plugdev"' >> /etc/udev/rules.d/12-input.rules
echo 'SUBSYSTEM=="tty", MODE="0666" GROUP="plugdev"' >> /etc/udev/rules.d/12-input.rules
loginctl terminate-user $USER

and I still see # ERROR: Failed to read device '/dev/input/event5'. You must be in the 'input' group to access global events. Use 'sudo usermod -a -G input USERNAME' to add user to the required group. appear in my console

Edit: The segfault I was getting was actually PyQt6 related and had nothing to do with keyboard. So I snipped out that part of my comment.
Edit 2: So, despite this message appearing, once I got past other unrelated issues, it seems the keys are indeed caught. So it works?

@adabru
Copy link

adabru commented Jan 19, 2023

I'm getting the same message as Avasam but it is working fine. I think this issue can be closed.

@Avasam
Copy link
Contributor

Avasam commented Jan 20, 2023

There was an early initialization attempt whenever the keyboard module was simply imported (this is why you had to use root or setup your groups first to even install)! But I've resolved that in #568

So the solution now is to setup your groups and permissions as described. This is as good as it'll get with the current method of listening for keys.

So I also believe this can be closed in favor of #538, #124 and #33

@phil294
Copy link

phil294 commented Apr 23, 2023

fyi there's an ever better solution than root or input group: sudo setcap "cap_dac_override=+p" path-to-program. This requires cooperation by the program itself though, see for example Espanso's docs: https://espanso.org/docs/install/linux/#adding-the-required-capabilities

@qwertychouskie
Copy link

Works on my system after adding my user to the relevant groups. I still get # ERROR: Failed to read device '/dev/input/event17'. You must be in the 'input' group to access global events. Use 'sudo usermod -a -G input USERNAME' to add user to the required group., however it works just fine.

@boppreh Any chance of getting a new version tagged and released to PyPI? I had to find this issue and manually download the latest version, things would be much easier if a new release was tagged.

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

No branches or pull requests