Add gobject introspection
[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
32 #include <string.h>
33
34 #include "gupnp-white-list.h"
35
36 G_DEFINE_TYPE (GUPnPWhiteList,
37                gupnp_white_list,
38                G_TYPE_OBJECT);
39
40 struct _GUPnPWhiteListPrivate {
41         gboolean enabled;
42         GList *entries;
43 };
44
45 enum {
46         PROP_0,
47         PROP_ENABLED,
48         PROP_ENTRIES
49 };
50
51 enum {
52         ENTRY_CHANGE,
53         ENABLED,
54         SIGNAL_LAST
55 };
56
57 static void
58 gupnp_white_list_init (GUPnPWhiteList *list)
59 {
60         list->priv = G_TYPE_INSTANCE_GET_PRIVATE (list,
61                                                   GUPNP_TYPE_WHITE_LIST,
62                                                   GUPnPWhiteListPrivate);
63
64         list->priv->entries = NULL;
65 }
66
67 static void
68 gupnp_white_list_set_property (GObject      *object,
69                                guint         property_id,
70                                const GValue *value,
71                                GParamSpec   *pspec)
72 {
73         GUPnPWhiteList *list;
74
75         list = GUPNP_WHITE_LIST (object);
76
77         switch (property_id) {
78         case PROP_ENABLED:
79                 list->priv->enabled = g_value_get_boolean (value);
80                 break;
81         case PROP_ENTRIES:
82                 list->priv->entries = g_value_get_pointer (value);
83                 break;
84         default:
85                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
86                 break;
87         }
88 }
89
90 static void
91 gupnp_white_list_get_property (GObject    *object,
92                                guint       property_id,
93                                GValue     *value,
94                                GParamSpec *pspec)
95 {
96         GUPnPWhiteList *list;
97
98         list = GUPNP_WHITE_LIST (object);
99
100         switch (property_id) {
101         case PROP_ENABLED:
102                 g_value_set_boolean (value, list->priv->enabled);
103                 break;
104         case PROP_ENTRIES:
105                 g_value_set_pointer (value, list->priv->entries);
106                 break;
107         default:
108                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
109                 break;
110         }
111 }
112
113 static void
114 gupnp_white_list_class_finalize (GObject *object)
115 {
116         GUPnPWhiteList *list;
117         GObjectClass *object_class;
118
119         list = GUPNP_WHITE_LIST (object);
120
121         g_list_free_full (list->priv->entries, g_free);
122         list->priv->entries = NULL;
123
124         /* Call super */
125         object_class = G_OBJECT_CLASS (gupnp_white_list_parent_class);
126         object_class->finalize (object);
127 }
128
129 static void
130 gupnp_white_list_class_init (GUPnPWhiteListClass *klass)
131 {
132         GObjectClass *object_class;
133
134         object_class = G_OBJECT_CLASS (klass);
135
136         object_class->set_property = gupnp_white_list_set_property;
137         object_class->get_property = gupnp_white_list_get_property;
138         object_class->finalize     = gupnp_white_list_class_finalize;
139
140         g_type_class_add_private (klass, sizeof (GUPnPWhiteListPrivate));
141
142         /**
143          * GUPnPWhiteList:enabled:
144          *
145          * Whether this white list is active or not.
146          **/
147         g_object_class_install_property
148                 (object_class,
149                  PROP_ENABLED,
150                  g_param_spec_boolean
151                          ("enabled",
152                           "Enabled",
153                           "TRUE if the white list is active.",
154                           FALSE,
155                           G_PARAM_CONSTRUCT |
156                           G_PARAM_READWRITE |
157                           G_PARAM_STATIC_STRINGS));
158
159         /**
160          * GUPnPWhiteList:entries:
161          *
162          * Whether this white list is active or not.
163          * Type: GList
164          * Transfer: none
165          **/
166         g_object_class_install_property
167                 (object_class,
168                  PROP_ENTRIES,
169                  g_param_spec_pointer
170                          ("entries",
171                           "Entries",
172                           "GList of strings that compose the white list.",
173                           G_PARAM_CONSTRUCT_ONLY |
174                           G_PARAM_READWRITE |
175                           G_PARAM_STATIC_STRINGS));
176 }
177
178 /**
179  * gupnp_white_list_new:
180  *
181  * Create a new #GUPnPWhiteList.
182  * The white list is disabled by default.
183  *
184  * Returns: (transfer full): A new #GUPnPWhiteList object.
185  **/
186 GUPnPWhiteList *
187 gupnp_white_list_new (void)
188 {
189         return g_object_new (GUPNP_TYPE_WHITE_LIST, NULL);
190 }
191
192 /**
193  * gupnp_white_list_set_enabled:
194  * @white_list: A #GUPnPWhiteList
195  * @enable:  %TRUE to enable @white_list, %FALSE otherwise
196  *
197  * Enable or disable the #GUPnPWhiteList to perform the network filtering.
198 **/
199 void
200 gupnp_white_list_set_enabled (GUPnPWhiteList *white_list, gboolean enable)
201 {
202         g_return_if_fail (GUPNP_IS_WHITE_LIST (white_list));
203
204         white_list->priv->enabled = enable;
205         g_object_notify (G_OBJECT (white_list), "enabled");
206 }
207
208 /**
209  * gupnp_white_list_get_enabled:
210  * @white_list: A #GUPnPWhiteList
211  *
212  * Return the status of the #GUPnPWhiteList
213  *
214  * Return value: %TRUE if @white_list is enabled, %FALSE otherwise.
215  **/
216 gboolean
217 gupnp_white_list_get_enabled (GUPnPWhiteList *white_list)
218 {
219         g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), FALSE);
220
221         return white_list->priv->enabled;
222 }
223
224 /**
225  * gupnp_white_list_is_empty:
226  * @white_list: A #GUPnPWhiteList
227  *
228  * Return the state of the entries list of #GUPnPWhiteList
229  *
230  * Return value: %TRUE if @white_list is empty, %FALSE otherwise.
231  **/
232 gboolean
233 gupnp_white_list_is_empty (GUPnPWhiteList *white_list)
234 {
235         g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), TRUE);
236
237         return (white_list->priv->entries == NULL);
238 }
239
240 /**
241  * gupnp_white_list_add_entry:
242  * @white_list: A #GUPnPWhiteList
243  * @entry: A value used to filter network
244  *
245  * Add @entry in the list of valid criteria used by @white_list to
246  * filter networks.
247  * if @entry already exists, it won't be added a second time.
248  *
249  * Return value: %TRUE if @entry is added, %FALSE otherwise.
250  **/
251 gboolean
252 gupnp_white_list_add_entry (GUPnPWhiteList *white_list, gchar* entry)
253 {
254         GList *s_entry;
255         GUPnPWhiteListPrivate *priv;
256
257         g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), FALSE);
258         g_return_val_if_fail ((entry != NULL), FALSE);
259
260         priv = white_list->priv;
261
262         s_entry = g_list_find_custom (priv->entries, entry,
263                                       (GCompareFunc) g_ascii_strcasecmp);
264
265         if (s_entry == NULL) {
266                 priv->entries = g_list_prepend (priv->entries,
267                                                 g_strdup (entry));
268                 g_object_notify (G_OBJECT (white_list), "entries");
269         }
270
271         return (s_entry == NULL);
272 }
273
274 /**
275  * gupnp_white_list_remove_entry:
276  * @white_list: A #GUPnPWhiteList
277  * @entry: A value to remove from the filter list.
278  *
279  * Remove @entry in the list of valid criteria used by @white_list to
280  * filter networks.
281  *
282  * Return value: %TRUE if @entry is removed, %FALSE otherwise.
283  **/
284 gboolean
285 gupnp_white_list_remove_entry (GUPnPWhiteList *white_list, gchar* entry)
286 {
287         GList *s_entry;
288         GUPnPWhiteListPrivate *priv;
289
290         g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), FALSE);
291         g_return_val_if_fail ((entry != NULL), FALSE);
292
293         priv = white_list->priv;
294
295         s_entry = g_list_find_custom (priv->entries, entry,
296                                       (GCompareFunc) g_ascii_strcasecmp);
297
298         if (s_entry != NULL) {
299                 priv->entries = g_list_remove_link (priv->entries, s_entry);
300                 g_list_free_full (s_entry, g_free);
301                 g_object_notify (G_OBJECT (white_list), "entries");
302         }
303
304         return (s_entry != NULL);
305 }
306
307 /**
308  * gupnp_white_list_get_entries:
309  * @white_list: A #GUPnPWhiteList
310  *
311  * Get the #GList of entries that compose the white list. Do not free
312  *
313  * Return value: (element-type utf8) (transfer none):  a #GList of entries
314  * used to filter networks, interfaces,... or %NULL.
315  * Do not modify or free the list nor its elements.
316  **/
317 GList *
318 gupnp_white_list_get_entries (GUPnPWhiteList *white_list)
319 {
320         g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), NULL);
321
322         return white_list->priv->entries;
323 }
324
325 /**
326  * gupnp_white_list_clear:
327  * @white_list: A #GUPnPWhiteList
328  *
329  * Remove all entries from #GList that compose the white list.
330  * The list is now empty. Even if #GUPnPWhiteList is enabled, it will have the
331  * same behavior as if it was disabled.
332 **/
333 void
334 gupnp_white_list_clear (GUPnPWhiteList *white_list)
335 {
336         GUPnPWhiteListPrivate *priv;
337
338         g_return_if_fail (GUPNP_IS_WHITE_LIST(white_list));
339
340         priv = white_list->priv;
341         g_list_free_full (priv->entries, g_free);
342         priv->entries = NULL;
343         g_object_notify (G_OBJECT (white_list), "entries");
344 }
345
346 /**
347  * gupnp_white_list_check_context:
348  * @white_list: A #GUPnPWhiteList
349  * @context: A #GUPnPContext to test.
350  *
351  * It will check if the @context is allowed or not. The @white_list will check
352  * all its entries againt #GUPnPContext interface, host ip and network fields
353  * information. This function doesn't take into account the @white_list status
354  * (enabled or not).
355  *
356  * Return value: %TRUE if @context is matching the @white_list criterias,
357  * %FALSE otherwise.
358  **/
359 gboolean
360 gupnp_white_list_check_context (GUPnPWhiteList *white_list,
361                                 GUPnPContext *context)
362 {
363         GSSDPClient  *client;
364         GList *l;
365         const char *interface;
366         const char *host_ip;
367         const char *network;
368         gboolean match = FALSE;
369
370         g_return_val_if_fail (GUPNP_IS_WHITE_LIST (white_list), FALSE);
371         g_return_val_if_fail (GUPNP_IS_CONTEXT (context), FALSE);
372
373         client = GSSDP_CLIENT (context);
374
375         interface = gssdp_client_get_interface (client);
376         host_ip = gssdp_client_get_host_ip (client);
377         network = gssdp_client_get_network (client);
378
379         l = white_list->priv->entries;
380
381         while (l && !match) {
382                 match = (interface && !strcmp (l->data, interface)) ||
383                         (host_ip && !strcmp (l->data, host_ip)) ||
384                         (network && !strcmp (l->data, network));
385
386                 l = l->next;
387         }
388
389         return match;
390 }