From 92e43feb3eb54736a28226b588bc087fdda1646e Mon Sep 17 00:00:00 2001 From: Michael Plass Date: Fri, 10 Mar 2017 16:54:26 -0800 Subject: [SupplicantStaIfaceHal] Detect PSK mismatch Use checks analogous to those in wpa_supplicant_8/wpa_supplicant/events.c to decide whether or not a disconnect is likely due to an incorrect password. Test: Attempt to join a PSK network with the wrong password Test: Unit tests added Bug: 35464954 Change-Id: I47196cf89dbd602c22a61b430b764c7ea76f04d5 --- .../android/server/wifi/SupplicantStaIfaceHal.java | 16 ++++++- .../server/wifi/SupplicantStaIfaceHalTest.java | 55 ++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java index 8c41441c3..66bda1e64 100644 --- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java +++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java @@ -1678,6 +1678,9 @@ public class SupplicantStaIfaceHal { } private class SupplicantStaIfaceHalCallback extends ISupplicantStaIfaceCallback.Stub { + private static final int WLAN_REASON_IE_IN_4WAY_DIFFERS = 17; // IEEE 802.11i + private boolean mStateIsFourway = false; // Used to help check for PSK password mismatch + /** * Parses the provided payload into an ANQP element. * @@ -1755,6 +1758,7 @@ public class SupplicantStaIfaceHal { mWifiMonitor.broadcastNetworkConnectionEvent( mIfaceName, mFrameworkNetworkId, bssidStr); } + mStateIsFourway = (newState == ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE); } } @@ -1818,6 +1822,16 @@ public class SupplicantStaIfaceHal { public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int reasonCode) { logCallback("onDisconnected"); synchronized (mLock) { + if (mVerboseLoggingEnabled) { + Log.e(TAG, "onDisconnected 4way=" + mStateIsFourway + + " locallyGenerated=" + locallyGenerated + + " reasonCode=" + reasonCode); + } + if (mStateIsFourway + && (!locallyGenerated || reasonCode != WLAN_REASON_IE_IN_4WAY_DIFFERS)) { + mWifiMonitor.broadcastAuthenticationFailureEvent( + mIfaceName, WifiMonitor.AUTHENTICATION_FAILURE_REASON_WRONG_PSWD); + } mWifiMonitor.broadcastNetworkDisconnectionEvent( mIfaceName, locallyGenerated ? 1 : 0, reasonCode, NativeUtil.macAddressFromByteArray(bssid)); @@ -1828,8 +1842,6 @@ public class SupplicantStaIfaceHal { public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode, boolean timedOut) { logCallback("onAssociationRejected"); synchronized (mLock) { - // TODO(b/35464954): Need to figure out when to trigger - // |WifiMonitor.AUTHENTICATION_FAILURE_REASON_WRONG_PSWD| mWifiMonitor.broadcastAssociationRejectionEvent(mIfaceName, statusCode, timedOut, NativeUtil.macAddressFromByteArray(bssid)); } diff --git a/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java b/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java index 04ebf2200..bb5221730 100644 --- a/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java +++ b/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java @@ -925,6 +925,61 @@ public class SupplicantStaIfaceHalTest { eq(WLAN_IFACE_NAME), eq(0), eq(reasonCode), eq(BSSID)); } + /** + * Tests the handling of incorrect network passwords. + */ + @Test + public void testAuthFailurePassword() throws Exception { + executeAndValidateInitializationSequence(); + assertNotNull(mISupplicantStaIfaceCallback); + + int reasonCode = 3; + mISupplicantStaIfaceCallback.onDisconnected( + NativeUtil.macAddressToByteArray(BSSID), true, reasonCode); + verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt()); + + mISupplicantStaIfaceCallback.onDisconnected( + NativeUtil.macAddressToByteArray(BSSID), false, reasonCode); + verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt()); + + mISupplicantStaIfaceCallback.onStateChanged( + ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE, + NativeUtil.macAddressToByteArray(BSSID), + SUPPLICANT_NETWORK_ID, + NativeUtil.decodeSsid(SUPPLICANT_SSID)); + mISupplicantStaIfaceCallback.onDisconnected( + NativeUtil.macAddressToByteArray(BSSID), true, reasonCode); + mISupplicantStaIfaceCallback.onDisconnected( + NativeUtil.macAddressToByteArray(BSSID), false, reasonCode); + + verify(mWifiMonitor, times(2)).broadcastAuthenticationFailureEvent(eq(WLAN_IFACE_NAME), + eq(WifiMonitor.AUTHENTICATION_FAILURE_REASON_WRONG_PSWD)); + + } + + /** + * Tests the handling of incorrect network passwords, edge case. + * + * If the disconnect reason is "IE in 4way differs", do not call it a password mismatch. + */ + @Test + public void testIeDiffers() throws Exception { + executeAndValidateInitializationSequence(); + assertNotNull(mISupplicantStaIfaceCallback); + + int reasonCode = 17; // IEEE 802.11i WLAN_REASON_IE_IN_4WAY_DIFFERS + + mISupplicantStaIfaceCallback.onStateChanged( + ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE, + NativeUtil.macAddressToByteArray(BSSID), + SUPPLICANT_NETWORK_ID, + NativeUtil.decodeSsid(SUPPLICANT_SSID)); + mISupplicantStaIfaceCallback.onDisconnected( + NativeUtil.macAddressToByteArray(BSSID), true, reasonCode); + verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt()); + } + + /** * Tests the handling of association rejection notification. */ -- cgit v1.2.3