* [PATCH 1/4] netdev: move address generation into station
@ 2020-03-19 20:03 James Prestwood
2020-03-19 20:03 ` [PATCH 2/4] station: support full MAC randomization and override James Prestwood
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: James Prestwood @ 2020-03-19 20:03 UTC (permalink / raw)
To: iwd
[-- Attachment #1: Type: text/plain, Size: 6269 bytes --]
This patch moves all the new address randomization/generation code into
station in order to support per-network address override. This was moved
into station because the address override setting will be set inside a
network config file, which netdev does not have any access to.
The way this is being achieved is to have the handshake set the desired
station address. Then, inside netdev, if the handshake spa address does
not match netdev's address we do a MAC change. Because of this wsc now
has to set the spa address before calling netdev_connect.
---
src/netdev.c | 37 +++++++++++++++----------------------
src/station.c | 14 ++++++++++++++
src/wsc.c | 3 +++
3 files changed, 32 insertions(+), 22 deletions(-)
diff --git a/src/netdev.c b/src/netdev.c
index e1c775be..8f53463b 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -166,7 +166,6 @@ static struct l_genl_family *nl80211;
static struct l_queue *netdev_list;
static struct watchlist netdev_watches;
static bool pae_over_nl80211;
-static bool mac_per_ssid;
static void do_debug(const char *str, void *user_data)
{
@@ -2417,8 +2416,6 @@ static int netdev_begin_connection(struct netdev *netdev,
}
}
- handshake_state_set_supplicant_address(netdev->handshake, netdev->addr);
-
/* set connected since the auth protocols cannot do so internally */
if (netdev->ap && auth_proto_start(netdev->ap))
netdev->connected = true;
@@ -2485,8 +2482,8 @@ static void netdev_mac_power_up_cb(int error, uint16_t type,
netdev->mac_change_cmd_id = 0;
if (error) {
- l_error("Error taking interface %u up for per-network MAC "
- "generation: %s", netdev->index, strerror(-error));
+ l_error("Error taking interface %u up for setting per-network "
+ "MAC address: %s", netdev->index, strerror(-error));
netdev_mac_change_failed(netdev, req, error);
return;
}
@@ -2511,13 +2508,13 @@ static void netdev_mac_power_down_cb(int error, uint16_t type,
netdev->mac_change_cmd_id = 0;
if (error) {
- l_error("Error taking interface %u down for per-network MAC "
- "generation: %s", netdev->index, strerror(-error));
+ l_error("Error taking interface %u down for setting per-network"
+ " MAC address: %s", netdev->index, strerror(-error));
netdev_mac_change_failed(netdev, req, error);
return;
}
- l_debug("Setting generated address on ifindex: %d to: "MAC,
+ l_debug("Setting address on ifindex: %d to: "MAC,
netdev->index, MAC_STR(req->addr));
netdev->mac_change_cmd_id = l_rtnl_set_mac(rtnl, netdev->index,
req->addr, true,
@@ -2555,18 +2552,15 @@ static void netdev_mac_power_down_cb(int error, uint16_t type,
*/
static int netdev_start_powered_mac_change(struct netdev *netdev,
struct scan_bss *bss,
- struct l_genl_msg *cmd_connect)
+ struct l_genl_msg *cmd_connect,
+ const uint8_t *new_addr)
{
struct rtnl_data *req;
- uint8_t new_addr[6];
-
- wiphy_generate_address_from_ssid(netdev->wiphy, (const char *)bss->ssid,
- new_addr);
/*
* MAC has already been changed previously, no need to again
*/
- if (!memcmp(new_addr, netdev->addr, sizeof(new_addr)))
+ if (!memcmp(new_addr, netdev->addr, sizeof(netdev->addr)))
return -EALREADY;
req = l_new(struct rtnl_data, 1);
@@ -2614,9 +2608,14 @@ static int netdev_connect_common(struct netdev *netdev,
NL80211_EXT_FEATURE_CAN_REPLACE_PTK0))
handshake_state_set_no_rekey(hs, true);
- if (mac_per_ssid) {
+ /*
+ * If the handshake address does not match netdevs, the MAC needs to be
+ * changed
+ */
+ if (memcmp(netdev->addr, hs->spa, ETH_ALEN) != 0) {
int ret = netdev_start_powered_mac_change(netdev, bss,
- cmd_connect);
+ cmd_connect,
+ hs->spa);
if (ret != -EALREADY)
return ret;
}
@@ -4664,7 +4663,6 @@ static int netdev_init(void)
{
struct l_genl *genl = iwd_get_genl();
const struct l_settings *settings = iwd_get_config();
- const char *rand_addr_str;
if (rtnl)
return -EALREADY;
@@ -4700,11 +4698,6 @@ static int netdev_init(void)
&pae_over_nl80211))
pae_over_nl80211 = true;
- rand_addr_str = l_settings_get_value(settings, "General",
- "AddressRandomization");
- if (rand_addr_str && !strcmp(rand_addr_str, "network"))
- mac_per_ssid = true;
-
watchlist_init(&netdev_watches, NULL);
netdev_list = l_queue_new();
diff --git a/src/station.c b/src/station.c
index 36b41f64..1b9a204c 100644
--- a/src/station.c
+++ b/src/station.c
@@ -871,10 +871,12 @@ static struct handshake_state *station_handshake_setup(struct station *station,
{
enum security security = network_get_security(network);
struct l_settings *settings = network_get_settings(network);
+ const struct l_settings *iwd_settings = iwd_get_config();
struct wiphy *wiphy = station->wiphy;
struct handshake_state *hs;
const char *ssid;
uint32_t eapol_proto_version;
+ const char *addr_setting;
hs = netdev_handshake_state_new(station->netdev);
@@ -934,6 +936,18 @@ 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));
+ addr_setting = l_settings_get_value(iwd_settings, "General",
+ "AddressRandomization");
+ if (addr_setting && !strcmp(addr_setting, "network")) {
+ uint8_t new_addr[6];
+
+ wiphy_generate_address_from_ssid(wiphy, (const char *)bss->ssid,
+ new_addr);
+ handshake_state_set_supplicant_address(hs, new_addr);
+ } else
+ handshake_state_set_supplicant_address(hs,
+ netdev_get_address(station->netdev));
+
return hs;
no_psk:
diff --git a/src/wsc.c b/src/wsc.c
index 393e8d8d..bdca241a 100644
--- a/src/wsc.c
+++ b/src/wsc.c
@@ -382,6 +382,9 @@ static int wsc_enrollee_connect(struct wsc_enrollee *wsce, struct scan_bss *bss,
if (ies_num)
memcpy(ie_iov + 1, ies, sizeof(struct iovec) * ies_num);
+ handshake_state_set_supplicant_address(hs,
+ netdev_get_address(wsce->netdev));
+
r = netdev_connect(wsce->netdev, bss, hs, ie_iov, 1 + ies_num,
wsc_enrollee_netdev_event,
wsc_enrollee_connect_cb, wsce);
--
2.21.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 2/4] station: support full MAC randomization and override
2020-03-19 20:03 [PATCH 1/4] netdev: move address generation into station James Prestwood
@ 2020-03-19 20:03 ` James Prestwood
2020-03-19 20:03 ` [PATCH 3/4] doc: document FullAddressRandomization and AddressOverride James Prestwood
2020-03-19 20:03 ` [PATCH 4/4] auto-t: add test for AddressRandomization option James Prestwood
2 siblings, 0 replies; 4+ messages in thread
From: James Prestwood @ 2020-03-19 20:03 UTC (permalink / raw)
To: iwd
[-- Attachment #1: Type: text/plain, Size: 2486 bytes --]
This patch adds two new options to a network provisioning file:
FullAddressRandomization={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 cannot 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 | 39 +++++++++++++++++++++++++++++++++++++--
1 file changed, 37 insertions(+), 2 deletions(-)
diff --git a/src/station.c b/src/station.c
index 1b9a204c..d16f126f 100644
--- a/src/station.c
+++ b/src/station.c
@@ -940,9 +940,44 @@ static struct handshake_state *station_handshake_setup(struct station *station,
"AddressRandomization");
if (addr_setting && !strcmp(addr_setting, "network")) {
uint8_t new_addr[6];
+ const char *value;
+ bool full_random;
+ bool override = false;
+
+ /*
+ * A value of 'network' could be one of three scenarios:
+ * 1. per-network MAC generation (default)
+ * 2. per-network full MAC randomization
+ * 3. per-network MAC override
+ */
+
+ if (!l_settings_get_bool(settings, "Settings",
+ "FullAddressRandomization",
+ &full_random))
+ full_random = false;
+
+ value = l_settings_get_value(settings, "Settings",
+ "AddressOverride");
+ if (value)
+ override = true;
+
+ if (override && full_random) {
+ l_error("Cannot use both FullAddressRandomization and "
+ "AddressOverride concurrently");
+ goto not_supported;
+ }
+
+ if (override) {
+ if (!util_string_to_address(value, new_addr)) {
+ l_error("[Network].AddressOverride is not a "
+ "valid MAC address");
+ goto not_supported;
+ }
+ } else if (full_random)
+ wiphy_generate_random_address(wiphy, new_addr);
+ else
+ wiphy_generate_address_from_ssid(wiphy, ssid, new_addr);
- wiphy_generate_address_from_ssid(wiphy, (const char *)bss->ssid,
- new_addr);
handshake_state_set_supplicant_address(hs, new_addr);
} else
handshake_state_set_supplicant_address(hs,
--
2.21.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 3/4] doc: document FullAddressRandomization and AddressOverride
2020-03-19 20:03 [PATCH 1/4] netdev: move address generation into station James Prestwood
2020-03-19 20:03 ` [PATCH 2/4] station: support full MAC randomization and override James Prestwood
@ 2020-03-19 20:03 ` James Prestwood
2020-03-19 20:03 ` [PATCH 4/4] auto-t: add test for AddressRandomization option James Prestwood
2 siblings, 0 replies; 4+ messages in thread
From: James Prestwood @ 2020-03-19 20:03 UTC (permalink / raw)
To: iwd
[-- Attachment #1: Type: text/plain, Size: 1148 bytes --]
---
src/iwd.network.rst | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/iwd.network.rst b/src/iwd.network.rst
index 6b068202..12efca72 100644
--- a/src/iwd.network.rst
+++ b/src/iwd.network.rst
@@ -109,6 +109,20 @@ The group ``[Settings]`` contains general settings.
Whether the network is hidden, i.e. its SSID must be included in an
active scan request
+ * - FullAddressRandomization
+ - 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 may not be used with
+ [Settings].AddressOverride.
+ * - 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 may not be used with
+ [Settings].FullAddressRandomization.
Network Authentication Settings
-------------------------------
--
2.21.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 4/4] auto-t: add test for AddressRandomization option
2020-03-19 20:03 [PATCH 1/4] netdev: move address generation into station James Prestwood
2020-03-19 20:03 ` [PATCH 2/4] station: support full MAC randomization and override James Prestwood
2020-03-19 20:03 ` [PATCH 3/4] doc: document FullAddressRandomization and AddressOverride James Prestwood
@ 2020-03-19 20:03 ` James Prestwood
2 siblings, 0 replies; 4+ messages in thread
From: James Prestwood @ 2020-03-19 20:03 UTC (permalink / raw)
To: iwd
[-- Attachment #1: Type: text/plain, Size: 6036 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..7f05b48a
--- /dev/null
+++ b/autotests/testAddressRandomization/full_random.psk
@@ -0,0 +1,6 @@
+[Security]
+Passphrase=secret123
+
+[Settings]
+FullAddressRandomization=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] 4+ messages in thread
end of thread, other threads:[~2020-03-19 20:03 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-03-19 20:03 [PATCH 1/4] netdev: move address generation into station James Prestwood
2020-03-19 20:03 ` [PATCH 2/4] station: support full MAC randomization and override James Prestwood
2020-03-19 20:03 ` [PATCH 3/4] doc: document FullAddressRandomization and AddressOverride James Prestwood
2020-03-19 20:03 ` [PATCH 4/4] auto-t: add test for AddressRandomization option James Prestwood
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox