All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/5] util: add util_is_valid_sta_address
@ 2020-03-19 22:58 James Prestwood
  2020-03-19 22:58 ` [PATCH v3 2/5] station: support full MAC randomization and override James Prestwood
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: James Prestwood @ 2020-03-19 22:58 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 1169 bytes --]

Checks that that address is neither broadcast or group
---
 src/util.c | 5 +++++
 src/util.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/src/util.c b/src/util.c
index 0c41ceb5..13b01c81 100644
--- a/src/util.c
+++ b/src/util.c
@@ -166,6 +166,11 @@ bool util_is_broadcast_address(const uint8_t *addr)
 	return !memcmp(addr, bcast_addr, 6);
 }
 
+bool util_is_valid_sta_address(const uint8_t *addr)
+{
+	return !util_is_broadcast_address(addr) && !util_is_group_address(addr);
+}
+
 /* This function assumes that identity is not bigger than 253 bytes */
 const char *util_get_domain(const char *identity)
 {
diff --git a/src/util.h b/src/util.h
index dfd1c847..edc6e777 100644
--- a/src/util.h
+++ b/src/util.h
@@ -38,6 +38,7 @@ const char *util_address_to_string(const uint8_t *addr);
 bool util_string_to_address(const char *str, uint8_t *addr);
 bool util_is_group_address(const uint8_t *addr);
 bool util_is_broadcast_address(const uint8_t *addr);
+bool util_is_valid_sta_address(const uint8_t *addr);
 
 const char *util_get_domain(const char *identity);
 const char *util_get_username(const char *identity);
-- 
2.21.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 2/5] station: support full MAC randomization and override
  2020-03-19 22:58 [PATCH v3 1/5] util: add util_is_valid_sta_address James Prestwood
@ 2020-03-19 22:58 ` James Prestwood
  2020-03-19 22:59 ` [PATCH v3 3/5] netdev: honor handshake->spa if set James Prestwood
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: James Prestwood @ 2020-03-19 22:58 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 2641 bytes --]

This patch adds two new options to a network provisioning file:

AlwaysRandomizeAddress={true,false}

If true, IWD will randomize the MAC address on each connection to this
network. The address does not persists between connections, any new
connection will result in a different MAC.

AddressOverride=<MAC>

If set, the MAC address will be set to <MAC> assuming its a valid MAC
address.

These two options should not be used together, and will only take effect
if [General].AddressRandomization is set to 'network' in the IWD
config file.

If neither of these options are set, and [General].AddressRandomization
is set to 'network', the default behavior remains the same; the MAC
will be generated deterministically on a per-network basis.
---
 src/station.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/src/station.c b/src/station.c
index 36b41f64..ca47568c 100644
--- a/src/station.c
+++ b/src/station.c
@@ -875,6 +875,10 @@ static struct handshake_state *station_handshake_setup(struct station *station,
 	struct handshake_state *hs;
 	const char *ssid;
 	uint32_t eapol_proto_version;
+	const char *value;
+	bool full_random;
+	bool override = false;
+	uint8_t new_addr[ETH_ALEN];
 
 	hs = netdev_handshake_state_new(station->netdev);
 
@@ -934,6 +938,42 @@ static struct handshake_state *station_handshake_setup(struct station *station,
 				IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384))
 		hs->erp_cache = erp_cache_get(network_get_ssid(network));
 
+	/*
+	 * We have three possible options here:
+	 * 1. per-network MAC generation (default, no option in network config)
+	 * 2. per-network full MAC randomization
+	 * 3. per-network MAC override
+	 */
+
+	if (!l_settings_get_bool(settings, "Settings",
+					"AlwaysRandomizeAddress",
+					&full_random))
+		full_random = false;
+
+	value = l_settings_get_value(settings, "Settings",
+					"AddressOverride");
+	if (value) {
+		if (util_string_to_address(value, new_addr) &&
+					util_is_valid_sta_address(new_addr))
+			override = true;
+		else
+			l_warn("[Network].AddressOverride is not a valid "
+				"MAC address");
+	}
+
+	if (override && full_random) {
+		l_warn("Cannot use both AlwaysRandomizeAddress and "
+			"AddressOverride concurrently, defaulting to override");
+		full_random = false;
+	}
+
+	if (override)
+		handshake_state_set_supplicant_address(hs, new_addr);
+	else if (full_random) {
+		wiphy_generate_random_address(wiphy, new_addr);
+		handshake_state_set_supplicant_address(hs, new_addr);
+	}
+
 	return hs;
 
 no_psk:
-- 
2.21.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 3/5] netdev: honor handshake->spa if set
  2020-03-19 22:58 [PATCH v3 1/5] util: add util_is_valid_sta_address James Prestwood
  2020-03-19 22:58 ` [PATCH v3 2/5] station: support full MAC randomization and override James Prestwood
@ 2020-03-19 22:59 ` James Prestwood
  2020-03-19 22:59 ` [PATCH v3 4/5] doc: document AlwaysRandomizeAddress and AddressOverride James Prestwood
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: James Prestwood @ 2020-03-19 22:59 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 1019 bytes --]

In order to support AlwaysRandomizeAddress and AddressOverride, station will
set the desired address into the handshake object. Then, netdev checks if
this was done and will use that address rather than generate one.
---
 src/netdev.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/netdev.c b/src/netdev.c
index e1c775be..e1afeb63 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -2560,8 +2560,13 @@ static int netdev_start_powered_mac_change(struct netdev *netdev,
 	struct rtnl_data *req;
 	uint8_t new_addr[6];
 
-	wiphy_generate_address_from_ssid(netdev->wiphy, (const char *)bss->ssid,
+	/* No address set in handshake, use per-network MAC generation */
+	if (util_mem_is_zero(netdev->handshake->spa, ETH_ALEN))
+		wiphy_generate_address_from_ssid(netdev->wiphy,
+						(const char *)bss->ssid,
 						new_addr);
+	else
+		memcpy(new_addr, netdev->handshake->spa, ETH_ALEN);
 
 	/*
 	 * MAC has already been changed previously, no need to again
-- 
2.21.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 4/5] doc: document AlwaysRandomizeAddress and AddressOverride
  2020-03-19 22:58 [PATCH v3 1/5] util: add util_is_valid_sta_address James Prestwood
  2020-03-19 22:58 ` [PATCH v3 2/5] station: support full MAC randomization and override James Prestwood
  2020-03-19 22:59 ` [PATCH v3 3/5] netdev: honor handshake->spa if set James Prestwood
@ 2020-03-19 22:59 ` James Prestwood
  2020-03-19 22:59 ` [PATCH v3 5/5] auto-t: add test for AddressRandomization option James Prestwood
  2020-03-19 23:02 ` [PATCH v3 1/5] util: add util_is_valid_sta_address Denis Kenzior
  4 siblings, 0 replies; 6+ messages in thread
From: James Prestwood @ 2020-03-19 22:59 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 1254 bytes --]

---
 src/iwd.network.rst | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/iwd.network.rst b/src/iwd.network.rst
index 6b068202..74520db3 100644
--- a/src/iwd.network.rst
+++ b/src/iwd.network.rst
@@ -109,6 +109,21 @@ The group ``[Settings]`` contains general settings.
 
        Whether the network is hidden, i.e. its SSID must be included in an
        active scan request
+   * - AlwaysRandomizeAddress
+     - Values: true, **false**
+
+       If enabled, the MAC address will be fully randomized on each connection.
+       This option is only used if [General].AddressRandomization is set to
+       'network'. See iwd.config. This value should not be used with
+       [Settings].AddressOverride, if both are set AddressOverride will be used.
+   * - AddressOverride
+     - MAC address string
+
+       Override the MAC address used for connecting to this network. This option
+       is only used if [General].AddressRandomization is set to 'network'. See
+       iwd.config. This value should not be used with
+       [Settings].FullAddressRandomization, if both are set AddressOverride will
+       be used.
 
 Network Authentication Settings
 -------------------------------
-- 
2.21.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 5/5] auto-t: add test for AddressRandomization option
  2020-03-19 22:58 [PATCH v3 1/5] util: add util_is_valid_sta_address James Prestwood
                   ` (2 preceding siblings ...)
  2020-03-19 22:59 ` [PATCH v3 4/5] doc: document AlwaysRandomizeAddress and AddressOverride James Prestwood
@ 2020-03-19 22:59 ` James Prestwood
  2020-03-19 23:02 ` [PATCH v3 1/5] util: add util_is_valid_sta_address Denis Kenzior
  4 siblings, 0 replies; 6+ messages in thread
From: James Prestwood @ 2020-03-19 22:59 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 6034 bytes --]

Tests all cases of AddressRandomization=network

1. Deterministic generation per-network (default)
2. Full randomization per-network
3. Address override per-network
---
 .../connection_test.py                        | 86 +++++++++++++++++++
 .../testAddressRandomization/full_random.psk  |  6 ++
 autotests/testAddressRandomization/hw.conf    |  7 ++
 autotests/testAddressRandomization/main.conf  |  2 +
 .../testAddressRandomization/override.psk     |  6 ++
 .../testAddressRandomization/pernetwork.psk   |  5 ++
 .../testAddressRandomization/ssidCCMP.conf    |  7 ++
 7 files changed, 119 insertions(+)
 create mode 100644 autotests/testAddressRandomization/connection_test.py
 create mode 100644 autotests/testAddressRandomization/full_random.psk
 create mode 100644 autotests/testAddressRandomization/hw.conf
 create mode 100644 autotests/testAddressRandomization/main.conf
 create mode 100644 autotests/testAddressRandomization/override.psk
 create mode 100644 autotests/testAddressRandomization/pernetwork.psk
 create mode 100644 autotests/testAddressRandomization/ssidCCMP.conf

diff --git a/autotests/testAddressRandomization/connection_test.py b/autotests/testAddressRandomization/connection_test.py
new file mode 100644
index 00000000..fab8fea9
--- /dev/null
+++ b/autotests/testAddressRandomization/connection_test.py
@@ -0,0 +1,86 @@
+#!/usr/bin/python3
+
+import unittest
+import sys
+import os
+
+sys.path.append('../util')
+import iwd
+from iwd import IWD
+from iwd import NetworkType
+import testutil
+
+class Test(unittest.TestCase):
+    def try_connection(self, wd):
+        devices = wd.list_devices(1)
+        device = devices[0]
+
+        ordered_network = device.get_ordered_network('ssidCCMP')
+
+        self.assertEqual(ordered_network.type, NetworkType.psk)
+
+        condition = 'not obj.connected'
+        wd.wait_for_object_condition(ordered_network.network_object, condition)
+
+        ordered_network.network_object.connect()
+
+        condition = 'obj.connected'
+        wd.wait_for_object_condition(ordered_network.network_object, condition)
+
+        testutil.test_iface_operstate()
+        testutil.test_ifaces_connected()
+
+        device.disconnect()
+
+        condition = 'not obj.connected'
+        wd.wait_for_object_condition(ordered_network.network_object, condition)
+
+        return device.address
+
+    def test_connection_success(self):
+        wd = IWD(True)
+
+        devices = wd.list_devices(1)
+        device = devices[0]
+
+        perm_addr = device.address
+
+        condition = 'not obj.scanning'
+        wd.wait_for_object_condition(device, condition)
+
+        device.scan()
+
+        condition = 'not obj.scanning'
+        wd.wait_for_object_condition(device, condition)
+
+        # 1. Test per-network deterministic MAC generation
+        os.system('cat pernetwork.psk > /var/lib/iwd/ssidCCMP.psk')
+        new_addr = self.try_connection(wd)
+        self.assertNotEqual(perm_addr, new_addr)
+        # try again to ensure the generation was deterministic
+        new_addr2 = self.try_connection(wd)
+        self.assertEqual(new_addr, new_addr2)
+
+        # 2. Test FullAddressRandomization
+        os.system('cat full_random.psk > /var/lib/iwd/ssidCCMP.psk')
+        new_addr = self.try_connection(wd)
+        self.assertNotEqual(perm_addr, new_addr)
+        # try again to make sure the generation was random
+        new_addr2 = self.try_connection(wd)
+        self.assertNotEqual(new_addr, new_addr2)
+
+        # 3. Test AddressOverride
+        os.system('cat override.psk > /var/lib/iwd/ssidCCMP.psk')
+        new_addr = self.try_connection(wd)
+        self.assertEqual(new_addr, 'e6:f6:38:a9:02:02')
+
+    @classmethod
+    def setUpClass(cls):
+        pass
+
+    @classmethod
+    def tearDownClass(cls):
+        IWD.clear_storage()
+
+if __name__ == '__main__':
+    unittest.main(exit=True)
diff --git a/autotests/testAddressRandomization/full_random.psk b/autotests/testAddressRandomization/full_random.psk
new file mode 100644
index 00000000..57934287
--- /dev/null
+++ b/autotests/testAddressRandomization/full_random.psk
@@ -0,0 +1,6 @@
+[Security]
+Passphrase=secret123
+
+[Settings]
+AlwaysRandomizeAddress=true
+AutoConnect=false
diff --git a/autotests/testAddressRandomization/hw.conf b/autotests/testAddressRandomization/hw.conf
new file mode 100644
index 00000000..fa46c8b8
--- /dev/null
+++ b/autotests/testAddressRandomization/hw.conf
@@ -0,0 +1,7 @@
+[SETUP]
+num_radios=2
+start_iwd=0
+tmpfs_extra_stuff=main.conf
+
+[HOSTAPD]
+rad0=ssidCCMP.conf
diff --git a/autotests/testAddressRandomization/main.conf b/autotests/testAddressRandomization/main.conf
new file mode 100644
index 00000000..1b66d338
--- /dev/null
+++ b/autotests/testAddressRandomization/main.conf
@@ -0,0 +1,2 @@
+[General]
+AddressRandomization=network
diff --git a/autotests/testAddressRandomization/override.psk b/autotests/testAddressRandomization/override.psk
new file mode 100644
index 00000000..ecce3616
--- /dev/null
+++ b/autotests/testAddressRandomization/override.psk
@@ -0,0 +1,6 @@
+[Security]
+Passphrase=secret123
+
+[Settings]
+AddressOverride=e6:f6:38:a9:02:02
+AutoConnect=false
diff --git a/autotests/testAddressRandomization/pernetwork.psk b/autotests/testAddressRandomization/pernetwork.psk
new file mode 100644
index 00000000..1150ba8c
--- /dev/null
+++ b/autotests/testAddressRandomization/pernetwork.psk
@@ -0,0 +1,5 @@
+[Security]
+Passphrase=secret123
+
+[Settings]
+AutoConnect=false
diff --git a/autotests/testAddressRandomization/ssidCCMP.conf b/autotests/testAddressRandomization/ssidCCMP.conf
new file mode 100644
index 00000000..074e8228
--- /dev/null
+++ b/autotests/testAddressRandomization/ssidCCMP.conf
@@ -0,0 +1,7 @@
+hw_mode=g
+channel=1
+ssid=ssidCCMP
+
+wpa=2
+wpa_pairwise=CCMP
+wpa_passphrase=secret123
-- 
2.21.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v3 1/5] util: add util_is_valid_sta_address
  2020-03-19 22:58 [PATCH v3 1/5] util: add util_is_valid_sta_address James Prestwood
                   ` (3 preceding siblings ...)
  2020-03-19 22:59 ` [PATCH v3 5/5] auto-t: add test for AddressRandomization option James Prestwood
@ 2020-03-19 23:02 ` Denis Kenzior
  4 siblings, 0 replies; 6+ messages in thread
From: Denis Kenzior @ 2020-03-19 23:02 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 256 bytes --]

Hi James,

On 3/19/20 5:58 PM, James Prestwood wrote:
> Checks that that address is neither broadcast or group
> ---
>   src/util.c | 5 +++++
>   src/util.h | 1 +
>   2 files changed, 6 insertions(+)
> 

All applied, thanks.

Regards,
-Denis

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-03-19 23:02 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-19 22:58 [PATCH v3 1/5] util: add util_is_valid_sta_address James Prestwood
2020-03-19 22:58 ` [PATCH v3 2/5] station: support full MAC randomization and override James Prestwood
2020-03-19 22:59 ` [PATCH v3 3/5] netdev: honor handshake->spa if set James Prestwood
2020-03-19 22:59 ` [PATCH v3 4/5] doc: document AlwaysRandomizeAddress and AddressOverride James Prestwood
2020-03-19 22:59 ` [PATCH v3 5/5] auto-t: add test for AddressRandomization option James Prestwood
2020-03-19 23:02 ` [PATCH v3 1/5] util: add util_is_valid_sta_address Denis Kenzior

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.