diff options
| author | Michael Biebl <biebl@debian.org> | 2021-10-01 23:05:04 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2021-10-01 23:05:04 +0200 |
| commit | e74c568b07b50b97873fb4ee1d776dedefbd54d6 (patch) | |
| tree | 3469f17ea9af91f7ff169b890633bda68b0cf76e /src/core/devices/wifi/nm-device-iwd.c | |
| parent | bfe522304da217296e2a61040f58e35ec5d6f3f2 (diff) | |
New upstream version 1.32.12 upstream/1.32.12
Diffstat (limited to 'src/core/devices/wifi/nm-device-iwd.c')
| -rw-r--r-- | src/core/devices/wifi/nm-device-iwd.c | 191 |
1 files changed, 113 insertions, 78 deletions
diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c index 01f2a303..56338743 100644 --- a/src/core/devices/wifi/nm-device-iwd.c +++ b/src/core/devices/wifi/nm-device-iwd.c @@ -13,16 +13,16 @@ #include "devices/nm-device.h" #include "nm-act-request.h" #include "nm-config.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-iwd-manager.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-setting-8021x.h" #include "nm-setting-connection.h" #include "nm-setting-wireless-security.h" #include "nm-setting-wireless.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" #include "nm-utils.h" #include "nm-wifi-common.h" #include "nm-wifi-utils.h" @@ -55,7 +55,7 @@ typedef struct { CList aps_lst_head; NMWifiAP * current_ap; GCancellable * cancellable; - NMDeviceWifiCapabilities capabilities; + _NMDeviceWifiCapabilities capabilities; NMActRequestGetSecretsCallId *wifi_secrets_id; guint periodic_scan_id; guint periodic_update_id; @@ -265,7 +265,7 @@ ap_from_network(NMDeviceIwd *self, .bss_path = bss_path, .last_seen_msec = last_seen_msec, .bssid_valid = TRUE, - .mode = NM_802_11_MODE_INFRA, + .mode = _NM_802_11_MODE_INFRA, .rsn_flags = ap_security_flags_from_network_type(type), .ssid = ssid, .signal_percent = nm_wifi_utils_level_to_quality(signal / 100), @@ -812,7 +812,7 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * NMSettingWirelessSecurity *s_wireless_sec = nm_connection_get_setting_wireless_security(connection); - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_AP)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, "device does not support Access Point mode"); @@ -830,7 +830,7 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * NMSettingWirelessSecurity *s_wireless_sec = nm_connection_get_setting_wireless_security(connection); - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_ADHOC)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, "device does not support Ad-Hoc mode"); @@ -1045,16 +1045,15 @@ complete_connection(NMDevice * device, } ssid_utf8 = iwd_ssid_to_str(ssid); - nm_utils_complete_generic( - nm_device_get_platform(device), - connection, - NM_SETTING_WIRELESS_SETTING_NAME, - existing_connections, - ssid_utf8, - ssid_utf8, - NULL, - nm_setting_wireless_get_mac_address(s_wifi) ? NULL : nm_device_get_iface(device), - TRUE); + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_WIRELESS_SETTING_NAME, + existing_connections, + ssid_utf8, + ssid_utf8, + NULL, + NULL, + TRUE); if (hidden) g_object_set(s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); @@ -1317,6 +1316,7 @@ static gboolean try_reply_agent_request(NMDeviceIwd * self, NMConnection * connection, GDBusMethodInvocation *invocation, + gboolean allow_existing, const char ** setting_name, const char ** setting_key, gboolean * replied) @@ -1331,56 +1331,64 @@ try_reply_agent_request(NMDeviceIwd * self, *replied = FALSE; if (nm_streq(method_name, "RequestPassphrase")) { - const char *psk; - if (!s_wireless_sec) return FALSE; - psk = nm_setting_wireless_security_get_psk(s_wireless_sec); - if (psk) { - _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the PSK to the IWD Agent"); + if (allow_existing) { + const char *psk = nm_setting_wireless_security_get_psk(s_wireless_sec); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", psk)); - *replied = TRUE; - return TRUE; + 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)); + *replied = TRUE; + return TRUE; + } } *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; *setting_key = NM_SETTING_WIRELESS_SECURITY_PSK; return TRUE; } else if (nm_streq(method_name, "RequestPrivateKeyPassphrase")) { - const char *password; - if (!s_8021x) return FALSE; - password = nm_setting_802_1x_get_private_key_password(s_8021x); - if (password) { - _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the private key password to the IWD Agent"); + if (allow_existing) { + const char *password = nm_setting_802_1x_get_private_key_password(s_8021x); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password)); - *replied = TRUE; - return TRUE; + if (password) { + _LOGD(LOGD_DEVICE | LOGD_WIFI, + "Returning the private key password to the IWD Agent"); + + g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password)); + *replied = TRUE; + return TRUE; + } } *setting_name = NM_SETTING_802_1X_SETTING_NAME; *setting_key = NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD; return TRUE; } else if (nm_streq(method_name, "RequestUserNameAndPassword")) { - const char *identity, *password; + const char *identity; if (!s_8021x) return FALSE; identity = nm_setting_802_1x_get_identity(s_8021x); - password = nm_setting_802_1x_get_password(s_8021x); - if (identity && password) { - _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the username and password to the IWD Agent"); - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(ss)", identity, password)); - *replied = TRUE; - return TRUE; + if (allow_existing) { + const char *password = nm_setting_802_1x_get_password(s_8021x); + + if (identity && password) { + _LOGD(LOGD_DEVICE | LOGD_WIFI, + "Returning the username and password to the IWD Agent"); + + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(ss)", identity, password)); + *replied = TRUE; + return TRUE; + } } *setting_name = NM_SETTING_802_1X_SETTING_NAME; @@ -1390,18 +1398,19 @@ try_reply_agent_request(NMDeviceIwd * self, *setting_key = NM_SETTING_802_1X_PASSWORD; return TRUE; } else if (nm_streq(method_name, "RequestUserPassword")) { - const char *password; - if (!s_8021x) return FALSE; - password = nm_setting_802_1x_get_password(s_8021x); - if (password) { - _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the user password to the IWD Agent"); + if (allow_existing) { + const char *password = nm_setting_802_1x_get_password(s_8021x); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password)); - *replied = TRUE; - return TRUE; + if (password) { + _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the user password to the IWD Agent"); + + g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password)); + *replied = TRUE; + return TRUE; + } } *setting_name = NM_SETTING_802_1X_SETTING_NAME; @@ -1452,6 +1461,8 @@ wifi_secrets_cb(NMActRequest * req, gboolean replied; NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMIwdNetworkSecurity security; + NMConnection * connection; nm_utils_user_data_unpack(user_data, &self, &invocation); @@ -1484,9 +1495,18 @@ wifi_secrets_cb(NMActRequest * req, goto secrets_error; } + connection = nm_device_get_applied_connection(device); + + if (nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security) + && security == NM_IWD_NETWORK_SECURITY_PSK) { + if (nm_settings_connection_get_timestamp(nm_device_get_settings_connection(device), NULL)) + get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + } + if (!try_reply_agent_request(self, - nm_act_request_get_applied_connection(req), + connection, invocation, + TRUE, &setting_name, &setting_key, &replied)) @@ -1512,9 +1532,6 @@ wifi_secrets_cb(NMActRequest * req, return; } - if (nm_settings_connection_get_timestamp(nm_act_request_get_settings_connection(req), NULL)) - get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - /* Request further secrets if we still need something */ wifi_secrets_get_one(self, setting_name, get_secret_flags, setting_key, invocation); return; @@ -1606,8 +1623,6 @@ network_connect_cb(GObject *source, GAsyncResult *res, gpointer user_data) dbus_error = g_dbus_error_get_remote_error(error); if (nm_streq0(dbus_error, "net.connman.iwd.Failed")) { - nm_connection_clear_secrets(connection); - /* If secrets were wrong, we'd be getting a net.connman.iwd.Failed */ reason = NM_DEVICE_STATE_REASON_NO_SECRETS; } else if (nm_streq0(dbus_error, "net.connman.iwd.Aborted") && priv->secrets_failed) { @@ -2621,9 +2636,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) switch (prop_id) { case PROP_MODE: if (!priv->current_ap) - g_value_set_uint(value, NM_802_11_MODE_UNKNOWN); + g_value_set_uint(value, _NM_802_11_MODE_UNKNOWN); else if (nm_wifi_ap_is_hotspot(priv->current_ap)) - g_value_set_uint(value, NM_802_11_MODE_AP); + g_value_set_uint(value, _NM_802_11_MODE_AP); else g_value_set_uint(value, nm_wifi_ap_get_mode(priv->current_ap)); @@ -3045,7 +3060,7 @@ nm_device_iwd_set_dbus_object(NMDeviceIwd *self, GDBusObject *object) GVariantIter * iter; const char * mode; gboolean powered; - NMDeviceWifiCapabilities capabilities; + _NMDeviceWifiCapabilities capabilities; if (!nm_g_object_ref_set(&priv->dbus_obj, object)) return; @@ -3107,14 +3122,14 @@ nm_device_iwd_set_dbus_object(NMDeviceIwd *self, GDBusObject *object) goto error; } - capabilities = NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_RSN; + capabilities = _NM_WIFI_DEVICE_CAP_CIPHER_CCMP | _NM_WIFI_DEVICE_CAP_RSN; g_variant_get(value, "as", &iter); while (g_variant_iter_next(iter, "&s", &mode)) { if (nm_streq(mode, "ap")) - capabilities |= NM_WIFI_DEVICE_CAP_AP; + capabilities |= _NM_WIFI_DEVICE_CAP_AP; else if (nm_streq(mode, "ad-hoc")) - capabilities |= NM_WIFI_DEVICE_CAP_ADHOC; + capabilities |= _NM_WIFI_DEVICE_CAP_ADHOC; } g_variant_iter_free(iter); @@ -3156,8 +3171,11 @@ nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation) const char * setting_key; gboolean replied; NMWifiAP * ap; + gboolean allow_existing = FALSE; NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMIwdNetworkSecurity security; + NMConnection * connection; nm_auto_ref_string NMRefString *network_path = NULL; if (!invocation) { @@ -3261,9 +3279,37 @@ nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation) /* Otherwise handle as usual */ } + /* Normally for PSK networks require new secret every time IWD asks for + * it. IWD only queries us if it has not saved the PSK (e.g. by policy) + * or a previous attempt has failed with current secrets so it wants a + * fresh value. It doesn't know about agent-owned secrets so whenever + * possible and the PSK is saved and not asked from NM. However if this + * is a new connection it may include all of the needed settings already + * so allow using these, too. Connection timestamp is set after + * activation or after first activation failure (to 0). + * + * For 802.1x, since IWD assumes the network is pre-provisioned by an + * admin and tested, there's no reason for IWD to save secrets in + * the network config file and there's no reason to ask for a new value + * of a saved (i.e. system-owned) secret because it can't be wrong. + * Since NM has a richer set of secret storage options we never specify + * NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW and let + * nm_settings_connection_get_secrets decide. + */ + connection = nm_device_get_applied_connection(device); + + if (nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security) + && security == NM_IWD_NETWORK_SECURITY_PSK) { + if (nm_settings_connection_get_timestamp(nm_device_get_settings_connection(device), NULL)) + get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + else + allow_existing = TRUE; + } + if (!try_reply_agent_request(self, - nm_device_get_applied_connection(device), + connection, invocation, + allow_existing, &setting_name, &setting_key, &replied)) { @@ -3274,17 +3320,6 @@ nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation) if (replied) return TRUE; - /* Normally require new secrets every time IWD asks for them. - * IWD only queries us if it has not saved the secrets (e.g. by policy) - * or a previous attempt has failed with current secrets so it wants - * a fresh set. However if this is a new connection it may include - * all of the needed settings already so allow using these, too. - * Connection timestamp is set after activation or after first - * activation failure (to 0). - */ - if (nm_settings_connection_get_timestamp(nm_device_get_settings_connection(device), NULL)) - get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - nm_device_state_changed(device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NO_SECRETS); wifi_secrets_get_one(self, setting_name, get_secret_flags, setting_key, invocation); @@ -3463,9 +3498,9 @@ nm_device_iwd_class_init(NMDeviceIwdClass *klass) obj_properties[PROP_MODE] = g_param_spec_uint(NM_DEVICE_IWD_MODE, "", "", - NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_AP, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_UNKNOWN, + _NM_802_11_MODE_AP, + _NM_802_11_MODE_INFRA, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_BITRATE] = g_param_spec_uint(NM_DEVICE_IWD_BITRATE, @@ -3496,7 +3531,7 @@ nm_device_iwd_class_init(NMDeviceIwdClass *klass) "", 0, G_MAXUINT32, - NM_WIFI_DEVICE_CAP_NONE, + _NM_WIFI_DEVICE_CAP_NONE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_SCANNING] = g_param_spec_boolean(NM_DEVICE_IWD_SCANNING, |