QubesOS / qubes-issues

The Qubes OS Project issue tracker
https://www.qubes-os.org/doc/issue-tracking/
544 stars 48 forks source link

enable qvm-service `gui-agent-virtual-input-device` for Whonix-Workstation App Qubes by default #8534

Open adrelanos opened 1 year ago

adrelanos commented 1 year ago

Quote skyzzuu:

That PR was just approved by Qubes. Whenever the new gui agent arrives, it can be enabled in the whonix templates using the qvm-service gui-agent-virtual-input-device.

We should enable the qvm-service gui-agent-virtual-input-device by default using qubes-core-admin-addon-whonix?

related development notes on qubes-core-admin-addon-whonix: Dev/Qubes - Whonix chapter qvm-tags in Whonix wiki

We could prepare a PR but not merge it yet to give manually testing enabling qvm-service gui-agent-virtual-input-device to see if kloak in Qubes time.

suggested timeline:

  1. The related PR https://github.com/QubesOS/qubes-gui-agent-linux/pull/194 which makes this possible hitting Qubes testing (or stable) repository.
  2. Writing documentation and inviting testers to manually test qvm-service gui-agent-virtual-input-device this.
  3. Enabling qvm-service gui-agent-virtual-input-device by default for everybody for all Whonix-Workstation App Qubes.

The draft PR to enable qvm-service gui-agent-virtual-input-device by default in qubes-core-admin-addon-whonix could be contributed at any time.

related:

DemiMarie commented 1 year ago

I expect this to work well so long as there is only one window in the qube, but this may cause synchronization problems when there are multiple windows in the qube.

skyzzuu commented 1 year ago

I expect this to work well so long as there is only one window in the qube, but this may cause synchronization problems when there are multiple windows in the qube.

Within the handle_keypress function, it's split up into 2 separate sections, one that only ever writes to /dev/uinput and one that only ever writes to the xserver fd. The section that runs depends on whether virtual input device creation was requested or not.

Running a quick test of this with virtual input device creation requested within a qube with gnome-text-editor in 1 window, and gnome-terminal with nano running in another produces the following results on my device:

shift test: start in gnome-text-editor press and hold down shift switch to nano while still holding shift typing produces upper-case characters release shift switch back to gnome-text-editor typing produces lower-case characters

caps-lock test: start in gnome-text-editor press down caps-lock switch to nano with caps-lock still down typing produces upper-case characters press caps-lock again to disable switch back to gnome-text-editor typing produces lower-case characters

ctrl test: start in gnome-text-editor press and hold down ctrl switch to nano and press s nano writes out the current file release ctrl switch back to gnome-text editor pressing s types out a lower-case s

I receive the same results when switching between windows in different qubes even if there are several windows opened in each one.

In this case since it should only be writing to uinput, modifier sync should happen independent of the current window. The other section of handle_keypress is the original handle_keypress function that runs when the qvm-service is not enabled.

There was an issue originally with modifier syncing when switching between qubes, but that was addressed by having the gui-agent remember the last known state of the modifier, and then sending either a key down or key up if there's a change in state, then updating the state in last_known_modifier_states.

adrelanos commented 1 year ago

I expect this to work well so long as there is only one window in the qube, but this may cause synchronization problems when there are multiple windows in the qube.

If this is an issue it would be best to move it to a separate ticket. What you describe sounds very important. But the scope of this ticket is rather simple in comparison.

DemiMarie commented 1 year ago

I expect this to work well so long as there is only one window in the qube, but this may cause synchronization problems when there are multiple windows in the qube.

If this is an issue it would be best to move it to a separate ticket. What you describe sounds very important. But the scope of this ticket is rather simple in comparison.

I’m not sure which ticket this should belong with.

The problem is that Xorg has its own idea of what the window stacking order is. It is absolutely not wanted here, but getting rid of it requires changes to Xorg that nobody is interested in doing. The (partial) workaround is to raise a window before sending events to it. However, this requires that sending events to the X server is synchronized with manipulating the X11 window stacking order. This is only possible if event delivery is synchronous, not if it is asynchronous. Additionally, the X11 GUI agent is going to eventually be replaced by a Wayland compositor, currently at https://github.com/DemiMarie/qubes-compositor. The Wayland compositor does not kernel input events at all, and does not even have a driver to communicate with the kernel input subsystem.

More fundamentally, the GUI agent is the wrong place to solve this — if someone compromises the VM, they will still be able to get precise input events, compromising anonymity. A much better solution is to run kloak on the host, or incorporating its functionality into the GUI daemon on the host. This ensures that anonymization is done before the (potentially compromised) guest gets access to the events. It also solves the event routing problem. In short, the guest is the wrong place to fix this, and while gui-agent-virtual-input-device is a temporary workaround, it will stop working in the future.

marmarek commented 1 year ago

I’m not sure which ticket this should belong with.

Not this one. This one is about enabling the feature for Whonix VMs, not how the feature itself works.

adrelanos commented 2 months ago

Since https://github.com/QubesOS/qubes-gui-agent-linux/pull/194 was implemented, this ticket is now unblocked.

Anyone please feel free to help with this one.

//cc @skyzzuu