summaryrefslogtreecommitdiff
path: root/service/java/com/android/server/wifi/WifiConfigManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'service/java/com/android/server/wifi/WifiConfigManager.java')
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java108
1 files changed, 76 insertions, 32 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 683ace4c8..d1734d445 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -76,6 +76,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.crypto.Mac;
+
/**
* This class provides the APIs to manage configured Wi-Fi networks.
* It deals with the following:
@@ -228,6 +230,9 @@ public class WifiConfigManager {
private static final int WIFI_PNO_FREQUENCY_CULLING_ENABLED_DEFAULT = 1; // 0 = disabled
private static final int WIFI_PNO_RECENCY_SORTING_ENABLED_DEFAULT = 1; // 0 = disabled:
+ private static final MacAddress DEFAULT_MAC_ADDRESS =
+ MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
+
/**
* Expiration timeout for deleted ephemeral ssids. (1 day)
*/
@@ -272,6 +277,7 @@ public class WifiConfigManager {
private final WifiPermissionsWrapper mWifiPermissionsWrapper;
private final WifiInjector mWifiInjector;
private boolean mConnectedMacRandomzationSupported;
+ private final Mac mMac;
/**
* Local log used for debugging any WifiConfigManager issues.
@@ -446,6 +452,11 @@ public class WifiConfigManager {
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Unable to resolve SystemUI's UID.");
}
+ mMac = WifiConfigurationUtil.obtainMacRandHashFunction(Process.WIFI_UID);
+ if (mMac == null) {
+ Log.wtf(TAG, "Failed to obtain secret for MAC randomization."
+ + " All randomized MAC addresses are lost!");
+ }
}
/**
@@ -464,6 +475,59 @@ public class WifiConfigManager {
return sb.toString();
}
+ @VisibleForTesting
+ protected int getRandomizedMacAddressMappingSize() {
+ return mRandomizedMacAddressMapping.size();
+ }
+
+ /**
+ * The persistent randomized MAC address is locally generated for each SSID and does not
+ * change until factory reset of the device. In the initial Q release the per-SSID randomized
+ * MAC is saved on the device, but in an update the storing of randomized MAC is removed.
+ * Instead, the randomized MAC is calculated directly from the SSID and a on device secret.
+ * For backward compatibility, this method first checks the device storage for saved
+ * randomized MAC. If it is not found or the saved MAC is invalid then it will calculate the
+ * randomized MAC directly.
+ *
+ * In the future as devices launched on Q no longer get supported, this method should get
+ * simplified to return the calculated MAC address directly.
+ * @param config the WifiConfiguration to obtain MAC address for.
+ * @return persistent MAC address for this WifiConfiguration
+ */
+ private MacAddress getPersistentMacAddress(WifiConfiguration config) {
+ // mRandomizedMacAddressMapping had been the location to save randomized MAC addresses.
+ String persistentMacString = mRandomizedMacAddressMapping.get(
+ config.getSsidAndSecurityTypeString());
+ // Use the MAC address stored in the storage if it exists and is valid. Otherwise
+ // use the MAC address calculated from a hash function as the persistent MAC.
+ if (persistentMacString != null) {
+ try {
+ return MacAddress.fromString(persistentMacString);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Error creating randomized MAC address from stored value.");
+ mRandomizedMacAddressMapping.remove(config.getSsidAndSecurityTypeString());
+ }
+ }
+ return WifiConfigurationUtil.calculatePersistentMacForConfiguration(config, mMac);
+ }
+
+ /**
+ * Obtain the persistent MAC address by first reading from an internal database. If non exists
+ * then calculate the persistent MAC using HMAC-SHA256.
+ * Finally set the randomized MAC of the configuration to the randomized MAC obtained.
+ * @param config the WifiConfiguration to make the update
+ * @return the persistent MacAddress or null if the operation is unsuccessful
+ */
+ private MacAddress setRandomizedMacToPersistentMac(WifiConfiguration config) {
+ MacAddress persistentMac = getPersistentMacAddress(config);
+ if (persistentMac == null || persistentMac.equals(config.getRandomizedMacAddress())) {
+ return persistentMac;
+ }
+ WifiConfiguration internalConfig = getInternalConfiguredNetwork(config.networkId);
+ internalConfig.setRandomizedMacAddress(persistentMac);
+ return persistentMac;
+ }
+
/**
* Enable/disable verbose logging in WifiConfigManager & its helper classes.
*/
@@ -520,8 +584,7 @@ public class WifiConfigManager {
* @param configuration WifiConfiguration to hide the MAC address
*/
private void maskRandomizedMacAddressInWifiConfiguration(WifiConfiguration configuration) {
- MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
- configuration.setRandomizedMacAddress(defaultMac);
+ configuration.setRandomizedMacAddress(DEFAULT_MAC_ADDRESS);
}
/**
@@ -1050,34 +1113,11 @@ public class WifiConfigManager {
packageName != null ? packageName : mContext.getPackageManager().getNameForUid(uid);
newInternalConfig.creationTime = newInternalConfig.updateTime =
createDebugTimeStampString(mClock.getWallClockMillis());
- updateRandomizedMacAddress(newInternalConfig);
-
- return newInternalConfig;
- }
-
- /**
- * Sets the randomized address for the given configuration from stored map if it exist.
- * Otherwise generates a new randomized address and save to the stored map.
- * @param config
- */
- private void updateRandomizedMacAddress(WifiConfiguration config) {
- // Update randomized MAC address according to stored map
- final String key = config.getSsidAndSecurityTypeString();
- // If the key is not found in the current store, then it means this network has never been
- // seen before. So add it to store.
- if (!mRandomizedMacAddressMapping.containsKey(key)) {
- mRandomizedMacAddressMapping.put(key,
- config.getOrCreateRandomizedMacAddress().toString());
- } else { // Otherwise read from the store and set the WifiConfiguration
- try {
- config.setRandomizedMacAddress(
- MacAddress.fromString(mRandomizedMacAddressMapping.get(key)));
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Error creating randomized MAC address from stored value.");
- mRandomizedMacAddressMapping.put(key,
- config.getOrCreateRandomizedMacAddress().toString());
- }
+ MacAddress randomizedMac = getPersistentMacAddress(newInternalConfig);
+ if (randomizedMac != null) {
+ newInternalConfig.setRandomizedMacAddress(randomizedMac);
}
+ return newInternalConfig;
}
/**
@@ -3026,12 +3066,16 @@ public class WifiConfigManager {
}
/**
- * Generate randomized MAC addresses for configured networks and persist mapping to storage.
+ * Assign randomized MAC addresses for configured networks.
+ * This is needed to generate persistent randomized MAC address for existing networks when
+ * a device updates to Q+ for the first time since we are not calling addOrUpdateNetwork when
+ * we load configuration at boot.
*/
private void generateRandomizedMacAddresses() {
for (WifiConfiguration config : getInternalConfiguredNetworks()) {
- mRandomizedMacAddressMapping.put(config.getSsidAndSecurityTypeString(),
- config.getOrCreateRandomizedMacAddress().toString());
+ if (DEFAULT_MAC_ADDRESS.equals(config.getRandomizedMacAddress())) {
+ setRandomizedMacToPersistentMac(config);
+ }
}
}