diff --git a/Makefile.am b/Makefile.am index 84a28c9..97c0a9a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -74,18 +74,6 @@ src_nm_wireguard_service_LDADD = \ EXTRA_src_nm_wireguard_service_DEPENDENCIES = \ linker-script-binary.ver -libexec_PROGRAMS += src/nm-openvpn-service-openvpn-helper - -src_nm_openvpn_service_openvpn_helper_CPPFLAGS = $(src_cppflags) -src_nm_openvpn_service_openvpn_helper_LDFLAGS = \ - -Wl,--version-script="$(srcdir)/linker-script-binary.ver" -src_nm_openvpn_service_openvpn_helper_LDADD = \ - src/libnm-utils.la \ - $(GLIB_LIBS) \ - $(LIBNM_LIBS) -EXTRA_src_nm_openvpn_service_openvpn_helper_DEPENDENCIES = \ - linker-script-binary.ver - ############################################################################### properties/resources.h: properties/gresource.xml diff --git a/src/nm-openvpn-service-openvpn-helper.c b/src/nm-openvpn-service-openvpn-helper.c deleted file mode 100644 index d6c3302..0000000 --- a/src/nm-openvpn-service-openvpn-helper.c +++ /dev/null @@ -1,777 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* nm-openvpn-service-openvpn-helper - helper called after OpenVPN established - * a connection, uses DBUS to send information back to nm-openvpn-service - * - * Tim Niemueller [www.niemueller.de] - * Based on work by Dan Williams - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2005 Red Hat, Inc. - * (C) Copyright 2005 Tim Niemueller - * - * $Id: nm-openvpn-service-openvpn-helper.c 4170 2008-10-11 14:44:45Z dcbw $ - */ - -#include "nm-default.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "nm-utils/nm-shared-utils.h" -#include "nm-utils/nm-vpn-plugin-macros.h" - -extern char **environ; - -static struct { - int log_level; - const char *log_prefix_token; -} gl; - -/*****************************************************************************/ - -#define _NMLOG(level, ...) \ - G_STMT_START { \ - if (gl.log_level >= (level)) { \ - g_print ("nm-openvpn[%s]: %-7s [helper-%ld] " _NM_UTILS_MACRO_FIRST (__VA_ARGS__) "\n", \ - gl.log_prefix_token ?: "???", \ - nm_utils_syslog_to_str (level), \ - (long) getpid () \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ - } \ - } G_STMT_END - -static inline gboolean -_LOGD_enabled (void) -{ - return gl.log_level >= LOG_INFO; -} - -#define _LOGD(...) _NMLOG(LOG_INFO, __VA_ARGS__) -#define _LOGI(...) _NMLOG(LOG_NOTICE, __VA_ARGS__) -#define _LOGW(...) _NMLOG(LOG_WARNING, __VA_ARGS__) - -/*****************************************************************************/ - -static void -helper_failed (GDBusProxy *proxy, const char *reason) -{ - GError *err = NULL; - - _LOGW ("nm-openvpn-service-openvpn-helper did not receive a valid %s from openvpn", reason); - - if (!g_dbus_proxy_call_sync (proxy, "SetFailure", - g_variant_new ("(s)", reason), - G_DBUS_CALL_FLAGS_NONE, -1, - NULL, - &err)) { - _LOGW ("Could not send failure information: %s", err->message); - g_error_free (err); - } - - exit (1); -} - -static void -send_config (GDBusProxy *proxy, GVariant *config, - GVariant *ip4config, GVariant *ip6config) -{ - GError *err = NULL; - - if (!g_dbus_proxy_call_sync (proxy, "SetConfig", - g_variant_new ("(*)", config), - G_DBUS_CALL_FLAGS_NONE, -1, - NULL, - &err)) { - _LOGW ("Could not send configuration information: %s", err->message); - g_error_free (err); - err = NULL; - } - - if (ip4config) { - if (!g_dbus_proxy_call_sync (proxy, "SetIp4Config", - g_variant_new ("(*)", ip4config), - G_DBUS_CALL_FLAGS_NONE, -1, - NULL, - &err)) { - _LOGW ("Could not send IPv4 configuration information: %s", err->message); - g_error_free (err); - err = NULL; - } - } - - if (ip6config) { - if (!g_dbus_proxy_call_sync (proxy, "SetIp6Config", - g_variant_new ("(*)", ip6config), - G_DBUS_CALL_FLAGS_NONE, -1, - NULL, - &err)) { - _LOGW ("Could not send IPv6 configuration information: %s", err->message); - g_error_free (err); - err = NULL; - } - } -} - -static GVariant * -str_to_gvariant (const char *str, gboolean try_convert) -{ - /* Empty */ - if (!str || strlen (str) < 1) - return NULL; - - if (!g_utf8_validate (str, -1, NULL)) { - if (try_convert && !(str = g_convert (str, -1, "ISO-8859-1", "UTF-8", NULL, NULL, NULL))) - str = g_convert (str, -1, "C", "UTF-8", NULL, NULL, NULL); - - if (!str) - /* Invalid */ - return NULL; - } - - return g_variant_new_string (str); -} - -static GVariant * -addr4_to_gvariant (const char *str) -{ - struct in_addr temp_addr; - - /* Empty */ - if (!str || strlen (str) < 1) - return NULL; - - if (inet_pton (AF_INET, str, &temp_addr) <= 0) - return NULL; - - return g_variant_new_uint32 (temp_addr.s_addr); -} - -static GVariant * -addr6_to_gvariant (const char *str) -{ - struct in6_addr temp_addr; - GVariantBuilder builder; - int i; - - /* Empty */ - if (!str || strlen (str) < 1) - return NULL; - - if (inet_pton (AF_INET6, str, &temp_addr) <= 0) - return NULL; - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("ay")); - for (i = 0; i < sizeof (temp_addr); i++) - g_variant_builder_add (&builder, "y", ((guint8 *) &temp_addr)[i]); - return g_variant_builder_end (&builder); -} - -static void -parse_addr_list (GPtrArray *array4, GPtrArray *array6, const char *str) -{ - char **split; - int i; - GVariant *variant; - - /* Empty */ - if (!str || strlen (str) < 1) - return; - - split = g_strsplit (str, " ", -1); - for (i = 0; split[i]; i++) { - if (array4 && (variant = addr4_to_gvariant (split[i])) != NULL) - g_ptr_array_add (array4, variant); - else if (array6 && (variant = addr6_to_gvariant (split[i])) != NULL) - g_ptr_array_add (array6, variant); - } - - g_strfreev (split); - - return; -} - -static inline gboolean -is_domain_valid (const char *str) -{ - return (str && (strlen(str) >= 1) && (strlen(str) <= 255)); -} - -static GVariant * -get_ip4_routes (void) -{ - GVariantBuilder builder; - char *tmp; - gboolean has_any = FALSE; - guint i; - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("aau")); - - for (i = 1;; i++) { - GVariantBuilder array; - char key_name[255]; - in_addr_t network; - in_addr_t netmask; - in_addr_t gateway = 0; - guint32 metric; - - nm_sprintf_buf (key_name, "route_network_%u", i); - tmp = getenv (key_name); - if (!tmp || !tmp[0]) - break; - - if (inet_pton (AF_INET, tmp, &network) != 1) { - _LOGW ("Ignoring invalid static route address %s = \"%s\"", key_name, tmp); - continue; - } - - nm_sprintf_buf (key_name, "route_netmask_%u", i); - tmp = getenv (key_name); - if ( !tmp - || inet_pton (AF_INET, tmp, &netmask) != 1) { - _LOGW ("Ignoring invalid static route netmask %s = %s%s%s", key_name, NM_PRINT_FMT_QUOTE_STRING (tmp)); - continue; - } - - nm_sprintf_buf (key_name, "route_gateway_%u", i); - tmp = getenv (key_name); - /* gateway can be missing */ - if ( tmp - && inet_pton (AF_INET, tmp, &gateway) != 1) { - _LOGW ("Ignoring invalid static route gateway %s = \"%s\"", key_name, tmp); - continue; - } - - nm_sprintf_buf (key_name, "route_metric_%u", i); - tmp = getenv (key_name); - /* metric can be missing */ - if (tmp && tmp[0]) { - metric = _nm_utils_ascii_str_to_int64 (tmp, 10, 0, G_MAXUINT32, 0); - if (errno) { - _LOGW ("Ignoring invalid static route metric %s = \"%s\"", key_name, tmp); - continue; - } - } else - metric = 0; - - g_variant_builder_init (&array, G_VARIANT_TYPE ("au")); - g_variant_builder_add_value (&array, g_variant_new_uint32 (network)); - g_variant_builder_add_value (&array, g_variant_new_uint32 (nm_utils_ip4_netmask_to_prefix (netmask))); - g_variant_builder_add_value (&array, g_variant_new_uint32 (gateway)); - g_variant_builder_add_value (&array, g_variant_new_uint32 (metric)); - g_variant_builder_add_value (&builder, g_variant_builder_end (&array)); - has_any = TRUE; - } - - if (!has_any) { - g_variant_builder_clear (&builder); - return NULL; - } - - return g_variant_builder_end (&builder); -} - -static GVariant * -get_ip6_routes (void) -{ - gs_unref_ptrarray GPtrArray *routes = NULL; - guint i; - - routes = g_ptr_array_new_full (10, (GDestroyNotify) nm_ip_route_unref); - - for (i = 1;; i++) { - NMIPRoute *route; - GError *error = NULL; - gs_free char *dst = NULL; - char key_name[255]; - int prefix; - const char *tmp; - - nm_sprintf_buf (key_name, "route_ipv6_network_%u", i); - tmp = getenv (key_name); - if (!tmp || !tmp[0]) - break; - - if ( !nm_utils_parse_inaddr_prefix (tmp, AF_INET6, &dst, &prefix) - || prefix == -1) { - _LOGW ("Ignoring invalid static route %s = \"%s\"", key_name, tmp); - continue; - } - - nm_sprintf_buf (key_name, "route_ipv6_gateway_%u", i); - tmp = getenv (key_name); - - route = nm_ip_route_new (AF_INET6, dst, prefix, tmp, -1, &error); - if (!route) { - _LOGW ("Ignoring route#%u: %s", i, error->message); - g_error_free (error); - continue; - } - - g_ptr_array_add (routes, route); - } - - if (!routes->len) - return NULL; - - return nm_utils_ip6_routes_to_variant (routes); -} - -static GVariant * -trusted_remote_to_gvariant (void) -{ - char *tmp; - GVariant *val = NULL; - const char *p; - gboolean is_name = FALSE; - - tmp = getenv ("trusted_ip6"); - if (tmp) { - val = addr6_to_gvariant (tmp); - if (val == NULL) { - _LOGW ("failed to convert VPN gateway address '%s' (%d)", - tmp, errno); - return NULL; - } - return val; - } - - tmp = getenv ("trusted_ip"); - if (!tmp) - tmp = getenv ("remote_1"); - if (!tmp) { - _LOGW ("did not receive remote gateway address"); - return NULL; - } - - /* Check if it seems to be a hostname */ - p = tmp; - while (*p) { - if (*p != '.' && !isdigit (*p)) { - is_name = TRUE; - break; - } - p++; - } - - /* Resolve a hostname if required. Only look for IPv4 addresses */ - if (is_name) { - struct in_addr addr; - struct addrinfo hints; - struct addrinfo *result = NULL, *rp; - int err; - - addr.s_addr = 0; - memset (&hints, 0, sizeof (hints)); - - hints.ai_family = AF_INET; - hints.ai_flags = AI_ADDRCONFIG; - err = getaddrinfo (tmp, NULL, &hints, &result); - if (err != 0) { - _LOGW ("failed to look up VPN gateway address '%s' (%d)", - tmp, err); - return NULL; - } - - /* FIXME: so what if the name resolves to multiple IP addresses? We - * don't know which one pptp decided to use so we could end up using a - * different one here, and the VPN just won't work. - */ - for (rp = result; rp; rp = rp->ai_next) { - if ( (rp->ai_family == AF_INET) - && (rp->ai_addrlen == sizeof (struct sockaddr_in))) { - struct sockaddr_in *inptr = (struct sockaddr_in *) rp->ai_addr; - - memcpy (&addr, &(inptr->sin_addr), sizeof (struct in_addr)); - break; - } - } - - freeaddrinfo (result); - if (addr.s_addr != 0) - return g_variant_new_uint32 (addr.s_addr); - else { - _LOGW ("failed to convert or look up VPN gateway address '%s'", - tmp); - return NULL; - } - } else { - val = addr4_to_gvariant (tmp); - if (val == NULL) { - _LOGW ("failed to convert VPN gateway address '%s' (%d)", - tmp, errno); - return NULL; - } - } - - return val; -} - -int -main (int argc, char *argv[]) -{ - GDBusProxy *proxy; - GVariantBuilder builder, ip4builder, ip6builder; - GVariant *ip4config, *ip6config; - char *tmp; - GVariant *val; - int i; - GError *err = NULL; - GPtrArray *dns4_list, *dns6_list; - GPtrArray *nbns_list; - GPtrArray *dns_domains; - struct in_addr temp_addr; - int tapdev = -1; - char **iter; - int shift = 0; - gboolean is_restart; - gboolean has_ip4_prefix = FALSE; - gboolean has_ip4_address = FALSE; - gboolean has_ip6_address = FALSE; - gchar *bus_name = NM_DBUS_SERVICE_OPENVPN; - -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif - - for (i = 1; i < argc; i++) { - if (!strcmp (argv[i], "--")) { - i++; - break; - } - if (nm_streq (argv[i], "--debug")) { - if (i + 2 >= argc) { - g_printerr ("Missing debug arguments (requires )\n"); - exit (1); - } - gl.log_level = _nm_utils_ascii_str_to_int64 (argv[++i], 10, 0, LOG_DEBUG, 0); - gl.log_prefix_token = argv[++i]; - } else if (!strcmp (argv[i], "--tun")) - tapdev = 0; - else if (!strcmp (argv[i], "--tap")) - tapdev = 1; - else if (!strcmp (argv[i], "--bus-name")) { - if (++i == argc) { - g_printerr ("Missing bus name argument\n"); - exit (1); - } - if (!g_dbus_is_name (argv[i])) { - g_printerr ("Invalid bus name\n"); - exit (1); - } - bus_name = argv[i]; - } else - break; - } - shift = i - 1; - - if (_LOGD_enabled ()) { - GString *args; - - args = g_string_new (NULL); - for (i = 0; i < argc; i++) { - if (i > 0) - g_string_append_c (args, ' '); - if (shift && 1 + shift == i) - g_string_append (args, " "); - tmp = g_strescape (argv[i], NULL); - g_string_append_printf (args, "\"%s\"", tmp); - g_free (tmp); - } - - _LOGD ("command line: %s", args->str); - g_string_free (args, TRUE); - - for (iter = environ; iter && *iter; iter++) - _LOGD ("environment: %s", *iter); - } - - /* shift the arguments to the right leaving only those provided by openvpn */ - argv[shift] = argv[0]; - argv += shift; - argc -= shift; - - is_restart = argc >= 7 && !g_strcmp0 (argv[6], "restart"); - - proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, - NULL, - bus_name, - NM_VPN_DBUS_PLUGIN_PATH, - NM_VPN_DBUS_PLUGIN_INTERFACE, - NULL, &err); - if (!proxy) { - _LOGW ("Could not create a D-Bus proxy: %s", err->message); - g_error_free (err); - exit (1); - } - - g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); - g_variant_builder_init (&ip4builder, G_VARIANT_TYPE_VARDICT); - g_variant_builder_init (&ip6builder, G_VARIANT_TYPE_VARDICT); - - /* External world-visible VPN gateway */ - val = trusted_remote_to_gvariant (); - if (val) - g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, val); - else - helper_failed (proxy, "VPN Gateway"); - - /* Internal VPN subnet gateway */ - tmp = getenv ("route_vpn_gateway"); - val = addr4_to_gvariant (tmp); - if (val) - g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY, val); - else { - val = addr6_to_gvariant (tmp); - if (val) - g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY, val); - } - - /* VPN device */ - tmp = getenv ("dev"); - val = str_to_gvariant (tmp, FALSE); - if (val) - g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_TUNDEV, val); - else - helper_failed (proxy, "Tunnel Device"); - - if (tapdev == -1) - tapdev = strncmp (tmp, "tap", 3) == 0; - - /* IPv4 address */ - tmp = getenv ("ifconfig_local"); - if (!tmp && is_restart) - tmp = argv[4]; - if (tmp && strlen (tmp)) { - val = addr4_to_gvariant (tmp); - if (val) { - has_ip4_address = TRUE; - g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS, val); - } else - helper_failed (proxy, "IP4 Address"); - } - - /* PTP address; for vpnc PTP address == internal IP4 address */ - tmp = getenv ("ifconfig_remote"); - if (!tmp && is_restart) - tmp = argv[5]; - val = addr4_to_gvariant (tmp); - if (val) { - /* Sigh. Openvpn added 'topology' stuff in 2.1 that changes the meaning - * of the ifconfig bits without actually telling you what they are - * supposed to mean; basically relying on specific 'ifconfig' behavior. - */ - if (tmp && !strncmp (tmp, "255.", 4)) { - guint32 addr; - - /* probably a netmask, not a PTP address; topology == subnet */ - addr = g_variant_get_uint32 (val); - g_variant_unref (val); - val = g_variant_new_uint32 (nm_utils_ip4_netmask_to_prefix (addr)); - g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val); - has_ip4_prefix = TRUE; - } else - g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_PTP, val); - } - - /* Netmask - * - * Either TAP or TUN modes can have an arbitrary netmask in newer versions - * of openvpn, while in older versions only TAP mode would. So accept a - * netmask if passed, otherwise default to /32 for TUN devices since they - * are usually point-to-point. - */ - tmp = getenv ("ifconfig_netmask"); - if (tmp && inet_pton (AF_INET, tmp, &temp_addr) > 0) { - val = g_variant_new_uint32 (nm_utils_ip4_netmask_to_prefix (temp_addr.s_addr)); - g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val); - } else if (!tapdev) { - if (has_ip4_address && !has_ip4_prefix) { - val = g_variant_new_uint32 (32); - g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val); - } - } else - _LOGW ("No IP4 netmask/prefix (missing or invalid 'ifconfig_netmask')"); - - val = get_ip4_routes (); - if (val) - g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, val); - else if (is_restart) { - g_variant_builder_add (&ip4builder, "{sv}", - NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES, - g_variant_new_boolean (TRUE)); - } - - /* IPv6 address */ - tmp = getenv ("ifconfig_ipv6_local"); - if (tmp && strlen (tmp)) { - val = addr6_to_gvariant (tmp); - if (val) { - g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_ADDRESS, val); - has_ip6_address = TRUE; - } else - helper_failed (proxy, "IP6 Address"); - } - - /* IPv6 remote address */ - tmp = getenv ("ifconfig_ipv6_remote"); - if (tmp && strlen (tmp)) { - val = addr6_to_gvariant (tmp); - if (val) - g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_PTP, val); - else - helper_failed (proxy, "IP6 PTP Address"); - } - - /* IPv6 netbits */ - tmp = getenv ("ifconfig_ipv6_netbits"); - if (tmp && strlen (tmp)) { - long int netbits; - - errno = 0; - netbits = strtol (tmp, NULL, 10); - if (errno || netbits < 0 || netbits > 128) { - _LOGW ("Ignoring invalid prefix '%s'", tmp); - } else { - val = g_variant_new_uint32 ((guint32) netbits); - g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_PREFIX, val); - } - } - - val = get_ip6_routes (); - if (val) - g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_ROUTES, val); - else if (is_restart) { - g_variant_builder_add (&ip6builder, "{sv}", - NM_VPN_PLUGIN_IP6_CONFIG_PRESERVE_ROUTES, - g_variant_new_boolean (TRUE)); - } - - /* DNS and WINS servers */ - dns_domains = g_ptr_array_sized_new (3); - dns4_list = g_ptr_array_new (); - dns6_list = g_ptr_array_new (); - nbns_list = g_ptr_array_new (); - - for (i = 1; i < 256; i++) { - char *env_name; - - env_name = g_strdup_printf ("foreign_option_%d", i); - tmp = getenv (env_name); - g_free (env_name); - - if (!tmp || strlen (tmp) < 1) - break; - - if (!g_str_has_prefix (tmp, "dhcp-option ")) - continue; - - tmp += 12; /* strlen ("dhcp-option ") */ - - if (g_str_has_prefix (tmp, "DNS ")) - parse_addr_list (dns4_list, dns6_list, tmp + 4); - else if (g_str_has_prefix (tmp, "WINS ")) - parse_addr_list (nbns_list, NULL, tmp + 5); - else if (g_str_has_prefix (tmp, "DOMAIN ") && is_domain_valid (tmp + 7)) - g_ptr_array_add (dns_domains, tmp + 7); - } - - if (dns4_list->len) { - val = g_variant_new_array (G_VARIANT_TYPE_UINT32, (GVariant **) dns4_list->pdata, dns4_list->len); - g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_DNS, val); - } - - if (has_ip6_address && dns6_list->len) { - val = g_variant_new_array (G_VARIANT_TYPE ("ay"), (GVariant **) dns6_list->pdata, dns6_list->len); - g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_DNS, val); - } - - if (nbns_list->len) { - val = g_variant_new_array (G_VARIANT_TYPE_UINT32, (GVariant **) nbns_list->pdata, nbns_list->len); - g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_NBNS, val); - } - - if (dns_domains->len) { - val = g_variant_new_strv ((const gchar **) dns_domains->pdata, dns_domains->len); - g_variant_builder_add (&ip4builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS, val); - - /* Domains apply to both IPv4 and IPv6 configurations */ - if (has_ip6_address) { - val = g_variant_new_strv ((const gchar **) dns_domains->pdata, dns_domains->len); - g_variant_builder_add (&ip6builder, "{sv}", NM_VPN_PLUGIN_IP6_CONFIG_DOMAINS, val); - } - } - - g_ptr_array_unref (dns4_list); - g_ptr_array_unref (dns6_list); - g_ptr_array_unref (nbns_list); - g_ptr_array_unref (dns_domains); - - /* Tunnel MTU */ - tmp = getenv ("tun_mtu"); - if (tmp && tmp[0]) { - guint32 mtu; - - mtu = _nm_utils_ascii_str_to_int64 (tmp, 10, 0, G_MAXUINT32, 0); - if (errno) - _LOGW ("Ignoring invalid tunnel MTU '%s'", tmp); - else { - g_variant_builder_add (&builder, "{sv}", - NM_VPN_PLUGIN_CONFIG_MTU, - g_variant_new_uint32 (mtu)); - } - } - - ip4config = g_variant_builder_end (&ip4builder); - - if (g_variant_n_children (ip4config)) { - val = g_variant_new_boolean (TRUE); - g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_HAS_IP4, val); - } else { - g_variant_unref (ip4config); - ip4config = NULL; - } - - ip6config = g_variant_builder_end (&ip6builder); - - if (g_variant_n_children (ip6config)) { - val = g_variant_new_boolean (TRUE); - g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_CONFIG_HAS_IP6, val); - } else { - g_variant_unref (ip6config); - ip6config = NULL; - } - - if (!ip4config && !ip6config) - helper_failed (proxy, "IPv4 or IPv6 configuration"); - - /* Send the config info to nm-openvpn-service */ - send_config (proxy, g_variant_builder_end (&builder), ip4config, ip6config); - - g_object_unref (proxy); - - return 0; -}