From 22f4358cf20a698ebce05d87b31399b37d9b66ec Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Thu, 23 Apr 2026 09:09:09 +0200 Subject: [PATCH] wifi: iwd: Honor passphrase storage option Newer iwd versions may request PSK secrets through RequestPassphraseWithOptions. This method lets NetworkManager return the passphrase together with options that describe how iwd should handle the secret. Use the new method to tell iwd whether the PSK may be stored in the iwd profile. For normal system-owned PSKs, allow storing as before. For agent-owned or not-saved PSKs, return Store=false so iwd can use the passphrase for the connection attempt without persisting it under /var/lib/iwd. --- src/core/devices/wifi/nm-device-iwd.c | 31 ++++++++++++++++++++++++-- src/core/devices/wifi/nm-iwd-manager.c | 5 +++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c index 94b9a7d703..408d1a8557 100644 --- a/src/core/devices/wifi/nm-device-iwd.c +++ b/src/core/devices/wifi/nm-device-iwd.c @@ -1314,6 +1314,8 @@ get_agent_request_network_path(GDBusMethodInvocation *invocation) if (nm_streq(method_name, "RequestPassphrase")) g_variant_get(params, "(&o)", &network_path); + else if (nm_streq(method_name, "RequestPassphraseWithOptions")) + g_variant_get(params, "(&o)", &network_path); else if (nm_streq(method_name, "RequestPrivateKeyPassphrase")) g_variant_get(params, "(&o)", &network_path); else if (nm_streq(method_name, "RequestUserNameAndPassword")) @@ -1333,6 +1335,18 @@ get_agent_request_network_path(GDBusMethodInvocation *invocation) * name and key so the caller can send a NM secrets request with this data. * Return TRUE in either case, return FALSE if an error is detected. */ +static gboolean +psk_should_store_in_iwd(NMSettingWirelessSecurity *s_wireless_sec) +{ + NMSettingSecretFlags psk_flags; + + psk_flags = nm_setting_wireless_security_get_psk_flags(s_wireless_sec); + + return !NM_FLAGS_ANY(psk_flags, + NM_SETTING_SECRET_FLAG_AGENT_OWNED + | NM_SETTING_SECRET_FLAG_NOT_SAVED); +} + static gboolean try_reply_agent_request(NMDeviceIwd *self, NMConnection *connection, @@ -1351,7 +1365,7 @@ try_reply_agent_request(NMDeviceIwd *self, *replied = FALSE; - if (nm_streq(method_name, "RequestPassphrase")) { + if (NM_IN_STRSET(method_name, "RequestPassphrase", "RequestPassphraseWithOptions")) { if (!s_wireless_sec) return FALSE; @@ -1361,7 +1375,20 @@ try_reply_agent_request(NMDeviceIwd *self, if (psk) { _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the PSK to the IWD Agent"); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", psk)); + if (nm_streq(method_name, "RequestPassphraseWithOptions")) { + GVariantBuilder builder; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(&builder, + "{sv}", + "Store", + g_variant_new_boolean(psk_should_store_in_iwd( + s_wireless_sec))); + g_dbus_method_invocation_return_value( + invocation, + g_variant_new("(s@a{sv})", psk, g_variant_builder_end(&builder))); + } else + g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", psk)); *replied = TRUE; return TRUE; } diff --git a/src/core/devices/wifi/nm-iwd-manager.c b/src/core/devices/wifi/nm-iwd-manager.c index bb2e056d39..c0e3bceb23 100644 --- a/src/core/devices/wifi/nm-iwd-manager.c +++ b/src/core/devices/wifi/nm-iwd-manager.c @@ -355,6 +355,11 @@ static const GDBusInterfaceInfo iwd_agent_iface_info = NM_DEFINE_GDBUS_INTERFACE "RequestPassphrase", .in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("network", "o"), ), .out_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("passphrase", "s"), ), ), + NM_DEFINE_GDBUS_METHOD_INFO( + "RequestPassphraseWithOptions", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("network", "o"), ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("passphrase", "s"), + NM_DEFINE_GDBUS_ARG_INFO("options", "a{sv}"), ), ), NM_DEFINE_GDBUS_METHOD_INFO( "RequestPrivateKeyPassphrase", .in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("network", "o"), ),