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