From 6b2381a2adabea7d8309ff158ef675ff88184305 Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Thu, 4 Jul 2019 17:41:09 +0530 Subject: Imported Upstream version 1.37 Change-Id: Ib5957e7ee3a9315ee86a331189bc3e9e71751ee8 Signed-off-by: Nishant Chaprana --- vpn/plugins/l2tp.c | 1 + vpn/plugins/openconnect.c | 30 ++++++++++++++++++++++++ vpn/plugins/openvpn.c | 25 ++++++++++++++++++++ vpn/plugins/pptp.c | 1 + vpn/plugins/vpn.c | 59 ++++++++++++++++++++++++++++++++++++++++++----- vpn/plugins/vpn.h | 4 ++++ 6 files changed, 114 insertions(+), 6 deletions(-) (limited to 'vpn/plugins') diff --git a/vpn/plugins/l2tp.c b/vpn/plugins/l2tp.c index a0d22c4d..5d83eb88 100644 --- a/vpn/plugins/l2tp.c +++ b/vpn/plugins/l2tp.c @@ -382,6 +382,7 @@ static int write_pppd_option(struct vpn_provider *provider, int fd) l2tp_write_option(fd, "nodetach", NULL); l2tp_write_option(fd, "lock", NULL); + l2tp_write_option(fd, "logfd", "2"); l2tp_write_option(fd, "usepeerdns", NULL); l2tp_write_option(fd, "noipdefault", NULL); l2tp_write_option(fd, "noauth", NULL); diff --git a/vpn/plugins/openconnect.c b/vpn/plugins/openconnect.c index 87679bfa..8e74479f 100644 --- a/vpn/plugins/openconnect.c +++ b/vpn/plugins/openconnect.c @@ -561,11 +561,41 @@ static int oc_error_code(struct vpn_provider *provider, int exit_code) } } +static int oc_route_env_parse(struct vpn_provider *provider, const char *key, + int *family, unsigned long *idx, enum vpn_provider_route_type *type) +{ + char *end; + const char *start; + + if (g_str_has_prefix(key, "CISCO_SPLIT_INC_")) { + *family = AF_INET; + start = key + strlen("CISCO_SPLIT_INC_"); + } else if (g_str_has_prefix(key, "CISCO_IPV6_SPLIT_INC_")) { + *family = AF_INET6; + start = key + strlen("CISCO_IPV6_SPLIT_INC_"); + } else + return -EINVAL; + + *idx = g_ascii_strtoull(start, &end, 10); + + if (strncmp(end, "_ADDR", 5) == 0) + *type = VPN_PROVIDER_ROUTE_TYPE_ADDR; + else if (strncmp(end, "_MASK", 5) == 0) + *type = VPN_PROVIDER_ROUTE_TYPE_MASK; + else if (strncmp(end, "_MASKLEN", 8) == 0 && *family == AF_INET6) + *type = VPN_PROVIDER_ROUTE_TYPE_MASK; + else + return -EINVAL; + + return 0; +} + static struct vpn_driver vpn_driver = { .notify = oc_notify, .connect = oc_connect, .error_code = oc_error_code, .save = oc_save, + .route_env_parse = oc_route_env_parse, }; static int openconnect_init(void) diff --git a/vpn/plugins/openvpn.c b/vpn/plugins/openvpn.c index e3395097..f38c0c36 100644 --- a/vpn/plugins/openvpn.c +++ b/vpn/plugins/openvpn.c @@ -470,11 +470,36 @@ static int ov_device_flags(struct vpn_provider *provider) return IFF_TUN; } +static int ov_route_env_parse(struct vpn_provider *provider, const char *key, + int *family, unsigned long *idx, enum vpn_provider_route_type *type) +{ + char *end; + const char *start; + + if (g_str_has_prefix(key, "route_network_")) { + start = key + strlen("route_network_"); + *type = VPN_PROVIDER_ROUTE_TYPE_ADDR; + } else if (g_str_has_prefix(key, "route_netmask_")) { + start = key + strlen("route_netmask_"); + *type = VPN_PROVIDER_ROUTE_TYPE_MASK; + } else if (g_str_has_prefix(key, "route_gateway_")) { + start = key + strlen("route_gateway_"); + *type = VPN_PROVIDER_ROUTE_TYPE_GW; + } else + return -EINVAL; + + *family = AF_INET; + *idx = g_ascii_strtoull(start, &end, 10); + + return 0; +} + static struct vpn_driver vpn_driver = { .notify = ov_notify, .connect = ov_connect, .save = ov_save, .device_flags = ov_device_flags, + .route_env_parse = ov_route_env_parse, }; static int openvpn_init(void) diff --git a/vpn/plugins/pptp.c b/vpn/plugins/pptp.c index 27b1d508..3dc93b03 100644 --- a/vpn/plugins/pptp.c +++ b/vpn/plugins/pptp.c @@ -453,6 +453,7 @@ static int run_connect(struct vpn_provider *provider, connman_task_add_argument(task, "nodetach", NULL); connman_task_add_argument(task, "lock", NULL); + connman_task_add_argument(task, "logfd", "2"); connman_task_add_argument(task, "usepeerdns", NULL); connman_task_add_argument(task, "noipdefault", NULL); connman_task_add_argument(task, "noauth", NULL); diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c index 9a423850..acede747 100644 --- a/vpn/plugins/vpn.c +++ b/vpn/plugins/vpn.c @@ -23,7 +23,6 @@ #include #endif -#define _GNU_SOURCE #include #include #include @@ -133,6 +132,10 @@ void vpn_died(struct connman_task *task, int exit_code, void *user_data) if (!data) goto vpn_exit; + /* The task may die after we have already started the new one */ + if (data->task != task) + goto done; + state = data->state; stop_vpn(provider); @@ -172,6 +175,7 @@ vpn_exit: g_free(data); } +done: connman_task_destroy(task); } @@ -303,19 +307,22 @@ static DBusMessage *vpn_notify(struct connman_task *task, vpn_newlink, provider); err = connman_inet_ifup(index); if (err < 0) { - if (err == -EALREADY) + if (err == -EALREADY) { /* * So the interface is up already, that is just * great. Unfortunately in this case the * newlink watch might not have been called at * all. We must manually call it here so that * the provider can go to ready state and the - * routes are setup properly. + * routes are setup properly. Also reset flags + * so vpn_newlink() can handle the change. */ + data->flags = 0; vpn_newlink(IFF_UP, 0, provider); - else + } else { DBG("Cannot take interface %d up err %d/%s", index, -err, strerror(-err)); + } } break; @@ -373,6 +380,7 @@ static int vpn_create_tun(struct vpn_provider *provider, int flags) } data->tun_flags = flags; + g_free(data->if_name); data->if_name = (char *)g_strdup(ifr.ifr_name); if (!data->if_name) { connman_error("Failed to allocate memory"); @@ -553,10 +561,15 @@ static int vpn_disconnect(struct vpn_provider *provider) static int vpn_remove(struct vpn_provider *provider) { struct vpn_data *data; + struct vpn_driver_data *driver_data; + const char *name; + int err = 0; data = vpn_provider_get_data(provider); + name = vpn_provider_get_driver_name(provider); + if (!data) - return 0; + goto call_remove; if (data->watch != 0) { vpn_provider_unref(provider); @@ -568,7 +581,20 @@ static int vpn_remove(struct vpn_provider *provider) g_usleep(G_USEC_PER_SEC); stop_vpn(provider); - return 0; + +call_remove: + if (!name) + return 0; + + driver_data = g_hash_table_lookup(driver_hash, name); + + if (driver_data && driver_data->vpn_driver->remove) + err = driver_data->vpn_driver->remove(provider); + + if (err) + DBG("%p vpn_driver->remove() returned %d", provider, err); + + return err; } static int vpn_save(struct vpn_provider *provider, GKeyFile *keyfile) @@ -585,6 +611,26 @@ static int vpn_save(struct vpn_provider *provider, GKeyFile *keyfile) return 0; } +static int vpn_route_env_parse(struct vpn_provider *provider, const char *key, + int *family, unsigned long *idx, + enum vpn_provider_route_type *type) +{ + struct vpn_driver_data *vpn_driver_data = NULL; + const char *name = NULL; + + if (!provider) + return -EINVAL; + + name = vpn_provider_get_driver_name(provider); + vpn_driver_data = g_hash_table_lookup(driver_hash, name); + + if (vpn_driver_data && vpn_driver_data->vpn_driver->route_env_parse) + return vpn_driver_data->vpn_driver->route_env_parse(provider, key, + family, idx, type); + + return 0; +} + int vpn_register(const char *name, struct vpn_driver *vpn_driver, const char *program) { @@ -606,6 +652,7 @@ int vpn_register(const char *name, struct vpn_driver *vpn_driver, data->provider_driver.remove = vpn_remove; data->provider_driver.save = vpn_save; data->provider_driver.set_state = vpn_set_state; + data->provider_driver.route_env_parse = vpn_route_env_parse; if (!driver_hash) driver_hash = g_hash_table_new_full(g_str_hash, diff --git a/vpn/plugins/vpn.h b/vpn/plugins/vpn.h index cb94bdcd..265fd82f 100644 --- a/vpn/plugins/vpn.h +++ b/vpn/plugins/vpn.h @@ -48,9 +48,13 @@ struct vpn_driver { vpn_provider_connect_cb_t cb, const char *dbus_sender, void *user_data); void (*disconnect) (struct vpn_provider *provider); + int (*remove) (struct vpn_provider *provider); int (*error_code) (struct vpn_provider *provider, int exit_code); int (*save) (struct vpn_provider *provider, GKeyFile *keyfile); int (*device_flags) (struct vpn_provider *provider); + int (*route_env_parse) (struct vpn_provider *provider, const char *key, + int *family, unsigned long *idx, + enum vpn_provider_route_type *type); }; int vpn_register(const char *name, struct vpn_driver *driver, -- cgit v1.2.3