WPS: Add MAC address to validation error message for Probe Request
[libeap.git] / src / ap / wps_hostapd.c
index 008a88a..f1ad1df 100644 (file)
@@ -499,6 +499,53 @@ static void hostapd_wps_clear_ies(struct hostapd_data *hapd)
 }
 
 
+static int get_uuid_cb(struct hostapd_iface *iface, void *ctx)
+{
+       const u8 **uuid = ctx;
+       size_t j;
+
+       if (iface == NULL)
+               return 0;
+       for (j = 0; j < iface->num_bss; j++) {
+               struct hostapd_data *hapd = iface->bss[j];
+               if (hapd->wps && !is_nil_uuid(hapd->wps->uuid)) {
+                       *uuid = hapd->wps->uuid;
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+
+static const u8 * get_own_uuid(struct hostapd_iface *iface)
+{
+       const u8 *uuid;
+       if (iface->for_each_interface == NULL)
+               return NULL;
+       uuid = NULL;
+       iface->for_each_interface(iface->interfaces, get_uuid_cb, &uuid);
+       return uuid;
+}
+
+
+static int count_interface_cb(struct hostapd_iface *iface, void *ctx)
+{
+       int *count= ctx;
+       (*count)++;
+       return 0;
+}
+
+
+static int interface_count(struct hostapd_iface *iface)
+{
+       int count = 0;
+       iface->for_each_interface(iface->interfaces, count_interface_cb,
+                                 &count);
+       return count;
+}
+
+
 int hostapd_init_wps(struct hostapd_data *hapd,
                     struct hostapd_bss_config *conf)
 {
@@ -522,11 +569,22 @@ int hostapd_init_wps(struct hostapd_data *hapd,
        wps->wps_state = hapd->conf->wps_state;
        wps->ap_setup_locked = hapd->conf->ap_setup_locked;
        if (is_nil_uuid(hapd->conf->uuid)) {
-               uuid_gen_mac_addr(hapd->own_addr, wps->uuid);
-               wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC address",
-                           wps->uuid, UUID_LEN);
-       } else
+               const u8 *uuid;
+               uuid = get_own_uuid(hapd->iface);
+               if (uuid) {
+                       os_memcpy(wps->uuid, uuid, UUID_LEN);
+                       wpa_hexdump(MSG_DEBUG, "WPS: Clone UUID from another "
+                                   "interface", wps->uuid, UUID_LEN);
+               } else {
+                       uuid_gen_mac_addr(hapd->own_addr, wps->uuid);
+                       wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC "
+                                   "address", wps->uuid, UUID_LEN);
+               }
+       } else {
                os_memcpy(wps->uuid, hapd->conf->uuid, UUID_LEN);
+               wpa_hexdump(MSG_DEBUG, "WPS: Use configured UUID",
+                           wps->uuid, UUID_LEN);
+       }
        wps->ssid_len = hapd->conf->ssid.ssid_len;
        os_memcpy(wps->ssid, hapd->conf->ssid.ssid, wps->ssid_len);
        wps->ap = 1;
@@ -647,10 +705,13 @@ int hostapd_init_wps(struct hostapd_data *hapd,
                conf->skip_cred_build;
        if (conf->ssid.security_policy == SECURITY_STATIC_WEP)
                cfg.static_wep_only = 1;
+       cfg.dualband = interface_count(hapd->iface) > 1;
+       if (cfg.dualband)
+               wpa_printf(MSG_DEBUG, "WPS: Dualband AP");
 
        wps->registrar = wps_registrar_init(wps, &cfg);
        if (wps->registrar == NULL) {
-               printf("Failed to initialize WPS Registrar\n");
+               wpa_printf(MSG_ERROR, "Failed to initialize WPS Registrar");
                os_free(wps->network_key);
                os_free(wps);
                return -1;
@@ -820,15 +881,28 @@ static int hostapd_wps_probe_req_rx(void *ctx, const u8 *addr,
        wps_ie = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA);
        if (wps_ie == NULL)
                return 0;
+       if (wps_validate_probe_req(wps_ie, addr) < 0) {
+               wpabuf_free(wps_ie);
+               return 0;
+       }
 
        if (wpabuf_len(wps_ie) > 0) {
-               wps_registrar_probe_req_rx(hapd->wps->registrar, addr, wps_ie);
+               int p2p_wildcard = 0;
+#ifdef CONFIG_P2P
+               if (elems.ssid && elems.ssid_len == P2P_WILDCARD_SSID_LEN &&
+                   os_memcmp(elems.ssid, P2P_WILDCARD_SSID,
+                             P2P_WILDCARD_SSID_LEN) == 0)
+                       p2p_wildcard = 1;
+#endif /* CONFIG_P2P */
+               wps_registrar_probe_req_rx(hapd->wps->registrar, addr, wps_ie,
+                                          p2p_wildcard);
 #ifdef CONFIG_WPS_UPNP
                /* FIX: what exactly should be included in the WLANEvent?
                 * WPS attributes? Full ProbeReq frame? */
-               upnp_wps_device_send_wlan_event(hapd->wps_upnp, addr,
-                                               UPNP_WPS_WLANEVENT_TYPE_PROBE,
-                                               wps_ie);
+               if (!p2p_wildcard)
+                       upnp_wps_device_send_wlan_event(
+                               hapd->wps_upnp, addr,
+                               UPNP_WPS_WLANEVENT_TYPE_PROBE, wps_ie);
 #endif /* CONFIG_WPS_UPNP */
        }
 
@@ -865,6 +939,7 @@ static int hostapd_rx_req_put_wlan_response(
         */
 
        sta = ap_get_sta(hapd, mac_addr);
+#ifndef CONFIG_WPS_STRICT
        if (!sta) {
                /*
                 * Workaround - Intel wsccmd uses bogus NewWLANEventMAC:
@@ -878,6 +953,7 @@ static int hostapd_rx_req_put_wlan_response(
                                break;
                }
        }
+#endif /* CONFIG_WPS_STRICT */
 
        if (!sta) {
                wpa_printf(MSG_DEBUG, "WPS UPnP: No matching STA found");