MAC Randomization: Store Randomized MAC Address in WifiConfiguration

Store randomized MAC address for each network in mMacAddress field, so
that we don't have to create a new MAC address when connecting to a
saved network.

Bug: 63905794
Bug: 71548300
Test: Unittest
Change-Id: I05a50d3c3bc94e5ac4a0ec7cbd1f192a6d4c0b11
This commit is contained in:
Jong Wook Kim
2018-01-19 10:30:05 -08:00
parent 2180c89c24
commit d4ab45c846
2 changed files with 98 additions and 1 deletions

View File

@@ -20,6 +20,7 @@ import android.annotation.SystemApi;
import android.content.pm.PackageManager;
import android.net.IpConfiguration;
import android.net.IpConfiguration.ProxySettings;
import android.net.MacAddress;
import android.net.ProxyInfo;
import android.net.StaticIpConfiguration;
import android.net.Uri;
@@ -852,6 +853,52 @@ public class WifiConfiguration implements Parcelable {
@SystemApi
public int numAssociation;
/**
* @hide
* Randomized MAC address to use with this particular network
*/
private MacAddress mRandomizedMacAddress;
/**
* @hide
* Checks if the given MAC address can be used for Connected Mac Randomization
* by verifying that it is non-null, unicast, and locally assigned.
* @param mac MacAddress to check
* @return true if mac is good to use
*/
private boolean isValidMacAddressForRandomization(MacAddress mac) {
return mac != null && !mac.isMulticastAddress() && mac.isLocallyAssigned();
}
/**
* @hide
* Returns Randomized MAC address to use with the network.
* If it is not set/valid, create a new randomized address.
*/
public MacAddress getOrCreateRandomizedMacAddress() {
if (!isValidMacAddressForRandomization(mRandomizedMacAddress)) {
mRandomizedMacAddress = MacAddress.createRandomUnicastAddress();
}
return mRandomizedMacAddress;
}
/**
* @hide
* Returns MAC address set to be the local randomized MAC address.
* Does not guarantee that the returned address is valid for use.
*/
public MacAddress getRandomizedMacAddress() {
return mRandomizedMacAddress;
}
/**
* @hide
* @param mac MacAddress to change into
*/
public void setRandomizedMacAddress(MacAddress mac) {
mRandomizedMacAddress = mac;
}
/** @hide
* Boost given to RSSI on a home network for the purpose of calculating the score
* This adds stickiness to home networks, as defined by:
@@ -2124,6 +2171,7 @@ public class WifiConfiguration implements Parcelable {
updateTime = source.updateTime;
shared = source.shared;
recentFailure.setAssociationStatus(source.recentFailure.getAssociationStatus());
mRandomizedMacAddress = source.mRandomizedMacAddress;
}
}
@@ -2191,6 +2239,7 @@ public class WifiConfiguration implements Parcelable {
dest.writeInt(shared ? 1 : 0);
dest.writeString(mPasspointManagementObjectTree);
dest.writeInt(recentFailure.getAssociationStatus());
dest.writeParcelable(mRandomizedMacAddress, flags);
}
/** Implement the Parcelable interface {@hide} */
@@ -2259,6 +2308,7 @@ public class WifiConfiguration implements Parcelable {
config.shared = in.readInt() != 0;
config.mPasspointManagementObjectTree = in.readString();
config.recentFailure.setAssociationStatus(in.readInt());
config.mRandomizedMacAddress = in.readParcelable(null);
return config;
}

View File

@@ -22,6 +22,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import android.os.Parcel;
import android.net.MacAddress;
import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
import org.junit.Before;
@@ -49,6 +50,7 @@ public class WifiConfigurationTest {
String cookie = "C O.o |<IE";
WifiConfiguration config = new WifiConfiguration();
config.setPasspointManagementObjectTree(cookie);
MacAddress macBeforeParcel = config.getOrCreateRandomizedMacAddress();
Parcel parcelW = Parcel.obtain();
config.writeToParcel(parcelW, 0);
byte[] bytes = parcelW.marshall();
@@ -59,8 +61,9 @@ public class WifiConfigurationTest {
parcelR.setDataPosition(0);
WifiConfiguration reconfig = WifiConfiguration.CREATOR.createFromParcel(parcelR);
// lacking a useful config.equals, check one field near the end.
// lacking a useful config.equals, check two fields near the end.
assertEquals(cookie, reconfig.getMoTree());
assertEquals(macBeforeParcel, reconfig.getOrCreateRandomizedMacAddress());
Parcel parcelWW = Parcel.obtain();
reconfig.writeToParcel(parcelWW, 0);
@@ -169,4 +172,48 @@ public class WifiConfigurationTest {
assertFalse(config.isOpenNetwork());
}
@Test
public void testGetOrCreateRandomizedMacAddress_SavesAndReturnsSameAddress() {
WifiConfiguration config = new WifiConfiguration();
MacAddress firstMacAddress = config.getOrCreateRandomizedMacAddress();
MacAddress secondMacAddress = config.getOrCreateRandomizedMacAddress();
assertEquals(firstMacAddress, secondMacAddress);
}
@Test
public void testSetRandomizedMacAddress_ChangesSavedAddress() {
WifiConfiguration config = new WifiConfiguration();
MacAddress macToChangeInto = MacAddress.createRandomUnicastAddress();
config.setRandomizedMacAddress(macToChangeInto);
MacAddress macAfterChange = config.getOrCreateRandomizedMacAddress();
assertEquals(macToChangeInto, macAfterChange);
}
@Test
public void testGetOrCreateRandomizedMacAddress_ReRandomizesInvalidAddress() {
WifiConfiguration config = new WifiConfiguration();
MacAddress macAddressZeroes = MacAddress.ALL_ZEROS_ADDRESS;
MacAddress macAddressMulticast = MacAddress.fromString("03:ff:ff:ff:ff:ff");
MacAddress macAddressGlobal = MacAddress.fromString("fc:ff:ff:ff:ff:ff");
config.setRandomizedMacAddress(null);
MacAddress macAfterChange = config.getOrCreateRandomizedMacAddress();
assertFalse(macAfterChange.equals(null));
config.setRandomizedMacAddress(macAddressZeroes);
macAfterChange = config.getOrCreateRandomizedMacAddress();
assertFalse(macAfterChange.equals(macAddressZeroes));
config.setRandomizedMacAddress(macAddressMulticast);
macAfterChange = config.getOrCreateRandomizedMacAddress();
assertFalse(macAfterChange.equals(macAddressMulticast));
config.setRandomizedMacAddress(macAddressGlobal);
macAfterChange = config.getOrCreateRandomizedMacAddress();
assertFalse(macAfterChange.equals(macAddressGlobal));
}
}