[gupnp] context-filter: Introduce new class



commit 97318875b1e6f66035ddfbf8ccabdd632b555672
Author: Jens Georg <mail jensge org>
Date:   Mon Aug 10 23:49:31 2020 +0200

    context-filter: Introduce new class

 libgupnp/gupnp-context-filter.c | 462 ++++++++++++++++++++++++++++++++++++++++
 libgupnp/gupnp-context-filter.h |  66 ++++++
 libgupnp/gupnp.h                |  13 +-
 libgupnp/meson.build            |   2 +
 4 files changed, 537 insertions(+), 6 deletions(-)
---
diff --git a/libgupnp/gupnp-context-filter.c b/libgupnp/gupnp-context-filter.c
new file mode 100644
index 0000000..71f2605
--- /dev/null
+++ b/libgupnp/gupnp-context-filter.c
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2013 Intel Corporation.
+ *
+ * Author: Ludovic Ferrandis <ludovic ferrandis intel com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+/**
+ * SECTION:gupnp-context-filter
+ * @short_description: Class for network filtering.
+ *
+ * #GUPnPContextFilter handles network filtering. It provides API to manage a
+ * list of entries that will be used to filter networks. The #GUPnPContextFilter
+ * could be enabled or not. If it's enabled but the entries list is empty, it
+ * behaves as disabled.
+ *
+ * Since: 1.4.0
+ */
+
+#include "gupnp-context-filter.h"
+
+#include <string.h>
+
+struct _GUPnPContextFilterPrivate {
+        gboolean enabled;
+        GList *entries;
+};
+typedef struct _GUPnPContextFilterPrivate GUPnPContextFilterPrivate;
+
+/**
+ * GUPnPContextFilter:
+ *
+ * Class for network context filtering.
+ *
+ * #GUPnPContextFilter handles network filtering. It provides API to manage a
+ * list of entries that will be used to filter networks. The #GUPnPContextFilter
+ * could be enabled or not. If it's enabled but the entries list is empty, it
+ * behaves as disabled.
+ *
+ * Since: 1.4.0
+ */
+
+G_DEFINE_TYPE_WITH_PRIVATE (GUPnPContextFilter,
+                            gupnp_context_filter,
+                            G_TYPE_OBJECT)
+
+enum
+{
+        PROP_0,
+        PROP_ENABLED,
+        PROP_ENTRIES
+};
+
+enum
+{
+        ENTRY_CHANGE,
+        ENABLED,
+        SIGNAL_LAST
+};
+
+static void
+gupnp_context_filter_init (GUPnPContextFilter *list)
+{
+        GUPnPContextFilterPrivate *priv;
+
+        priv = gupnp_context_filter_get_instance_private (list);
+
+        priv->entries = NULL;
+}
+
+static void
+gupnp_context_filter_set_property (GObject *object,
+                                   guint property_id,
+                                   const GValue *value,
+                                   GParamSpec *pspec)
+{
+        GUPnPContextFilter *list;
+        GUPnPContextFilterPrivate *priv;
+
+        list = GUPNP_CONTEXT_FILTER (object);
+        priv = gupnp_context_filter_get_instance_private (list);
+
+        switch (property_id) {
+        case PROP_ENABLED:
+                priv->enabled = g_value_get_boolean (value);
+                break;
+        case PROP_ENTRIES:
+                priv->entries = g_value_get_pointer (value);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                break;
+        }
+}
+
+static void
+gupnp_context_filter_get_property (GObject *object,
+                                   guint property_id,
+                                   GValue *value,
+                                   GParamSpec *pspec)
+{
+        GUPnPContextFilter *list;
+        GUPnPContextFilterPrivate *priv;
+
+        list = GUPNP_CONTEXT_FILTER (object);
+        priv = gupnp_context_filter_get_instance_private (list);
+
+        switch (property_id) {
+        case PROP_ENABLED:
+                g_value_set_boolean (value, priv->enabled);
+                break;
+        case PROP_ENTRIES:
+                g_value_set_pointer (value, priv->entries);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                break;
+        }
+}
+
+static void
+gupnp_context_filter_class_finalize (GObject *object)
+{
+        GUPnPContextFilter *list;
+        GObjectClass *object_class;
+        GUPnPContextFilterPrivate *priv;
+
+        list = GUPNP_CONTEXT_FILTER (object);
+        priv = gupnp_context_filter_get_instance_private (list);
+
+        g_list_free_full (priv->entries, g_free);
+        priv->entries = NULL;
+
+        /* Call super */
+        object_class = G_OBJECT_CLASS (gupnp_context_filter_parent_class);
+        object_class->finalize (object);
+}
+
+static void
+gupnp_context_filter_class_init (GUPnPContextFilterClass *klass)
+{
+        GObjectClass *object_class;
+
+        object_class = G_OBJECT_CLASS (klass);
+
+        object_class->set_property = gupnp_context_filter_set_property;
+        object_class->get_property = gupnp_context_filter_get_property;
+        object_class->finalize = gupnp_context_filter_class_finalize;
+
+        /**
+         * GUPnPContextFilter:enabled:
+         *
+         * Whether this context filter is active or not.
+         *
+         * Since: 1.4.0
+         **/
+        g_object_class_install_property (
+                object_class,
+                PROP_ENABLED,
+                g_param_spec_boolean ("enabled",
+                                      "Enabled",
+                                      "TRUE if the context filter is active.",
+                                      FALSE,
+                                      G_PARAM_CONSTRUCT | G_PARAM_READWRITE |
+                                              G_PARAM_STATIC_STRINGS));
+
+        /**
+         * GUPnPContextFilter:entries: (type GList(utf8))
+         *
+         * Whether this white list is active or not.
+         *
+         * Since: 1.4.0
+         **/
+        g_object_class_install_property (
+                object_class,
+                PROP_ENTRIES,
+                g_param_spec_pointer (
+                        "entries",
+                        "Entries",
+                        "GList of strings that compose the white list.",
+                        G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+                                G_PARAM_STATIC_STRINGS));
+}
+
+/**
+ * gupnp_context_filter_new:
+ *
+ * Create a new #GUPnPContextFilter.
+ * The white list is disabled by default.
+ *
+ * Returns: (transfer full): A new #GUPnPContextFilter object.
+ *
+ * Since: 1.4.0
+ **/
+GUPnPContextFilter *
+gupnp_context_filter_new (void)
+{
+        return g_object_new (GUPNP_TYPE_CONTEXT_FILTER, NULL);
+}
+
+/**
+ * gupnp_context_filter_set_enabled:
+ * @context_filter: A #GUPnPContextFilter
+ * @enable:  %TRUE to enable @context_filter, %FALSE otherwise
+ *
+ * Enable or disable the #GUPnPContextFilter to perform the network filtering.
+ *
+ * Since: 1.4.0
+ **/
+void
+gupnp_context_filter_set_enabled (GUPnPContextFilter *context_filter,
+                                  gboolean enable)
+{
+        GUPnPContextFilterPrivate *priv;
+
+        g_return_if_fail (GUPNP_IS_CONTEXT_FILTER (context_filter));
+
+        priv = gupnp_context_filter_get_instance_private (context_filter);
+        priv->enabled = enable;
+        g_object_notify (G_OBJECT (context_filter), "enabled");
+}
+
+/**
+ * gupnp_context_filter_get_enabled:
+ * @context_filter: A #GUPnPContextFilter
+ *
+ * Return the status of the #GUPnPContextFilter
+ *
+ * Return value: %TRUE if @context_filter is enabled, %FALSE otherwise.
+ *
+ * Since: 1.4.0
+ **/
+gboolean
+gupnp_context_filter_get_enabled (GUPnPContextFilter *context_filter)
+{
+        GUPnPContextFilterPrivate *priv;
+
+        g_return_val_if_fail (GUPNP_IS_CONTEXT_FILTER (context_filter), FALSE);
+
+        priv = gupnp_context_filter_get_instance_private (context_filter);
+
+        return priv->enabled;
+}
+
+/**
+ * gupnp_context_filter_is_empty:
+ * @context_filter: A #GUPnPContextFilter
+ *
+ * Return the state of the entries list of #GUPnPContextFilter
+ *
+ * Return value: %TRUE if @context_filter is empty, %FALSE otherwise.
+ *
+ * Since: 1.4.0
+ **/
+gboolean
+gupnp_context_filter_is_empty (GUPnPContextFilter *context_filter)
+{
+        GUPnPContextFilterPrivate *priv;
+
+        g_return_val_if_fail (GUPNP_IS_CONTEXT_FILTER (context_filter), TRUE);
+
+        priv = gupnp_context_filter_get_instance_private (context_filter);
+
+        return (priv->entries == NULL);
+}
+
+/**
+ * gupnp_context_filter_add_entry:
+ * @context_filter: A #GUPnPContextFilter
+ * @entry: A value used to filter network
+ *
+ * Add @entry in the list of valid criteria used by @context_filter to
+ * filter networks.
+ * if @entry already exists, it won't be added a second time.
+ *
+ * Return value: %TRUE if @entry is added, %FALSE otherwise.
+ *
+ * Since: 1.4.0
+ **/
+gboolean
+gupnp_context_filter_add_entry (GUPnPContextFilter *context_filter,
+                                const gchar *entry)
+{
+        GList *s_entry;
+        GUPnPContextFilterPrivate *priv;
+
+        g_return_val_if_fail (GUPNP_IS_CONTEXT_FILTER (context_filter), FALSE);
+        g_return_val_if_fail ((entry != NULL), FALSE);
+
+        priv = gupnp_context_filter_get_instance_private (context_filter);
+
+        s_entry = g_list_find_custom (priv->entries,
+                                      entry,
+                                      (GCompareFunc) g_ascii_strcasecmp);
+
+        if (s_entry == NULL) {
+                priv->entries =
+                        g_list_prepend (priv->entries, g_strdup (entry));
+                g_object_notify (G_OBJECT (context_filter), "entries");
+        }
+
+        return (s_entry == NULL);
+}
+
+/**
+ * gupnp_context_filter_add_entryv:
+ * @context_filter: A #GUPnPContextFilter
+ * @entries: (array zero-terminated=1): A %NULL-terminated list of strings
+ *
+ * Add a list of entries to a #GUPnPContextFilter. This is a helper function to
+ * directly add a %NULL-terminated array of string usually aquired from
+ * commandline args.
+ *
+ * Since: 1.4.0
+ */
+void
+gupnp_context_filter_add_entryv (GUPnPContextFilter *context_filter,
+                                 gchar **entries)
+{
+        gchar *const *iter = entries;
+
+        g_return_if_fail (GUPNP_IS_CONTEXT_FILTER (context_filter));
+        g_return_if_fail ((entries != NULL));
+
+        for (; *iter != NULL; iter++)
+                gupnp_context_filter_add_entry (context_filter, *iter);
+}
+
+/**
+ * gupnp_context_filter_remove_entry:
+ * @context_filter: A #GUPnPContextFilter
+ * @entry: A value to remove from the filter list.
+ *
+ * Remove @entry in the list of valid criteria used by @context_filter to
+ * filter networks.
+ *
+ * Return value: %TRUE if @entry is removed, %FALSE otherwise.
+ *
+ * Since: 1.4.0
+ **/
+gboolean
+gupnp_context_filter_remove_entry (GUPnPContextFilter *context_filter,
+                                   const gchar *entry)
+{
+        GList *s_entry;
+        GUPnPContextFilterPrivate *priv;
+
+        g_return_val_if_fail (GUPNP_IS_CONTEXT_FILTER (context_filter), FALSE);
+        g_return_val_if_fail ((entry != NULL), FALSE);
+
+        priv = gupnp_context_filter_get_instance_private (context_filter);
+
+        s_entry = g_list_find_custom (priv->entries,
+                                      entry,
+                                      (GCompareFunc) g_ascii_strcasecmp);
+
+        if (s_entry != NULL) {
+                priv->entries = g_list_remove_link (priv->entries, s_entry);
+                g_list_free_full (s_entry, g_free);
+                g_object_notify (G_OBJECT (context_filter), "entries");
+        }
+
+        return (s_entry != NULL);
+}
+
+/**
+ * gupnp_context_filter_get_entries:
+ * @context_filter: A #GUPnPContextFilter
+ *
+ * Get the #GList of entries that compose the white list. Do not free
+ *
+ * Return value: (element-type utf8) (transfer none):  a #GList of entries
+ * used to filter networks, interfaces,... or %NULL.
+ * Do not modify or free the list nor its elements.
+ *
+ * Since: 1.4.0
+ **/
+GList *
+gupnp_context_filter_get_entries (GUPnPContextFilter *context_filter)
+{
+        GUPnPContextFilterPrivate *priv;
+
+        g_return_val_if_fail (GUPNP_IS_CONTEXT_FILTER (context_filter), NULL);
+
+        priv = gupnp_context_filter_get_instance_private (context_filter);
+
+        return priv->entries;
+}
+
+/**
+ * gupnp_context_filter_clear:
+ * @context_filter: A #GUPnPContextFilter
+ *
+ * Remove all entries from #GList that compose the white list.
+ * The list is now empty. Even if #GUPnPContextFilter is enabled, it will have
+ * the same behavior as if it was disabled.
+ *
+ * Since: 1.4.0
+ **/
+void
+gupnp_context_filter_clear (GUPnPContextFilter *context_filter)
+{
+        GUPnPContextFilterPrivate *priv;
+
+        g_return_if_fail (GUPNP_IS_CONTEXT_FILTER (context_filter));
+
+        priv = gupnp_context_filter_get_instance_private (context_filter);
+        g_list_free_full (priv->entries, g_free);
+        priv->entries = NULL;
+        g_object_notify (G_OBJECT (context_filter), "entries");
+}
+
+/**
+ * gupnp_context_filter_check_context:
+ * @context_filter: A #GUPnPContextFilter
+ * @context: A #GUPnPContext to test.
+ *
+ * It will check if the @context is allowed or not. The @context_filter will
+ *check all its entries againt #GUPnPContext interface, host ip and network
+ *fields information. This function doesn't take into account the
+ *@context_filter status (enabled or not).
+ *
+ * Return value: %TRUE if @context is matching the @context_filter criterias,
+ * %FALSE otherwise.
+ *
+ * Since: 1.4.0
+ **/
+gboolean
+gupnp_context_filter_check_context (GUPnPContextFilter *context_filter,
+                                    GUPnPContext *context)
+{
+        GSSDPClient *client;
+        GList *l;
+        const char *interface;
+        const char *host_ip;
+        const char *network;
+        gboolean match = FALSE;
+        GUPnPContextFilterPrivate *priv;
+
+        g_return_val_if_fail (GUPNP_IS_CONTEXT_FILTER (context_filter), FALSE);
+        g_return_val_if_fail (GUPNP_IS_CONTEXT (context), FALSE);
+
+        client = GSSDP_CLIENT (context);
+        priv = gupnp_context_filter_get_instance_private (context_filter);
+
+        interface = gssdp_client_get_interface (client);
+        host_ip = gssdp_client_get_host_ip (client);
+        network = gssdp_client_get_network (client);
+
+        l = priv->entries;
+
+        while (l && !match) {
+                match = (interface && !strcmp (l->data, interface)) ||
+                        (host_ip && !strcmp (l->data, host_ip)) ||
+                        (network && !strcmp (l->data, network));
+
+                l = l->next;
+        }
+
+        return match;
+}
diff --git a/libgupnp/gupnp-context-filter.h b/libgupnp/gupnp-context-filter.h
new file mode 100644
index 0000000..b36226b
--- /dev/null
+++ b/libgupnp/gupnp-context-filter.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2013 Intel Corporation.
+ *
+ * Author: Ludovic Ferrandis <ludovic ferrandis intel com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ */
+
+#ifndef GUPNP_CONTEXT_FILTER_H
+#define GUPNP_CONTEXT_FILTER_H
+
+#include <libgupnp/gupnp-context.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define GUPNP_TYPE_CONTEXT_FILTER (gupnp_context_filter_get_type ())
+
+G_DECLARE_DERIVABLE_TYPE (GUPnPContextFilter,
+                          gupnp_context_filter,
+                          GUPNP,
+                          CONTEXT_FILTER,
+                          GObject)
+
+struct _GUPnPContextFilterClass {
+        GObjectClass parent_class;
+};
+
+GUPnPContextFilter *
+gupnp_context_filter_new (void);
+
+void
+gupnp_context_filter_set_enabled (GUPnPContextFilter *context_filter,
+                                  gboolean enable);
+
+gboolean
+gupnp_context_filter_get_enabled (GUPnPContextFilter *context_filter);
+
+gboolean
+gupnp_context_filter_is_empty (GUPnPContextFilter *context_filter);
+
+gboolean
+gupnp_context_filter_add_entry (GUPnPContextFilter *context_filter,
+                                const gchar *entry);
+void
+gupnp_context_filter_add_entryv (GUPnPContextFilter *context_filter,
+                                 gchar **entries);
+
+gboolean
+gupnp_context_filter_remove_entry (GUPnPContextFilter *context_filter,
+                                   const gchar *entry);
+
+GList *
+gupnp_context_filter_get_entries (GUPnPContextFilter *context_filter);
+
+void
+gupnp_context_filter_clear (GUPnPContextFilter *context_filter);
+
+gboolean
+gupnp_context_filter_check_context (GUPnPContextFilter *context_filter,
+                                    GUPnPContext *context);
+
+G_END_DECLS
+
+#endif /* GUPNP_CONTEXT_FILTER_H */
diff --git a/libgupnp/gupnp.h b/libgupnp/gupnp.h
index fb4e187..8c85d7d 100644
--- a/libgupnp/gupnp.h
+++ b/libgupnp/gupnp.h
@@ -7,20 +7,21 @@
  */
 
 #include <libgupnp/gupnp-acl.h>
-#include <libgupnp/gupnp-context.h>
+#include <libgupnp/gupnp-context-filter.h>
 #include <libgupnp/gupnp-context-manager.h>
+#include <libgupnp/gupnp-context.h>
 #include <libgupnp/gupnp-control-point.h>
-#include <libgupnp/gupnp-error.h>
-#include <libgupnp/gupnp-device.h>
 #include <libgupnp/gupnp-device-info.h>
 #include <libgupnp/gupnp-device-proxy.h>
+#include <libgupnp/gupnp-device.h>
+#include <libgupnp/gupnp-error.h>
 #include <libgupnp/gupnp-resource-factory.h>
 #include <libgupnp/gupnp-root-device.h>
-#include <libgupnp/gupnp-service.h>
 #include <libgupnp/gupnp-service-info.h>
 #include <libgupnp/gupnp-service-introspection.h>
 #include <libgupnp/gupnp-service-proxy.h>
-#include <libgupnp/gupnp-white-list.h>
-#include <libgupnp/gupnp-xml-doc.h>
+#include <libgupnp/gupnp-service.h>
 #include <libgupnp/gupnp-types.h>
 #include <libgupnp/gupnp-uuid.h>
+#include <libgupnp/gupnp-white-list.h>
+#include <libgupnp/gupnp-xml-doc.h>
diff --git a/libgupnp/meson.build b/libgupnp/meson.build
index d63d07e..332fbe5 100644
--- a/libgupnp/meson.build
+++ b/libgupnp/meson.build
@@ -45,6 +45,7 @@ enums = gnome.mkenums(
 headers = files(
     'gupnp-acl.h',
     'gupnp-context.h',
+    'gupnp-context-filter.h',
     'gupnp-context-manager.h',
     'gupnp-control-point.h',
     'gupnp-device.h',
@@ -68,6 +69,7 @@ install_headers(headers, subdir : 'gupnp-1.2/libgupnp')
 sources = files(
     'gupnp-acl.c',
     'gupnp-context.c',
+    'gupnp-context-filter.c',
     'gupnp-context-manager.c',
     'gupnp-control-point.c',
     'gupnp-device.c',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]