/* * Copyright (C) 2013 Intel Corporation. * * Author: Ludovic Ferrandis * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /** * SECTION:gupnp-white-list * @short_description: Class for network filtering. * * #GUPnPWhiteList handles network filtering. It provides API to manage a list * of entries that will be used to filter networks. * The #GUPnPWhiteList could be enabled or not. If it's enabled but the entries * list is empty, it behaves as disabled. */ #include #include "gupnp-white-list.h" G_DEFINE_TYPE (GUPnPWhiteList, gupnp_white_list, G_TYPE_OBJECT); struct _GUPnPWhiteListPrivate { gboolean enabled; GList *entries; }; enum { PROP_0, PROP_ENABLED, PROP_ENTRIES }; enum { ENTRY_CHANGE, ENABLED, SIGNAL_LAST }; static void gupnp_white_list_init (GUPnPWhiteList *list) { list->priv = G_TYPE_INSTANCE_GET_PRIVATE (list, GUPNP_TYPE_WHITE_LIST, GUPnPWhiteListPrivate); list->priv->entries = NULL; } static void gupnp_white_list_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { GUPnPWhiteList *list; list = GUPNP_WHITE_LIST (object); switch (property_id) { case PROP_ENABLED: list->priv->enabled = g_value_get_boolean (value); break; case PROP_ENTRIES: list->priv->entries = g_value_get_pointer (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void gupnp_white_list_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { GUPnPWhiteList *list; list = GUPNP_WHITE_LIST (object); switch (property_id) { case PROP_ENABLED: g_value_set_boolean (value, list->priv->enabled); break; case PROP_ENTRIES: g_value_set_pointer (value, list->priv->entries); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void gupnp_white_list_class_finalize (GObject *object) { GUPnPWhiteList *list; GObjectClass *object_class; list = GUPNP_WHITE_LIST (object); g_list_free_full (list->priv->entries, g_free); list->priv->entries = NULL; /* Call super */ object_class = G_OBJECT_CLASS (gupnp_white_list_parent_class); object_class->finalize (object); } static void gupnp_white_list_class_init (GUPnPWhiteListClass *klass) { GObjectClass *object_class; object_class = G_OBJECT_CLASS (klass); object_class->set_property = gupnp_white_list_set_property; object_class->get_property = gupnp_white_list_get_property; object_class->finalize = gupnp_white_list_class_finalize; g_type_class_add_private (klass, sizeof (GUPnPWhiteListPrivate)); /** * GUPnPWhiteList:enabled: * * Whether this white list is active or not. **/ g_object_class_install_property (object_class, PROP_ENABLED, g_param_spec_boolean ("enabled", "Enabled", "TRUE if the white list is active.", FALSE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GUPnPWhiteList:entries: * * Whether this white list is active or not. * Type: GList * Transfer: none **/ 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_white_list_new: * * Create a new #GUPnPWhiteList. * The white list is disabled by default. * * Returns: (transfer full): A new #GUPnPWhiteList object. **/ GUPnPWhiteList * gupnp_white_list_new (void) { return g_object_new (GUPNP_TYPE_WHITE_LIST, NULL); } /** * gupnp_white_list_set_enabled: * @white_list: A #GUPnPWhiteList * @enable: %TRUE to enable @white_list, %FALSE otherwise * * Enable or disable the #GUPnPWhiteList to perform the network filtering. **/ void gupnp_white_list_set_enabled (GUPnPWhiteList *white_list, gboolean enable) { g_return_if_fail (GUPNP_IS_WHITE_LIST (white_list)); white_list->priv->enabled = enable; g_object_notify (G_OBJECT (white_list), "enabled"); } /** * gupnp_white_list_get_enabled: * @white_list: A #GUPnPWhiteList * * Return the status of the #GUPnPWhiteList * * Return value: %TRUE if @white_list is enabled, %FALSE otherwise. **/ gboolean gupnp_white_list_get_enabled (GUPnPWhiteList *white_list) { g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), FALSE); return white_list->priv->enabled; } /** * gupnp_white_list_is_empty: * @white_list: A #GUPnPWhiteList * * Return the state of the entries list of #GUPnPWhiteList * * Return value: %TRUE if @white_list is empty, %FALSE otherwise. **/ gboolean gupnp_white_list_is_empty (GUPnPWhiteList *white_list) { g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), TRUE); return (white_list->priv->entries == NULL); } /** * gupnp_white_list_add_entry: * @white_list: A #GUPnPWhiteList * @entry: A value used to filter network * * Add @entry in the list of valid criteria used by @white_list to * filter networks. * if @entry already exists, it won't be added a second time. * * Return value: %TRUE if @entry is added, %FALSE otherwise. **/ gboolean gupnp_white_list_add_entry (GUPnPWhiteList *white_list, gchar* entry) { GList *s_entry; GUPnPWhiteListPrivate *priv; g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), FALSE); g_return_val_if_fail ((entry != NULL), FALSE); priv = white_list->priv; 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 (white_list), "entries"); } return (s_entry == NULL); } /** * gupnp_white_list_remove_entry: * @white_list: A #GUPnPWhiteList * @entry: A value to remove from the filter list. * * Remove @entry in the list of valid criteria used by @white_list to * filter networks. * * Return value: %TRUE if @entry is removed, %FALSE otherwise. **/ gboolean gupnp_white_list_remove_entry (GUPnPWhiteList *white_list, gchar* entry) { GList *s_entry; GUPnPWhiteListPrivate *priv; g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), FALSE); g_return_val_if_fail ((entry != NULL), FALSE); priv = white_list->priv; 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 (white_list), "entries"); } return (s_entry != NULL); } /** * gupnp_white_list_get_entries: * @white_list: A #GUPnPWhiteList * * 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. **/ GList * gupnp_white_list_get_entries (GUPnPWhiteList *white_list) { g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), NULL); return white_list->priv->entries; } /** * gupnp_white_list_clear: * @white_list: A #GUPnPWhiteList * * Remove all entries from #GList that compose the white list. * The list is now empty. Even if #GUPnPWhiteList is enabled, it will have the * same behavior as if it was disabled. **/ void gupnp_white_list_clear (GUPnPWhiteList *white_list) { GUPnPWhiteListPrivate *priv; g_return_if_fail (GUPNP_IS_WHITE_LIST(white_list)); priv = white_list->priv; g_list_free_full (priv->entries, g_free); priv->entries = NULL; g_object_notify (G_OBJECT (white_list), "entries"); } /** * gupnp_white_list_check_context: * @white_list: A #GUPnPWhiteList * @context: A #GUPnPContext to test. * * It will check if the @context is allowed or not. The @white_list will check * all its entries againt #GUPnPContext interface, host ip and network fields * information. This function doesn't take into account the @white_list status * (enabled or not). * * Return value: %TRUE if @context is matching the @white_list criterias, * %FALSE otherwise. **/ gboolean gupnp_white_list_check_context (GUPnPWhiteList *white_list, GUPnPContext *context) { GSSDPClient *client; GList *l; const char *interface; const char *host_ip; const char *network; gboolean match = FALSE; g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), FALSE); g_return_val_if_fail (GUPNP_IS_CONTEXT (context), FALSE); client = GSSDP_CLIENT (context); interface = gssdp_client_get_interface (client); host_ip = gssdp_client_get_host_ip (client); network = gssdp_client_get_network (client); l = white_list->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; }