]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
D-Bus: Add MAC address randomization endpoints
authorEric Caruso <ejcaruso@chromium.org>
Thu, 17 Oct 2019 23:03:51 +0000 (16:03 -0700)
committerJouni Malinen <j@w1.fi>
Sun, 27 Oct 2019 17:50:22 +0000 (19:50 +0200)
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>
doc/dbus.doxygen
wpa_supplicant/dbus/dbus_new.c
wpa_supplicant/dbus/dbus_new_handlers.c
wpa_supplicant/dbus/dbus_new_handlers.h
wpa_supplicant/scan.c
wpa_supplicant/scan.h

index 072ed3486954b6a83f17710189b96d91d239c1d3..9bca70cb79c999cf44092f6ab0128415a6f4dff4 100644 (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
index 4d744ec324482e05f113da51752ea2b3bf705983..5e6b5220ece1cb2b0c75395345806972505bd1c0 100644 (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 }
 };
 
index 1206c3cdeef6d386f8615e25cc3c4a4caf2349b6..258209259e71cab2e893046c79965d32f9f03dea 100644 (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
index d922ce1b4189169086eb178e48ce5d7e3f0c56c8..afa26efed675bd1bb995ffb7b9bbe32bdc7af57a 100644 (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);
index 3edae43e82e882f12593c0713a5ccb1201bd8a98..fe0d154f2ba753e53fb2922dddffe8a6c6650413 100644 (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;
index 2aa0a8be0e4d705f68f732e5c457c3ef4ffbfe22..58caa7818dced877eeaabb38eacec14e4bf84ef0 100644 (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);