Hi Daniel,
On Tue, Oct 19, 2010 at 10:08:13AM -0400, Daniel Wagner wrote:
> From: Daniel Wagner <[email protected]>
That's great, thanks for adding this new feature.
I have some generic comments:
1) It seems the openvpn and openconnect plugins share a lot of code. Here is
what I propose:
- Factor this shared code out and dump it in plugins/vpn.c
- Define the vpn_register() and vpn_unregister() routines that would take a
name, a connect() function and register/unregister the corresponding provider.
This would be the only exported vpn API.
- If OPENCONNECT or OPENVPN are defined, then plugins/vpn.c is compiled.
2) I think the connect-openvpn script could be integrated into the existing
connect-vpn one.
Cheers,
Samuel.
> ---
>
> v1: added missing connect-openvpn test script
> v0: initial version
>
> Makefile.plugins | 21 ++
> configure.ac | 17 ++
> plugins/openvpn.c | 477
> ++++++++++++++++++++++++++++++++++++++++++++++
> scripts/openvpn-script.c | 123 ++++++++++++
> src/provider.c | 34 ++--
> test/connect-openvpn | 24 +++
> 6 files changed, 681 insertions(+), 15 deletions(-)
> create mode 100644 plugins/openvpn.c
> create mode 100644 scripts/openvpn-script.c
> create mode 100755 test/connect-openvpn
>
> diff --git a/Makefile.plugins b/Makefile.plugins
> index e6b79b0..8e82c9e 100644
> --- a/Makefile.plugins
> +++ b/Makefile.plugins
> @@ -121,6 +121,21 @@ plugins_openconnect_la_LDFLAGS = $(plugin_ldflags)
> endif
> endif
>
> +if OPENVPN
> +if OPENVPN_BUILTIN
> +builtin_modules += openvpn
> +builtin_sources += plugins/openvpn.c
> +builtin_cflags += -DOPENVPN=\"@open...@\"
> +else
> +plugin_LTLIBRARIES += plugins/openvpn.la
> +plugin_objects += $(plugins_openvpn_la_OBJECTS)
> +plugins_openvpn_la_CFLAGS = $(plugin_cflags) -DOPENVPN=\"@open...@\" \
> + -DSTATEDIR=\""$(statedir)"\" \
> + -DSCRIPTDIR=\""$(build_scriptdir)"\"
> +plugins_openvpn_la_LDFLAGS = $(plugin_ldflags)
> +endif
> +endif
> +
> if PORTAL
> if PORTAL_BUILTIN
> builtin_modules += portal
> @@ -229,6 +244,12 @@ script_PROGRAMS += scripts/openconnect-script
> scripts_openconnect_script_LDADD = @DBUS_LIBS@
> endif
>
> +if OPENVPN
> +script_PROGRAMS += scripts/openvpn-script
> +
> +scripts_openvpn_script_LDADD = @DBUS_LIBS@
> +endif
> +
> if DHCLIENT
> script_DATA += scripts/dhclient.conf
> script_PROGRAMS += scripts/dhclient-script
> diff --git a/configure.ac b/configure.ac
> index 1b52a93..31b91d9 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -129,6 +129,23 @@ fi
> AM_CONDITIONAL(OPENCONNECT, test "${enable_openconnect}" != "no")
> AM_CONDITIONAL(OPENCONNECT_BUILTIN, test "${enable_openconnect}" = "builtin")
>
> +AC_ARG_WITH(openvpn, AC_HELP_STRING([--with-openvpn=PROGRAM],
> + [specify location of openvpn binary]), [path_openvpn=${withval}])
> +
> +AC_ARG_ENABLE(openvpn,
> + AC_HELP_STRING([--enable-openvpn], [enable openvpn support]),
> + [enable_openvpn=${enableval}], [enable_openvpn="no"])
> +if (test "${enable_openvpn}" != "no"); then
> + if (test -z "${path_openvpn}"); then
> + AC_PATH_PROG(OPENVPN, [openvpn], [], $PATH:/sbin:/usr/sbin)
> + else
> + OPENVPN="${path_openvpn}"
> + AC_SUBST(OPENVPN)
> + fi
> +fi
> +AM_CONDITIONAL(OPENVPN, test "${enable_openvpn}" != "no")
> +AM_CONDITIONAL(OPENVPN_BUILTIN, test "${enable_openvpn}" = "builtin")
> +
> AC_ARG_ENABLE(portal,
> AC_HELP_STRING([--enable-portal], [enable portal detection support]),
> [enable_portal=${enableval}], [enable_portal="no"])
> diff --git a/plugins/openvpn.c b/plugins/openvpn.c
> new file mode 100644
> index 0000000..edb160c
> --- /dev/null
> +++ b/plugins/openvpn.c
> @@ -0,0 +1,477 @@
> +/*
> + *
> + * Connection Manager
> + *
> + * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
> + * Copyright (C) 2010 BMW Car IT GmbH. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
> USA
> + *
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <string.h>
> +#include <fcntl.h>
> +#include <unistd.h>
> +#include <sys/stat.h>
> +#include <sys/wait.h>
> +#include <stdio.h>
> +#include <errno.h>
> +#include <sys/ioctl.h>
> +#include <linux/if_tun.h>
> +#include <net/if.h>
> +#include <stdint.h>
> +
> +#include <glib/garray.h>
> +#include <glib/gerror.h>
> +#include <glib/gmain.h>
> +#include <glib/gspawn.h>
> +
> +#define CONNMAN_API_SUBJECT_TO_CHANGE
> +#include <connman/plugin.h>
> +#include <connman/device.h>
> +#include <connman/element.h>
> +#include <connman/provider.h>
> +#include <connman/log.h>
> +#include <connman/element.h>
> +#include <connman/rtnl.h>
> +#include <connman/task.h>
> +
> +#include <connman/dbus.h>
> +
> +#include "inet.h"
> +
> +enum ov_state {
> + OV_STATE_UNKNOWN = 0,
> + OV_STATE_IDLE = 1,
> + OV_STATE_CONNECT = 2,
> + OV_STATE_READY = 3,
> + OV_STATE_DISCONNECT = 4,
> + OV_STATE_FAILURE = 5,
> +};
> +
> +struct ov_data {
> + struct connman_provider *provider;
> + char *if_name;
> + unsigned flags;
> + unsigned int watch;
> + unsigned int state;
> + struct connman_task *task;
> +};
> +
> +static DBusConnection *connection;
> +
> +static int kill_tun(char *tun_name)
> +{
> + struct ifreq ifr;
> + int fd, err;
> +
> + memset(&ifr, 0, sizeof(ifr));
> + ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
> + sprintf(ifr.ifr_name, "%s", tun_name);
> +
> + fd = open("/dev/net/tun", O_RDWR);
> + if (fd < 0) {
> + err = -errno;
> + connman_error("Failed to open /dev/net/tun to device %s: %s",
> + tun_name, strerror(errno));
> + return err;
> + }
> +
> + if (ioctl(fd, TUNSETIFF, (void *)&ifr)) {
> + err = -errno;
> + connman_error("Failed to TUNSETIFF for device %s to it: %s",
> + tun_name, strerror(errno));
> + close(fd);
> + return err;
> + }
> +
> + if (ioctl(fd, TUNSETPERSIST, 0)) {
> + err = -errno;
> + connman_error("Failed to set tun device %s nonpersistent: %s",
> + tun_name, strerror(errno));
> + close(fd);
> + return err;
> + }
> + close(fd);
> + DBG("Killed tun device %s", tun_name);
> + return 0;
> +}
> +
> +static void openvpn_died(struct connman_task *task, void *user_data)
> +{
> + struct connman_provider *provider = user_data;
> + struct ov_data *data = connman_provider_get_data(provider);
> + int state = data->state;
> +
> + DBG("provider %p data %p", provider, data);
> +
> + if (!data)
> + goto oc_exit;
> +
> + kill_tun(data->if_name);
> + connman_provider_set_data(provider, NULL);
> + connman_rtnl_remove_watch(data->watch);
> +
> +oc_exit:
> + if (state != OV_STATE_READY && state != OV_STATE_DISCONNECT)
> + connman_provider_set_state(provider,
> + CONNMAN_PROVIDER_STATE_FAILURE);
> + else
> + connman_provider_set_state(provider,
> + CONNMAN_PROVIDER_STATE_IDLE);
> +
> + connman_provider_set_index(provider, -1);
> + connman_provider_unref(data->provider);
> + g_free(data);
> +
> + connman_task_destroy(task);
> +}
> +
> +static void vpn_newlink(unsigned flags, unsigned change, void *user_data)
> +{
> + struct connman_provider *provider = user_data;
> + struct ov_data *data = connman_provider_get_data(provider);
> +
> + if ((data->flags & IFF_UP) != (flags & IFF_UP)) {
> + if (flags & IFF_UP) {
> + data->state = OV_STATE_READY;
> + connman_provider_set_state(provider,
> + CONNMAN_PROVIDER_STATE_READY);
> + }
> + }
> + data->flags = flags;
> +}
> +
> +static void openvpn_task_notify(struct connman_task *task,
> + DBusMessage *msg, void *user_data)
> +{
> + DBusMessageIter iter, dict;
> + struct connman_provider *provider = user_data;
> + struct ov_data *data;
> + const char *reason, *key, *value;
> + const char *domain = NULL;
> + int index;
> +
> + dbus_message_iter_init(msg, &iter);
> +
> + dbus_message_iter_get_basic(&iter, &reason);
> + dbus_message_iter_next(&iter);
> +
> + if (!provider) {
> + connman_error("No provider found");
> + return;
> + }
> +
> + data = connman_provider_get_data(provider);
> + if (!data) {
> + DBG("provider %p no data", provider);
> + return;
> + }
> +
> + if (strcmp(reason, "up")) {
> + connman_provider_set_state(provider,
> + CONNMAN_PROVIDER_STATE_DISCONNECT);
> + return;
> + }
> +
> + domain = connman_provider_get_string(provider, "VPN.Domain");
> +
> + dbus_message_iter_recurse(&iter, &dict);
> +
> + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
> + DBusMessageIter entry;
> +
> + dbus_message_iter_recurse(&dict, &entry);
> + dbus_message_iter_get_basic(&entry, &key);
> + dbus_message_iter_next(&entry);
> + dbus_message_iter_get_basic(&entry, &value);
> +
> + DBG("%s = %s", key, value);
> +
> + if (!strcmp(key, "route_gateway_1"))
> + connman_provider_set_string(provider, "Gateway", value);
> +
> + if (!strcmp(key, "route_netmask_1"))
> + connman_provider_set_string(provider, "Netmask", value);
> +
> + if (!strcmp(key, "route_network_1"))
> + connman_provider_set_string(provider, "Address", value);
> +
> + dbus_message_iter_next(&dict);
> + }
> +
> + index = connman_provider_get_index(provider);
> + connman_provider_set_string(provider, "Domain", domain);
> + data->watch = connman_rtnl_add_newlink_watch(index,
> + vpn_newlink, provider);
> +
> + connman_inet_ifup(index);
> +}
> +
> +static int ov_connect(struct connman_provider *provider)
> +{
> + struct ov_data *data = connman_provider_get_data(provider);
> + struct ifreq ifr;
> + int fd, i, index;
> + const char *vpnhost, *cafile, *mtu, *certfile, *keyfile;
> + int ret = 0;
> +
> + if (data != NULL)
> + return -EISCONN;
> +
> + data = g_try_new0(struct ov_data, 1);
> + if (data == NULL)
> + return -ENOMEM;
> +
> + data->provider = connman_provider_ref(provider);
> + data->watch = 0;
> + data->flags = 0;
> + data->task = NULL;
> + data->state = OV_STATE_IDLE;
> +
> + connman_provider_set_data(provider, data);
> +
> + vpnhost = connman_provider_get_string(provider, "Host");
> + if (!vpnhost) {
> + connman_error("Host not set; cannot enable VPN");
> + ret = -EINVAL;
> + goto exist_err;
> + }
> +
> + cafile = connman_provider_get_string(provider, "OpenVPN.CACert");
> + certfile = connman_provider_get_string(provider, "OpenVPN.Cert");
> + keyfile = connman_provider_get_string(provider, "OpenVPN.Key");
> + mtu = connman_provider_get_string(provider, "VPN.MTU");
> +
> + fd = open("/dev/net/tun", O_RDWR);
> + if (fd < 0) {
> + i = -errno;
> + connman_error("Failed to open /dev/net/tun: %s",
> + strerror(errno));
> + ret = i;
> + goto exist_err;
> + }
> +
> + memset(&ifr, 0, sizeof(ifr));
> + ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
> +
> + for (i = 0; i < 256; i++) {
> + sprintf(ifr.ifr_name, "tun%d", i);
> +
> + if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
> + break;
> + }
> +
> + if (i == 256) {
> + connman_error("Failed to find available tun device");
> + close(fd);
> + ret = -ENODEV;
> + goto exist_err;
> + }
> +
> + data->if_name = (char *)g_strdup(ifr.ifr_name);
> + if (!data->if_name) {
> + ret = -ENOMEM;
> + goto exist_err;
> + }
> +
> + if (ioctl(fd, TUNSETPERSIST, 1)) {
> + i = -errno;
> + connman_error("Failed to set tun persistent: %s",
> + strerror(errno));
> + close(fd);
> + ret = i;
> + goto exist_err;
> + }
> +
> + close(fd);
> +
> + index = connman_inet_ifindex(data->if_name);
> + if (index < 0) {
> + connman_error("Failed to get tun ifindex");
> + kill_tun(data->if_name);
> + ret = -EIO;
> + goto exist_err;
> + }
> + connman_provider_set_index(provider, index);
> +
> + data->task = connman_task_create(OPENVPN);
> +
> + if (data->task == NULL) {
> + ret = -ENOMEM;
> + kill_tun(data->if_name);
> + goto exist_err;
> + }
> +
> + if (connman_task_set_notify(data->task, "notify",
> + openvpn_task_notify, provider)) {
> + ret = -ENOMEM;
> + kill_tun(data->if_name);
> + connman_task_destroy(data->task);
> + data->task = NULL;
> + goto exist_err;
> + }
> +
> + if (mtu)
> + connman_task_add_argument(data->task, "--mtu", (char *)mtu);
> +
> + connman_task_add_argument(data->task, "--syslog", NULL);
> +
> + connman_task_add_argument(data->task, "--script-security", "2");
> +
> + connman_task_add_argument(data->task, "--up",
> + SCRIPTDIR "/openvpn-script");
> +
> + connman_task_add_argument(data->task, "--setenv", NULL);
> + connman_task_add_argument(data->task, "CONNMAN_BUSNAME",
> + dbus_bus_get_unique_name(connection));
> +
> + connman_task_add_argument(data->task, "--setenv", NULL);
> + connman_task_add_argument(data->task, "CONNMAN_INTERFACE",
> + CONNMAN_TASK_INTERFACE);
> +
> + connman_task_add_argument(data->task, "--setenv", NULL);
> + connman_task_add_argument(data->task, "CONNMAN_PATH",
> + connman_task_get_path(data->task));
> +
> + connman_task_add_argument(data->task, "--dev", data->if_name);
> +
> + connman_task_add_argument(data->task, "--tls-client", NULL);
> + connman_task_add_argument(data->task, "--remote", (char *)vpnhost);
> + connman_task_add_argument(data->task, "--nobind", NULL);
> + connman_task_add_argument(data->task, "--persist-key", NULL);
> + connman_task_add_argument(data->task, "--persist-tun", NULL);
> +
> + connman_task_add_argument(data->task, "--route-noexec", NULL);
> + connman_task_add_argument(data->task, "--ifconfig-noexec", NULL);
> + connman_task_add_argument(data->task, "--up-restart", NULL);
> +
> + connman_task_add_argument(data->task, "--client", NULL);
> +
> + if (cafile) {
> + connman_task_add_argument(data->task, "--ca",
> + (char *)cafile);
> + }
> +
> + if (certfile) {
> + connman_task_add_argument(data->task, "--cert",
> + (char *)certfile);
> + }
> +
> + if (keyfile) {
> + connman_task_add_argument(data->task, "--key",
> + (char *)keyfile);
> + }
> +
> +
> + fd = fileno(stderr);
> + ret = connman_task_run(data->task, openvpn_died, provider,
> + NULL, &fd, &fd);
> + if (ret) {
> + connman_error("OpenVPN failed to start");
> + kill_tun(data->if_name);
> + ret = -EIO;
> + connman_task_destroy(data->task);
> + data->task = NULL;
> + goto exist_err;
> + }
> +
> + DBG("openvpn started with dev %s", data->if_name);
> +
> + data->state = OV_STATE_CONNECT;
> +
> + return -EINPROGRESS;
> +
> +exist_err:
> + connman_provider_set_index(provider, -1);
> + connman_provider_set_data(provider, NULL);
> + connman_provider_unref(data->provider);
> + g_free(data);
> +
> + return ret;
> +}
> +
> +static int ov_probe(struct connman_provider *provider)
> +{
> + return 0;
> +}
> +
> +static int ov_disconnect(struct connman_provider *provider)
> +{
> + struct ov_data *data = connman_provider_get_data(provider);
> +
> + DBG("disconnect provider %p:", provider);
> +
> + if (data == NULL)
> + return 0;
> +
> + if (data->watch != 0)
> + connman_rtnl_remove_watch(data->watch);
> +
> + data->watch = 0;
> + data->state = OV_STATE_DISCONNECT;
> + connman_task_stop(data->task);
> +
> + return 0;
> +}
> +
> +static int ov_remove(struct connman_provider *provider)
> +{
> + struct ov_data *data;
> +
> + data = connman_provider_get_data(provider);
> + connman_provider_set_data(provider, NULL);
> + if (data == NULL)
> + return 0;
> +
> + if (data->watch != 0)
> + connman_rtnl_remove_watch(data->watch);
> + data->watch = 0;
> + connman_task_stop(data->task);
> +
> + g_usleep(G_USEC_PER_SEC);
> + kill_tun(data->if_name);
> + return 0;
> +}
> +
> +static struct connman_provider_driver provider_driver = {
> + .name = "openvpn",
> + .disconnect = ov_disconnect,
> + .connect = ov_connect,
> + .probe = ov_probe,
> + .remove = ov_remove,
> +};
> +
> +static int openvpn_init(void)
> +{
> + connection = connman_dbus_get_connection();
> +
> + connman_provider_driver_register(&provider_driver);
> +
> + return 0;
> +}
> +
> +static void openvpn_exit(void)
> +{
> + connman_provider_driver_unregister(&provider_driver);
> +
> + dbus_connection_unref(connection);
> +}
> +
> +CONNMAN_PLUGIN_DEFINE(openvpn, "OpenVPN plugin", VERSION,
> + CONNMAN_PLUGIN_PRIORITY_DEFAULT, openvpn_init, openvpn_exit)
> diff --git a/scripts/openvpn-script.c b/scripts/openvpn-script.c
> new file mode 100644
> index 0000000..8d2c3ff
> --- /dev/null
> +++ b/scripts/openvpn-script.c
> @@ -0,0 +1,123 @@
> +/*
> + *
> + * Connection Manager
> + *
> + * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
> + * Copyright (C) 2010 BMW Car IT GmbH. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
> USA
> + *
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include <dbus/dbus.h>
> +
> +extern char **environ;
> +
> +static void append(DBusMessageIter *dict, const char *pattern)
> +{
> + DBusMessageIter entry;
> + const char *key, *value;
> + char *delim;
> +
> + delim = strchr(pattern, '=');
> + *delim = '\0';
> +
> + key = pattern;
> + value = delim + 1;
> +
> + dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
> + NULL, &entry);
> +
> + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
> +
> + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &value);
> +
> + dbus_message_iter_close_container(dict, &entry);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> + DBusConnection *conn;
> + DBusError error;
> + DBusMessage *msg;
> + DBusMessageIter iter, dict;
> + char **envp, *busname, *interface, *path, *reason;
> +
> + busname = getenv("CONNMAN_BUSNAME");
> + interface = getenv("CONNMAN_INTERFACE");
> + path = getenv("CONNMAN_PATH");
> +
> + reason = getenv("script_type");
> +
> + if (!busname || !interface || !path || !reason) {
> + fprintf(stderr, "Required environment variables not set\n");
> + return 1;
> + }
> + dbus_error_init(&error);
> +
> + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
> + if (conn == NULL) {
> + if (dbus_error_is_set(&error) == TRUE) {
> + fprintf(stderr, "%s\n", error.message);
> + dbus_error_free(&error);
> + } else
> + fprintf(stderr, "Failed to get on system bus\n");
> + return 0;
> + }
> +
> + msg = dbus_message_new_method_call(busname, path,
> + interface, "notify");
> + if (msg == NULL) {
> + dbus_connection_unref(conn);
> + fprintf(stderr, "Failed to allocate method call\n");
> + return 0;
> + }
> +
> + dbus_message_set_no_reply(msg, TRUE);
> +
> + dbus_message_append_args(msg,
> + DBUS_TYPE_STRING, &reason,
> + DBUS_TYPE_INVALID);
> +
> + dbus_message_iter_init_append(msg, &iter);
> +
> + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
> + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
> + DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING
> + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
> +
> + for (envp = environ; envp && *envp; envp++)
> + append(&dict, *envp);
> +
> + dbus_message_iter_close_container(&iter, &dict);
> +
> + if (dbus_connection_send(conn, msg, NULL) == FALSE)
> + fprintf(stderr, "Failed to send message\n");
> +
> + dbus_connection_flush(conn);
> +
> + dbus_message_unref(msg);
> +
> + dbus_connection_unref(conn);
> +
> + return 0;
> +}
> diff --git a/src/provider.c b/src/provider.c
> index adad8df..73dfd82 100644
> --- a/src/provider.c
> +++ b/src/provider.c
> @@ -288,23 +288,27 @@ static int set_connected(struct connman_provider
> *provider,
> name = connman_inet_ifname(provider->element.index);
>
> nameservers = g_strdup(provider->dns);
> - value = nameservers;
> - second_ns = strchr(value, ' ');
> - if (second_ns)
> - *(second_ns++) = 0;
> - __connman_service_append_nameserver(service, value);
> - value = second_ns;
> -
> - while (value) {
> - char *next = strchr(value, ' ');
> - if (next)
> - *(next++) = 0;
> -
> - connman_resolver_append(name, provider->domain, value);
> - value = next;
> + if (nameservers != NULL) {
> + value = nameservers;
> + second_ns = strchr(value, ' ');
> + if (second_ns)
> + *(second_ns++) = 0;
> + __connman_service_append_nameserver(service, value);
> + value = second_ns;
> +
> + while (value) {
> + char *next = strchr(value, ' ');
> + if (next)
> + *(next++) = 0;
> +
> + connman_resolver_append(name, provider->domain,
> + value);
> + value = next;
> + }
> +
> + g_free(nameservers);
> }
>
> - g_free(nameservers);
> g_free(name);
>
> } else {
> diff --git a/test/connect-openvpn b/test/connect-openvpn
> new file mode 100755
> index 0000000..66bd5fb
> --- /dev/null
> +++ b/test/connect-openvpn
> @@ -0,0 +1,24 @@
> +#!/usr/bin/python
> +
> +import sys
> +import dbus
> +
> +if (len(sys.argv) < 7):
> + print "Usage: %s <name> <host> <domain> <cafile> <cerfile> <keyfile>" %
> (sys.argv[0])
> + sys.exit(1)
> +
> +bus = dbus.SystemBus()
> +
> +manager = dbus.Interface(bus.get_object("org.moblin.connman", "/"),
> + "org.moblin.connman.Manager")
> +
> +print "Attempting to connect service %s" % (sys.argv[1])
> +
> +path = manager.ConnectProvider(({ "Type": "openvpn", "Name": sys.argv[1],
> + "Host": sys.argv[2],
> + "VPN.Domain": sys.argv[3],
> + "OpenVPN.CACert": sys.argv[4],
> + "OpenVPN.Cert": sys.argv[5],
> + "OpenVPN.Key": sys.argv[6]}))
> +
> +print "VPN service path is %s" %(path)
> --
> 1.7.2.3
>
> _______________________________________________
> connman mailing list
> [email protected]
> http://lists.connman.net/listinfo/connman
--
Intel Open Source Technology Centre
http://oss.intel.com/
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman