summary refs log tree commit diff
path: root/clients/common/nm-vpn-helpers.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-10-05 22:27:18 +0200
committerMichael Biebl <biebl@debian.org>2020-10-05 22:27:18 +0200
commitaafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch)
treea2a9bb4d007339a0b1304540388230ccedac32bd /clients/common/nm-vpn-helpers.c
parente7b44ef4c80907346ec7492a09c45277459924fc (diff)
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'clients/common/nm-vpn-helpers.c')
-rw-r--r--clients/common/nm-vpn-helpers.c1500
1 files changed, 746 insertions, 754 deletions
diff --git a/clients/common/nm-vpn-helpers.c b/clients/common/nm-vpn-helpers.c
index 74ff52bb..8312043f 100644
--- a/clients/common/nm-vpn-helpers.c
+++ b/clients/common/nm-vpn-helpers.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2013 - 2015 Red Hat, Inc.
  */
@@ -23,807 +23,799 @@
 /*****************************************************************************/
 
 NMVpnEditorPlugin *
-nm_vpn_get_editor_plugin (const char *service_type, GError **error)
+nm_vpn_get_editor_plugin(const char *service_type, GError **error)
 {
-	NMVpnEditorPlugin *plugin = NULL;
-	NMVpnPluginInfo *plugin_info;
-	gs_free_error GError *local = NULL;
-
-	g_return_val_if_fail (service_type, NULL);
-	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
-	plugin_info = nm_vpn_plugin_info_list_find_by_service (nm_vpn_get_plugin_infos (), service_type);
-
-	if (!plugin_info) {
-		g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
-		             _("unknown VPN plugin \"%s\""), service_type);
-		return NULL;
-	}
-	plugin = nm_vpn_plugin_info_get_editor_plugin (plugin_info);
-	if (!plugin)
-		plugin = nm_vpn_plugin_info_load_editor_plugin (plugin_info, &local);
-
-	if (!plugin) {
-		if (   !nm_vpn_plugin_info_get_plugin (plugin_info)
-		    && nm_vpn_plugin_info_lookup_property (plugin_info, NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "properties")) {
-			g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
-			             _("cannot load legacy-only VPN plugin \"%s\" for \"%s\""),
-			             nm_vpn_plugin_info_get_name (plugin_info),
-			             nm_vpn_plugin_info_get_filename (plugin_info));
-		} else if (g_error_matches (local, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
-			g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
-			             _("cannot load VPN plugin \"%s\" due to missing \"%s\". Missing client plugin?"),
-			             nm_vpn_plugin_info_get_name (plugin_info),
-			             nm_vpn_plugin_info_get_plugin (plugin_info));
-		} else {
-			g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
-			             _("failed to load VPN plugin \"%s\": %s"),
-			             nm_vpn_plugin_info_get_name (plugin_info),
-			             local->message);
-		}
-		return NULL;
-	}
-
-	return plugin;
+    NMVpnEditorPlugin *plugin = NULL;
+    NMVpnPluginInfo *  plugin_info;
+    gs_free_error GError *local = NULL;
+
+    g_return_val_if_fail(service_type, NULL);
+    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
+
+    plugin_info = nm_vpn_plugin_info_list_find_by_service(nm_vpn_get_plugin_infos(), service_type);
+
+    if (!plugin_info) {
+        g_set_error(error,
+                    NM_VPN_PLUGIN_ERROR,
+                    NM_VPN_PLUGIN_ERROR_FAILED,
+                    _("unknown VPN plugin \"%s\""),
+                    service_type);
+        return NULL;
+    }
+    plugin = nm_vpn_plugin_info_get_editor_plugin(plugin_info);
+    if (!plugin)
+        plugin = nm_vpn_plugin_info_load_editor_plugin(plugin_info, &local);
+
+    if (!plugin) {
+        if (!nm_vpn_plugin_info_get_plugin(plugin_info)
+            && nm_vpn_plugin_info_lookup_property(plugin_info,
+                                                  NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME,
+                                                  "properties")) {
+            g_set_error(error,
+                        NM_VPN_PLUGIN_ERROR,
+                        NM_VPN_PLUGIN_ERROR_FAILED,
+                        _("cannot load legacy-only VPN plugin \"%s\" for \"%s\""),
+                        nm_vpn_plugin_info_get_name(plugin_info),
+                        nm_vpn_plugin_info_get_filename(plugin_info));
+        } else if (g_error_matches(local, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
+            g_set_error(
+                error,
+                NM_VPN_PLUGIN_ERROR,
+                NM_VPN_PLUGIN_ERROR_FAILED,
+                _("cannot load VPN plugin \"%s\" due to missing \"%s\". Missing client plugin?"),
+                nm_vpn_plugin_info_get_name(plugin_info),
+                nm_vpn_plugin_info_get_plugin(plugin_info));
+        } else {
+            g_set_error(error,
+                        NM_VPN_PLUGIN_ERROR,
+                        NM_VPN_PLUGIN_ERROR_FAILED,
+                        _("failed to load VPN plugin \"%s\": %s"),
+                        nm_vpn_plugin_info_get_name(plugin_info),
+                        local->message);
+        }
+        return NULL;
+    }
+
+    return plugin;
 }
 
 GSList *
-nm_vpn_get_plugin_infos (void)
+nm_vpn_get_plugin_infos(void)
 {
-	static bool plugins_loaded;
-	static GSList *plugins = NULL;
-
-	if (G_LIKELY (plugins_loaded))
-		return plugins;
-	plugins_loaded = TRUE;
-	plugins = nm_vpn_plugin_info_list_load ();
-	return plugins;
+    static bool    plugins_loaded;
+    static GSList *plugins = NULL;
+
+    if (G_LIKELY(plugins_loaded))
+        return plugins;
+    plugins_loaded = TRUE;
+    plugins        = nm_vpn_plugin_info_list_load();
+    return plugins;
 }
 
 gboolean
-nm_vpn_supports_ipv6 (NMConnection *connection)
+nm_vpn_supports_ipv6(NMConnection *connection)
 {
-	NMSettingVpn *s_vpn;
-	const char *service_type;
-	NMVpnEditorPlugin *plugin;
-	guint32 capabilities;
+    NMSettingVpn *     s_vpn;
+    const char *       service_type;
+    NMVpnEditorPlugin *plugin;
+    guint32            capabilities;
 
-	s_vpn = nm_connection_get_setting_vpn (connection);
-	g_return_val_if_fail (s_vpn != NULL, FALSE);
+    s_vpn = nm_connection_get_setting_vpn(connection);
+    g_return_val_if_fail(s_vpn != NULL, FALSE);
 
-	service_type = nm_setting_vpn_get_service_type (s_vpn);
-	if (!service_type)
-		return FALSE;
+    service_type = nm_setting_vpn_get_service_type(s_vpn);
+    if (!service_type)
+        return FALSE;
 
-	plugin = nm_vpn_get_editor_plugin (service_type, NULL);
-	if (!plugin)
-		return FALSE;
+    plugin = nm_vpn_get_editor_plugin(service_type, NULL);
+    if (!plugin)
+        return FALSE;
 
-	capabilities = nm_vpn_editor_plugin_get_capabilities (plugin);
-	return NM_FLAGS_HAS (capabilities, NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6);
+    capabilities = nm_vpn_editor_plugin_get_capabilities(plugin);
+    return NM_FLAGS_HAS(capabilities, NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6);
 }
 
 const NmcVpnPasswordName *
-nm_vpn_get_secret_names (const char *service_type)
+nm_vpn_get_secret_names(const char *service_type)
 {
-	const char *type;
-
-	if (!service_type)
-		return NULL;
-
-	if (   !NM_STR_HAS_PREFIX (service_type, NM_DBUS_INTERFACE)
-	    || service_type[NM_STRLEN (NM_DBUS_INTERFACE)] != '.') {
-		/* all our well-known, hard-coded vpn-types start with NM_DBUS_INTERFACE. */
-		return NULL;
-	}
-
-	type = service_type + (NM_STRLEN (NM_DBUS_INTERFACE) + 1);
-
-#define _VPN_PASSWORD_LIST(...) \
-	({ \
-		static const NmcVpnPasswordName _arr[] = { \
-			__VA_ARGS__ \
-			{ 0 }, \
-		}; \
-		_arr; \
-	})
-
-	if (NM_IN_STRSET (type, "pptp",
-	                        "iodine",
-	                        "ssh",
-	                        "l2tp",
-	                        "fortisslvpn")) {
-		return _VPN_PASSWORD_LIST (
-			{ "password", N_("Password") },
-		);
-	}
-
-	if (NM_IN_STRSET (type, "openvpn")) {
-		return _VPN_PASSWORD_LIST (
-			{ "password",            N_("Password") },
-			{ "cert-pass",           N_("Certificate password") },
-			{ "http-proxy-password", N_("HTTP proxy password") },
-		);
-	}
-
-	if (NM_IN_STRSET (type, "vpnc")) {
-		return _VPN_PASSWORD_LIST (
-			{ "Xauth password", N_("Password") },
-			{ "IPSec secret",   N_("Group password") },
-		);
-	};
-
-	if (NM_IN_STRSET (type, "openswan",
-	                        "libreswan",
-	                        "strongswan")) {
-		return _VPN_PASSWORD_LIST (
-			{ "xauthpassword", N_("Password") },
-			{ "pskvalue",      N_("Group password") },
-		);
-	};
-
-	if (NM_IN_STRSET (type, "openconnect")) {
-		return _VPN_PASSWORD_LIST (
-			{ "gateway", N_("Gateway") },
-			{ "cookie",  N_("Cookie") },
-			{ "gwcert",  N_("Gateway certificate hash") },
-		);
-	};
-
-	return NULL;
+    const char *type;
+
+    if (!service_type)
+        return NULL;
+
+    if (!NM_STR_HAS_PREFIX(service_type, NM_DBUS_INTERFACE)
+        || service_type[NM_STRLEN(NM_DBUS_INTERFACE)] != '.') {
+        /* all our well-known, hard-coded vpn-types start with NM_DBUS_INTERFACE. */
+        return NULL;
+    }
+
+    type = service_type + (NM_STRLEN(NM_DBUS_INTERFACE) + 1);
+
+#define _VPN_PASSWORD_LIST(...)                    \
+    ({                                             \
+        static const NmcVpnPasswordName _arr[] = { \
+            __VA_ARGS__{0},                        \
+        };                                         \
+        _arr;                                      \
+    })
+
+    if (NM_IN_STRSET(type, "pptp", "iodine", "ssh", "l2tp", "fortisslvpn")) {
+        return _VPN_PASSWORD_LIST({"password", N_("Password")}, );
+    }
+
+    if (NM_IN_STRSET(type, "openvpn")) {
+        return _VPN_PASSWORD_LIST({"password", N_("Password")},
+                                  {"cert-pass", N_("Certificate password")},
+                                  {"http-proxy-password", N_("HTTP proxy password")}, );
+    }
+
+    if (NM_IN_STRSET(type, "vpnc")) {
+        return _VPN_PASSWORD_LIST({"Xauth password", N_("Password")},
+                                  {"IPSec secret", N_("Group password")}, );
+    };
+
+    if (NM_IN_STRSET(type, "openswan", "libreswan", "strongswan")) {
+        return _VPN_PASSWORD_LIST({"xauthpassword", N_("Password")},
+                                  {"pskvalue", N_("Group password")}, );
+    };
+
+    if (NM_IN_STRSET(type, "openconnect")) {
+        return _VPN_PASSWORD_LIST({"gateway", N_("Gateway")},
+                                  {"cookie", N_("Cookie")},
+                                  {"gwcert", N_("Gateway certificate hash")}, );
+    };
+
+    return NULL;
 }
 
 static gboolean
-_extract_variable_value (char *line, const char *tag, char **value)
+_extract_variable_value(char *line, const char *tag, char **value)
 {
-	char *p1, *p2;
-
-	if (!g_str_has_prefix (line, tag))
-		return FALSE;
-
-	p1 = line + strlen (tag);
-	p2 = line + strlen (line) - 1;
-	if ((*p1 == '\'' || *p1 == '"') && (*p1 == *p2)) {
-		p1++;
-		*p2 = '\0';
-	}
-	NM_SET_OUT (value, g_strdup (p1));
-	return TRUE;
+    char *p1, *p2;
+
+    if (!g_str_has_prefix(line, tag))
+        return FALSE;
+
+    p1 = line + strlen(tag);
+    p2 = line + strlen(line) - 1;
+    if ((*p1 == '\'' || *p1 == '"') && (*p1 == *p2)) {
+        p1++;
+        *p2 = '\0';
+    }
+    NM_SET_OUT(value, g_strdup(p1));
+    return TRUE;
 }
 
 gboolean
-nm_vpn_openconnect_authenticate_helper (const char *host,
-                                        char **cookie,
-                                        char **gateway,
-                                        char **gwcert,
-                                        int *status,
-                                        GError **error)
+nm_vpn_openconnect_authenticate_helper(const char *host,
+                                       char **     cookie,
+                                       char **     gateway,
+                                       char **     gwcert,
+                                       int *       status,
+                                       GError **   error)
 {
-	gs_free char *output = NULL;
-	gs_free const char **output_v = NULL;
-	const char *const*iter;
-	const char *path;
-	const char *const DEFAULT_PATHS[] = {
-		"/sbin/",
-		"/usr/sbin/",
-		"/usr/local/sbin/",
-		"/bin/",
-		"/usr/bin/",
-		"/usr/local/bin/",
-		NULL,
-	};
-
-	path = nm_utils_file_search_in_paths ("openconnect", "/usr/sbin/openconnect", DEFAULT_PATHS,
-	                                      G_FILE_TEST_IS_EXECUTABLE, NULL, NULL, error);
-	if (!path)
-		return FALSE;
-
-	if (!g_spawn_sync (NULL,
-	                   (char **) NM_MAKE_STRV (path, "--authenticate", host),
-	                   NULL,
-	                     G_SPAWN_SEARCH_PATH
-	                   | G_SPAWN_CHILD_INHERITS_STDIN,
-	                   NULL,
-	                   NULL,
-	                   &output,
-	                   NULL,
-	                   status,
-	                   error))
-		return FALSE;
-
-	/* Parse output and set cookie, gateway and gwcert
-	 * output example:
-	 * COOKIE='loremipsum'
-	 * HOST='1.2.3.4'
-	 * FINGERPRINT='sha1:32bac90cf09a722e10ecc1942c67fe2ac8c21e2e'
-	 */
-	output_v = nm_utils_strsplit_set_with_empty (output, "\r\n");
-	for (iter = output_v; iter && *iter; iter++) {
-		char *s_mutable = (char *) *iter;
-
-		_extract_variable_value (s_mutable, "COOKIE=", cookie);
-		_extract_variable_value (s_mutable, "HOST=", gateway);
-		_extract_variable_value (s_mutable, "FINGERPRINT=", gwcert);
-	}
-
-	return TRUE;
+    gs_free char *       output   = NULL;
+    gs_free const char **output_v = NULL;
+    const char *const *  iter;
+    const char *         path;
+    const char *const    DEFAULT_PATHS[] = {
+        "/sbin/",
+        "/usr/sbin/",
+        "/usr/local/sbin/",
+        "/bin/",
+        "/usr/bin/",
+        "/usr/local/bin/",
+        NULL,
+    };
+
+    path = nm_utils_file_search_in_paths("openconnect",
+                                         "/usr/sbin/openconnect",
+                                         DEFAULT_PATHS,
+                                         G_FILE_TEST_IS_EXECUTABLE,
+                                         NULL,
+                                         NULL,
+                                         error);
+    if (!path)
+        return FALSE;
+
+    if (!g_spawn_sync(NULL,
+                      (char **) NM_MAKE_STRV(path, "--authenticate", host),
+                      NULL,
+                      G_SPAWN_SEARCH_PATH | G_SPAWN_CHILD_INHERITS_STDIN,
+                      NULL,
+                      NULL,
+                      &output,
+                      NULL,
+                      status,
+                      error))
+        return FALSE;
+
+    /* Parse output and set cookie, gateway and gwcert
+     * output example:
+     * COOKIE='loremipsum'
+     * HOST='1.2.3.4'
+     * FINGERPRINT='sha1:32bac90cf09a722e10ecc1942c67fe2ac8c21e2e'
+     */
+    output_v = nm_utils_strsplit_set_with_empty(output, "\r\n");
+    for (iter = output_v; iter && *iter; iter++) {
+        char *s_mutable = (char *) *iter;
+
+        _extract_variable_value(s_mutable, "COOKIE=", cookie);
+        _extract_variable_value(s_mutable, "HOST=", gateway);
+        _extract_variable_value(s_mutable, "FINGERPRINT=", gwcert);
+    }
+
+    return TRUE;
 }
 
 static gboolean
-_wg_complete_peer (GPtrArray **p_peers,
-                   NMWireGuardPeer *peer_take,
-                   gsize peer_start_line_nr,
-                   const char *filename,
-                   GError **error)
+_wg_complete_peer(GPtrArray **     p_peers,
+                  NMWireGuardPeer *peer_take,
+                  gsize            peer_start_line_nr,
+                  const char *     filename,
+                  GError **        error)
 {
-	nm_auto_unref_wgpeer NMWireGuardPeer *peer = peer_take;
-	gs_free_error GError *local = NULL;
-
-	if (!peer)
-		return TRUE;
-
-	if (!nm_wireguard_peer_is_valid (peer, TRUE, TRUE, &local)) {
-		nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN,
-		                    _("Invalid peer starting at %s:%zu: %s"),
-		                    filename,
-		                    peer_start_line_nr,
-		                    local->message);
-		return FALSE;
-	}
-
-	if (!*p_peers)
-		*p_peers = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_wireguard_peer_unref);
-	g_ptr_array_add (*p_peers, g_steal_pointer (&peer));
-	return TRUE;
+    nm_auto_unref_wgpeer NMWireGuardPeer *peer = peer_take;
+    gs_free_error GError *local                = NULL;
+
+    if (!peer)
+        return TRUE;
+
+    if (!nm_wireguard_peer_is_valid(peer, TRUE, TRUE, &local)) {
+        nm_utils_error_set(error,
+                           NM_UTILS_ERROR_UNKNOWN,
+                           _("Invalid peer starting at %s:%zu: %s"),
+                           filename,
+                           peer_start_line_nr,
+                           local->message);
+        return FALSE;
+    }
+
+    if (!*p_peers)
+        *p_peers = g_ptr_array_new_with_free_func((GDestroyNotify) nm_wireguard_peer_unref);
+    g_ptr_array_add(*p_peers, g_steal_pointer(&peer));
+    return TRUE;
 }
 
 static gboolean
-_line_match (char *line, const char *key, gsize key_len, const char **out_key, char **out_value)
+_line_match(char *line, const char *key, gsize key_len, const char **out_key, char **out_value)
 {
-	nm_assert (line);
-	nm_assert (key);
-	nm_assert (strlen (key) == key_len);
-	nm_assert (!strchr (key, '='));
-	nm_assert (out_key && !*out_key);
-	nm_assert (out_value && !*out_value);
-
-	/* Note that `wg-quick` (linux.bash) does case-insensitive comparison (shopt -s nocasematch).
-	 * `wg setconf` does case-insensitive comparison too (with strncasecmp, which is locale dependent).
-	 *
-	 * We do a case-insensitive comparison of the key, however in a locale-independent manner. */
-
-	if (g_ascii_strncasecmp (line, key, key_len) != 0)
-		return FALSE;
-
-	if (line[key_len] != '=')
-		return FALSE;
-
-	*out_key = key;
-	*out_value = &line[key_len + 1];
-	return TRUE;
+    nm_assert(line);
+    nm_assert(key);
+    nm_assert(strlen(key) == key_len);
+    nm_assert(!strchr(key, '='));
+    nm_assert(out_key && !*out_key);
+    nm_assert(out_value && !*out_value);
+
+    /* Note that `wg-quick` (linux.bash) does case-insensitive comparison (shopt -s nocasematch).
+     * `wg setconf` does case-insensitive comparison too (with strncasecmp, which is locale dependent).
+     *
+     * We do a case-insensitive comparison of the key, however in a locale-independent manner. */
+
+    if (g_ascii_strncasecmp(line, key, key_len) != 0)
+        return FALSE;
+
+    if (line[key_len] != '=')
+        return FALSE;
+
+    *out_key   = key;
+    *out_value = &line[key_len + 1];
+    return TRUE;
 }
 
 #define line_match(line, key, out_key, out_value) \
-	_line_match ((line), ""key"", NM_STRLEN (key), (out_key), (out_value))
+    _line_match((line), "" key "", NM_STRLEN(key), (out_key), (out_value))
 
 static gboolean
-value_split_word (char **line_remainder, char **out_word)
+value_split_word(char **line_remainder, char **out_word)
 {
-	char *str;
+    char *str;
 
-	if ((*line_remainder)[0] == '\0')
-		return FALSE;
+    if ((*line_remainder)[0] == '\0')
+        return FALSE;
 
-	*out_word = *line_remainder;
+    *out_word = *line_remainder;
 
-	str = strchrnul (*line_remainder, ',');
-	if (str[0] == ',') {
-		str[0] = '\0';
-		*line_remainder = &str[1];
-	} else
-		*line_remainder = str;
-	return TRUE;
+    str = strchrnul(*line_remainder, ',');
+    if (str[0] == ',') {
+        str[0]          = '\0';
+        *line_remainder = &str[1];
+    } else
+        *line_remainder = str;
+    return TRUE;
 }
 
 NMConnection *
-nm_vpn_wireguard_import (const char *filename,
-                         GError **error)
+nm_vpn_wireguard_import(const char *filename, GError **error)
 {
-	nm_auto_clear_secret_ptr NMSecretPtr file_content = NM_SECRET_PTR_INIT ();
-	char ifname[IFNAMSIZ];
-	gs_free char *uuid = NULL;
-	gboolean ifname_valid = FALSE;
-	const char *cstr;
-	char *line_remainder;
-	gs_unref_object NMConnection *connection = NULL;
-	NMSettingConnection *s_con;
-	NMSettingIPConfig *s_ip4;
-	NMSettingIPConfig *s_ip6;
-	NMSettingWireGuard *s_wg;
-	gs_free_error GError *local = NULL;
-	enum {
-		LINE_CONTEXT_INIT,
-		LINE_CONTEXT_INTERFACE,
-		LINE_CONTEXT_PEER,
-	} line_context;
-	gsize line_nr;
-	gsize current_peer_start_line_nr = 0;
-	nm_auto_unref_wgpeer NMWireGuardPeer *current_peer = NULL;
-	gs_unref_ptrarray GPtrArray *data_dns_search = NULL;
-	gs_unref_ptrarray GPtrArray *data_dns_v4 = NULL;
-	gs_unref_ptrarray GPtrArray *data_dns_v6 = NULL;
-	gs_unref_ptrarray GPtrArray *data_addr_v4 = NULL;
-	gs_unref_ptrarray GPtrArray *data_addr_v6 = NULL;
-	gs_unref_ptrarray GPtrArray *data_peers = NULL;
-	const char *data_private_key = NULL;
-	gint64 data_table;
-	guint data_listen_port = 0;
-	guint data_fwmark = 0;
-	guint data_mtu = 0;
-	int is_v4;
-	guint i;
-
-	g_return_val_if_fail (filename, NULL);
-	g_return_val_if_fail (!error || !*error, NULL);
-
-	/* contrary to "wg-quick", we never interpret the filename as "/etc/wireguard/$INTERFACE.conf".
-	 * If the filename has no '/', it is interpreted as relative to the current working directory.
-	 * However, we do require a suitable filename suffix and that the name corresponds to the interface
-	 * name. */
-	cstr = strrchr (filename, '/');
-	cstr = cstr ? &cstr[1] : filename;
-	if (NM_STR_HAS_SUFFIX (cstr, ".conf")) {
-		gsize len = strlen (cstr) - NM_STRLEN (".conf");
-
-		if (len > 0 && len < sizeof (ifname)) {
-			memcpy (ifname, cstr, len);
-			ifname[len] = '\0';
-
-			if (nm_utils_ifname_valid (ifname, NMU_IFACE_KERNEL, NULL))
-				ifname_valid = TRUE;
-		}
-	}
-	if (!ifname_valid) {
-		nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN,
-		                            _("The name of the WireGuard config must be a valid interface name followed by \".conf\""));
-		return FALSE;
-	}
-
-	if (!nm_utils_file_get_contents (-1,
-	                                 filename,
-	                                 10*1024*1024,
-	                                 NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET,
-	                                 &file_content.str,
-	                                 &file_content.len,
-	                                 NULL,
-	                                 error))
-		return NULL;
-
-	/* We interpret the file like `wg-quick up` and `wg setconf` do.
-	 *
-	 * Of course the WireGuard scripts do something fundamentlly different. They
-	 * perform actions to configure the WireGuard link in kernel, add routes and
-	 * addresses, and call resolvconf. It all happens at the time when the script
-	 * run.
-	 *
-	 * This code here instead generates a NetworkManager connection profile so that
-	 * NetworkManager will apply a similar configuration when later activating the profile. */
-
-#define _TABLE_AUTO  ((gint64) -1)
-#define _TABLE_OFF   ((gint64) -2)
-
-	data_table = _TABLE_AUTO;
-
-	line_remainder = file_content.str;
-	line_context = LINE_CONTEXT_INIT;
-	line_nr = 0;
-	while (line_remainder[0] != '\0') {
-		const char *matched_key = NULL;
-		char *value = NULL;
-		char *line;
-		char ch;
-		gint64 i64;
-
-		line_nr++;
-
-		line = line_remainder;
-		line_remainder = strchrnul (line, '\n');
-		if (line_remainder[0] != '\0')
-			(line_remainder++)[0] = '\0';
-
-		/* Drop all spaces and truncate at first '#'.
-		 * See wg's config_read_line().
-		 *
-		 * Note that wg-quick doesn't do that.
-		 *
-		 * Neither `wg setconf` nor `wg-quick` does a strict parsing.
-		 * We don't either. Just try to interpret the file (mostly) the same as
-		 * they would.
-		 */
-		{
-			gsize l, n;
-
-			n = 0;
-			for (l = 0; (ch = line[l]); l++) {
-				if (g_ascii_isspace (ch)) {
-					/* wg-setconf strips all whitespace before parsing the content. That means,
-					 * *[I nterface]" will be accepted. We do that too. */
-					continue;
-				}
-				if (ch == '#')
-					break;
-				line[n++] = line[l];
-			}
-			if (n == 0)
-				continue;
-			line[n] = '\0';
-		}
-
-		if (g_ascii_strcasecmp (line, "[Interface]") == 0) {
-			if (!_wg_complete_peer (&data_peers,
-			                        g_steal_pointer (&current_peer),
-			                        current_peer_start_line_nr,
-			                        filename,
-			                        error))
-				return FALSE;
-			line_context = LINE_CONTEXT_INTERFACE;
-			continue;
-		}
-
-		if (g_ascii_strcasecmp (line, "[Peer]") == 0) {
-			if (!_wg_complete_peer (&data_peers,
-			                        g_steal_pointer (&current_peer),
-			                        current_peer_start_line_nr,
-			                        filename,
-			                        error))
-				return FALSE;
-			current_peer_start_line_nr = line_nr;
-			current_peer = nm_wireguard_peer_new ();
-			line_context = LINE_CONTEXT_PEER;
-			continue;
-		}
-
-		if (line_context == LINE_CONTEXT_INTERFACE) {
-
-			if (line_match (line, "Address", &matched_key, &value)) {
-				char *value_word;
-
-				while (value_split_word (&value, &value_word)) {
-					GPtrArray **p_data_addr;
-					NMIPAddr addr_bin;
-					int addr_family;
-					int prefix_len;
-
-					if (!nm_utils_parse_inaddr_prefix_bin (AF_UNSPEC,
-					                                       value_word,
-					                                       &addr_family,
-					                                       &addr_bin,
-					                                       &prefix_len))
-						goto fail_invalid_value;
-
-					p_data_addr =   (addr_family == AF_INET)
-					              ? &data_addr_v4
-					              : &data_addr_v6;
-
-					if (!*p_data_addr)
-						*p_data_addr = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref);
-
-					g_ptr_array_add (*p_data_addr,
-					                 nm_ip_address_new_binary (addr_family,
-					                                           &addr_bin,
-					                                             prefix_len == -1
-					                                           ? ((addr_family == AF_INET) ? 32 : 128)
-					                                           : prefix_len,
-					                                           NULL));
-				}
-				continue;
-			}
-
-			if (line_match (line, "MTU", &matched_key, &value)) {
-				i64 = _nm_utils_ascii_str_to_int64 (value, 0, 0, G_MAXUINT32, -1);
-				if (i64 == -1)
-					goto fail_invalid_value;
-
-				/* wg-quick accepts the "MTU" value, but it also fetches routes to
-				 * autodetect it. NetworkManager won't do that, we can only configure
-				 * an explicit MTU or no autodetection will be performed. */
-				data_mtu = i64;
-				continue;
-			}
-
-			if (line_match (line, "DNS", &matched_key, &value)) {
-				char *value_word;
-
-				while (value_split_word (&value, &value_word)) {
-					GPtrArray **p_data_dns;
-					NMIPAddr addr_bin;
-					int addr_family;
-
-					if (nm_utils_parse_inaddr_bin (AF_UNSPEC,
-					                               value_word,
-					                               &addr_family,
-					                               &addr_bin)) {
-						p_data_dns =   (addr_family == AF_INET)
-						             ? &data_dns_v4
-						             : &data_dns_v6;
-						if (!*p_data_dns)
-							*p_data_dns = g_ptr_array_new_with_free_func (g_free);
-
-						g_ptr_array_add (*p_data_dns,
-						                 nm_utils_inet_ntop_dup (addr_family, &addr_bin));
-						continue;
-					}
-
-					if (!data_dns_search)
-						data_dns_search = g_ptr_array_new_with_free_func (g_free);
-					g_ptr_array_add (data_dns_search, g_strdup (value_word));
-				}
-				continue;
-			}
-
-			if (line_match (line, "Table", &matched_key, &value)) {
-
-				if (nm_streq (value, "auto"))
-					data_table = _TABLE_AUTO;
-				else if (nm_streq (value, "off"))
-					data_table = _TABLE_OFF;
-				else {
-					/* we don't support table names from /etc/iproute2/rt_tables
-					 * But we accept hex like `ip route add` would. */
-					i64 = _nm_utils_ascii_str_to_int64 (value, 0, 0, G_MAXINT32, -1);
-					if (i64 == -1)
-						goto fail_invalid_value;
-					data_table = i64;
-				}
-				continue;
-			}
-
-			if (   line_match (line, "PreUp", &matched_key, &value)
-			    || line_match (line, "PreDown", &matched_key, &value)
-			    || line_match (line, "PostUp", &matched_key, &value)
-			    || line_match (line, "PostDown", &matched_key, &value)) {
-				/* we don't run any scripts. Silently ignore these parameters. */
-				continue;
-			}
-
-			if (line_match (line, "SaveConfig", &matched_key, &value)) {
-				/* we ignore the setting, but enforce that it's either true or false (like
-				 * wg-quick. */
-				if (!NM_IN_STRSET (value, "true", "false"))
-					goto fail_invalid_value;
-				continue;
-			}
-
-			if (line_match (line, "ListenPort", &matched_key, &value)) {
-				/* we don't use getaddrinfo(), unlike `wg setconf`. Just interpret
-				 * the port as plain decimal number. */
-				i64 = _nm_utils_ascii_str_to_int64 (value, 10, 0, 0xFFFF, -1);
-				if (i64 == -1)
-					goto fail_invalid_value;
-				data_listen_port = i64;
-				continue;
-			}
-
-			if (line_match (line, "FwMark", &matched_key, &value)) {
-				if (nm_streq (value, "off"))
-					data_fwmark = 0;
-				else {
-					i64 = _nm_utils_ascii_str_to_int64 (value, 0, 0, G_MAXINT32, -1);
-					if (i64 == -1)
-						goto fail_invalid_value;
-					data_fwmark = i64;
-				}
-				continue;
-			}
-
-			if (line_match (line, "PrivateKey", &matched_key, &value)) {
-				if (!nm_utils_base64secret_decode (value, NM_WIREGUARD_PUBLIC_KEY_LEN, NULL))
-					goto fail_invalid_secret;
-				data_private_key = value;
-				continue;
-			}
-
-			goto fail_invalid_line;
-		}
-
-
-		if (line_context == LINE_CONTEXT_PEER) {
-
-			if (line_match (line, "Endpoint", &matched_key, &value)) {
-				if (!nm_wireguard_peer_set_endpoint (current_peer, value, FALSE))
-					goto fail_invalid_value;
-				continue;
-			}
-
-			if (line_match (line, "PublicKey", &matched_key, &value)) {
-				if (!nm_wireguard_peer_set_public_key (current_peer, value, FALSE))
-					goto fail_invalid_value;
-				continue;
-			}
-
-			if (line_match (line, "AllowedIPs", &matched_key, &value)) {
-				char *value_word;
-
-				while (value_split_word (&value, &value_word)) {
-					if (!nm_wireguard_peer_append_allowed_ip (current_peer,
-					                                          value_word,
-					                                          FALSE))
-						goto fail_invalid_value;
-				}
-				continue;
-			}
-
-			if (line_match (line, "PersistentKeepalive", &matched_key, &value)) {
-				if (nm_streq (value, "off"))
-					i64 = 0;
-				else {
-					i64 = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT16, -1);
-					if (i64 == -1)
-						goto fail_invalid_value;
-				}
-				nm_wireguard_peer_set_persistent_keepalive (current_peer, i64);
-				continue;
-			}
-
-			if (line_match (line, "PresharedKey", &matched_key, &value)) {
-				if (!nm_wireguard_peer_set_preshared_key (current_peer, value, FALSE))
-					goto fail_invalid_secret;
-				nm_wireguard_peer_set_preshared_key_flags (current_peer, NM_SETTING_SECRET_FLAG_NONE);
-				continue;
-			}
-
-			goto fail_invalid_line;
-		}
+    nm_auto_clear_secret_ptr NMSecretPtr file_content = NM_SECRET_PTR_INIT();
+    char                                 ifname[IFNAMSIZ];
+    gs_free char *                       uuid         = NULL;
+    gboolean                             ifname_valid = FALSE;
+    const char *                         cstr;
+    char *                               line_remainder;
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingIPConfig *           s_ip4;
+    NMSettingIPConfig *           s_ip6;
+    NMSettingWireGuard *          s_wg;
+    gs_free_error GError *local = NULL;
+    enum {
+        LINE_CONTEXT_INIT,
+        LINE_CONTEXT_INTERFACE,
+        LINE_CONTEXT_PEER,
+    } line_context;
+    gsize                line_nr;
+    gsize                current_peer_start_line_nr    = 0;
+    nm_auto_unref_wgpeer NMWireGuardPeer *current_peer = NULL;
+    gs_unref_ptrarray GPtrArray *data_dns_search       = NULL;
+    gs_unref_ptrarray GPtrArray *data_dns_v4           = NULL;
+    gs_unref_ptrarray GPtrArray *data_dns_v6           = NULL;
+    gs_unref_ptrarray GPtrArray *data_addr_v4          = NULL;
+    gs_unref_ptrarray GPtrArray *data_addr_v6          = NULL;
+    gs_unref_ptrarray GPtrArray *data_peers            = NULL;
+    const char *                 data_private_key      = NULL;
+    gint64                       data_table;
+    guint                        data_listen_port = 0;
+    guint                        data_fwmark      = 0;
+    guint                        data_mtu         = 0;
+    int                          is_v4;
+    guint                        i;
+
+    g_return_val_if_fail(filename, NULL);
+    g_return_val_if_fail(!error || !*error, NULL);
+
+    /* contrary to "wg-quick", we never interpret the filename as "/etc/wireguard/$INTERFACE.conf".
+     * If the filename has no '/', it is interpreted as relative to the current working directory.
+     * However, we do require a suitable filename suffix and that the name corresponds to the interface
+     * name. */
+    cstr = strrchr(filename, '/');
+    cstr = cstr ? &cstr[1] : filename;
+    if (NM_STR_HAS_SUFFIX(cstr, ".conf")) {
+        gsize len = strlen(cstr) - NM_STRLEN(".conf");
+
+        if (len > 0 && len < sizeof(ifname)) {
+            memcpy(ifname, cstr, len);
+            ifname[len] = '\0';
+
+            if (nm_utils_ifname_valid(ifname, NMU_IFACE_KERNEL, NULL))
+                ifname_valid = TRUE;
+        }
+    }
+    if (!ifname_valid) {
+        nm_utils_error_set_literal(error,
+                                   NM_UTILS_ERROR_UNKNOWN,
+                                   _("The name of the WireGuard config must be a valid interface "
+                                     "name followed by \".conf\""));
+        return FALSE;
+    }
+
+    if (!nm_utils_file_get_contents(-1,
+                                    filename,
+                                    10 * 1024 * 1024,
+                                    NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET,
+                                    &file_content.str,
+                                    &file_content.len,
+                                    NULL,
+                                    error))
+        return NULL;
+
+        /* We interpret the file like `wg-quick up` and `wg setconf` do.
+     *
+     * Of course the WireGuard scripts do something fundamentlly different. They
+     * perform actions to configure the WireGuard link in kernel, add routes and
+     * addresses, and call resolvconf. It all happens at the time when the script
+     * run.
+     *
+     * This code here instead generates a NetworkManager connection profile so that
+     * NetworkManager will apply a similar configuration when later activating the profile. */
+
+#define _TABLE_AUTO ((gint64) -1)
+#define _TABLE_OFF  ((gint64) -2)
+
+    data_table = _TABLE_AUTO;
+
+    line_remainder = file_content.str;
+    line_context   = LINE_CONTEXT_INIT;
+    line_nr        = 0;
+    while (line_remainder[0] != '\0') {
+        const char *matched_key = NULL;
+        char *      value       = NULL;
+        char *      line;
+        char        ch;
+        gint64      i64;
+
+        line_nr++;
+
+        line           = line_remainder;
+        line_remainder = strchrnul(line, '\n');
+        if (line_remainder[0] != '\0')
+            (line_remainder++)[0] = '\0';
+
+        /* Drop all spaces and truncate at first '#'.
+         * See wg's config_read_line().
+         *
+         * Note that wg-quick doesn't do that.
+         *
+         * Neither `wg setconf` nor `wg-quick` does a strict parsing.
+         * We don't either. Just try to interpret the file (mostly) the same as
+         * they would.
+         */
+        {
+            gsize l, n;
+
+            n = 0;
+            for (l = 0; (ch = line[l]); l++) {
+                if (g_ascii_isspace(ch)) {
+                    /* wg-setconf strips all whitespace before parsing the content. That means,
+                     * *[I nterface]" will be accepted. We do that too. */
+                    continue;
+                }
+                if (ch == '#')
+                    break;
+                line[n++] = line[l];
+            }
+            if (n == 0)
+                continue;
+            line[n] = '\0';
+        }
+
+        if (g_ascii_strcasecmp(line, "[Interface]") == 0) {
+            if (!_wg_complete_peer(&data_peers,
+                                   g_steal_pointer(&current_peer),
+                                   current_peer_start_line_nr,
+                                   filename,
+                                   error))
+                return FALSE;
+            line_context = LINE_CONTEXT_INTERFACE;
+            continue;
+        }
+
+        if (g_ascii_strcasecmp(line, "[Peer]") == 0) {
+            if (!_wg_complete_peer(&data_peers,
+                                   g_steal_pointer(&current_peer),
+                                   current_peer_start_line_nr,
+                                   filename,
+                                   error))
+                return FALSE;
+            current_peer_start_line_nr = line_nr;
+            current_peer               = nm_wireguard_peer_new();
+            line_context               = LINE_CONTEXT_PEER;
+            continue;
+        }
+
+        if (line_context == LINE_CONTEXT_INTERFACE) {
+            if (line_match(line, "Address", &matched_key, &value)) {
+                char *value_word;
+
+                while (value_split_word(&value, &value_word)) {
+                    GPtrArray **p_data_addr;
+                    NMIPAddr    addr_bin;
+                    int         addr_family;
+                    int         prefix_len;
+
+                    if (!nm_utils_parse_inaddr_prefix_bin(AF_UNSPEC,
+                                                          value_word,
+                                                          &addr_family,
+                                                          &addr_bin,
+                                                          &prefix_len))
+                        goto fail_invalid_value;
+
+                    p_data_addr = (addr_family == AF_INET) ? &data_addr_v4 : &data_addr_v6;
+
+                    if (!*p_data_addr)
+                        *p_data_addr =
+                            g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref);
+
+                    g_ptr_array_add(
+                        *p_data_addr,
+                        nm_ip_address_new_binary(
+                            addr_family,
+                            &addr_bin,
+                            prefix_len == -1 ? ((addr_family == AF_INET) ? 32 : 128) : prefix_len,
+                            NULL));
+                }
+                continue;
+            }
+
+            if (line_match(line, "MTU", &matched_key, &value)) {
+                i64 = _nm_utils_ascii_str_to_int64(value, 0, 0, G_MAXUINT32, -1);
+                if (i64 == -1)
+                    goto fail_invalid_value;
+
+                /* wg-quick accepts the "MTU" value, but it also fetches routes to
+                 * autodetect it. NetworkManager won't do that, we can only configure
+                 * an explicit MTU or no autodetection will be performed. */
+                data_mtu = i64;
+                continue;
+            }
+
+            if (line_match(line, "DNS", &matched_key, &value)) {
+                char *value_word;
+
+                while (value_split_word(&value, &value_word)) {
+                    GPtrArray **p_data_dns;
+                    NMIPAddr    addr_bin;
+                    int         addr_family;
+
+                    if (nm_utils_parse_inaddr_bin(AF_UNSPEC, value_word, &addr_family, &addr_bin)) {
+                        p_data_dns = (addr_family == AF_INET) ? &data_dns_v4 : &data_dns_v6;
+                        if (!*p_data_dns)
+                            *p_data_dns = g_ptr_array_new_with_free_func(g_free);
+
+                        g_ptr_array_add(*p_data_dns,
+                                        nm_utils_inet_ntop_dup(addr_family, &addr_bin));
+                        continue;
+                    }
+
+                    if (!data_dns_search)
+                        data_dns_search = g_ptr_array_new_with_free_func(g_free);
+                    g_ptr_array_add(data_dns_search, g_strdup(value_word));
+                }
+                continue;
+            }
+
+            if (line_match(line, "Table", &matched_key, &value)) {
+                if (nm_streq(value, "auto"))
+                    data_table = _TABLE_AUTO;
+                else if (nm_streq(value, "off"))
+                    data_table = _TABLE_OFF;
+                else {
+                    /* we don't support table names from /etc/iproute2/rt_tables
+                     * But we accept hex like `ip route add` would. */
+                    i64 = _nm_utils_ascii_str_to_int64(value, 0, 0, G_MAXINT32, -1);
+                    if (i64 == -1)
+                        goto fail_invalid_value;
+                    data_table = i64;
+                }
+                continue;
+            }
+
+            if (line_match(line, "PreUp", &matched_key, &value)
+                || line_match(line, "PreDown", &matched_key, &value)
+                || line_match(line, "PostUp", &matched_key, &value)
+                || line_match(line, "PostDown", &matched_key, &value)) {
+                /* we don't run any scripts. Silently ignore these parameters. */
+                continue;
+            }
+
+            if (line_match(line, "SaveConfig", &matched_key, &value)) {
+                /* we ignore the setting, but enforce that it's either true or false (like
+                 * wg-quick. */
+                if (!NM_IN_STRSET(value, "true", "false"))
+                    goto fail_invalid_value;
+                continue;
+            }
+
+            if (line_match(line, "ListenPort", &matched_key, &value)) {
+                /* we don't use getaddrinfo(), unlike `wg setconf`. Just interpret
+                 * the port as plain decimal number. */
+                i64 = _nm_utils_ascii_str_to_int64(value, 10, 0, 0xFFFF, -1);
+                if (i64 == -1)
+                    goto fail_invalid_value;
+                data_listen_port = i64;
+                continue;
+            }
+
+            if (line_match(line, "FwMark", &matched_key, &value)) {
+                if (nm_streq(value, "off"))
+                    data_fwmark = 0;
+                else {
+                    i64 = _nm_utils_ascii_str_to_int64(value, 0, 0, G_MAXINT32, -1);
+                    if (i64 == -1)
+                        goto fail_invalid_value;
+                    data_fwmark = i64;
+                }
+                continue;
+            }
+
+            if (line_match(line, "PrivateKey", &matched_key, &value)) {
+                if (!nm_utils_base64secret_decode(value, NM_WIREGUARD_PUBLIC_KEY_LEN, NULL))
+                    goto fail_invalid_secret;
+                data_private_key = value;
+                continue;
+            }
+
+            goto fail_invalid_line;
+        }
+
+        if (line_context == LINE_CONTEXT_PEER) {
+            if (line_match(line, "Endpoint", &matched_key, &value)) {
+                if (!nm_wireguard_peer_set_endpoint(current_peer, value, FALSE))
+                    goto fail_invalid_value;
+                continue;
+            }
+
+            if (line_match(line, "PublicKey", &matched_key, &value)) {
+                if (!nm_wireguard_peer_set_public_key(current_peer, value, FALSE))
+                    goto fail_invalid_value;
+                continue;
+            }
+
+            if (line_match(line, "AllowedIPs", &matched_key, &value)) {
+                char *value_word;
+
+                while (value_split_word(&value, &value_word)) {
+                    if (!nm_wireguard_peer_append_allowed_ip(current_peer, value_word, FALSE))
+                        goto fail_invalid_value;
+                }
+                continue;
+            }
+
+            if (line_match(line, "PersistentKeepalive", &matched_key, &value)) {
+                if (nm_streq(value, "off"))
+                    i64 = 0;
+                else {
+                    i64 = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT16, -1);
+                    if (i64 == -1)
+                        goto fail_invalid_value;
+                }
+                nm_wireguard_peer_set_persistent_keepalive(current_peer, i64);
+                continue;
+            }
+
+            if (line_match(line, "PresharedKey", &matched_key, &value)) {
+                if (!nm_wireguard_peer_set_preshared_key(current_peer, value, FALSE))
+                    goto fail_invalid_secret;
+                nm_wireguard_peer_set_preshared_key_flags(current_peer,
+                                                          NM_SETTING_SECRET_FLAG_NONE);
+                continue;
+            }
+
+            goto fail_invalid_line;
+        }
 
 fail_invalid_line:
-		nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
-		                    _("unrecognized line at %s:%zu"),
-		                    filename, line_nr);
-		return FALSE;
+        nm_utils_error_set(error,
+                           NM_UTILS_ERROR_INVALID_ARGUMENT,
+                           _("unrecognized line at %s:%zu"),
+                           filename,
+                           line_nr);
+        return FALSE;
 fail_invalid_value:
-		nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
-		                    _("invalid value for '%s' at %s:%zu"),
-		                    matched_key, filename, line_nr);
-		return FALSE;
+        nm_utils_error_set(error,
+                           NM_UTILS_ERROR_INVALID_ARGUMENT,
+                           _("invalid value for '%s' at %s:%zu"),
+                           matched_key,
+                           filename,
+                           line_nr);
+        return FALSE;
 fail_invalid_secret:
-		nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
-		                    _("invalid secret '%s' at %s:%zu"),
-		                    matched_key, filename, line_nr);
-		return FALSE;
-	}
-
-	if (!_wg_complete_peer (&data_peers,
-	                        g_steal_pointer (&current_peer),
-	                        current_peer_start_line_nr,
-	                        filename,
-	                        error))
-		return FALSE;
-
-	connection = nm_simple_connection_new ();
-	s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
-	nm_connection_add_setting (connection, NM_SETTING (s_con));
-	s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ());
-	nm_connection_add_setting (connection, NM_SETTING (s_ip4));
-	s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ());
-	nm_connection_add_setting (connection, NM_SETTING (s_ip6));
-	s_wg = NM_SETTING_WIREGUARD (nm_setting_wireguard_new ());
-	nm_connection_add_setting (connection, NM_SETTING (s_wg));
-
-	uuid = nm_utils_uuid_generate ();
-
-	g_object_set (s_con,
-	              NM_SETTING_CONNECTION_ID,
-	              ifname,
-	              NM_SETTING_CONNECTION_UUID,
-	              uuid,
-	              NM_SETTING_CONNECTION_TYPE,
-	              NM_SETTING_WIREGUARD_SETTING_NAME,
-	              NM_SETTING_CONNECTION_INTERFACE_NAME,
-	              ifname,
-	              NULL);
-
-	g_object_set (s_wg,
-	              NM_SETTING_WIREGUARD_PRIVATE_KEY,
-	              data_private_key,
-	              NM_SETTING_WIREGUARD_LISTEN_PORT,
-	              data_listen_port,
-	              NM_SETTING_WIREGUARD_FWMARK,
-	              data_fwmark,
-	              NM_SETTING_WIREGUARD_MTU,
-	              data_mtu,
-	              NULL);
-
-	if (data_peers) {
-		for (i = 0; i < data_peers->len; i++)
-			nm_setting_wireguard_append_peer (s_wg, data_peers->pdata[i]);
-	}
-
-	for (is_v4 = 0; is_v4 < 2; is_v4++) {
-		const char *method_disabled = is_v4 ? NM_SETTING_IP4_CONFIG_METHOD_DISABLED : NM_SETTING_IP6_CONFIG_METHOD_DISABLED;
-		const char *method_manual   = is_v4 ? NM_SETTING_IP4_CONFIG_METHOD_MANUAL   : NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
-		NMSettingIPConfig *s_ip     = is_v4 ? s_ip4                                 : s_ip6;
-		GPtrArray *data_dns         = is_v4 ? data_dns_v4                           : data_dns_v6;
-		GPtrArray *data_addr        = is_v4 ? data_addr_v4                          : data_addr_v6;
-		GPtrArray *data_dns_search2 = data_dns_search;
-
-		if (data_dns && !data_addr) {
-			/* When specifying "DNS", we also require an "Address" for the same address
-			 * family. That is because a NMSettingIPConfig cannot have @method_disabled
-			 * and DNS settings at the same time.
-			 *
-			 * We don't have addresses. Silently ignore the DNS setting. */
-			data_dns = NULL;
-			data_dns_search2 = NULL;
-		}
-
-		g_object_set (s_ip,
-		              NM_SETTING_IP_CONFIG_METHOD,
-		              data_addr ? method_manual : method_disabled,
-		              NULL);
-
-		/* For WireGuard profiles, always set dns-priority to a negative value,
-		 * so that DNS servers on other profiles get ignored. This is also what
-		 * wg-quick does, by calling `resolvconf -x`. */
-		g_object_set (s_ip,
-		              NM_SETTING_IP_CONFIG_DNS_PRIORITY,
-		              (int) -10,
-		              NULL);
-
-		if (data_addr) {
-			for (i = 0; i < data_addr->len; i++)
-				nm_setting_ip_config_add_address (s_ip, data_addr->pdata[i]);
-		}
-		if (data_dns) {
-			for (i = 0; i < data_dns->len; i++)
-				nm_setting_ip_config_add_dns (s_ip, data_dns->pdata[i]);
-
-			/* Of the wg-quick doesn't specify a search domain, assume the user
-			 * wants to use the domain server for all searches. */
-			if (!data_dns_search2)
-				nm_setting_ip_config_add_dns_search (s_ip, "~");
-		}
-		if (data_dns_search2) {
-			for (i = 0; i < data_dns_search2->len; i++)
-				nm_setting_ip_config_add_dns_search (s_ip, data_dns_search2->pdata[i]);
-		}
-
-		if (data_table == _TABLE_AUTO) {
-			/* in the "auto" setting, wg-quick adds peer-routes automatically to the main
-			 * table. NetworkManager will do that too, but there are differences:
-			 *
-			 * - NetworkManager (contrary to wg-quick) does not check whether the peer-route is necessary.
-			 *   It will always add a route for each allowed-ips range, even if there is already another
-			 *   route that would ensure packets to the endpoint are routed via the WireGuard interface.
-			 *   If you don't want that, disable "wireguard.peer-routes", and add the necessary routes
-			 *   yourself to "ipv4.routes" and "ipv6.routes".
-			 *
-			 * - With "auto", wg-quick also configures policy routing to handle default-routes (/0) to
-			 *   avoid routing loops.
-			 *   The imported connection profile will have wireguard.ip4-auto-default-route and
-			 *   wireguard.ip6-auto-default-route set to "default". It will thus configure wg-quick's
-			 *   policy routing if the profile has any AllowedIPs ranges with /0.
-			 */
-		} else if (data_table == _TABLE_OFF) {
-			if (is_v4) {
-				g_object_set (s_wg,
-				              NM_SETTING_WIREGUARD_PEER_ROUTES,
-				              FALSE,
-				              NULL);
-			}
-		} else {
-			g_object_set (s_ip,
-			              NM_SETTING_IP_CONFIG_ROUTE_TABLE,
-			              (guint) data_table,
-			              NULL);
-		}
-	}
-
-	if (!nm_connection_normalize (connection, NULL, NULL, &local)) {
-		nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
-		                    _("Failed to create WireGuard connection: %s"),
-		                    local->message);
-		return FALSE;
-	}
-
-	return g_steal_pointer (&connection);
+        nm_utils_error_set(error,
+                           NM_UTILS_ERROR_INVALID_ARGUMENT,
+                           _("invalid secret '%s' at %s:%zu"),
+                           matched_key,
+                           filename,
+                           line_nr);
+        return FALSE;
+    }
+
+    if (!_wg_complete_peer(&data_peers,
+                           g_steal_pointer(&current_peer),
+                           current_peer_start_line_nr,
+                           filename,
+                           error))
+        return FALSE;
+
+    connection = nm_simple_connection_new();
+    s_con      = NM_SETTING_CONNECTION(nm_setting_connection_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+    s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+    s_ip6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_ip6));
+    s_wg = NM_SETTING_WIREGUARD(nm_setting_wireguard_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_wg));
+
+    uuid = nm_utils_uuid_generate();
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 ifname,
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIREGUARD_SETTING_NAME,
+                 NM_SETTING_CONNECTION_INTERFACE_NAME,
+                 ifname,
+                 NULL);
+
+    g_object_set(s_wg,
+                 NM_SETTING_WIREGUARD_PRIVATE_KEY,
+                 data_private_key,
+                 NM_SETTING_WIREGUARD_LISTEN_PORT,
+                 data_listen_port,
+                 NM_SETTING_WIREGUARD_FWMARK,
+                 data_fwmark,
+                 NM_SETTING_WIREGUARD_MTU,
+                 data_mtu,
+                 NULL);
+
+    if (data_peers) {
+        for (i = 0; i < data_peers->len; i++)
+            nm_setting_wireguard_append_peer(s_wg, data_peers->pdata[i]);
+    }
+
+    for (is_v4 = 0; is_v4 < 2; is_v4++) {
+        const char *method_disabled =
+            is_v4 ? NM_SETTING_IP4_CONFIG_METHOD_DISABLED : NM_SETTING_IP6_CONFIG_METHOD_DISABLED;
+        const char *method_manual =
+            is_v4 ? NM_SETTING_IP4_CONFIG_METHOD_MANUAL : NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
+        NMSettingIPConfig *s_ip             = is_v4 ? s_ip4 : s_ip6;
+        GPtrArray *        data_dns         = is_v4 ? data_dns_v4 : data_dns_v6;
+        GPtrArray *        data_addr        = is_v4 ? data_addr_v4 : data_addr_v6;
+        GPtrArray *        data_dns_search2 = data_dns_search;
+
+        if (data_dns && !data_addr) {
+            /* When specifying "DNS", we also require an "Address" for the same address
+             * family. That is because a NMSettingIPConfig cannot have @method_disabled
+             * and DNS settings at the same time.
+             *
+             * We don't have addresses. Silently ignore the DNS setting. */
+            data_dns         = NULL;
+            data_dns_search2 = NULL;
+        }
+
+        g_object_set(s_ip,
+                     NM_SETTING_IP_CONFIG_METHOD,
+                     data_addr ? method_manual : method_disabled,
+                     NULL);
+
+        /* For WireGuard profiles, always set dns-priority to a negative value,
+         * so that DNS servers on other profiles get ignored. This is also what
+         * wg-quick does, by calling `resolvconf -x`. */
+        g_object_set(s_ip, NM_SETTING_IP_CONFIG_DNS_PRIORITY, (int) -50, NULL);
+
+        if (data_addr) {
+            for (i = 0; i < data_addr->len; i++)
+                nm_setting_ip_config_add_address(s_ip, data_addr->pdata[i]);
+        }
+        if (data_dns) {
+            for (i = 0; i < data_dns->len; i++)
+                nm_setting_ip_config_add_dns(s_ip, data_dns->pdata[i]);
+
+            /* Of the wg-quick doesn't specify a search domain, assume the user
+             * wants to use the domain server for all searches. */
+            if (!data_dns_search2)
+                nm_setting_ip_config_add_dns_search(s_ip, "~");
+        }
+        if (data_dns_search2) {
+            for (i = 0; i < data_dns_search2->len; i++)
+                nm_setting_ip_config_add_dns_search(s_ip, data_dns_search2->pdata[i]);
+        }
+
+        if (data_table == _TABLE_AUTO) {
+            /* in the "auto" setting, wg-quick adds peer-routes automatically to the main
+             * table. NetworkManager will do that too, but there are differences:
+             *
+             * - NetworkManager (contrary to wg-quick) does not check whether the peer-route is necessary.
+             *   It will always add a route for each allowed-ips range, even if there is already another
+             *   route that would ensure packets to the endpoint are routed via the WireGuard interface.
+             *   If you don't want that, disable "wireguard.peer-routes", and add the necessary routes
+             *   yourself to "ipv4.routes" and "ipv6.routes".
+             *
+             * - With "auto", wg-quick also configures policy routing to handle default-routes (/0) to
+             *   avoid routing loops.
+             *   The imported connection profile will have wireguard.ip4-auto-default-route and
+             *   wireguard.ip6-auto-default-route set to "default". It will thus configure wg-quick's
+             *   policy routing if the profile has any AllowedIPs ranges with /0.
+             */
+        } else if (data_table == _TABLE_OFF) {
+            if (is_v4) {
+                g_object_set(s_wg, NM_SETTING_WIREGUARD_PEER_ROUTES, FALSE, NULL);
+            }
+        } else {
+            g_object_set(s_ip, NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) data_table, NULL);
+        }
+    }
+
+    if (!nm_connection_normalize(connection, NULL, NULL, &local)) {
+        nm_utils_error_set(error,
+                           NM_UTILS_ERROR_INVALID_ARGUMENT,
+                           _("Failed to create WireGuard connection: %s"),
+                           local->message);
+        return FALSE;
+    }
+
+    return g_steal_pointer(&connection);
 }