summaryrefslogtreecommitdiff
path: root/vpn/plugins
diff options
context:
space:
mode:
authorSeonah Moon <seonah1.moon@samsung.com>2018-01-08 13:42:54 +0900
committerSeonah Moon <seonah1.moon@samsung.com>2018-01-08 13:43:31 +0900
commit9362752a471a5c892d679548fbf2828d5fc5684b (patch)
tree83c7d29a28556906938f5c2198d81e2d35f86f92 /vpn/plugins
parent22633ced6225d294ce8483efbf2b39ea0c0c1b65 (diff)
downloadconnman-9362752a471a5c892d679548fbf2828d5fc5684b.tar.gz
connman-9362752a471a5c892d679548fbf2828d5fc5684b.tar.bz2
connman-9362752a471a5c892d679548fbf2828d5fc5684b.zip
Imported Upstream version 1.35upstream/1.35
Change-Id: I174854914d9fd06a813270b57d1f7bc2bac63c6a Signed-off-by: Seonah Moon <seonah1.moon@samsung.com>
Diffstat (limited to 'vpn/plugins')
-rw-r--r--vpn/plugins/l2tp.c9
-rw-r--r--vpn/plugins/openconnect.c2
-rw-r--r--vpn/plugins/openvpn.c92
-rw-r--r--vpn/plugins/pptp.c7
-rw-r--r--vpn/plugins/vpn.c44
-rw-r--r--vpn/plugins/vpn.h1
-rw-r--r--vpn/plugins/vpnc.c34
7 files changed, 166 insertions, 23 deletions
diff --git a/vpn/plugins/l2tp.c b/vpn/plugins/l2tp.c
index 22f9dcf8..a0d22c4d 100644
--- a/vpn/plugins/l2tp.c
+++ b/vpn/plugins/l2tp.c
@@ -108,13 +108,13 @@ struct {
{ "PPPD.RefuseMSCHAP2", "refuse-mschapv2", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.NoBSDComp", "nobsdcomp", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.NoPcomp", "nopcomp", OPT_PPPD, NULL, OPT_BOOL },
- { "PPPD.UseAccomp", "accomp", OPT_PPPD, NULL, OPT_BOOL },
+ { "PPPD.UseAccomp", "noaccomp", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.NoDeflate", "nodeflate", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.ReqMPPE", "require-mppe", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.ReqMPPE40", "require-mppe-40", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.ReqMPPE128", "require-mppe-128", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.ReqMPPEStateful", "mppe-stateful", OPT_PPPD, NULL, OPT_BOOL },
- { "PPPD.NoVJ", "no-vj-comp", OPT_PPPD, NULL, OPT_BOOL },
+ { "PPPD.NoVJ", "novj", OPT_PPPD, NULL, OPT_BOOL },
};
static DBusConnection *connection;
@@ -497,8 +497,9 @@ static void request_input_reply(DBusMessage *reply, void *user_data)
DBG("provider %p", l2tp_reply->provider);
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
- error = dbus_message_get_error_name(reply);
+ if (!reply || dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
+ if (reply)
+ error = dbus_message_get_error_name(reply);
goto done;
}
diff --git a/vpn/plugins/openconnect.c b/vpn/plugins/openconnect.c
index 5feaed9d..87679bfa 100644
--- a/vpn/plugins/openconnect.c
+++ b/vpn/plugins/openconnect.c
@@ -315,7 +315,7 @@ static void request_input_cookie_reply(DBusMessage *reply, void *user_data)
DBG("provider %p", data->provider);
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
+ if (!reply || dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
goto err;
if (!vpn_agent_check_reply_has_dict(reply))
diff --git a/vpn/plugins/openvpn.c b/vpn/plugins/openvpn.c
index 9ee5795c..e3395097 100644
--- a/vpn/plugins/openvpn.c
+++ b/vpn/plugins/openvpn.c
@@ -29,6 +29,7 @@
#include <unistd.h>
#include <stdio.h>
#include <net/if.h>
+#include <linux/if_tun.h>
#include <glib.h>
@@ -71,6 +72,8 @@ struct {
{ "OpenVPN.CompLZO", "--comp-lzo", 0 },
{ "OpenVPN.RemoteCertTls", "--remote-cert-tls", 1 },
{ "OpenVPN.ConfigFile", "--config", 1 },
+ { "OpenVPN.DeviceType", NULL, 1 },
+ { "OpenVPN.Verb", "--verb", 1 },
};
struct nameserver_entry {
@@ -156,7 +159,7 @@ static int ov_notify(DBusMessage *msg, struct vpn_provider *provider)
{
DBusMessageIter iter, dict;
const char *reason, *key, *value;
- char *address = NULL, *gateway = NULL, *peer = NULL;
+ char *address = NULL, *gateway = NULL, *peer = NULL, *netmask = NULL;
struct connman_ipaddress *ipaddress;
GSList *nameserver_list = NULL;
@@ -192,6 +195,9 @@ static int ov_notify(DBusMessage *msg, struct vpn_provider *provider)
if (!strcmp(key, "ifconfig_local"))
address = g_strdup(value);
+ if (!strcmp(key, "ifconfig_netmask"))
+ netmask = g_strdup(value);
+
if (!strcmp(key, "ifconfig_remote"))
peer = g_strdup(value);
@@ -218,11 +224,12 @@ static int ov_notify(DBusMessage *msg, struct vpn_provider *provider)
g_free(address);
g_free(gateway);
g_free(peer);
+ g_free(netmask);
return VPN_STATE_FAILURE;
}
- connman_ipaddress_set_ipv4(ipaddress, address, NULL, gateway);
+ connman_ipaddress_set_ipv4(ipaddress, address, netmask, gateway);
connman_ipaddress_set_peer(ipaddress, peer);
vpn_provider_set_ipaddress(provider, ipaddress);
@@ -256,6 +263,7 @@ static int ov_notify(DBusMessage *msg, struct vpn_provider *provider)
g_free(address);
g_free(gateway);
g_free(peer);
+ g_free(netmask);
connman_ipaddress_free(ipaddress);
return VPN_STATE_CONNECT;
@@ -306,13 +314,54 @@ static int task_append_config_data(struct vpn_provider *provider,
return 0;
}
+static gboolean can_read_data(GIOChannel *chan,
+ GIOCondition cond, gpointer data)
+{
+ void (*cbf)(const char *format, ...) = data;
+ gchar *str;
+ gsize size;
+
+ if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
+ return FALSE;
+
+ g_io_channel_read_line(chan, &str, &size, NULL, NULL);
+ cbf(str);
+ g_free(str);
+
+ return TRUE;
+}
+
+static int setup_log_read(int stdout_fd, int stderr_fd)
+{
+ GIOChannel *chan;
+ int watch;
+
+ chan = g_io_channel_unix_new(stdout_fd);
+ g_io_channel_set_close_on_unref(chan, TRUE);
+ watch = g_io_add_watch(chan, G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
+ can_read_data, connman_debug);
+ g_io_channel_unref(chan);
+
+ if (watch == 0)
+ return -EIO;
+
+ chan = g_io_channel_unix_new(stderr_fd);
+ g_io_channel_set_close_on_unref(chan, TRUE);
+ watch = g_io_add_watch(chan, G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
+ can_read_data, connman_error);
+ g_io_channel_unref(chan);
+
+ return watch == 0? -EIO : 0;
+}
+
static int ov_connect(struct vpn_provider *provider,
struct connman_task *task, const char *if_name,
vpn_provider_connect_cb_t cb, const char *dbus_sender,
void *user_data)
{
const char *option;
- int err = 0, fd;
+ int stdout_fd, stderr_fd;
+ int err = 0;
option = vpn_provider_get_string(provider, "Host");
if (!option) {
@@ -341,8 +390,6 @@ static int ov_connect(struct vpn_provider *provider,
connman_task_add_argument(task, "--client", NULL);
}
- connman_task_add_argument(task, "--syslog", NULL);
-
connman_task_add_argument(task, "--script-security", "2");
connman_task_add_argument(task, "--up",
@@ -362,7 +409,15 @@ static int ov_connect(struct vpn_provider *provider,
connman_task_get_path(task));
connman_task_add_argument(task, "--dev", if_name);
- connman_task_add_argument(task, "--dev-type", "tun");
+ option = vpn_provider_get_string(provider, "OpenVPN.DeviceType");
+ if (option) {
+ connman_task_add_argument(task, "--dev-type", option);
+ } else {
+ /*
+ * Default to tun for backwards compatibility.
+ */
+ connman_task_add_argument(task, "--dev-type", "tun");
+ }
connman_task_add_argument(task, "--persist-tun", NULL);
@@ -379,15 +434,15 @@ static int ov_connect(struct vpn_provider *provider,
*/
connman_task_add_argument(task, "--ping-restart", "0");
- fd = fileno(stderr);
err = connman_task_run(task, vpn_died, provider,
- NULL, &fd, &fd);
+ NULL, &stdout_fd, &stderr_fd);
if (err < 0) {
connman_error("openvpn failed to start");
err = -EIO;
goto done;
}
+ err = setup_log_read(stdout_fd, stderr_fd);
done:
if (cb)
cb(provider, user_data, err);
@@ -395,10 +450,31 @@ done:
return err;
}
+static int ov_device_flags(struct vpn_provider *provider)
+{
+ const char *option;
+
+ option = vpn_provider_get_string(provider, "OpenVPN.DeviceType");
+ if (!option) {
+ return IFF_TUN;
+ }
+
+ if (g_str_equal(option, "tap")) {
+ return IFF_TAP;
+ }
+
+ if (!g_str_equal(option, "tun")) {
+ connman_warn("bad OpenVPN.DeviceType value, falling back to tun");
+ }
+
+ return IFF_TUN;
+}
+
static struct vpn_driver vpn_driver = {
.notify = ov_notify,
.connect = ov_connect,
.save = ov_save,
+ .device_flags = ov_device_flags,
};
static int openvpn_init(void)
diff --git a/vpn/plugins/pptp.c b/vpn/plugins/pptp.c
index 9f2a214d..27b1d508 100644
--- a/vpn/plugins/pptp.c
+++ b/vpn/plugins/pptp.c
@@ -77,7 +77,7 @@ struct {
{ "PPPD.RequirMPPE40", "require-mppe-40", NULL, OPT_BOOL },
{ "PPPD.RequirMPPE128", "require-mppe-128", NULL, OPT_BOOL },
{ "PPPD.RequirMPPEStateful", "mppe-stateful", NULL, OPT_BOOL },
- { "PPPD.NoVJ", "no-vj-comp", NULL, OPT_BOOL },
+ { "PPPD.NoVJ", "novj", NULL, OPT_BOOL },
};
static DBusConnection *connection;
@@ -289,8 +289,9 @@ static void request_input_reply(DBusMessage *reply, void *user_data)
DBG("provider %p", pptp_reply->provider);
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
- error = dbus_message_get_error_name(reply);
+ if (!reply || dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
+ if (reply)
+ error = dbus_message_get_error_name(reply);
goto done;
}
diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c
index b438d06e..9a423850 100644
--- a/vpn/plugins/vpn.c
+++ b/vpn/plugins/vpn.c
@@ -56,6 +56,7 @@ struct vpn_data {
unsigned int watch;
enum vpn_state state;
struct connman_task *task;
+ int tun_flags;
};
struct vpn_driver_data {
@@ -89,7 +90,7 @@ static int stop_vpn(struct vpn_provider *provider)
return 0;
memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+ ifr.ifr_flags = data->tun_flags | IFF_NO_PI;
sprintf(ifr.ifr_name, "%s", data->if_name);
fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
@@ -195,6 +196,34 @@ int vpn_set_ifname(struct vpn_provider *provider, const char *ifname)
return 0;
}
+static int vpn_set_state(struct vpn_provider *provider,
+ enum vpn_provider_state state)
+{
+ struct vpn_data *data = vpn_provider_get_data(provider);
+ if (!data)
+ return -EINVAL;
+
+ switch (state) {
+ case VPN_PROVIDER_STATE_UNKNOWN:
+ return -EINVAL;
+ case VPN_PROVIDER_STATE_IDLE:
+ data->state = VPN_STATE_IDLE;
+ break;
+ case VPN_PROVIDER_STATE_CONNECT:
+ case VPN_PROVIDER_STATE_READY:
+ data->state = VPN_STATE_CONNECT;
+ break;
+ case VPN_PROVIDER_STATE_DISCONNECT:
+ data->state = VPN_STATE_DISCONNECT;
+ break;
+ case VPN_PROVIDER_STATE_FAILURE:
+ data->state = VPN_STATE_FAILURE;
+ break;
+ }
+
+ return 0;
+}
+
static void vpn_newlink(unsigned flags, unsigned change, void *user_data)
{
struct vpn_provider *provider = user_data;
@@ -307,7 +336,7 @@ static DBusMessage *vpn_notify(struct connman_task *task,
return NULL;
}
-static int vpn_create_tun(struct vpn_provider *provider)
+static int vpn_create_tun(struct vpn_provider *provider, int flags)
{
struct vpn_data *data = vpn_provider_get_data(provider);
struct ifreq ifr;
@@ -327,7 +356,7 @@ static int vpn_create_tun(struct vpn_provider *provider)
}
memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+ ifr.ifr_flags = flags | IFF_NO_PI;
for (i = 0; i < 256; i++) {
sprintf(ifr.ifr_name, "vpn%d", i);
@@ -343,6 +372,7 @@ static int vpn_create_tun(struct vpn_provider *provider)
goto exist_err;
}
+ data->tun_flags = flags;
data->if_name = (char *)g_strdup(ifr.ifr_name);
if (!data->if_name) {
connman_error("Failed to allocate memory");
@@ -384,7 +414,7 @@ static int vpn_connect(struct vpn_provider *provider,
struct vpn_data *data = vpn_provider_get_data(provider);
struct vpn_driver_data *vpn_driver_data;
const char *name;
- int ret = 0;
+ int ret = 0, tun_flags = IFF_TUN;
enum vpn_state state = VPN_STATE_UNKNOWN;
if (data)
@@ -432,7 +462,10 @@ static int vpn_connect(struct vpn_provider *provider,
}
if (vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) {
- ret = vpn_create_tun(provider);
+ if (vpn_driver_data->vpn_driver->device_flags) {
+ tun_flags = vpn_driver_data->vpn_driver->device_flags(provider);
+ }
+ ret = vpn_create_tun(provider, tun_flags);
if (ret < 0)
goto exist_err;
}
@@ -572,6 +605,7 @@ int vpn_register(const char *name, struct vpn_driver *vpn_driver,
data->provider_driver.probe = vpn_probe;
data->provider_driver.remove = vpn_remove;
data->provider_driver.save = vpn_save;
+ data->provider_driver.set_state = vpn_set_state;
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 bf56728d..cb94bdcd 100644
--- a/vpn/plugins/vpn.h
+++ b/vpn/plugins/vpn.h
@@ -50,6 +50,7 @@ struct vpn_driver {
void (*disconnect) (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 vpn_register(const char *name, struct vpn_driver *driver,
diff --git a/vpn/plugins/vpnc.c b/vpn/plugins/vpnc.c
index 09674bd8..af9dbe76 100644
--- a/vpn/plugins/vpnc.c
+++ b/vpn/plugins/vpnc.c
@@ -29,6 +29,7 @@
#include <unistd.h>
#include <stdio.h>
#include <net/if.h>
+#include <linux/if_tun.h>
#include <glib.h>
@@ -72,7 +73,7 @@ struct {
{ "VPNC.LocalPort", "Local Port", "0", OPT_STRING, true, },
{ "VPNC.CiscoPort", "Cisco UDP Encapsulation Port", "0", OPT_STRING,
true },
- { "VPNC.AppVersion", "Application Version", NULL, OPT_STRING, true },
+ { "VPNC.AppVersion", "Application version", NULL, OPT_STRING, true },
{ "VPNC.NATTMode", "NAT Traversal Mode", "cisco-udp", OPT_STRING,
true },
{ "VPNC.DPDTimeout", "DPD idle timeout (our side)", NULL, OPT_STRING,
@@ -287,7 +288,15 @@ static int vc_connect(struct vpn_provider *provider,
connman_task_add_argument(task, "--no-detach", NULL);
connman_task_add_argument(task, "--ifname", if_name);
- connman_task_add_argument(task, "--ifmode", "tun");
+ option = vpn_provider_get_string(provider, "VPNC.DeviceType");
+ if (option) {
+ connman_task_add_argument(task, "--ifmode", option);
+ } else {
+ /*
+ * Default to tun for backwards compatibility.
+ */
+ connman_task_add_argument(task, "--ifmode", "tun");
+ }
connman_task_add_argument(task, "--script",
SCRIPTDIR "/openconnect-script");
@@ -329,11 +338,32 @@ static int vc_error_code(struct vpn_provider *provider, int exit_code)
}
}
+static int vc_device_flags(struct vpn_provider *provider)
+{
+ const char *option;
+
+ option = vpn_provider_get_string(provider, "VPNC.DeviceType");
+ if (!option) {
+ return IFF_TUN;
+ }
+
+ if (g_str_equal(option, "tap")) {
+ return IFF_TAP;
+ }
+
+ if (!g_str_equal(option, "tun")) {
+ connman_warn("bad VPNC.DeviceType value, falling back to tun");
+ }
+
+ return IFF_TUN;
+}
+
static struct vpn_driver vpn_driver = {
.notify = vc_notify,
.connect = vc_connect,
.error_code = vc_error_code,
.save = vc_save,
+ .device_flags = vc_device_flags,
};
static int vpnc_init(void)