692 lines
29 KiB
Python
692 lines
29 KiB
Python
|
|
#!/usr/bin/env python3.4
|
||
|
|
#
|
||
|
|
# Copyright 2019 - The Android Open Source Project
|
||
|
|
#
|
||
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
# you may not use this file except in compliance with the License.
|
||
|
|
# You may obtain a copy of the License at
|
||
|
|
#
|
||
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
#
|
||
|
|
# Unless required by applicable law or agreed to in writing, software
|
||
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
# See the License for the specific language governing permissions and
|
||
|
|
# limitations under the License.
|
||
|
|
|
||
|
|
import itertools
|
||
|
|
import re
|
||
|
|
import time
|
||
|
|
|
||
|
|
import acts.base_test
|
||
|
|
import acts.signals as signals
|
||
|
|
import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
|
||
|
|
import acts.utils
|
||
|
|
|
||
|
|
from acts import asserts
|
||
|
|
from acts.test_decorators import test_tracker_info
|
||
|
|
from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
|
||
|
|
from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
|
||
|
|
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
|
||
|
|
from scapy.all import *
|
||
|
|
from acts.controllers.ap_lib import hostapd_constants
|
||
|
|
|
||
|
|
WifiEnums = wutils.WifiEnums
|
||
|
|
|
||
|
|
# Default timeout used for reboot, toggle WiFi and Airplane mode,
|
||
|
|
# for the system to settle down after the operation.
|
||
|
|
DEFAULT_TIMEOUT = 10
|
||
|
|
SHORT_TIMEOUT = 5
|
||
|
|
|
||
|
|
# Constants for WiFi state change operations.
|
||
|
|
FORGET = 1
|
||
|
|
TOGGLE = 2
|
||
|
|
REBOOT_DUT = 3
|
||
|
|
REBOOT_AP = 4
|
||
|
|
|
||
|
|
# MAC Randomization setting constants.
|
||
|
|
RANDOMIZATION_NONE = 0
|
||
|
|
RANDOMIZATION_PERSISTENT = 1
|
||
|
|
|
||
|
|
|
||
|
|
class WifiMacRandomizationTest(WifiBaseTest):
|
||
|
|
"""Tests for APIs in Android's WifiManager class.
|
||
|
|
|
||
|
|
Test Bed Requirement:
|
||
|
|
* Atleast one Android device and atleast two Access Points.
|
||
|
|
* Several Wi-Fi networks visible to the device.
|
||
|
|
"""
|
||
|
|
|
||
|
|
def setup_class(self):
|
||
|
|
super().setup_class()
|
||
|
|
|
||
|
|
self.dut = self.android_devices[0]
|
||
|
|
self.dut_client = self.android_devices[1]
|
||
|
|
wutils.wifi_test_device_init(self.dut)
|
||
|
|
wutils.wifi_test_device_init(self.dut_client)
|
||
|
|
req_params = [
|
||
|
|
"sta_sta_supported_models", "dbs_supported_models",
|
||
|
|
"support_one_factory_mac_address", "roaming_attn"
|
||
|
|
]
|
||
|
|
opt_param = ["open_network", "reference_networks", "wep_networks"]
|
||
|
|
self.unpack_userparams(req_param_names=req_params,
|
||
|
|
opt_param_names=opt_param)
|
||
|
|
|
||
|
|
if not hasattr(self, 'packet_capture'):
|
||
|
|
raise signals.TestFailure("Needs packet_capture attribute to "
|
||
|
|
"support sniffing.")
|
||
|
|
self.configure_packet_capture()
|
||
|
|
|
||
|
|
if "AccessPoint" in self.user_params:
|
||
|
|
self.legacy_configure_ap_and_start(wep_network=True, ap_count=2)
|
||
|
|
elif "OpenWrtAP" in self.user_params:
|
||
|
|
self.configure_openwrt_ap_and_start(open_network=True,
|
||
|
|
wpa_network=True,
|
||
|
|
wep_network=True,
|
||
|
|
mirror_ap=True,
|
||
|
|
ap_count=2)
|
||
|
|
|
||
|
|
asserts.assert_true(
|
||
|
|
len(self.reference_networks) > 0,
|
||
|
|
"Need at least one reference network with psk.")
|
||
|
|
|
||
|
|
# Reboot device to reset factory MAC of wlan1
|
||
|
|
self.dut.reboot()
|
||
|
|
self.dut_client.reboot()
|
||
|
|
time.sleep(DEFAULT_TIMEOUT)
|
||
|
|
wutils.wifi_toggle_state(self.dut, True)
|
||
|
|
wutils.wifi_toggle_state(self.dut_client, True)
|
||
|
|
if self.dut.model in self.support_one_factory_mac_address:
|
||
|
|
self.soft_ap_factory_mac = (
|
||
|
|
self.dut.droid.wifigetFactorymacAddresses()[0])
|
||
|
|
else:
|
||
|
|
self.soft_ap_factory_mac = self.get_soft_ap_mac_address()
|
||
|
|
self.sta_factory_mac = self.dut.droid.wifigetFactorymacAddresses()[0]
|
||
|
|
|
||
|
|
self.wpapsk_2g = self.reference_networks[0]["2g"]
|
||
|
|
self.wpapsk_5g = self.reference_networks[0]["5g"]
|
||
|
|
self.wep_2g = self.wep_networks[0]["2g"]
|
||
|
|
self.wep_5g = self.wep_networks[0]["5g"]
|
||
|
|
self.open_2g = self.open_network[0]["2g"]
|
||
|
|
self.open_5g = self.open_network[0]["5g"]
|
||
|
|
|
||
|
|
def setup_test(self):
|
||
|
|
super().setup_test()
|
||
|
|
for ad in self.android_devices:
|
||
|
|
ad.droid.wakeLockAcquireBright()
|
||
|
|
ad.droid.wakeUpNow()
|
||
|
|
wutils.wifi_toggle_state(ad, True)
|
||
|
|
|
||
|
|
def teardown_test(self):
|
||
|
|
super().teardown_test()
|
||
|
|
for ad in self.android_devices:
|
||
|
|
ad.droid.wakeLockRelease()
|
||
|
|
ad.droid.goToSleepNow()
|
||
|
|
self.dut.droid.wifiRemoveNetworkSuggestions([])
|
||
|
|
wutils.reset_wifi(self.dut)
|
||
|
|
wutils.reset_wifi(self.dut_client)
|
||
|
|
|
||
|
|
def teardown_class(self):
|
||
|
|
if "AccessPoint" in self.user_params:
|
||
|
|
del self.user_params["reference_networks"]
|
||
|
|
del self.user_params["open_network"]
|
||
|
|
del self.user_params["wep_networks"]
|
||
|
|
|
||
|
|
"""Helper Functions"""
|
||
|
|
|
||
|
|
def get_randomized_mac(self, network):
|
||
|
|
"""Get the randomized MAC address.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
network: dict, network information.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
The randomized MAC address string for the network.
|
||
|
|
|
||
|
|
"""
|
||
|
|
return self.dut.droid.wifigetRandomizedMacAddress(network)
|
||
|
|
|
||
|
|
def connect_to_network_and_verify_mac_randomization(
|
||
|
|
self, network, status=RANDOMIZATION_PERSISTENT):
|
||
|
|
"""Connect to the given network and verify MAC.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
network: dict, the network information.
|
||
|
|
status: int, MAC randomization level.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
The randomized MAC addresss string.
|
||
|
|
|
||
|
|
"""
|
||
|
|
wutils.connect_to_wifi_network(self.dut, network)
|
||
|
|
return self.verify_mac_randomization(network, status=status)
|
||
|
|
|
||
|
|
def verify_mac_randomization_and_add_to_list(self, network, mac_list):
|
||
|
|
"""Connect to a network and populate it's MAC in a reference list,
|
||
|
|
that will be used to verify any repeated MAC addresses.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
network: dict, the network information.
|
||
|
|
mac_list: list of MAC addresss strings.
|
||
|
|
|
||
|
|
"""
|
||
|
|
rand_mac = self.connect_to_network_and_verify_mac_randomization(
|
||
|
|
network)
|
||
|
|
if rand_mac in mac_list:
|
||
|
|
raise signals.TestFailure('A new Randomized MAC was not generated '
|
||
|
|
' for this network %s.' % network)
|
||
|
|
mac_list.append(rand_mac)
|
||
|
|
|
||
|
|
def verify_mac_randomization(self,
|
||
|
|
network,
|
||
|
|
status=RANDOMIZATION_PERSISTENT):
|
||
|
|
"""Get the various types of MAC addresses for the device and verify.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
network: dict, the network information.
|
||
|
|
status: int, MAC randomization level.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
The randomized MAC address string for the network.
|
||
|
|
|
||
|
|
"""
|
||
|
|
randomized_mac = self.get_randomized_mac(network)
|
||
|
|
default_mac = self.get_sta_mac_address()
|
||
|
|
self.log.info(
|
||
|
|
"Factory MAC = %s\nRandomized MAC = %s\nDefault MAC = %s" %
|
||
|
|
(self.sta_factory_mac, randomized_mac, default_mac))
|
||
|
|
message = ('Randomized MAC and Factory MAC are the same. '
|
||
|
|
'Randomized MAC = %s, Factory MAC = %s' %
|
||
|
|
(randomized_mac, self.sta_factory_mac))
|
||
|
|
asserts.assert_true(randomized_mac != self.sta_factory_mac, message)
|
||
|
|
if status == RANDOMIZATION_NONE:
|
||
|
|
asserts.assert_true(
|
||
|
|
default_mac == self.sta_factory_mac, "Connection is not "
|
||
|
|
"using Factory MAC as the default MAC.")
|
||
|
|
else:
|
||
|
|
message = (
|
||
|
|
'Connection is not using randomized MAC as the default MAC. '
|
||
|
|
'Randomized MAC = %s, Default MAC = %s' %
|
||
|
|
(randomized_mac, default_mac))
|
||
|
|
asserts.assert_true(default_mac == randomized_mac, message)
|
||
|
|
return randomized_mac
|
||
|
|
|
||
|
|
def check_mac_persistence(self, network, condition):
|
||
|
|
"""Check if the MAC is persistent after carrying out specific operations
|
||
|
|
like forget WiFi, toggle WiFi, reboot device and AP.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
network: dict, The network information.
|
||
|
|
condition: int, value to trigger certain operation on the device.
|
||
|
|
|
||
|
|
Raises:
|
||
|
|
TestFaikure is the MAC is not persistent.
|
||
|
|
|
||
|
|
"""
|
||
|
|
rand_mac1 = self.connect_to_network_and_verify_mac_randomization(
|
||
|
|
network)
|
||
|
|
|
||
|
|
if condition == FORGET:
|
||
|
|
wutils.wifi_forget_network(self.dut, network['SSID'])
|
||
|
|
|
||
|
|
elif condition == TOGGLE:
|
||
|
|
wutils.wifi_toggle_state(self.dut, False)
|
||
|
|
wutils.wifi_toggle_state(self.dut, True)
|
||
|
|
|
||
|
|
elif condition == REBOOT_DUT:
|
||
|
|
self.dut.reboot()
|
||
|
|
time.sleep(DEFAULT_TIMEOUT)
|
||
|
|
|
||
|
|
elif condition == REBOOT_AP:
|
||
|
|
wutils.turn_ap_off(self, 1)
|
||
|
|
time.sleep(DEFAULT_TIMEOUT)
|
||
|
|
wutils.turn_ap_on(self, 1)
|
||
|
|
time.sleep(DEFAULT_TIMEOUT)
|
||
|
|
|
||
|
|
rand_mac2 = self.connect_to_network_and_verify_mac_randomization(
|
||
|
|
network)
|
||
|
|
|
||
|
|
if rand_mac1 != rand_mac2:
|
||
|
|
raise signals.TestFailure('Randomized MAC is not persistent after '
|
||
|
|
'forgetting networ. Old MAC = %s New MAC'
|
||
|
|
' = %s' % (rand_mac1, rand_mac2))
|
||
|
|
|
||
|
|
def verify_mac_not_found_in_pcap(self, mac, packets):
|
||
|
|
for pkt in packets:
|
||
|
|
self.log.debug("Packet Summary = %s" % pkt.summary())
|
||
|
|
if mac in pkt.summary():
|
||
|
|
raise signals.TestFailure(
|
||
|
|
"Caught Factory MAC in packet sniffer"
|
||
|
|
"Packet = %s Device = %s" % (pkt.show(), self.dut))
|
||
|
|
|
||
|
|
def verify_mac_is_found_in_pcap(self, mac, packets):
|
||
|
|
for pkt in packets:
|
||
|
|
self.log.debug("Packet Summary = %s" % pkt.summary())
|
||
|
|
if mac in pkt.summary():
|
||
|
|
return
|
||
|
|
raise signals.TestFailure("Did not find MAC = %s in packet sniffer."
|
||
|
|
"for device %s" % (mac, self.dut))
|
||
|
|
|
||
|
|
def get_sta_mac_address(self):
|
||
|
|
"""Gets the current MAC address being used for client mode."""
|
||
|
|
out = self.dut.adb.shell("ifconfig wlan0")
|
||
|
|
res = re.match(".* HWaddr (\S+).*", out, re.S)
|
||
|
|
return res.group(1)
|
||
|
|
|
||
|
|
def get_soft_ap_mac_address(self):
|
||
|
|
"""Gets the current MAC address being used for SoftAp."""
|
||
|
|
if self.dut.model in self.sta_sta_supported_models:
|
||
|
|
out = self.dut.adb.shell("ifconfig wlan2")
|
||
|
|
return re.match(".* HWaddr (\S+).*", out, re.S).group(1)
|
||
|
|
if self.dut.model in self.dbs_supported_models:
|
||
|
|
out = self.dut.adb.shell("ifconfig wlan1")
|
||
|
|
return re.match(".* HWaddr (\S+).*", out, re.S).group(1)
|
||
|
|
else:
|
||
|
|
return self.get_sta_mac_address()
|
||
|
|
|
||
|
|
def _add_suggestion_and_verify_mac_randomization(self, network_suggestion):
|
||
|
|
"""Add wifi network suggestion and verify MAC randomization.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
network_suggestion: network suggestion to add.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Randomized MAC address.
|
||
|
|
"""
|
||
|
|
self.log.info("Adding network suggestion")
|
||
|
|
asserts.assert_true(
|
||
|
|
self.dut.droid.wifiAddNetworkSuggestions([network_suggestion]),
|
||
|
|
"Failed to add suggestions")
|
||
|
|
wutils.start_wifi_connection_scan_and_ensure_network_found(
|
||
|
|
self.dut, network_suggestion[WifiEnums.SSID_KEY])
|
||
|
|
wutils.wait_for_connect(self.dut,
|
||
|
|
network_suggestion[WifiEnums.SSID_KEY])
|
||
|
|
default_mac = self.get_sta_mac_address()
|
||
|
|
randomized_mac = self.dut.droid.wifiGetConnectionInfo()["mac_address"]
|
||
|
|
self.log.info(
|
||
|
|
"Factory MAC = %s\nRandomized MAC = %s\nDefault MAC = %s" %
|
||
|
|
(self.sta_factory_mac, randomized_mac, default_mac))
|
||
|
|
asserts.assert_true(
|
||
|
|
default_mac == randomized_mac,
|
||
|
|
"Connection is not using randomized MAC as the default MAC.")
|
||
|
|
return randomized_mac
|
||
|
|
|
||
|
|
def _remove_suggestion_and_verify_disconnect(self, network_suggestion):
|
||
|
|
"""Remove wifi network suggestion and verify device disconnects.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
network_suggestion: network suggestion to remove.
|
||
|
|
"""
|
||
|
|
self.dut.log.info("Removing network suggestions")
|
||
|
|
asserts.assert_true(
|
||
|
|
self.dut.droid.wifiRemoveNetworkSuggestions([network_suggestion]),
|
||
|
|
"Failed to remove suggestions")
|
||
|
|
wutils.wait_for_disconnect(self.dut)
|
||
|
|
self.dut.ed.clear_all_events()
|
||
|
|
asserts.assert_false(
|
||
|
|
wutils.wait_for_connect(self.dut,
|
||
|
|
network_suggestion[WifiEnums.SSID_KEY],
|
||
|
|
assert_on_fail=False),
|
||
|
|
"Device should not connect back")
|
||
|
|
|
||
|
|
"""Tests"""
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="2dd0a05e-a318-45a6-81cd-962e098fa242")
|
||
|
|
def test_set_mac_randomization_to_none(self):
|
||
|
|
self.pcap_procs = wutils.start_pcap(self.packet_capture, 'dual',
|
||
|
|
self.test_name)
|
||
|
|
network = self.wpapsk_2g
|
||
|
|
# Set macRandomizationSetting to RANDOMIZATION_NONE.
|
||
|
|
network["macRand"] = RANDOMIZATION_NONE
|
||
|
|
self.connect_to_network_and_verify_mac_randomization(
|
||
|
|
network, status=RANDOMIZATION_NONE)
|
||
|
|
pcap_fname = '%s_%s.pcap' % \
|
||
|
|
(self.pcap_procs[hostapd_constants.BAND_2G][1],
|
||
|
|
hostapd_constants.BAND_2G.upper())
|
||
|
|
time.sleep(SHORT_TIMEOUT)
|
||
|
|
wutils.stop_pcap(self.packet_capture, self.pcap_procs, False)
|
||
|
|
packets = rdpcap(pcap_fname)
|
||
|
|
self.verify_mac_is_found_in_pcap(self.sta_factory_mac, packets)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="d9e64202-02d5-421a-967c-42e45f1f7f91")
|
||
|
|
def test_mac_randomization_wpapsk(self):
|
||
|
|
"""Verify MAC randomization for a WPA network.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Connect to WPA network.
|
||
|
|
2. Get the Factory, Randomized and Default MACs.
|
||
|
|
3. Verify randomized MAC is the default MAC for the device.
|
||
|
|
|
||
|
|
"""
|
||
|
|
self.connect_to_network_and_verify_mac_randomization(self.wpapsk_2g)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="b5be7c53-2edf-449e-ba70-a1fb7acf735e")
|
||
|
|
def test_mac_randomization_wep(self):
|
||
|
|
"""Verify MAC randomization for a WEP network.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Connect to WEP network.
|
||
|
|
2. Get the Factory, Randomized and Default MACs.
|
||
|
|
3. Verify randomized MAC is the default MAC for the device.
|
||
|
|
|
||
|
|
"""
|
||
|
|
self.connect_to_network_and_verify_mac_randomization(self.wep_2g)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="f5347ac0-68d5-4882-a58d-1bd0d575503c")
|
||
|
|
def test_mac_randomization_open(self):
|
||
|
|
"""Verify MAC randomization for a open network.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Connect to open network.
|
||
|
|
2. Get the Factory, Randomized and Default MACs.
|
||
|
|
3. Verify randomized MAC is the default MAC for the device.
|
||
|
|
|
||
|
|
"""
|
||
|
|
self.connect_to_network_and_verify_mac_randomization(self.open_2g)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="5d260421-2adf-4ace-b281-3d15aec39b2a")
|
||
|
|
def test_persistent_mac_after_forget(self):
|
||
|
|
"""Check if MAC is persistent after forgetting/adding a network.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Connect to WPA network and get the randomized MAC.
|
||
|
|
2. Forget the network.
|
||
|
|
3. Connect to the same network again.
|
||
|
|
4. Verify randomized MAC has not changed.
|
||
|
|
|
||
|
|
"""
|
||
|
|
self.check_mac_persistence(self.wpapsk_2g, FORGET)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="09d40a93-ead2-45ca-9905-14b05fd79f34")
|
||
|
|
def test_persistent_mac_after_toggle(self):
|
||
|
|
"""Check if MAC is persistent after toggling WiFi network.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Connect to WPA network and get the randomized MAC.
|
||
|
|
2. Turn WiFi ON/OFF.
|
||
|
|
3. Connect to the same network again.
|
||
|
|
4. Verify randomized MAC has not changed.
|
||
|
|
|
||
|
|
"""
|
||
|
|
self.check_mac_persistence(self.wpapsk_2g, TOGGLE)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="b3aa514f-8562-44e8-bfe0-4ecab9af165b")
|
||
|
|
def test_persistent_mac_after_device_reboot(self):
|
||
|
|
"""Check if MAC is persistent after a device reboot.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Connect to WPA network and get the randomized MAC.
|
||
|
|
2. Reboot DUT.
|
||
|
|
3. Connect to the same network again.
|
||
|
|
4. Verify randomized MAC has not changed.
|
||
|
|
|
||
|
|
"""
|
||
|
|
self.check_mac_persistence(self.wpapsk_2g, REBOOT_DUT)
|
||
|
|
|
||
|
|
# Disable reboot test for debugging purpose.
|
||
|
|
#@test_tracker_info(uuid="82d691a0-22e4-4a3d-9596-e150531fcd34")
|
||
|
|
def persistent_mac_after_ap_reboot(self):
|
||
|
|
"""Check if MAC is persistent after AP reboots itself.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Connect to WPA network and get the randomized MAC.
|
||
|
|
2. Reboot AP(basically restart hostapd in our case).
|
||
|
|
3. Connect to the same network again.
|
||
|
|
4. Verify randomized MAC has not changed.
|
||
|
|
|
||
|
|
"""
|
||
|
|
self.check_mac_persistence(self.wpapsk_2g, REBOOT_AP)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="e1f33dbc-808c-4e61-8a4a-3a72c1f63c7e")
|
||
|
|
def test_mac_randomization_multiple_networks(self):
|
||
|
|
"""Connect to multiple networks and verify same MAC.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Connect to network A, get randomizd MAC.
|
||
|
|
2. Conenct to network B, get randomized MAC.
|
||
|
|
3. Connect back to network A and verify same MAC.
|
||
|
|
4. Connect back to network B and verify same MAC.
|
||
|
|
|
||
|
|
"""
|
||
|
|
mac_list = list()
|
||
|
|
|
||
|
|
# Connect to two different networks and get randomized MAC addresses.
|
||
|
|
self.verify_mac_randomization_and_add_to_list(self.wpapsk_2g, mac_list)
|
||
|
|
self.verify_mac_randomization_and_add_to_list(self.open_2g, mac_list)
|
||
|
|
|
||
|
|
# Connect to the previous network and check MAC is persistent.
|
||
|
|
mac_wpapsk = self.connect_to_network_and_verify_mac_randomization(
|
||
|
|
self.wpapsk_2g)
|
||
|
|
msg = (
|
||
|
|
'Randomized MAC is not persistent for this network %s. Old MAC = '
|
||
|
|
'%s \nNew MAC = %s')
|
||
|
|
if mac_wpapsk != mac_list[0]:
|
||
|
|
raise signals.TestFailure(
|
||
|
|
msg % (self.wpapsk_5g, mac_list[0], mac_wpapsk))
|
||
|
|
mac_open = self.connect_to_network_and_verify_mac_randomization(
|
||
|
|
self.open_2g)
|
||
|
|
if mac_open != mac_list[1]:
|
||
|
|
raise signals.TestFailure(msg %
|
||
|
|
(self.open_5g, mac_list[1], mac_open))
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="edb5a0e5-7f3b-4147-b1d3-48ad7ad9799e")
|
||
|
|
def test_mac_randomization_different_APs(self):
|
||
|
|
"""Verify randomization using two different APs.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Connect to network A on AP1, get the randomized MAC.
|
||
|
|
2. Connect to network B on AP2, get the randomized MAC.
|
||
|
|
3. Veirfy the two MACs are different.
|
||
|
|
|
||
|
|
"""
|
||
|
|
ap1 = self.wpapsk_2g
|
||
|
|
ap2 = self.reference_networks[1]["5g"]
|
||
|
|
mac_ap1 = self.connect_to_network_and_verify_mac_randomization(ap1)
|
||
|
|
mac_ap2 = self.connect_to_network_and_verify_mac_randomization(ap2)
|
||
|
|
if mac_ap1 == mac_ap2:
|
||
|
|
raise signals.TestFailure(
|
||
|
|
"Same MAC address was generated for both "
|
||
|
|
"APs: %s" % mac_ap1)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="b815e9ce-bccd-4fc3-9774-1e1bc123a2a8")
|
||
|
|
def test_mac_randomization_ap_sta(self):
|
||
|
|
"""Bring up STA and softAP and verify MAC randomization.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Connect to a network and get randomized MAC.
|
||
|
|
2. Bring up softAP on the DUT.
|
||
|
|
3. Connect to softAP network on the client and get MAC.
|
||
|
|
4. Verify AP and STA use different randomized MACs.
|
||
|
|
5. Find the channel of the SoftAp network.
|
||
|
|
6. Configure sniffer on that channel.
|
||
|
|
7. Verify the factory MAC is not leaked.
|
||
|
|
|
||
|
|
"""
|
||
|
|
wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US)
|
||
|
|
wutils.set_wifi_country_code(self.dut_client,
|
||
|
|
wutils.WifiEnums.CountryCode.US)
|
||
|
|
mac_sta = self.connect_to_network_and_verify_mac_randomization(
|
||
|
|
self.wpapsk_2g)
|
||
|
|
softap = wutils.start_softap_and_verify(self, WIFI_CONFIG_APBAND_2G)
|
||
|
|
wutils.connect_to_wifi_network(self.dut_client, softap)
|
||
|
|
softap_info = self.dut_client.droid.wifiGetConnectionInfo()
|
||
|
|
mac_ap = softap_info['mac_address']
|
||
|
|
if mac_sta == mac_ap:
|
||
|
|
raise signals.TestFailure("Same MAC address was used for both "
|
||
|
|
"AP and STA: %s" % mac_sta)
|
||
|
|
|
||
|
|
# Verify SoftAp MAC is randomized
|
||
|
|
softap_mac = self.get_soft_ap_mac_address()
|
||
|
|
message = (
|
||
|
|
'Randomized SoftAp MAC and Factory SoftAp MAC are the same. '
|
||
|
|
'Randomized SoftAp MAC = %s, Factory SoftAp MAC = %s' %
|
||
|
|
(softap_mac, self.soft_ap_factory_mac))
|
||
|
|
asserts.assert_true(softap_mac != self.soft_ap_factory_mac, message)
|
||
|
|
|
||
|
|
softap_channel = hostapd_constants.CHANNEL_MAP[
|
||
|
|
softap_info['frequency']]
|
||
|
|
self.log.info("softap_channel = %s\n" % (softap_channel))
|
||
|
|
result = self.packet_capture.configure_monitor_mode(
|
||
|
|
hostapd_constants.BAND_2G, softap_channel)
|
||
|
|
if not result:
|
||
|
|
raise ValueError("Failed to configure channel for 2G band")
|
||
|
|
self.pcap_procs = wutils.start_pcap(self.packet_capture, 'dual',
|
||
|
|
self.test_name)
|
||
|
|
# re-connect to the softAp network after sniffer is started
|
||
|
|
wutils.connect_to_wifi_network(self.dut_client, self.wpapsk_2g)
|
||
|
|
wutils.connect_to_wifi_network(self.dut_client, softap)
|
||
|
|
time.sleep(SHORT_TIMEOUT)
|
||
|
|
wutils.stop_pcap(self.packet_capture, self.pcap_procs, False)
|
||
|
|
pcap_fname = '%s_%s.pcap' % \
|
||
|
|
(self.pcap_procs[hostapd_constants.BAND_2G][1],
|
||
|
|
hostapd_constants.BAND_2G.upper())
|
||
|
|
packets = rdpcap(pcap_fname)
|
||
|
|
self.verify_mac_not_found_in_pcap(self.soft_ap_factory_mac, packets)
|
||
|
|
self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets)
|
||
|
|
self.verify_mac_is_found_in_pcap(softap_mac, packets)
|
||
|
|
self.verify_mac_is_found_in_pcap(self.get_sta_mac_address(), packets)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="3ca3f911-29f1-41fb-b836-4d25eac1669f")
|
||
|
|
def test_roaming_mac_randomization(self):
|
||
|
|
"""test MAC randomization in the roaming scenario.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Connect to network A on AP1, get randomized MAC.
|
||
|
|
2. Set AP1 to MAX attenuation so that we roam to AP2.
|
||
|
|
3. Wait for device to roam to AP2 and get randomized MAC.
|
||
|
|
4. Veirfy that the device uses same AMC for both APs.
|
||
|
|
|
||
|
|
"""
|
||
|
|
AP1_network = self.reference_networks[0]["5g"]
|
||
|
|
AP2_network = self.reference_networks[1]["5g"]
|
||
|
|
if "OpenWrtAP" in self.user_params:
|
||
|
|
AP1_network["bssid"] = self.bssid_map[0]["5g"][AP1_network["SSID"]]
|
||
|
|
AP2_network["bssid"] = self.bssid_map[1]["5g"][AP2_network["SSID"]]
|
||
|
|
wutils.set_attns(self.attenuators, "AP1_on_AP2_off", self.roaming_attn)
|
||
|
|
mac_before_roam = self.connect_to_network_and_verify_mac_randomization(
|
||
|
|
AP1_network)
|
||
|
|
wutils.trigger_roaming_and_validate(self.dut, self.attenuators,
|
||
|
|
"AP1_off_AP2_on", AP2_network,
|
||
|
|
self.roaming_attn)
|
||
|
|
mac_after_roam = self.get_randomized_mac(AP2_network)
|
||
|
|
if mac_after_roam != mac_before_roam:
|
||
|
|
raise signals.TestFailure(
|
||
|
|
"Randomized MAC address changed after "
|
||
|
|
"roaming from AP1 to AP2.\nMAC before roam = %s\nMAC after "
|
||
|
|
"roam = %s" % (mac_before_roam, mac_after_roam))
|
||
|
|
wutils.trigger_roaming_and_validate(self.dut, self.attenuators,
|
||
|
|
"AP1_on_AP2_off", AP1_network,
|
||
|
|
self.roaming_attn)
|
||
|
|
mac_after_roam = self.get_randomized_mac(AP1_network)
|
||
|
|
if mac_after_roam != mac_before_roam:
|
||
|
|
raise signals.TestFailure(
|
||
|
|
"Randomized MAC address changed after "
|
||
|
|
"roaming from AP1 to AP2.\nMAC before roam = %s\nMAC after "
|
||
|
|
"roam = %s" % (mac_before_roam, mac_after_roam))
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="17b12f1a-7c62-4188-b5a5-52d7a0bb7849")
|
||
|
|
def test_check_mac_sta_with_link_probe(self):
|
||
|
|
"""Test to ensure Factory MAC is not exposed, using sniffer data.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Configure and start the sniffer on 5GHz band.
|
||
|
|
2. Connect to 5GHz network.
|
||
|
|
3. Send link probes.
|
||
|
|
4. Stop the sniffer.
|
||
|
|
5. Invoke scapy to read the .pcap file.
|
||
|
|
6. Read each packet summary and make sure Factory MAC is not used.
|
||
|
|
|
||
|
|
"""
|
||
|
|
self.pcap_procs = wutils.start_pcap(self.packet_capture, 'dual',
|
||
|
|
self.test_name)
|
||
|
|
time.sleep(SHORT_TIMEOUT)
|
||
|
|
network = self.wpapsk_5g
|
||
|
|
rand_mac = self.connect_to_network_and_verify_mac_randomization(
|
||
|
|
network)
|
||
|
|
pcap_fname_bflink = '%s_%s.pcap' % \
|
||
|
|
(self.pcap_procs[hostapd_constants.BAND_5G][1],
|
||
|
|
hostapd_constants.BAND_5G.upper())
|
||
|
|
wutils.stop_pcap(self.packet_capture, self.pcap_procs, False)
|
||
|
|
time.sleep(SHORT_TIMEOUT)
|
||
|
|
packets_bflink = rdpcap(pcap_fname_bflink)
|
||
|
|
self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets_bflink)
|
||
|
|
self.verify_mac_is_found_in_pcap(rand_mac, packets_bflink)
|
||
|
|
self.pcap_procs = wutils.start_pcap(self.packet_capture, 'dual',
|
||
|
|
self.test_name)
|
||
|
|
time.sleep(SHORT_TIMEOUT)
|
||
|
|
wutils.send_link_probes(self.dut, 3, 3)
|
||
|
|
pcap_fname = '%s_%s.pcap' % \
|
||
|
|
(self.pcap_procs[hostapd_constants.BAND_5G][1],
|
||
|
|
hostapd_constants.BAND_5G.upper())
|
||
|
|
wutils.stop_pcap(self.packet_capture, self.pcap_procs, False)
|
||
|
|
time.sleep(SHORT_TIMEOUT)
|
||
|
|
packets = rdpcap(pcap_fname)
|
||
|
|
self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets)
|
||
|
|
self.verify_mac_is_found_in_pcap(rand_mac, packets)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="1c2cc0fd-a340-40c4-b679-6acc5f526451")
|
||
|
|
def test_check_mac_in_wifi_scan(self):
|
||
|
|
"""Test to ensure Factory MAC is not exposed, in Wi-Fi scans
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Configure and start the sniffer on both bands.
|
||
|
|
2. Perform a full scan.
|
||
|
|
3. Stop the sniffer.
|
||
|
|
4. Invoke scapy to read the .pcap file.
|
||
|
|
5. Read each packet summary and make sure Factory MAC is not used.
|
||
|
|
|
||
|
|
"""
|
||
|
|
self.pcap_procs = wutils.start_pcap(self.packet_capture, 'dual',
|
||
|
|
self.test_name)
|
||
|
|
wutils.start_wifi_connection_scan(self.dut)
|
||
|
|
time.sleep(SHORT_TIMEOUT)
|
||
|
|
wutils.stop_pcap(self.packet_capture, self.pcap_procs, False)
|
||
|
|
pcap_fname = '%s_%s.pcap' % \
|
||
|
|
(self.pcap_procs[hostapd_constants.BAND_2G][1],
|
||
|
|
hostapd_constants.BAND_2G.upper())
|
||
|
|
packets = rdpcap(pcap_fname)
|
||
|
|
self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="7714d31f-bb08-4f29-b246-0ce1398a3c03")
|
||
|
|
def test_mac_randomization_for_network_suggestion(self):
|
||
|
|
"""Add network suggestion and verify MAC randomization.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Add a network suggestion and verify device connects to it.
|
||
|
|
2. Verify the device uses randomized MAC address for this network.
|
||
|
|
"""
|
||
|
|
network_suggestion = self.reference_networks[0]["2g"]
|
||
|
|
self._add_suggestion_and_verify_mac_randomization(network_suggestion)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="144ad0b4-b79d-4b1d-a8a9-3c612a76c32c")
|
||
|
|
def test_enhanced_mac_randomization_for_network_suggestion(self):
|
||
|
|
"""Test enhanced MAC randomization.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Add a network suggestion with enhanced mac randomization enabled.
|
||
|
|
2. Connect to the network and verify the MAC address is random.
|
||
|
|
3. Remove the suggestion network and add it back.
|
||
|
|
4. Connect to the network. Verify the MAC address is random and
|
||
|
|
different from the randomized MAC observed in step 2.
|
||
|
|
"""
|
||
|
|
asserts.skip_if(not self.dut.droid.isSdkAtLeastS(),
|
||
|
|
"This feature is only supported on S and later.")
|
||
|
|
|
||
|
|
network_suggestion = self.reference_networks[0]["5g"]
|
||
|
|
network_suggestion["enhancedMacRandomizationEnabled"] = True
|
||
|
|
|
||
|
|
# add network suggestion with enhanced mac randomization
|
||
|
|
randomized_mac1 = self._add_suggestion_and_verify_mac_randomization(
|
||
|
|
network_suggestion)
|
||
|
|
|
||
|
|
# remove network suggestion and verify no connection
|
||
|
|
self._remove_suggestion_and_verify_disconnect(network_suggestion)
|
||
|
|
|
||
|
|
# add network suggestion and verify device connects back
|
||
|
|
randomized_mac2 = self._add_suggestion_and_verify_mac_randomization(
|
||
|
|
network_suggestion)
|
||
|
|
|
||
|
|
# verify both randomized mac addrs are different
|
||
|
|
asserts.assert_true(randomized_mac1 != randomized_mac2,
|
||
|
|
"Randomized MAC addresses are same.")
|