diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index 351f8da9d..291b96b75 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -1428,7 +1428,7 @@ static void wpas_dpp_start_gas_client(struct wpa_supplicant *wpa_s) MAC2STR(auth->peer_mac_addr), auth->curr_freq); res = gas_query_req(wpa_s->gas, auth->peer_mac_addr, auth->curr_freq, - 1, buf, wpas_dpp_gas_resp_cb, wpa_s); + 1, 1, buf, wpas_dpp_gas_resp_cb, wpa_s); if (res < 0) { wpa_msg(wpa_s, MSG_DEBUG, "GAS: Failed to send Query Request"); wpabuf_free(buf); diff --git a/wpa_supplicant/gas_query.c b/wpa_supplicant/gas_query.c index 8e977a3ec..759b9b9cd 100644 --- a/wpa_supplicant/gas_query.c +++ b/wpa_supplicant/gas_query.c @@ -43,6 +43,7 @@ struct gas_query_pending { unsigned int offchannel_tx_started:1; unsigned int retry:1; unsigned int wildcard_bssid:1; + unsigned int maintain_addr:1; int freq; u16 status_code; struct wpabuf *req; @@ -693,7 +694,8 @@ static void gas_query_start_cb(struct wpa_radio_work *work, int deinit) return; } - if (wpas_update_random_addr_disassoc(wpa_s) < 0) { + if (!query->maintain_addr && + wpas_update_random_addr_disassoc(wpa_s) < 0) { wpa_msg(wpa_s, MSG_INFO, "Failed to assign random MAC address for GAS"); gas_query_free(query, 1); @@ -749,12 +751,23 @@ static int gas_query_set_sa(struct gas_query *gas, struct wpa_supplicant *wpa_s = gas->wpa_s; struct os_reltime now; - if (!wpa_s->conf->gas_rand_mac_addr || + if (query->maintain_addr || + !wpa_s->conf->gas_rand_mac_addr || !(wpa_s->current_bss ? (wpa_s->drv_flags & WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED) : (wpa_s->drv_flags & WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA))) { /* Use own MAC address as the transmitter address */ + wpa_printf(MSG_DEBUG, + "GAS: Use own MAC address as the transmitter address%s%s%s", + query->maintain_addr ? " (maintain_addr)" : "", + !wpa_s->conf->gas_rand_mac_addr ? " (no gas_rand_mac_adr set)" : "", + !(wpa_s->current_bss ? + (wpa_s->drv_flags & + WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED) : + (wpa_s->drv_flags & + WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA)) ? + " (no driver rand capa" : ""); os_memcpy(query->sa, wpa_s->own_addr, ETH_ALEN); return 0; } @@ -800,6 +813,9 @@ static int gas_query_set_sa(struct gas_query *gas, * @gas: GAS query data from gas_query_init() * @dst: Destination MAC address for the query * @freq: Frequency (in MHz) for the channel on which to send the query + * @wildcard_bssid: Force use of wildcard BSSID value + * @maintain_addr: Maintain own MAC address for exchange (i.e., ignore MAC + * address randomization rules) * @req: GAS query payload (to be freed by gas_query module in case of success * return) * @cb: Callback function for reporting GAS query result and response @@ -807,7 +823,7 @@ static int gas_query_set_sa(struct gas_query *gas, * Returns: dialog token (>= 0) on success or -1 on failure */ int gas_query_req(struct gas_query *gas, const u8 *dst, int freq, - int wildcard_bssid, struct wpabuf *req, + int wildcard_bssid, int maintain_addr, struct wpabuf *req, void (*cb)(void *ctx, const u8 *dst, u8 dialog_token, enum gas_query_result result, const struct wpabuf *adv_proto, @@ -829,6 +845,7 @@ int gas_query_req(struct gas_query *gas, const u8 *dst, int freq, return -1; query->gas = gas; + query->maintain_addr = !!maintain_addr; if (gas_query_set_sa(gas, query)) { os_free(query); return -1; diff --git a/wpa_supplicant/gas_query.h b/wpa_supplicant/gas_query.h index d2b455442..f9ce7b680 100644 --- a/wpa_supplicant/gas_query.h +++ b/wpa_supplicant/gas_query.h @@ -35,7 +35,7 @@ enum gas_query_result { }; int gas_query_req(struct gas_query *gas, const u8 *dst, int freq, - int wildcard_bssid, struct wpabuf *req, + int wildcard_bssid, int maintain_addr, struct wpabuf *req, void (*cb)(void *ctx, const u8 *dst, u8 dialog_token, enum gas_query_result result, const struct wpabuf *adv_proto, diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c index 47a1d0175..3bf777e6a 100644 --- a/wpa_supplicant/hs20_supplicant.c +++ b/wpa_supplicant/hs20_supplicant.c @@ -288,7 +288,8 @@ int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes, if (buf == NULL) return -1; - res = gas_query_req(wpa_s->gas, dst, freq, 0, buf, anqp_resp_cb, wpa_s); + res = gas_query_req(wpa_s->gas, dst, freq, 0, 0, buf, anqp_resp_cb, + wpa_s); if (res < 0) { wpa_printf(MSG_DEBUG, "ANQP: Failed to send Query Request"); wpabuf_free(buf); diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index 49b9907b0..c48525cec 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -316,7 +316,7 @@ static int interworking_anqp_send_req(struct wpa_supplicant *wpa_s, if (buf == NULL) return -1; - res = gas_query_req(wpa_s->gas, bss->bssid, bss->freq, 0, buf, + res = gas_query_req(wpa_s->gas, bss->bssid, bss->freq, 0, 0, buf, interworking_anqp_resp_cb, wpa_s); if (res < 0) { wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Failed to send Query Request"); @@ -2804,7 +2804,8 @@ int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, if (buf == NULL) return -1; - res = gas_query_req(wpa_s->gas, dst, freq, 0, buf, anqp_resp_cb, wpa_s); + res = gas_query_req(wpa_s->gas, dst, freq, 0, 0, buf, anqp_resp_cb, + wpa_s); if (res < 0) { wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Failed to send Query Request"); wpabuf_free(buf); @@ -3243,7 +3244,8 @@ int gas_send_request(struct wpa_supplicant *wpa_s, const u8 *dst, } else wpabuf_put_le16(buf, 0); - res = gas_query_req(wpa_s->gas, dst, freq, 0, buf, gas_resp_cb, wpa_s); + res = gas_query_req(wpa_s->gas, dst, freq, 0, 0, buf, gas_resp_cb, + wpa_s); if (res < 0) { wpa_msg(wpa_s, MSG_DEBUG, "GAS: Failed to send Query Request"); wpabuf_free(buf); diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index f242c3a9e..3b9056770 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -481,6 +481,11 @@ fast_reauth=1 # 0 = use permanent MAC address # 1 = use random MAC address # 2 = like 1, but maintain OUI (with local admin bit set) +# Note that this setting is ignored when a specific MAC address is needed for +# a full protocol exchange that includes GAS, e.g., when going through a DPP +# exchange that exposes the configured interface address as part of the DP +# Public Action frame exchanges before using GAS. That same address is then used +# during the GAS exchange as well to avoid breaking the protocol expectations. #gas_rand_mac_addr=0 # Lifetime of GAS random MAC address in seconds (default: 60)