Upgrade to 1.2.29

- Support creating both ends of IPsec (Libreswan) tunnels. (RHEL-67307)
 - Support leftprotoport and rightprotoport options. (RHEL-130888)
 - Fix error on duplicate key 'phase2alg'. (RHEL-128213)
 - Fix import connection with RSA key. (RHEL-125174)

Resolves: RHEL-67307 RHEL-130888 RHEL-128213 RHEL-125174

Signed-off-by: Gris Ge <fge@redhat.com>
This commit is contained in:
Gris Ge 2025-12-09 11:35:20 +08:00
parent f037751b82
commit 0348bf473c
8 changed files with 14 additions and 822 deletions

1
.gitignore vendored
View File

@ -25,3 +25,4 @@ NetworkManager-openswan-0.8.tar.gz
/NetworkManager-libreswan-1.2.24.tar.xz
/NetworkManager-libreswan-1.2.26.tar.xz
/NetworkManager-libreswan-1.2.27.tar.xz
/NetworkManager-libreswan-1.2.29.tar.xz

View File

@ -1,43 +0,0 @@
From ce3b4049ce916d23b7c8e57d43765e7eb044779b Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Mon, 13 Oct 2025 17:48:07 +0800
Subject: [PATCH] Export `esp` option
Unit test case updated.
Resolves: https://issues.redhat.com/browse/RHEL-119653
Signed-off-by: Gris Ge <fge@redhat.com>
---
shared/test-utils.c | 1 +
shared/utils.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/shared/test-utils.c b/shared/test-utils.c
index 76c903e..16a96d1 100644
--- a/shared/test-utils.c
+++ b/shared/test-utils.c
@@ -199,6 +199,7 @@ test_config_write (void)
" salifetime=24h\n"
" rightsubnet=0.0.0.0/0\n"
" rekey=yes\n"
+ " esp=aes_gcm256\n"
" phase2alg=aes_gcm256\n"
" keyingtries=1\n"
" leftxauthclient=yes\n"
diff --git a/shared/utils.c b/shared/utils.c
index cdaaaf0..ac735a5 100644
--- a/shared/utils.c
+++ b/shared/utils.c
@@ -338,7 +338,7 @@ static const struct LibreswanParam params[] = {
/* Special. */
{ NM_LIBRESWAN_KEY_REKEY, add_rekey, PARAM_PRINTABLE },
- { NM_LIBRESWAN_KEY_ESP, add },
+ { NM_LIBRESWAN_KEY_ESP, add, PARAM_PRINTABLE },
/* Used internally or just ignored altogether. */
{ NM_LIBRESWAN_KEY_VENDOR, add, PARAM_IGNORE },
--
2.51.0

View File

@ -1,425 +0,0 @@
From 50d0fc5a265b63fe14eac8e82560012ad112e4b7 Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Wed, 15 Oct 2025 16:06:19 +0800
Subject: [PATCH 1/2] Fix PSK authentication when leftid starts with `@`
When `leftid` starts with `@`, the
`/etc/ipsec.d/ipsec-<$connection_uuid>.secrets` file created will
contains content like:
```
@@cli-a.example.org: PSK "LONG_PSK_STRING"
```
To fix that issue, change both `nm_libreswan_get_ipsec_conf()` and
`nm_libreswan_config_psk_write()` to accept sanitized NmSettingVPN only.
The `nm_libreswan_config_psk_write()` will not adding any leading `@`
anymore since the leftid is already sanitized.
Signed-off-by: Gris Ge <fge@redhat.com>
---
shared/test-utils.c | 65 ++++++++++++++++++++++++++------------
shared/utils.c | 14 +++-----
shared/utils.h | 3 ++
src/nm-libreswan-service.c | 8 ++---
4 files changed, 57 insertions(+), 33 deletions(-)
diff --git a/shared/test-utils.c b/shared/test-utils.c
index 16a96d1..8bf5888 100644
--- a/shared/test-utils.c
+++ b/shared/test-utils.c
@@ -30,11 +30,14 @@ test_config_write (void)
{
GError *error = NULL;
NMSettingVpn *s_vpn;
+ NMSettingVpn *s_vpn_sanitized;
char *str;
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "right", "11.12.13.14");
- str = nm_libreswan_get_ipsec_conf (4, s_vpn, "con_name", NULL, FALSE, TRUE, &error);
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
+ g_assert_no_error (error);
+ str = nm_libreswan_get_ipsec_conf (4, s_vpn_sanitized, "con_name", NULL, FALSE, TRUE, &error);
g_assert_no_error (error);
g_assert_cmpstr (str, ==,
"conn con_name\n"
@@ -55,11 +58,14 @@ test_config_write (void)
" modecfgpull=yes\n");
g_free (str);
g_object_unref (s_vpn);
+ g_object_unref (s_vpn_sanitized);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "right", "11.12.13.14");
nm_setting_vpn_add_data_item (s_vpn, "dhgroup", "ignored");
- str = nm_libreswan_get_ipsec_conf (4, s_vpn, "con_name", NULL, FALSE, TRUE, &error);
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
+ g_assert_no_error (error);
+ str = nm_libreswan_get_ipsec_conf (4, s_vpn_sanitized, "con_name", NULL, FALSE, TRUE, &error);
g_assert_no_error (error);
g_assert_cmpstr (str, ==,
"conn con_name\n"
@@ -81,13 +87,16 @@ test_config_write (void)
g_free (str);
g_object_unref (s_vpn);
+ g_object_unref (s_vpn_sanitized);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "ikev2", "insist");
nm_setting_vpn_add_data_item (s_vpn, "leftcert", "LibreswanClient");
nm_setting_vpn_add_data_item (s_vpn, "leftid", "%fromcert");
nm_setting_vpn_add_data_item (s_vpn, "right", "11.12.13.14");
- str = nm_libreswan_get_ipsec_conf (4, s_vpn,
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
+ g_assert_no_error (error);
+ str = nm_libreswan_get_ipsec_conf (4, s_vpn_sanitized,
"f0008435-07af-4836-a53d-b43e8730e68f",
NULL, FALSE, TRUE, &error);
g_assert_no_error (error);
@@ -108,13 +117,16 @@ test_config_write (void)
" modecfgpull=yes\n");
g_free (str);
g_object_unref (s_vpn);
+ g_object_unref (s_vpn_sanitized);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "ikev2", "insist");
nm_setting_vpn_add_data_item (s_vpn, "leftrsasigkey", "hello");
nm_setting_vpn_add_data_item (s_vpn, "rightrsasigkey", "world");
nm_setting_vpn_add_data_item (s_vpn, "right", "11.12.13.14");
- str = nm_libreswan_get_ipsec_conf (4, s_vpn, "conn", NULL, FALSE, TRUE, &error);
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
+ g_assert_no_error (error);
+ str = nm_libreswan_get_ipsec_conf (4, s_vpn_sanitized, "conn", NULL, FALSE, TRUE, &error);
g_assert_no_error (error);
g_assert_cmpstr (str, ==,
"conn conn\n"
@@ -131,10 +143,13 @@ test_config_write (void)
" modecfgpull=yes\n");
g_free (str);
g_object_unref (s_vpn);
+ g_object_unref (s_vpn_sanitized);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "right", "11.12.13.14");
- str = nm_libreswan_get_ipsec_conf (3, s_vpn,
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
+ g_assert_no_error (error);
+ str = nm_libreswan_get_ipsec_conf (3, s_vpn_sanitized,
"my_con",
"/foo/bar/ifupdown hello 123 456",
TRUE, FALSE, &error);
@@ -161,6 +176,7 @@ test_config_write (void)
" nm-configured=yes");
g_free (str);
g_object_unref (s_vpn);
+ g_object_unref (s_vpn_sanitized);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "ikev2", "insist");
@@ -170,7 +186,9 @@ test_config_write (void)
nm_setting_vpn_add_data_item (s_vpn, "nm-auto-defaults", "false");
nm_setting_vpn_add_data_item (s_vpn, "leftsendcert", "always");
nm_setting_vpn_add_data_item (s_vpn, "rightca", "%same");
- str = nm_libreswan_get_ipsec_conf (4, s_vpn, "conn", NULL, FALSE, TRUE, &error);
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
+ g_assert_no_error (error);
+ str = nm_libreswan_get_ipsec_conf (4, s_vpn_sanitized, "conn", NULL, FALSE, TRUE, &error);
g_assert_no_error (error);
g_assert_cmpstr (str, ==,
"conn conn\n"
@@ -182,11 +200,14 @@ test_config_write (void)
" rightca=\"%same\"\n");
g_free (str);
g_object_unref (s_vpn);
+ g_object_unref (s_vpn_sanitized);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "right", "11.12.13.14");
nm_setting_vpn_add_data_item (s_vpn, "esp", "aes_gcm256");
- str = nm_libreswan_get_ipsec_conf (4, s_vpn, "con_name", NULL, FALSE, TRUE, &error);
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
+ g_assert_no_error (error);
+ str = nm_libreswan_get_ipsec_conf (4, s_vpn_sanitized, "con_name", NULL, FALSE, TRUE, &error);
g_assert_no_error (error);
g_assert_cmpstr (str, ==,
"conn con_name\n"
@@ -209,11 +230,14 @@ test_config_write (void)
" modecfgpull=yes\n");
g_free (str);
g_object_unref (s_vpn);
+ g_object_unref (s_vpn_sanitized);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "right", "11.12.13.14");
nm_setting_vpn_add_data_item (s_vpn, "vendor", "Cisco");
- str = nm_libreswan_get_ipsec_conf (4, s_vpn, "con_name", NULL, FALSE, TRUE, &error);
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
+ g_assert_no_error (error);
+ str = nm_libreswan_get_ipsec_conf (4, s_vpn_sanitized, "con_name", NULL, FALSE, TRUE, &error);
g_assert_no_error (error);
g_assert_cmpstr (str, ==,
"conn con_name\n"
@@ -235,53 +259,54 @@ test_config_write (void)
" modecfgpull=yes\n");
g_free (str);
g_object_unref (s_vpn);
+ g_object_unref (s_vpn_sanitized);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
- str = nm_libreswan_get_ipsec_conf (4, s_vpn, "conn", NULL, FALSE, TRUE, &error);
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
g_assert_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT);
- g_assert_null (str);
g_clear_error (&error);
g_object_unref (s_vpn);
+ g_assert_null (s_vpn_sanitized);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "right", "11.12.13.14");
nm_setting_vpn_add_data_item (s_vpn, "ikev2", "hello world");
- str = nm_libreswan_get_ipsec_conf (4, s_vpn, "conn", NULL, FALSE, TRUE, &error);
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
g_assert_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT);
- g_assert_null (str);
g_clear_error (&error);
g_object_unref (s_vpn);
+ g_assert_null (s_vpn_sanitized);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "right", "11.12\n13.14");
- str = nm_libreswan_get_ipsec_conf (4, s_vpn, "conn", NULL, FALSE, TRUE, &error);
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
g_assert_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT);
- g_assert_null (str);
+ g_assert_null (s_vpn_sanitized);
g_clear_error (&error);
g_object_unref (s_vpn);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "rightcert", "\"cert\"");
- str = nm_libreswan_get_ipsec_conf (4, s_vpn, "conn", NULL, FALSE, TRUE, &error);
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
g_assert_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT);
- g_assert_null (str);
+ g_assert_null (s_vpn_sanitized);
g_clear_error (&error);
g_object_unref (s_vpn);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "nm-auto-defaults", "false");
nm_setting_vpn_add_data_item (s_vpn, "rightcert", "\"cert\"");
- str = nm_libreswan_get_ipsec_conf (4, s_vpn, "conn", NULL, FALSE, TRUE, &error);
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
g_assert_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT);
- g_assert_null (str);
+ g_assert_null (s_vpn_sanitized);
g_clear_error (&error);
g_object_unref (s_vpn);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
nm_setting_vpn_add_data_item (s_vpn, "nm-auto-defaults", "false");
- str = nm_libreswan_get_ipsec_conf (4, s_vpn, "conn", NULL, FALSE, TRUE, &error);
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
g_assert_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT);
- g_assert_null (str);
+ g_assert_null (s_vpn_sanitized);
g_clear_error (&error);
g_object_unref (s_vpn);
}
diff --git a/shared/utils.c b/shared/utils.c
index ac735a5..8dab313 100644
--- a/shared/utils.c
+++ b/shared/utils.c
@@ -384,7 +384,7 @@ check_val (const char *val, gboolean allow_spaces, GError **error)
return TRUE;
}
-static NMSettingVpn *
+NMSettingVpn *
sanitize_setting_vpn (NMSettingVpn *s_vpn,
GError **error)
{
@@ -458,34 +458,30 @@ sanitize_setting_vpn (NMSettingVpn *s_vpn,
char *
nm_libreswan_get_ipsec_conf (int ipsec_version,
- NMSettingVpn *s_vpn,
+ NMSettingVpn *s_vpn_sanitized,
const char *con_name,
const char *leftupdown_script,
gboolean openswan,
gboolean trailing_newline,
GError **error)
{
- gs_unref_object NMSettingVpn *sanitized = NULL;
nm_auto_free_gstring GString *ipsec_conf = NULL;
const char *val;
int i;
- g_return_val_if_fail (NM_IS_SETTING_VPN (s_vpn), NULL);
+ g_return_val_if_fail (NM_IS_SETTING_VPN (s_vpn_sanitized), NULL);
g_return_val_if_fail (!error || !*error, NULL);
g_return_val_if_fail (con_name && *con_name, NULL);
if (!check_val (con_name, FALSE, error))
return NULL;
- sanitized = sanitize_setting_vpn (s_vpn, error);
- if (!sanitized)
- return NULL;
-
ipsec_conf = g_string_sized_new (1024);
g_string_append_printf (ipsec_conf, "conn %s\n", con_name);
for (i = 0; params[i].name != NULL; i++) {
- val = nm_setting_vpn_get_data_item (sanitized, params[i].name);
+ val = nm_setting_vpn_get_data_item (s_vpn_sanitized,
+ params[i].name);
if (val == NULL)
continue;
diff --git a/shared/utils.h b/shared/utils.h
index 67718e9..7832966 100644
--- a/shared/utils.h
+++ b/shared/utils.h
@@ -64,4 +64,7 @@ const char *nm_libreswan_find_helper_libexec (const char *progname, GError **err
gboolean nm_libreswan_parse_subnets (const char *str, GPtrArray *arr, GError **error);
char *nm_libreswan_normalize_subnets (const char *str, GError **error);
+NMSettingVpn *sanitize_setting_vpn (NMSettingVpn *s_vpn, GError **error);
+
+
#endif /* __UTILS_H__ */
diff --git a/src/nm-libreswan-service.c b/src/nm-libreswan-service.c
index 7987ada..58ada03 100644
--- a/src/nm-libreswan-service.c
+++ b/src/nm-libreswan-service.c
@@ -522,8 +522,7 @@ nm_libreswan_config_psk_write (NMSettingVpn *s_vpn,
/* nm_libreswan_get_ipsec_conf() in _connect_common should've checked these. */
g_return_val_if_fail (strchr (leftid, '"') == NULL, FALSE);
g_return_val_if_fail (strchr (leftid, '\n') == NULL, FALSE);
-
- secrets = g_strdup_printf ("@%s: PSK \"%s\"", leftid, psk);
+ secrets = g_strdup_printf ("%s: PSK \"%s\"", leftid, psk);
} else {
right = nm_setting_vpn_get_data_item (s_vpn, NM_LIBRESWAN_KEY_RIGHT);
@@ -1757,7 +1756,7 @@ _connect_common (NMVpnServicePlugin *plugin,
{
NMLibreswanPlugin *self = NM_LIBRESWAN_PLUGIN (plugin);
NMLibreswanPluginPrivate *priv = NM_LIBRESWAN_PLUGIN_GET_PRIVATE (self);
- NMSettingVpn *s_vpn;
+ gs_unref_object NMSettingVpn *s_vpn = NULL;
const char *con_name = nm_connection_get_uuid (connection);
gs_free char *ipsec_banner = NULL;
gs_free char *ifupdown_script = NULL;
@@ -1795,7 +1794,8 @@ _connect_common (NMVpnServicePlugin *plugin,
return FALSE;
}
- s_vpn = nm_connection_get_setting_vpn (connection);
+ s_vpn = sanitize_setting_vpn(nm_connection_get_setting_vpn (connection),
+ error);
g_assert (s_vpn);
g_object_get (self, NM_VPN_SERVICE_PLUGIN_DBUS_SERVICE_NAME, &bus_name, NULL);
--
2.51.0
From 55aa9f0e48acfe1ff5ee06825139bc6bdd59b4cc Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Fri, 17 Oct 2025 16:58:30 +0800
Subject: [PATCH 2/2] Copy secrets when sanitizing
The PSK authentication is not wkring because the
`sanitize_setting_vpn()` never copy secrets.
Fixed by introduce `PARAM_SECRET` and change `sanitize_setting_vpn()` to
copy secrets.
Signed-off-by: Gris Ge <fge@redhat.com>
---
shared/utils.c | 46 +++++++++++++++++++++++++++++++---------------
1 file changed, 31 insertions(+), 15 deletions(-)
diff --git a/shared/utils.c b/shared/utils.c
index 8dab313..9cb36be 100644
--- a/shared/utils.c
+++ b/shared/utils.c
@@ -38,6 +38,7 @@ enum LibreswanParamFlags {
PARAM_OLD = 0x0010, /* Only include for libreswan < 4. */
PARAM_NEW = 0x0020, /* Only include for libreswan >= 4. */
PARAM_IGNORE = 0x0040, /* Not passed to or from Libreswan. */
+ PARAM_SECRET = 0x0080, /* For secrets */
};
struct LibreswanParam {
@@ -347,7 +348,9 @@ static const struct LibreswanParam params[] = {
{ NM_LIBRESWAN_KEY_PFSGROUP, add, PARAM_IGNORE },
{ NM_LIBRESWAN_KEY_PSK_INPUT_MODES, add, PARAM_IGNORE },
{ NM_LIBRESWAN_KEY_XAUTH_PASSWORD_INPUT_MODES, add, PARAM_IGNORE },
+ { NM_LIBRESWAN_KEY_PSK_VALUE, add, PARAM_IGNORE | PARAM_SECRET},
{ NM_LIBRESWAN_KEY_PSK_VALUE "-flags", add, PARAM_IGNORE },
+ { NM_LIBRESWAN_KEY_XAUTH_PASSWORD, add, PARAM_IGNORE | PARAM_SECRET},
{ NM_LIBRESWAN_KEY_XAUTH_PASSWORD "-flags", add, PARAM_IGNORE },
{ NM_LIBRESWAN_KEY_NM_AUTO_DEFAULTS, add, PARAM_IGNORE },
@@ -407,22 +410,35 @@ sanitize_setting_vpn (NMSettingVpn *s_vpn,
TRUE);
for (i = 0; params[i].name != NULL; i++) {
- val = nm_setting_vpn_get_data_item (s_vpn, params[i].name);
- if (val != NULL) {
- handled_items++;
- } else if (params[i].flags & PARAM_REQUIRED) {
- g_set_error (error,
- NM_UTILS_ERROR,
- NM_UTILS_ERROR_INVALID_ARGUMENT,
- _("'%s' key needs to be present"),
- params[i].name);
- return NULL;
- }
-
- if (auto_defaults) {
- params[i].add_sanitized (sanitized, params[i].name, val);
+ if (params[i].flags & PARAM_SECRET) {
+ val = nm_setting_vpn_get_secret(s_vpn, params[i].name);
+ if (val != NULL) {
+ nm_setting_vpn_add_secret(sanitized,
+ params[i].name,
+ val);
+ }
} else {
- nm_setting_vpn_add_data_item (sanitized, params[i].name, val);
+ val = nm_setting_vpn_get_data_item (s_vpn,
+ params[i].name);
+ if (val != NULL) {
+ handled_items++;
+ } else if (params[i].flags & PARAM_REQUIRED) {
+ g_set_error (error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("'%s' key needs to be present"),
+ params[i].name);
+ return NULL;
+ }
+
+ if (auto_defaults) {
+ params[i].add_sanitized (sanitized,
+ params[i].name, val);
+ } else {
+ nm_setting_vpn_add_data_item (sanitized,
+ params[i].name,
+ val);
+ }
}
val = nm_setting_vpn_get_data_item (sanitized, params[i].name);
--
2.51.0

View File

@ -1,228 +0,0 @@
From a304902564b3f27080da30c0e5c9adfe6f1071c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= <ihuguet@riseup.net>
Date: Thu, 16 Oct 2025 12:45:41 +0200
Subject: [PATCH] import/export: add special comment for nm-auto-defaults
detection
In commit 3ea80883fef we added the nm-auto-defaults property to allow
interpreting configurations just like Libreswan, without assumptions
like setting leftmodecfgclient=yes by default, which is different to
what Libreswan would do.
This means that with nm-auto-defaults=no the behaviour is slightly
different. When we export a connection with nm-auto-defaults=no, we
cannot reflect it in the exported file, as it is not a valid option in
Libreswan. If we import back the same file, it will be imported as
nm-auto-defaults=yes (by default), thus it will have different
behaviour. This is wrong, export & import should be symetric.
Make the "write" function to emit a `# nm-auto-defaults=no` comment in
the exported file. When importing, make the "parse" function to
interpret this special comment as `nm-auto-defaults=no`. This will
ensure that we can export & import symetrically.
The comment can also be added manually to any file that users want to
import.
Note: increase the minimum GLib version to 2.44 to use g_autoptr. It was
released more than 10 years ago, so we're quite safe.
---
configure.ac | 6 ++---
shared/test-utils.c | 57 ++++++++++++++++++++++++++++++++++++++++++---
shared/utils.c | 25 ++++++++++++++++++--
3 files changed, 80 insertions(+), 8 deletions(-)
diff --git a/configure.ac b/configure.ac
index 9b9677a..f87ffdf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -116,9 +116,9 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package])
IT_PROG_INTLTOOL([0.35])
AM_GLIB_GNU_GETTEXT
-PKG_CHECK_MODULES(GLIB, gio-unix-2.0 >= 2.36)
-GLIB_CFLAGS="$GLIB_CFLAGS -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_36"
-GLIB_CFLAGS="$GLIB_CFLAGS -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36"
+PKG_CHECK_MODULES(GLIB, gio-unix-2.0 >= 2.44)
+GLIB_CFLAGS="$GLIB_CFLAGS -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_44"
+GLIB_CFLAGS="$GLIB_CFLAGS -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_44"
PKG_CHECK_MODULES(LIBNL, libnl-3.0 >= 3.2.8)
diff --git a/shared/test-utils.c b/shared/test-utils.c
index 8bf5888..c523c9c 100644
--- a/shared/test-utils.c
+++ b/shared/test-utils.c
@@ -183,7 +183,7 @@ test_config_write (void)
nm_setting_vpn_add_data_item (s_vpn, "leftrsasigkey", "hello");
nm_setting_vpn_add_data_item (s_vpn, "rightrsasigkey", "world");
nm_setting_vpn_add_data_item (s_vpn, "right", "11.12.13.14");
- nm_setting_vpn_add_data_item (s_vpn, "nm-auto-defaults", "false");
+ nm_setting_vpn_add_data_item (s_vpn, "nm-auto-defaults", "no");
nm_setting_vpn_add_data_item (s_vpn, "leftsendcert", "always");
nm_setting_vpn_add_data_item (s_vpn, "rightca", "%same");
s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
@@ -191,6 +191,9 @@ test_config_write (void)
str = nm_libreswan_get_ipsec_conf (4, s_vpn_sanitized, "conn", NULL, FALSE, TRUE, &error);
g_assert_no_error (error);
g_assert_cmpstr (str, ==,
+ "# NetworkManager specific configs, don't remove:\n"
+ "# nm-auto-defaults=no\n"
+ "\n"
"conn conn\n"
" ikev2=insist\n"
" right=11.12.13.14\n"
@@ -294,7 +297,7 @@ test_config_write (void)
g_object_unref (s_vpn);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
- nm_setting_vpn_add_data_item (s_vpn, "nm-auto-defaults", "false");
+ nm_setting_vpn_add_data_item (s_vpn, "nm-auto-defaults", "no");
nm_setting_vpn_add_data_item (s_vpn, "rightcert", "\"cert\"");
s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
g_assert_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT);
@@ -303,7 +306,7 @@ test_config_write (void)
g_object_unref (s_vpn);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
- nm_setting_vpn_add_data_item (s_vpn, "nm-auto-defaults", "false");
+ nm_setting_vpn_add_data_item (s_vpn, "nm-auto-defaults", "no");
s_vpn_sanitized = sanitize_setting_vpn (s_vpn, &error);
g_assert_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT);
g_assert_null (s_vpn_sanitized);
@@ -612,6 +615,54 @@ test_config_read (void)
g_object_unref (s_vpn);
g_clear_pointer (&con_name, g_free);
+ /* With the '# nm-auto-defaults=no' special comment */
+ s_vpn = nm_libreswan_parse_ipsec_conf (
+ "# nm-auto-defaults=no\n"
+ "conn conn\n"
+ " ikev2=insist\n"
+ " right=11.12.13.14\n"
+ " rightrsasigkey=\"world\"\n"
+ " leftrsasigkey=\"hello\"\n"
+ " leftsendcert=always\n"
+ " rightca=\"%same\"\n",
+ &con_name,
+ &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "ikev2"), ==, "insist");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "leftrsasigkey"), == , "hello");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "rightrsasigkey"), == , "world");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "right"), == , "11.12.13.14");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "nm-auto-defaults"), == , "no");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "leftsendcert"), == , "always");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "rightca"), == , "%same");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "rightca"), == , "%same");
+ g_object_unref (s_vpn);
+ g_clear_pointer (&con_name, g_free);
+
+ /* With the '# nm-auto-defaults=no' special comment, different spacing */
+ s_vpn = nm_libreswan_parse_ipsec_conf (
+ "#nm-auto-defaults = no \n"
+ "conn conn\n"
+ " ikev2=insist\n"
+ " right=11.12.13.14\n"
+ " rightrsasigkey=\"world\"\n"
+ " leftrsasigkey=\"hello\"\n"
+ " leftsendcert=always\n"
+ " rightca=\"%same\"\n",
+ &con_name,
+ &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "ikev2"), ==, "insist");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "leftrsasigkey"), == , "hello");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "rightrsasigkey"), == , "world");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "right"), == , "11.12.13.14");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "nm-auto-defaults"), == , "no");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "leftsendcert"), == , "always");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "rightca"), == , "%same");
+ g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, "rightca"), == , "%same");
+ g_object_unref (s_vpn);
+ g_clear_pointer (&con_name, g_free);
+
s_vpn = nm_libreswan_parse_ipsec_conf (
"conn my_con\n",
&con_name,
diff --git a/shared/utils.c b/shared/utils.c
index 9cb36be..c188e5b 100644
--- a/shared/utils.c
+++ b/shared/utils.c
@@ -482,6 +482,7 @@ nm_libreswan_get_ipsec_conf (int ipsec_version,
GError **error)
{
nm_auto_free_gstring GString *ipsec_conf = NULL;
+ gboolean auto_defaults;
const char *val;
int i;
@@ -493,6 +494,16 @@ nm_libreswan_get_ipsec_conf (int ipsec_version,
return NULL;
ipsec_conf = g_string_sized_new (1024);
+
+ auto_defaults = _nm_utils_ascii_str_to_bool (
+ nm_setting_vpn_get_data_item (s_vpn_sanitized, NM_LIBRESWAN_KEY_NM_AUTO_DEFAULTS),
+ TRUE);
+ if (!auto_defaults) {
+ g_string_append(ipsec_conf, "# NetworkManager specific configs, don't remove:\n");
+ g_string_append(ipsec_conf, "# nm-auto-defaults=no\n");
+ g_string_append(ipsec_conf, "\n");
+ }
+
g_string_append_printf (ipsec_conf, "conn %s\n", con_name);
for (i = 0; params[i].name != NULL; i++) {
@@ -573,6 +584,8 @@ static const char line_match[] =
")?" /* (or just blank line) */
"\\s*(?:#.*)?$"; /* optional comment */
+static const char no_auto_match[] = "#\\s*nm-auto-defaults\\s*=\\s*no";
+
NMSettingVpn *
nm_libreswan_parse_ipsec_conf (const char *ipsec_conf,
char **out_con_name,
@@ -584,7 +597,8 @@ nm_libreswan_parse_ipsec_conf (const char *ipsec_conf,
gs_free char *con_name = NULL;
GMatchInfo *match_info = NULL;
GError *parse_error = NULL;
- GRegex *line_regex;
+ g_autoptr(GRegex) line_regex = NULL;
+ g_autoptr(GRegex) no_auto_regex = NULL;
const char *old, *new;
const char *rekey;
char *key, *val;
@@ -596,6 +610,8 @@ nm_libreswan_parse_ipsec_conf (const char *ipsec_conf,
line_regex = g_regex_new (line_match, G_REGEX_RAW, 0, NULL);
g_return_val_if_fail (line_regex, NULL);
+ no_auto_regex = g_regex_new (no_auto_match, G_REGEX_RAW, 0, NULL);
+ g_return_val_if_fail (no_auto_regex, NULL);
s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
@@ -611,6 +627,11 @@ nm_libreswan_parse_ipsec_conf (const char *ipsec_conf,
break;
}
+ if (g_regex_match(no_auto_regex, lines[i], 0, NULL)) {
+ nm_setting_vpn_add_data_item(s_vpn, NM_LIBRESWAN_KEY_NM_AUTO_DEFAULTS, "no");
+ continue;
+ }
+
key = g_match_info_fetch (match_info, 1); /* Key */
val = g_match_info_fetch (match_info, 2); /* Unquoted value */
/* Without fix from
@@ -666,7 +687,7 @@ nm_libreswan_parse_ipsec_conf (const char *ipsec_conf,
if (parse_error)
break;
}
- g_regex_unref (line_regex);
+
if (parse_error) {
g_propagate_error (error, parse_error);
return NULL;
--
2.51.0

View File

@ -1,54 +0,0 @@
From 15946667c771ba88d38f82cc467fd52d268e44bb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= <ihuguet@riseup.net>
Date: Tue, 21 Oct 2025 08:37:35 +0200
Subject: [PATCH] export: sanitize before exporting (RHEL only)
The commit referenced below moved the responsibility of sanitizing the
connection from nm_libreswan_get_ipsec_conf to its caller, but it forgot
to sanitize in export_to_file(). Fix it.
This is a RHEL-only patch, as this is fixed by a later commit that we
didn't want to backport yet. When we rebase, this patch can be dropped.
Fixes: 50d0fc5a265b ('Fix PSK authentication when leftid starts with `@`')
---
properties/nm-libreswan-editor-plugin.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/properties/nm-libreswan-editor-plugin.c b/properties/nm-libreswan-editor-plugin.c
index 2b455ba..7a75e09 100644
--- a/properties/nm-libreswan-editor-plugin.c
+++ b/properties/nm-libreswan-editor-plugin.c
@@ -91,6 +91,7 @@ export_to_file (NMVpnEditorPlugin *self,
GError **error)
{
NMSettingVpn *s_vpn;
+ gs_unref_object NMSettingVpn *s_vpn_sanitized = NULL;
gboolean openswan = FALSE;
gs_free_error GError *local = NULL;
gs_free char *ipsec_conf = NULL;
@@ -98,8 +99,19 @@ export_to_file (NMVpnEditorPlugin *self,
int version;
s_vpn = nm_connection_get_setting_vpn (connection);
- if (s_vpn)
- openswan = nm_streq (nm_setting_vpn_get_service_type (s_vpn), NM_VPN_SERVICE_TYPE_OPENSWAN);
+ if (!s_vpn) {
+ g_set_error_literal (error,
+ NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION,
+ _("Empty VPN setting."));
+ return FALSE;
+ }
+
+ s_vpn_sanitized = sanitize_setting_vpn (s_vpn, error);
+ if (!s_vpn_sanitized)
+ return FALSE;
+
+ s_vpn = s_vpn_sanitized;
+ openswan = nm_streq (nm_setting_vpn_get_service_type (s_vpn), NM_VPN_SERVICE_TYPE_OPENSWAN);
nm_libreswan_detect_version (nm_libreswan_find_helper_bin ("ipsec", NULL),
&is_openswan, &version, NULL);
--
2.51.0

View File

@ -1,61 +0,0 @@
From 397096f85c155d18834e8f7b90b1ea439344cd32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= <ihuguet@riseup.net>
Date: Thu, 23 Oct 2025 11:54:46 +0200
Subject: [PATCH] service: don't crash with malformed connections
If a connection is malformed, i.e. by having incorrect values, a crash
(or something worse) could happen in _connect_common because we were
assuming that the value returned from sanitize_setting_vpn() must be
non-NULL. If the connection is malformed, it will be NULL.
Fix it by gracefully handling this scenario.
This is a RHEL-only patch, as this is fixed by a later commit that we
didn't want to backport yet. When we rebase, this patch can be dropped.
Fixes: 50d0fc5a265b ('Fix PSK authentication when leftid starts with `@`')
---
src/nm-libreswan-service.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/src/nm-libreswan-service.c b/src/nm-libreswan-service.c
index 58ada03..a093547 100644
--- a/src/nm-libreswan-service.c
+++ b/src/nm-libreswan-service.c
@@ -1756,7 +1756,8 @@ _connect_common (NMVpnServicePlugin *plugin,
{
NMLibreswanPlugin *self = NM_LIBRESWAN_PLUGIN (plugin);
NMLibreswanPluginPrivate *priv = NM_LIBRESWAN_PLUGIN_GET_PRIVATE (self);
- gs_unref_object NMSettingVpn *s_vpn = NULL;
+ NMSettingVpn *s_vpn;
+ gs_unref_object NMSettingVpn *s_vpn_sanitized = NULL;
const char *con_name = nm_connection_get_uuid (connection);
gs_free char *ipsec_banner = NULL;
gs_free char *ifupdown_script = NULL;
@@ -1794,9 +1795,20 @@ _connect_common (NMVpnServicePlugin *plugin,
return FALSE;
}
- s_vpn = sanitize_setting_vpn(nm_connection_get_setting_vpn (connection),
- error);
- g_assert (s_vpn);
+ s_vpn = nm_connection_get_setting_vpn(connection);
+ if (!s_vpn) {
+ g_set_error_literal(error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION,
+ _("Empty VPN setting."));
+ return FALSE;
+ }
+
+ s_vpn_sanitized = sanitize_setting_vpn(s_vpn, error);
+ if (!s_vpn_sanitized)
+ return FALSE;
+
+ s_vpn = s_vpn_sanitized;
g_object_get (self, NM_VPN_SERVICE_PLUGIN_DBUS_SERVICE_NAME, &bus_name, NULL);
--
2.51.0

View File

@ -14,17 +14,12 @@
Summary: NetworkManager VPN plug-in for IPsec VPN
Name: NetworkManager-libreswan
Version: 1.2.27
Release: 4%{?dist}
Version: 1.2.29
Release: 1%{?dist}
License: GPL-2.0-or-later
URL: https://gitlab.gnome.org/GNOME/NetworkManager-libreswan
Source0: https://download.gnome.org/sources/NetworkManager-libreswan/1.2/%{name}-%{version}.tar.xz
Patch0: 0001-Export-esp-option.patch
Patch1: 0002-fix-psk-auth-when-leftid-starts-with-at.patch
Patch2: 0003-import-export-nm-auto-defaults-no.patch
Patch3: 0004-sanitize-before-exporting-RHEL-only.patch
Patch4: 0005-service-don-t-crash-with-malformed-connections.patch
BuildRequires: make
BuildRequires: gcc
BuildRequires: gtk3-devel
@ -128,6 +123,13 @@ mv %{buildroot}%{_sysconfdir}/dbus-1 %{buildroot}%{_datadir}/
%changelog
* Tue Dec 09 2025 Gris Ge <fge@redhat.com> - 1.2.29-1
- Upgrade to 1.2.29
- Support creating both ends of IPsec (Libreswan) tunnels. (RHEL-67307)
- Support leftprotoport and rightprotoport options. (RHEL-130888)
- Fix error on duplicate key 'phase2alg'. (RHEL-128213)
- Fix import connection with RSA key. (RHEL-125174)
* Thu Oct 23 2025 Vladimír Beneš <vbenes@redhat.com> - 1.2.27-4
- Fix potentional crash in malformed items import
@ -135,9 +137,9 @@ mv %{buildroot}%{_sysconfdir}/dbus-1 %{buildroot}%{_datadir}/
- Fix a regression in nm-auto-defaults=yes
* Mon Oct 20 2025 Vladimír Beneš <vbenes@redhat.com> - 1.2.27-2
* Symetric import/export with nm-auto-default (RHEL-119641)
* Esp param properly exported (RHEL-119653)
* Correct leftid export when it contains @
- Symetric import/export with nm-auto-default (RHEL-119641)
- Esp param properly exported (RHEL-119653)
- Correct leftid export when it contains @
* Wed Oct 01 2025 Lubomir Rintel <lkundrak@v3.sk> - 1.2.27-1
- Update to later upstream release to address regressions (RHEL-56551)

View File

@ -1 +1 @@
SHA512 (NetworkManager-libreswan-1.2.27.tar.xz) = e2a8be105bd839a7aba72ef265609b7ddea5fae0f30deac08c2ea205c5455974012ee5d93e5f3fc9575c9ee33d42f5f3f52d1ed4f28a38c9685c71272035f129
SHA512 (NetworkManager-libreswan-1.2.29.tar.xz) = 9cbf439d98292c8af1ee3855b8dde486b4b46fb479b858b10f8e64091c3e47b3cd799ac47348b5be277d24366eb171c09c8f62c2692c0dd92ec2d321abff6e48