diff options
-rw-r--r-- | src/mm-filter.c | 49 | ||||
-rw-r--r-- | src/mm-filter.h | 34 | ||||
-rw-r--r-- | src/mm-plugin-manager.c | 18 | ||||
-rw-r--r-- | src/mm-plugin.c | 6 | ||||
-rw-r--r-- | src/mm-plugin.h | 3 |
5 files changed, 96 insertions, 14 deletions
diff --git a/src/mm-filter.c b/src/mm-filter.c index bc7d378d..9a22cdd4 100644 --- a/src/mm-filter.c +++ b/src/mm-filter.c @@ -34,11 +34,24 @@ enum { }; struct _MMFilterPrivate { - MMFilterRule enabled_rules; + MMFilterRule enabled_rules; + GList *plugin_whitelist_tags; }; /*****************************************************************************/ +void +mm_filter_register_plugin_whitelist_tag (MMFilter *self, + const gchar *tag) +{ + if (!g_list_find_custom (self->priv->plugin_whitelist_tags, tag, (GCompareFunc) g_strcmp0)) { + mm_dbg ("[filter] registered plugin whitelist tag: %s", tag); + self->priv->plugin_whitelist_tags = g_list_prepend (self->priv->plugin_whitelist_tags, g_strdup (tag)); + } +} + +/*****************************************************************************/ + gboolean mm_filter_port (MMFilter *self, MMKernelDevice *port, @@ -67,6 +80,19 @@ mm_filter_port (MMFilter *self, return FALSE; } + /* If the device is whitelisted by a plugin, we allow it. */ + if (self->priv->enabled_rules & MM_FILTER_RULE_PLUGIN_WHITELIST) { + GList *l; + + for (l = self->priv->plugin_whitelist_tags; l; l = g_list_next (l)) { + if (mm_kernel_device_get_global_property_as_boolean (port, (const gchar *)(l->data)) || + mm_kernel_device_get_property_as_boolean (port, (const gchar *)(l->data))) { + mm_dbg ("[filter] (%s/%s) port allowed: device is whitelisted by plugin", subsystem, name); + return TRUE; + } + } + } + /* If this is a virtual device, don't allow it */ if ((self->priv->enabled_rules & MM_FILTER_RULE_VIRTUAL) && (!mm_kernel_device_get_physdev_sysfs_path (port))) { @@ -258,6 +284,15 @@ filter_rule_env_process (MMFilterRule enabled_rules) /*****************************************************************************/ +gboolean +mm_filter_check_rule_enabled (MMFilter *self, + MMFilterRule rule) +{ + return !!(self->priv->enabled_rules & rule); +} + +/*****************************************************************************/ + /* If TTY rule enabled, either DEFAULT_ALLOWED or DEFAULT_FORBIDDEN must be set. */ #define VALIDATE_RULE_TTY(rules) (!(rules & MM_FILTER_RULE_TTY) || \ ((rules & (MM_FILTER_RULE_TTY_DEFAULT_ALLOWED | MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN)) && \ @@ -289,6 +324,7 @@ mm_filter_new (MMFilterRule enabled_rules, mm_dbg ("[filter] created"); mm_dbg ("[filter] explicit whitelist: %s", RULE_ENABLED_STR (MM_FILTER_RULE_EXPLICIT_WHITELIST)); mm_dbg ("[filter] explicit blacklist: %s", RULE_ENABLED_STR (MM_FILTER_RULE_EXPLICIT_BLACKLIST)); + mm_dbg ("[filter] plugin whitelist: %s", RULE_ENABLED_STR (MM_FILTER_RULE_PLUGIN_WHITELIST)); mm_dbg ("[filter] virtual devices forbidden: %s", RULE_ENABLED_STR (MM_FILTER_RULE_VIRTUAL)); mm_dbg ("[filter] net devices allowed: %s", RULE_ENABLED_STR (MM_FILTER_RULE_NET)); mm_dbg ("[filter] cdc-wdm devices allowed: %s", RULE_ENABLED_STR (MM_FILTER_RULE_CDC_WDM)); @@ -357,6 +393,16 @@ mm_filter_init (MMFilter *self) } static void +finalize (GObject *object) +{ + MMFilter *self = MM_FILTER (object); + + g_list_free_full (self->priv->plugin_whitelist_tags, g_free); + + G_OBJECT_CLASS (mm_filter_parent_class)->finalize (object); +} + +static void mm_filter_class_init (MMFilterClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -366,6 +412,7 @@ mm_filter_class_init (MMFilterClass *klass) /* Virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; + object_class->finalize = finalize; g_object_class_install_property ( object_class, PROP_ENABLED_RULES, diff --git a/src/mm-filter.h b/src/mm-filter.h index 098a06f3..73fc9894 100644 --- a/src/mm-filter.h +++ b/src/mm-filter.h @@ -48,23 +48,25 @@ typedef enum { /*< underscore_name=mm_filter_rule >*/ MM_FILTER_RULE_NONE = 0, MM_FILTER_RULE_EXPLICIT_WHITELIST = 1 << 0, MM_FILTER_RULE_EXPLICIT_BLACKLIST = 1 << 1, - MM_FILTER_RULE_VIRTUAL = 1 << 2, - MM_FILTER_RULE_NET = 1 << 3, - MM_FILTER_RULE_CDC_WDM = 1 << 4, - MM_FILTER_RULE_TTY = 1 << 5, - MM_FILTER_RULE_TTY_BLACKLIST = 1 << 6, - MM_FILTER_RULE_TTY_MANUAL_SCAN_ONLY = 1 << 7, - MM_FILTER_RULE_TTY_PLATFORM_DRIVER = 1 << 8, - MM_FILTER_RULE_TTY_DEFAULT_ALLOWED = 1 << 9, - MM_FILTER_RULE_TTY_DRIVER = 1 << 10, - MM_FILTER_RULE_TTY_ACM_INTERFACE = 1 << 11, - MM_FILTER_RULE_TTY_WITH_NET = 1 << 12, - MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN = 1 << 13, + MM_FILTER_RULE_PLUGIN_WHITELIST = 1 << 2, + MM_FILTER_RULE_VIRTUAL = 1 << 3, + MM_FILTER_RULE_NET = 1 << 4, + MM_FILTER_RULE_CDC_WDM = 1 << 5, + MM_FILTER_RULE_TTY = 1 << 6, + MM_FILTER_RULE_TTY_BLACKLIST = 1 << 7, + MM_FILTER_RULE_TTY_MANUAL_SCAN_ONLY = 1 << 8, + MM_FILTER_RULE_TTY_PLATFORM_DRIVER = 1 << 9, + MM_FILTER_RULE_TTY_DEFAULT_ALLOWED = 1 << 10, + MM_FILTER_RULE_TTY_DRIVER = 1 << 11, + MM_FILTER_RULE_TTY_ACM_INTERFACE = 1 << 12, + MM_FILTER_RULE_TTY_WITH_NET = 1 << 13, + MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN = 1 << 14, } MMFilterRule; #define MM_FILTER_RULE_ALL \ (MM_FILTER_RULE_EXPLICIT_WHITELIST | \ MM_FILTER_RULE_EXPLICIT_BLACKLIST | \ + MM_FILTER_RULE_PLUGIN_WHITELIST | \ MM_FILTER_RULE_VIRTUAL | \ MM_FILTER_RULE_NET | \ MM_FILTER_RULE_CDC_WDM | \ @@ -97,6 +99,7 @@ typedef enum { /*< underscore_name=mm_filter_rule >*/ #define MM_FILTER_POLICY_STRICT \ (MM_FILTER_RULE_EXPLICIT_WHITELIST | \ MM_FILTER_RULE_EXPLICIT_BLACKLIST | \ + MM_FILTER_RULE_PLUGIN_WHITELIST | \ MM_FILTER_RULE_VIRTUAL | \ MM_FILTER_RULE_NET | \ MM_FILTER_RULE_CDC_WDM | \ @@ -112,6 +115,7 @@ typedef enum { /*< underscore_name=mm_filter_rule >*/ #define MM_FILTER_POLICY_PARANOID \ (MM_FILTER_RULE_EXPLICIT_WHITELIST | \ MM_FILTER_RULE_EXPLICIT_BLACKLIST | \ + MM_FILTER_RULE_PLUGIN_WHITELIST | \ MM_FILTER_RULE_VIRTUAL | \ MM_FILTER_RULE_NET | \ MM_FILTER_RULE_CDC_WDM | \ @@ -139,4 +143,10 @@ gboolean mm_filter_device_and_port (MMFilter *self, MMDevice *device, MMKernelDevice *port); +void mm_filter_register_plugin_whitelist_tag (MMFilter *self, + const gchar *tag); + +gboolean mm_filter_check_rule_enabled (MMFilter *self, + MMFilterRule rule); + #endif /* MM_FILTER_H */ diff --git a/src/mm-plugin-manager.c b/src/mm-plugin-manager.c index 2123bded..557c2d5d 100644 --- a/src/mm-plugin-manager.c +++ b/src/mm-plugin-manager.c @@ -1496,6 +1496,21 @@ mm_plugin_manager_peek_plugin (MMPluginManager *self, /*****************************************************************************/ +static void +register_plugin_whitelist_tags (MMPluginManager *self, + MMPlugin *plugin) +{ + const gchar **tags; + guint i; + + if (!mm_filter_check_rule_enabled (self->priv->filter, MM_FILTER_RULE_PLUGIN_WHITELIST)) + return; + + tags = mm_plugin_get_allowed_udev_tags (plugin); + for (i = 0; tags && tags[i]; i++) + mm_filter_register_plugin_whitelist_tag (self->priv->filter, tags[i]); +} + static MMPlugin * load_plugin (const gchar *path) { @@ -1609,6 +1624,9 @@ load_plugins (MMPluginManager *self, else /* Vendor specific plugin */ self->priv->plugins = g_list_append (self->priv->plugins, plugin); + + /* Register plugin whitelist tags in filter, if any */ + register_plugin_whitelist_tags (self, plugin); } /* Check the generic plugin once all looped */ diff --git a/src/mm-plugin.c b/src/mm-plugin.c index a19111ff..fbb0d5c8 100644 --- a/src/mm-plugin.c +++ b/src/mm-plugin.c @@ -141,6 +141,12 @@ mm_plugin_get_name (MMPlugin *self) return self->priv->name; } +const gchar ** +mm_plugin_get_allowed_udev_tags (MMPlugin *self) +{ + return (const gchar **) self->priv->udev_tags; +} + /*****************************************************************************/ static gboolean diff --git a/src/mm-plugin.h b/src/mm-plugin.h index 223e9d12..84df989c 100644 --- a/src/mm-plugin.h +++ b/src/mm-plugin.h @@ -124,7 +124,8 @@ struct _MMPluginClass { GType mm_plugin_get_type (void); -const gchar *mm_plugin_get_name (MMPlugin *self); +const gchar *mm_plugin_get_name (MMPlugin *self); +const gchar **mm_plugin_get_allowed_udev_tags (MMPlugin *self); /* This method will run all pre-probing filters, to see if we can discard this * plugin from the probing logic as soon as possible. */ |