]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Fix config exchange with gas_rand_mac_addr
authorJouni Malinen <jouni@codeaurora.org>
Wed, 22 Apr 2020 14:04:43 +0000 (17:04 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 22 Apr 2020 14:09:01 +0000 (17:09 +0300)
Do not use a random MAC address for the GAS exchange that is used as
part of the DPP protocol exchange since that would break DPP.
Configurator expects the same MAC address to be used for DPP
Authentication exchange and DPP Configuration exchange (GAS).

Since the DPP Authentication exchange has already used the MAC address
configured on the interface, use of a random address for the GAS
exchange would not provide any additional privacy protection. If a
random MAC address needs to be used for this type of an exchange, that
random address would need to be first configured on the interface before
starting DPP exchange.

This does not change GAS query behavior for any other use case, i.e.,
the gas_rand_mac_addr configuration continues to apply to all the
Interworking/Hotspot 2.0 uses.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
wpa_supplicant/dpp_supplicant.c
wpa_supplicant/gas_query.c
wpa_supplicant/gas_query.h
wpa_supplicant/hs20_supplicant.c
wpa_supplicant/interworking.c
wpa_supplicant/wpa_supplicant.conf

index 351f8da9d0c32efdc76fb53c6d005a6e9baa8e3f..291b96b7510c8af1faab2730c4ae4d7614aefc5c 100644 (file)
@@ -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);
index 8e977a3eccb36b6e856f13c5fbd2d67ec480d694..759b9b9cd4015b61b6e810d9270720c11459eddd 100644 (file)
@@ -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;
index d2b455442f0a5f6e63df7fd16c23e0df8f947849..f9ce7b680fda6f5fe9dafb9f35120cb23063ec5e 100644 (file)
@@ -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,
index 47a1d0175de599fc868c82bceef9c3db676da090..3bf777e6aa13546ec2e39e3fc87bde260fbb5507 100644 (file)
@@ -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);
index 49b9907b079cf1f33ce76af7edb1bd86e0a78af9..c48525cec5c2fb591922d7b882ed8dfe746c8b88 100644 (file)
@@ -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);
index f242c3a9e0406b9fe8778f0fc0a8d36baad70cfc..3b9056770f314baee49075a4ab6dabb4752c68a9 100644 (file)
@@ -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)