diff options
-rw-r--r-- | src/mm-base-manager.c | 2 | ||||
-rw-r--r-- | src/mm-filter.c | 43 | ||||
-rw-r--r-- | src/mm-filter.h | 12 | ||||
-rw-r--r-- | src/mm-plugin-manager.c | 45 | ||||
-rw-r--r-- | src/mm-plugin-manager.h | 3 |
5 files changed, 95 insertions, 10 deletions
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c index 6961ca90..1673c25e 100644 --- a/src/mm-base-manager.c +++ b/src/mm-base-manager.c @@ -1144,7 +1144,7 @@ initable_init (GInitable *initable, return FALSE; /* Create plugin manager */ - priv->plugin_manager = mm_plugin_manager_new (priv->plugin_dir, error); + priv->plugin_manager = mm_plugin_manager_new (priv->plugin_dir, priv->filter, error); if (!priv->plugin_manager) return FALSE; diff --git a/src/mm-filter.c b/src/mm-filter.c index 087166f0..ca0241a0 100644 --- a/src/mm-filter.c +++ b/src/mm-filter.c @@ -20,6 +20,8 @@ #include "mm-filter.h" #include "mm-log.h" +#define FILTER_PORT_MAYBE_FORBIDDEN "maybe-forbidden" + G_DEFINE_TYPE (MMFilter, mm_filter, G_TYPE_OBJECT) enum { @@ -142,10 +144,10 @@ mm_filter_port (MMFilter *self, return TRUE; } - /* Default forbidden? */ + /* Default forbidden? flag the port as maybe-forbidden, and go on */ if (self->priv->enabled_rules & MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN) { - mm_dbg ("[filter] (%s/%s) port forbidden", subsystem, name); - return FALSE; + g_object_set_data (G_OBJECT (port), FILTER_PORT_MAYBE_FORBIDDEN, GUINT_TO_POINTER (TRUE)); + return TRUE; } g_assert_not_reached (); @@ -157,6 +159,40 @@ mm_filter_port (MMFilter *self, } /*****************************************************************************/ + +gboolean +mm_filter_device_and_port (MMFilter *self, + MMDevice *device, + MMKernelDevice *port) +{ + const gchar *subsystem; + const gchar *name; + + /* If it wasn't flagged as maybe forbidden, there's nothing to do */ + if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (port), FILTER_PORT_MAYBE_FORBIDDEN))) + return TRUE; + + subsystem = mm_kernel_device_get_subsystem (port); + name = mm_kernel_device_get_name (port); + + /* Check whether this device holds a NET port in addition to this TTY */ + if (self->priv->enabled_rules & MM_FILTER_RULE_TTY_WITH_NET) { + GList *l; + + for (l = mm_device_peek_port_probe_list (device); l; l = g_list_next (l)) { + if (!g_strcmp0 (mm_port_probe_get_port_subsys (MM_PORT_PROBE (l->data)), "net")) { + mm_dbg ("[filter] (%s/%s): port allowed: device also exports a net interface (%s)", + subsystem, name, mm_port_probe_get_port_name (MM_PORT_PROBE (l->data))); + return TRUE; + } + } + } + + mm_dbg ("[filter] (%s/%s) port filtered: forbidden", subsystem, name); + return FALSE; +} + +/*****************************************************************************/ /* Use filter rule names as environment variables to control them on startup: * - MM_FILTER_RULE_XXX=1 to explicitly enable the rule. * - MM_FILTER_RULE_XXX=0 to explicitly disable the rule. @@ -235,6 +271,7 @@ mm_filter_new (MMFilterRule enabled_rules, mm_dbg ("[filter] platform driver check: %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_PLATFORM_DRIVER)); mm_dbg ("[filter] driver check: %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_DRIVER)); mm_dbg ("[filter] cdc-acm interface check: %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_ACM_INTERFACE)); + mm_dbg ("[filter] with net check: %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_WITH_NET)); if (self->priv->enabled_rules & MM_FILTER_RULE_TTY_DEFAULT_ALLOWED) mm_dbg ("[filter] default: allowed"); else if (self->priv->enabled_rules & MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN) diff --git a/src/mm-filter.h b/src/mm-filter.h index 6c4e7e49..486d65bf 100644 --- a/src/mm-filter.h +++ b/src/mm-filter.h @@ -19,6 +19,7 @@ #include <glib-object.h> #include <gio/gio.h> +#include "mm-device.h" #include "mm-kernel-device.h" #define MM_TYPE_FILTER (mm_filter_get_type ()) @@ -56,7 +57,8 @@ typedef enum { /*< underscore_name=mm_filter_rule >*/ MM_FILTER_RULE_TTY_DEFAULT_ALLOWED = 1 << 8, MM_FILTER_RULE_TTY_DRIVER = 1 << 9, MM_FILTER_RULE_TTY_ACM_INTERFACE = 1 << 10, - MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN = 1 << 11, + MM_FILTER_RULE_TTY_WITH_NET = 1 << 11, + MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN = 1 << 12, } MMFilterRule; #define MM_FILTER_RULE_ALL \ @@ -70,6 +72,8 @@ typedef enum { /*< underscore_name=mm_filter_rule >*/ MM_FILTER_RULE_TTY_PLATFORM_DRIVER | \ MM_FILTER_RULE_TTY_DEFAULT_ALLOWED | \ MM_FILTER_RULE_TTY_DRIVER | \ + MM_FILTER_RULE_TTY_ACM_INTERFACE | \ + MM_FILTER_RULE_TTY_WITH_NET | \ MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN) /* This is the default ModemManager policy that tries to automatically probe @@ -96,6 +100,7 @@ typedef enum { /*< underscore_name=mm_filter_rule >*/ MM_FILTER_RULE_TTY_PLATFORM_DRIVER | \ MM_FILTER_RULE_TTY_DRIVER | \ MM_FILTER_RULE_TTY_ACM_INTERFACE | \ + MM_FILTER_RULE_TTY_WITH_NET | \ MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN) /* This is equivalent to the strict policy, but also applying the device @@ -111,6 +116,7 @@ typedef enum { /*< underscore_name=mm_filter_rule >*/ MM_FILTER_RULE_TTY_PLATFORM_DRIVER | \ MM_FILTER_RULE_TTY_DRIVER | \ MM_FILTER_RULE_TTY_ACM_INTERFACE | \ + MM_FILTER_RULE_TTY_WITH_NET | \ MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN) /* This policy only allows using device ports explicitly whitelisted via @@ -124,4 +130,8 @@ gboolean mm_filter_port (MMFilter *self, MMKernelDevice *port, gboolean manual_scan); +gboolean mm_filter_device_and_port (MMFilter *self, + MMDevice *device, + MMKernelDevice *port); + #endif /* MM_FILTER_H */ diff --git a/src/mm-plugin-manager.c b/src/mm-plugin-manager.c index dee96184..a6c8336a 100644 --- a/src/mm-plugin-manager.c +++ b/src/mm-plugin-manager.c @@ -38,12 +38,15 @@ G_DEFINE_TYPE_EXTENDED (MMPluginManager, mm_plugin_manager, G_TYPE_OBJECT, 0, enum { PROP_0, PROP_PLUGIN_DIR, + PROP_FILTER, LAST_PROP }; struct _MMPluginManagerPrivate { /* Path to look for plugins */ gchar *plugin_dir; + /* Device filter */ + MMFilter *filter; /* This list contains all plugins except for the generic one, order is not * important. It is loaded once when the program starts, and the list is NOT @@ -1106,19 +1109,34 @@ device_context_run_port_context (DeviceContext *device_context, static gboolean device_context_min_wait_time_elapsed (DeviceContext *device_context) { + MMPluginManager *self; GList *l; + GList *tmp; + + self = device_context->self; device_context->min_wait_time_id = 0; mm_dbg ("[plugin manager] task %s: min wait time elapsed", device_context->name); /* Move list of port contexts out of the wait list */ g_assert (!device_context->port_contexts); - device_context->port_contexts = device_context->wait_port_contexts; + tmp = device_context->wait_port_contexts; device_context->wait_port_contexts = NULL; /* Launch supports check for each port in the Plugin Manager */ - for (l = device_context->port_contexts; l; l = g_list_next (l)) - device_context_run_port_context (device_context, (PortContext *)(l->data)); + for (l = tmp; l; l = g_list_next (l)) { + PortContext *port_context = (PortContext *)(l->data); + + if (!mm_filter_device_and_port (self->priv->filter, port_context->device, port_context->port)) { + /* If port is filtered, unref it right away */ + port_context_unref (port_context); + } else { + /* If port not filtered, store and run it */ + device_context->port_contexts = g_list_append (device_context->port_contexts, port_context); + device_context_run_port_context (device_context, port_context); + } + } + g_list_free (tmp); return G_SOURCE_REMOVE; } @@ -1620,13 +1638,15 @@ out: } MMPluginManager * -mm_plugin_manager_new (const gchar *plugin_dir, - GError **error) +mm_plugin_manager_new (const gchar *plugin_dir, + MMFilter *filter, + GError **error) { return g_initable_new (MM_TYPE_PLUGIN_MANAGER, NULL, error, MM_PLUGIN_MANAGER_PLUGIN_DIR, plugin_dir, + MM_PLUGIN_MANAGER_FILTER, filter, NULL); } @@ -1652,6 +1672,9 @@ set_property (GObject *object, g_free (priv->plugin_dir); priv->plugin_dir = g_value_dup_string (value); break; + case PROP_FILTER: + priv->filter = g_value_dup_object (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1670,6 +1693,9 @@ get_property (GObject *object, case PROP_PLUGIN_DIR: g_value_set_string (value, priv->plugin_dir); break; + case PROP_FILTER: + g_value_set_object (value, priv->filter); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1700,6 +1726,8 @@ dispose (GObject *object) g_free (self->priv->plugin_dir); self->priv->plugin_dir = NULL; + g_clear_object (&self->priv->filter); + G_OBJECT_CLASS (mm_plugin_manager_parent_class)->dispose (object); } @@ -1729,4 +1757,11 @@ mm_plugin_manager_class_init (MMPluginManagerClass *manager_class) "Where to look for plugins", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property + (object_class, PROP_FILTER, + g_param_spec_object (MM_PLUGIN_MANAGER_FILTER, + "Filter", + "Device filter", + MM_TYPE_FILTER, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } diff --git a/src/mm-plugin-manager.h b/src/mm-plugin-manager.h index 0ae2811d..6a0f47eb 100644 --- a/src/mm-plugin-manager.h +++ b/src/mm-plugin-manager.h @@ -22,6 +22,7 @@ #include "mm-device.h" #include "mm-plugin.h" +#include "mm-filter.h" #include "mm-base-modem.h" #define MM_TYPE_PLUGIN_MANAGER (mm_plugin_manager_get_type ()) @@ -32,6 +33,7 @@ #define MM_PLUGIN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN_MANAGER, MMPluginManagerClass)) #define MM_PLUGIN_MANAGER_PLUGIN_DIR "plugin-dir" /* Construct-only */ +#define MM_PLUGIN_MANAGER_FILTER "filter" /* Construct-only */ typedef struct _MMPluginManager MMPluginManager; typedef struct _MMPluginManagerClass MMPluginManagerClass; @@ -48,6 +50,7 @@ struct _MMPluginManagerClass { GType mm_plugin_manager_get_type (void); MMPluginManager *mm_plugin_manager_new (const gchar *plugindir, + MMFilter *filter, GError **error); void mm_plugin_manager_device_support_check (MMPluginManager *self, MMDevice *device, |