plugin: always obfuscate keycodes

Same approach as chosen in libinput-record, this leaves the F1-F10 out
but otherwise prints every other "normal" key (including modifiers) as
KEY_A.

In the future we may need some more specific approach but for now this
will do. For the use-cases where we do need some specific approach,
libinput record and libinput debug-events will still show the full
keycode on request anyway.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1276>
This commit is contained in:
Peter Hutterer 2025-07-20 11:05:05 +10:00
parent abd5989ee8
commit 73103a5c38
3 changed files with 68 additions and 8 deletions

View file

@ -49,6 +49,10 @@ enum evdev_usage {
EVDEV_KEY_RESERVED = _evbit(EV_KEY, KEY_RESERVED), EVDEV_KEY_RESERVED = _evbit(EV_KEY, KEY_RESERVED),
EVDEV_KEY_ESC = _evbit(EV_KEY, KEY_ESC), EVDEV_KEY_ESC = _evbit(EV_KEY, KEY_ESC),
EVDEV_KEY_A = _evbit(EV_KEY, KEY_A),
EVDEV_KEY_CAPSLOCK = _evbit(EV_KEY, KEY_CAPSLOCK),
EVDEV_KEY_KP7 = _evbit(EV_KEY, KEY_KP7),
EVDEV_KEY_KPDOT = _evbit(EV_KEY, KEY_KPDOT),
EVDEV_KEY_MICMUTE = _evbit(EV_KEY, KEY_MICMUTE), EVDEV_KEY_MICMUTE = _evbit(EV_KEY, KEY_MICMUTE),
EVDEV_KEY_OK = _evbit(EV_KEY, KEY_OK), EVDEV_KEY_OK = _evbit(EV_KEY, KEY_OK),
EVDEV_KEY_LIGHTS_TOGGLE = _evbit(EV_KEY, KEY_LIGHTS_TOGGLE), EVDEV_KEY_LIGHTS_TOGGLE = _evbit(EV_KEY, KEY_LIGHTS_TOGGLE),

View file

@ -28,6 +28,7 @@
#include "util-files.h" #include "util-files.h"
#include "util-list.h" #include "util-list.h"
#include "evdev-frame.h"
#include "evdev-plugin.h" #include "evdev-plugin.h"
#include "libinput-plugin-button-debounce.h" #include "libinput-plugin-button-debounce.h"
#include "libinput-plugin-mouse-wheel-lowres.h" #include "libinput-plugin-mouse-wheel-lowres.h"
@ -508,9 +509,17 @@ print_frame(struct libinput *libinput, struct evdev_frame *frame, const char *pr
struct evdev_event *events = evdev_frame_get_events(frame, &nevents); struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
for (size_t i = 0; i < nevents; i++) { for (size_t i = 0; i < nevents; i++) {
struct evdev_event *e = &events[i]; struct evdev_event e = events[i];
enum evdev_usage usage = evdev_usage_enum(e.usage);
switch (evdev_usage_enum(e->usage)) { if ((usage > EVDEV_KEY_ESC && usage < EVDEV_KEY_CAPSLOCK) ||
(usage >= EVDEV_KEY_KP7 && usage <= EVDEV_KEY_KPDOT)) {
e.usage = evdev_usage_from(EVDEV_KEY_A);
} else if (usage == EVDEV_MSC_SCAN) {
e.value = 30; /* KEY_A scancode */
}
switch (evdev_usage_enum(e.usage)) {
case EVDEV_SYN_REPORT: case EVDEV_SYN_REPORT:
log_debug( log_debug(
libinput, libinput,
@ -528,9 +537,9 @@ print_frame(struct libinput *libinput, struct evdev_frame *frame, const char *pr
prefix, prefix,
time / 1000, time / 1000,
time % 1000, time % 1000,
evdev_event_get_type_name(e), evdev_event_get_type_name(&e),
evdev_event_get_code_name(e), evdev_event_get_code_name(&e),
e->value); e.value);
break; break;
default: default:
log_debug(libinput, log_debug(libinput,
@ -538,9 +547,9 @@ print_frame(struct libinput *libinput, struct evdev_frame *frame, const char *pr
prefix, prefix,
time / 1000, time / 1000,
time % 1000, time % 1000,
evdev_event_get_type_name(e), evdev_event_get_type_name(&e),
evdev_event_get_code_name(e), evdev_event_get_code_name(&e),
e->value); e.value);
break; break;
} }
} }

View file

@ -523,6 +523,52 @@ START_TEST(keyboard_alt_printscreen)
} }
END_TEST END_TEST
START_TEST(keyboard_keycode_obfuscation)
{
#ifdef EVENT_DEBUGGING
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
litest_with_logcapture(li, capture)
{
litest_event(dev, EV_KEY, KEY_Q, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, KEY_Q, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_dispatch(li);
litest_drain_events(li);
/* clang-format off */
/* We get two possible debug messages:
* Queuing event14 KEYBOARD_KEY +0.000s KEY_Q (16) released
* event14: plugin evdev - 0.000 EV_KEY KEY_Q 0
*
* The latter must not exist, it must be obfuscated to KEY_A
*/
/* clang-format on */
char **strv = capture->debugs;
size_t index;
litest_assert(strv_find_substring(strv, "KEY_Q", &index));
do {
litest_assert_str_not_in("EV_KEY", strv[index]);
strv += index + 1;
} while (strv_find_substring(strv, "KEY_Q", &index));
strv = capture->debugs;
litest_assert(strv_find_substring(strv, "KEY_A", &index));
do {
litest_assert_str_in("EV_KEY", strv[index]);
strv += index + 1;
} while (strv_find_substring(strv, "KEY_A", &index));
}
#else
return LITEST_SKIP;
#endif
}
END_TEST
TEST_COLLECTION(keyboard) TEST_COLLECTION(keyboard)
{ {
/* clang-format off */ /* clang-format off */
@ -541,5 +587,6 @@ TEST_COLLECTION(keyboard)
litest_add(keyboard_no_scroll, LITEST_KEYS, LITEST_WHEEL); litest_add(keyboard_no_scroll, LITEST_KEYS, LITEST_WHEEL);
litest_add_for_device(keyboard_alt_printscreen, LITEST_KEYBOARD); litest_add_for_device(keyboard_alt_printscreen, LITEST_KEYBOARD);
litest_add_for_device(keyboard_keycode_obfuscation, LITEST_KEYBOARD);
/* clang-format on */ /* clang-format on */
} }