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:
parent
bb66d46758
commit
10f8351d6e
6 changed files with 209 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue