[PATCH] wpa_supplicant: Add support for pregenerated MAC
worker at cksn.tk
worker at cksn.tk
Wed Nov 10 22:57:44 PST 2021
does this fix the problem that the user privacy setting will change the
device-MAC address all the time? or what does it do in detail? i will
reference this post here, so we also trying to fix some MAC/SSID/PSK
issues:
https://community.ui.com/questions/Does-Ubiquiti-have-any-plan-to-implement-WPA2-PPSK/1e42db2c-5fbf-42d7-a37e-793cdcc20b80
volker.
On 10.11.21 20:16, Andrzej Ostruszka wrote:
> Add new 'mac_addr' policy (3) with which supplicant expects to also
> obtain 'mac_value' with pregenerated value of MAC address to be used for
> given SSID.
>
> The main difference between this policy and policy 1 is the ability to
> control persistence of the MAC address used. For example if there is
> a requirement to always use the same (but random) MAC address for given
> SSID (even if user removes/forgets the network) this could be handled
> outside of the wpa_supplicant by using some SSID based hashing scheme to
> generate MAC (or by just storing the randomly generated one) and
> providing it to wpa_supplicant together with mac_addr=3 policy.
>
> Signed-off-by: Andrzej Ostruszka <amo at semihalf.com>
> Change-Id: I4046cf1cd08c84350a44703fe1fa0ecab4c82870
> ---
> wpa_supplicant/config.c | 46 ++++++++++++++++++++++++-
> wpa_supplicant/config_ssid.h | 9 +++++
> wpa_supplicant/dbus/dbus_new_handlers.c | 22 +++++++++++-
> wpa_supplicant/wpa_supplicant.c | 16 +++++++--
> wpa_supplicant/wpa_supplicant_i.h | 3 +-
> 5 files changed, 90 insertions(+), 6 deletions(-)
>
> diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
> index bf97de698..1d17a3a32 100644
> --- a/wpa_supplicant/config.c
> +++ b/wpa_supplicant/config.c
> @@ -2321,6 +2321,49 @@ static char * wpa_config_write_peerkey(const struct parse_data *data,
> #endif /* NO_CONFIG_WRITE */
>
>
> +static int wpa_config_parse_mac_value(const struct parse_data *data,
> + struct wpa_ssid *ssid, int line,
> + const char *value)
> +{
> + u8 mac_value[ETH_ALEN];
> +
> + if (hwaddr_aton(value, mac_value) == 0) {
> + if (os_memcmp(mac_value, ssid->mac_value, ETH_ALEN) == 0)
> + return 1;
> + os_memcpy(ssid->mac_value, mac_value, ETH_ALEN);
> + return 0;
> + }
> +
> + wpa_printf(MSG_ERROR, "Line %d: Invalid MAC address '%s'",
> + line, value);
> + return -1;
> +}
> +
> +#ifndef NO_CONFIG_WRITE
> +static char * wpa_config_write_mac_value(const struct parse_data *data,
> + struct wpa_ssid *ssid)
> +{
> + const size_t size = 3 * ETH_ALEN;
> + char *value;
> + int res;
> +
> + if (ssid->mac_addr != 3)
> + return NULL;
> +
> + value = os_malloc(size);
> + if (value == NULL)
> + return NULL;
> + res = os_snprintf(value, size, MACSTR, MAC2STR(ssid->mac_value));
> + if (os_snprintf_error(size, res)) {
> + os_free(value);
> + return NULL;
> + }
> + value[size-1] = '\0';
> + return value;
> +}
> +#endif /* NO_CONFIG_WRITE */
> +
> +
> /* Helper macros for network block parser */
>
> #ifdef OFFSET
> @@ -2618,7 +2661,8 @@ static const struct parse_data ssid_fields[] = {
> { INT(update_identifier) },
> { STR_RANGE(roaming_consortium_selection, 0, MAX_ROAMING_CONS_OI_LEN) },
> #endif /* CONFIG_HS20 */
> - { INT_RANGE(mac_addr, 0, 2) },
> + { INT_RANGE(mac_addr, 0, 3) },
> + { FUNC_KEY(mac_value) },
> { INT_RANGE(pbss, 0, 2) },
> { INT_RANGE(wps_disabled, 0, 1) },
> { INT_RANGE(fils_dh_group, 0, 65535) },
> diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
> index 339eead1c..61a5139ec 100644
> --- a/wpa_supplicant/config_ssid.h
> +++ b/wpa_supplicant/config_ssid.h
> @@ -954,6 +954,7 @@ struct wpa_ssid {
> * 0 = use permanent MAC address
> * 1 = use random MAC address for each ESS connection
> * 2 = like 1, but maintain OUI (with local admin bit set)
> + * 3 = use dedicated/pregenerated MAC address
> *
> * Internally, special value -1 is used to indicate that the parameter
> * was not specified in the configuration (i.e., default behavior is
> @@ -961,6 +962,14 @@ struct wpa_ssid {
> */
> int mac_addr;
>
> + /**
> + * mac_value - specific MAC address to be used
> + *
> + * When mac_addr policy is equal to 3 this is the value of the MAC
> + * address that should be used.
> + */
> + u8 mac_value[ETH_ALEN];
> +
> /**
> * no_auto_peer - Do not automatically peer with compatible mesh peers
> *
> diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
> index db9f30c9a..c4a7ceb44 100644
> --- a/wpa_supplicant/dbus/dbus_new_handlers.c
> +++ b/wpa_supplicant/dbus/dbus_new_handlers.c
> @@ -148,7 +148,7 @@ static const char * const dont_quote[] = {
> #ifdef CONFIG_P2P
> "go_p2p_dev_addr", "p2p_client_list", "psk_list",
> #endif /* CONFIG_P2P */
> - NULL
> + "mac_value", NULL
> };
>
> static dbus_bool_t should_quote_opt(const char *key)
> @@ -202,6 +202,8 @@ dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s,
> struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
> DBusMessageIter iter_dict;
> char *value = NULL;
> + bool mac_addr3_set = false;
> + bool mac_value_set = false;
>
> if (!wpa_dbus_dict_open_read(iter, &iter_dict, error))
> return FALSE;
> @@ -311,12 +313,30 @@ dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s,
> else if (os_strcmp(entry.key, "priority") == 0)
> wpa_config_update_prio_list(wpa_s->conf);
>
> + /*
> + * MAC address policy "3" needs to come with mac_value in
> + * the message so make sure that it is present (checked after
> + * the loop - here we just note what has been supplied).
> + */
> + if (os_strcmp(entry.key, "mac_addr") == 0 &&
> + atoi(value) == 3)
> + mac_addr3_set = true;
> + if (os_strcmp(entry.key, "mac_value") == 0)
> + mac_value_set = true;
> +
> skip_update:
> os_free(value);
> value = NULL;
> wpa_dbus_dict_entry_clear(&entry);
> }
>
> + if (mac_addr3_set && !mac_value_set) {
> + wpa_printf(MSG_ERROR, "Invalid mac_addr policy config");
> + dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
> + "Invalid mac_addr policy config");
> + return FALSE;
> + }
> +
> return TRUE;
>
> error:
> diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
> index b80f1d4f0..c6f32e75f 100644
> --- a/wpa_supplicant/wpa_supplicant.c
> +++ b/wpa_supplicant/wpa_supplicant.c
> @@ -2058,13 +2058,16 @@ void wpas_connect_work_done(struct wpa_supplicant *wpa_s)
> }
>
>
> -int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style)
> +int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style,
> + struct wpa_ssid *ssid)
> {
> struct os_reltime now;
> u8 addr[ETH_ALEN];
>
> os_get_reltime(&now);
> if (wpa_s->last_mac_addr_style == style &&
> + /* pregenerated addresses do not expire */
> + wpa_s->last_mac_addr_style != 3 &&
> wpa_s->last_mac_addr_change.sec != 0 &&
> !os_reltime_expired(&now, &wpa_s->last_mac_addr_change,
> wpa_s->conf->rand_addr_lifetime)) {
> @@ -2083,6 +2086,13 @@ int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style)
> if (random_mac_addr_keep_oui(addr) < 0)
> return -1;
> break;
> + case 3:
> + if (!ssid) {
> + wpa_msg(wpa_s, MSG_ERROR, "Invalid 'ssid' for address policy 3");
> + return -1;
> + }
> + os_memcpy(addr, ssid->mac_value, ETH_ALEN);
> + break;
> default:
> return -1;
> }
> @@ -2116,7 +2126,7 @@ int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s)
> !wpa_s->conf->preassoc_mac_addr)
> return 0;
>
> - return wpas_update_random_addr(wpa_s, wpa_s->conf->preassoc_mac_addr);
> + return wpas_update_random_addr(wpa_s, wpa_s->conf->preassoc_mac_addr, NULL);
> }
>
>
> @@ -2251,7 +2261,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
> #endif /* CONFIG_SAE */
>
> if (rand_style > 0 && !wpa_s->reassoc_same_ess) {
> - if (wpas_update_random_addr(wpa_s, rand_style) < 0)
> + if (wpas_update_random_addr(wpa_s, rand_style, ssid) < 0)
> return;
> wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
> } else if (rand_style == 0 && wpa_s->mac_addr_changed) {
> diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
> index cbc955159..ee8049a4c 100644
> --- a/wpa_supplicant/wpa_supplicant_i.h
> +++ b/wpa_supplicant/wpa_supplicant_i.h
> @@ -1631,7 +1631,8 @@ int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
> void wpas_request_connection(struct wpa_supplicant *wpa_s);
> void wpas_request_disconnection(struct wpa_supplicant *wpa_s);
> int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen);
> -int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style);
> +int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style,
> + struct wpa_ssid *ssid);
> int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s);
> void add_freq(int *freqs, int *num_freqs, int freq);
>
More information about the Hostap
mailing list