[Spice-devel] [PATCH spice-gtk 6/6] usbredir: Add awareness of host/guest side filtering

Hans de Goede hdegoede at redhat.com
Tue Feb 21 06:12:25 PST 2012


Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 gtk/channel-usbredir-priv.h |    6 ++++++
 gtk/channel-usbredir.c      |   19 ++++++++++++++++---
 gtk/usb-device-manager.c    |   18 +++++++++++++++++-
 3 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/gtk/channel-usbredir-priv.h b/gtk/channel-usbredir-priv.h
index 10dd479..97035d5 100644
--- a/gtk/channel-usbredir-priv.h
+++ b/gtk/channel-usbredir-priv.h
@@ -22,6 +22,7 @@
 #define __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__
 
 #include <libusb.h>
+#include <usbredirfilter.h>
 #include "spice-client.h"
 
 G_BEGIN_DECLS
@@ -49,6 +50,11 @@ void spice_usbredir_channel_disconnect_device(SpiceUsbredirChannel *channel);
 
 libusb_device *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel);
 
+void spice_usbredir_channel_get_guest_filter(
+                               SpiceUsbredirChannel         *channel,
+                               struct usbredirfilter_rule  **rules_ret,
+                               int                          *rules_count_ret);
+
 G_END_DECLS
 
 #endif /* __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__ */
diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c
index bf614e6..91b9acf 100644
--- a/gtk/channel-usbredir.c
+++ b/gtk/channel-usbredir.c
@@ -437,6 +437,22 @@ libusb_device *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel)
     return channel->priv->device;
 }
 
+G_GNUC_INTERNAL
+void spice_usbredir_channel_get_guest_filter(
+                               SpiceUsbredirChannel         *channel,
+                               struct usbredirfilter_rule  **rules_ret,
+                               int                          *rules_count_ret)
+{
+    SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+    g_return_if_fail(priv->host != NULL);
+
+    usbredirhost_get_guest_filter(priv->host, rules_ret, rules_count_ret);
+}
+
+/* ------------------------------------------------------------------ */
+/* callbacks (any context)                                            */
+
 /* Note that this function must be re-entrant safe, as it can get called
    from both the main thread as well as from the usb event handling thread */
 static void usbredir_write_flush_callback(void *user_data)
@@ -451,9 +467,6 @@ static void usbredir_write_flush_callback(void *user_data)
     usbredirhost_write_guest_data(priv->host);
 }
 
-/* ------------------------------------------------------------------ */
-/* callbacks (any context)                                            */
-
 static void usbredir_log(void *user_data, int level, const char *msg)
 {
     SpiceUsbredirChannel *channel = user_data;
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index c07ac7a..0b7a4e9 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -929,8 +929,9 @@ spice_usb_device_manager_can_redirect_device(SpiceUsbDeviceManager  *self,
                                              GError                **err)
 {
 #ifdef USE_USBREDIR
+    struct usbredirfilter_rule *guest_filter_rules = NULL;
     SpiceUsbDeviceManagerPrivate *priv = self->priv;
-    int i;
+    int i, guest_filter_rules_count;
     gboolean enabled;
 
     g_return_val_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self), FALSE);
@@ -954,6 +955,21 @@ spice_usb_device_manager_can_redirect_device(SpiceUsbDeviceManager  *self,
     if (spice_usb_device_manager_is_device_connected(self, device))
         return TRUE;
 
+    /* We assume all channels have the same filter, so we just take the
+       filter from the first channel */
+    spice_usbredir_channel_get_guest_filter(
+        g_ptr_array_index(priv->channels, 0),
+        &guest_filter_rules, &guest_filter_rules_count);
+
+    if (guest_filter_rules &&
+            usbredirhost_check_device_filter(
+                            guest_filter_rules, guest_filter_rules_count,
+                            (libusb_device *)device, 0) != 0) {
+        g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+                            _("Some USB devices are blocked by host policy"));
+        return FALSE;
+    }
+
     /* Check if there are free channels */
     for (i = 0; i < priv->channels->len; i++) {
         SpiceUsbredirChannel *channel = g_ptr_array_index(priv->channels, i);
-- 
1.7.7.6



More information about the Spice-devel mailing list