Skip to content

Multi-device support #38

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

Merged
merged 56 commits into from
Aug 16, 2023
Merged

Multi-device support #38

merged 56 commits into from
Aug 16, 2023

Conversation

vmonaco
Copy link
Owner

@vmonaco vmonaco commented Sep 20, 2021

This PR adds support for obfuscating multiple devices simultaneously. This addresses #7 and #37.

Changes include:

  • Support multiple devices each specified by the '-r' flag. No need to specify '-w' anymore since the output devices are created
  • Add support to autodetect all keyboard and pointing devices
  • Use libevdev for uinput device creation
  • Use libsodium for PRNG
  • Lower the default max delay to 20ms, enough to obfuscate device fingerprints

I lowered the max delay to 20ms because obfuscating a pointer device by even a small amount introduces a noticeable lag. Users are much more perceptive of pointing lag compared keyboard lag. This includes devices that emit REL_X and REL_Y events (most computer mice) or ABS_X and ABS_Y events (typically includes virtual machines).

Events should be emitted in the order they were received (FIFO), otherwise there could be unwanted effects if events become permuted, e.g., performing a drag-and-drop requires a particular sequence of motion and click events. It might be possible to maintain a separate max delay for each physical device so long as events are not permuted.

Another option is to adjust the max delay depending on whether a pointing device is currently being used. A heuristic could look something like "if number of motion events exceeds 5 in the past 1 second, then set the max delay to 20ms, otherwise set the max delay to 100ms".

@vmonaco
Copy link
Owner Author

vmonaco commented Sep 20, 2021

Note: I haven't updated any of the debian packaging yet. libsodium and libevdev are now dependencies.

What's the preferred build chain on Whonix? I was going to just stick a "$(shell pkg-config --cflags --libs libevdev)" into the Makefile, but this probably isn't very portable, and pkg-config doesn't come installed on Whonix by default anyway. Any suggestions?

@adrelanos
Copy link
Contributor

Build dependencies or runtime dependencies?


For build dependencies:

Change debian/control from:

Build-Depends: debhelper (>= 13), debhelper-compat (= 13), dh-apparmor

to:

Build-Depends: debhelper (>= 13), debhelper-compat (= 13), dh-apparmor, libsodium, libevdev


For runtime dependencies:

Change from:

Depends: ${shlibs:Depends}, ${misc:Depends}

to:

Depends: ${shlibs:Depends}, ${misc:Depends}, libsodium, libevdev


Would that work?

Makefile I don't know yet. pkg-config could be added to Build-Depends: if need be.

@vmonaco
Copy link
Owner Author

vmonaco commented Sep 21, 2021

Thanks, I added the runtime and build dependencies.

Might be easiest to add pkg-config as well unless there's another command to get the cflags for a particular package on Whonix. The other option would be to use something like autoconf or cmake, but those seem overkill for this application.

@adrelanos
Copy link
Contributor

Might be easiest to add pkg-config

Not a problem at all for Build-Depends:. From packager perspective, it's just all the dependencies that upstream defined. Problem only becomes if these are unavailable rom packages.debian.org repository for the suite (currently bullseye).

@HulaHoop0
Copy link

Another option is to adjust the max delay depending on whether a pointing device is currently being used. A heuristic could look something like "if number of motion events exceeds 5 in the past 1 second, then set the max delay to 20ms, otherwise set the max delay to 100ms".

Could the events coming from mice be distinguished and treated separately from keyboard ones more easily? perhaps by separating them according to Linux device nomenclature or some other method? - That way the best threshold is maintained for the separate device types while not impacting performance or protection.

I found some code that interacts with udev to tell them apart:

https://www.mattfischer.com/blog/archives/182

https://naiveprogrammer.blogspot.com/2011/01/using-udev-to-catch-keyboard-and-mouse.html

@vmonaco
Copy link
Owner Author

vmonaco commented Sep 23, 2021

Could the events coming from mice be distinguished and treated separately from keyboard ones more easily? perhaps by separating them according to Linux device nomenclature or some other method? - That way the best threshold is maintained for the separate device types while not impacting performance or protection.

Yes, absolutely. I've already stuck some functions in there to determine whether a device is a keyboard or mouse, and maintaining a separate threshold for each device class is certainly possible. The only potential issue is if both devices are being used simultaneously, events across the devices could become permuted but within each device they would maintain order. For example, physical action sequence:

key down -> mouse button down -> mouse button up -> key up

could become:

mouse button down -> mouse button up -> key down -> key up

if the key down and up events are delayed beyond the time the mouse button down and up events are released.

I found some code that interacts with udev to tell them apart:

https://www.mattfischer.com/blog/archives/182

https://naiveprogrammer.blogspot.com/2011/01/using-udev-to-catch-keyboard-and-mouse.html

Awesome, thanks for the links

@qua3k
Copy link

qua3k commented Sep 23, 2021

You should call sodium_init() before any other function provided by sodium to initialize the library.

If libsodium cannot be initialized it is not safe to use.

@vmonaco
Copy link
Owner Author

vmonaco commented Sep 23, 2021

@qua3k fixed, thanks a lot for catching that

@vmonaco
Copy link
Owner Author

vmonaco commented Sep 24, 2021

@adrelanos, running kloak directly as root seems to work fine, but building the deb package and running as a service fails at creating the new ui devices at this line:
https://github.com/vmonaco/kloak/blob/dev/src/main.c#L208

I suspect the apparmor profile needs to be changed. I tried changing
owner /dev/input/event* r,
to
owner /dev/input/event* rw,
with no luck. Any ideas? Do we need to add a udev rule to allow device creation?

@adrelanos
Copy link
Contributor

aa-logprof might help. Since you're already a user of git, aa-logprof might easily tell us what's missing. Written a guide how to use it just now:
https://www.whonix.org/wiki/AppArmor#Fix_Profiles

Does that help?

Related:

@vmonaco
Copy link
Owner Author

vmonaco commented Jul 9, 2023

Any help here would be appreciated :) admittedly I don't have many cycles to work on it currently.

Pretty sure it was an issue with AppArmor and I have something not configured correctly.

@adrelanos
Copy link
Contributor

We must not allow security hardening to stop the development of this project.

  • Seccomp was a nice contribution but the original contributor is no longer around. There's an issue I couldn't fix after a few hours. Hence, disabling SystemCallFilter in the dev branch. Later others are welcome to contribute a fix. I don't think secomp is important for kloak since I don't see what attack surface kloak attacks to the system.
  • Similar for AppArmor. It's nice but not essential for this project at all. AppArmor however I might be able to fix with reasonable effort.

adrelanos added a commit to Whonix/kloak that referenced this pull request Jul 9, 2023
@adrelanos adrelanos mentioned this pull request Jul 9, 2023
@adrelanos
Copy link
Contributor

From now, for any AppArmor issues I suggest:

  • A) locally disable the apparmor profile (easiest is to delete the file and reboot)
  • B) and/or leave it broken. I'll pick it up from there. AppArmor is very fixable for me since I've been working with it for many years now. So that really shouldn't slow down this project.

@vmonaco
Copy link
Owner Author

vmonaco commented Aug 14, 2023

finally determined the root cause here, there were a few missing seccomp filters. Added them back to the service file and it works now.

Do you want to test one more time on Whonix to make sure everything works properly and then I think we're ready to merge?

@adrelanos
Copy link
Contributor

This branch is ready to merge. And it's just a merge into the dev branch. So should be merged either way as soon as possible.

But it won't work on its own due to seccomp and apparmor issues. These however are resolved in my PR #49 which I updated just now.

Therefore I recommend to merge this one first then then merge #49 after that.

In case of the C level changes in #49 deemed not ready, I recommend either:

  • A) disable apparmor and seccompt upstream (here), or
  • B) add my apparmor and seccomp fixes, or
  • C) ask me to provide a pull request as soon as this branch was merged which I am happy to provide very soon.

@adrelanos
Copy link
Contributor

Forgot to mention, I tested this + #49 in Whonix today and it was working fine.

@vmonaco
Copy link
Owner Author

vmonaco commented Aug 16, 2023

changes in #49 all look good, thanks!

skyzzuu added a commit to skyzzuu/kloak that referenced this pull request Sep 9, 2023
Merge pull request vmonaco#38 from vmonaco/dev
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

Successfully merging this pull request may close these issues.

4 participants