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

Hans de Goede hdegoede at redhat.com
Wed Feb 22 08:28:26 PST 2012


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

diff --git a/configure.ac b/configure.ac
index bf9b4ed..6e8c8e3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -346,7 +346,7 @@ if test "x$enable_usbredir" = "xno"; then
   have_usbredir="no"
 else
   PKG_CHECK_MODULES([USBREDIR],
-                    [gudev-1.0 libusb-1.0 >= 1.0.9 libusbredirhost >= 0.3.4 libusbredirparser >= 0.3.4],
+                    [gudev-1.0 libusb-1.0 >= 1.0.9 libusbredirhost >= 0.4 libusbredirparser >= 0.4],
                     [have_usbredir=yes],
                     [have_usbredir=no])
   if test "x$have_usbredir" = "xno" && test "x$enable_usbredir" = "xyes"; then
diff --git a/gtk/channel-usbredir-priv.h b/gtk/channel-usbredir-priv.h
index 10dd479..5d28c79 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,
+                          const 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 fa7dce0..eb81fe5 100644
--- a/gtk/channel-usbredir.c
+++ b/gtk/channel-usbredir.c
@@ -408,6 +408,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,
+                          const 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)
@@ -422,9 +438,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 959e0ab..37cc88b 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -921,8 +921,9 @@ spice_usb_device_manager_can_redirect_device(SpiceUsbDeviceManager  *self,
                                              GError                **err)
 {
 #ifdef USE_USBREDIR
+    const 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);
@@ -946,6 +947,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