Imported Upstream version 0.20.12
[profile/ivi/GUPnP.git] / libgupnp / gupnp-white-list.c
1 /*
2  * Copyright (C) 2013 Intel Corporation.
3  *
4  * Author: Ludovic Ferrandis <ludovic.ferrandis@intel.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 /**
23  * SECTION:gupnp-white-list
24  * @short_description: Class for network filtering.
25  *
26  * #GUPnPWhiteList handles network filtering. It provides API to manage a list
27  * of entries that will be used to filter networks.
28  * The #GUPnPWhiteList could be enabled or not. If it's enabled but the entries
29  * list is empty, it behaves as disabled.
30  *
31  * Since: 0.20.5
32  */
33
34 #include <string.h>
35
36 #include "gupnp-white-list.h"
37
38 G_DEFINE_TYPE (GUPnPWhiteList,
39                gupnp_white_list,
40                G_TYPE_OBJECT);
41
42 struct _GUPnPWhiteListPrivate {
43         gboolean enabled;
44         GList *entries;
45 };
46
47 enum {
48         PROP_0,
49         PROP_ENABLED,
50         PROP_ENTRIES
51 };
52
53 enum {
54         ENTRY_CHANGE,
55         ENABLED,
56         SIGNAL_LAST
57 };
58
59 static void
60 gupnp_white_list_init (GUPnPWhiteList *list)
61 {
62         list->priv = G_TYPE_INSTANCE_GET_PRIVATE (list,
63                                                   GUPNP_TYPE_WHITE_LIST,
64                                                   GUPnPWhiteListPrivate);
65
66         list->priv->entries = NULL;
67 }
68
69 static void
70 gupnp_white_list_set_property (GObject      *object,
71                                guint         property_id,
72                                const GValue *value,
73                                GParamSpec   *pspec)
74 {
75         GUPnPWhiteList *list;
76
77         list = GUPNP_WHITE_LIST (object);
78
79         switch (property_id) {
80         case PROP_ENABLED:
81                 list->priv->enabled = g_value_get_boolean (value);
82                 break;
83         case PROP_ENTRIES:
84                 list->priv->entries = g_value_get_pointer (value);
85                 break;
86         default:
87                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
88                 break;
89         }
90 }
91
92 static void
93 gupnp_white_list_get_property (GObject    *object,
94                                guint       property_id,
95                                GValue     *value,
96                                GParamSpec *pspec)
97 {
98         GUPnPWhiteList *list;
99
100         list = GUPNP_WHITE_LIST (object);
101
102         switch (property_id) {
103         case PROP_ENABLED:
104                 g_value_set_boolean (value, list->priv->enabled);
105                 break;
106         case PROP_ENTRIES:
107                 g_value_set_pointer (value, list->priv->entries);
108                 break;
109         default:
110                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
111                 break;
112         }
113 }
114
115 static void
116 gupnp_white_list_class_finalize (GObject *object)
117 {
118         GUPnPWhiteList *list;
119         GObjectClass *object_class;
120
121         list = GUPNP_WHITE_LIST (object);
122
123         g_list_free_full (list->priv->entries, g_free);
124         list->priv->entries = NULL;
125
126         /* Call super */
127         object_class = G_OBJECT_CLASS (gupnp_white_list_parent_class);
128         object_class->finalize (object);
129 }
130
131 static void
132 gupnp_white_list_class_init (GUPnPWhiteListClass *klass)
133 {
134         GObjectClass *object_class;
135
136         object_class = G_OBJECT_CLASS (klass);
137
138         object_class->set_property = gupnp_white_list_set_property;
139         object_class->get_property = gupnp_white_list_get_property;
140         object_class->finalize     = gupnp_white_list_class_finalize;
141
142         g_type_class_add_private (klass, sizeof (GUPnPWhiteListPrivate));
143
144         /**
145          * GUPnPWhiteList:enabled:
146          *
147          * Whether this white list is active or not.
148          *
149          * Since: 0.20.5
150          **/
151         g_object_class_install_property
152                 (object_class,
153                  PROP_ENABLED,
154                  g_param_spec_boolean
155                          ("enabled",
156                           "Enabled",
157                           "TRUE if the white list is active.",
158                           FALSE,
159                           G_PARAM_CONSTRUCT |
160                           G_PARAM_READWRITE |
161                           G_PARAM_STATIC_STRINGS));
162
163         /**
164          * GUPnPWhiteList:entries: (type GList(utf8))
165          *
166          * Whether this white list is active or not.
167          *
168          * Since: 0.20.5
169          **/
170         g_object_class_install_property
171                 (object_class,
172                  PROP_ENTRIES,
173                  g_param_spec_pointer
174                          ("entries",
175                           "Entries",
176                           "GList of strings that compose the white list.",
177                           G_PARAM_CONSTRUCT_ONLY |
178                           G_PARAM_READWRITE |
179                           G_PARAM_STATIC_STRINGS));
180 }
181
182 /**
183  * gupnp_white_list_new:
184  *
185  * Create a new #GUPnPWhiteList.
186  * The white list is disabled by default.
187  *
188  * Returns: (transfer full): A new #GUPnPWhiteList object.
189  *
190  * Since: 0.20.5
191  **/
192 GUPnPWhiteList *
193 gupnp_white_list_new (void)
194 {
195         return g_object_new (GUPNP_TYPE_WHITE_LIST, NULL);
196 }
197
198 /**
199  * gupnp_white_list_set_enabled:
200  * @white_list: A #GUPnPWhiteList
201  * @enable:  %TRUE to enable @white_list, %FALSE otherwise
202  *
203  * Enable or disable the #GUPnPWhiteList to perform the network filtering.
204  *
205  * Since: 0.20.5
206  **/
207 void
208 gupnp_white_list_set_enabled (GUPnPWhiteList *white_list, gboolean enable)
209 {
210         g_return_if_fail (GUPNP_IS_WHITE_LIST (white_list));
211
212         white_list->priv->enabled = enable;
213         g_object_notify (G_OBJECT (white_list), "enabled");
214 }
215
216 /**
217  * gupnp_white_list_get_enabled:
218  * @white_list: A #GUPnPWhiteList
219  *
220  * Return the status of the #GUPnPWhiteList
221  *
222  * Return value: %TRUE if @white_list is enabled, %FALSE otherwise.
223  *
224  * Since: 0.20.5
225  **/
226 gboolean
227 gupnp_white_list_get_enabled (GUPnPWhiteList *white_list)
228 {
229         g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), FALSE);
230
231         return white_list->priv->enabled;
232 }
233
234 /**
235  * gupnp_white_list_is_empty:
236  * @white_list: A #GUPnPWhiteList
237  *
238  * Return the state of the entries list of #GUPnPWhiteList
239  *
240  * Return value: %TRUE if @white_list is empty, %FALSE otherwise.
241  *
242  * Since: 0.20.5
243  **/
244 gboolean
245 gupnp_white_list_is_empty (GUPnPWhiteList *white_list)
246 {
247         g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), TRUE);
248
249         return (white_list->priv->entries == NULL);
250 }
251
252 /**
253  * gupnp_white_list_add_entry:
254  * @white_list: A #GUPnPWhiteList
255  * @entry: A value used to filter network
256  *
257  * Add @entry in the list of valid criteria used by @white_list to
258  * filter networks.
259  * if @entry already exists, it won't be added a second time.
260  *
261  * Return value: %TRUE if @entry is added, %FALSE otherwise.
262  *
263  * Since: 0.20.5
264  **/
265 gboolean
266 gupnp_white_list_add_entry (GUPnPWhiteList *white_list, gchar* entry)
267 {
268         GList *s_entry;
269         GUPnPWhiteListPrivate *priv;
270
271         g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), FALSE);
272         g_return_val_if_fail ((entry != NULL), FALSE);
273
274         priv = white_list->priv;
275
276         s_entry = g_list_find_custom (priv->entries, entry,
277                                       (GCompareFunc) g_ascii_strcasecmp);
278
279         if (s_entry == NULL) {
280                 priv->entries = g_list_prepend (priv->entries,
281                                                 g_strdup (entry));
282                 g_object_notify (G_OBJECT (white_list), "entries");
283         }
284
285         return (s_entry == NULL);
286 }
287
288 /**
289  * gupnp_white_list_add_entryv:
290  * @white_list: A #GUPnPWhiteList
291  * @entries: (array zero-terminated=1): A %NULL-terminated list of strings
292  *
293  * Add a list of entries to a #GUPnPWhiteList. This is a helper function to
294  * directly add a %NULL-terminated array of string usually aquired from
295  * commandline args.
296  *
297  * Since: 0.20.8
298  */
299 void
300 gupnp_white_list_add_entryv (GUPnPWhiteList *white_list, gchar **entries)
301 {
302         gchar * const * iter = entries;
303
304         g_return_if_fail (GUPNP_IS_WHITE_LIST (white_list));
305         g_return_if_fail ((entries != NULL));
306
307         for (; *iter != NULL; iter++)
308                 gupnp_white_list_add_entry (white_list, *iter);
309  }
310
311 /**
312  * gupnp_white_list_remove_entry:
313  * @white_list: A #GUPnPWhiteList
314  * @entry: A value to remove from the filter list.
315  *
316  * Remove @entry in the list of valid criteria used by @white_list to
317  * filter networks.
318  *
319  * Return value: %TRUE if @entry is removed, %FALSE otherwise.
320  *
321  * Since: 0.20.5
322  **/
323 gboolean
324 gupnp_white_list_remove_entry (GUPnPWhiteList *white_list, gchar* entry)
325 {
326         GList *s_entry;
327         GUPnPWhiteListPrivate *priv;
328
329         g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), FALSE);
330         g_return_val_if_fail ((entry != NULL), FALSE);
331
332         priv = white_list->priv;
333
334         s_entry = g_list_find_custom (priv->entries, entry,
335                                       (GCompareFunc) g_ascii_strcasecmp);
336
337         if (s_entry != NULL) {
338                 priv->entries = g_list_remove_link (priv->entries, s_entry);
339                 g_list_free_full (s_entry, g_free);
340                 g_object_notify (G_OBJECT (white_list), "entries");
341         }
342
343         return (s_entry != NULL);
344 }
345
346 /**
347  * gupnp_white_list_get_entries:
348  * @white_list: A #GUPnPWhiteList
349  *
350  * Get the #GList of entries that compose the white list. Do not free
351  *
352  * Return value: (element-type utf8) (transfer none):  a #GList of entries
353  * used to filter networks, interfaces,... or %NULL.
354  * Do not modify or free the list nor its elements.
355  *
356  * Since: 0.20.5
357  **/
358 GList *
359 gupnp_white_list_get_entries (GUPnPWhiteList *white_list)
360 {
361         g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), NULL);
362
363         return white_list->priv->entries;
364 }
365
366 /**
367  * gupnp_white_list_clear:
368  * @white_list: A #GUPnPWhiteList
369  *
370  * Remove all entries from #GList that compose the white list.
371  * The list is now empty. Even if #GUPnPWhiteList is enabled, it will have the
372  * same behavior as if it was disabled.
373  *
374  * Since: 0.20.5
375  **/
376 void
377 gupnp_white_list_clear (GUPnPWhiteList *white_list)
378 {
379         GUPnPWhiteListPrivate *priv;
380
381         g_return_if_fail (GUPNP_IS_WHITE_LIST(white_list));
382
383         priv = white_list->priv;
384         g_list_free_full (priv->entries, g_free);
385         priv->entries = NULL;
386         g_object_notify (G_OBJECT (white_list), "entries");
387 }
388
389 /**
390  * gupnp_white_list_check_context:
391  * @white_list: A #GUPnPWhiteList
392  * @context: A #GUPnPContext to test.
393  *
394  * It will check if the @context is allowed or not. The @white_list will check
395  * all its entries againt #GUPnPContext interface, host ip and network fields
396  * information. This function doesn't take into account the @white_list status
397  * (enabled or not).
398  *
399  * Return value: %TRUE if @context is matching the @white_list criterias,
400  * %FALSE otherwise.
401  *
402  * Since: 0.20.5
403  **/
404 gboolean
405 gupnp_white_list_check_context (GUPnPWhiteList *white_list,
406                                 GUPnPContext *context)
407 {
408         GSSDPClient  *client;
409         GList *l;
410         const char *interface;
411         const char *host_ip;
412         const char *network;
413         gboolean match = FALSE;
414
415         g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), FALSE);
416         g_return_val_if_fail (GUPNP_IS_CONTEXT (context), FALSE);
417
418         client = GSSDP_CLIENT (context);
419
420         interface = gssdp_client_get_interface (client);
421         host_ip = gssdp_client_get_host_ip (client);
422         network = gssdp_client_get_network (client);
423
424         l = white_list->priv->entries;
425
426         while (l && !match) {
427                 match = (interface && !strcmp (l->data, interface)) ||
428                         (host_ip && !strcmp (l->data, host_ip)) ||
429                         (network && !strcmp (l->data, network));
430
431                 l = l->next;
432         }
433
434         return match;
435 }