mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-25 03:40:37 +01:00
wifi: use authentication retry mechanism
While NetworkManager tries it's best to determine whether a new PSK is needed, it can still run into edge cases. One of these edge cases is that a device can leave the range of an access point and therefore fail a 4-way handshake. Because these cases can't be confidently detected, a device which was previously connected, should try to exhaust it's authentication retries before requesting new secrets. This leads to less user-facing prompts while increasing the time from PSK change to prompt.
This commit is contained in:
parent
6dc51ddf01
commit
746a5902ad
1 changed files with 78 additions and 12 deletions
|
|
@ -2251,6 +2251,26 @@ wps_timeout_cb(gpointer user_data)
|
|||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
wifi_connection_is_new(NMDeviceWifi *self)
|
||||
{
|
||||
NMDevice *device = NM_DEVICE(self);
|
||||
NMActRequest *req;
|
||||
NMSettingsConnection *connection;
|
||||
guint64 timestamp = 0;
|
||||
|
||||
req = nm_device_get_act_request(device);
|
||||
g_return_val_if_fail(NM_IS_ACT_REQUEST(req), TRUE);
|
||||
|
||||
connection = nm_act_request_get_settings_connection(req);
|
||||
g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(connection), TRUE);
|
||||
|
||||
if (nm_settings_connection_get_timestamp(connection, ×tamp) && timestamp != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
wifi_secrets_get_secrets(NMDeviceWifi *self,
|
||||
const char *setting_name,
|
||||
|
|
@ -2405,10 +2425,11 @@ handle_8021x_or_psk_auth_fail(NMDeviceWifi *self,
|
|||
NMSupplicantInterfaceState old_state,
|
||||
int disconnect_reason)
|
||||
{
|
||||
NMDevice *device = NM_DEVICE(self);
|
||||
NMActRequest *req;
|
||||
const char *setting_name = NULL;
|
||||
gboolean handled = FALSE;
|
||||
NMDevice *device = NM_DEVICE(self);
|
||||
NMActRequest *req;
|
||||
const char *setting_name = NULL;
|
||||
NMSecretAgentGetSecretsFlags secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION
|
||||
| NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
|
||||
g_return_val_if_fail(new_state == NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED, FALSE);
|
||||
|
||||
|
|
@ -2418,8 +2439,7 @@ handle_8021x_or_psk_auth_fail(NMDeviceWifi *self,
|
|||
req = nm_device_get_act_request(NM_DEVICE(self));
|
||||
g_return_val_if_fail(req != NULL, FALSE);
|
||||
|
||||
if (need_new_8021x_secrets(self, old_state, &setting_name)
|
||||
|| need_new_wpa_psk(self, old_state, disconnect_reason, &setting_name)) {
|
||||
if (need_new_8021x_secrets(self, old_state, &setting_name)) {
|
||||
nm_act_request_clear_secrets(req);
|
||||
|
||||
_LOGI(LOGD_DEVICE | LOGD_WIFI,
|
||||
|
|
@ -2429,14 +2449,54 @@ handle_8021x_or_psk_auth_fail(NMDeviceWifi *self,
|
|||
nm_device_state_changed(device,
|
||||
NM_DEVICE_STATE_NEED_AUTH,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
wifi_secrets_get_secrets(self,
|
||||
setting_name,
|
||||
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION
|
||||
| NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
|
||||
handled = TRUE;
|
||||
wifi_secrets_get_secrets(self, setting_name, secret_flags);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return handled;
|
||||
if (need_new_wpa_psk(self, old_state, disconnect_reason, &setting_name)) {
|
||||
nm_act_request_clear_secrets(req);
|
||||
cleanup_association_attempt(self, TRUE);
|
||||
|
||||
if (wifi_connection_is_new(self)) {
|
||||
_LOGI(LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation: (wifi) new connection disconnected during association, asking for "
|
||||
"new key");
|
||||
nm_device_state_changed(device,
|
||||
NM_DEVICE_STATE_NEED_AUTH,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
wifi_secrets_get_secrets(self, setting_name, secret_flags);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!nm_device_auth_retries_try_next(device)) {
|
||||
nm_device_state_changed(device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_NO_SECRETS);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (nm_device_auth_retries_has_next(device)) {
|
||||
secret_flags &= ~NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
_LOGI(
|
||||
LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation: (wifi) disconnected during association, reauthenticating connection");
|
||||
} else {
|
||||
_LOGI(LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation: (wifi) disconnected during association, asking for new key");
|
||||
}
|
||||
|
||||
nm_device_state_changed(device,
|
||||
NM_DEVICE_STATE_NEED_AUTH,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
wifi_secrets_get_secrets(self, setting_name, secret_flags);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_LOGI(LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation: (wifi) disconnected during association, retrying connection");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -2868,6 +2928,12 @@ supplicant_iface_notify_wpa_psk_mismatch_cb(NMSupplicantInterface *iface, NMDevi
|
|||
if (nm_device_get_state(device) != NM_DEVICE_STATE_CONFIG)
|
||||
return;
|
||||
|
||||
if (!wifi_connection_is_new(self) && nm_device_auth_retries_has_next(device)) {
|
||||
_LOGI(LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation: (wifi) psk mismatch reported by supplicant, retrying connection");
|
||||
return;
|
||||
}
|
||||
|
||||
_LOGI(LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation: (wifi) psk mismatch reported by supplicant, asking for new key");
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue