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