summaryrefslogtreecommitdiff
path: root/vpn
diff options
context:
space:
mode:
authorNishant Chaprana <n.chaprana@samsung.com>2019-09-17 19:00:55 +0530
committerNishant Chaprana <n.chaprana@samsung.com>2019-09-18 19:23:41 +0530
commit26cc90dfaf2ad149b702626f9552c81abbb26862 (patch)
tree2524c8994cf58358350fde67dfba5c3b8cb58f7d /vpn
parent9e3beb21876b6e63bd8acf53e751480d7a1cc16f (diff)
parent6b2381a2adabea7d8309ff158ef675ff88184305 (diff)
downloadconnman-26cc90dfaf2ad149b702626f9552c81abbb26862.tar.gz
connman-26cc90dfaf2ad149b702626f9552c81abbb26862.tar.bz2
connman-26cc90dfaf2ad149b702626f9552c81abbb26862.zip
Imported Upstream version 1.37submit/tizen/20190920.082459
Change-Id: Idb47c1ddbedc9f97181b8e9a5eeac04ddd832a2c Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
Diffstat (limited to 'vpn')
-rwxr-xr-xvpn/connman-vpn.service.in2
-rwxr-xr-xvpn/plugins/l2tp.c1
-rwxr-xr-xvpn/plugins/openconnect.c30
-rwxr-xr-xvpn/plugins/openvpn.c25
-rwxr-xr-xvpn/plugins/pptp.c1
-rwxr-xr-xvpn/plugins/vpn.c59
-rwxr-xr-xvpn/plugins/vpn.h4
-rwxr-xr-xvpn/vpn-dbus.conf6
-rwxr-xr-xvpn/vpn-provider.c66
-rwxr-xr-xvpn/vpn-provider.h10
-rwxr-xr-xvpn/vpn-rtnl.c2
11 files changed, 145 insertions, 61 deletions
diff --git a/vpn/connman-vpn.service.in b/vpn/connman-vpn.service.in
index 9399eb96..a8f2948f 100755
--- a/vpn/connman-vpn.service.in
+++ b/vpn/connman-vpn.service.in
@@ -1,5 +1,7 @@
[Unit]
Description=ConnMan VPN service
+Requires=dbus.socket
+After=dbus.socket
[Service]
Type=dbus
diff --git a/vpn/plugins/l2tp.c b/vpn/plugins/l2tp.c
index a0d22c4d..5d83eb88 100755
--- 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 100755
--- 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 d115df6e..6b090e45 100755
--- a/vpn/plugins/openvpn.c
+++ b/vpn/plugins/openvpn.c
@@ -472,11 +472,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 100755
--- 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 f6e24c4c..d9c6dbbb 100755
--- a/vpn/plugins/vpn.c
+++ b/vpn/plugins/vpn.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
@@ -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;
@@ -423,6 +430,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");
@@ -609,10 +617,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);
@@ -624,7 +637,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)
@@ -641,6 +667,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)
{
@@ -662,6 +708,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 1888d5ff..318a10c5 100755
--- a/vpn/plugins/vpn.h
+++ b/vpn/plugins/vpn.h
@@ -55,9 +55,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,
diff --git a/vpn/vpn-dbus.conf b/vpn/vpn-dbus.conf
index 476be1c1..8ebfc6b6 100755
--- a/vpn/vpn-dbus.conf
+++ b/vpn/vpn-dbus.conf
@@ -4,13 +4,19 @@
<policy user="root">
<allow own="net.connman.vpn"/>
<allow send_destination="net.connman.vpn"/>
+ <allow send_interface="net.connman.vpn.Agent"/>
</policy>
<policy user="network_fw">
<allow own="net.connman.vpn"/>
<allow send_destination="net.connman.vpn"/>
+ <allow send_interface="net.connman.vpn.Agent"/>
+ </policy>
+ <policy at_console="true">
+ <allow send_destination="net.connman.vpn"/>
</policy>
<policy context="default">
<deny own="net.connman.vpn"/>
<deny send_destination="net.connman.vpn"/>
+ <deny send_interface="net.connman.vpn.Agent"/>
</policy>
</busconfig>
diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c
index 67239e40..bb1a103a 100755
--- a/vpn/vpn-provider.c
+++ b/vpn/vpn-provider.c
@@ -37,6 +37,7 @@
#include "connman/vpn-dbus.h"
#include "vpn-provider.h"
#include "vpn.h"
+#include "plugins/vpn.h"
static DBusConnection *connection;
static GHashTable *provider_hash;
@@ -2446,61 +2447,18 @@ int vpn_provider_set_nameservers(struct vpn_provider *provider,
return 0;
}
-enum provider_route_type {
- PROVIDER_ROUTE_TYPE_NONE = 0,
- PROVIDER_ROUTE_TYPE_MASK = 1,
- PROVIDER_ROUTE_TYPE_ADDR = 2,
- PROVIDER_ROUTE_TYPE_GW = 3,
-};
-
static int route_env_parse(struct vpn_provider *provider, const char *key,
int *family, unsigned long *idx,
- enum provider_route_type *type)
+ enum vpn_provider_route_type *type)
{
- char *end;
- const char *start;
+ if (!provider)
+ return -EINVAL;
DBG("name %s", provider->name);
- if (!strcmp(provider->type, "openvpn")) {
- if (g_str_has_prefix(key, "route_network_")) {
- start = key + strlen("route_network_");
- *type = PROVIDER_ROUTE_TYPE_ADDR;
- } else if (g_str_has_prefix(key, "route_netmask_")) {
- start = key + strlen("route_netmask_");
- *type = PROVIDER_ROUTE_TYPE_MASK;
- } else if (g_str_has_prefix(key, "route_gateway_")) {
- start = key + strlen("route_gateway_");
- *type = PROVIDER_ROUTE_TYPE_GW;
- } else
- return -EINVAL;
-
- *family = AF_INET;
- *idx = g_ascii_strtoull(start, &end, 10);
-
- } else if (!strcmp(provider->type, "openconnect")) {
- 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 = PROVIDER_ROUTE_TYPE_ADDR;
- else if (strncmp(end, "_MASK", 5) == 0)
- *type = PROVIDER_ROUTE_TYPE_MASK;
- else if (strncmp(end, "_MASKLEN", 8) == 0 &&
- *family == AF_INET6) {
- *type = PROVIDER_ROUTE_TYPE_MASK;
- } else
- return -EINVAL;
- }
+ if (provider->driver && provider->driver->route_env_parse)
+ return provider->driver->route_env_parse(provider, key, family, idx,
+ type);
return 0;
}
@@ -2511,7 +2469,7 @@ int vpn_provider_append_route(struct vpn_provider *provider,
struct vpn_route *route;
int ret, family = 0;
unsigned long idx = 0;
- enum provider_route_type type = PROVIDER_ROUTE_TYPE_NONE;
+ enum vpn_provider_route_type type = VPN_PROVIDER_ROUTE_TYPE_NONE;
DBG("key %s value %s", key, value);
@@ -2536,15 +2494,15 @@ int vpn_provider_append_route(struct vpn_provider *provider,
}
switch (type) {
- case PROVIDER_ROUTE_TYPE_NONE:
+ case VPN_PROVIDER_ROUTE_TYPE_NONE:
break;
- case PROVIDER_ROUTE_TYPE_MASK:
+ case VPN_PROVIDER_ROUTE_TYPE_MASK:
route->netmask = g_strdup(value);
break;
- case PROVIDER_ROUTE_TYPE_ADDR:
+ case VPN_PROVIDER_ROUTE_TYPE_ADDR:
route->network = g_strdup(value);
break;
- case PROVIDER_ROUTE_TYPE_GW:
+ case VPN_PROVIDER_ROUTE_TYPE_GW:
route->gateway = g_strdup(value);
break;
}
diff --git a/vpn/vpn-provider.h b/vpn/vpn-provider.h
index bdc5f5c1..96452c11 100755
--- a/vpn/vpn-provider.h
+++ b/vpn/vpn-provider.h
@@ -57,6 +57,13 @@ enum vpn_provider_error {
VPN_PROVIDER_ERROR_AUTH_FAILED = 3,
};
+enum vpn_provider_route_type {
+ VPN_PROVIDER_ROUTE_TYPE_NONE = 0,
+ VPN_PROVIDER_ROUTE_TYPE_MASK = 1,
+ VPN_PROVIDER_ROUTE_TYPE_ADDR = 2,
+ VPN_PROVIDER_ROUTE_TYPE_GW = 3,
+};
+
struct vpn_provider;
struct connman_ipaddress;
@@ -134,6 +141,9 @@ struct vpn_provider_driver {
int (*save) (struct vpn_provider *provider, GKeyFile *keyfile);
int (*set_state)(struct vpn_provider *provider,
enum vpn_provider_state state);
+ int (*route_env_parse) (struct vpn_provider *provider, const char *key,
+ int *family, unsigned long *idx,
+ enum vpn_provider_route_type *type);
};
int vpn_provider_driver_register(struct vpn_provider_driver *driver);
diff --git a/vpn/vpn-rtnl.c b/vpn/vpn-rtnl.c
index a7565dba..6ddfd832 100755
--- a/vpn/vpn-rtnl.c
+++ b/vpn/vpn-rtnl.c
@@ -879,7 +879,7 @@ static void rtnl_message(void *buf, size_t len)
if (!NLMSG_OK(hdr, len))
break;
- debug("%s len %d type %d flags 0x%04x seq %d pid %d",
+ debug("%s len %u type %u flags 0x%04x seq %u pid %u",
type2string(hdr->nlmsg_type),
hdr->nlmsg_len, hdr->nlmsg_type,
hdr->nlmsg_flags, hdr->nlmsg_seq,