diff options
Diffstat (limited to 'service')
3 files changed, 101 insertions, 20 deletions
diff --git a/service/java/com/android/server/wifi/ConfigurationMap.java b/service/java/com/android/server/wifi/ConfigurationMap.java index a5cd18f2a..443eef879 100644 --- a/service/java/com/android/server/wifi/ConfigurationMap.java +++ b/service/java/com/android/server/wifi/ConfigurationMap.java @@ -126,6 +126,30 @@ public class ConfigurationMap { ScanResultMatchInfo.fromScanResult(scanResult)); } + /** + * Retrieves a |WifiConfiguration| object with PSK key management, that is matching the provided + * |scanResult| SSID from the internal map. + * Used for upgrading WPA2-Personal networks to WPA3-Personal, when AP is in transition mode. + */ + public WifiConfiguration getPskNetworkByScanResultForCurrentUser(ScanResult scanResult) { + // Check if WPA2-Personal saved network is available + ScanResultMatchInfo matchInfo = ScanResultMatchInfo.fromScanResult(scanResult); + matchInfo.networkType = WifiConfiguration.SECURITY_TYPE_PSK; + return mScanResultMatchInfoMapForCurrentUser.get(matchInfo); + } + + /** + * Retrieves a |WifiConfiguration| object with no security, that is matching the provided + * |scanResult| SSID from the internal map. + * Used for upgrading Open networks to OWE, when AP is in transition mode. + */ + public WifiConfiguration getOpenNetworkByScanResultForCurrentUser(ScanResult scanResult) { + // Check if Open saved network is available + ScanResultMatchInfo matchInfo = ScanResultMatchInfo.fromScanResult(scanResult); + matchInfo.networkType = WifiConfiguration.SECURITY_TYPE_OPEN; + return mScanResultMatchInfoMapForCurrentUser.get(matchInfo); + } + public Collection<WifiConfiguration> valuesForAllUsers() { return mPerID.values(); } diff --git a/service/java/com/android/server/wifi/ScanResultMatchInfo.java b/service/java/com/android/server/wifi/ScanResultMatchInfo.java index b3d10cc38..1e15a3ecc 100644 --- a/service/java/com/android/server/wifi/ScanResultMatchInfo.java +++ b/service/java/com/android/server/wifi/ScanResultMatchInfo.java @@ -131,26 +131,8 @@ public class ScanResultMatchInfo { return false; } ScanResultMatchInfo other = (ScanResultMatchInfo) otherObj; - if (!Objects.equals(networkSsid, other.networkSsid)) { - return false; - } - boolean networkTypeEquals; - - // Detect <SSID, PSK+SAE> scan result and say it is equal to <SSID, PSK> configuration - if (other.pskSaeInTransitionMode && networkType == WifiConfiguration.SECURITY_TYPE_PSK - || (pskSaeInTransitionMode - && other.networkType == WifiConfiguration.SECURITY_TYPE_PSK)) { - networkTypeEquals = true; - } else if ((networkType == WifiConfiguration.SECURITY_TYPE_OPEN - && other.oweInTransitionMode) || (oweInTransitionMode - && other.networkType == WifiConfiguration.SECURITY_TYPE_OPEN)) { - // Special case we treat Enhanced Open and Open as equals. This is done to support the - // case where a saved network is Open but we found an OWE in transition network. - networkTypeEquals = true; - } else { - networkTypeEquals = networkType == other.networkType; - } - return networkTypeEquals; + return Objects.equals(networkSsid, other.networkSsid) + && networkType == other.networkType; } @Override diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index 533155d0c..c027675ce 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -1117,6 +1117,7 @@ public class WifiConfigManager { if (randomizedMac != null) { newInternalConfig.setRandomizedMacAddress(randomizedMac); } + newInternalConfig.clonedNetworkConfigKey = externalConfig.clonedNetworkConfigKey; return newInternalConfig; } @@ -1401,6 +1402,27 @@ public class WifiConfigManager { Log.e(TAG, "Failed to remove network " + config.getPrintableSsid()); return false; } + + // Remove any cloned networks + if (config.clonedNetworkConfigKey != null) { + WifiConfiguration clonedConfig = getConfiguredNetwork(config.clonedNetworkConfigKey); + + if (clonedConfig != null) { + Log.d(TAG, "Removing cloned network " + clonedConfig.getPrintableSsid()); + if (!removeNetworkInternal(clonedConfig, uid)) { + Log.e(TAG, "Failed to remove network " + clonedConfig.getPrintableSsid()); + return false; + } + + if (clonedConfig.networkId == mLastSelectedNetworkId) { + clearLastSelectedNetwork(); + } + } else { + Log.w(TAG, "Could not find a cloned network with key " + + config.clonedNetworkConfigKey); + } + } + if (networkId == mLastSelectedNetworkId) { clearLastSelectedNetwork(); } @@ -2265,6 +2287,24 @@ public class WifiConfigManager { } catch (IllegalArgumentException e) { Log.e(TAG, "Failed to lookup network from config map", e); } + if (config == null) { + /** + * Special case for WPA3-Personal and OWE in transition mode. + * These networks will be treated as WPA3/OWE with a special flag that indicates + * transition mode enabled. If we have a matching WPA2/Open saved network, create a new + * upgraded WPA3/OWE network and use it to connect. + */ + ScanResultMatchInfo matchInfo = ScanResultMatchInfo.fromScanResult(scanResult); + if (matchInfo.pskSaeInTransitionMode || matchInfo.oweInTransitionMode) { + if (handleTransitionNetwork(scanResult, matchInfo.pskSaeInTransitionMode)) { + try { + config = mConfiguredNetworks.getByScanResultForCurrentUser(scanResult); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Failed to lookup network from config map", e); + } + } + } + } if (config != null) { if (mVerboseLoggingEnabled) { Log.v(TAG, "getSavedNetworkFromScanDetail Found " + config.configKey() @@ -2274,6 +2314,41 @@ public class WifiConfigManager { return config; } + private boolean handleTransitionNetwork(ScanResult scanResult, boolean isPskSae) { + WifiConfiguration config; + + if (isPskSae) { + config = mConfiguredNetworks.getPskNetworkByScanResultForCurrentUser(scanResult); + } else { + config = mConfiguredNetworks.getOpenNetworkByScanResultForCurrentUser(scanResult); + } + + if (config != null) { + // Create a new WPA3-Personal or OWE connection + WifiConfiguration newConfig = new WifiConfiguration(config); + newConfig.networkId = WifiConfiguration.INVALID_NETWORK_ID; + newConfig.clonedNetworkConfigKey = config.configKey(); + if (isPskSae) { + newConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE); + } else { + newConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE); + } + NetworkUpdateResult res = addOrUpdateNetwork(newConfig, config.creatorUid, + config.creatorName); + + if (!res.isSuccess()) { + Log.e(TAG, "Failed to add new configuration for " + newConfig.SSID); + return false; + } + config.clonedNetworkConfigKey = newConfig.configKey(); + addOrUpdateNetwork(config, config.creatorUid); + enableNetwork(res.netId, false, config.creatorUid); + return true; + } + + return false; + } + /** * Retrieves a configured network corresponding to the provided scan detail if one exists and * caches the provided |scanDetail| into the corresponding scan detail cache entry |