[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