wez / evremap

A keyboard input remapper for Linux/Wayland systems, written by @wez
MIT License
401 stars 32 forks source link

Feature request: execute command on keypress #15

Open ngxson opened 2 years ago

ngxson commented 2 years ago

I've been looking for a lightweight input remapper. You project is absolutely amazing, it's so efficient and so easy to work with.

I created a forked version of the project. I added the ability to execute command using a hotkey. In my case, that's the command to logout from gnome session (to be used in case of GPU hang). Here's link to my forked version: https://github.com/ngxson/hobby-evremap/blob/master/src/remapper.rs#L446

However, since I don't have much knowledge about rust, I can only hard-code the command. It would be nice to have an option in the toml file.

wez commented 2 years ago

I've avoided coding this because it opens up some additional security concerns around verifying that the config hasn't been modified by someone in a way that might lead to a privilege escalation attack.

Ignoring that for the moment, I think there is a simple way to implement this feature and make it configurable.

Add something like:

   Exec {
     input: HashSet<KeyCode>,
     program: Vec<String>,
   }

to the Mapping enum: https://github.com/wez/evremap/blob/master/src/mapping.rs#L38

and

#[derive(Debug, Deserialize)]
struct ExecConfig {
   input: Vec<KeyCodeWrapper>,
   program: Vec<String>,
}

and then:

    #[serde(default)]
    exec: Vec<ExecConfig>,

to https://github.com/wez/evremap/blob/master/src/mapping.rs#L116

that would allow adding entries like this to the config:

[[exec]]
input = ["KEY_SHOP"]
exec = ["sudo", "-u", "ngxson", "gnome-session-quit", "--force"]

then I think that you could check the exec mappings in compute_keys and execute the program there if it matched. Probably want to return an empty set when you match an exec rule.

ngxson commented 2 years ago

Thanks for the suggestion ;-)

Yeah I understand that there's a risk of privilege escalation. Therefore, I have another idea: can we add an argument to enable this feature at will?

For example, normally we run evremap remap config.toml
But if we want to use exec: evremap remap-with-exec config.toml

This should allow advanced users to remap key to specific functions. Provided that Wayland does not support global hotkey (yet?), having the ability to map a hotkey to a command should be a nice-to-have feature.

wez commented 2 years ago

Yeah I understand that there's a risk of privilege escalation. Therefore, I have another idea: can we add an argument to enable this feature at will?

That doesn't change the risk: whether it is remap or remap-with-exec, if the config file is read by a service that automatically runs as root and uses that subcommand, then care needs to be take to secure it. Making a different subcommand doesn't buy us anything.

Wayland does not support global hotkey (yet?), having the ability to map a hotkey to a command should be a nice-to-have feature.

That's another level of complication: if evremap runs as a system service as root, and you want it to execute things in the wayland session as the appropriate logged in user, you'll need to do something complex to safely map to the appropriate user in that session.

This is more difficult than simply verifying that the config is owned by root before allowing the service to run.

ngxson commented 2 years ago

That doesn't change the risk: whether it is remap or remap-with-exec, if the config file is read by a service that automatically runs as root and uses that subcommand, then care needs to be take to secure it. Making a different subcommand doesn't buy us anything.

Technically it doesn't, but mentally maybe. It's a way to convey the idea that "hey, if you use remap-with-exec, you are taking the risk". I expect to have 2 types of users who use the program: ones just follow the guide and don't really (or strictly) care about security, ones trust their system and know what's the risk.

Also, if the attacker has the ability to modify both systemd unit (i.e. add remap-with-exec argument) and modify the config.toml file to add their malicious code, in that case, I don't think it's worth to attack evremap anymore.

I'm more like an user who cares more about the usability (functions, performance, aesthetic,...) so sorry if it's quite contentious here.

That's another level of complication: if evremap runs as a system service as root, and you want it to execute things in the wayland session as the appropriate logged in user, you'll need to do something complex to safely map to the appropriate user in that session.

The user can also run evremap as normal user. But even running as root, I think it's totally up to the user to define which way they want to communicate between evremap and logged in session.

In my case for example, I have 2 possible use cases:

And of course it's up to you to decide if it's worth adding this feature to your project. To me, I'm still ok with my setup (hard-coded command). I just want to share a possible use case ;-)