ccMSC / ckb

RGB Driver for Linux and OS X
http://forum.corsair.com/v3/showthread.php?t=133929
GNU General Public License v2.0
1.34k stars 170 forks source link

/dev/input/ckb* readable to all #73

Open GigabyteProductions opened 9 years ago

GigabyteProductions commented 9 years ago

Since everyone has read access to /dev/input/ckb* and all files inside of these folders, they can spy on other users like so:

$ cat /dev/input/ckb1/notify1
key +p
key -p
key +a
key -a
key +s
key -s
key +s
key -s
key +w
key -w
key +o
key -o
key +r
key -r
key +d
key -d

A temporary solution could be to make these files only readable to a designated group, and if it's expected that only one user will ever use the keyboard (in this case, the other users are mostly remote users), all that's needed is to add that user to the group.

This solution is not ideal as the problem still persists if more than one user is expected to want color and G-key function. A better solution could be to only allow root or a ckb system user to read /dev/input/ckb, and change ownership on logins and sessions switches (like from the data shown from loginctl list-sessions and loginctl seat-status on Ubuntu). Another option is to make ckb-daemon handle G-key events and animations while having the ckb client tell the daemon ahead of time what to do when a key is pressed.

The best solution overall might be to register some kind of control device with the X server. This solution would probably be more compatible with Linux systems that don't have logind or session tracking, for example. I'm just not entirely sure how this could be implemented, as I'm not well acquainted with the internals of X.

ccMSC commented 9 years ago

There's a note about this at the bottom of DAEMON.MD - basically, ckb is mostly aimed at single-user systems, which makes this meaningless (there are far better ways to spy on people using Xorg). However, there is a --gid option if you're paranoid.

I've considered, and may yet implement, a system to make them available only to the user at the keyboard. It's going to be pretty hacky because it needs to use different methods for different distributions (loginctl for systemd, ck-list-sessions for Upstart, I have no idea what sysvinit uses if that's still around) and they all require parsing to get the actual UID.

GigabyteProductions commented 9 years ago

I feel stupid for not seeing DAEMON.MD. I thought X authority files prevented anyone else from connecting to your X server. Wouldn't that mitigate any spying through Xorg?

Also, would it be offensively going against your wishes if I looked into implementing this without needing to interface with all the different session managers?

ccMSC commented 9 years ago

They do. I meant specifically systems that have only one user, so there couldn't be any other users logging in remotely/using a different console.

If you could figure out a good way to implement user switching though, that would be great :) Here are the commands I came up with (run with BASH, listed in order of precedence):

IFS=$'\n'; for sess in `loginctl --no-pager --no-legend | awk '{print $1;}'`; do STATUS=`loginctl show-session "$sess"`; if [[ `echo "$STATUS" | grep -i 'Active=yes'` != "" && `echo "$STATUS" | grep -i 'VTNr=0'` == "" ]]; then echo "$STATUS" | grep -i 'Name='; break; fi; done

Output: Name=<username>

ck-list-sessions | awk 'BEGIN{ORS=""};/^[^[:blank:]]/{p=0}/^Session/{print "\n";p=1} p' | grep -i 'active\s*=\s*true' | head -1 | sed -rn "s/.*unix-user\s*=\s*'?([0123456789]+).*/unix-user=\1/p"

Output: unix-user=<uid>

stat /dev/`cat /sys/class/tty/tty0/active` | grep Uid

Output: Uid: ( <uid>/ <username>)

Statting the TTY works for VTs but not for X (maybe rootless X, haven't tried that). The other two solutions work for both. I haven't checked to see if the parameters/parsing work across all distros, might need some modification.