aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-base-manager.c2
-rw-r--r--src/mm-filter.c43
-rw-r--r--src/mm-filter.h12
-rw-r--r--src/mm-plugin-manager.c45
-rw-r--r--src/mm-plugin-manager.h3
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,