network: keep saved wifi profiles when NM fails with no-secrets

fixes #3313
port 1.6

(cherry picked from commit c0f775ae49)
This commit is contained in:
bbedward
2026-09-05 16:21:49 +00:00
committed by dms-ci[bot]
parent a1b51b191f
commit 75b8932b20
2 changed files with 27 additions and 1 deletions
@@ -183,6 +183,12 @@ func (b *NetworkManagerBackend) classifyNMStateReason(reason uint32) string {
}
}
// NM raises NO_SECRETS once auth retries run out on a saved profile too, not only
// on a dismissed prompt (nm-device-wifi.c handle_8021x_or_psk_auth_fail, #3313).
func forgetOnConnectFailure(reasonCode string, preExisting bool) bool {
return reasonCode == errdefs.ErrUserCanceled && !preExisting
}
// With several adapters, state must follow the associated device, not whichever
// enumerated first (#2460).
func (b *NetworkManagerBackend) wifiDeviceForState() (gonetworkmanager.Device, gonetworkmanager.DeviceWireless) {
@@ -321,7 +327,7 @@ func (b *NetworkManagerBackend) updateWiFiState() error {
b.state.ConnectingSSID = ""
b.state.LastError = reasonCode
if reasonCode == errdefs.ErrUserCanceled {
if forgetOnConnectFailure(reasonCode, b.state.ConnectingPreExisting) {
forgetSSID = connectingSSID
}
@@ -146,3 +146,23 @@ func TestNetworkManagerBackend_UpdateWiFiState_PicksConnectedDevice(t *testing.T
assert.True(t, backend.state.WiFiConnected)
assert.Equal(t, "wlan1", backend.state.WiFiDevice)
}
func TestForgetOnConnectFailure(t *testing.T) {
tests := []struct {
name string
reasonCode string
preExisting bool
want bool
}{
{"cancelled prompt on freshly created profile", errdefs.ErrUserCanceled, false, true},
{"no-secrets failure on saved profile", errdefs.ErrUserCanceled, true, false},
{"bad credentials on freshly created profile", errdefs.ErrBadCredentials, false, false},
{"generic failure on saved profile", errdefs.ErrConnectionFailed, true, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, forgetOnConnectFailure(tt.reasonCode, tt.preExisting))
})
}
}