Request for auto-connect of uinput interface for Emote

Emote is a small utility that provides a popup emoji selector. On selection, the emojis are inserted into the currently focused app by simulating a ctrl-v clipboard paste. On x11, this is achieved by using xdotool.

I am currently in the process of adding support for wayland. To support similar auto-paste functionality on wayland, I’m using ydotool. ydotool requires access to uinput as it works by emulating a virtual input device.

This means I will need the snap to auto-connect to the uinput interface in order to actually work on wayland. As such - I’d like to request that the snap be granted permission to auto-connect on this interface.

The use of the interface will be limited to the outputting of ctrl+v (https://github.com/tom-james-watson/Emote/blob/wayland-support/emote/picker.py#L472).

Many thanks.

Snap:

PR for wayland support:

If there’s any more information needed to process this then please let me know.

The uinput interface is super-privileged since it allows arbitrary injection of input to the system, and since it seems to be a common pattern for software that uses uinput to guide users to chmod 666 /dev/uinput to work-around accessing this as a standard user.

Since emote is using ydotool to access uinput can you explain how it gets around this access restriction? I notice on the ydotool README they say that root privileges is usually required - this makes sense, so is emote running as a root-daemon?

It looks like ydotool works in a client/server mode with a server listening for commands on a unix domain socket at /tmp/.ydotool_socket. In theory that would allow a snap to use the interface without changing device permissions, and the snap’s copy of ydotoold shouldn’t be accessible to other applications due to private /tmp.

Of course, the rest of the security concerns still apply: unlike the xdotool implementation, this will allow generating input seen by any user on the system, and due to the design you’d have code making use of this ability running from boot.

It looks like ydotool works in a client/server mode with a server listening for commands on a unix domain socket at /tmp/.ydotool_socket. In theory that would allow a snap to use the interface without changing device permissions, and the snap’s copy of ydotoold shouldn’t be accessible to other applications due to private /tmp.

Yeah, that’s right. Emote simply starts the ydotoold daemon on app start. Invocations of ydotool to paste the emojis then communicate with ydotoold via /tmp/.ydotool_socket.

I can appreciate that the general security concerns still need considering. I think this is the kind of situation where an android-style permission dialog would be perfect, but obviously we’re not there yet.

The app unfortunately is not so useful without being able to paste the emoji, so I think I would need to add some in-app dialog for Wayland, directing the user to manually connect the interface. That’s understandably a UX I’d like to avoid.

How would that work, assuming that the application is not running as root? If you’re running ydotoold as a regular user, then it would be denied access to /dev/uinput even with the interface connection.

I’m not sure of the best long term solution for this kind of thing. It kind of sounds like your app wants to behave like an input method. While there has been work to make input methods usable by sandboxed applications (e.g. via ibus-portal), but there hasn’t been anything to support sandboxed input methods.

Without that, the best you’re likely to handle is putting the emoji on the clipboard, and then rely on the user to paste it.

It looks like I have changed the permissions of /dev/uinput at some point on my machine and so have been misunderstanding how ydotool works as it has always looked like it works fine without root to me. That’s my bad. I think we can close this out because I would need to rework the implementation regardless of what I do.

I’m going to investigate something like https://github.com/bugaevc/wl-clipboard to see if there are any user space alternatives. Pasting the emoji manually is a pretty poor UX - especially if users come from the X11 implementation where it works perfectly.

Thanks for your time.

1 Like

Note that many of these changes with Wayland are intentional. When X11 was first developed, it was assumed that all clients connected to the display server were essentially running in the same security domain. So it wasn’t so bad that one application could send synthetic events to another application, or screenshot other applications.

On a modern desktop where some applications are sandboxed, those assumptions are not true. You probably don’t want a confined application to be able to feed keystrokes to the terminal emulator to run code outside of the sandbox. You don’t want it screenshotting the web browser while the user is browsing their banking website. You don’t want it reading the contents of the clipboard while it is not the foreground application.

These types of restrictions couldn’t easily be retrofitted into the X11 protocol, but are possible with Wayland.

Yeah, I appreciate the motivations behind these changes, they make perfect sense. The problem is there clearly are occasions when a user wants to be able to do some of those things, such as pasting a selected emoji into another app. At the end of the day the user ends up with a worse user experience when switching to Wayland in this case, which is a shame. Maybe as more users are moved over to Wayland these kind of things will end up being supported via user space APIs in some way or another.

Right. And I suggested input method frameworks as a way that this can work on Wayland. For example, if you’re using ibus, it’s ctrl+shift+e emoji picker works this way.

Unfortunately, I don’t think any of the input method frameworks currently support confined input method implementations.

@tomjwatson we are removing this request from our queue since you will be working on your app rework, but please feel free to write here again when needed and we will be re-opening the request.

Thanks!