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