D-Bus: Add MAC address randomization endpoints

Add D-Bus property:
* MACAddressRandomizationMask: a{say}

which configure random MAC address functionality in the Wi-Fi
driver via netlink.

Signed-off-by: Eric Caruso <ejcaruso@chromium.org>
This commit is contained in:
Eric Caruso 2019-10-17 16:03:51 -07:00 committed by Jouni Malinen
parent bb66d46758
commit 10f8351d6e
6 changed files with 209 additions and 0 deletions

View file

@ -1043,6 +1043,12 @@ fi.w1.wpa_supplicant1.CreateInterface.
<h3>WpsPriority - s - (read/write)</h3>
<p>Priority for the networks added through WPS</p>
</li>
<li>
<h3>MACAddressRandomizationMask - a{say} - (read/write)</h3>
<p>Masks to show which bits not to randomize with MAC address randomization. Possible keys are "scan", "sched_scan", and "pno". Values must be an array of 6 bytes.</p>
<p>When this property is set, the new dictionary replaces the old value, rather than merging them together. Leaving a key out of the dictionary will turn off MAC address randomization for that scan type.</p>
</li>
</ul>
\subsection dbus_interface_signals Signals

View file

@ -3803,6 +3803,12 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
NULL,
NULL
},
{ "MACAddressRandomizationMask", WPAS_DBUS_NEW_IFACE_INTERFACE,
"a{say}",
wpas_dbus_getter_mac_address_randomization_mask,
wpas_dbus_setter_mac_address_randomization_mask,
NULL
},
{ NULL, NULL, NULL, NULL, NULL, NULL }
};

View file

@ -3985,6 +3985,173 @@ out:
}
/**
* wpas_dbus_setter_mac_address_randomization_mask - Set masks used for
* MAC address randomization
* @iter: Pointer to incoming dbus message iter
* @error: Location to store error on failure
* @user_data: Function specific data
* Returns: TRUE on success, FALSE on failure
*
* Setter for "MACAddressRandomizationMask" property.
*/
dbus_bool_t wpas_dbus_setter_mac_address_randomization_mask(
const struct wpa_dbus_property_desc *property_desc,
DBusMessageIter *iter, DBusError *error, void *user_data)
{
struct wpa_supplicant *wpa_s = user_data;
DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter;
const char *key;
unsigned int rand_type = 0;
const u8 *mask;
int mask_len;
unsigned int rand_types_to_disable = MAC_ADDR_RAND_ALL;
dbus_message_iter_recurse(iter, &variant_iter);
if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY) {
dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
"invalid message format");
return FALSE;
}
dbus_message_iter_recurse(&variant_iter, &dict_iter);
while (dbus_message_iter_get_arg_type(&dict_iter) ==
DBUS_TYPE_DICT_ENTRY) {
dbus_message_iter_recurse(&dict_iter, &entry_iter);
if (dbus_message_iter_get_arg_type(&entry_iter) !=
DBUS_TYPE_STRING) {
dbus_set_error(error, DBUS_ERROR_FAILED,
"%s: key not a string", __func__);
return FALSE;
}
dbus_message_iter_get_basic(&entry_iter, &key);
dbus_message_iter_next(&entry_iter);
if (dbus_message_iter_get_arg_type(&entry_iter) !=
DBUS_TYPE_ARRAY ||
dbus_message_iter_get_element_type(&entry_iter) !=
DBUS_TYPE_BYTE) {
dbus_set_error(error, DBUS_ERROR_FAILED,
"%s: mask was not a byte array",
__func__);
return FALSE;
}
dbus_message_iter_recurse(&entry_iter, &array_iter);
dbus_message_iter_get_fixed_array(&array_iter, &mask,
&mask_len);
if (os_strcmp(key, "scan") == 0) {
rand_type = MAC_ADDR_RAND_SCAN;
} else if (os_strcmp(key, "sched_scan") == 0) {
rand_type = MAC_ADDR_RAND_SCHED_SCAN;
} else if (os_strcmp(key, "pno") == 0) {
rand_type = MAC_ADDR_RAND_PNO;
} else {
dbus_set_error(error, DBUS_ERROR_FAILED,
"%s: bad scan type \"%s\"",
__func__, key);
return FALSE;
}
if (mask_len != ETH_ALEN) {
dbus_set_error(error, DBUS_ERROR_FAILED,
"%s: malformed MAC mask given",
__func__);
return FALSE;
}
if (wpas_enable_mac_addr_randomization(
wpa_s, rand_type, wpa_s->perm_addr, mask)) {
dbus_set_error(error, DBUS_ERROR_FAILED,
"%s: failed to set up MAC address randomization for %s",
__func__, key);
return FALSE;
}
wpa_printf(MSG_DEBUG,
"%s: Enabled MAC address randomization for %s with mask: "
MACSTR, wpa_s->ifname, key, MAC2STR(mask));
rand_types_to_disable &= ~rand_type;
dbus_message_iter_next(&dict_iter);
}
if (rand_types_to_disable &&
wpas_disable_mac_addr_randomization(wpa_s, rand_types_to_disable)) {
dbus_set_error(error, DBUS_ERROR_FAILED,
"%s: failed to disable MAC address randomization",
__func__);
return FALSE;
}
return TRUE;
}
dbus_bool_t wpas_dbus_getter_mac_address_randomization_mask(
const struct wpa_dbus_property_desc *property_desc,
DBusMessageIter *iter, DBusError *error, void *user_data)
{
struct wpa_supplicant *wpa_s = user_data;
DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter;
unsigned int i;
u8 mask_buf[ETH_ALEN];
/* Read docs on dbus_message_iter_append_fixed_array() for why this
* is necessary... */
u8 *mask = mask_buf;
static const struct {
const char *key;
unsigned int type;
} types[] = {
{ "scan", MAC_ADDR_RAND_SCAN },
{ "sched_scan", MAC_ADDR_RAND_SCHED_SCAN },
{ "pno", MAC_ADDR_RAND_PNO }
};
if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
"a{say}", &variant_iter) ||
!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
"{say}", &dict_iter)) {
dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
return FALSE;
}
for (i = 0; i < ARRAY_SIZE(types); i++) {
if (wpas_mac_addr_rand_scan_get_mask(wpa_s, types[i].type,
mask))
continue;
if (!dbus_message_iter_open_container(&dict_iter,
DBUS_TYPE_DICT_ENTRY,
NULL, &entry_iter) ||
!dbus_message_iter_append_basic(&entry_iter,
DBUS_TYPE_STRING,
&types[i].key) ||
!dbus_message_iter_open_container(&entry_iter,
DBUS_TYPE_ARRAY,
DBUS_TYPE_BYTE_AS_STRING,
&array_iter) ||
!dbus_message_iter_append_fixed_array(&array_iter,
DBUS_TYPE_BYTE,
&mask,
ETH_ALEN) ||
!dbus_message_iter_close_container(&entry_iter,
&array_iter) ||
!dbus_message_iter_close_container(&dict_iter,
&entry_iter)) {
dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
"no memory");
return FALSE;
}
}
if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) ||
!dbus_message_iter_close_container(iter, &variant_iter)) {
dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
return FALSE;
}
return TRUE;
}
/**
* wpas_dbus_getter_sta_address - Return the address of a connected station
* @iter: Pointer to incoming dbus message iter

View file

@ -177,6 +177,8 @@ DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_engine_path);
DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_module_path);
DECLARE_ACCESSOR(wpas_dbus_getter_blobs);
DECLARE_ACCESSOR(wpas_dbus_getter_stas);
DECLARE_ACCESSOR(wpas_dbus_getter_mac_address_randomization_mask);
DECLARE_ACCESSOR(wpas_dbus_setter_mac_address_randomization_mask);
DECLARE_ACCESSOR(wpas_dbus_getter_sta_address);
DECLARE_ACCESSOR(wpas_dbus_getter_sta_aid);
DECLARE_ACCESSOR(wpas_dbus_getter_sta_caps);

View file

@ -2844,6 +2844,32 @@ int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s,
}
int wpas_mac_addr_rand_scan_get_mask(struct wpa_supplicant *wpa_s,
unsigned int type, u8 *mask)
{
const u8 *to_copy;
if ((wpa_s->mac_addr_rand_enable & type) != type)
return -1;
if (type == MAC_ADDR_RAND_SCAN) {
to_copy = wpa_s->mac_addr_scan;
} else if (type == MAC_ADDR_RAND_SCHED_SCAN) {
to_copy = wpa_s->mac_addr_sched_scan;
} else if (type == MAC_ADDR_RAND_PNO) {
to_copy = wpa_s->mac_addr_pno;
} else {
wpa_printf(MSG_DEBUG,
"scan: Invalid MAC randomization type=0x%x",
type);
return -1;
}
os_memcpy(mask, to_copy + ETH_ALEN, ETH_ALEN);
return 0;
}
int wpas_abort_ongoing_scan(struct wpa_supplicant *wpa_s)
{
struct wpa_radio_work *work;

View file

@ -52,6 +52,8 @@ void wpas_mac_addr_rand_scan_clear(struct wpa_supplicant *wpa_s,
int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s,
unsigned int type, const u8 *addr,
const u8 *mask);
int wpas_mac_addr_rand_scan_get_mask(struct wpa_supplicant *wpa_s,
unsigned int type, u8 *mask);
int wpas_abort_ongoing_scan(struct wpa_supplicant *wpa_s);
void filter_scan_res(struct wpa_supplicant *wpa_s,
struct wpa_scan_results *res);