Merge tag 'upstream/1.40' into tizen.
[platform/upstream/connman.git] / plugins / vpn.c
1 /*
2  *
3  *  Connection Manager
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 <string.h>
27 #include <errno.h>
28 #include <sys/socket.h>
29 #include <stdlib.h>
30 #include <glib.h>
31
32 #include <gdbus.h>
33
34 #define CONNMAN_API_SUBJECT_TO_CHANGE
35 #include <connman/technology.h>
36 #include <connman/plugin.h>
37 #include <connman/log.h>
38 #include <connman/dbus.h>
39 #include <connman/provider.h>
40 #include <connman/ipaddress.h>
41 #include <connman/notifier.h>
42 #include <connman/vpn-dbus.h>
43 #include <connman/inet.h>
44 #include <gweb/gresolv.h>
45
46 #define DBUS_TIMEOUT 10000
47
48 static DBusConnection *connection;
49
50 static GHashTable *vpn_connections = NULL;
51 static guint watch;
52 static guint added_watch;
53 static guint removed_watch;
54 static guint property_watch;
55
56 struct vpn_route {
57         int family;
58         char *network;
59         char *netmask;
60         char *gateway;
61 };
62
63 struct config_create_data {
64         connection_ready_cb callback;
65         DBusMessage *message;
66         char *path;
67 };
68
69 struct connection_data {
70         char *path;
71         char *ident;
72         struct connman_provider *provider;
73         int index;
74         DBusPendingCall *call;
75         DBusPendingCall *disconnect_call;
76         bool connect_pending;
77         struct config_create_data *cb_data;
78         char *service_ident;
79
80         char *state;
81         char *type;
82         char *name;
83         char *host;
84         char **host_ip;
85         char *domain;
86         char **nameservers;
87         bool immutable;
88         bool default_route_set;
89
90         GHashTable *server_routes;
91         GHashTable *user_routes;
92         GHashTable *setting_strings;
93
94         struct connman_ipaddress *ip;
95
96         GResolv *resolv;
97         guint resolv_id;
98         guint remove_resolv_id;
99 };
100
101 static int set_string(struct connman_provider *provider,
102                                         const char *key, const char *value)
103 {
104         struct connection_data *data;
105
106         data = connman_provider_get_data(provider);
107         if (!data)
108                 return -EINVAL;
109
110         DBG("data %p provider %p key %s value %s", data, provider, key, value);
111
112         if (g_str_equal(key, "Type")) {
113                 g_free(data->type);
114                 data->type = g_strdup(value);
115         } else if (g_str_equal(key, "Name")) {
116                 g_free(data->name);
117                 data->name = g_strdup(value);
118         } else if (g_str_equal(key, "Host")) {
119                 g_free(data->host);
120                 data->host = g_strdup(value);
121         } else if (g_str_equal(key, "VPN.Domain") ||
122                                 g_str_equal(key, "Domain")) {
123                 g_free(data->domain);
124                 data->domain = g_strdup(value);
125         } else
126                 g_hash_table_replace(data->setting_strings,
127                                 g_strdup(key), g_strdup(value));
128         return 0;
129 }
130
131 static const char *get_string(struct connman_provider *provider,
132                                                         const char *key)
133 {
134         struct connection_data *data;
135
136         data = connman_provider_get_data(provider);
137         if (!data)
138                 return NULL;
139
140         DBG("data %p provider %p key %s", data, provider, key);
141
142         if (g_str_equal(key, "Type"))
143                 return data->type;
144         else if (g_str_equal(key, "Name"))
145                 return data->name;
146         else if (g_str_equal(key, "Host"))
147                 return data->host;
148         else if (g_str_equal(key, "HostIP")) {
149                 if (!data->host_ip ||
150                                 !data->host_ip[0])
151                         return data->host;
152                 else
153                         return data->host_ip[0];
154         } else if (g_str_equal(key, "VPN.Domain"))
155                 return data->domain;
156         else if (g_str_equal(key, "Transport"))
157                 return data->service_ident;
158
159         return g_hash_table_lookup(data->setting_strings, key);
160 }
161
162 static char *get_ident(const char *path)
163 {
164         char *pos;
165
166         if (*path != '/')
167                 return NULL;
168
169         pos = strrchr(path, '/');
170         if (!pos)
171                 return NULL;
172
173         return pos + 1;
174 }
175
176 static void cancel_host_resolv(struct connection_data *data)
177 {
178
179         if (data->remove_resolv_id)
180                 g_source_remove(data->remove_resolv_id);
181
182         if (data->resolv && data->resolv_id)
183                 g_resolv_cancel_lookup(data->resolv, data->resolv_id);
184
185         data->resolv_id = 0;
186         data->remove_resolv_id = 0;
187
188         g_resolv_unref(data->resolv);
189         data->resolv = NULL;
190 }
191
192 static gboolean remove_resolv(gpointer user_data)
193 {
194         struct connection_data *data = user_data;
195
196         cancel_host_resolv(data);
197
198         return FALSE;
199 }
200
201 static void resolv_result(GResolvResultStatus status,
202                                         char **results, gpointer user_data)
203 {
204         struct connection_data *data = user_data;
205
206         DBG("status %d", status);
207
208         if (status == G_RESOLV_RESULT_STATUS_SUCCESS && results &&
209                                                 g_strv_length(results) > 0) {
210                 g_strfreev(data->host_ip);
211                 data->host_ip = g_strdupv(results);
212         }
213
214         /*
215          * We cannot unref the resolver here as resolv struct is manipulated
216          * by gresolv.c after we return from this callback.
217          */
218         data->remove_resolv_id = g_idle_add(remove_resolv, data);
219
220         data->resolv_id = 0;
221 }
222
223 static void resolv_host_addr(struct connection_data *data)
224 {
225         if (!data->host)
226                 return;
227
228         if (connman_inet_check_ipaddress(data->host) > 0)
229                 return;
230
231         if (data->host_ip)
232                 return;
233
234         data->resolv = g_resolv_new(0);
235         if (!data->resolv) {
236                 DBG("Cannot resolv %s", data->host);
237                 return;
238         }
239
240         DBG("Trying to resolv %s", data->host);
241
242         data->resolv_id = g_resolv_lookup_hostname(data->resolv, data->host,
243                                                 resolv_result, data);
244 }
245
246 static void free_config_cb_data(struct config_create_data *cb_data)
247 {
248         if (!cb_data)
249                 return;
250
251         g_free(cb_data->path);
252         cb_data->path = NULL;
253
254         if (cb_data->message) {
255                 dbus_message_unref(cb_data->message);
256                 cb_data->message = NULL;
257         }
258
259         cb_data->callback = NULL;
260
261         g_free(cb_data);
262 }
263
264 static bool provider_is_connected(struct connection_data *data)
265 {
266         return data && (g_str_equal(data->state, "ready") ||
267                         g_str_equal(data->state, "configuration"));
268 }
269
270 static void set_provider_state(struct connection_data *data)
271 {
272         enum connman_provider_state state = CONNMAN_PROVIDER_STATE_UNKNOWN;
273         bool connected;
274         int err = 0;
275
276         DBG("provider %p new state %s", data->provider, data->state);
277
278         connected = provider_is_connected(data);
279
280         if (g_str_equal(data->state, "ready")) {
281                 state = CONNMAN_PROVIDER_STATE_READY;
282                 goto set;
283         } else if (g_str_equal(data->state, "configuration")) {
284                 state = CONNMAN_PROVIDER_STATE_CONNECT;
285         } else if (g_str_equal(data->state, "idle")) {
286                 state = CONNMAN_PROVIDER_STATE_IDLE;
287         } else if (g_str_equal(data->state, "disconnect")) {
288                 err = ECONNREFUSED;
289                 state = CONNMAN_PROVIDER_STATE_DISCONNECT;
290                 goto set;
291         } else if (g_str_equal(data->state, "failure")) {
292                 err = ECONNREFUSED;
293                 state = CONNMAN_PROVIDER_STATE_FAILURE;
294                 goto set;
295         }
296
297         connman_provider_set_state(data->provider, state);
298         goto free;
299
300 set:
301         if (data->cb_data)
302                 data->cb_data->callback(data->cb_data->message,
303                                         err, data->ident);
304
305         connman_provider_set_state(data->provider, state);
306
307         free_config_cb_data(data->cb_data);
308         data->cb_data = NULL;
309
310 free:
311         if (!connected) {
312                 g_free(data->service_ident);
313                 data->service_ident = NULL;
314         }
315 }
316
317 static int create_provider(struct connection_data *data, void *user_data)
318 {
319         struct connman_provider_driver *driver = user_data;
320         int err;
321
322         DBG("%s", data->path);
323
324         data->provider = connman_provider_get(data->ident);
325         if (!data->provider)
326                 return -ENOMEM;
327
328         DBG("provider %p name %s", data->provider, data->name);
329
330         connman_provider_set_data(data->provider, data);
331         connman_provider_set_driver(data->provider, driver);
332
333         err = connman_provider_create_service(data->provider);
334         if (err == 0) {
335                 connman_provider_set_immutable(data->provider, data->immutable);
336                 if (g_str_equal(data->state, "ready")) {
337                         connman_provider_set_index(data->provider,
338                                                         data->index);
339                         if (data->ip)
340                                 connman_provider_set_ipaddress(data->provider,
341                                                                 data->ip);
342                 }
343
344                 set_provider_state(data);
345         }
346
347         return 0;
348 }
349
350 static void destroy_route(gpointer user_data)
351 {
352         struct vpn_route *route = user_data;
353
354         g_free(route->network);
355         g_free(route->netmask);
356         g_free(route->gateway);
357         g_free(route);
358 }
359
360 static struct connection_data *create_connection_data(const char *path)
361 {
362         struct connection_data *data;
363
364         data = g_try_new0(struct connection_data, 1);
365         if (!data)
366                 return NULL;
367
368         DBG("path %s", path);
369
370         data->path = g_strdup(path);
371         data->ident = g_strdup(get_ident(path));
372         data->index = -1;
373
374         data->setting_strings = g_hash_table_new_full(g_str_hash,
375                                                 g_str_equal, g_free, g_free);
376
377         data->server_routes = g_hash_table_new_full(g_direct_hash,
378                                         g_str_equal, g_free, destroy_route);
379         data->user_routes = g_hash_table_new_full(g_str_hash,
380                                         g_str_equal, g_free, destroy_route);
381
382         return data;
383 }
384
385 static int extract_ip(DBusMessageIter *array, int family,
386                                                 struct connection_data *data)
387 {
388         DBusMessageIter dict;
389         char *address = NULL, *gateway = NULL, *netmask = NULL, *peer = NULL;
390         unsigned char prefix_len;
391
392         if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
393                 return -EINVAL;
394
395         dbus_message_iter_recurse(array, &dict);
396
397         while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
398                 DBusMessageIter entry, value;
399                 const char *key;
400
401                 dbus_message_iter_recurse(&dict, &entry);
402                 dbus_message_iter_get_basic(&entry, &key);
403
404                 dbus_message_iter_next(&entry);
405                 dbus_message_iter_recurse(&entry, &value);
406
407                 if (g_str_equal(key, "Address")) {
408                         dbus_message_iter_get_basic(&value, &address);
409                         DBG("address %s", address);
410                 } else if (g_str_equal(key, "Netmask")) {
411                         dbus_message_iter_get_basic(&value, &netmask);
412                         DBG("netmask %s", netmask);
413                 } else if (g_str_equal(key, "PrefixLength")) {
414                         dbus_message_iter_get_basic(&value, &netmask);
415                         DBG("prefix length %s", netmask);
416                 } else if (g_str_equal(key, "Peer")) {
417                         dbus_message_iter_get_basic(&value, &peer);
418                         DBG("peer %s", peer);
419                 } else if (g_str_equal(key, "Gateway")) {
420                         dbus_message_iter_get_basic(&value, &gateway);
421                         DBG("gateway %s", gateway);
422                 }
423
424                 dbus_message_iter_next(&dict);
425         }
426
427         connman_ipaddress_free(data->ip);
428         data->ip = connman_ipaddress_alloc(family);
429         if (!data->ip)
430                 return -ENOMEM;
431
432         switch (family) {
433         case AF_INET:
434                 connman_ipaddress_set_ipv4(data->ip, address, netmask,
435                                                                 gateway);
436                 break;
437         case AF_INET6:
438                 prefix_len = atoi(netmask);
439                 connman_ipaddress_set_ipv6(data->ip, address, prefix_len,
440                                                                 gateway);
441                 break;
442         default:
443                 return -EINVAL;
444         }
445
446         connman_ipaddress_set_peer(data->ip, peer);
447         connman_ipaddress_set_p2p(data->ip, true);
448
449         return 0;
450 }
451
452 static int extract_nameservers(DBusMessageIter *array,
453                                                 struct connection_data *data)
454 {
455         DBusMessageIter entry;
456         char **nameservers = NULL;
457         int i = 0;
458
459         dbus_message_iter_recurse(array, &entry);
460
461         while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
462                 const char *nameserver;
463
464                 dbus_message_iter_get_basic(&entry, &nameserver);
465
466                 nameservers = g_try_renew(char *, nameservers, i + 2);
467                 if (!nameservers)
468                         return -ENOMEM;
469
470                 DBG("[%d] %s", i, nameserver);
471
472                 nameservers[i] = g_strdup(nameserver);
473                 if (!nameservers[i])
474                         return -ENOMEM;
475
476                 nameservers[++i] = NULL;
477
478                 dbus_message_iter_next(&entry);
479         }
480
481         g_strfreev(data->nameservers);
482         data->nameservers = nameservers;
483
484         return 0;
485 }
486
487 static int errorstr2val(const char *error) {
488         if (g_strcmp0(error, CONNMAN_ERROR_INTERFACE ".InProgress") == 0)
489                 return -EINPROGRESS;
490
491         if (g_strcmp0(error, CONNMAN_ERROR_INTERFACE ".AlreadyConnected") == 0)
492                 return -EISCONN;
493
494         if (g_strcmp0(error, CONNMAN_ERROR_INTERFACE ".OperationCanceled") == 0)
495                 return -ECANCELED;
496
497         return -ECONNREFUSED;
498 }
499
500 static void connect_reply(DBusPendingCall *call, void *user_data)
501 {
502         DBusMessage *reply;
503         DBusError error;
504         struct connection_data *data = user_data;
505         struct config_create_data *cb_data = data->cb_data;
506
507         DBG("");
508
509         if (!dbus_pending_call_get_completed(call)) {
510                 connman_warn("vpn connect reply pending call incomplete");
511                 goto out;
512         }
513
514         if (call != data->call) {
515                 connman_error("invalid call %p to VPN connect_reply data %p "
516                                         " call %p ", call, data, data->call);
517                 dbus_pending_call_unref(call);
518                 return;
519         }
520
521         DBG("user_data %p path %s", user_data, cb_data ? cb_data->path : NULL);
522
523         reply = dbus_pending_call_steal_reply(call);
524         if (!reply)
525                 goto out;
526
527         dbus_error_init(&error);
528
529         if (dbus_set_error_from_message(&error, reply)) {
530                 int err = errorstr2val(error.name);
531
532                 /*
533                  * ECANCELED means that user has canceled authentication
534                  * dialog. That's not really an error, it's part of a normal
535                  * workflow. We also take it as a request to turn autoconnect
536                  * off, in case if it was on.
537                  */
538                 if (err == -ECANCELED) {
539                         DBG("%s connect canceled", data->path);
540                         connman_provider_set_autoconnect(data->provider, false);
541                 } else if (err != -EINPROGRESS) {
542                         connman_error("Connect reply: %s (%s)", error.message,
543                                                                 error.name);
544                         DBG("data %p cb_data %p", data, cb_data);
545
546                         if (cb_data) {
547                                 cb_data->callback(cb_data->message, err, NULL);
548                                 free_config_cb_data(cb_data);
549                                 data->cb_data = NULL;
550                         }
551                 }
552
553                 dbus_error_free(&error);
554         }
555
556         /*
557          * The vpn connection is up when we get a "ready" state
558          * property so at this point we do nothing for the provider
559          * state.
560          */
561
562         dbus_message_unref(reply);
563
564 out:
565         dbus_pending_call_unref(data->call);
566
567         data->call = NULL;
568         data->connect_pending = false;
569 }
570
571 static int connect_provider(struct connection_data *data, void *user_data,
572                         const char *dbus_sender)
573 {
574         DBusPendingCall *call;
575         DBusMessage *message;
576         struct config_create_data *cb_data = user_data;
577         struct connman_service *transport = connman_service_get_default();
578
579         DBG("data %p user %p path %s sender %s", data, cb_data, data->path,
580                                                                 dbus_sender);
581
582         if (!transport) {
583                 DBG("no default service, refusing to connect");
584                 return -EINVAL;
585         }
586
587         if (data->connect_pending && data->call) {
588                 connman_info("connect already pending");
589                 return -EALREADY;
590         }
591
592         /* We need to pass original dbus sender to connman-vpnd,
593          * use a Connect2 method for that if the original dbus sender is set.
594          * Connect method requires no parameter, Connect2 requires dbus sender
595          * name to be set.
596          */
597         message = dbus_message_new_method_call(VPN_SERVICE, data->path,
598                                         VPN_CONNECTION_INTERFACE,
599                                         dbus_sender && *dbus_sender ?
600                                                 VPN_CONNECT2 : VPN_CONNECT);
601         if (!message)
602                 return -ENOMEM;
603
604         if (dbus_sender && *dbus_sender)
605                 dbus_message_append_args(message, DBUS_TYPE_STRING,
606                                         &dbus_sender, NULL);
607         else
608                 dbus_sender = "";
609
610         if (!dbus_connection_send_with_reply(connection, message,
611                                                 &call, DBUS_TIMEOUT)) {
612                 connman_error("Unable to call %s.%s()",
613                         VPN_CONNECTION_INTERFACE, dbus_sender && *dbus_sender ?
614                                                 VPN_CONNECT2 : VPN_CONNECT);
615                 dbus_message_unref(message);
616                 return -EINVAL;
617         }
618
619         if (!call) {
620                 dbus_message_unref(message);
621                 return -EINVAL;
622         }
623
624         if (data->call) {
625                 dbus_pending_call_cancel(data->call);
626                 dbus_pending_call_unref(data->call);
627         }
628
629         data->call = call;
630         data->connect_pending = true;
631
632         if (cb_data) {
633                 g_free(cb_data->path);
634                 cb_data->path = g_strdup(data->path);
635         }
636
637         /*
638          * This is the service which (most likely) will be used
639          * as a transport for VPN connection.
640          */
641         g_free(data->service_ident);
642         data->service_ident =
643                 g_strdup(connman_service_get_identifier(transport));
644         DBG("transport %s", data->service_ident);
645
646         dbus_pending_call_set_notify(call, connect_reply, data, NULL);
647
648         dbus_message_unref(message);
649
650         return -EINPROGRESS;
651 }
652
653 static void add_connection(const char *path, DBusMessageIter *properties,
654                         void *user_data)
655 {
656         struct connection_data *data;
657         int err;
658         char *ident = get_ident(path);
659         bool found = false;
660
661         data = g_hash_table_lookup(vpn_connections, ident);
662         if (data) {
663                 /*
664                  * We might have a dummy connection struct here that
665                  * was created by configuration_create_reply() so in
666                  * that case just continue.
667                  */
668                 if (!data->connect_pending)
669                         return;
670
671                 found = true;
672         } else {
673                 data = create_connection_data(path);
674                 if (!data)
675                         return;
676         }
677
678         DBG("data %p path %s", data, path);
679
680         while (dbus_message_iter_get_arg_type(properties) ==
681                         DBUS_TYPE_DICT_ENTRY) {
682                 DBusMessageIter entry, value;
683                 const char *key;
684                 char *str;
685
686                 dbus_message_iter_recurse(properties, &entry);
687                 dbus_message_iter_get_basic(&entry, &key);
688
689                 dbus_message_iter_next(&entry);
690                 dbus_message_iter_recurse(&entry, &value);
691
692                 if (g_str_equal(key, "State")) {
693                         dbus_message_iter_get_basic(&value, &str);
694                         DBG("state %s -> %s", data->state, str);
695                         data->state = g_strdup(str);
696                 } else if (g_str_equal(key, "IPv4")) {
697                         extract_ip(&value, AF_INET, data);
698                 } else if (g_str_equal(key, "IPv6")) {
699                         extract_ip(&value, AF_INET6, data);
700                 } else if (g_str_equal(key, "Name")) {
701                         dbus_message_iter_get_basic(&value, &str);
702                         data->name = g_strdup(str);
703                 } else if (g_str_equal(key, "Type")) {
704                         dbus_message_iter_get_basic(&value, &str);
705                         data->type = g_strdup(str);
706                 } else if (g_str_equal(key, "Immutable")) {
707                         dbus_bool_t immutable;
708
709                         dbus_message_iter_get_basic(&value, &immutable);
710                         data->immutable = immutable;
711                 } else if (g_str_equal(key, "Host")) {
712                         dbus_message_iter_get_basic(&value, &str);
713                         data->host = g_strdup(str);
714                 } else if (g_str_equal(key, "Domain")) {
715                         dbus_message_iter_get_basic(&value, &str);
716                         g_free(data->domain);
717                         data->domain = g_strdup(str);
718                 } else if (g_str_equal(key, "Nameservers")) {
719                         extract_nameservers(&value, data);
720                 } else if (g_str_equal(key, "Index")) {
721                         dbus_message_iter_get_basic(&value, &data->index);
722                 } else if (g_str_equal(key, "ServerRoutes")) {
723                         /* Ignored */
724                 } else if (g_str_equal(key, "UserRoutes")) {
725                         /* Ignored */
726                 } else {
727                         if (dbus_message_iter_get_arg_type(&value) ==
728                                                         DBUS_TYPE_STRING) {
729                                 dbus_message_iter_get_basic(&value, &str);
730                                 g_hash_table_replace(data->setting_strings,
731                                                 g_strdup(key), g_strdup(str));
732                         } else {
733                                 DBG("unknown key %s", key);
734                         }
735                 }
736
737                 dbus_message_iter_next(properties);
738         }
739
740         if (!found)
741                 g_hash_table_insert(vpn_connections, g_strdup(data->ident),
742                                                                         data);
743
744         err = create_provider(data, user_data);
745         if (err < 0)
746                 goto out;
747
748         resolv_host_addr(data);
749
750         if (data->nameservers)
751                 connman_provider_set_nameservers(data->provider,
752                                                 data->nameservers);
753
754         if (data->domain)
755                 connman_provider_set_domain(data->provider,
756                                                 data->domain);
757
758         if (data->connect_pending) {
759                 const char *dbus_sender = NULL;
760
761                 if (data->cb_data && data->cb_data->message) {
762                         dbus_sender =
763                                 dbus_message_get_sender(data->cb_data->message);
764                 }
765                 connect_provider(data, data->cb_data, dbus_sender);
766         }
767
768         return;
769
770 out:
771         DBG("removing %s", data->ident);
772         g_hash_table_remove(vpn_connections, data->ident);
773 }
774
775 static void get_connections_reply(DBusPendingCall *call, void *user_data)
776 {
777         DBusMessage *reply;
778         DBusError error;
779         DBusMessageIter array, dict;
780         const char *signature = DBUS_TYPE_ARRAY_AS_STRING
781                 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
782                 DBUS_TYPE_OBJECT_PATH_AS_STRING
783                 DBUS_TYPE_ARRAY_AS_STRING
784                 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
785                 DBUS_TYPE_STRING_AS_STRING
786                 DBUS_TYPE_VARIANT_AS_STRING
787                 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
788                 DBUS_STRUCT_END_CHAR_AS_STRING;
789
790         DBG("");
791
792         if (!dbus_pending_call_get_completed(call)) {
793                 connman_warn("get connections reply pending call incomplete");
794                 goto out;
795         }
796
797         reply = dbus_pending_call_steal_reply(call);
798         if (!reply)
799                 goto out;
800
801         dbus_error_init(&error);
802
803         if (dbus_set_error_from_message(&error, reply)) {
804                 connman_error("%s", error.message);
805                 dbus_error_free(&error);
806                 goto done;
807         }
808
809         if (!dbus_message_has_signature(reply, signature)) {
810                 connman_error("vpnd signature \"%s\" does not match "
811                                                         "expected \"%s\"",
812                         dbus_message_get_signature(reply), signature);
813                 goto done;
814         }
815
816         if (!dbus_message_iter_init(reply, &array))
817                 goto done;
818
819         dbus_message_iter_recurse(&array, &dict);
820
821         while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
822                 DBusMessageIter value, properties;
823                 const char *path;
824
825                 dbus_message_iter_recurse(&dict, &value);
826                 dbus_message_iter_get_basic(&value, &path);
827
828                 dbus_message_iter_next(&value);
829                 dbus_message_iter_recurse(&value, &properties);
830
831                 add_connection(path, &properties, user_data);
832
833                 dbus_message_iter_next(&dict);
834         }
835
836 done:
837         dbus_message_unref(reply);
838
839 out:
840         dbus_pending_call_unref(call);
841 }
842
843 static int get_connections(void *user_data)
844 {
845         DBusPendingCall *call;
846         DBusMessage *message;
847
848         DBG("");
849
850         message = dbus_message_new_method_call(VPN_SERVICE, "/",
851                                         VPN_MANAGER_INTERFACE,
852                                         GET_CONNECTIONS);
853         if (!message)
854                 return -ENOMEM;
855
856         if (!dbus_connection_send_with_reply(connection, message,
857                                                 &call, DBUS_TIMEOUT)) {
858                 connman_error("Unable to call %s.%s()", VPN_MANAGER_INTERFACE,
859                                                         GET_CONNECTIONS);
860                 dbus_message_unref(message);
861                 return -EINVAL;
862         }
863
864         if (!call) {
865                 dbus_message_unref(message);
866                 return -EINVAL;
867         }
868
869         dbus_pending_call_set_notify(call, get_connections_reply,
870                                                         user_data, NULL);
871
872         dbus_message_unref(message);
873
874         return -EINPROGRESS;
875 }
876
877 static int provider_probe(struct connman_provider *provider)
878 {
879         return 0;
880 }
881
882 static void remove_connection_reply(DBusPendingCall *call, void *user_data)
883 {
884         DBusMessage *reply;
885         DBusError error;
886
887         DBG("");
888
889         if (!dbus_pending_call_get_completed(call)) {
890                 connman_warn("remove connection reply pending call incomplete");
891                 goto out;
892         }
893
894         reply = dbus_pending_call_steal_reply(call);
895         if (!reply)
896                 goto out;
897
898         dbus_error_init(&error);
899
900         if (dbus_set_error_from_message(&error, reply)) {
901                 /*
902                  * If the returned error is NotFound, it means that we
903                  * have actually removed the provider in vpnd already.
904                  */
905                 if (!dbus_error_has_name(&error,
906                                 CONNMAN_ERROR_INTERFACE".NotFound"))
907                         connman_error("%s", error.message);
908
909                 dbus_error_free(&error);
910         }
911
912         dbus_message_unref(reply);
913
914 out:
915         dbus_pending_call_unref(call);
916 }
917
918 static int provider_remove(struct connman_provider *provider)
919 {
920         DBusPendingCall *call;
921         DBusMessage *message;
922         struct connection_data *data;
923
924         data = connman_provider_get_data(provider);
925
926         DBG("provider %p data %p", provider, data);
927
928         if (!data) {
929                 /*
930                  * This means the provider is already removed,
931                  * just ignore the dbus in this case.
932                  */
933                 return -EALREADY;
934         }
935
936         /*
937          * When provider.c:provider_remove() calls this function,
938          * it will remove the provider itself after the call.
939          * This means that we cannot use the provider pointer later
940          * as it is no longer valid.
941          */
942         data->provider = NULL;
943
944         message = dbus_message_new_method_call(VPN_SERVICE, "/",
945                                         VPN_MANAGER_INTERFACE,
946                                         VPN_REMOVE);
947         if (!message)
948                 return -ENOMEM;
949
950         dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &data->path,
951                                 NULL);
952
953         if (!dbus_connection_send_with_reply(connection, message,
954                                                 &call, DBUS_TIMEOUT)) {
955                 connman_error("Unable to call %s.%s()", VPN_MANAGER_INTERFACE,
956                                                         VPN_REMOVE);
957                 dbus_message_unref(message);
958                 return -EINVAL;
959         }
960
961         if (!call) {
962                 dbus_message_unref(message);
963                 return -EINVAL;
964         }
965
966         dbus_pending_call_set_notify(call, remove_connection_reply,
967                                                         NULL, NULL);
968
969         dbus_message_unref(message);
970
971         return 0;
972 }
973
974 static int provider_connect(struct connman_provider *provider,
975                                         const char *dbus_sender)
976 {
977         struct connection_data *data;
978
979         data = connman_provider_get_data(provider);
980         if (!data)
981                 return -EINVAL;
982
983         return connect_provider(data, NULL, dbus_sender);
984 }
985
986 static void disconnect_reply(DBusPendingCall *call, void *user_data)
987 {
988         struct connection_data *data = user_data;
989         DBusMessage *reply;
990         DBusError error;
991
992         DBG("user %p", user_data);
993
994         reply = dbus_pending_call_steal_reply(call);
995
996         dbus_error_init(&error);
997
998         if (dbus_set_error_from_message(&error, reply)) {
999                 connman_error("%s", error.message);
1000                 dbus_error_free(&error);
1001                 goto done;
1002         }
1003
1004 done:
1005         dbus_message_unref(reply);
1006         dbus_pending_call_unref(call);
1007         data->disconnect_call = NULL;
1008 }
1009
1010 static int disconnect_provider(struct connection_data *data)
1011 {
1012         bool sent;
1013         DBusMessage *message;
1014
1015         DBG("data %p path %s", data, data->path);
1016
1017         if (data->disconnect_call) {
1018                 DBG("already disconnecting");
1019                 return -EINVAL;
1020         }
1021
1022         message = dbus_message_new_method_call(VPN_SERVICE, data->path,
1023                                         VPN_CONNECTION_INTERFACE,
1024                                         VPN_DISCONNECT);
1025         if (!message)
1026                 return -ENOMEM;
1027
1028         sent = dbus_connection_send_with_reply(connection, message,
1029                                         &data->disconnect_call, DBUS_TIMEOUT);
1030         dbus_message_unref(message);
1031
1032         if (!sent || !data->disconnect_call) {
1033                 connman_error("Unable to call %s.%s()",
1034                         VPN_CONNECTION_INTERFACE, VPN_DISCONNECT);
1035                 return -EINVAL;
1036         }
1037
1038         dbus_pending_call_set_notify(data->disconnect_call, disconnect_reply,
1039                                                                 data, NULL);
1040
1041         data->default_route_set = false;
1042
1043         connman_provider_set_state(data->provider,
1044                                         CONNMAN_PROVIDER_STATE_DISCONNECT);
1045
1046         g_free(data->service_ident);
1047         data->service_ident = NULL;
1048
1049         return -EINPROGRESS;
1050 }
1051
1052 static int provider_disconnect(struct connman_provider *provider)
1053 {
1054         int err = 0;
1055
1056         struct connection_data *data;
1057
1058         DBG("provider %p", provider);
1059
1060         data = connman_provider_get_data(provider);
1061         if (!data)
1062                 return -EINVAL;
1063
1064         if (provider_is_connected(data))
1065                 err = disconnect_provider(data);
1066
1067         if (data->call) {
1068                 dbus_pending_call_cancel(data->call);
1069                 dbus_pending_call_unref(data->call);
1070                 data->call = NULL;
1071         }
1072
1073         data->connect_pending = false;
1074
1075         return err;
1076 }
1077
1078 static void configuration_create_reply(DBusPendingCall *call, void *user_data)
1079 {
1080         DBusMessage *reply;
1081         DBusError error;
1082         DBusMessageIter iter;
1083         const char *signature = DBUS_TYPE_OBJECT_PATH_AS_STRING;
1084         const char *path;
1085         char *ident;
1086         struct connection_data *data;
1087         struct config_create_data *cb_data = user_data;
1088
1089         DBG("user %p", cb_data);
1090
1091         if (!dbus_pending_call_get_completed(call)) {
1092                 connman_warn("configuration create reply pending call incomplete");
1093                 goto out;
1094         }
1095
1096         reply = dbus_pending_call_steal_reply(call);
1097         if (!reply)
1098                 goto out;
1099
1100         dbus_error_init(&error);
1101
1102         if (dbus_set_error_from_message(&error, reply)) {
1103                 connman_error("dbus error: %s", error.message);
1104                 dbus_error_free(&error);
1105                 goto done;
1106         }
1107
1108         if (!dbus_message_has_signature(reply, signature)) {
1109                 connman_error("vpn configuration signature \"%s\" does not "
1110                                                 "match expected \"%s\"",
1111                         dbus_message_get_signature(reply), signature);
1112                 goto done;
1113         }
1114
1115         if (!dbus_message_iter_init(reply, &iter))
1116                 goto done;
1117
1118         dbus_message_iter_get_basic(&iter, &path);
1119
1120         /*
1121          * Then try to connect the VPN as expected by ConnectProvider API
1122          */
1123         ident = get_ident(path);
1124
1125         data = g_hash_table_lookup(vpn_connections, ident);
1126         if (!data) {
1127                 /*
1128                  * Someone removed the data. We cannot really continue.
1129                  */
1130                 DBG("Pending data not found for %s, cannot continue!", ident);
1131         } else {
1132                 data->call = NULL;
1133                 data->connect_pending = true;
1134
1135                 if (!data->cb_data)
1136                         data->cb_data = cb_data;
1137                 else
1138                         DBG("Connection callback data already in use!");
1139
1140                 /*
1141                  * Connection is created in add_connections() after
1142                  * we have received the ConnectionAdded signal.
1143                  */
1144
1145                 DBG("cb %p msg %p", data->cb_data,
1146                         data->cb_data ? data->cb_data->message : NULL);
1147         }
1148
1149 done:
1150         dbus_message_unref(reply);
1151
1152 out:
1153         dbus_pending_call_unref(call);
1154 }
1155
1156 static void set_dbus_ident(char *ident)
1157 {
1158         int i, len = strlen(ident);
1159
1160         for (i = 0; i < len; i++) {
1161                 if (ident[i] >= '0' && ident[i] <= '9')
1162                         continue;
1163                 if (ident[i] >= 'a' && ident[i] <= 'z')
1164                         continue;
1165                 if (ident[i] >= 'A' && ident[i] <= 'Z')
1166                         continue;
1167                 ident[i] = '_';
1168         }
1169 }
1170
1171 static struct vpn_route *parse_user_route(const char *user_route)
1172 {
1173         char *network, *netmask;
1174         struct vpn_route *route = NULL;
1175         int family = PF_UNSPEC;
1176         char **elems = g_strsplit(user_route, "/", 0);
1177
1178         if (!elems)
1179                 return NULL;
1180
1181         network = elems[0];
1182         if (!network || *network == '\0') {
1183                 DBG("no network/netmask set");
1184                 goto out;
1185         }
1186
1187         netmask = elems[1];
1188         if (netmask && *netmask == '\0') {
1189                 DBG("no netmask set");
1190                 goto out;
1191         }
1192
1193         if (g_strrstr(network, ":"))
1194                 family = AF_INET6;
1195         else if (g_strrstr(network, ".")) {
1196                 family = AF_INET;
1197
1198                 if (!g_strrstr(netmask, ".")) {
1199                         /* We have netmask length */
1200                         in_addr_t addr;
1201                         struct in_addr netmask_in;
1202                         unsigned char prefix_len = 32;
1203
1204                         if (netmask) {
1205                                 char *ptr;
1206                                 long int value = strtol(netmask, &ptr, 10);
1207                                 if (ptr != netmask && *ptr == '\0' &&
1208                                                 value && value <= 32)
1209                                         prefix_len = value;
1210                         }
1211
1212                         addr = 0xffffffff << (32 - prefix_len);
1213                         netmask_in.s_addr = htonl(addr);
1214                         netmask = inet_ntoa(netmask_in);
1215
1216                         DBG("network %s netmask %s", network, netmask);
1217                 }
1218         }
1219
1220         route = g_try_new(struct vpn_route, 1);
1221         if (!route)
1222                 goto out;
1223
1224         route->network = g_strdup(network);
1225         route->netmask = g_strdup(netmask);
1226         route->gateway = NULL;
1227         route->family = family;
1228
1229 out:
1230         g_strfreev(elems);
1231         return route;
1232 }
1233
1234 static GSList *get_user_networks(DBusMessageIter *array)
1235 {
1236         DBusMessageIter entry;
1237         GSList *list = NULL;
1238
1239         dbus_message_iter_recurse(array, &entry);
1240
1241         while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
1242                 const char *val;
1243                 struct vpn_route *route;
1244
1245                 dbus_message_iter_get_basic(&entry, &val);
1246
1247                 route = parse_user_route(val);
1248                 if (route)
1249                         list = g_slist_prepend(list, route);
1250
1251                 dbus_message_iter_next(&entry);
1252         }
1253
1254         return list;
1255 }
1256
1257 static void append_route(DBusMessageIter *iter, void *user_data)
1258 {
1259         struct vpn_route *route = user_data;
1260         DBusMessageIter item;
1261         int family = 0;
1262
1263         connman_dbus_dict_open(iter, &item);
1264
1265         if (!route)
1266                 goto empty_dict;
1267
1268         if (route->family == AF_INET)
1269                 family = 4;
1270         else if (route->family == AF_INET6)
1271                 family = 6;
1272
1273         if (family != 0)
1274                 connman_dbus_dict_append_basic(&item, "ProtocolFamily",
1275                                         DBUS_TYPE_INT32, &family);
1276
1277         if (route->network)
1278                 connman_dbus_dict_append_basic(&item, "Network",
1279                                         DBUS_TYPE_STRING, &route->network);
1280
1281         if (route->netmask)
1282                 connman_dbus_dict_append_basic(&item, "Netmask",
1283                                         DBUS_TYPE_STRING, &route->netmask);
1284
1285         if (route->gateway)
1286                 connman_dbus_dict_append_basic(&item, "Gateway",
1287                                         DBUS_TYPE_STRING, &route->gateway);
1288
1289 empty_dict:
1290         connman_dbus_dict_close(iter, &item);
1291 }
1292
1293 static void append_routes(DBusMessageIter *iter, void *user_data)
1294 {
1295         GSList *list, *routes = user_data;
1296
1297         DBG("routes %p", routes);
1298
1299         for (list = routes; list; list = g_slist_next(list)) {
1300                 DBusMessageIter dict;
1301                 struct vpn_route *route = list->data;
1302
1303                 dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL,
1304                                                 &dict);
1305                 append_route(&dict, route);
1306                 dbus_message_iter_close_container(iter, &dict);
1307         }
1308 }
1309
1310 static int create_configuration(DBusMessage *msg, connection_ready_cb callback)
1311 {
1312         DBusMessage *new_msg = NULL;
1313         DBusPendingCall *call;
1314         DBusMessageIter iter, array, new_iter, new_dict;
1315         const char *type = NULL, *name = NULL;
1316         const char *host = NULL, *domain = NULL;
1317         char *ident, *me = NULL;
1318         int err = 0;
1319         dbus_bool_t result;
1320         struct connection_data *data;
1321         struct config_create_data *user_data = NULL;
1322         GSList *networks = NULL;
1323
1324         /*
1325          * We copy the old message data into new message. We cannot
1326          * just use the old message as is because the user route
1327          * information is not in the same format in vpnd.
1328          */
1329         new_msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
1330         dbus_message_iter_init_append(new_msg, &new_iter);
1331         connman_dbus_dict_open(&new_iter, &new_dict);
1332
1333         dbus_message_iter_init(msg, &iter);
1334         dbus_message_iter_recurse(&iter, &array);
1335
1336         while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
1337                 DBusMessageIter entry, value;
1338                 void *item_value;
1339                 const char *key;
1340                 int value_type;
1341
1342                 dbus_message_iter_recurse(&array, &entry);
1343                 dbus_message_iter_get_basic(&entry, &key);
1344
1345                 dbus_message_iter_next(&entry);
1346                 dbus_message_iter_recurse(&entry, &value);
1347
1348                 value_type = dbus_message_iter_get_arg_type(&value);
1349                 item_value = NULL;
1350
1351                 switch (value_type) {
1352                 case DBUS_TYPE_STRING:
1353                         dbus_message_iter_get_basic(&value, &item_value);
1354
1355                         if (g_str_equal(key, "Type"))
1356                                 type = (const char *)item_value;
1357                         else if (g_str_equal(key, "Name"))
1358                                 name = (const char *)item_value;
1359                         else if (g_str_equal(key, "Host"))
1360                                 host = (const char *)item_value;
1361                         else if (g_str_equal(key, "VPN.Domain"))
1362                                 domain = (const char *)item_value;
1363
1364                         DBG("%s %s", key, (char *)item_value);
1365
1366                         if (item_value)
1367                                 connman_dbus_dict_append_basic(&new_dict, key,
1368                                                 value_type, &item_value);
1369                         break;
1370                 case DBUS_TYPE_ARRAY:
1371                         if (g_str_equal(key, "Networks")) {
1372                                 networks = get_user_networks(&value);
1373                                 connman_dbus_dict_append_array(&new_dict,
1374                                                         "UserRoutes",
1375                                                         DBUS_TYPE_DICT_ENTRY,
1376                                                         append_routes,
1377                                                         networks);
1378                         }
1379                         break;
1380                 }
1381
1382                 dbus_message_iter_next(&array);
1383         }
1384
1385         connman_dbus_dict_close(&new_iter, &new_dict);
1386
1387         DBG("VPN type %s name %s host %s domain %s networks %p",
1388                 type, name, host, domain, networks);
1389
1390         if (!host || !domain) {
1391                 err = -EINVAL;
1392                 goto done;
1393         }
1394
1395         if (!type || !name) {
1396                 err = -EOPNOTSUPP;
1397                 goto done;
1398         }
1399
1400         ident = g_strdup_printf("%s_%s", host, domain);
1401         set_dbus_ident(ident);
1402
1403         DBG("ident %s", ident);
1404
1405         data = g_hash_table_lookup(vpn_connections, ident);
1406         if (data) {
1407                 if (data->call || data->cb_data) {
1408                         DBG("create configuration call already pending");
1409                         err = -EINPROGRESS;
1410                         goto done;
1411                 }
1412         } else {
1413                 char *path = g_strdup_printf("%s/connection/%s", VPN_PATH,
1414                                                                 ident);
1415                 data = create_connection_data(path);
1416                 g_free(path);
1417
1418                 if (!data) {
1419                         err = -ENOMEM;
1420                         goto done;
1421                 }
1422
1423                 g_hash_table_insert(vpn_connections, g_strdup(ident), data);
1424         }
1425
1426         /*
1427          * User called net.connman.Manager.ConnectProvider if we are here.
1428          * So use the data from original message in the new msg.
1429          */
1430         me = g_strdup(dbus_message_get_destination(msg));
1431
1432         dbus_message_set_interface(new_msg, VPN_MANAGER_INTERFACE);
1433         dbus_message_set_path(new_msg, "/");
1434         dbus_message_set_destination(new_msg, VPN_SERVICE);
1435         dbus_message_set_sender(new_msg, me);
1436         dbus_message_set_member(new_msg, "Create");
1437
1438         user_data = g_try_new0(struct config_create_data, 1);
1439         if (!user_data) {
1440                 err = -ENOMEM;
1441                 goto done;
1442         }
1443
1444         user_data->callback = callback;
1445         user_data->message = dbus_message_ref(msg);
1446         user_data->path = NULL;
1447
1448         DBG("cb %p msg %p", user_data, msg);
1449
1450         result = dbus_connection_send_with_reply(connection, new_msg,
1451                                                 &call, DBUS_TIMEOUT);
1452         if (!result || !call) {
1453                 err = -EIO;
1454                 goto done;
1455         }
1456
1457         dbus_pending_call_set_notify(call, configuration_create_reply,
1458                                                         user_data, NULL);
1459         data->call = call;
1460
1461 done:
1462         if (new_msg)
1463                 dbus_message_unref(new_msg);
1464
1465         if (networks)
1466                 g_slist_free_full(networks, destroy_route);
1467
1468         g_free(me);
1469         return err;
1470 }
1471
1472 static bool check_host(char **hosts, char *host)
1473 {
1474         int i;
1475
1476         if (!hosts)
1477                 return false;
1478
1479         for (i = 0; hosts[i]; i++) {
1480                 if (g_strcmp0(hosts[i], host) == 0)
1481                         return true;
1482         }
1483
1484         return false;
1485 }
1486
1487 static void set_route(struct connection_data *data, struct vpn_route *route)
1488 {
1489         /*
1490          * If the VPN administrator/user has given a route to
1491          * VPN server, then we must discard that because the
1492          * server cannot be contacted via VPN tunnel.
1493          */
1494         if (check_host(data->host_ip, route->network)) {
1495                 DBG("Discarding VPN route to %s via %s at index %d",
1496                         route->network, route->gateway, data->index);
1497                 return;
1498         }
1499
1500         DBG("set route provider %p %s/%s/%s", data->provider,
1501                                                 route->network, route->gateway,
1502                                                 route->netmask);
1503
1504         /* Do not add default route for split routed VPNs.*/
1505         if (connman_provider_is_split_routing(data->provider) &&
1506                                 connman_inet_is_default_route(route->family,
1507                                         route->network, route->gateway,
1508                                         route->netmask))
1509                 return;
1510
1511         if (route->family == AF_INET6) {
1512                 unsigned char prefix_len = atoi(route->netmask);
1513
1514                 connman_inet_add_ipv6_network_route(data->index,
1515                                                         route->network,
1516                                                         route->gateway,
1517                                                         prefix_len);
1518         } else {
1519                 connman_inet_add_network_route(data->index, route->network,
1520                                                 route->gateway,
1521                                                 route->netmask);
1522         }
1523
1524         if (connman_inet_is_default_route(route->family, route->network,
1525                                         route->gateway, route->netmask))
1526                 data->default_route_set = true;
1527 }
1528
1529 static int save_route(GHashTable *routes, int family, const char *network,
1530                         const char *netmask, const char *gateway);
1531
1532 static int add_network_route(struct connection_data *data)
1533 {
1534         struct vpn_route rt = { 0, };
1535         int err;
1536
1537         if (!data)
1538                 return -EINVAL;
1539
1540         rt.family = connman_provider_get_family(data->provider);
1541         switch (rt.family) {
1542         case PF_INET:
1543                 err = connman_inet_get_route_addresses(data->index,
1544                                         &rt.network, &rt.netmask, &rt.gateway);
1545                 break;
1546         case PF_INET6:
1547                 err = connman_inet_ipv6_get_route_addresses(data->index,
1548                                         &rt.network, &rt.netmask, &rt.gateway);
1549                 break;
1550         default:
1551                 connman_error("invalid protocol family %d", rt.family);
1552                 return -EINVAL;
1553         }
1554
1555         DBG("network %s gateway %s netmask %s for provider %p",
1556                                                 rt.network, rt.gateway, rt.netmask,
1557                                                 data->provider);
1558
1559         if (err) {
1560                 connman_error("cannot get network/gateway/netmask for %p",
1561                                                         data->provider);
1562                 goto out;
1563         }
1564
1565         err = save_route(data->server_routes, rt.family, rt.network, rt.netmask,
1566                                 rt.gateway);
1567         if (err) {
1568                 connman_warn("failed to add network route for provider"
1569                                         "%p", data->provider);
1570                 goto out;
1571         }
1572
1573         set_route(data, &rt);
1574
1575 out:
1576         g_free(rt.network);
1577         g_free(rt.netmask);
1578         g_free(rt.gateway);
1579
1580         return 0;
1581 }
1582
1583 static bool is_valid_route_table(struct connman_provider *provider,
1584                                                         GHashTable *table)
1585 {
1586         GHashTableIter iter;
1587         gpointer value, key;
1588         struct vpn_route *route;
1589         size_t table_size;
1590
1591         if (!table)
1592                 return false;
1593
1594         table_size = g_hash_table_size(table);
1595
1596         /* Non-split routed may have only the default route */
1597         if (table_size > 0 && !connman_provider_is_split_routing(provider))
1598                 return true;
1599
1600         /* Split routed has more than the default route */
1601         if (table_size > 1)
1602                 return true;
1603
1604         /*
1605          * Only one route for split routed VPN, which should not be the
1606          * default route.
1607          */
1608         g_hash_table_iter_init(&iter, table);
1609         if (!g_hash_table_iter_next(&iter, &key, &value)) /* First and only */
1610                 return false;
1611
1612         route = value;
1613         if (!route)
1614                 return false;
1615
1616         DBG("check route %d %s/%s/%s", route->family, route->network,
1617                                         route->gateway, route->netmask);
1618
1619         if (!connman_inet_is_default_route(route->family, route->network,
1620                                 route->gateway, route->netmask))
1621                 return true;
1622
1623         return false;
1624 }
1625
1626 static bool check_routes(struct connman_provider *provider)
1627 {
1628         struct connection_data *data;;
1629
1630         DBG("provider %p", provider);
1631
1632         data = connman_provider_get_data(provider);
1633         if (!data)
1634                 return false;
1635
1636         if (is_valid_route_table(provider, data->user_routes))
1637                 return true;
1638
1639         if (is_valid_route_table(provider, data->server_routes))
1640                 return true;
1641
1642         return false;
1643 }
1644
1645 static int set_routes(struct connman_provider *provider,
1646                                 enum connman_provider_route_type type)
1647 {
1648         struct connection_data *data;
1649         GHashTableIter iter;
1650         gpointer value, key;
1651
1652         DBG("provider %p", provider);
1653
1654         data = connman_provider_get_data(provider);
1655         if (!data)
1656                 return -EINVAL;
1657
1658         if (type == CONNMAN_PROVIDER_ROUTE_ALL ||
1659                                         type == CONNMAN_PROVIDER_ROUTE_USER) {
1660                 g_hash_table_iter_init(&iter, data->user_routes);
1661
1662                 while (g_hash_table_iter_next(&iter, &key, &value))
1663                         set_route(data, value);
1664         }
1665
1666         if (type == CONNMAN_PROVIDER_ROUTE_ALL ||
1667                                 type == CONNMAN_PROVIDER_ROUTE_SERVER) {
1668                 g_hash_table_iter_init(&iter, data->server_routes);
1669
1670                 while (g_hash_table_iter_next(&iter, &key, &value))
1671                         set_route(data, value);
1672         }
1673
1674         /* If non-split routed VPN does not have a default route, add it */
1675         if (!connman_provider_is_split_routing(provider) &&
1676                                                 !data->default_route_set) {
1677                 int family = connman_provider_get_family(provider);
1678                 const char *ipaddr_any = family == AF_INET6 ?
1679                                                         "::" : "0.0.0.0";
1680                 struct vpn_route def_route = {family, (char*) ipaddr_any,
1681                                                 (char*) ipaddr_any, NULL};
1682
1683                 set_route(data, &def_route);
1684         }
1685
1686         /* Split routed VPN must have at least one route to the network */
1687         if (connman_provider_is_split_routing(provider) &&
1688                                                 !check_routes(provider)) {
1689                 int err = add_network_route(data);
1690                 if (err) {
1691                         connman_warn("cannot add network route provider %p",
1692                                                                 provider);
1693                         return err;
1694                 }
1695         }
1696
1697         return 0;
1698 }
1699
1700 static struct connman_provider_driver provider_driver = {
1701         .name = "VPN",
1702         .type = CONNMAN_PROVIDER_TYPE_VPN,
1703         .probe = provider_probe,
1704         .remove = provider_remove,
1705         .connect = provider_connect,
1706         .disconnect = provider_disconnect,
1707         .set_property = set_string,
1708         .get_property = get_string,
1709         .create = create_configuration,
1710         .set_routes = set_routes,
1711         .check_routes = check_routes,
1712 };
1713
1714 static void destroy_provider(struct connection_data *data)
1715 {
1716         DBG("data %p", data);
1717
1718         if (provider_is_connected(data))
1719                 connman_provider_disconnect(data->provider);
1720
1721         connman_provider_set_data(data->provider, NULL);
1722         connman_provider_remove(data->provider);
1723         data->provider = NULL;
1724 }
1725
1726 static void connection_destroy(gpointer hash_data)
1727 {
1728         struct connection_data *data = hash_data;
1729
1730         DBG("data %p", data);
1731
1732         if (data->provider)
1733                 destroy_provider(data);
1734
1735         if (data->call) {
1736                 dbus_pending_call_cancel(data->call);
1737                 dbus_pending_call_unref(data->call);
1738         }
1739
1740         if (data->disconnect_call) {
1741                 dbus_pending_call_cancel(data->disconnect_call);
1742                 dbus_pending_call_unref(data->disconnect_call);
1743         }
1744
1745         g_free(data->service_ident);
1746         g_free(data->path);
1747         g_free(data->ident);
1748         g_free(data->state);
1749         g_free(data->type);
1750         g_free(data->name);
1751         g_free(data->host);
1752         g_strfreev(data->host_ip);
1753         g_free(data->domain);
1754         g_hash_table_destroy(data->server_routes);
1755         g_hash_table_destroy(data->user_routes);
1756         g_strfreev(data->nameservers);
1757         g_hash_table_destroy(data->setting_strings);
1758         connman_ipaddress_free(data->ip);
1759
1760         cancel_host_resolv(data);
1761
1762         g_free(data);
1763 }
1764
1765 static void vpnd_created(DBusConnection *conn, void *user_data)
1766 {
1767         DBG("connection %p", conn);
1768
1769         get_connections(user_data);
1770 }
1771
1772 static void vpnd_removed(DBusConnection *conn, void *user_data)
1773 {
1774         DBG("connection %p", conn);
1775
1776         g_hash_table_remove_all(vpn_connections);
1777 }
1778
1779 static void remove_connection(DBusConnection *conn, const char *path)
1780 {
1781         DBG("path %s", path);
1782
1783         g_hash_table_remove(vpn_connections, get_ident(path));
1784 }
1785
1786 static gboolean connection_removed(DBusConnection *conn, DBusMessage *message,
1787                                 void *user_data)
1788 {
1789         const char *path;
1790         const char *signature = DBUS_TYPE_OBJECT_PATH_AS_STRING;
1791         struct connection_data *data;
1792
1793         if (!dbus_message_has_signature(message, signature)) {
1794                 connman_error("vpn removed signature \"%s\" does not match "
1795                                                         "expected \"%s\"",
1796                         dbus_message_get_signature(message), signature);
1797                 return TRUE;
1798         }
1799
1800         dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
1801                                 DBUS_TYPE_INVALID);
1802
1803         data = g_hash_table_lookup(vpn_connections, get_ident(path));
1804         if (data)
1805                 remove_connection(conn, path);
1806
1807         return TRUE;
1808 }
1809
1810 static gboolean connection_added(DBusConnection *conn, DBusMessage *message,
1811                                 void *user_data)
1812 {
1813         DBusMessageIter iter, properties;
1814         const char *path;
1815         const char *signature = DBUS_TYPE_OBJECT_PATH_AS_STRING
1816                 DBUS_TYPE_ARRAY_AS_STRING
1817                 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1818                 DBUS_TYPE_STRING_AS_STRING
1819                 DBUS_TYPE_VARIANT_AS_STRING
1820                 DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
1821
1822         if (!dbus_message_has_signature(message, signature)) {
1823                 connman_error("vpn ConnectionAdded signature \"%s\" does not "
1824                                                 "match expected \"%s\"",
1825                         dbus_message_get_signature(message), signature);
1826                 return TRUE;
1827         }
1828
1829         DBG("");
1830
1831         if (!dbus_message_iter_init(message, &iter))
1832                 return TRUE;
1833
1834         dbus_message_iter_get_basic(&iter, &path);
1835
1836         dbus_message_iter_next(&iter);
1837         dbus_message_iter_recurse(&iter, &properties);
1838
1839         add_connection(path, &properties, user_data);
1840
1841         return TRUE;
1842 }
1843
1844 static int save_route(GHashTable *routes, int family, const char *network,
1845                         const char *netmask, const char *gateway)
1846 {
1847         struct vpn_route *route;
1848         char *key = g_strdup_printf("%d/%s/%s", family, network, netmask);
1849
1850         DBG("family %d network %s netmask %s", family, network, netmask);
1851
1852         route = g_hash_table_lookup(routes, key);
1853         if (!route) {
1854                 route = g_try_new0(struct vpn_route, 1);
1855                 if (!route) {
1856                         connman_error("out of memory");
1857                         return -ENOMEM;
1858                 }
1859
1860                 route->family = family;
1861                 route->network = g_strdup(network);
1862                 route->netmask = g_strdup(netmask);
1863                 route->gateway = g_strdup(gateway);
1864
1865                 g_hash_table_replace(routes, key, route);
1866         } else {
1867                 g_free(key);
1868                 return -EALREADY;
1869         }
1870
1871         return 0;
1872 }
1873
1874 static void change_provider_split_routing(struct connman_provider *provider,
1875                                                         bool split_routing)
1876 {
1877         struct connection_data *data;
1878         int err;
1879
1880         if (!provider)
1881                 return;
1882
1883         if (connman_provider_is_split_routing(provider) == split_routing)
1884                 return;
1885
1886         data = connman_provider_get_data(provider);
1887         if (split_routing && data && provider_is_connected(data) &&
1888                                                 !check_routes(provider)) {
1889                 err = add_network_route(data);
1890                 if (err) {
1891                         connman_warn("cannot add network route provider %p",
1892                                                                 provider);
1893                         return;
1894                 }
1895         }
1896
1897         err = connman_provider_set_split_routing(provider, split_routing);
1898         switch (err) {
1899         case 0:
1900                 /* fall through */
1901         case -EALREADY:
1902                 break;
1903         case -EINVAL:
1904                 /* fall through */
1905         case -EOPNOTSUPP:
1906                 connman_warn("cannot change split routing %d", err);
1907         default:
1908                 break;
1909         }
1910 }
1911
1912 static int read_route_dict(GHashTable *routes, DBusMessageIter *dicts)
1913 {
1914         DBusMessageIter dict;
1915         const char *network, *netmask, *gateway;
1916         int family;
1917
1918         dbus_message_iter_recurse(dicts, &dict);
1919
1920         network = netmask = gateway = NULL;
1921         family = PF_UNSPEC;
1922
1923         while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
1924
1925                 DBusMessageIter entry, value;
1926                 const char *key;
1927
1928                 dbus_message_iter_recurse(&dict, &entry);
1929                 dbus_message_iter_get_basic(&entry, &key);
1930
1931                 dbus_message_iter_next(&entry);
1932                 dbus_message_iter_recurse(&entry, &value);
1933
1934                 if (g_str_equal(key, "ProtocolFamily")) {
1935                         int pf;
1936                         dbus_message_iter_get_basic(&value, &pf);
1937                         switch (pf) {
1938                         case 4:
1939                                 family = AF_INET;
1940                                 break;
1941                         case 6:
1942                                 family = AF_INET6;
1943                                 break;
1944                         }
1945                         DBG("family %d", family);
1946                 } else if (g_str_equal(key, "Netmask")) {
1947                         dbus_message_iter_get_basic(&value, &netmask);
1948                         DBG("netmask %s", netmask);
1949                 } else if (g_str_equal(key, "Network")) {
1950                         dbus_message_iter_get_basic(&value, &network);
1951                         DBG("host %s", network);
1952                 } else if (g_str_equal(key, "Gateway")) {
1953                         dbus_message_iter_get_basic(&value, &gateway);
1954                         DBG("gateway %s", gateway);
1955                 }
1956
1957                 dbus_message_iter_next(&dict);
1958         }
1959
1960         if (!netmask || !network || !gateway) {
1961                 DBG("Value missing.");
1962                 return -EINVAL;
1963         }
1964
1965         return save_route(routes, family, network, netmask, gateway);
1966 }
1967
1968 static int routes_changed(DBusMessageIter *array, GHashTable *routes)
1969 {
1970         DBusMessageIter entry;
1971         int ret = -EINVAL;
1972
1973         if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) {
1974                 DBG("Expecting array, ignoring routes.");
1975                 return -EINVAL;
1976         }
1977
1978         while (dbus_message_iter_get_arg_type(array) == DBUS_TYPE_ARRAY) {
1979
1980                 dbus_message_iter_recurse(array, &entry);
1981
1982                 while (dbus_message_iter_get_arg_type(&entry) ==
1983                                                         DBUS_TYPE_STRUCT) {
1984                         DBusMessageIter dicts;
1985
1986                         dbus_message_iter_recurse(&entry, &dicts);
1987
1988                         while (dbus_message_iter_get_arg_type(&dicts) ==
1989                                                         DBUS_TYPE_ARRAY) {
1990                                 int err = read_route_dict(routes, &dicts);
1991                                 if (ret != 0)
1992                                         ret = err;
1993                                 dbus_message_iter_next(&dicts);
1994                         }
1995
1996                         dbus_message_iter_next(&entry);
1997                 }
1998
1999                 dbus_message_iter_next(array);
2000         }
2001
2002         return ret;
2003 }
2004
2005 static gboolean property_changed(DBusConnection *conn,
2006                                 DBusMessage *message,
2007                                 void *user_data)
2008 {
2009         const char *path = dbus_message_get_path(message);
2010         struct connection_data *data = NULL;
2011         DBusMessageIter iter, value;
2012         bool ip_set = false;
2013         int err;
2014         char *str;
2015         const char *key;
2016         const char *signature = DBUS_TYPE_STRING_AS_STRING
2017                 DBUS_TYPE_VARIANT_AS_STRING;
2018
2019         if (!dbus_message_has_signature(message, signature)) {
2020                 connman_error("vpn property signature \"%s\" does not match "
2021                                                         "expected \"%s\"",
2022                         dbus_message_get_signature(message), signature);
2023                 return TRUE;
2024         }
2025
2026         data = g_hash_table_lookup(vpn_connections, get_ident(path));
2027         if (!data)
2028                 return TRUE;
2029
2030         if (!dbus_message_iter_init(message, &iter))
2031                 return TRUE;
2032
2033         dbus_message_iter_get_basic(&iter, &key);
2034
2035         dbus_message_iter_next(&iter);
2036         dbus_message_iter_recurse(&iter, &value);
2037
2038         DBG("key %s", key);
2039
2040         if (g_str_equal(key, "State")) {
2041                 dbus_message_iter_get_basic(&value, &str);
2042
2043                 DBG("%s %s -> %s", data->path, data->state, str);
2044
2045                 if (g_str_equal(data->state, str))
2046                         return TRUE;
2047
2048                 g_free(data->state);
2049                 data->state = g_strdup(str);
2050
2051                 set_provider_state(data);
2052         } else if (g_str_equal(key, "Index")) {
2053                 dbus_message_iter_get_basic(&value, &data->index);
2054                 connman_provider_set_index(data->provider, data->index);
2055         } else if (g_str_equal(key, "IPv4")) {
2056                 err = extract_ip(&value, AF_INET, data);
2057                 ip_set = true;
2058         } else if (g_str_equal(key, "IPv6")) {
2059                 err = extract_ip(&value, AF_INET6, data);
2060                 ip_set = true;
2061         } else if (g_str_equal(key, "ServerRoutes")) {
2062                 err = routes_changed(&value, data->server_routes);
2063                 /*
2064                  * Note that the vpnd will delay the route sending a bit
2065                  * (in order to collect the routes from VPN client),
2066                  * so we might have got the State changed property before
2067                  * we got ServerRoutes. This means that we must try to set
2068                  * the routes here because they would be left unset otherwise.
2069                  */
2070                 if (err == 0)
2071                         set_routes(data->provider,
2072                                                 CONNMAN_PROVIDER_ROUTE_SERVER);
2073         } else if (g_str_equal(key, "UserRoutes")) {
2074                 err = routes_changed(&value, data->user_routes);
2075                 if (err == 0)
2076                         set_routes(data->provider,
2077                                                 CONNMAN_PROVIDER_ROUTE_USER);
2078         } else if (g_str_equal(key, "Nameservers")) {
2079                 if (extract_nameservers(&value, data) == 0 &&
2080                                                 data->nameservers)
2081                         connman_provider_set_nameservers(data->provider,
2082                                                         data->nameservers);
2083         } else if (g_str_equal(key, "Domain")) {
2084                 dbus_message_iter_get_basic(&value, &str);
2085                 g_free(data->domain);
2086                 data->domain = g_strdup(str);
2087                 connman_provider_set_domain(data->provider, data->domain);
2088         } else if (g_str_equal(key, "SplitRouting")) {
2089                 dbus_bool_t split_routing;
2090                 dbus_message_iter_get_basic(&value, &split_routing);
2091                 change_provider_split_routing(data->provider, split_routing);
2092         }
2093
2094         if (ip_set && err == 0) {
2095                 err = connman_provider_set_ipaddress(data->provider, data->ip);
2096                 if (err < 0)
2097                         DBG("setting provider IP address failed (%s/%d)",
2098                                 strerror(-err), -err);
2099         }
2100
2101         return TRUE;
2102 }
2103
2104 static int vpn_find_online_transport_cb(struct connman_service *service,
2105                                                         void *user_data)
2106 {
2107         if (connman_service_get_type(service) != CONNMAN_SERVICE_TYPE_VPN) {
2108                 switch (connman_service_get_state(service)) {
2109                 case CONNMAN_SERVICE_STATE_ONLINE:
2110                         *((struct connman_service**)user_data) = service;
2111                         return 1;
2112                 default:
2113                         break;
2114                 }
2115         }
2116
2117         return 0;
2118 }
2119
2120 static struct connman_service *vpn_find_online_transport()
2121 {
2122         struct connman_service *service = NULL;
2123
2124         connman_service_iterate_services(vpn_find_online_transport_cb,
2125                                                                 &service);
2126         return service;
2127 }
2128
2129 static bool vpn_is_valid_transport(struct connman_service *transport)
2130 {
2131         if (transport) {
2132                 struct connman_service *online;
2133
2134                 switch (connman_service_get_state(transport)) {
2135                 case CONNMAN_SERVICE_STATE_READY:
2136                         online = vpn_find_online_transport();
2137
2138                         /* Stay connected if there are no online services */
2139                         if (!online)
2140                                 return true;
2141
2142                         DBG("%s is ready, %s is online, disconnecting",
2143                                 connman_service_get_identifier(transport),
2144                                 connman_service_get_identifier(online));
2145                         break;
2146
2147                 case CONNMAN_SERVICE_STATE_ONLINE:
2148                         online = vpn_find_online_transport();
2149
2150                         /* Check if our transport is still the default */
2151                         if (online == transport)
2152                                 return true;
2153
2154                         DBG("%s is replaced by %s as default, disconnecting",
2155                                 connman_service_get_identifier(transport),
2156                                 connman_service_get_identifier(online));
2157                         break;
2158
2159                 default:
2160                         break;
2161                 }
2162         } else {
2163                 DBG("transport gone");
2164         }
2165
2166         return false;
2167 }
2168
2169 static void vpn_disconnect_check_provider(struct connection_data *data)
2170 {
2171         if (provider_is_connected(data)) {
2172                 /* With NULL service ident NULL is returned immediately */
2173                 struct connman_service *service =
2174                         connman_service_lookup_from_identifier
2175                                                 (data->service_ident);
2176
2177                 if (!vpn_is_valid_transport(service)) {
2178                         connman_provider_disconnect(data->provider);
2179                 }
2180
2181                 /* VPN moved to be split routed, default route is not set */
2182                 if (connman_provider_is_split_routing(data->provider))
2183                         data->default_route_set = false;
2184         }
2185 }
2186
2187 static void vpn_disconnect_check()
2188 {
2189         GHashTableIter iter;
2190         gpointer value;
2191
2192         DBG("");
2193         g_hash_table_iter_init(&iter, vpn_connections);
2194         while (g_hash_table_iter_next(&iter, NULL, &value))
2195                 vpn_disconnect_check_provider(value);
2196 }
2197
2198 static void vpn_service_add(struct connman_service *service, const char *name)
2199 {
2200         vpn_disconnect_check();
2201 }
2202
2203 static void vpn_service_list_changed(struct connman_service *service)
2204 {
2205         vpn_disconnect_check();
2206 }
2207
2208 static void vpn_service_state_changed(struct connman_service *service,
2209                                         enum connman_service_state state)
2210 {
2211         vpn_disconnect_check();
2212 }
2213
2214 static const struct connman_notifier vpn_notifier = {
2215         .name                   = "vpn",
2216         .priority               = CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
2217         .default_changed        = vpn_service_list_changed,
2218         .service_add            = vpn_service_add,
2219         .service_remove         = vpn_service_list_changed,
2220         .service_state_changed  = vpn_service_state_changed
2221 };
2222
2223 static int vpn_init(void)
2224 {
2225         int err;
2226
2227         connection = connman_dbus_get_connection();
2228         if (!connection)
2229                 return -EIO;
2230
2231         watch = g_dbus_add_service_watch(connection, VPN_SERVICE,
2232                         vpnd_created, vpnd_removed, &provider_driver, NULL);
2233
2234         added_watch = g_dbus_add_signal_watch(connection, VPN_SERVICE, NULL,
2235                                         VPN_MANAGER_INTERFACE,
2236                                         CONNECTION_ADDED, connection_added,
2237                                         &provider_driver, NULL);
2238
2239         removed_watch = g_dbus_add_signal_watch(connection, VPN_SERVICE, NULL,
2240                                         VPN_MANAGER_INTERFACE,
2241                                         CONNECTION_REMOVED, connection_removed,
2242                                         NULL, NULL);
2243
2244         property_watch = g_dbus_add_signal_watch(connection, VPN_SERVICE, NULL,
2245                                         VPN_CONNECTION_INTERFACE,
2246                                         PROPERTY_CHANGED, property_changed,
2247                                         NULL, NULL);
2248
2249         if (added_watch == 0 || removed_watch == 0 || property_watch == 0) {
2250                 err = -EIO;
2251                 goto remove;
2252         }
2253
2254         err = connman_provider_driver_register(&provider_driver);
2255         if (err == 0) {
2256                 vpn_connections = g_hash_table_new_full(g_str_hash,
2257                                                 g_str_equal,
2258                                                 g_free, connection_destroy);
2259
2260                 vpnd_created(connection, &provider_driver);
2261         }
2262
2263         connman_notifier_register(&vpn_notifier);
2264         return err;
2265
2266 remove:
2267         g_dbus_remove_watch(connection, watch);
2268         g_dbus_remove_watch(connection, added_watch);
2269         g_dbus_remove_watch(connection, removed_watch);
2270         g_dbus_remove_watch(connection, property_watch);
2271
2272         dbus_connection_unref(connection);
2273
2274         return err;
2275 }
2276
2277 static void vpn_exit(void)
2278 {
2279         g_dbus_remove_watch(connection, watch);
2280         g_dbus_remove_watch(connection, added_watch);
2281         g_dbus_remove_watch(connection, removed_watch);
2282         g_dbus_remove_watch(connection, property_watch);
2283
2284         connman_notifier_unregister(&vpn_notifier);
2285         connman_provider_driver_unregister(&provider_driver);
2286
2287         if (vpn_connections)
2288                 g_hash_table_destroy(vpn_connections);
2289
2290         dbus_connection_unref(connection);
2291 }
2292
2293 CONNMAN_PLUGIN_DEFINE(vpn, "VPN plugin", VERSION,
2294                 CONNMAN_PLUGIN_PRIORITY_DEFAULT, vpn_init, vpn_exit)