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