5 * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
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.
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.
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
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <linux/if_tun.h>
36 #include <sys/types.h>
40 #include <dbus/dbus.h>
42 #include <glib/gprintf.h>
44 #include <connman/log.h>
45 #include <connman/rtnl.h>
46 #include <connman/task.h>
47 #include <connman/inet.h>
49 #include "../vpn-rtnl.h"
50 #include "../vpn-provider.h"
56 struct vpn_provider *provider;
61 struct connman_task *task;
65 struct vpn_driver_data {
68 struct vpn_driver *vpn_driver;
69 struct vpn_provider_driver provider_driver;
72 GHashTable *driver_hash = NULL;
74 static int stop_vpn(struct vpn_provider *provider)
76 struct vpn_data *data = vpn_provider_get_data(provider);
77 struct vpn_driver_data *vpn_driver_data;
85 name = vpn_provider_get_driver_name(provider);
89 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
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);
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);
101 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
104 connman_error("Failed to open /dev/net/tun to device %s: %s",
105 data->if_name, strerror(errno));
109 if (ioctl(fd, TUNSETIFF, (void *)&ifr)) {
111 connman_error("Failed to TUNSETIFF for device %s to it: %s",
112 data->if_name, strerror(errno));
117 if (ioctl(fd, TUNSETPERSIST, 0)) {
119 connman_error("Failed to set tun device %s nonpersistent: %s",
120 data->if_name, strerror(errno));
125 DBG("Killed tun device %s", data->if_name);
129 void vpn_died(struct connman_task *task, int exit_code, void *user_data)
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;
136 DBG("provider %p data %p", provider, data);
141 /* The task may die after we have already started the new one */
142 if (data->task != task)
148 vpn_provider_set_data(provider, NULL);
150 if (data->watch != 0) {
151 vpn_rtnl_remove_watch(data->watch);
153 vpn_provider_unref(provider);
157 if (state != VPN_STATE_READY && state != VPN_STATE_DISCONNECT) {
159 struct vpn_driver_data *vpn_data = NULL;
161 name = vpn_provider_get_driver_name(provider);
163 vpn_data = g_hash_table_lookup(driver_hash, name);
166 vpn_data->vpn_driver->error_code)
167 ret = vpn_data->vpn_driver->error_code(provider,
170 ret = VPN_PROVIDER_ERROR_UNKNOWN;
172 vpn_provider_indicate_error(provider, ret);
174 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_IDLE);
176 vpn_provider_set_index(provider, -1);
179 vpn_provider_unref(data->provider);
180 g_free(data->if_name);
185 connman_task_destroy(task);
188 int vpn_set_ifname(struct vpn_provider *provider, const char *ifname)
190 struct vpn_data *data = vpn_provider_get_data(provider);
193 if (!ifname || !data)
196 index = connman_inet_ifindex(ifname);
201 g_free(data->if_name);
203 data->if_name = (char *)g_strdup(ifname);
204 vpn_provider_set_index(provider, index);
209 static int vpn_set_state(struct vpn_provider *provider,
210 enum vpn_provider_state state)
212 struct vpn_data *data = vpn_provider_get_data(provider);
217 case VPN_PROVIDER_STATE_UNKNOWN:
219 case VPN_PROVIDER_STATE_IDLE:
220 data->state = VPN_STATE_IDLE;
222 case VPN_PROVIDER_STATE_CONNECT:
223 case VPN_PROVIDER_STATE_READY:
224 data->state = VPN_STATE_CONNECT;
226 case VPN_PROVIDER_STATE_DISCONNECT:
227 data->state = VPN_STATE_DISCONNECT;
229 case VPN_PROVIDER_STATE_FAILURE:
230 data->state = VPN_STATE_FAILURE;
237 static void vpn_newlink(unsigned flags, unsigned change, void *user_data)
239 struct vpn_provider *provider = user_data;
240 struct vpn_data *data = vpn_provider_get_data(provider);
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);
252 static DBusMessage *vpn_notify(struct connman_task *task,
253 DBusMessage *msg, void *user_data)
255 struct vpn_provider *provider = user_data;
256 struct vpn_data *data;
257 struct vpn_driver_data *vpn_driver_data;
259 int state, index, err;
261 data = vpn_provider_get_data(provider);
263 name = vpn_provider_get_driver_name(provider);
266 DBG("Cannot find VPN driver for provider %p", provider);
267 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
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);
278 state = vpn_driver_data->vpn_driver->notify(msg, provider);
280 DBG("provider %p driver %s state %d", provider, name, state);
283 case VPN_STATE_CONNECT:
284 case VPN_STATE_READY:
285 if (data->state == VPN_STATE_READY) {
287 * This is the restart case, in which case we must
288 * just set the IP address.
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.
295 * Also the state must change, otherwise the routes
296 * will not be set properly.
298 vpn_provider_set_state(provider,
299 VPN_PROVIDER_STATE_CONNECT);
301 vpn_provider_clear_address(provider, AF_INET);
302 vpn_provider_clear_address(provider, AF_INET6);
304 vpn_provider_change_address(provider);
305 vpn_provider_set_state(provider,
306 VPN_PROVIDER_STATE_READY);
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);
316 if (err == -EALREADY) {
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.
327 vpn_newlink(IFF_UP, 0, provider);
329 DBG("Cannot take interface %d up err %d/%s",
330 index, -err, strerror(-err));
335 case VPN_STATE_UNKNOWN:
337 case VPN_STATE_DISCONNECT:
338 case VPN_STATE_FAILURE:
339 vpn_provider_set_state(provider,
340 VPN_PROVIDER_STATE_DISCONNECT);
343 case VPN_STATE_AUTH_FAILURE:
344 vpn_provider_indicate_error(provider,
345 VPN_PROVIDER_ERROR_AUTH_FAILED);
352 #if defined TIZEN_EXT
353 static void vpn_event(struct vpn_provider *provider, int state)
355 struct vpn_driver_data *vpn_driver_data;
358 name = vpn_provider_get_driver_name(provider);
360 DBG("Cannot find VPN driver for provider %p", provider);
361 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
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);
372 DBG("provider %p driver %s state %d", provider, name, state);
375 case VPN_STATE_CONNECT:
376 vpn_provider_set_state(provider,
377 VPN_PROVIDER_STATE_CONNECT);
379 case VPN_STATE_READY:
380 vpn_provider_set_state(provider,
381 VPN_PROVIDER_STATE_READY);
384 case VPN_STATE_UNKNOWN:
386 case VPN_STATE_DISCONNECT:
387 case VPN_STATE_FAILURE:
388 vpn_provider_set_state(provider,
389 VPN_PROVIDER_STATE_DISCONNECT);
392 case VPN_STATE_AUTH_FAILURE:
393 vpn_provider_indicate_error(provider,
394 VPN_PROVIDER_ERROR_AUTH_FAILED);
402 static int vpn_create_tun(struct vpn_provider *provider, int flags)
404 struct vpn_data *data = vpn_provider_get_data(provider);
412 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
415 connman_error("Failed to open /dev/net/tun: %s",
421 memset(&ifr, 0, sizeof(ifr));
422 ifr.ifr_flags = flags | IFF_NO_PI;
424 for (i = 0; i < 256; i++) {
425 sprintf(ifr.ifr_name, "vpn%d", i);
427 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
432 connman_error("Failed to find available tun device");
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");
448 if (ioctl(fd, TUNSETPERSIST, 1)) {
450 connman_error("Failed to set tun persistent: %s",
459 index = connman_inet_ifindex(data->if_name);
461 connman_error("Failed to get tun ifindex");
466 vpn_provider_set_index(provider, index);
474 static gboolean is_numeric(const char *str)
481 for(i = 0; str[i] ; i++) {
482 if(!g_ascii_isdigit(str[i]))
489 static gint get_gid(const char *group_name)
494 if(!group_name || !(*group_name))
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);
501 grp = getgrnam(group_name);
510 static gint get_uid(const char *user_name)
515 if(!user_name || !(*user_name))
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);
522 pw = getpwnam(user_name);
531 static gint get_supplementary_gids(gchar **groups, gid_t **gid_list)
533 gint group_count = 0;
538 for(i = 0; groups[i]; i++) {
541 list = (gid_t*)g_try_realloc(list,
542 sizeof(gid_t) * group_count);
545 DBG("cannot allocate supplementary group list");
549 list[i] = get_gid(groups[i]);
558 static void vpn_task_setup(gpointer user_data)
560 struct vpn_plugin_data *data;
563 gid_t *gid_list = NULL;
564 size_t gid_list_size;
567 gchar **suppl_groups;
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);
575 gid = get_gid(group);
576 gid_list_size = get_supplementary_gids(suppl_groups, &gid_list);
578 DBG("vpn_task_setup uid:%d gid:%d supplementary group list size:%zu",
579 uid, gid, gid_list_size);
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));
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));
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));
596 static gboolean update_provider_state(gpointer data)
598 struct vpn_provider *provider = data;
599 struct vpn_data *vpn_data;
604 vpn_data = vpn_provider_get_data(provider);
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);
616 static int vpn_connect(struct vpn_provider *provider,
617 vpn_provider_connect_cb_t cb,
618 const char *dbus_sender, void *user_data)
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;
624 int ret = 0, tun_flags = IFF_TUN;
625 enum vpn_state state = VPN_STATE_UNKNOWN;
630 DBG("data %p state %d", data, state);
633 case VPN_STATE_UNKNOWN:
634 data = g_try_new0(struct vpn_data, 1);
638 data->provider = vpn_provider_ref(provider);
643 vpn_provider_set_data(provider, data);
646 case VPN_STATE_DISCONNECT:
648 case VPN_STATE_FAILURE:
649 case VPN_STATE_AUTH_FAILURE:
650 data->state = VPN_STATE_IDLE;
653 case VPN_STATE_CONNECT:
656 case VPN_STATE_READY:
660 name = vpn_provider_get_driver_name(provider);
664 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
666 if (!vpn_driver_data || !vpn_driver_data->vpn_driver) {
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);
675 ret = vpn_create_tun(provider, tun_flags);
681 if (vpn_driver_data && vpn_driver_data->vpn_driver &&
682 vpn_driver_data->vpn_driver->flags & VPN_FLAG_NO_DAEMON) {
684 ret = vpn_driver_data->vpn_driver->connect(provider,
685 NULL, NULL, NULL, NULL, NULL);
691 DBG("%s started with dev %s",
692 vpn_driver_data->provider_driver.name, data->if_name);
694 data->state = VPN_STATE_CONNECT;
696 g_timeout_add(1, update_provider_state, provider);
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);
711 if (connman_task_set_notify(data->task, "notify",
712 vpn_notify, provider)) {
715 connman_task_destroy(data->task);
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);
726 ret = vpn_driver_data->vpn_driver->connect(provider, data->task,
727 data->if_name, cb, dbus_sender,
729 if (ret < 0 && ret != -EINPROGRESS) {
731 connman_task_destroy(data->task);
736 DBG("%s started with dev %s",
737 vpn_driver_data->provider_driver.name, data->if_name);
739 data->state = VPN_STATE_CONNECT;
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);
753 static int vpn_probe(struct vpn_provider *provider)
758 static int vpn_disconnect(struct vpn_provider *provider)
760 struct vpn_data *data = vpn_provider_get_data(provider);
761 struct vpn_driver_data *vpn_driver_data;
764 DBG("disconnect provider %p:", provider);
769 name = vpn_provider_get_driver_name(provider);
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);
777 if (data->watch != 0) {
778 vpn_provider_unref(provider);
779 vpn_rtnl_remove_watch(data->watch);
783 data->state = VPN_STATE_DISCONNECT;
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);
792 connman_task_stop(data->task);
797 static int vpn_remove(struct vpn_provider *provider)
799 struct vpn_data *data;
800 struct vpn_driver_data *driver_data;
804 data = vpn_provider_get_data(provider);
805 name = vpn_provider_get_driver_name(provider);
810 if (data->watch != 0) {
811 vpn_provider_unref(provider);
812 vpn_rtnl_remove_watch(data->watch);
817 connman_task_stop(data->task);
819 g_usleep(G_USEC_PER_SEC);
826 driver_data = g_hash_table_lookup(driver_hash, name);
828 if (driver_data && driver_data->vpn_driver->remove)
829 err = driver_data->vpn_driver->remove(provider);
832 DBG("%p vpn_driver->remove() returned %d", provider, err);
837 static int vpn_save(struct vpn_provider *provider, GKeyFile *keyfile)
839 struct vpn_driver_data *vpn_driver_data;
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);
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)
855 struct vpn_driver_data *vpn_driver_data = NULL;
856 const char *name = NULL;
861 name = vpn_provider_get_driver_name(provider);
862 vpn_driver_data = g_hash_table_lookup(driver_hash, name);
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,
871 int vpn_register(const char *name, struct vpn_driver *vpn_driver,
874 struct vpn_driver_data *data;
876 data = g_try_new0(struct vpn_driver_data, 1);
881 data->program = program;
883 if (vpn_settings_parse_vpn_plugin_config(data->name) != 0)
884 DBG("No configuration provided for VPN plugin %s", data->name);
886 data->vpn_driver = vpn_driver;
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;
898 driver_hash = g_hash_table_new_full(g_str_hash,
903 connman_error("driver_hash not initialized for %s", name);
908 g_hash_table_replace(driver_hash, (char *)name, data);
910 vpn_provider_driver_register(&data->provider_driver);
915 void vpn_unregister(const char *name)
917 struct vpn_driver_data *data;
919 data = g_hash_table_lookup(driver_hash, name);
923 vpn_provider_driver_unregister(&data->provider_driver);
924 vpn_settings_delete_vpn_plugin_config(name);
926 g_hash_table_remove(driver_hash, name);
928 if (g_hash_table_size(driver_hash) == 0)
929 g_hash_table_destroy(driver_hash);