Fix Crash in connman-vpnd in reboot scenario when config file is present
[platform/upstream/connman.git] / vpn / vpn-provider.c
1 /*
2  *
3  *  ConnMan VPN daemon
4  *
5  *  Copyright (C) 2012-2013  Intel Corporation. All rights reserved.
6  *  Copyright (C) 2019  Jolla Ltd. All rights reserved.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License version 2 as
10  *  published by the Free Software Foundation.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <errno.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <gdbus.h>
32 #include <connman/log.h>
33 #include <gweb/gresolv.h>
34 #include <netdb.h>
35
36 #include "../src/connman.h"
37 #include "connman/agent.h"
38 #include "connman/vpn-dbus.h"
39 #include "vpn-provider.h"
40 #include "vpn.h"
41 #include "plugins/vpn.h"
42
43 static DBusConnection *connection;
44 static GHashTable *provider_hash;
45 static GSList *driver_list;
46 static int configuration_count;
47 static bool handle_routes;
48
49 struct vpn_route {
50         int family;
51         char *network;
52         char *netmask;
53         char *gateway;
54 };
55
56 struct vpn_setting {
57         bool hide_value;
58         bool immutable;
59         char *value;
60 };
61
62 struct vpn_provider {
63         int refcount;
64         int index;
65         int fd;
66         enum vpn_provider_state state;
67         char *path;
68         char *identifier;
69         char *name;
70         char *type;
71         char *host;
72         char *domain;
73         int family;
74         GHashTable *routes;
75         struct vpn_provider_driver *driver;
76         void *driver_data;
77         GHashTable *setting_strings;
78         GHashTable *user_routes;
79         GSList *user_networks;
80         GResolv *resolv;
81         char **host_ip;
82         struct vpn_ipconfig *ipconfig_ipv4;
83         struct vpn_ipconfig *ipconfig_ipv6;
84         char **nameservers;
85         guint notify_id;
86         char *config_file;
87         char *config_entry;
88         bool immutable;
89         struct connman_ipaddress *prev_ipv4_addr;
90         struct connman_ipaddress *prev_ipv6_addr;
91         void *plugin_data;
92         unsigned int auth_error_counter;
93         unsigned int conn_error_counter;
94 };
95
96 static void append_properties(DBusMessageIter *iter,
97                                 struct vpn_provider *provider);
98 static int vpn_provider_save(struct vpn_provider *provider);
99
100 static void free_route(gpointer data)
101 {
102         struct vpn_route *route = data;
103
104         g_free(route->network);
105         g_free(route->netmask);
106         g_free(route->gateway);
107
108         g_free(route);
109 }
110
111 static void free_setting(gpointer data)
112 {
113         struct vpn_setting *setting = data;
114
115         g_free(setting->value);
116         g_free(setting);
117 }
118
119 static void append_route(DBusMessageIter *iter, void *user_data)
120 {
121         struct vpn_route *route = user_data;
122         DBusMessageIter item;
123         int family = 0;
124
125         connman_dbus_dict_open(iter, &item);
126
127         if (!route)
128                 goto empty_dict;
129
130         if (route->family == AF_INET)
131                 family = 4;
132         else if (route->family == AF_INET6)
133                 family = 6;
134
135         if (family != 0)
136                 connman_dbus_dict_append_basic(&item, "ProtocolFamily",
137                                         DBUS_TYPE_INT32, &family);
138
139         if (route->network)
140                 connman_dbus_dict_append_basic(&item, "Network",
141                                         DBUS_TYPE_STRING, &route->network);
142
143         if (route->netmask)
144                 connman_dbus_dict_append_basic(&item, "Netmask",
145                                         DBUS_TYPE_STRING, &route->netmask);
146
147         if (route->gateway)
148                 connman_dbus_dict_append_basic(&item, "Gateway",
149                                         DBUS_TYPE_STRING, &route->gateway);
150
151 empty_dict:
152         connman_dbus_dict_close(iter, &item);
153 }
154
155 static void append_routes(DBusMessageIter *iter, void *user_data)
156 {
157         GHashTable *routes = user_data;
158         GHashTableIter hash;
159         gpointer value, key;
160
161         if (!routes) {
162                 append_route(iter, NULL);
163                 return;
164         }
165
166         g_hash_table_iter_init(&hash, routes);
167
168         while (g_hash_table_iter_next(&hash, &key, &value)) {
169                 DBusMessageIter dict;
170
171                 dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL,
172                                                 &dict);
173                 append_route(&dict, value);
174                 dbus_message_iter_close_container(iter, &dict);
175         }
176 }
177
178 static void send_routes(struct vpn_provider *provider, GHashTable *routes,
179                         const char *name)
180 {
181         connman_dbus_property_changed_array(provider->path,
182                                         VPN_CONNECTION_INTERFACE,
183                                         name,
184                                         DBUS_TYPE_DICT_ENTRY,
185                                         append_routes,
186                                         routes);
187 }
188
189 static int provider_routes_changed(struct vpn_provider *provider)
190 {
191         DBG("provider %p", provider);
192
193         send_routes(provider, provider->routes, "ServerRoutes");
194
195         return 0;
196 }
197
198 /*
199  * Sort vpn_route struct based on (similarly to the route key in hash table):
200  * 1) IP protocol number
201  * 2) Network addresses
202  * 3) Netmask addresses
203  * 4) Gateway addresses
204  */
205 static gint compare_route(gconstpointer a, gconstpointer b)
206 {
207         const struct vpn_route *route_a = a;
208         const struct vpn_route *route_b = b;
209         int difference;
210
211         /* If IP families differ, prefer IPv6 over IPv4 */
212         if (route_a->family != route_b->family) {
213                 if (route_a->family < route_b->family)
214                         return -1;
215
216                 if (route_a->family > route_b->family)
217                         return 1;
218         }
219
220         /* If networks differ, return  */
221         if ((difference = g_strcmp0(route_a->network, route_b->network)))
222                 return difference;
223
224         /* If netmasks differ, return. */
225         if ((difference = g_strcmp0(route_a->netmask, route_b->netmask)))
226                 return difference;
227
228         return g_strcmp0(route_a->gateway, route_b->gateway);
229 }
230
231 static GSList *read_route_dict(GSList *routes, DBusMessageIter *dicts)
232 {
233         DBusMessageIter dict, value, entry;
234         const char *network, *netmask, *gateway;
235         struct vpn_route *route;
236         int family, type;
237         const char *key;
238
239         dbus_message_iter_recurse(dicts, &entry);
240
241         network = netmask = gateway = NULL;
242         family = PF_UNSPEC;
243
244         while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_DICT_ENTRY) {
245
246                 dbus_message_iter_recurse(&entry, &dict);
247                 dbus_message_iter_get_basic(&dict, &key);
248
249                 dbus_message_iter_next(&dict);
250                 dbus_message_iter_recurse(&dict, &value);
251
252                 type = dbus_message_iter_get_arg_type(&value);
253
254                 switch (type) {
255                 case DBUS_TYPE_INT32:
256                         if (g_str_equal(key, "ProtocolFamily"))
257                                 dbus_message_iter_get_basic(&value, &family);
258                         break;
259
260                 case DBUS_TYPE_STRING:
261                         if (g_str_equal(key, "Network"))
262                                 dbus_message_iter_get_basic(&value, &network);
263                         else if (g_str_equal(key, "Netmask"))
264                                 dbus_message_iter_get_basic(&value, &netmask);
265                         else if (g_str_equal(key, "Gateway"))
266                                 dbus_message_iter_get_basic(&value, &gateway);
267                         break;
268                 }
269
270                 dbus_message_iter_next(&entry);
271         }
272
273         DBG("family %d network %s netmask %s gateway %s", family,
274                 network, netmask, gateway);
275
276         if (!network || !netmask) {
277                 DBG("Ignoring route as network/netmask is missing");
278                 return routes;
279         }
280
281         route = g_try_new(struct vpn_route, 1);
282         if (!route) {
283                 g_slist_free_full(routes, free_route);
284                 return NULL;
285         }
286
287         if (family == PF_UNSPEC) {
288                 family = connman_inet_check_ipaddress(network);
289                 if (family < 0) {
290                         DBG("Cannot get address family of %s (%d/%s)", network,
291                                 family, gai_strerror(family));
292
293                         g_free(route);
294                         return routes;
295                 }
296         } else {
297                 switch (family) {
298                 case '4':
299                 case 4:
300                         family = AF_INET;
301                         break;
302                 case '6':
303                 case 6:
304                         family = AF_INET6;
305                         break;
306                 default:
307                         family = PF_UNSPEC;
308                         break;
309                 }
310         }
311
312         route->family = family;
313         route->network = g_strdup(network);
314         route->netmask = g_strdup(netmask);
315         route->gateway = g_strdup(gateway);
316
317         routes = g_slist_insert_sorted(routes, route, compare_route);
318         return routes;
319 }
320
321 static GSList *get_user_networks(DBusMessageIter *array)
322 {
323         DBusMessageIter entry;
324         GSList *list = NULL;
325
326         while (dbus_message_iter_get_arg_type(array) == DBUS_TYPE_ARRAY) {
327
328                 dbus_message_iter_recurse(array, &entry);
329
330                 while (dbus_message_iter_get_arg_type(&entry) ==
331                                                         DBUS_TYPE_STRUCT) {
332                         DBusMessageIter dicts;
333
334                         dbus_message_iter_recurse(&entry, &dicts);
335
336                         while (dbus_message_iter_get_arg_type(&dicts) ==
337                                                         DBUS_TYPE_ARRAY) {
338
339                                 list = read_route_dict(list, &dicts);
340                                 dbus_message_iter_next(&dicts);
341                         }
342
343                         dbus_message_iter_next(&entry);
344                 }
345
346                 dbus_message_iter_next(array);
347         }
348
349         return list;
350 }
351
352 static void set_user_networks(struct vpn_provider *provider, GSList *networks)
353 {
354         GSList *list;
355
356         for (list = networks; list; list = g_slist_next(list)) {
357                 struct vpn_route *route = list->data;
358
359                 if (__vpn_provider_append_user_route(provider,
360                                         route->family, route->network,
361                                         route->netmask, route->gateway) != 0)
362                         break;
363         }
364 }
365
366 static void del_routes(struct vpn_provider *provider)
367 {
368         GHashTableIter hash;
369         gpointer value, key;
370
371         g_hash_table_iter_init(&hash, provider->user_routes);
372         while (handle_routes && g_hash_table_iter_next(&hash,
373                                                 &key, &value)) {
374                 struct vpn_route *route = value;
375                 if (route->family == AF_INET6) {
376                         unsigned char prefixlen = atoi(route->netmask);
377                         connman_inet_del_ipv6_network_route(provider->index,
378                                                         route->network,
379                                                         prefixlen);
380                 } else
381                         connman_inet_del_host_route(provider->index,
382                                                 route->network);
383         }
384
385         g_hash_table_remove_all(provider->user_routes);
386         g_slist_free_full(provider->user_networks, free_route);
387         provider->user_networks = NULL;
388 }
389
390 static void send_value(const char *path, const char *key, const char *value)
391 {
392         const char *empty = "";
393         const char *str;
394
395         if (value)
396                 str = value;
397         else
398                 str = empty;
399
400         connman_dbus_property_changed_basic(path,
401                                         VPN_CONNECTION_INTERFACE,
402                                         key,
403                                         DBUS_TYPE_STRING,
404                                         &str);
405 }
406
407 static gboolean provider_send_changed(gpointer data)
408 {
409         struct vpn_provider *provider = data;
410
411         provider_routes_changed(provider);
412
413         provider->notify_id = 0;
414
415         return FALSE;
416 }
417
418 static void provider_schedule_changed(struct vpn_provider *provider)
419 {
420         if (provider->notify_id != 0)
421                 g_source_remove(provider->notify_id);
422
423         provider->notify_id = g_timeout_add(100, provider_send_changed,
424                                                                 provider);
425 }
426
427 static DBusMessage *get_properties(DBusConnection *conn,
428                                         DBusMessage *msg, void *data)
429 {
430         struct vpn_provider *provider = data;
431         DBusMessage *reply;
432         DBusMessageIter array;
433
434         DBG("provider %p", provider);
435
436         reply = dbus_message_new_method_return(msg);
437         if (!reply)
438                 return NULL;
439
440         dbus_message_iter_init_append(reply, &array);
441
442         append_properties(&array, provider);
443
444         return reply;
445 }
446
447 /* True when lists are equal, false otherwise */
448 static bool compare_network_lists(GSList *a, GSList *b)
449 {
450         struct vpn_route *route_a, *route_b;
451         GSList *iter_a, *iter_b;
452
453         if (!a && !b)
454                 return true;
455
456         /*
457          * If either of lists is NULL or the lists are of different size, the
458          * lists are not equal.
459          */
460         if ((!a || !b) || (g_slist_length(a) != g_slist_length(b)))
461                 return false;
462
463         /* Routes are in sorted list so items can be compared in order. */
464         for (iter_a = a, iter_b = b; iter_a && iter_b;
465                                 iter_a = iter_a->next, iter_b = iter_b->next) {
466
467                 route_a = iter_a->data;
468                 route_b = iter_b->data;
469
470                 if (compare_route(route_a, route_b))
471                         return false;
472         }
473
474         return true;
475 }
476
477 static int set_provider_property(struct vpn_provider *provider,
478                         const char *name, DBusMessageIter *value, int type)
479 {
480         int err = 0;
481
482         DBG("provider %p", provider);
483
484         if (!provider || !name || !value)
485                 return -EINVAL;
486
487         if (g_str_equal(name, "UserRoutes")) {
488                 GSList *networks;
489
490                 if (type != DBUS_TYPE_ARRAY)
491                         return -EINVAL;
492
493                 networks = get_user_networks(value);
494
495                 if (compare_network_lists(provider->user_networks, networks)) {
496                         g_slist_free_full(networks, free_route);
497                         return -EALREADY;
498                 }
499
500                 del_routes(provider);
501                 provider->user_networks = networks;
502                 set_user_networks(provider, provider->user_networks);
503
504                 if (!handle_routes)
505                         send_routes(provider, provider->user_routes,
506                                                 "UserRoutes");
507         } else {
508                 const char *str;
509
510                 if (type != DBUS_TYPE_STRING)
511                         return -EINVAL;
512
513                 dbus_message_iter_get_basic(value, &str);
514
515                 DBG("property %s value %s", name, str);
516
517                 /* Empty string clears the value, similar to ClearProperty. */
518                 err = vpn_provider_set_string(provider, name,
519                                         *str ? str : NULL);
520         }
521
522         return err;
523 }
524
525 static GString *append_to_gstring(GString *str, const char *value)
526 {
527         if (!str)
528                 return g_string_new(value);
529
530         g_string_append_printf(str, ",%s", value);
531
532         return str;
533 }
534
535 static DBusMessage *set_properties(DBusMessageIter *iter, DBusMessage *msg,
536                                                                 void *data)
537 {
538         struct vpn_provider *provider = data;
539         DBusMessageIter dict;
540         const char *key;
541         bool change = false;
542         GString *invalid = NULL;
543         GString *denied = NULL;
544         int type;
545         int err;
546
547         for (dbus_message_iter_recurse(iter, &dict);
548                                 dbus_message_iter_get_arg_type(&dict) ==
549                                 DBUS_TYPE_DICT_ENTRY;
550                                 dbus_message_iter_next(&dict)) {
551                 DBusMessageIter entry, value;
552
553                 dbus_message_iter_recurse(&dict, &entry);
554                 /*
555                  * Ignore invalid types in order to process all values in the
556                  * dict. If there is an invalid type in between the dict there
557                  * may already be changes on some values and breaking out here
558                  *  would have the provider in an inconsistent state, leaving
559                  * the rest, potentially correct property values untouched.
560                  */
561                 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
562                         continue;
563
564                 dbus_message_iter_get_basic(&entry, &key);
565
566                 DBG("key %s", key);
567
568                 dbus_message_iter_next(&entry);
569                 /* Ignore and report back all non variant types. */
570                 if (dbus_message_iter_get_arg_type(&entry)
571                                         != DBUS_TYPE_VARIANT) {
572                         invalid = append_to_gstring(invalid, key);
573                         continue;
574                 }
575
576                 dbus_message_iter_recurse(&entry, &value);
577
578                 type = dbus_message_iter_get_arg_type(&value);
579                 /* Ignore and report back all invalid property types */
580                 if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_ARRAY) {
581                         invalid = append_to_gstring(invalid, key);
582                         continue;
583                 }
584
585                 err = set_provider_property(provider, key, &value, type);
586                 switch (err) {
587                 case 0:
588                         change = true;
589                         break;
590                 case -EINVAL:
591                         invalid = append_to_gstring(invalid, key);
592                         break;
593                 case -EPERM:
594                         denied = append_to_gstring(denied, key);
595                         break;
596                 }
597         }
598
599         if (change)
600                 vpn_provider_save(provider);
601
602         if (invalid || denied) {
603                 DBusMessage *error;
604                 char *invalid_str = g_string_free(invalid, FALSE);
605                 char *denied_str = g_string_free(denied, FALSE);
606
607                 /*
608                  * If there are both invalid and denied properties report
609                  * back invalid arguments. Add also the failed properties to
610                  * the error message.
611                  */
612                 error = g_dbus_create_error(msg, (invalid ?
613                                 CONNMAN_ERROR_INTERFACE ".InvalidProperty" :
614                                 CONNMAN_ERROR_INTERFACE ".PermissionDenied"),
615                                 "%s %s%s%s", (invalid ? "Invalid properties" :
616                                 "Permission denied"),
617                                 (invalid ? invalid_str : ""),
618                                 (invalid && denied ? "," : ""),
619                                 (denied ? denied_str : ""));
620
621                 g_free(invalid_str);
622                 g_free(denied_str);
623
624                 return error;
625         }
626
627         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
628 }
629
630 static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
631                                                                 void *data)
632 {
633         struct vpn_provider *provider = data;
634         DBusMessageIter iter, value;
635         const char *name;
636         int type;
637         int err;
638
639         DBG("conn %p", conn);
640
641         if (provider->immutable)
642                 return __connman_error_not_supported(msg);
643
644         if (!dbus_message_iter_init(msg, &iter))
645                 return __connman_error_invalid_arguments(msg);
646
647         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
648                 return __connman_error_invalid_arguments(msg);
649
650         dbus_message_iter_get_basic(&iter, &name);
651         dbus_message_iter_next(&iter);
652
653         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
654                 return __connman_error_invalid_arguments(msg);
655
656         dbus_message_iter_recurse(&iter, &value);
657
658         type = dbus_message_iter_get_arg_type(&value);
659         if (type == DBUS_TYPE_ARRAY && g_str_equal(name, "Properties"))
660                 return set_properties(&value, msg, data);
661
662         err = set_provider_property(provider, name, &value, type);
663         switch (err) {
664         case 0:
665                 vpn_provider_save(provider);
666                 break;
667         case -EALREADY:
668                 break;
669         case -EINVAL:
670                 return __connman_error_invalid_property(msg);
671         default:
672                 return __connman_error_failed(msg, -err);
673         }
674
675         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
676 }
677
678 static DBusMessage *clear_property(DBusConnection *conn, DBusMessage *msg,
679                                                                 void *data)
680 {
681         struct vpn_provider *provider = data;
682         const char *name;
683         bool change = false;
684         int err;
685
686         DBG("conn %p", conn);
687
688         if (provider->immutable)
689                 return __connman_error_not_supported(msg);
690
691         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
692                                                         DBUS_TYPE_INVALID);
693
694         if (g_str_equal(name, "UserRoutes")) {
695                 /*
696                  * If either user_routes or user_networks has any entries
697                  * there is a change that is to be written to settings file.
698                  */
699                 if (g_hash_table_size(provider->user_routes) ||
700                                 provider->user_networks)
701                         change = true;
702
703                 del_routes(provider);
704
705                 if (!handle_routes)
706                         send_routes(provider, provider->user_routes, name);
707         } else if (vpn_provider_get_string(provider, name)) {
708                 err = vpn_provider_set_string(provider, name, NULL);
709                 switch (err) {
710                 case 0:
711                         change = true;
712                         /* fall through */
713                 case -EALREADY:
714                         break;
715                 case -EINVAL:
716                         return __connman_error_invalid_property(msg);
717                 default:
718                         return __connman_error_failed(msg, -err);
719                 }
720         } else {
721                 return __connman_error_invalid_property(msg);
722         }
723
724         if (change)
725                 vpn_provider_save(provider);
726
727         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
728 }
729
730 static DBusMessage *do_connect(DBusConnection *conn, DBusMessage *msg,
731                                                                 void *data)
732 {
733         struct vpn_provider *provider = data;
734         int err;
735
736         DBG("conn %p provider %p", conn, provider);
737
738         err = __vpn_provider_connect(provider, msg);
739         if (err < 0 && err != -EINPROGRESS)
740                 return __connman_error_failed(msg, -err);
741
742         return NULL;
743 }
744
745 static DBusMessage *do_connect2(DBusConnection *conn, DBusMessage *msg,
746                                                                 void *data)
747 {
748         return do_connect(conn, msg, data);
749 }
750
751 static DBusMessage *do_disconnect(DBusConnection *conn, DBusMessage *msg,
752                                                                 void *data)
753 {
754         struct vpn_provider *provider = data;
755         int err;
756
757         DBG("conn %p provider %p", conn, provider);
758
759         err = __vpn_provider_disconnect(provider);
760         if (err < 0 && err != -EINPROGRESS)
761                 return __connman_error_failed(msg, -err);
762
763         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
764 }
765
766 static const GDBusMethodTable connection_methods[] = {
767         { GDBUS_METHOD("GetProperties",
768                         NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
769                         get_properties) },
770         { GDBUS_METHOD("SetProperty",
771                         GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
772                         NULL, set_property) },
773         { GDBUS_METHOD("ClearProperty",
774                         GDBUS_ARGS({ "name", "s" }), NULL,
775                         clear_property) },
776         { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, do_connect) },
777         { GDBUS_ASYNC_METHOD("Connect2",
778                         GDBUS_ARGS({ "dbus_sender", "s" }),
779                         NULL, do_connect2) },
780         { GDBUS_METHOD("Disconnect", NULL, NULL, do_disconnect) },
781         { },
782 };
783
784 static const GDBusSignalTable connection_signals[] = {
785         { GDBUS_SIGNAL("PropertyChanged",
786                         GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
787         { },
788 };
789
790 static void resolv_result(GResolvResultStatus status,
791                                         char **results, gpointer user_data)
792 {
793         struct vpn_provider *provider = user_data;
794
795         DBG("status %d", status);
796
797         if (status == G_RESOLV_RESULT_STATUS_SUCCESS && results &&
798                                                 g_strv_length(results) > 0)
799                 provider->host_ip = g_strdupv(results);
800
801         vpn_provider_unref(provider);
802
803         /* Remove the resolver here so that it will not be left
804          * hanging around and cause double free in unregister_provider()
805          */
806         g_resolv_unref(provider->resolv);
807         provider->resolv = NULL;
808 }
809
810 static void provider_resolv_host_addr(struct vpn_provider *provider)
811 {
812         if (!provider->host)
813                 return;
814
815         if (connman_inet_check_ipaddress(provider->host) > 0)
816                 return;
817
818         if (provider->host_ip)
819                 return;
820
821         /*
822          * If the hostname is not numeric, try to resolv it. We do not wait
823          * the result as it might take some time. We will get the result
824          * before VPN will feed routes to us because VPN client will need
825          * the IP address also before VPN connection can be established.
826          */
827         provider->resolv = g_resolv_new(0);
828         if (!provider->resolv) {
829                 DBG("Cannot resolv %s", provider->host);
830                 return;
831         }
832
833         DBG("Trying to resolv %s", provider->host);
834
835         vpn_provider_ref(provider);
836
837         g_resolv_lookup_hostname(provider->resolv, provider->host,
838                                 resolv_result, provider);
839 }
840
841 void __vpn_provider_append_properties(struct vpn_provider *provider,
842                                                         DBusMessageIter *iter)
843 {
844         if (provider->host)
845                 connman_dbus_dict_append_basic(iter, "Host",
846                                         DBUS_TYPE_STRING, &provider->host);
847
848         if (provider->domain)
849                 connman_dbus_dict_append_basic(iter, "Domain",
850                                         DBUS_TYPE_STRING, &provider->domain);
851
852         if (provider->type)
853                 connman_dbus_dict_append_basic(iter, "Type", DBUS_TYPE_STRING,
854                                                  &provider->type);
855 }
856
857 int __vpn_provider_append_user_route(struct vpn_provider *provider,
858                                 int family, const char *network,
859                                 const char *netmask, const char *gateway)
860 {
861         struct vpn_route *route;
862         char *key = g_strdup_printf("%d/%s/%s/%s", family, network,
863                                 netmask, gateway ? gateway : "");
864
865         DBG("family %d network %s netmask %s gw %s", family, network,
866                                                         netmask, gateway);
867
868         route = g_hash_table_lookup(provider->user_routes, key);
869         if (!route) {
870                 route = g_try_new0(struct vpn_route, 1);
871                 if (!route) {
872                         connman_error("out of memory");
873                         return -ENOMEM;
874                 }
875
876                 route->family = family;
877                 route->network = g_strdup(network);
878                 route->netmask = g_strdup(netmask);
879                 route->gateway = g_strdup(gateway);
880
881                 g_hash_table_replace(provider->user_routes, key, route);
882         } else
883                 g_free(key);
884
885         return 0;
886 }
887
888 static struct vpn_route *get_route(char *route_str)
889 {
890         char **elems = g_strsplit(route_str, "/", 0);
891         char *network, *netmask, *gateway, *family_str;
892         int family = PF_UNSPEC;
893         struct vpn_route *route = NULL;
894
895         if (!elems)
896                 return NULL;
897
898         family_str = elems[0];
899
900         network = elems[1];
901         if (!network || network[0] == '\0')
902                 goto out;
903
904         netmask = elems[2];
905         if (!netmask || netmask[0] == '\0')
906                 goto out;
907
908         gateway = elems[3];
909
910         route = g_try_new0(struct vpn_route, 1);
911         if (!route)
912                 goto out;
913
914         if (family_str[0] == '\0' || atoi(family_str) == 0) {
915                 family = PF_UNSPEC;
916         } else {
917                 switch (family_str[0]) {
918                 case '4':
919                         family = AF_INET;
920                         break;
921                 case '6':
922                         family = AF_INET6;
923                         break;
924                 }
925         }
926
927         if (g_strrstr(network, ":")) {
928                 if (family != PF_UNSPEC && family != AF_INET6)
929                         DBG("You have IPv6 address but you have non IPv6 route");
930         } else if (g_strrstr(network, ".")) {
931                 if (family != PF_UNSPEC && family != AF_INET)
932                         DBG("You have IPv4 address but you have non IPv4 route");
933
934                 if (!g_strrstr(netmask, ".")) {
935                         /* We have netmask length */
936                         in_addr_t addr;
937                         struct in_addr netmask_in;
938                         unsigned char prefix_len = 32;
939                         char *ptr;
940                         long int value = strtol(netmask, &ptr, 10);
941
942                         if (ptr != netmask && *ptr == '\0' && value <= 32)
943                                 prefix_len = value;
944
945                         addr = 0xffffffff << (32 - prefix_len);
946                         netmask_in.s_addr = htonl(addr);
947                         netmask = inet_ntoa(netmask_in);
948
949                         DBG("network %s netmask %s", network, netmask);
950                 }
951         }
952
953         if (family == PF_UNSPEC) {
954                 family = connman_inet_check_ipaddress(network);
955                 if (family < 0 || family == PF_UNSPEC)
956                         goto out;
957         }
958
959         route->family = family;
960         route->network = g_strdup(network);
961         route->netmask = g_strdup(netmask);
962         route->gateway = g_strdup(gateway);
963
964 out:
965         g_strfreev(elems);
966         return route;
967 }
968
969 static GSList *get_routes(gchar **networks)
970 {
971         struct vpn_route *route;
972         GSList *routes = NULL;
973         int i;
974
975         for (i = 0; networks[i]; i++) {
976                 route = get_route(networks[i]);
977                 if (route)
978                         routes = g_slist_prepend(routes, route);
979         }
980
981         return routes;
982 }
983
984 static int provider_load_from_keyfile(struct vpn_provider *provider,
985                 GKeyFile *keyfile)
986 {
987         gsize idx = 0;
988         gchar **settings;
989         gchar *key, *value;
990         gsize length, num_user_networks;
991         gchar **networks = NULL;
992
993         settings = g_key_file_get_keys(keyfile, provider->identifier, &length,
994                                 NULL);
995         if (!settings) {
996                 g_key_file_free(keyfile);
997                 return -ENOENT;
998         }
999
1000         while (idx < length) {
1001                 key = settings[idx];
1002                 if (key) {
1003                         if (g_str_equal(key, "Networks")) {
1004                                 networks = __vpn_config_get_string_list(keyfile,
1005                                                 provider->identifier,
1006                                                 key,
1007                                                 &num_user_networks,
1008                                                 NULL);
1009                                 provider->user_networks = get_routes(networks);
1010
1011                         } else {
1012                                 value = __vpn_config_get_string(keyfile,
1013                                                         provider->identifier,
1014                                                         key, NULL);
1015                                 vpn_provider_set_string(provider, key,
1016                                                         value);
1017                                 g_free(value);
1018                         }
1019                 }
1020                 idx += 1;
1021         }
1022         g_strfreev(settings);
1023         g_strfreev(networks);
1024
1025         if (provider->user_networks)
1026                 set_user_networks(provider, provider->user_networks);
1027
1028         return 0;
1029 }
1030
1031
1032 static int vpn_provider_load(struct vpn_provider *provider)
1033 {
1034         GKeyFile *keyfile;
1035
1036         DBG("provider %p", provider);
1037
1038         keyfile = __connman_storage_load_provider(provider->identifier);
1039         if (!keyfile)
1040                 return -ENOENT;
1041
1042         provider_load_from_keyfile(provider, keyfile);
1043
1044         g_key_file_free(keyfile);
1045         return 0;
1046 }
1047
1048 static gchar **create_network_list(GSList *networks, gsize *count)
1049 {
1050         GSList *list;
1051         gchar **result = NULL;
1052         gchar **prev_result;
1053         unsigned int num_elems = 0;
1054
1055         for (list = networks; list; list = g_slist_next(list)) {
1056                 struct vpn_route *route = list->data;
1057                 int family;
1058
1059                 prev_result = result;
1060                 result = g_try_realloc(result,
1061                                 (num_elems + 1) * sizeof(gchar *));
1062                 if (!result) {
1063                         g_free(prev_result);
1064                         return NULL;
1065                 }
1066
1067                 switch (route->family) {
1068                 case AF_INET:
1069                         family = 4;
1070                         break;
1071                 case AF_INET6:
1072                         family = 6;
1073                         break;
1074                 default:
1075                         family = 0;
1076                         break;
1077                 }
1078
1079                 result[num_elems] = g_strdup_printf("%d/%s/%s/%s",
1080                                 family, route->network, route->netmask,
1081                                 !route->gateway ? "" : route->gateway);
1082
1083                 num_elems++;
1084         }
1085
1086         prev_result = result;
1087         result = g_try_realloc(result, (num_elems + 1) * sizeof(gchar *));
1088         if (!result) {
1089                 g_free(prev_result);
1090                 return NULL;
1091         }
1092
1093         result[num_elems] = NULL;
1094         *count = num_elems;
1095         return result;
1096 }
1097
1098 static void reset_error_counters(struct vpn_provider *provider)
1099 {
1100         if (!provider)
1101                 return;
1102
1103         provider->auth_error_counter = provider->conn_error_counter = 0;
1104 }
1105
1106 static int vpn_provider_save(struct vpn_provider *provider)
1107 {
1108         GKeyFile *keyfile;
1109
1110         DBG("provider %p immutable %s", provider,
1111                                         provider->immutable ? "yes" : "no");
1112
1113         reset_error_counters(provider);
1114
1115         if (provider->state == VPN_PROVIDER_STATE_FAILURE)
1116                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_IDLE);
1117
1118         if (provider->immutable) {
1119                 /*
1120                  * Do not save providers that are provisioned via .config
1121                  * file.
1122                  */
1123                 return -EPERM;
1124         }
1125
1126         keyfile = g_key_file_new();
1127         if (!keyfile)
1128                 return -ENOMEM;
1129
1130         g_key_file_set_string(keyfile, provider->identifier,
1131                         "Name", provider->name);
1132         g_key_file_set_string(keyfile, provider->identifier,
1133                         "Type", provider->type);
1134         g_key_file_set_string(keyfile, provider->identifier,
1135                         "Host", provider->host);
1136         g_key_file_set_string(keyfile, provider->identifier,
1137                         "VPN.Domain", provider->domain);
1138         if (provider->user_networks) {
1139                 gchar **networks;
1140                 gsize network_count;
1141
1142                 networks = create_network_list(provider->user_networks,
1143                                                         &network_count);
1144                 if (networks) {
1145                         g_key_file_set_string_list(keyfile,
1146                                                 provider->identifier,
1147                                                 "Networks",
1148                                                 (const gchar ** const)networks,
1149                                                 network_count);
1150                         g_strfreev(networks);
1151                 }
1152         }
1153
1154         if (provider->config_file && strlen(provider->config_file) > 0)
1155                 g_key_file_set_string(keyfile, provider->identifier,
1156                                 "Config.file", provider->config_file);
1157
1158         if (provider->config_entry &&
1159                                         strlen(provider->config_entry) > 0)
1160                 g_key_file_set_string(keyfile, provider->identifier,
1161                                 "Config.ident", provider->config_entry);
1162
1163         if (provider->driver && provider->driver->save)
1164                 provider->driver->save(provider, keyfile);
1165
1166         __connman_storage_save_provider(keyfile, provider->identifier);
1167         g_key_file_free(keyfile);
1168
1169         return 0;
1170 }
1171
1172 struct vpn_provider *__vpn_provider_lookup(const char *identifier)
1173 {
1174         struct vpn_provider *provider = NULL;
1175
1176         provider = g_hash_table_lookup(provider_hash, identifier);
1177
1178         return provider;
1179 }
1180
1181 static bool match_driver(struct vpn_provider *provider,
1182                                 struct vpn_provider_driver *driver)
1183 {
1184         if (g_strcmp0(driver->name, provider->type) == 0)
1185                 return true;
1186
1187         return false;
1188 }
1189
1190 static int provider_probe(struct vpn_provider *provider)
1191 {
1192         GSList *list;
1193
1194         DBG("provider %p driver %p name %s", provider, provider->driver,
1195                                                 provider->name);
1196
1197         if (provider->driver)
1198                 return -EALREADY;
1199
1200         for (list = driver_list; list; list = list->next) {
1201                 struct vpn_provider_driver *driver = list->data;
1202
1203                 if (!match_driver(provider, driver))
1204                         continue;
1205
1206                 DBG("driver %p name %s", driver, driver->name);
1207
1208                 if (driver->probe && driver->probe(provider) == 0) {
1209                         provider->driver = driver;
1210                         break;
1211                 }
1212         }
1213
1214         if (!provider->driver)
1215                 return -ENODEV;
1216
1217         return 0;
1218 }
1219
1220 static void provider_remove(struct vpn_provider *provider)
1221 {
1222         if (provider->driver) {
1223                 provider->driver->remove(provider);
1224                 provider->driver = NULL;
1225         }
1226 }
1227
1228 static int provider_register(struct vpn_provider *provider)
1229 {
1230         return provider_probe(provider);
1231 }
1232
1233 static void provider_unregister(struct vpn_provider *provider)
1234 {
1235         provider_remove(provider);
1236 }
1237
1238 struct vpn_provider *
1239 vpn_provider_ref_debug(struct vpn_provider *provider,
1240                         const char *file, int line, const char *caller)
1241 {
1242         DBG("%p ref %d by %s:%d:%s()", provider, provider->refcount + 1,
1243                 file, line, caller);
1244
1245         __sync_fetch_and_add(&provider->refcount, 1);
1246
1247         return provider;
1248 }
1249
1250 static void provider_destruct(struct vpn_provider *provider)
1251 {
1252         DBG("provider %p", provider);
1253
1254         if (provider->notify_id != 0)
1255                 g_source_remove(provider->notify_id);
1256
1257         g_free(provider->name);
1258         g_free(provider->type);
1259         g_free(provider->host);
1260         g_free(provider->domain);
1261         g_free(provider->identifier);
1262         g_free(provider->path);
1263         g_slist_free_full(provider->user_networks, free_route);
1264         g_strfreev(provider->nameservers);
1265         g_hash_table_destroy(provider->routes);
1266         g_hash_table_destroy(provider->user_routes);
1267         g_hash_table_destroy(provider->setting_strings);
1268         if (provider->resolv) {
1269                 g_resolv_unref(provider->resolv);
1270                 provider->resolv = NULL;
1271         }
1272         __vpn_ipconfig_unref(provider->ipconfig_ipv4);
1273         __vpn_ipconfig_unref(provider->ipconfig_ipv6);
1274
1275         g_strfreev(provider->host_ip);
1276         g_free(provider->config_file);
1277         g_free(provider->config_entry);
1278         connman_ipaddress_free(provider->prev_ipv4_addr);
1279         connman_ipaddress_free(provider->prev_ipv6_addr);
1280         g_free(provider);
1281 }
1282
1283 void vpn_provider_unref_debug(struct vpn_provider *provider,
1284                                 const char *file, int line, const char *caller)
1285 {
1286         DBG("%p ref %d by %s:%d:%s()", provider, provider->refcount - 1,
1287                 file, line, caller);
1288
1289         if (__sync_fetch_and_sub(&provider->refcount, 1) != 1)
1290                 return;
1291
1292         provider_remove(provider);
1293
1294         provider_destruct(provider);
1295 }
1296
1297 static void configuration_count_add(void)
1298 {
1299         DBG("count %d", configuration_count + 1);
1300
1301         __sync_fetch_and_add(&configuration_count, 1);
1302 }
1303
1304 static void configuration_count_del(void)
1305 {
1306         DBG("count %d", configuration_count - 1);
1307
1308         if (__sync_fetch_and_sub(&configuration_count, 1) != 1)
1309                 return;
1310 }
1311
1312 int __vpn_provider_disconnect(struct vpn_provider *provider)
1313 {
1314         int err;
1315
1316         DBG("provider %p", provider);
1317
1318         if (provider->driver && provider->driver->disconnect)
1319                 err = provider->driver->disconnect(provider);
1320         else
1321                 return -EOPNOTSUPP;
1322
1323         if (err == -EINPROGRESS)
1324                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_CONNECT);
1325
1326         return err;
1327 }
1328
1329 static void connect_cb(struct vpn_provider *provider, void *user_data,
1330                                                                 int error)
1331 {
1332         DBusMessage *pending = user_data;
1333
1334         DBG("provider %p user %p error %d", provider, user_data, error);
1335
1336         if (error != 0) {
1337                 DBusMessage *reply = __connman_error_failed(pending, error);
1338                 if (reply)
1339                         g_dbus_send_message(connection, reply);
1340
1341                 switch (error) {
1342                 case EACCES:
1343                         vpn_provider_indicate_error(provider,
1344                                                 VPN_PROVIDER_ERROR_AUTH_FAILED);
1345                         break;
1346                 case ENOENT:
1347                         /*
1348                          * No reply, disconnect called by connmand because of
1349                          * connection timeout.
1350                          */
1351                         break;
1352                 case ENOMSG:
1353                         /* fall through */
1354                 case ETIMEDOUT:
1355                         /* No reply or timed out -> cancel the agent request */
1356                         connman_agent_cancel(provider);
1357                         vpn_provider_indicate_error(provider,
1358                                                 VPN_PROVIDER_ERROR_UNKNOWN);
1359                         break;
1360                 case ECANCELED:
1361                         /* fall through */
1362                 case ECONNABORTED:
1363                         /*
1364                          * This can be called in other situations than when
1365                          * VPN agent error checker is called. In such case
1366                          * react to both ECONNABORTED and ECANCELED as if the
1367                          * connection was called to terminate and do full
1368                          * disconnect -> idle cycle when being connected or
1369                          * ready. Setting the state also using the driver
1370                          * callback (vpn_set_state()) ensures that the driver is
1371                          * being disconnected as well and eventually the vpn
1372                          * process gets killed and vpn_died() is called to make
1373                          * the provider back to idle state.
1374                          */
1375                         if (provider->state == VPN_PROVIDER_STATE_CONNECT ||
1376                                                 provider->state ==
1377                                                 VPN_PROVIDER_STATE_READY) {
1378                                 if (provider->driver->set_state)
1379                                         provider->driver->set_state(provider,
1380                                                 VPN_PROVIDER_STATE_DISCONNECT);
1381
1382                                 vpn_provider_set_state(provider,
1383                                                 VPN_PROVIDER_STATE_DISCONNECT);
1384                         }
1385                         break;
1386                 default:
1387                         vpn_provider_indicate_error(provider,
1388                                         VPN_PROVIDER_ERROR_CONNECT_FAILED);
1389                         vpn_provider_set_state(provider,
1390                                         VPN_PROVIDER_STATE_FAILURE);
1391                 }
1392         } else {
1393                 reset_error_counters(provider);
1394                 g_dbus_send_reply(connection, pending, DBUS_TYPE_INVALID);
1395         }
1396
1397         dbus_message_unref(pending);
1398 }
1399
1400 int __vpn_provider_connect(struct vpn_provider *provider, DBusMessage *msg)
1401 {
1402         DBusMessage *reply;
1403         int err;
1404
1405         DBG("provider %p state %d", provider, provider->state);
1406
1407         switch (provider->state) {
1408         /*
1409          * When previous connection has failed change state to idle and let
1410          * the connmand to process this information as well. Return -EINPROGRESS
1411          * to indicate that transition is in progress and next connection
1412          * attempt will continue as normal.
1413          */
1414         case VPN_PROVIDER_STATE_FAILURE:
1415                 if (provider->driver && provider->driver->set_state)
1416                         provider->driver->set_state(provider,
1417                                                 VPN_PROVIDER_STATE_IDLE);
1418
1419                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_IDLE);
1420                 /* fall through */
1421         /*
1422          * If re-using a provider and it is being disconnected let it finish
1423          * the disconnect process in order to let vpn.c:vpn_died() to get
1424          * processed and everything cleaned up. Otherwise the reference
1425          * counters are not decreased properly causing the previous interface
1426          * being left up and its routes will remain in routing table. Return
1427          * -EINPROGRESS to indicate that transition is in progress.
1428          */
1429         case VPN_PROVIDER_STATE_DISCONNECT:
1430                 /*
1431                  * Failure transition or disconnecting does not yield a
1432                  * message to be sent. Send in progress message to avoid
1433                  * D-Bus LimitsExceeded error message.
1434                  */
1435                 reply = __connman_error_in_progress(msg);
1436                 if (reply)
1437                         g_dbus_send_message(connection, reply);
1438
1439                 return -EINPROGRESS;
1440         case VPN_PROVIDER_STATE_UNKNOWN:
1441         case VPN_PROVIDER_STATE_IDLE:
1442         case VPN_PROVIDER_STATE_CONNECT:
1443         case VPN_PROVIDER_STATE_READY:
1444                 break;
1445         }
1446
1447         if (provider->driver && provider->driver->connect) {
1448                 const char *dbus_sender = dbus_message_get_sender(msg);
1449
1450                 dbus_message_ref(msg);
1451
1452                 if (dbus_message_has_signature(msg,
1453                                                 DBUS_TYPE_STRING_AS_STRING)) {
1454                         const char *sender = NULL;
1455
1456                         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING,
1457                                         &sender, DBUS_TYPE_INVALID);
1458                         if (sender && sender[0])
1459                                 dbus_sender = sender;
1460                 }
1461
1462                 err = provider->driver->connect(provider, connect_cb,
1463                                                 dbus_sender, msg);
1464         } else
1465                 return -EOPNOTSUPP;
1466
1467         if (err == -EINPROGRESS)
1468                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_CONNECT);
1469
1470         return err;
1471 }
1472
1473 static void connection_removed_signal(struct vpn_provider *provider)
1474 {
1475         DBusMessage *signal;
1476         DBusMessageIter iter;
1477
1478         signal = dbus_message_new_signal(VPN_MANAGER_PATH,
1479                         VPN_MANAGER_INTERFACE, "ConnectionRemoved");
1480         if (!signal)
1481                 return;
1482
1483         dbus_message_iter_init_append(signal, &iter);
1484         dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1485                                                         &provider->path);
1486         dbus_connection_send(connection, signal, NULL);
1487         dbus_message_unref(signal);
1488 }
1489
1490 static char *get_ident(const char *path)
1491 {
1492         char *pos;
1493
1494         if (*path != '/')
1495                 return NULL;
1496
1497         pos = strrchr(path, '/');
1498         if (!pos)
1499                 return NULL;
1500
1501         return pos + 1;
1502 }
1503
1504 int __vpn_provider_remove(const char *path)
1505 {
1506         struct vpn_provider *provider;
1507         char *ident;
1508
1509         DBG("path %s", path);
1510
1511         ident = get_ident(path);
1512
1513         provider = __vpn_provider_lookup(ident);
1514         if (provider)
1515                 return __vpn_provider_delete(provider);
1516
1517         return -ENXIO;
1518 }
1519
1520 int __vpn_provider_delete(struct vpn_provider *provider)
1521 {
1522         DBG("Deleting VPN %s", provider->identifier);
1523
1524         connection_removed_signal(provider);
1525
1526         provider_unregister(provider);
1527
1528         __connman_storage_remove_provider(provider->identifier);
1529
1530         g_hash_table_remove(provider_hash, provider->identifier);
1531
1532         return 0;
1533 }
1534
1535 static void append_ipv4(DBusMessageIter *iter, void *user_data)
1536 {
1537         struct vpn_provider *provider = user_data;
1538         const char *address, *gateway, *peer;
1539
1540         address = __vpn_ipconfig_get_local(provider->ipconfig_ipv4);
1541         if (address) {
1542                 in_addr_t addr;
1543                 struct in_addr netmask;
1544                 char *mask;
1545                 int prefixlen;
1546
1547                 prefixlen = __vpn_ipconfig_get_prefixlen(
1548                                                 provider->ipconfig_ipv4);
1549
1550                 addr = 0xffffffff << (32 - prefixlen);
1551                 netmask.s_addr = htonl(addr);
1552                 mask = inet_ntoa(netmask);
1553
1554                 connman_dbus_dict_append_basic(iter, "Address",
1555                                                 DBUS_TYPE_STRING, &address);
1556
1557                 connman_dbus_dict_append_basic(iter, "Netmask",
1558                                                 DBUS_TYPE_STRING, &mask);
1559         }
1560
1561         gateway = __vpn_ipconfig_get_gateway(provider->ipconfig_ipv4);
1562         if (gateway)
1563                 connman_dbus_dict_append_basic(iter, "Gateway",
1564                                                 DBUS_TYPE_STRING, &gateway);
1565
1566         peer = __vpn_ipconfig_get_peer(provider->ipconfig_ipv4);
1567         if (peer)
1568                 connman_dbus_dict_append_basic(iter, "Peer",
1569                                                 DBUS_TYPE_STRING, &peer);
1570 }
1571
1572 static void append_ipv6(DBusMessageIter *iter, void *user_data)
1573 {
1574         struct vpn_provider *provider = user_data;
1575         const char *address, *gateway, *peer;
1576
1577         address = __vpn_ipconfig_get_local(provider->ipconfig_ipv6);
1578         if (address) {
1579                 unsigned char prefixlen;
1580
1581                 connman_dbus_dict_append_basic(iter, "Address",
1582                                                 DBUS_TYPE_STRING, &address);
1583
1584                 prefixlen = __vpn_ipconfig_get_prefixlen(
1585                                                 provider->ipconfig_ipv6);
1586
1587                 connman_dbus_dict_append_basic(iter, "PrefixLength",
1588                                                 DBUS_TYPE_BYTE, &prefixlen);
1589         }
1590
1591         gateway = __vpn_ipconfig_get_gateway(provider->ipconfig_ipv6);
1592         if (gateway)
1593                 connman_dbus_dict_append_basic(iter, "Gateway",
1594                                                 DBUS_TYPE_STRING, &gateway);
1595
1596         peer = __vpn_ipconfig_get_peer(provider->ipconfig_ipv6);
1597         if (peer)
1598                 connman_dbus_dict_append_basic(iter, "Peer",
1599                                                 DBUS_TYPE_STRING, &peer);
1600 }
1601
1602 static const char *state2string(enum vpn_provider_state state)
1603 {
1604         switch (state) {
1605         case VPN_PROVIDER_STATE_UNKNOWN:
1606                 break;
1607         case VPN_PROVIDER_STATE_IDLE:
1608                 return "idle";
1609         case VPN_PROVIDER_STATE_CONNECT:
1610                 return "configuration";
1611         case VPN_PROVIDER_STATE_READY:
1612                 return "ready";
1613         case VPN_PROVIDER_STATE_DISCONNECT:
1614                 return "disconnect";
1615         case VPN_PROVIDER_STATE_FAILURE:
1616                 return "failure";
1617         }
1618
1619         return NULL;
1620 }
1621
1622 static void append_nameservers(DBusMessageIter *iter, char **servers)
1623 {
1624         int i;
1625
1626         DBG("%p", servers);
1627
1628         for (i = 0; servers[i]; i++) {
1629                 DBG("servers[%d] %s", i, servers[i]);
1630                 dbus_message_iter_append_basic(iter,
1631                                         DBUS_TYPE_STRING, &servers[i]);
1632         }
1633 }
1634
1635 static void append_dns(DBusMessageIter *iter, void *user_data)
1636 {
1637         struct vpn_provider *provider = user_data;
1638
1639         if (provider->nameservers)
1640                 append_nameservers(iter, provider->nameservers);
1641 }
1642
1643 static int provider_indicate_state(struct vpn_provider *provider,
1644                                 enum vpn_provider_state state)
1645 {
1646         const char *str;
1647         enum vpn_provider_state old_state;
1648
1649         str = state2string(state);
1650         DBG("provider %p state %s/%d", provider, str, state);
1651         if (!str)
1652                 return -EINVAL;
1653
1654         old_state = provider->state;
1655         provider->state = state;
1656
1657         if (state == VPN_PROVIDER_STATE_READY) {
1658                 connman_dbus_property_changed_basic(provider->path,
1659                                         VPN_CONNECTION_INTERFACE, "Index",
1660                                         DBUS_TYPE_INT32, &provider->index);
1661
1662                 if (provider->family == AF_INET)
1663                         connman_dbus_property_changed_dict(provider->path,
1664                                         VPN_CONNECTION_INTERFACE, "IPv4",
1665                                         append_ipv4, provider);
1666                 else if (provider->family == AF_INET6)
1667                         connman_dbus_property_changed_dict(provider->path,
1668                                         VPN_CONNECTION_INTERFACE, "IPv6",
1669                                         append_ipv6, provider);
1670
1671                 connman_dbus_property_changed_array(provider->path,
1672                                                 VPN_CONNECTION_INTERFACE,
1673                                                 "Nameservers",
1674                                                 DBUS_TYPE_STRING,
1675                                                 append_dns, provider);
1676
1677                 if (provider->domain)
1678                         connman_dbus_property_changed_basic(provider->path,
1679                                                 VPN_CONNECTION_INTERFACE,
1680                                                 "Domain",
1681                                                 DBUS_TYPE_STRING,
1682                                                 &provider->domain);
1683         }
1684
1685         if (old_state != state)
1686                 connman_dbus_property_changed_basic(provider->path,
1687                                         VPN_CONNECTION_INTERFACE, "State",
1688                                         DBUS_TYPE_STRING, &str);
1689
1690         return 0;
1691 }
1692
1693 static void append_state(DBusMessageIter *iter,
1694                                         struct vpn_provider *provider)
1695 {
1696         char *str;
1697
1698         switch (provider->state) {
1699         case VPN_PROVIDER_STATE_UNKNOWN:
1700         case VPN_PROVIDER_STATE_IDLE:
1701                 str = "idle";
1702                 break;
1703         case VPN_PROVIDER_STATE_CONNECT:
1704                 str = "configuration";
1705                 break;
1706         case VPN_PROVIDER_STATE_READY:
1707                 str = "ready";
1708                 break;
1709         case VPN_PROVIDER_STATE_DISCONNECT:
1710                 str = "disconnect";
1711                 break;
1712         case VPN_PROVIDER_STATE_FAILURE:
1713                 str = "failure";
1714                 break;
1715         }
1716
1717         connman_dbus_dict_append_basic(iter, "State",
1718                                 DBUS_TYPE_STRING, &str);
1719 }
1720
1721 static void append_properties(DBusMessageIter *iter,
1722                                         struct vpn_provider *provider)
1723 {
1724         DBusMessageIter dict;
1725         GHashTableIter hash;
1726         gpointer value, key;
1727         dbus_bool_t immutable;
1728
1729         connman_dbus_dict_open(iter, &dict);
1730
1731         append_state(&dict, provider);
1732
1733         if (provider->type)
1734                 connman_dbus_dict_append_basic(&dict, "Type",
1735                                         DBUS_TYPE_STRING, &provider->type);
1736
1737         if (provider->name)
1738                 connman_dbus_dict_append_basic(&dict, "Name",
1739                                         DBUS_TYPE_STRING, &provider->name);
1740
1741         if (provider->host)
1742                 connman_dbus_dict_append_basic(&dict, "Host",
1743                                         DBUS_TYPE_STRING, &provider->host);
1744         if (provider->index >= 0)
1745                 connman_dbus_dict_append_basic(&dict, "Index",
1746                                         DBUS_TYPE_INT32, &provider->index);
1747         if (provider->domain)
1748                 connman_dbus_dict_append_basic(&dict, "Domain",
1749                                         DBUS_TYPE_STRING, &provider->domain);
1750
1751         immutable = provider->immutable;
1752         connman_dbus_dict_append_basic(&dict, "Immutable", DBUS_TYPE_BOOLEAN,
1753                                         &immutable);
1754
1755         if (provider->family == AF_INET)
1756                 connman_dbus_dict_append_dict(&dict, "IPv4", append_ipv4,
1757                                                 provider);
1758         else if (provider->family == AF_INET6)
1759                 connman_dbus_dict_append_dict(&dict, "IPv6", append_ipv6,
1760                                                 provider);
1761
1762         connman_dbus_dict_append_array(&dict, "Nameservers",
1763                                 DBUS_TYPE_STRING, append_dns, provider);
1764
1765         connman_dbus_dict_append_array(&dict, "UserRoutes",
1766                                 DBUS_TYPE_DICT_ENTRY, append_routes,
1767                                 provider->user_routes);
1768
1769         connman_dbus_dict_append_array(&dict, "ServerRoutes",
1770                                 DBUS_TYPE_DICT_ENTRY, append_routes,
1771                                 provider->routes);
1772
1773         if (provider->setting_strings) {
1774                 g_hash_table_iter_init(&hash, provider->setting_strings);
1775
1776                 while (g_hash_table_iter_next(&hash, &key, &value)) {
1777                         struct vpn_setting *setting = value;
1778
1779                         if (!setting->hide_value &&
1780                                                         setting->value)
1781                                 connman_dbus_dict_append_basic(&dict, key,
1782                                                         DBUS_TYPE_STRING,
1783                                                         &setting->value);
1784                 }
1785         }
1786
1787         connman_dbus_dict_close(iter, &dict);
1788 }
1789
1790 static void connection_added_signal(struct vpn_provider *provider)
1791 {
1792         DBusMessage *signal;
1793         DBusMessageIter iter;
1794
1795         signal = dbus_message_new_signal(VPN_MANAGER_PATH,
1796                         VPN_MANAGER_INTERFACE, "ConnectionAdded");
1797         if (!signal)
1798                 return;
1799
1800         dbus_message_iter_init_append(signal, &iter);
1801         dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1802                                                         &provider->path);
1803         append_properties(&iter, provider);
1804
1805         dbus_connection_send(connection, signal, NULL);
1806         dbus_message_unref(signal);
1807 }
1808
1809 static bool check_host(char **hosts, char *host)
1810 {
1811         int i;
1812
1813         if (!hosts)
1814                 return false;
1815
1816         for (i = 0; hosts[i]; i++) {
1817                 if (g_strcmp0(hosts[i], host) == 0)
1818                         return true;
1819         }
1820
1821         return false;
1822 }
1823
1824 static void provider_append_routes(gpointer key, gpointer value,
1825                                         gpointer user_data)
1826 {
1827         struct vpn_route *route = value;
1828         struct vpn_provider *provider = user_data;
1829         int index = provider->index;
1830
1831         if (!handle_routes)
1832                 return;
1833
1834         /*
1835          * If the VPN administrator/user has given a route to
1836          * VPN server, then we must discard that because the
1837          * server cannot be contacted via VPN tunnel.
1838          */
1839         if (check_host(provider->host_ip, route->network)) {
1840                 DBG("Discarding VPN route to %s via %s at index %d",
1841                         route->network, route->gateway, index);
1842                 return;
1843         }
1844
1845         if (route->family == AF_INET6) {
1846                 unsigned char prefix_len = atoi(route->netmask);
1847
1848                 connman_inet_add_ipv6_network_route(index, route->network,
1849                                                         route->gateway,
1850                                                         prefix_len);
1851         } else {
1852                 connman_inet_add_network_route(index, route->network,
1853                                                 route->gateway,
1854                                                 route->netmask);
1855         }
1856 }
1857
1858 static int set_connected(struct vpn_provider *provider,
1859                                         bool connected)
1860 {
1861         struct vpn_ipconfig *ipconfig;
1862
1863         DBG("provider %p id %s connected %d", provider,
1864                                         provider->identifier, connected);
1865
1866         if (connected) {
1867                 if (provider->family == AF_INET6)
1868                         ipconfig = provider->ipconfig_ipv6;
1869                 else
1870                         ipconfig = provider->ipconfig_ipv4;
1871
1872                 __vpn_ipconfig_address_add(ipconfig, provider->family);
1873
1874                 if (handle_routes)
1875                         __vpn_ipconfig_gateway_add(ipconfig, provider->family);
1876
1877                 provider_indicate_state(provider,
1878                                         VPN_PROVIDER_STATE_READY);
1879
1880                 g_hash_table_foreach(provider->routes, provider_append_routes,
1881                                         provider);
1882
1883                 g_hash_table_foreach(provider->user_routes,
1884                                         provider_append_routes, provider);
1885
1886         } else {
1887                 provider_indicate_state(provider,
1888                                         VPN_PROVIDER_STATE_DISCONNECT);
1889
1890                 provider_indicate_state(provider,
1891                                         VPN_PROVIDER_STATE_IDLE);
1892         }
1893
1894         return 0;
1895 }
1896
1897 int vpn_provider_set_state(struct vpn_provider *provider,
1898                                         enum vpn_provider_state state)
1899 {
1900         if (!provider)
1901                 return -EINVAL;
1902
1903         switch (state) {
1904         case VPN_PROVIDER_STATE_UNKNOWN:
1905                 return -EINVAL;
1906         case VPN_PROVIDER_STATE_IDLE:
1907                 return set_connected(provider, false);
1908         case VPN_PROVIDER_STATE_CONNECT:
1909                 return provider_indicate_state(provider, state);
1910         case VPN_PROVIDER_STATE_READY:
1911                 return set_connected(provider, true);
1912         case VPN_PROVIDER_STATE_DISCONNECT:
1913                 return provider_indicate_state(provider, state);
1914         case VPN_PROVIDER_STATE_FAILURE:
1915                 return provider_indicate_state(provider, state);
1916         }
1917         return -EINVAL;
1918 }
1919
1920 void vpn_provider_add_error(struct vpn_provider *provider,
1921                         enum vpn_provider_error error)
1922 {
1923         switch (error) {
1924         case VPN_PROVIDER_ERROR_UNKNOWN:
1925                 break;
1926         case VPN_PROVIDER_ERROR_CONNECT_FAILED:
1927                 ++provider->conn_error_counter;
1928                 break;
1929         case VPN_PROVIDER_ERROR_LOGIN_FAILED:
1930         case VPN_PROVIDER_ERROR_AUTH_FAILED:
1931                 ++provider->auth_error_counter;
1932                 break;
1933         }
1934 }
1935
1936 int vpn_provider_indicate_error(struct vpn_provider *provider,
1937                                         enum vpn_provider_error error)
1938 {
1939         DBG("provider %p id %s error %d", provider, provider->identifier,
1940                                                                         error);
1941
1942         vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
1943
1944         vpn_provider_add_error(provider, error);
1945
1946         if (provider->driver && provider->driver->set_state)
1947                 provider->driver->set_state(provider, provider->state);
1948
1949         return 0;
1950 }
1951
1952 static int connection_unregister(struct vpn_provider *provider)
1953 {
1954         DBG("provider %p path %s", provider, provider->path);
1955
1956         if (!provider->path)
1957                 return -EALREADY;
1958
1959         g_dbus_unregister_interface(connection, provider->path,
1960                                 VPN_CONNECTION_INTERFACE);
1961
1962         g_free(provider->path);
1963         provider->path = NULL;
1964
1965         return 0;
1966 }
1967
1968 static int connection_register(struct vpn_provider *provider)
1969 {
1970         DBG("provider %p path %s", provider, provider->path);
1971
1972         if (provider->path)
1973                 return -EALREADY;
1974
1975         provider->path = g_strdup_printf("%s/connection/%s", VPN_PATH,
1976                                                 provider->identifier);
1977
1978         g_dbus_register_interface(connection, provider->path,
1979                                 VPN_CONNECTION_INTERFACE,
1980                                 connection_methods, connection_signals,
1981                                 NULL, provider, NULL);
1982
1983         return 0;
1984 }
1985
1986 static void unregister_provider(gpointer data)
1987 {
1988         struct vpn_provider *provider = data;
1989
1990         configuration_count_del();
1991
1992         connection_unregister(provider);
1993
1994         /* If the provider has any DNS resolver queries pending,
1995          * they need to be cleared here because the unref will not
1996          * be able to do that (because the provider_resolv_host_addr()
1997          * has increased the ref count by 1). This is quite rare as
1998          * normally the resolving either returns a value or has a
1999          * timeout which clears the memory. Typically resolv_result() will
2000          * unref the provider but in this case that call has not yet
2001          * happened.
2002          */
2003         if (provider->resolv)
2004                 vpn_provider_unref(provider);
2005
2006         vpn_provider_unref(provider);
2007 }
2008
2009 static void provider_initialize(struct vpn_provider *provider)
2010 {
2011         DBG("provider %p", provider);
2012
2013         provider->index = 0;
2014         provider->fd = -1;
2015         provider->name = NULL;
2016         provider->type = NULL;
2017         provider->domain = NULL;
2018         provider->identifier = NULL;
2019         provider->immutable = false;
2020         provider->user_networks = NULL;
2021         provider->routes = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2022                                         NULL, free_route);
2023         provider->user_routes = g_hash_table_new_full(g_str_hash, g_str_equal,
2024                                         g_free, free_route);
2025         provider->setting_strings = g_hash_table_new_full(g_str_hash,
2026                                         g_str_equal, g_free, free_setting);
2027 }
2028
2029 static struct vpn_provider *vpn_provider_new(void)
2030 {
2031         struct vpn_provider *provider;
2032
2033         provider = g_try_new0(struct vpn_provider, 1);
2034         if (!provider)
2035                 return NULL;
2036
2037         provider->refcount = 1;
2038
2039         DBG("provider %p", provider);
2040         provider_initialize(provider);
2041
2042         return provider;
2043 }
2044
2045 static struct vpn_provider *vpn_provider_get(const char *identifier)
2046 {
2047         struct vpn_provider *provider;
2048
2049         provider = g_hash_table_lookup(provider_hash, identifier);
2050         if (provider)
2051                 return provider;
2052
2053         provider = vpn_provider_new();
2054         if (!provider)
2055                 return NULL;
2056
2057         DBG("provider %p", provider);
2058
2059         provider->identifier = g_strdup(identifier);
2060
2061         g_hash_table_insert(provider_hash, provider->identifier, provider);
2062
2063         configuration_count_add();
2064
2065         return provider;
2066 }
2067
2068 static void vpn_provider_put(const char *identifier)
2069 {
2070         configuration_count_del();
2071
2072         g_hash_table_remove(provider_hash, identifier);
2073 }
2074
2075 static void provider_dbus_ident(char *ident)
2076 {
2077         int i, len = strlen(ident);
2078
2079         for (i = 0; i < len; i++) {
2080                 if (ident[i] >= '0' && ident[i] <= '9')
2081                         continue;
2082                 if (ident[i] >= 'a' && ident[i] <= 'z')
2083                         continue;
2084                 if (ident[i] >= 'A' && ident[i] <= 'Z')
2085                         continue;
2086                 ident[i] = '_';
2087         }
2088 }
2089
2090 static struct vpn_provider *provider_create_from_keyfile(GKeyFile *keyfile,
2091                 const char *ident)
2092 {
2093         struct vpn_provider *provider;
2094
2095         if (!keyfile || !ident)
2096                 return NULL;
2097
2098         provider = __vpn_provider_lookup(ident);
2099         if (!provider) {
2100                 provider = vpn_provider_get(ident);
2101                 if (!provider) {
2102                         DBG("can not create provider");
2103                         return NULL;
2104                 }
2105
2106                 provider_load_from_keyfile(provider, keyfile);
2107
2108                 if (!provider->name || !provider->host ||
2109                                 !provider->domain) {
2110                         DBG("cannot get name, host or domain");
2111                         vpn_provider_unref(provider);
2112                         return NULL;
2113                 }
2114
2115                 if (provider_register(provider) == 0)
2116                         connection_register(provider);
2117         }
2118         return provider;
2119 }
2120
2121 static void provider_create_all_from_type(const char *provider_type)
2122 {
2123         unsigned int i;
2124         char **providers;
2125         char *id, *type;
2126         GKeyFile *keyfile;
2127
2128         DBG("provider type %s", provider_type);
2129
2130         providers = __connman_storage_get_providers();
2131
2132         if (!providers)
2133                 return;
2134
2135         for (i = 0; providers[i]; i += 1) {
2136
2137                 if (strncmp(providers[i], "provider_", 9) != 0)
2138                         continue;
2139
2140                 id = providers[i] + 9;
2141                 keyfile = __connman_storage_load_provider(id);
2142
2143                 if (!keyfile)
2144                         continue;
2145
2146                 type = __vpn_config_get_string(keyfile, id, "Type", NULL);
2147
2148                 DBG("keyfile %p id %s type %s", keyfile, id, type);
2149
2150                 if (strcmp(provider_type, type) != 0) {
2151                         g_free(type);
2152                         g_key_file_free(keyfile);
2153                         continue;
2154                 }
2155
2156                 if (!provider_create_from_keyfile(keyfile, id))
2157                         DBG("could not create provider");
2158
2159                 g_free(type);
2160                 g_key_file_free(keyfile);
2161         }
2162         g_strfreev(providers);
2163 }
2164
2165 #if !defined TIZEN_EXT
2166 char *__vpn_provider_create_identifier(const char *host, const char *domain)
2167 {
2168         char *ident;
2169
2170         if (domain)
2171                 ident = g_strdup_printf("%s_%s", host, domain);
2172         else
2173                 ident = g_strdup_printf("%s", host);
2174
2175         provider_dbus_ident(ident);
2176
2177         return ident;
2178 }
2179 #else
2180 char *__vpn_provider_create_identifier(const char *host, const char *domain, const char *name)
2181 {
2182         char *ident;
2183
2184         if (domain)
2185                 ident = g_strdup_printf("%s_%s_%s", host, domain, name);
2186         else
2187                 ident = g_strdup_printf("%s_%s", host, name);
2188         if (!ident)
2189                 return NULL;
2190
2191         provider_dbus_ident(ident);
2192
2193         return ident;
2194 }
2195 #endif
2196
2197 int __vpn_provider_create(DBusMessage *msg)
2198 {
2199         struct vpn_provider *provider;
2200         DBusMessageIter iter, array;
2201         const char *type = NULL, *name = NULL;
2202         const char *host = NULL, *domain = NULL;
2203         GSList *networks = NULL;
2204         char *ident;
2205         int err;
2206
2207         dbus_message_iter_init(msg, &iter);
2208         dbus_message_iter_recurse(&iter, &array);
2209
2210         while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
2211                 DBusMessageIter entry, value;
2212                 const char *key;
2213
2214                 dbus_message_iter_recurse(&array, &entry);
2215                 dbus_message_iter_get_basic(&entry, &key);
2216
2217                 dbus_message_iter_next(&entry);
2218                 dbus_message_iter_recurse(&entry, &value);
2219
2220                 switch (dbus_message_iter_get_arg_type(&value)) {
2221                 case DBUS_TYPE_STRING:
2222                         if (g_str_equal(key, "Type"))
2223                                 dbus_message_iter_get_basic(&value, &type);
2224                         else if (g_str_equal(key, "Name"))
2225                                 dbus_message_iter_get_basic(&value, &name);
2226                         else if (g_str_equal(key, "Host"))
2227                                 dbus_message_iter_get_basic(&value, &host);
2228                         else if (g_str_equal(key, "VPN.Domain") ||
2229                                         g_str_equal(key, "Domain"))
2230                                 dbus_message_iter_get_basic(&value, &domain);
2231                         break;
2232                 case DBUS_TYPE_ARRAY:
2233                         if (g_str_equal(key, "UserRoutes"))
2234                                 networks = get_user_networks(&value);
2235                         break;
2236                 }
2237
2238                 dbus_message_iter_next(&array);
2239         }
2240
2241         if (!host)
2242                 return -EINVAL;
2243
2244         DBG("Type %s name %s networks %p", type, name, networks);
2245
2246         if (!type || !name)
2247                 return -EOPNOTSUPP;
2248
2249 #if !defined TIZEN_EXT
2250         ident = __vpn_provider_create_identifier(host, domain);
2251 #else
2252         ident = __vpn_provider_create_identifier(host, domain, name);
2253 #endif
2254         DBG("ident %s", ident);
2255
2256         provider = __vpn_provider_lookup(ident);
2257         if (!provider) {
2258                 provider = vpn_provider_get(ident);
2259                 if (!provider) {
2260                         DBG("can not create provider");
2261                         g_free(ident);
2262                         return -EOPNOTSUPP;
2263                 }
2264
2265                 provider->host = g_strdup(host);
2266                 provider->domain = g_strdup(domain);
2267                 provider->name = g_strdup(name);
2268                 provider->type = g_strdup(type);
2269
2270                 if (provider_register(provider) == 0)
2271                         vpn_provider_load(provider);
2272
2273                 provider_resolv_host_addr(provider);
2274         }
2275
2276         if (networks) {
2277                 g_slist_free_full(provider->user_networks, free_route);
2278                 provider->user_networks = networks;
2279                 set_user_networks(provider, provider->user_networks);
2280         }
2281
2282         dbus_message_iter_init(msg, &iter);
2283         dbus_message_iter_recurse(&iter, &array);
2284
2285         while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
2286                 DBusMessageIter entry, value;
2287                 const char *key, *str;
2288
2289                 dbus_message_iter_recurse(&array, &entry);
2290                 dbus_message_iter_get_basic(&entry, &key);
2291
2292                 dbus_message_iter_next(&entry);
2293                 dbus_message_iter_recurse(&entry, &value);
2294
2295                 switch (dbus_message_iter_get_arg_type(&value)) {
2296                 case DBUS_TYPE_STRING:
2297                         dbus_message_iter_get_basic(&value, &str);
2298                         vpn_provider_set_string(provider, key, str);
2299                         break;
2300                 }
2301
2302                 dbus_message_iter_next(&array);
2303         }
2304
2305         g_free(ident);
2306
2307         vpn_provider_save(provider);
2308
2309         err = provider_register(provider);
2310         if (err != 0 && err != -EALREADY)
2311                 return err;
2312
2313         connection_register(provider);
2314
2315         DBG("provider %p index %d path %s", provider, provider->index,
2316                                                         provider->path);
2317
2318         g_dbus_send_reply(connection, msg,
2319                                 DBUS_TYPE_OBJECT_PATH, &provider->path,
2320                                 DBUS_TYPE_INVALID);
2321
2322         connection_added_signal(provider);
2323
2324         return 0;
2325 }
2326
2327 static const char *get_string(GHashTable *settings, const char *key)
2328 {
2329         DBG("settings %p key %s", settings, key);
2330
2331         return g_hash_table_lookup(settings, key);
2332 }
2333
2334 static GSList *parse_user_networks(const char *network_str)
2335 {
2336         GSList *networks = NULL;
2337         char **elems;
2338         int i = 0;
2339
2340         if (!network_str)
2341                 return NULL;
2342
2343         elems = g_strsplit(network_str, ",", 0);
2344         if (!elems)
2345                 return NULL;
2346
2347         while (elems[i]) {
2348                 struct vpn_route *vpn_route;
2349                 char *network, *netmask, *gateway;
2350                 int family;
2351                 char **route;
2352
2353                 route = g_strsplit(elems[i], "/", 0);
2354                 if (!route)
2355                         goto next;
2356
2357                 network = route[0];
2358                 if (!network || network[0] == '\0')
2359                         goto next;
2360
2361                 family = connman_inet_check_ipaddress(network);
2362                 if (family < 0) {
2363                         DBG("Cannot get address family of %s (%d/%s)", network,
2364                                 family, gai_strerror(family));
2365
2366                         goto next;
2367                 }
2368
2369                 switch (family) {
2370                 case AF_INET:
2371                         break;
2372                 case AF_INET6:
2373                         break;
2374                 default:
2375                         DBG("Unsupported address family %d", family);
2376                         goto next;
2377                 }
2378
2379                 netmask = route[1];
2380                 if (!netmask || netmask[0] == '\0')
2381                         goto next;
2382
2383                 gateway = route[2];
2384
2385                 vpn_route = g_try_new0(struct vpn_route, 1);
2386                 if (!vpn_route) {
2387                         g_strfreev(route);
2388                         break;
2389                 }
2390
2391                 vpn_route->family = family;
2392                 vpn_route->network = g_strdup(network);
2393                 vpn_route->netmask = g_strdup(netmask);
2394                 vpn_route->gateway = g_strdup(gateway);
2395
2396                 DBG("route %s/%s%s%s", network, netmask,
2397                         gateway ? " via " : "", gateway ? gateway : "");
2398
2399                 networks = g_slist_prepend(networks, vpn_route);
2400
2401         next:
2402                 g_strfreev(route);
2403                 i++;
2404         }
2405
2406         g_strfreev(elems);
2407
2408         return g_slist_reverse(networks);
2409 }
2410
2411 int __vpn_provider_create_from_config(GHashTable *settings,
2412                                 const char *config_ident,
2413                                 const char *config_entry)
2414 {
2415         struct vpn_provider *provider;
2416         const char *type, *name, *host, *domain, *networks_str;
2417         GSList *networks;
2418         char *ident = NULL;
2419         GHashTableIter hash;
2420         gpointer value, key;
2421         int err;
2422
2423         type = get_string(settings, "Type");
2424         name = get_string(settings, "Name");
2425         host = get_string(settings, "Host");
2426         domain = get_string(settings, "Domain");
2427         networks_str = get_string(settings, "Networks");
2428         networks = parse_user_networks(networks_str);
2429
2430         if (!host) {
2431                 err = -EINVAL;
2432                 goto fail;
2433         }
2434
2435         DBG("type %s name %s networks %s", type, name, networks_str);
2436
2437         if (!type || !name) {
2438                 err = -EOPNOTSUPP;
2439                 goto fail;
2440         }
2441
2442 #if !defined TIZEN_EXT
2443         ident = __vpn_provider_create_identifier(host, domain);
2444 #else
2445         ident = __vpn_provider_create_identifier(host, domain, name);
2446 #endif
2447         DBG("ident %s", ident);
2448
2449         provider = __vpn_provider_lookup(ident);
2450         if (!provider) {
2451                 provider = vpn_provider_get(ident);
2452                 if (!provider) {
2453                         DBG("can not create provider");
2454                         err = -EOPNOTSUPP;
2455                         goto fail;
2456                 }
2457
2458                 provider->host = g_strdup(host);
2459                 provider->domain = g_strdup(domain);
2460                 provider->name = g_strdup(name);
2461                 provider->type = g_ascii_strdown(type, -1);
2462
2463                 provider->config_file = g_strdup(config_ident);
2464                 provider->config_entry = g_strdup(config_entry);
2465
2466                 provider_resolv_host_addr(provider);
2467         }
2468
2469         if (networks) {
2470                 g_slist_free_full(provider->user_networks, free_route);
2471                 provider->user_networks = networks;
2472                 set_user_networks(provider, provider->user_networks);
2473         }
2474
2475         g_hash_table_iter_init(&hash, settings);
2476
2477         while (g_hash_table_iter_next(&hash, &key, &value))
2478                 __vpn_provider_set_string_immutable(provider, key, value);
2479
2480         provider->immutable = true;
2481
2482         vpn_provider_save(provider);
2483
2484         err = provider_register(provider);
2485         if (err != 0 && err != -EALREADY)
2486                 goto fail;
2487
2488         connection_register(provider);
2489
2490         DBG("provider %p index %d path %s", provider, provider->index,
2491                                                         provider->path);
2492
2493         connection_added_signal(provider);
2494
2495         g_free(ident);
2496
2497         return 0;
2498
2499 fail:
2500         vpn_provider_put(ident);
2501         g_free(ident);
2502         g_slist_free_full(networks, free_route);
2503
2504         return err;
2505 }
2506
2507 static void append_connection_structs(DBusMessageIter *iter, void *user_data)
2508 {
2509         DBusMessageIter entry;
2510         GHashTableIter hash;
2511         gpointer value, key;
2512
2513         g_hash_table_iter_init(&hash, provider_hash);
2514
2515         while (g_hash_table_iter_next(&hash, &key, &value)) {
2516                 struct vpn_provider *provider = value;
2517
2518 #if defined TIZEN_EXT
2519                 DBG("provider %p", provider);
2520 #else
2521                 DBG("path %s", provider->path);
2522 #endif
2523
2524                 if (!provider->identifier)
2525                         continue;
2526
2527                 dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT,
2528                                 NULL, &entry);
2529                 dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
2530                                 &provider->path);
2531                 append_properties(&entry, provider);
2532                 dbus_message_iter_close_container(iter, &entry);
2533         }
2534 }
2535
2536 DBusMessage *__vpn_provider_get_connections(DBusMessage *msg)
2537 {
2538         DBusMessage *reply;
2539
2540         DBG("");
2541
2542         reply = dbus_message_new_method_return(msg);
2543         if (!reply)
2544                 return NULL;
2545
2546         __connman_dbus_append_objpath_dict_array(reply,
2547                         append_connection_structs, NULL);
2548
2549         return reply;
2550 }
2551
2552 const char *vpn_provider_get_ident(struct vpn_provider *provider)
2553 {
2554         if (!provider)
2555                 return NULL;
2556
2557         return provider->identifier;
2558 }
2559
2560 static int set_string(struct vpn_provider *provider,
2561                         const char *key, const char *value,
2562                         bool hide_value, bool immutable)
2563 {
2564         DBG("provider %p key %s immutable %s value %s", provider, key,
2565                 immutable ? "yes" : "no",
2566                 hide_value ? "<not printed>" : value);
2567
2568         if (g_str_equal(key, "Type")) {
2569                 if (!g_strcmp0(provider->type, value))
2570                         return -EALREADY;
2571
2572                 g_free(provider->type);
2573                 provider->type = g_ascii_strdown(value, -1);
2574                 send_value(provider->path, "Type", provider->type);
2575         } else if (g_str_equal(key, "Name")) {
2576                 if (!g_strcmp0(provider->name, value))
2577                         return -EALREADY;
2578
2579                 g_free(provider->name);
2580                 provider->name = g_strdup(value);
2581                 send_value(provider->path, "Name", provider->name);
2582         } else if (g_str_equal(key, "Host")) {
2583                 if (!g_strcmp0(provider->host, value))
2584                         return -EALREADY;
2585
2586                 g_free(provider->host);
2587                 provider->host = g_strdup(value);
2588                 send_value(provider->path, "Host", provider->host);
2589         } else if (g_str_equal(key, "VPN.Domain") ||
2590                         g_str_equal(key, "Domain")) {
2591                 if (!g_strcmp0(provider->domain, value))
2592                         return -EALREADY;
2593
2594                 g_free(provider->domain);
2595                 provider->domain = g_strdup(value);
2596                 send_value(provider->path, "Domain", provider->domain);
2597         } else {
2598                 struct vpn_setting *setting;
2599                 bool replace = true;
2600
2601                 setting = g_hash_table_lookup(provider->setting_strings, key);
2602                 if (setting) {
2603                         if (!immutable && setting->immutable) {
2604                                 DBG("Trying to set immutable variable %s", key);
2605                                 return -EPERM;
2606                         } else if (!g_strcmp0(setting->value, value)) {
2607                                 return -EALREADY;
2608                         }
2609
2610                         g_free(setting->value);
2611                         replace = false;
2612                 } else {
2613                         setting = g_try_new0(struct vpn_setting, 1);
2614                         if (!setting)
2615                                 return -ENOMEM;
2616                 }
2617
2618                 setting->value = g_strdup(value);
2619                 setting->hide_value = hide_value;
2620
2621                 if (immutable)
2622                         setting->immutable = true;
2623
2624                 if (!hide_value)
2625                         send_value(provider->path, key, setting->value);
2626
2627                 if (replace)
2628                         g_hash_table_replace(provider->setting_strings,
2629                                                 g_strdup(key), setting);
2630         }
2631
2632         return 0;
2633 }
2634
2635 int vpn_provider_set_string(struct vpn_provider *provider,
2636                                         const char *key, const char *value)
2637 {
2638         return set_string(provider, key, value, false, false);
2639 }
2640
2641 int vpn_provider_set_string_hide_value(struct vpn_provider *provider,
2642                                         const char *key, const char *value)
2643 {
2644         return set_string(provider, key, value, true, false);
2645 }
2646
2647 int __vpn_provider_set_string_immutable(struct vpn_provider *provider,
2648                                         const char *key, const char *value)
2649 {
2650         return set_string(provider, key, value, false, true);
2651 }
2652
2653 const char *vpn_provider_get_string(struct vpn_provider *provider,
2654                                                         const char *key)
2655 {
2656         struct vpn_setting *setting;
2657
2658         DBG("provider %p key %s", provider, key);
2659
2660         if (g_str_equal(key, "Type"))
2661                 return provider->type;
2662         else if (g_str_equal(key, "Name"))
2663                 return provider->name;
2664         else if (g_str_equal(key, "Host"))
2665                 return provider->host;
2666         else if (g_str_equal(key, "HostIP")) {
2667                 if (!provider->host_ip ||
2668                                 !provider->host_ip[0])
2669                         return provider->host;
2670                 else
2671                         return provider->host_ip[0];
2672         } else if (g_str_equal(key, "VPN.Domain") ||
2673                         g_str_equal(key, "Domain"))
2674                 return provider->domain;
2675
2676         setting = g_hash_table_lookup(provider->setting_strings, key);
2677         if (!setting)
2678                 return NULL;
2679
2680         return setting->value;
2681 }
2682
2683 bool vpn_provider_get_boolean(struct vpn_provider *provider, const char *key,
2684                                                         bool default_value)
2685 {
2686         struct vpn_setting *setting;
2687
2688         connman_info("provider %p key %s", provider, key);
2689
2690         setting = g_hash_table_lookup(provider->setting_strings, key);
2691         if (!setting || !setting->value)
2692                 return default_value;
2693
2694         if (!g_strcmp0(setting->value, "true"))
2695                 return true;
2696
2697         if (!g_strcmp0(setting->value, "false"))
2698                 return false;
2699
2700         return default_value;
2701 }
2702
2703 bool vpn_provider_get_string_immutable(struct vpn_provider *provider,
2704                                                         const char *key)
2705 {
2706         struct vpn_setting *setting;
2707
2708         /* These values can be changed if the provider is not immutable */
2709         if (g_str_equal(key, "Type")) {
2710                 return provider->immutable;
2711         } else if (g_str_equal(key, "Name")) {
2712                 return provider->immutable;
2713         } else if (g_str_equal(key, "Host")) {
2714                 return provider->immutable;
2715         } else if (g_str_equal(key, "HostIP")) {
2716                 return provider->immutable;
2717         } else if (g_str_equal(key, "VPN.Domain") ||
2718                         g_str_equal(key, "Domain")) {
2719                 return provider->immutable;
2720         }
2721
2722         setting = g_hash_table_lookup(provider->setting_strings, key);
2723         if (!setting)
2724                 return true; /* Not found, regard as immutable - no changes */
2725
2726         return setting->immutable;
2727 }
2728
2729 bool __vpn_provider_check_routes(struct vpn_provider *provider)
2730 {
2731         if (!provider)
2732                 return false;
2733
2734         if (provider->user_routes &&
2735                         g_hash_table_size(provider->user_routes) > 0)
2736                 return true;
2737
2738         if (provider->routes &&
2739                         g_hash_table_size(provider->routes) > 0)
2740                 return true;
2741
2742         return false;
2743 }
2744
2745 void *vpn_provider_get_data(struct vpn_provider *provider)
2746 {
2747         return provider->driver_data;
2748 }
2749
2750 void vpn_provider_set_data(struct vpn_provider *provider, void *data)
2751 {
2752         provider->driver_data = data;
2753 }
2754
2755 void *vpn_provider_get_plugin_data(struct vpn_provider *provider)
2756 {
2757 #if defined TIZEN_EXT
2758         if (!provider)
2759                 return NULL;
2760 #endif
2761         return provider->plugin_data;
2762 }
2763
2764 void vpn_provider_set_plugin_data(struct vpn_provider *provider, void *data)
2765 {
2766         provider->plugin_data = data;
2767 }
2768
2769 void vpn_provider_set_index(struct vpn_provider *provider, int index)
2770 {
2771         DBG("index %d provider %p", index, provider);
2772
2773         if (!provider->ipconfig_ipv4) {
2774                 provider->ipconfig_ipv4 = __vpn_ipconfig_create(index,
2775                                                                 AF_INET);
2776                 if (!provider->ipconfig_ipv4) {
2777                         DBG("Couldn't create ipconfig for IPv4");
2778                         goto done;
2779                 }
2780         }
2781
2782         __vpn_ipconfig_set_index(provider->ipconfig_ipv4, index);
2783
2784         if (!provider->ipconfig_ipv6) {
2785                 provider->ipconfig_ipv6 = __vpn_ipconfig_create(index,
2786                                                                 AF_INET6);
2787                 if (!provider->ipconfig_ipv6) {
2788                         DBG("Couldn't create ipconfig for IPv6");
2789                         goto done;
2790                 }
2791         }
2792
2793         __vpn_ipconfig_set_index(provider->ipconfig_ipv6, index);
2794
2795 done:
2796         provider->index = index;
2797 }
2798
2799 int vpn_provider_get_index(struct vpn_provider *provider)
2800 {
2801         return provider->index;
2802 }
2803
2804 int vpn_provider_set_ipaddress(struct vpn_provider *provider,
2805                                         struct connman_ipaddress *ipaddress)
2806 {
2807         struct vpn_ipconfig *ipconfig = NULL;
2808
2809         switch (ipaddress->family) {
2810         case AF_INET:
2811                 ipconfig = provider->ipconfig_ipv4;
2812                 break;
2813         case AF_INET6:
2814                 ipconfig = provider->ipconfig_ipv6;
2815                 break;
2816         default:
2817                 break;
2818         }
2819
2820         DBG("provider %p state %d ipconfig %p family %d", provider,
2821                 provider->state, ipconfig, ipaddress->family);
2822
2823         if (!ipconfig)
2824                 return -EINVAL;
2825
2826         provider->family = ipaddress->family;
2827
2828         if (provider->state == VPN_PROVIDER_STATE_CONNECT ||
2829                         provider->state == VPN_PROVIDER_STATE_READY) {
2830                 struct connman_ipaddress *addr =
2831                                         __vpn_ipconfig_get_address(ipconfig);
2832
2833                 /*
2834                  * Remember the old address so that we can remove it in notify
2835                  * function in plugins/vpn.c if we ever restart
2836                  */
2837                 if (ipaddress->family == AF_INET6) {
2838                         connman_ipaddress_free(provider->prev_ipv6_addr);
2839                         provider->prev_ipv6_addr =
2840                                                 connman_ipaddress_copy(addr);
2841                 } else {
2842                         connman_ipaddress_free(provider->prev_ipv4_addr);
2843                         provider->prev_ipv4_addr =
2844                                                 connman_ipaddress_copy(addr);
2845                 }
2846         }
2847
2848         if (ipaddress->local) {
2849                 __vpn_ipconfig_set_local(ipconfig, ipaddress->local);
2850                 __vpn_ipconfig_set_peer(ipconfig, ipaddress->peer);
2851                 __vpn_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast);
2852                 __vpn_ipconfig_set_gateway(ipconfig, ipaddress->gateway);
2853                 __vpn_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen);
2854         }
2855
2856         return 0;
2857 }
2858
2859 int vpn_provider_set_pac(struct vpn_provider *provider,
2860                                 const char *pac)
2861 {
2862         DBG("provider %p pac %s", provider, pac);
2863
2864         return 0;
2865 }
2866
2867
2868 int vpn_provider_set_domain(struct vpn_provider *provider,
2869                                         const char *domain)
2870 {
2871         DBG("provider %p domain %s", provider, domain);
2872
2873         g_free(provider->domain);
2874         provider->domain = g_strdup(domain);
2875
2876         return 0;
2877 }
2878
2879 int vpn_provider_set_nameservers(struct vpn_provider *provider,
2880                                         const char *nameservers)
2881 {
2882         DBG("provider %p nameservers %s", provider, nameservers);
2883
2884         g_strfreev(provider->nameservers);
2885         provider->nameservers = NULL;
2886
2887         if (!nameservers)
2888                 return 0;
2889
2890         provider->nameservers = g_strsplit_set(nameservers, ", ", 0);
2891
2892         return 0;
2893 }
2894
2895 static int route_env_parse(struct vpn_provider *provider, const char *key,
2896                                 int *family, unsigned long *idx,
2897                                 enum vpn_provider_route_type *type)
2898 {
2899         if (!provider)
2900                 return -EINVAL;
2901
2902         DBG("name %s", provider->name);
2903
2904         if (provider->driver && provider->driver->route_env_parse)
2905                 return provider->driver->route_env_parse(provider, key, family, idx,
2906                                 type);
2907
2908         return 0;
2909 }
2910
2911 int vpn_provider_append_route(struct vpn_provider *provider,
2912                                         const char *key, const char *value)
2913 {
2914         struct vpn_route *route;
2915         int ret, family = 0;
2916         unsigned long idx = 0;
2917         enum vpn_provider_route_type type = VPN_PROVIDER_ROUTE_TYPE_NONE;
2918
2919         DBG("key %s value %s", key, value);
2920
2921         ret = route_env_parse(provider, key, &family, &idx, &type);
2922         if (ret < 0)
2923                 return ret;
2924
2925         DBG("idx %lu family %d type %d", idx, family, type);
2926
2927         route = g_hash_table_lookup(provider->routes, GINT_TO_POINTER(idx));
2928         if (!route) {
2929                 route = g_try_new0(struct vpn_route, 1);
2930                 if (!route) {
2931                         connman_error("out of memory");
2932                         return -ENOMEM;
2933                 }
2934
2935                 route->family = family;
2936
2937                 g_hash_table_replace(provider->routes, GINT_TO_POINTER(idx),
2938                                                 route);
2939         }
2940
2941         switch (type) {
2942         case VPN_PROVIDER_ROUTE_TYPE_NONE:
2943                 break;
2944         case VPN_PROVIDER_ROUTE_TYPE_MASK:
2945                 route->netmask = g_strdup(value);
2946                 break;
2947         case VPN_PROVIDER_ROUTE_TYPE_ADDR:
2948                 route->network = g_strdup(value);
2949                 break;
2950         case VPN_PROVIDER_ROUTE_TYPE_GW:
2951                 route->gateway = g_strdup(value);
2952                 break;
2953         }
2954
2955         if (!handle_routes) {
2956                 if (route->netmask && route->gateway &&
2957                                                         route->network)
2958                         provider_schedule_changed(provider);
2959         }
2960
2961         return 0;
2962 }
2963
2964 const char *vpn_provider_get_driver_name(struct vpn_provider *provider)
2965 {
2966         if (!provider->driver)
2967                 return NULL;
2968
2969         return provider->driver->name;
2970 }
2971
2972 const char *vpn_provider_get_save_group(struct vpn_provider *provider)
2973 {
2974         return provider->identifier;
2975 }
2976
2977 static gint compare_priority(gconstpointer a, gconstpointer b)
2978 {
2979         return 0;
2980 }
2981
2982 static void clean_provider(gpointer key, gpointer value, gpointer user_data)
2983 {
2984         struct vpn_provider *provider = value;
2985
2986         if (provider->driver && provider->driver->remove)
2987                 provider->driver->remove(provider);
2988
2989         connection_unregister(provider);
2990 }
2991
2992 int vpn_provider_driver_register(struct vpn_provider_driver *driver)
2993 {
2994         DBG("driver %p name %s", driver, driver->name);
2995
2996         driver_list = g_slist_insert_sorted(driver_list, driver,
2997                                                         compare_priority);
2998         provider_create_all_from_type(driver->name);
2999         return 0;
3000 }
3001
3002 void vpn_provider_driver_unregister(struct vpn_provider_driver *driver)
3003 {
3004         GHashTableIter iter;
3005         gpointer value, key;
3006
3007         DBG("driver %p name %s", driver, driver->name);
3008
3009         driver_list = g_slist_remove(driver_list, driver);
3010
3011         g_hash_table_iter_init(&iter, provider_hash);
3012         while (g_hash_table_iter_next(&iter, &key, &value)) {
3013                 struct vpn_provider *provider = value;
3014
3015                 if (provider && provider->driver &&
3016                                 g_strcmp0(provider->driver->name,
3017                                                         driver->name) == 0) {
3018                         provider->driver = NULL;
3019                 }
3020         }
3021 }
3022
3023 const char *vpn_provider_get_name(struct vpn_provider *provider)
3024 {
3025         return provider->name;
3026 }
3027
3028 const char *vpn_provider_get_host(struct vpn_provider *provider)
3029 {
3030         return provider->host;
3031 }
3032
3033 const char *vpn_provider_get_path(struct vpn_provider *provider)
3034 {
3035         return provider->path;
3036 }
3037
3038 unsigned int vpn_provider_get_authentication_errors(
3039                                                 struct vpn_provider *provider)
3040 {
3041         return provider->auth_error_counter;
3042 }
3043
3044 unsigned int vpn_provider_get_connection_errors(
3045                                                 struct vpn_provider *provider)
3046 {
3047         return provider->conn_error_counter;
3048 }
3049
3050 void vpn_provider_change_address(struct vpn_provider *provider)
3051 {
3052         switch (provider->family) {
3053         case AF_INET:
3054                 connman_inet_set_address(provider->index,
3055                         __vpn_ipconfig_get_address(provider->ipconfig_ipv4));
3056                 break;
3057         case AF_INET6:
3058                 connman_inet_set_ipv6_address(provider->index,
3059                         __vpn_ipconfig_get_address(provider->ipconfig_ipv6));
3060                 break;
3061         default:
3062                 break;
3063         }
3064 }
3065
3066 void vpn_provider_clear_address(struct vpn_provider *provider, int family)
3067 {
3068         const char *address;
3069         unsigned char len;
3070
3071         DBG("provider %p family %d ipv4 %p ipv6 %p", provider, family,
3072                 provider->prev_ipv4_addr, provider->prev_ipv6_addr);
3073
3074         switch (family) {
3075         case AF_INET:
3076                 if (provider->prev_ipv4_addr) {
3077                         connman_ipaddress_get_ip(provider->prev_ipv4_addr,
3078                                                 &address, &len);
3079
3080                         DBG("ipv4 %s/%d", address, len);
3081
3082                         connman_inet_clear_address(provider->index,
3083                                         provider->prev_ipv4_addr);
3084                         connman_ipaddress_free(provider->prev_ipv4_addr);
3085                         provider->prev_ipv4_addr = NULL;
3086                 }
3087                 break;
3088         case AF_INET6:
3089                 if (provider->prev_ipv6_addr) {
3090                         connman_ipaddress_get_ip(provider->prev_ipv6_addr,
3091                                                 &address, &len);
3092
3093                         DBG("ipv6 %s/%d", address, len);
3094
3095                         connman_inet_clear_ipv6_address(provider->index,
3096                                                         address, len);
3097
3098                         connman_ipaddress_free(provider->prev_ipv6_addr);
3099                         provider->prev_ipv6_addr = NULL;
3100                 }
3101                 break;
3102         default:
3103                 break;
3104         }
3105 }
3106
3107 static int agent_probe(struct connman_agent *agent)
3108 {
3109         DBG("agent %p", agent);
3110         return 0;
3111 }
3112
3113 static void agent_remove(struct connman_agent *agent)
3114 {
3115         DBG("agent %p", agent);
3116 }
3117
3118 static struct connman_agent_driver agent_driver = {
3119         .name           = "vpn",
3120         .interface      = VPN_AGENT_INTERFACE,
3121         .probe          = agent_probe,
3122         .remove         = agent_remove,
3123 };
3124
3125 static void remove_unprovisioned_providers(void)
3126 {
3127         gchar **providers;
3128         GKeyFile *keyfile, *configkeyfile;
3129         char *file, *section;
3130         int i = 0;
3131
3132         providers = __connman_storage_get_providers();
3133         if (!providers)
3134                 return;
3135
3136         for (; providers[i]; i++) {
3137                 char *group = providers[i] + sizeof("provider_") - 1;
3138                 file = section = NULL;
3139                 keyfile = configkeyfile = NULL;
3140
3141                 keyfile = __connman_storage_load_provider(group);
3142                 if (!keyfile)
3143                         continue;
3144
3145                 file = __vpn_config_get_string(keyfile, group,
3146                                         "Config.file", NULL);
3147                 if (!file)
3148                         goto next;
3149
3150                 section = __vpn_config_get_string(keyfile, group,
3151                                         "Config.ident", NULL);
3152                 if (!section)
3153                         goto next;
3154
3155                 configkeyfile = __connman_storage_load_provider_config(file);
3156                 if (!configkeyfile) {
3157                         /*
3158                          * Config file is missing, remove the provisioned
3159                          * service.
3160                          */
3161                         __connman_storage_remove_provider(group);
3162                         goto next;
3163                 }
3164
3165                 if (!g_key_file_has_group(configkeyfile, section))
3166                         /*
3167                          * Config section is missing, remove the provisioned
3168                          * service.
3169                          */
3170                         __connman_storage_remove_provider(group);
3171
3172         next:
3173                 if (keyfile)
3174                         g_key_file_free(keyfile);
3175
3176                 if (configkeyfile)
3177                         g_key_file_free(configkeyfile);
3178
3179                 g_free(section);
3180                 g_free(file);
3181         }
3182
3183         g_strfreev(providers);
3184 }
3185
3186 int __vpn_provider_init(bool do_routes)
3187 {
3188         int err;
3189
3190         DBG("");
3191
3192         handle_routes = do_routes;
3193
3194         err = connman_agent_driver_register(&agent_driver);
3195         if (err < 0) {
3196                 connman_error("Cannot register agent driver for %s",
3197                                                 agent_driver.name);
3198                 return err;
3199         }
3200
3201         connection = connman_dbus_get_connection();
3202
3203         remove_unprovisioned_providers();
3204
3205         provider_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
3206                                                 NULL, unregister_provider);
3207         return 0;
3208 }
3209
3210 void __vpn_provider_cleanup(void)
3211 {
3212         DBG("");
3213
3214         connman_agent_driver_unregister(&agent_driver);
3215
3216         g_hash_table_foreach(provider_hash, clean_provider, NULL);
3217
3218         g_hash_table_destroy(provider_hash);
3219         provider_hash = NULL;
3220
3221         dbus_connection_unref(connection);
3222 }