Imported Upstream version 1.40
[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         const 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 static int vpn_create_tun(struct vpn_provider *provider, int flags)
353 {
354         struct vpn_data *data = vpn_provider_get_data(provider);
355         struct ifreq ifr;
356         int i, fd, index;
357         int ret = 0;
358
359         if (!data)
360                 return -EISCONN;
361
362         fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
363         if (fd < 0) {
364                 i = -errno;
365                 connman_error("Failed to open /dev/net/tun: %s",
366                               strerror(errno));
367                 ret = i;
368                 goto exist_err;
369         }
370
371         memset(&ifr, 0, sizeof(ifr));
372         ifr.ifr_flags = flags | IFF_NO_PI;
373
374         for (i = 0; i < 256; i++) {
375                 sprintf(ifr.ifr_name, "vpn%d", i);
376
377                 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
378                         break;
379         }
380
381         if (i == 256) {
382                 connman_error("Failed to find available tun device");
383                 close(fd);
384                 ret = -ENODEV;
385                 goto exist_err;
386         }
387
388         data->tun_flags = flags;
389         g_free(data->if_name);
390         data->if_name = (char *)g_strdup(ifr.ifr_name);
391         if (!data->if_name) {
392                 connman_error("Failed to allocate memory");
393                 close(fd);
394                 ret = -ENOMEM;
395                 goto exist_err;
396         }
397
398         if (ioctl(fd, TUNSETPERSIST, 1)) {
399                 i = -errno;
400                 connman_error("Failed to set tun persistent: %s",
401                               strerror(errno));
402                 close(fd);
403                 ret = i;
404                 goto exist_err;
405         }
406
407         close(fd);
408
409         index = connman_inet_ifindex(data->if_name);
410         if (index < 0) {
411                 connman_error("Failed to get tun ifindex");
412                 stop_vpn(provider);
413                 ret = -EIO;
414                 goto exist_err;
415         }
416         vpn_provider_set_index(provider, index);
417
418         return 0;
419
420 exist_err:
421         return ret;
422 }
423
424 static gid_t get_gid(const char *group_name)
425 {
426         struct group *grp;
427
428         grp = vpn_util_get_group(group_name);
429         if (grp)
430                 return grp->gr_gid;
431
432         return -1;
433 }
434
435 static uid_t get_uid(const char *user_name)
436 {
437         struct passwd *pw;
438
439         pw = vpn_util_get_passwd(user_name);
440         if (pw)
441                 return pw->pw_uid;
442
443         return -1;
444 }
445
446 static gint get_supplementary_gids(gchar **groups, gid_t **gid_list)
447 {
448         gint group_count = 0;
449         gid_t *list = NULL;
450         int i;
451
452         if (groups) {
453                 for(i = 0; groups[i]; i++) {
454                         group_count++;
455
456                         list = (gid_t*)g_try_realloc(list,
457                                                 sizeof(gid_t) * group_count);
458
459                         if (!list) {
460                                 DBG("cannot allocate supplementary group list");
461                                 break;
462                         }
463
464                         list[i] = get_gid(groups[i]);
465                 }
466         }
467
468         *gid_list = list;
469
470         return group_count;
471 }
472
473 static void vpn_task_setup(gpointer user_data)
474 {
475         struct vpn_plugin_data *data;
476         uid_t uid;
477         gid_t gid;
478         gid_t *gid_list = NULL;
479         size_t gid_list_size;
480         const gchar *user;
481         const gchar *group;
482         gchar **suppl_groups;
483
484         data = user_data;
485         user = vpn_settings_get_binary_user(data);
486         group = vpn_settings_get_binary_group(data);
487         suppl_groups = vpn_settings_get_binary_supplementary_groups(data);
488
489         uid = get_uid(user);
490         gid = get_gid(group);
491         gid_list_size = get_supplementary_gids(suppl_groups, &gid_list);
492
493         DBG("vpn_task_setup uid:%d gid:%d supplementary group list size:%zu",
494                                         uid, gid, gid_list_size);
495
496
497         /* Change group if proper group name was set, requires CAP_SETGID.*/
498         if (gid > 0 && setgid(gid))
499                 connman_error("error setting gid %d %s", gid, strerror(errno));
500
501         /* Set the supplementary groups if list exists, requires CAP_SETGID. */
502         if (gid_list_size && gid_list && setgroups(gid_list_size, gid_list))
503                 connman_error("error setting gid list %s", strerror(errno));
504
505         /* Change user for the task if set, requires CAP_SETUID */
506         if (uid > 0 && setuid(uid))
507                 connman_error("error setting uid %d %s", uid, strerror(errno));
508 }
509
510
511 static gboolean update_provider_state(gpointer data)
512 {
513         struct vpn_provider *provider = data;
514         struct vpn_data *vpn_data;
515         int index;
516
517         DBG("");
518
519         vpn_data = vpn_provider_get_data(provider);
520
521         index = vpn_provider_get_index(provider);
522         DBG("index to watch %d", index);
523         vpn_provider_ref(provider);
524         vpn_data->watch = vpn_rtnl_add_newlink_watch(index,
525                                                 vpn_newlink, provider);
526         connman_inet_ifup(index);
527
528         return FALSE;
529 }
530
531 static int vpn_connect(struct vpn_provider *provider,
532                         vpn_provider_connect_cb_t cb,
533                         const char *dbus_sender, void *user_data)
534 {
535         struct vpn_data *data = vpn_provider_get_data(provider);
536         struct vpn_driver_data *vpn_driver_data;
537         struct vpn_plugin_data *vpn_plugin_data;
538         const char *name;
539         int ret = 0, tun_flags = IFF_TUN;
540         enum vpn_state state = VPN_STATE_UNKNOWN;
541
542         if (data)
543                 state = data->state;
544
545         DBG("data %p state %d", data, state);
546
547         switch (state) {
548         case VPN_STATE_UNKNOWN:
549                 data = g_try_new0(struct vpn_data, 1);
550                 if (!data)
551                         return -ENOMEM;
552
553                 data->provider = vpn_provider_ref(provider);
554                 data->watch = 0;
555                 data->flags = 0;
556                 data->task = NULL;
557
558                 vpn_provider_set_data(provider, data);
559                 /* fall through */
560
561         case VPN_STATE_DISCONNECT:
562         case VPN_STATE_IDLE:
563         case VPN_STATE_FAILURE:
564         case VPN_STATE_AUTH_FAILURE:
565                 data->state = VPN_STATE_IDLE;
566                 break;
567
568         case VPN_STATE_CONNECT:
569                 return -EINPROGRESS;
570
571         case VPN_STATE_READY:
572                 return -EISCONN;
573         }
574
575         name = vpn_provider_get_driver_name(provider);
576         if (!name)
577                 return -EINVAL;
578
579         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
580
581         if (!vpn_driver_data || !vpn_driver_data->vpn_driver) {
582                 ret = -EINVAL;
583                 goto exist_err;
584         }
585
586         if (!(vpn_driver_data->vpn_driver->flags & VPN_FLAG_NO_TUN)) {
587                 if (vpn_driver_data->vpn_driver->device_flags) {
588                         tun_flags = vpn_driver_data->vpn_driver->device_flags(provider);
589                 }
590                 ret = vpn_create_tun(provider, tun_flags);
591                 if (ret < 0)
592                         goto exist_err;
593         }
594
595
596         if (vpn_driver_data && vpn_driver_data->vpn_driver &&
597                         vpn_driver_data->vpn_driver->flags & VPN_FLAG_NO_DAEMON) {
598
599                 ret = vpn_driver_data->vpn_driver->connect(provider,
600                                         NULL, NULL, cb, dbus_sender, user_data);
601                 if (ret) {
602                         stop_vpn(provider);
603                         goto exist_err;
604                 }
605
606                 DBG("%s started with dev %s",
607                         vpn_driver_data->provider_driver.name, data->if_name);
608
609                 data->state = VPN_STATE_CONNECT;
610
611                 g_timeout_add(1, update_provider_state, provider);
612                 return -EINPROGRESS;
613         }
614
615         vpn_plugin_data =
616                 vpn_settings_get_vpn_plugin_config(vpn_driver_data->name);
617         data->task = connman_task_create(vpn_driver_data->program,
618                                         vpn_task_setup, vpn_plugin_data);
619
620         if (!data->task) {
621                 ret = -ENOMEM;
622                 stop_vpn(provider);
623                 goto exist_err;
624         }
625
626         if (connman_task_set_notify(data->task, "notify",
627                                         vpn_notify, provider)) {
628                 ret = -ENOMEM;
629                 stop_vpn(provider);
630                 connman_task_destroy(data->task);
631                 data->task = NULL;
632                 goto exist_err;
633         }
634
635         ret = vpn_driver_data->vpn_driver->connect(provider, data->task,
636                                                 data->if_name, cb, dbus_sender,
637                                                 user_data);
638         if (ret < 0 && ret != -EINPROGRESS) {
639                 stop_vpn(provider);
640                 connman_task_destroy(data->task);
641                 data->task = NULL;
642                 goto exist_err;
643         }
644
645         DBG("%s started with dev %s",
646                 vpn_driver_data->provider_driver.name, data->if_name);
647
648         data->state = VPN_STATE_CONNECT;
649
650         return -EINPROGRESS;
651
652 exist_err:
653         vpn_provider_set_index(provider, -1);
654         vpn_provider_set_data(provider, NULL);
655         vpn_provider_unref(data->provider);
656         g_free(data->if_name);
657         g_free(data);
658
659         return ret;
660 }
661
662 static int vpn_probe(struct vpn_provider *provider)
663 {
664         return 0;
665 }
666
667 static int vpn_disconnect(struct vpn_provider *provider)
668 {
669         struct vpn_data *data = vpn_provider_get_data(provider);
670         struct vpn_driver_data *vpn_driver_data;
671         const char *name;
672
673         DBG("disconnect provider %p:", provider);
674
675         if (!data)
676                 return 0;
677
678         name = vpn_provider_get_driver_name(provider);
679         if (!name)
680                 return 0;
681
682         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
683         if (vpn_driver_data->vpn_driver->disconnect)
684                 vpn_driver_data->vpn_driver->disconnect(provider);
685
686         if (data->watch != 0) {
687                 vpn_provider_unref(provider);
688                 vpn_rtnl_remove_watch(data->watch);
689                 data->watch = 0;
690         }
691
692         data->state = VPN_STATE_DISCONNECT;
693
694         if (!vpn_driver_data->vpn_driver->disconnect) {
695                 DBG("Driver has no disconnect() implementation, set provider "
696                                         "state to disconnect.");
697                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_DISCONNECT);
698         }
699
700         if (data->task)
701                 connman_task_stop(data->task);
702
703         return 0;
704 }
705
706 static int vpn_remove(struct vpn_provider *provider)
707 {
708         struct vpn_data *data;
709         struct vpn_driver_data *driver_data;
710         const char *name;
711         int err = 0;
712
713         data = vpn_provider_get_data(provider);
714         name = vpn_provider_get_driver_name(provider);
715
716         if (!data)
717                 goto call_remove;
718
719         if (data->watch != 0) {
720                 vpn_provider_unref(provider);
721                 vpn_rtnl_remove_watch(data->watch);
722                 data->watch = 0;
723         }
724
725         if (data->task)
726                 connman_task_stop(data->task);
727
728         g_usleep(G_USEC_PER_SEC);
729         stop_vpn(provider);
730
731 call_remove:
732         if (!name)
733                 return 0;
734
735         driver_data = g_hash_table_lookup(driver_hash, name);
736
737         if (driver_data && driver_data->vpn_driver->remove)
738                 err = driver_data->vpn_driver->remove(provider);
739
740         if (err)
741                 DBG("%p vpn_driver->remove() returned %d", provider, err);
742
743         return err;
744 }
745
746 static int vpn_save(struct vpn_provider *provider, GKeyFile *keyfile)
747 {
748         struct vpn_driver_data *vpn_driver_data;
749         const char *name;
750
751         name = vpn_provider_get_driver_name(provider);
752         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
753         if (vpn_driver_data &&
754                         vpn_driver_data->vpn_driver->save)
755                 return vpn_driver_data->vpn_driver->save(provider, keyfile);
756
757         return 0;
758 }
759
760 static int vpn_route_env_parse(struct vpn_provider *provider, const char *key,
761                         int *family, unsigned long *idx,
762                         enum vpn_provider_route_type *type)
763 {
764         struct vpn_driver_data *vpn_driver_data = NULL;
765         const char *name = NULL;
766
767         if (!provider)
768                 return -EINVAL;
769
770         name = vpn_provider_get_driver_name(provider);
771         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
772
773         if (vpn_driver_data && vpn_driver_data->vpn_driver->route_env_parse)
774                 return vpn_driver_data->vpn_driver->route_env_parse(provider, key,
775                         family, idx, type);
776
777         return 0;
778 }
779
780 int vpn_register(const char *name, const struct vpn_driver *vpn_driver,
781                         const char *program)
782 {
783         struct vpn_driver_data *data;
784
785         data = g_try_new0(struct vpn_driver_data, 1);
786         if (!data)
787                 return -ENOMEM;
788
789         data->name = name;
790         data->program = program;
791
792         if (vpn_settings_parse_vpn_plugin_config(data->name) != 0)
793                 DBG("No configuration provided for VPN plugin %s", data->name);
794
795         data->vpn_driver = vpn_driver;
796
797         data->provider_driver.name = name;
798         data->provider_driver.disconnect = vpn_disconnect;
799         data->provider_driver.connect = vpn_connect;
800         data->provider_driver.probe = vpn_probe;
801         data->provider_driver.remove = vpn_remove;
802         data->provider_driver.save = vpn_save;
803         data->provider_driver.set_state = vpn_set_state;
804         data->provider_driver.route_env_parse = vpn_route_env_parse;
805
806         if (!driver_hash)
807                 driver_hash = g_hash_table_new_full(g_str_hash,
808                                                         g_str_equal,
809                                                         NULL, g_free);
810
811         if (!driver_hash) {
812                 connman_error("driver_hash not initialized for %s", name);
813                 g_free(data);
814                 return -ENOMEM;
815         }
816
817         g_hash_table_replace(driver_hash, (char *)name, data);
818
819         vpn_provider_driver_register(&data->provider_driver);
820
821         return 0;
822 }
823
824 void vpn_unregister(const char *name)
825 {
826         struct vpn_driver_data *data;
827
828         data = g_hash_table_lookup(driver_hash, name);
829         if (!data)
830                 return;
831
832         vpn_provider_driver_unregister(&data->provider_driver);
833         vpn_settings_delete_vpn_plugin_config(name);
834
835         g_hash_table_remove(driver_hash, name);
836
837         if (g_hash_table_size(driver_hash) == 0)
838                 g_hash_table_destroy(driver_hash);
839 }