diff --git a/0001-Export-esp-option.patch b/0001-Export-esp-option.patch new file mode 100644 index 0000000..52f4822 --- /dev/null +++ b/0001-Export-esp-option.patch @@ -0,0 +1,43 @@ +From ce3b4049ce916d23b7c8e57d43765e7eb044779b Mon Sep 17 00:00:00 2001 +From: Gris Ge +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 +--- + 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 + diff --git a/0002-fix-psk-auth-when-leftid-starts-with-at.patch b/0002-fix-psk-auth-when-leftid-starts-with-at.patch new file mode 100644 index 0000000..5aab561 --- /dev/null +++ b/0002-fix-psk-auth-when-leftid-starts-with-at.patch @@ -0,0 +1,425 @@ +From 50d0fc5a265b63fe14eac8e82560012ad112e4b7 Mon Sep 17 00:00:00 2001 +From: Gris Ge +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 +--- + 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 +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 +--- + 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 + diff --git a/0003-import-export-nm-auto-defaults-no.patch b/0003-import-export-nm-auto-defaults-no.patch new file mode 100644 index 0000000..4d075c2 --- /dev/null +++ b/0003-import-export-nm-auto-defaults-no.patch @@ -0,0 +1,228 @@ +From a304902564b3f27080da30c0e5c9adfe6f1071c0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +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 + diff --git a/NetworkManager-libreswan.spec b/NetworkManager-libreswan.spec index 131f08a..64f1e7a 100644 --- a/NetworkManager-libreswan.spec +++ b/NetworkManager-libreswan.spec @@ -11,7 +11,7 @@ %global real_version 1.2.27 %global rpm_version 1.2.27 -%global release_version 1 +%global release_version 2 %global real_version_major %(printf '%s' '%{real_version}' | sed -n 's/^\\([1-9][0-9]*\\.[1-9][0-9]*\\)\\.[1-9][0-9]*$/\\1/p') @@ -27,9 +27,9 @@ License: GPLv2+ URL: https://gitlab.gnome.org/GNOME/NetworkManager-libreswan/ Source0: https://download.gnome.org/sources/NetworkManager-libreswan/%{real_version_major}/%{name}-%{real_version}.tar.xz -# Patch0: https://gitlab.gnome.org/GNOME/NetworkManager-libreswan/-/commit/3ea80883fefc.patch#/0001-Add-nm-auto-defaults-option.patch -# Patch1: https://gitlab.gnome.org/GNOME/NetworkManager-libreswan/-/commit/9b4467bd226d.patch#/0002-Treat-leftmodecfgserver-differently-according-to-nm-.patch -# Patch2: https://gitlab.gnome.org/GNOME/NetworkManager-libreswan/-/commit/43f3df676e82.patch#/0003-shared-utils-only-set-phase2alg-esp-for-ikev1-in-agg.patch +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 BuildRequires: make BuildRequires: gcc @@ -131,6 +131,11 @@ rm -f %{buildroot}%{_libdir}/NetworkManager/lib*.la %endif %changelog +* Mon Oct 20 2025 Vladimír Beneš - 1.2.27-2 +* Symetric import/export with nm-auto-default (RHEL-122306) +* Esp param properly exported (RHEL-122626) +* Correct leftid export when it contains @ + * Thu Oct 02 2025 Vladimír Beneš - 1.2.27-1 - Update to later upstream release to address regressions (RHEL-56551) - Support rightca in ipsec section (RHEL-118819)