summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovico de Nittis <aasonykk@gmail.com>2020-08-04 16:19:45 +0200
committerBenjamin Berg <benjamin@sipsolutions.net>2020-09-03 16:31:09 +0000
commitc9749af95539fb32075c5719c3bf776ce695aa30 (patch)
tree7e826450bb3a0adf81ef025791c404b23335d3e1
parentde1a2d12fecb59d803f26a6f3edde2d2fa8bd18f (diff)
downloadgnome-settings-daemon-c9749af95539fb32075c5719c3bf776ce695aa30.tar.gz
usb-protection: Relax the whitelist to all HIDs and HUBs
We discriminate keyboards when the screen is locked, i.e. we allow them so that the user can input their password. But when the keyboard is behind a hub, e.g. the laptop on a docking station, then the keyboard does not work. The mouse is probably also commonly used to unlock the screen before typing the password. Because this protection is enabled by default, and we don't want to get in the way of the user and their session, with this commit we expand the class of allowed devices to all HIDs and HUBs. Stricter protection features might be evaluated in the future.
-rw-r--r--plugins/usb-protection/gsd-usb-protection-manager.c71
1 files changed, 35 insertions, 36 deletions
diff --git a/plugins/usb-protection/gsd-usb-protection-manager.c b/plugins/usb-protection/gsd-usb-protection-manager.c
index 036caef4..0b0557fe 100644
--- a/plugins/usb-protection/gsd-usb-protection-manager.c
+++ b/plugins/usb-protection/gsd-usb-protection-manager.c
@@ -421,25 +421,36 @@ static void authorize_device (GDBusProxy *proxy,
}
static gboolean
-is_only_hid (GVariant *device)
+is_hid_or_hub (GVariant *device,
+ gboolean *has_other_classes)
{
g_autoptr(GVariantIter) iter = NULL;
g_autofree gchar *name = NULL;
g_autofree gchar *value = NULL;
guint i;
- gboolean only_hid = TRUE;
+ gboolean is_hid_or_hub = FALSE;
+
+ if (has_other_classes != NULL) {
+ *has_other_classes = FALSE;
+ }
g_variant_get_child (device, PRESENCE_ATTRIBUTES, "a{ss}", &iter);
while (g_variant_iter_loop (iter, "{ss}", &name, &value)) {
if (g_strcmp0 (name, WITH_INTERFACE) == 0) {
g_auto(GStrv) interfaces_splitted = NULL;
interfaces_splitted = g_strsplit (value, " ", -1);
- for (i = 0; i < g_strv_length (interfaces_splitted); i++)
- if (!g_str_has_prefix (interfaces_splitted[i], "03:"))
- only_hid = FALSE;
+ for (i = 0; i < g_strv_length (interfaces_splitted); i++) {
+ if (g_str_has_prefix (interfaces_splitted[i], "03:")
+ || g_str_has_prefix (interfaces_splitted[i], "09:")) {
+ is_hid_or_hub = TRUE;
+ }
+ else if (has_other_classes != NULL) {
+ *has_other_classes = TRUE;
+ }
+ }
}
}
- return only_hid;
+ return is_hid_or_hub;
}
static gboolean
@@ -458,23 +469,6 @@ is_hardwired (GVariant *device)
return FALSE;
}
-static gboolean
-is_keyboard (GVariant *device)
-{
- g_autoptr(GVariantIter) iter = NULL;
- g_autofree gchar *name = NULL;
- g_autofree gchar *value = NULL;
-
- g_variant_get_child (device, PRESENCE_ATTRIBUTES, "a{ss}", &iter);
- while (g_variant_iter_loop (iter, "{ss}", &name, &value)) {
- if (g_strcmp0 (name, WITH_INTERFACE) == 0) {
- return g_strrstr (value, "03:00:01") != NULL ||
- g_strrstr (value, "03:01:01") != NULL;
- }
- }
- return FALSE;
-}
-
static void
auth_device (GsdUsbProtectionManager *manager,
GVariant *device)
@@ -528,6 +522,8 @@ on_usbguard_signal (GDBusProxy *proxy,
g_autoptr(GVariantIter) iter = NULL;
g_autofree gchar *name = NULL;
g_autofree gchar *device_name = NULL;
+ gboolean hid_or_hub = FALSE;
+ gboolean has_other_classes = FALSE;
g_debug ("USBGuard signal: %s", signal_name);
@@ -578,18 +574,20 @@ on_usbguard_signal (GDBusProxy *proxy,
protection_level = g_settings_get_enum (manager->settings, USB_PROTECTION_LEVEL);
g_debug ("Screensaver active: %d", manager->screensaver_active);
+ hid_or_hub = is_hid_or_hub (parameters, &has_other_classes);
if (manager->screensaver_active) {
- /* If the session is locked we check if the inserted device is a keyboard.
- * If that is the case we authorize the newly inserted keyboard as an
+ /* If the session is locked we check if the inserted device is a HID,
+ * e.g. a keyboard or a mouse, or an HUB.
+ * If that is the case we authorize the newly inserted device as an
* antilockout policy.
*
- * If this keyboard advertises also interfaces outside the HID class it is suspect.
- * It could be a false positive because this could be a "smart" keyboard, but at
- * this stage is better be safe. */
- if (is_keyboard (parameters) && is_only_hid (parameters)) {
+ * If this device advertises also interfaces outside the HID class, or the
+ * HUB class, it is suspect. It could be a false positive because this could
+ * be a "smart" keyboard for example, but at this stage is better be safe. */
+ if (hid_or_hub && !has_other_classes) {
show_notification (manager,
- _("New keyboard detected"),
- _("Either your keyboard has been reconnected or a new one has been plugged in. "
+ _("New device detected"),
+ _("Either one of your existing devices has been reconnected or a new one has been plugged in. "
"If you did not do it, check your system for any suspicious device."));
auth_device (manager, parameters);
} else {
@@ -611,14 +609,15 @@ on_usbguard_signal (GDBusProxy *proxy,
/* If the protection level is "lockscreen" the device will be automatically
* authorized by usbguard. */
if (protection_level == G_DESKTOP_USB_PROTECTION_ALWAYS) {
- /* We authorize the device if this is a keyboard.
+ /* We authorize the device if this is a HID,
+ * e.g. a keyboard or a mouse, or an HUB.
* We also lock the screen to prevent an attacker to plug malicious
* devices if the legitimate user forgot to lock his session.
*
- * If this keyboard advertises also interfaces outside the HID class it is suspect.
- * It could be a false positive because this could be a "smart" keyboard, but at
- * this stage is better be safe. */
- if (is_keyboard (parameters) && is_only_hid (parameters)) {
+ * If this device advertises also interfaces outside the HID class, or the
+ * HUB class, it is suspect. It could be a false positive because this could
+ * be a "smart" keyboard for example, but at this stage is better be safe. */
+ if (hid_or_hub && !has_other_classes) {
gsd_screen_saver_call_lock (manager->screensaver_proxy,
manager->cancellable,
(GAsyncReadyCallback) on_screen_locked,