Add support to get PMF information
[platform/upstream/connman.git] / vpn / plugins / vpn.c
1 /*
2  *
3  *  ConnMan VPN daemon
4  *
5  *  Copyright (C) 2007-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 <fcntl.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #include <stdio.h>
31 #include <errno.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <linux/if_tun.h>
35 #include <net/if.h>
36 #include <sys/types.h>
37 #include <pwd.h>
38 #include <grp.h>
39
40 #include <dbus/dbus.h>
41
42 #include <glib/gprintf.h>
43
44 #include <connman/log.h>
45 #include <connman/rtnl.h>
46 #include <connman/task.h>
47 #include <connman/inet.h>
48
49 #include "../vpn-rtnl.h"
50 #include "../vpn-provider.h"
51
52 #include "vpn.h"
53 #include "../vpn.h"
54
55 struct vpn_data {
56         struct vpn_provider *provider;
57         char *if_name;
58         unsigned flags;
59         unsigned int watch;
60         enum vpn_state state;
61         struct connman_task *task;
62         int tun_flags;
63 };
64
65 struct vpn_driver_data {
66         const char *name;
67         const char *program;
68         struct vpn_driver *vpn_driver;
69         struct vpn_provider_driver provider_driver;
70 };
71
72 GHashTable *driver_hash = NULL;
73
74 static int stop_vpn(struct vpn_provider *provider)
75 {
76         struct vpn_data *data = vpn_provider_get_data(provider);
77         struct vpn_driver_data *vpn_driver_data;
78         const char *name;
79         struct ifreq ifr;
80         int fd, err;
81
82         if (!data)
83                 return -EINVAL;
84
85         name = vpn_provider_get_driver_name(provider);
86         if (!name)
87                 return -EINVAL;
88
89         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
90
91         if (vpn_driver_data && vpn_driver_data->vpn_driver &&
92                         vpn_driver_data->vpn_driver->flags & VPN_FLAG_NO_TUN) {
93                 vpn_driver_data->vpn_driver->disconnect(data->provider);
94                 return 0;
95         }
96
97         memset(&ifr, 0, sizeof(ifr));
98         ifr.ifr_flags = data->tun_flags | IFF_NO_PI;
99         sprintf(ifr.ifr_name, "%s", data->if_name);
100
101         fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
102         if (fd < 0) {
103                 err = -errno;
104                 connman_error("Failed to open /dev/net/tun to device %s: %s",
105                               data->if_name, strerror(errno));
106                 return err;
107         }
108
109         if (ioctl(fd, TUNSETIFF, (void *)&ifr)) {
110                 err = -errno;
111                 connman_error("Failed to TUNSETIFF for device %s to it: %s",
112                               data->if_name, strerror(errno));
113                 close(fd);
114                 return err;
115         }
116
117         if (ioctl(fd, TUNSETPERSIST, 0)) {
118                 err = -errno;
119                 connman_error("Failed to set tun device %s nonpersistent: %s",
120                               data->if_name, strerror(errno));
121                 close(fd);
122                 return err;
123         }
124         close(fd);
125         DBG("Killed tun device %s", data->if_name);
126         return 0;
127 }
128
129 void vpn_died(struct connman_task *task, int exit_code, void *user_data)
130 {
131         struct vpn_provider *provider = user_data;
132         struct vpn_data *data = vpn_provider_get_data(provider);
133         int state = VPN_STATE_FAILURE;
134         enum vpn_provider_error ret;
135
136         DBG("provider %p data %p", provider, data);
137
138         if (!data)
139                 goto vpn_exit;
140
141         /* The task may die after we have already started the new one */
142         if (data->task != task)
143                 goto done;
144
145         state = data->state;
146
147         stop_vpn(provider);
148         vpn_provider_set_data(provider, NULL);
149
150         if (data->watch != 0) {
151                 vpn_rtnl_remove_watch(data->watch);
152                 data->watch = 0;
153                 vpn_provider_unref(provider);
154         }
155
156 vpn_exit:
157         if (state != VPN_STATE_READY && state != VPN_STATE_DISCONNECT) {
158                 const char *name;
159                 struct vpn_driver_data *vpn_data = NULL;
160
161                 name = vpn_provider_get_driver_name(provider);
162                 if (name)
163                         vpn_data = g_hash_table_lookup(driver_hash, name);
164
165                 if (vpn_data &&
166                                 vpn_data->vpn_driver->error_code)
167                         ret = vpn_data->vpn_driver->error_code(provider,
168                                         exit_code);
169                 else
170                         ret = VPN_PROVIDER_ERROR_UNKNOWN;
171
172                 vpn_provider_indicate_error(provider, ret);
173         } else
174                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_IDLE);
175
176         vpn_provider_set_index(provider, -1);
177
178         if (data) {
179                 vpn_provider_unref(data->provider);
180                 g_free(data->if_name);
181                 g_free(data);
182         }
183
184 done:
185         connman_task_destroy(task);
186 }
187
188 int vpn_set_ifname(struct vpn_provider *provider, const char *ifname)
189 {
190         struct vpn_data *data = vpn_provider_get_data(provider);
191         int index;
192
193         if (!ifname || !data)
194                 return  -EIO;
195
196         index = connman_inet_ifindex(ifname);
197         if (index < 0)
198                 return  -EIO;
199
200         if (data->if_name)
201                 g_free(data->if_name);
202
203         data->if_name = (char *)g_strdup(ifname);
204         vpn_provider_set_index(provider, index);
205
206         return 0;
207 }
208
209 static int vpn_set_state(struct vpn_provider *provider,
210                                                 enum vpn_provider_state state)
211 {
212         struct vpn_data *data = vpn_provider_get_data(provider);
213         if (!data)
214                 return -EINVAL;
215
216         switch (state) {
217         case VPN_PROVIDER_STATE_UNKNOWN:
218                 return -EINVAL;
219         case VPN_PROVIDER_STATE_IDLE:
220                 data->state = VPN_STATE_IDLE;
221                 break;
222         case VPN_PROVIDER_STATE_CONNECT:
223         case VPN_PROVIDER_STATE_READY:
224                 data->state = VPN_STATE_CONNECT;
225                 break;
226         case VPN_PROVIDER_STATE_DISCONNECT:
227                 data->state = VPN_STATE_DISCONNECT;
228                 break;
229         case VPN_PROVIDER_STATE_FAILURE:
230                 data->state = VPN_STATE_FAILURE;
231                 break;
232         }
233
234         return 0;
235 }
236
237 static void vpn_newlink(unsigned flags, unsigned change, void *user_data)
238 {
239         struct vpn_provider *provider = user_data;
240         struct vpn_data *data = vpn_provider_get_data(provider);
241
242         if ((data->flags & IFF_UP) != (flags & IFF_UP)) {
243                 if (flags & IFF_UP) {
244                         data->state = VPN_STATE_READY;
245                         vpn_provider_set_state(provider,
246                                         VPN_PROVIDER_STATE_READY);
247                 }
248         }
249         data->flags = flags;
250 }
251
252 static DBusMessage *vpn_notify(struct connman_task *task,
253                         DBusMessage *msg, void *user_data)
254 {
255         struct vpn_provider *provider = user_data;
256         struct vpn_data *data;
257         struct vpn_driver_data *vpn_driver_data;
258         const char *name;
259         int state, index, err;
260
261         data = vpn_provider_get_data(provider);
262
263         name = vpn_provider_get_driver_name(provider);
264
265         if (!name) {
266                 DBG("Cannot find VPN driver for provider %p", provider);
267                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
268                 return NULL;
269         }
270
271         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
272         if (!vpn_driver_data) {
273                 DBG("Cannot find VPN driver data for name %s", name);
274                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
275                 return NULL;
276         }
277
278         state = vpn_driver_data->vpn_driver->notify(msg, provider);
279
280         DBG("provider %p driver %s state %d", provider, name, state);
281
282         switch (state) {
283         case VPN_STATE_CONNECT:
284         case VPN_STATE_READY:
285                 if (data->state == VPN_STATE_READY) {
286                         /*
287                          * This is the restart case, in which case we must
288                          * just set the IP address.
289                          *
290                          * We need to remove first the old address, just
291                          * replacing the old address will not work as expected
292                          * because the old address will linger in the interface
293                          * and not disappear so the clearing is needed here.
294                          *
295                          * Also the state must change, otherwise the routes
296                          * will not be set properly.
297                          */
298                         vpn_provider_set_state(provider,
299                                                 VPN_PROVIDER_STATE_CONNECT);
300
301                         vpn_provider_clear_address(provider, AF_INET);
302                         vpn_provider_clear_address(provider, AF_INET6);
303
304                         vpn_provider_change_address(provider);
305                         vpn_provider_set_state(provider,
306                                                 VPN_PROVIDER_STATE_READY);
307                         break;
308                 }
309
310                 index = vpn_provider_get_index(provider);
311                 vpn_provider_ref(provider);
312                 data->watch = vpn_rtnl_add_newlink_watch(index,
313                                                      vpn_newlink, provider);
314                 err = connman_inet_ifup(index);
315                 if (err < 0) {
316                         if (err == -EALREADY) {
317                                 /*
318                                  * So the interface is up already, that is just
319                                  * great. Unfortunately in this case the
320                                  * newlink watch might not have been called at
321                                  * all. We must manually call it here so that
322                                  * the provider can go to ready state and the
323                                  * routes are setup properly. Also reset flags
324                                  * so vpn_newlink() can handle the change.
325                                  */
326                                 data->flags = 0;
327                                 vpn_newlink(IFF_UP, 0, provider);
328                         } else {
329                                 DBG("Cannot take interface %d up err %d/%s",
330                                         index, -err, strerror(-err));
331                         }
332                 }
333                 break;
334
335         case VPN_STATE_UNKNOWN:
336         case VPN_STATE_IDLE:
337         case VPN_STATE_DISCONNECT:
338         case VPN_STATE_FAILURE:
339                 vpn_provider_set_state(provider,
340                                         VPN_PROVIDER_STATE_DISCONNECT);
341                 break;
342
343         case VPN_STATE_AUTH_FAILURE:
344                 vpn_provider_indicate_error(provider,
345                                         VPN_PROVIDER_ERROR_AUTH_FAILED);
346                 break;
347         }
348
349         return NULL;
350 }
351
352 #if defined TIZEN_EXT
353 static void vpn_event(struct vpn_provider *provider, int state)
354 {
355         struct vpn_driver_data *vpn_driver_data;
356         const char *name;
357
358         name = vpn_provider_get_driver_name(provider);
359         if (!name) {
360                 DBG("Cannot find VPN driver for provider %p", provider);
361                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
362                 return;
363         }
364
365         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
366         if (!vpn_driver_data) {
367                 DBG("Cannot find VPN driver data for name %s", name);
368                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
369                 return;
370         }
371
372         DBG("provider %p driver %s state %d", provider, name, state);
373
374         switch (state) {
375         case VPN_STATE_CONNECT:
376                 vpn_provider_set_state(provider,
377                                 VPN_PROVIDER_STATE_CONNECT);
378                 break;
379         case VPN_STATE_READY:
380                 vpn_provider_set_state(provider,
381                                 VPN_PROVIDER_STATE_READY);
382                 break;
383
384         case VPN_STATE_UNKNOWN:
385         case VPN_STATE_IDLE:
386         case VPN_STATE_DISCONNECT:
387         case VPN_STATE_FAILURE:
388                 vpn_provider_set_state(provider,
389                                         VPN_PROVIDER_STATE_DISCONNECT);
390                 break;
391
392         case VPN_STATE_AUTH_FAILURE:
393                 vpn_provider_indicate_error(provider,
394                                         VPN_PROVIDER_ERROR_AUTH_FAILED);
395                 break;
396         }
397
398         return;
399 }
400 #endif
401
402 static int vpn_create_tun(struct vpn_provider *provider, int flags)
403 {
404         struct vpn_data *data = vpn_provider_get_data(provider);
405         struct ifreq ifr;
406         int i, fd, index;
407         int ret = 0;
408
409         if (!data)
410                 return -EISCONN;
411
412         fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
413         if (fd < 0) {
414                 i = -errno;
415                 connman_error("Failed to open /dev/net/tun: %s",
416                               strerror(errno));
417                 ret = i;
418                 goto exist_err;
419         }
420
421         memset(&ifr, 0, sizeof(ifr));
422         ifr.ifr_flags = flags | IFF_NO_PI;
423
424         for (i = 0; i < 256; i++) {
425                 sprintf(ifr.ifr_name, "vpn%d", i);
426
427                 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
428                         break;
429         }
430
431         if (i == 256) {
432                 connman_error("Failed to find available tun device");
433                 close(fd);
434                 ret = -ENODEV;
435                 goto exist_err;
436         }
437
438         data->tun_flags = flags;
439         g_free(data->if_name);
440         data->if_name = (char *)g_strdup(ifr.ifr_name);
441         if (!data->if_name) {
442                 connman_error("Failed to allocate memory");
443                 close(fd);
444                 ret = -ENOMEM;
445                 goto exist_err;
446         }
447
448         if (ioctl(fd, TUNSETPERSIST, 1)) {
449                 i = -errno;
450                 connman_error("Failed to set tun persistent: %s",
451                               strerror(errno));
452                 close(fd);
453                 ret = i;
454                 goto exist_err;
455         }
456
457         close(fd);
458
459         index = connman_inet_ifindex(data->if_name);
460         if (index < 0) {
461                 connman_error("Failed to get tun ifindex");
462                 stop_vpn(provider);
463                 ret = -EIO;
464                 goto exist_err;
465         }
466         vpn_provider_set_index(provider, index);
467
468         return 0;
469
470 exist_err:
471         return ret;
472 }
473
474 static gboolean is_numeric(const char *str)
475 {
476         gint i;
477
478         if(!str || !(*str))
479                 return false;
480
481         for(i = 0; str[i] ; i++) {
482                 if(!g_ascii_isdigit(str[i]))
483                         return false;
484         }
485
486         return true;
487 }
488
489 static gint get_gid(const char *group_name)
490 {
491         gint gid = -1;
492         struct group *grp;
493
494         if(!group_name || !(*group_name))
495                 return gid;
496
497         if (is_numeric(group_name)) {
498                 gid_t group_id = (gid_t)g_ascii_strtoull(group_name, NULL, 10);
499                 grp = getgrgid(group_id);
500         } else {
501                 grp = getgrnam(group_name);
502         }
503
504         if (grp)
505                 gid = grp->gr_gid;
506
507         return gid;
508 }
509
510 static gint get_uid(const char *user_name)
511 {
512         gint uid = -1;
513         struct passwd *pw;
514
515         if(!user_name || !(*user_name))
516                 return uid;
517
518         if (is_numeric(user_name)) {
519                 uid_t user_id = (uid_t)g_ascii_strtoull(user_name, NULL, 10);
520                 pw = getpwuid(user_id);
521         } else {
522                 pw = getpwnam(user_name);
523         }
524
525         if (pw)
526                 uid = pw->pw_uid;
527
528         return uid;
529 }
530
531 static gint get_supplementary_gids(gchar **groups, gid_t **gid_list)
532 {
533         gint group_count = 0;
534         gid_t *list = NULL;
535         int i;
536
537         if (groups) {
538                 for(i = 0; groups[i]; i++) {
539                         group_count++;
540
541                         list = (gid_t*)g_try_realloc(list,
542                                                 sizeof(gid_t) * group_count);
543
544                         if (!list) {
545                                 DBG("cannot allocate supplementary group list");
546                                 break;
547                         }
548
549                         list[i] = get_gid(groups[i]);
550                 }
551         }
552
553         *gid_list = list;
554
555         return group_count;
556 }
557
558 static void vpn_task_setup(gpointer user_data)
559 {
560         struct vpn_plugin_data *data;
561         gint uid;
562         gint gid;
563         gid_t *gid_list = NULL;
564         size_t gid_list_size;
565         const gchar *user;
566         const gchar *group;
567         gchar **suppl_groups;
568
569         data = user_data;
570         user = vpn_settings_get_binary_user(data);
571         group = vpn_settings_get_binary_group(data);
572         suppl_groups = vpn_settings_get_binary_supplementary_groups(data);
573
574         uid = get_uid(user);
575         gid = get_gid(group);
576         gid_list_size = get_supplementary_gids(suppl_groups, &gid_list);
577
578         DBG("vpn_task_setup uid:%d gid:%d supplementary group list size:%zu",
579                                         uid, gid, gid_list_size);
580
581
582         /* Change group if proper group name was set, requires CAP_SETGID.*/
583         if (gid > 0 && setgid(gid))
584                 connman_error("error setting gid %d %s", gid, strerror(errno));
585
586         /* Set the supplementary groups if list exists, requires CAP_SETGID. */
587         if (gid_list_size && gid_list && setgroups(gid_list_size, gid_list))
588                 connman_error("error setting gid list %s", strerror(errno));
589
590         /* Change user for the task if set, requires CAP_SETUID */
591         if (uid > 0 && setuid(uid))
592                 connman_error("error setting uid %d %s", uid, strerror(errno));
593 }
594
595
596 static gboolean update_provider_state(gpointer data)
597 {
598         struct vpn_provider *provider = data;
599         struct vpn_data *vpn_data;
600         int index;
601
602         DBG("");
603
604         vpn_data = vpn_provider_get_data(provider);
605
606         index = vpn_provider_get_index(provider);
607         DBG("index to watch %d", index);
608         vpn_provider_ref(provider);
609         vpn_data->watch = vpn_rtnl_add_newlink_watch(index,
610                                                 vpn_newlink, provider);
611         connman_inet_ifup(index);
612
613         return FALSE;
614 }
615
616 static int vpn_connect(struct vpn_provider *provider,
617                         vpn_provider_connect_cb_t cb,
618                         const char *dbus_sender, void *user_data)
619 {
620         struct vpn_data *data = vpn_provider_get_data(provider);
621         struct vpn_driver_data *vpn_driver_data;
622         struct vpn_plugin_data *vpn_plugin_data;
623         const char *name;
624         int ret = 0, tun_flags = IFF_TUN;
625         enum vpn_state state = VPN_STATE_UNKNOWN;
626
627         if (data)
628                 state = data->state;
629
630         DBG("data %p state %d", data, state);
631
632         switch (state) {
633         case VPN_STATE_UNKNOWN:
634                 data = g_try_new0(struct vpn_data, 1);
635                 if (!data)
636                         return -ENOMEM;
637
638                 data->provider = vpn_provider_ref(provider);
639                 data->watch = 0;
640                 data->flags = 0;
641                 data->task = NULL;
642
643                 vpn_provider_set_data(provider, data);
644                 /* fall through */
645
646         case VPN_STATE_DISCONNECT:
647         case VPN_STATE_IDLE:
648         case VPN_STATE_FAILURE:
649         case VPN_STATE_AUTH_FAILURE:
650                 data->state = VPN_STATE_IDLE;
651                 break;
652
653         case VPN_STATE_CONNECT:
654                 return -EINPROGRESS;
655
656         case VPN_STATE_READY:
657                 return -EISCONN;
658         }
659
660         name = vpn_provider_get_driver_name(provider);
661         if (!name)
662                 return -EINVAL;
663
664         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
665
666         if (!vpn_driver_data || !vpn_driver_data->vpn_driver) {
667                 ret = -EINVAL;
668                 goto exist_err;
669         }
670
671         if (!(vpn_driver_data->vpn_driver->flags & VPN_FLAG_NO_TUN)) {
672                 if (vpn_driver_data->vpn_driver->device_flags) {
673                         tun_flags = vpn_driver_data->vpn_driver->device_flags(provider);
674                 }
675                 ret = vpn_create_tun(provider, tun_flags);
676                 if (ret < 0)
677                         goto exist_err;
678         }
679
680
681         if (vpn_driver_data && vpn_driver_data->vpn_driver &&
682                         vpn_driver_data->vpn_driver->flags & VPN_FLAG_NO_DAEMON) {
683
684                 ret = vpn_driver_data->vpn_driver->connect(provider,
685                                                 NULL, NULL, NULL, NULL, NULL);
686                 if (ret) {
687                         stop_vpn(provider);
688                         goto exist_err;
689                 }
690
691                 DBG("%s started with dev %s",
692                         vpn_driver_data->provider_driver.name, data->if_name);
693
694                 data->state = VPN_STATE_CONNECT;
695
696                 g_timeout_add(1, update_provider_state, provider);
697                 return -EINPROGRESS;
698         }
699
700         vpn_plugin_data =
701                 vpn_settings_get_vpn_plugin_config(vpn_driver_data->name);
702         data->task = connman_task_create(vpn_driver_data->program,
703                                         vpn_task_setup, vpn_plugin_data);
704
705         if (!data->task) {
706                 ret = -ENOMEM;
707                 stop_vpn(provider);
708                 goto exist_err;
709         }
710
711         if (connman_task_set_notify(data->task, "notify",
712                                         vpn_notify, provider)) {
713                 ret = -ENOMEM;
714                 stop_vpn(provider);
715                 connman_task_destroy(data->task);
716                 data->task = NULL;
717                 goto exist_err;
718         }
719
720
721 #if defined TIZEN_EXT
722         if(vpn_driver_data->vpn_driver->set_event_cb)
723                 vpn_driver_data->vpn_driver->set_event_cb(vpn_event, provider);
724 #endif
725
726         ret = vpn_driver_data->vpn_driver->connect(provider, data->task,
727                                                 data->if_name, cb, dbus_sender,
728                                                 user_data);
729         if (ret < 0 && ret != -EINPROGRESS) {
730                 stop_vpn(provider);
731                 connman_task_destroy(data->task);
732                 data->task = NULL;
733                 goto exist_err;
734         }
735
736         DBG("%s started with dev %s",
737                 vpn_driver_data->provider_driver.name, data->if_name);
738
739         data->state = VPN_STATE_CONNECT;
740
741         return -EINPROGRESS;
742
743 exist_err:
744         vpn_provider_set_index(provider, -1);
745         vpn_provider_set_data(provider, NULL);
746         vpn_provider_unref(data->provider);
747         g_free(data->if_name);
748         g_free(data);
749
750         return ret;
751 }
752
753 static int vpn_probe(struct vpn_provider *provider)
754 {
755         return 0;
756 }
757
758 static int vpn_disconnect(struct vpn_provider *provider)
759 {
760         struct vpn_data *data = vpn_provider_get_data(provider);
761         struct vpn_driver_data *vpn_driver_data;
762         const char *name;
763
764         DBG("disconnect provider %p:", provider);
765
766         if (!data)
767                 return 0;
768
769         name = vpn_provider_get_driver_name(provider);
770         if (!name)
771                 return 0;
772
773         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
774         if (vpn_driver_data->vpn_driver->disconnect)
775                 vpn_driver_data->vpn_driver->disconnect(provider);
776
777         if (data->watch != 0) {
778                 vpn_provider_unref(provider);
779                 vpn_rtnl_remove_watch(data->watch);
780                 data->watch = 0;
781         }
782
783         data->state = VPN_STATE_DISCONNECT;
784
785         if (!vpn_driver_data->vpn_driver->disconnect) {
786                 DBG("Driver has no disconnect() implementation, set provider "
787                                         "state to disconnect.");
788                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_DISCONNECT);
789         }
790
791         if (data->task)
792                 connman_task_stop(data->task);
793
794         return 0;
795 }
796
797 static int vpn_remove(struct vpn_provider *provider)
798 {
799         struct vpn_data *data;
800         struct vpn_driver_data *driver_data;
801         const char *name;
802         int err = 0;
803
804         data = vpn_provider_get_data(provider);
805         name = vpn_provider_get_driver_name(provider);
806
807         if (!data)
808                 goto call_remove;
809
810         if (data->watch != 0) {
811                 vpn_provider_unref(provider);
812                 vpn_rtnl_remove_watch(data->watch);
813                 data->watch = 0;
814         }
815
816         if (data->task)
817                 connman_task_stop(data->task);
818
819         g_usleep(G_USEC_PER_SEC);
820         stop_vpn(provider);
821
822 call_remove:
823         if (!name)
824                 return 0;
825
826         driver_data = g_hash_table_lookup(driver_hash, name);
827
828         if (driver_data && driver_data->vpn_driver->remove)
829                 err = driver_data->vpn_driver->remove(provider);
830
831         if (err)
832                 DBG("%p vpn_driver->remove() returned %d", provider, err);
833
834         return err;
835 }
836
837 static int vpn_save(struct vpn_provider *provider, GKeyFile *keyfile)
838 {
839         struct vpn_driver_data *vpn_driver_data;
840         const char *name;
841
842         name = vpn_provider_get_driver_name(provider);
843         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
844         if (vpn_driver_data &&
845                         vpn_driver_data->vpn_driver->save)
846                 return vpn_driver_data->vpn_driver->save(provider, keyfile);
847
848         return 0;
849 }
850
851 static int vpn_route_env_parse(struct vpn_provider *provider, const char *key,
852                         int *family, unsigned long *idx,
853                         enum vpn_provider_route_type *type)
854 {
855         struct vpn_driver_data *vpn_driver_data = NULL;
856         const char *name = NULL;
857
858         if (!provider)
859                 return -EINVAL;
860
861         name = vpn_provider_get_driver_name(provider);
862         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
863
864         if (vpn_driver_data && vpn_driver_data->vpn_driver->route_env_parse)
865                 return vpn_driver_data->vpn_driver->route_env_parse(provider, key,
866                         family, idx, type);
867
868         return 0;
869 }
870
871 int vpn_register(const char *name, struct vpn_driver *vpn_driver,
872                         const char *program)
873 {
874         struct vpn_driver_data *data;
875
876         data = g_try_new0(struct vpn_driver_data, 1);
877         if (!data)
878                 return -ENOMEM;
879
880         data->name = name;
881         data->program = program;
882
883         if (vpn_settings_parse_vpn_plugin_config(data->name) != 0)
884                 DBG("No configuration provided for VPN plugin %s", data->name);
885
886         data->vpn_driver = vpn_driver;
887
888         data->provider_driver.name = name;
889         data->provider_driver.disconnect = vpn_disconnect;
890         data->provider_driver.connect = vpn_connect;
891         data->provider_driver.probe = vpn_probe;
892         data->provider_driver.remove = vpn_remove;
893         data->provider_driver.save = vpn_save;
894         data->provider_driver.set_state = vpn_set_state;
895         data->provider_driver.route_env_parse = vpn_route_env_parse;
896
897         if (!driver_hash)
898                 driver_hash = g_hash_table_new_full(g_str_hash,
899                                                         g_str_equal,
900                                                         NULL, g_free);
901
902         if (!driver_hash) {
903                 connman_error("driver_hash not initialized for %s", name);
904                 g_free(data);
905                 return -ENOMEM;
906         }
907
908         g_hash_table_replace(driver_hash, (char *)name, data);
909
910         vpn_provider_driver_register(&data->provider_driver);
911
912         return 0;
913 }
914
915 void vpn_unregister(const char *name)
916 {
917         struct vpn_driver_data *data;
918
919         data = g_hash_table_lookup(driver_hash, name);
920         if (!data)
921                 return;
922
923         vpn_provider_driver_unregister(&data->provider_driver);
924         vpn_settings_delete_vpn_plugin_config(name);
925
926         g_hash_table_remove(driver_hash, name);
927
928         if (g_hash_table_size(driver_hash) == 0)
929                 g_hash_table_destroy(driver_hash);
930 }