Cumulative patch from commit 31ded52e7084976c5f84caae6cb55e632dd8b013

31ded52 SME: Add more debug prints for OBSS scans and 20/40 MHz co-ex report
7f8eb34 SME: Fix OBSS scan result processing for 20/40 MHz co-ex report
b7a8d67 Allow hostapd to advertise 40 MHz intolerant HT capability
692ec30 FT: Add support for postponing FT response
6ace13a P2P: Clean up channel selection code to use helper functions
70c3523 WPS: Comment out unused AP WEP config write with WPS 2.0
c3ba70f P2P: Update op_reg_class in random social channel case
70634ee hostapd: Check driver DFS offload capability for channel disablement
65d645c nl80211: Fetch DFS offload capability from driver
a500f31 WPS: Comment out unused AP WEP config update with WPS 2.0
be4e5af Add SAE and FT-SAE key_mgmt to hostapd GET_CONFIG
1d4fe3b Remove unnecessary parameter validation
94b84bc P2P: Avoid unsafe pre-configured channel as channel preference
d3c9c35 Add freq= parameter to 'set pno' command
b998236 dbus: Implement P2P Peers info IEs buffer getter
c6f356f dbus: Export the peer's device address as a property
442adfd dbus: Declare properly ServiceDiscoveryRequest method
8903741 dbus: Cancelling a service request always reply by an error
13494c4 dbus: Remove duplicate signal declaration
513dcec Don't overwrite channel on hostapd config reload
5eae87a P2P: Fix GO failed interface init
c46235a wpa_supplicant: Fix radio_remove_interface
2ce7e4f Android: Enable CONFIG_EAP_AKA_PRIME option
95bf699 Add get_radio_name() driver wrapper for wpa_supplicant
d06ecab D-Bus: Make p2p_no_group_iface configurable
8b6b6d8 Fix hostapd.conf description of HT40+

Change-Id: I5e776f71050a106195a39e96d0c38930a387a806
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index 11351c4..e1020a6 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -469,9 +469,6 @@
 {
 	char *end;
 
-	if (!settings)
-		return -1;
-
 	os_memset(settings, 0, sizeof(*settings));
 	settings->cs_count = strtol(pos, &end, 10);
 	if (pos == end) {
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 4ed718c..2ecaec8 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -171,6 +171,16 @@
 	for (j = 0; j < iface->num_bss; j++) {
 		hapd = iface->bss[j];
 		hapd->iconf = newconf;
+		hapd->iconf->channel = oldconf->channel;
+		hapd->iconf->ieee80211n = oldconf->ieee80211n;
+		hapd->iconf->ieee80211ac = oldconf->ieee80211ac;
+		hapd->iconf->ht_capab = oldconf->ht_capab;
+		hapd->iconf->vht_capab = oldconf->vht_capab;
+		hapd->iconf->vht_oper_chwidth = oldconf->vht_oper_chwidth;
+		hapd->iconf->vht_oper_centr_freq_seg0_idx =
+			oldconf->vht_oper_centr_freq_seg0_idx;
+		hapd->iconf->vht_oper_centr_freq_seg1_idx =
+			oldconf->vht_oper_centr_freq_seg1_idx;
 		hapd->conf = newconf->bss[j];
 		hostapd_reload_bss(hapd);
 	}
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index d319ce0..54a79b0 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -111,10 +111,13 @@
 			if ((feature->channels[j].flag &
 			     HOSTAPD_CHAN_RADAR) && dfs_enabled) {
 				dfs = 1;
-			} else if (feature->channels[j].flag &
-				   (HOSTAPD_CHAN_NO_IBSS |
-				    HOSTAPD_CHAN_PASSIVE_SCAN |
-				    HOSTAPD_CHAN_RADAR)) {
+			} else if (((feature->channels[j].flag &
+				     HOSTAPD_CHAN_RADAR) &&
+				    !(iface->drv_flags &
+				      WPA_DRIVER_FLAGS_DFS_OFFLOAD)) ||
+				   (feature->channels[j].flag &
+				    (HOSTAPD_CHAN_NO_IBSS |
+				     HOSTAPD_CHAN_PASSIVE_SCAN))) {
 				feature->channels[j].flag |=
 					HOSTAPD_CHAN_DISABLED;
 			}
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 4d19bb0..77e7858 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -621,6 +621,7 @@
 	}
 #ifdef CONFIG_IEEE80211R
 	os_free(sm->assoc_resp_ftie);
+	wpabuf_free(sm->ft_pending_req_ies);
 #endif /* CONFIG_IEEE80211R */
 	os_free(sm->last_rx_eapol_key);
 	os_free(sm->wpa_ie);
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index 3ab3e3d..929a253 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -42,6 +42,7 @@
 #define FT_R0KH_R1KH_PULL_DATA_LEN 44
 #define FT_R0KH_R1KH_RESP_DATA_LEN 76
 #define FT_R0KH_R1KH_PUSH_DATA_LEN 88
+#define FT_R0KH_R1KH_PULL_NONCE_LEN 16
 
 struct ft_r0kh_r1kh_pull_frame {
 	u8 frame_type; /* RSN_REMOTE_FRAME_TYPE_FT_RRB */
@@ -49,7 +50,7 @@
 	le16 data_length; /* little endian length of data (44) */
 	u8 ap_address[ETH_ALEN];
 
-	u8 nonce[16];
+	u8 nonce[FT_R0KH_R1KH_PULL_NONCE_LEN];
 	u8 pmk_r0_name[WPA_PMK_NAME_LEN];
 	u8 r1kh_id[FT_R1KH_ID_LEN];
 	u8 s1kh_id[ETH_ALEN];
@@ -63,7 +64,7 @@
 	le16 data_length; /* little endian length of data (76) */
 	u8 ap_address[ETH_ALEN];
 
-	u8 nonce[16]; /* copied from pull */
+	u8 nonce[FT_R0KH_R1KH_PULL_NONCE_LEN]; /* copied from pull */
 	u8 r1kh_id[FT_R1KH_ID_LEN]; /* copied from pull */
 	u8 s1kh_id[ETH_ALEN]; /* copied from pull */
 	u8 pmk_r1[PMK_LEN];
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index c22c4cc..7701596 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -1,6 +1,6 @@
 /*
  * hostapd - IEEE 802.11r - Fast BSS Transition
- * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -9,6 +9,7 @@
 #include "utils/includes.h"
 
 #include "utils/common.h"
+#include "utils/eloop.h"
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
 #include "crypto/aes_wrap.h"
@@ -22,6 +23,12 @@
 
 #ifdef CONFIG_IEEE80211R
 
+static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine *sm,
+				     const u8 *current_ap, const u8 *sta_addr,
+				     u16 status, const u8 *resp_ies,
+				     size_t resp_ies_len);
+
+
 static int wpa_ft_rrb_send(struct wpa_authenticator *wpa_auth, const u8 *dst,
 			   const u8 *data, size_t data_len)
 {
@@ -293,22 +300,25 @@
 }
 
 
-static int wpa_ft_pull_pmk_r1(struct wpa_authenticator *wpa_auth,
-			      const u8 *s1kh_id, const u8 *r0kh_id,
-			      size_t r0kh_id_len, const u8 *pmk_r0_name)
+static int wpa_ft_pull_pmk_r1(struct wpa_state_machine *sm,
+			      const u8 *ies, size_t ies_len,
+			      const u8 *pmk_r0_name)
 {
 	struct ft_remote_r0kh *r0kh;
 	struct ft_r0kh_r1kh_pull_frame frame, f;
 
-	r0kh = wpa_auth->conf.r0kh_list;
+	r0kh = sm->wpa_auth->conf.r0kh_list;
 	while (r0kh) {
-		if (r0kh->id_len == r0kh_id_len &&
-		    os_memcmp(r0kh->id, r0kh_id, r0kh_id_len) == 0)
+		if (r0kh->id_len == sm->r0kh_id_len &&
+		    os_memcmp(r0kh->id, sm->r0kh_id, sm->r0kh_id_len) == 0)
 			break;
 		r0kh = r0kh->next;
 	}
-	if (r0kh == NULL)
+	if (r0kh == NULL) {
+		wpa_hexdump(MSG_DEBUG, "FT: Did not find R0KH-ID",
+			    sm->r0kh_id, sm->r0kh_id_len);
 		return -1;
+	}
 
 	wpa_printf(MSG_DEBUG, "FT: Send PMK-R1 pull request to remote R0KH "
 		   "address " MACSTR, MAC2STR(r0kh->addr));
@@ -317,25 +327,32 @@
 	frame.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
 	frame.packet_type = FT_PACKET_R0KH_R1KH_PULL;
 	frame.data_length = host_to_le16(FT_R0KH_R1KH_PULL_DATA_LEN);
-	os_memcpy(frame.ap_address, wpa_auth->addr, ETH_ALEN);
+	os_memcpy(frame.ap_address, sm->wpa_auth->addr, ETH_ALEN);
 
 	/* aes_wrap() does not support inplace encryption, so use a temporary
 	 * buffer for the data. */
-	if (random_get_bytes(f.nonce, sizeof(f.nonce))) {
+	if (random_get_bytes(f.nonce, FT_R0KH_R1KH_PULL_NONCE_LEN)) {
 		wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
 			   "nonce");
 		return -1;
 	}
+	os_memcpy(sm->ft_pending_pull_nonce, f.nonce,
+		  FT_R0KH_R1KH_PULL_NONCE_LEN);
 	os_memcpy(f.pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN);
-	os_memcpy(f.r1kh_id, wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN);
-	os_memcpy(f.s1kh_id, s1kh_id, ETH_ALEN);
+	os_memcpy(f.r1kh_id, sm->wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN);
+	os_memcpy(f.s1kh_id, sm->addr, ETH_ALEN);
 	os_memset(f.pad, 0, sizeof(f.pad));
 
 	if (aes_wrap(r0kh->key, (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
 		     f.nonce, frame.nonce) < 0)
 		return -1;
 
-	wpa_ft_rrb_send(wpa_auth, r0kh->addr, (u8 *) &frame, sizeof(frame));
+	wpabuf_free(sm->ft_pending_req_ies);
+	sm->ft_pending_req_ies = wpabuf_alloc_copy(ies, ies_len);
+	if (sm->ft_pending_req_ies == NULL)
+		return -1;
+
+	wpa_ft_rrb_send(sm->wpa_auth, r0kh->addr, (u8 *) &frame, sizeof(frame));
 
 	return 0;
 }
@@ -777,7 +794,7 @@
 }
 
 
-static u16 wpa_ft_process_auth_req(struct wpa_state_machine *sm,
+static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
 				   const u8 *ies, size_t ies_len,
 				   u8 **resp_ies, size_t *resp_ies_len)
 {
@@ -848,19 +865,13 @@
 
 	if (wpa_ft_fetch_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1_name, pmk_r1,
 		    &pairwise) < 0) {
-		if (wpa_ft_pull_pmk_r1(sm->wpa_auth, sm->addr, sm->r0kh_id,
-				       sm->r0kh_id_len, parse.rsn_pmkid) < 0) {
+		if (wpa_ft_pull_pmk_r1(sm, ies, ies_len, parse.rsn_pmkid) < 0) {
 			wpa_printf(MSG_DEBUG, "FT: Did not have matching "
 				   "PMK-R1 and unknown R0KH-ID");
 			return WLAN_STATUS_INVALID_PMKID;
 		}
 
-		/*
-		 * TODO: Should return "status pending" (and the caller should
-		 * not send out response now). The real response will be sent
-		 * once the response from R0KH is received.
-		 */
-		return WLAN_STATUS_INVALID_PMKID;
+		return -1; /* Status pending */
 	}
 
 	wpa_hexdump_key(MSG_DEBUG, "FT: Selected PMK-R1", pmk_r1, PMK_LEN);
@@ -940,6 +951,7 @@
 	u16 status;
 	u8 *resp_ies;
 	size_t resp_ies_len;
+	int res;
 
 	if (sm == NULL) {
 		wpa_printf(MSG_DEBUG, "FT: Received authentication frame, but "
@@ -950,8 +962,16 @@
 	wpa_printf(MSG_DEBUG, "FT: Received authentication frame: STA=" MACSTR
 		   " BSSID=" MACSTR " transaction=%d",
 		   MAC2STR(sm->addr), MAC2STR(bssid), auth_transaction);
-	status = wpa_ft_process_auth_req(sm, ies, ies_len, &resp_ies,
-					 &resp_ies_len);
+	sm->ft_pending_cb = cb;
+	sm->ft_pending_cb_ctx = ctx;
+	sm->ft_pending_auth_transaction = auth_transaction;
+	res = wpa_ft_process_auth_req(sm, ies, ies_len, &resp_ies,
+				      &resp_ies_len);
+	if (res < 0) {
+		wpa_printf(MSG_DEBUG, "FT: Callback postponed until response is available");
+		return;
+	}
+	status = res;
 
 	wpa_printf(MSG_DEBUG, "FT: FT authentication response: dst=" MACSTR
 		   " auth_transaction=%d status=%d",
@@ -1182,15 +1202,27 @@
 }
 
 
+static void wpa_ft_rrb_rx_request_cb(void *ctx, const u8 *dst, const u8 *bssid,
+				     u16 auth_transaction, u16 resp,
+				     const u8 *ies, size_t ies_len)
+{
+	struct wpa_state_machine *sm = ctx;
+	wpa_printf(MSG_DEBUG, "FT: Over-the-DS RX request cb for " MACSTR,
+		   MAC2STR(sm->addr));
+	wpa_ft_send_rrb_auth_resp(sm, sm->ft_pending_current_ap, sm->addr,
+				  WLAN_STATUS_SUCCESS, ies, ies_len);
+}
+
+
 static int wpa_ft_rrb_rx_request(struct wpa_authenticator *wpa_auth,
 				 const u8 *current_ap, const u8 *sta_addr,
 				 const u8 *body, size_t len)
 {
 	struct wpa_state_machine *sm;
 	u16 status;
-	u8 *resp_ies, *pos;
-	size_t resp_ies_len, rlen;
-	struct ft_rrb_frame *frame;
+	u8 *resp_ies;
+	size_t resp_ies_len;
+	int res;
 
 	sm = wpa_ft_add_sta(wpa_auth, sta_addr);
 	if (sm == NULL) {
@@ -1201,8 +1233,33 @@
 
 	wpa_hexdump(MSG_MSGDUMP, "FT: RRB Request Frame body", body, len);
 
-	status = wpa_ft_process_auth_req(sm, body, len, &resp_ies,
-					 &resp_ies_len);
+	sm->ft_pending_cb = wpa_ft_rrb_rx_request_cb;
+	sm->ft_pending_cb_ctx = sm;
+	os_memcpy(sm->ft_pending_current_ap, current_ap, ETH_ALEN);
+	res = wpa_ft_process_auth_req(sm, body, len, &resp_ies,
+				      &resp_ies_len);
+	if (res < 0) {
+		wpa_printf(MSG_DEBUG, "FT: No immediate response available - wait for pull response");
+		return 0;
+	}
+	status = res;
+
+	res = wpa_ft_send_rrb_auth_resp(sm, current_ap, sta_addr, status,
+					resp_ies, resp_ies_len);
+	os_free(resp_ies);
+	return res;
+}
+
+
+static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine *sm,
+				     const u8 *current_ap, const u8 *sta_addr,
+				     u16 status, const u8 *resp_ies,
+				     size_t resp_ies_len)
+{
+	struct wpa_authenticator *wpa_auth = sm->wpa_auth;
+	size_t rlen;
+	struct ft_rrb_frame *frame;
+	u8 *pos;
 
 	wpa_printf(MSG_DEBUG, "FT: RRB authentication response: STA=" MACSTR
 		   " CurrentAP=" MACSTR " status=%d",
@@ -1218,10 +1275,8 @@
 	rlen = 2 + 2 * ETH_ALEN + 2 + resp_ies_len;
 
 	frame = os_malloc(sizeof(*frame) + rlen);
-	if (frame == NULL) {
-		os_free(resp_ies);
+	if (frame == NULL)
 		return -1;
-	}
 	frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
 	frame->packet_type = FT_PACKET_RESPONSE;
 	frame->action_length = host_to_le16(rlen);
@@ -1235,10 +1290,8 @@
 	pos += ETH_ALEN;
 	WPA_PUT_LE16(pos, status);
 	pos += 2;
-	if (resp_ies) {
+	if (resp_ies)
 		os_memcpy(pos, resp_ies, resp_ies_len);
-		os_free(resp_ies);
-	}
 
 	wpa_ft_rrb_send(wpa_auth, current_ap, (u8 *) frame,
 			sizeof(*frame) + rlen);
@@ -1290,7 +1343,7 @@
 		    f.nonce, sizeof(f.nonce));
 	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - PMKR0Name",
 		    f.pmk_r0_name, WPA_PMK_NAME_LEN);
-	wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull - R1KH-ID=" MACSTR "S1KH-ID="
+	wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull - R1KH-ID=" MACSTR " S1KH-ID="
 		   MACSTR, MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id));
 
 	os_memset(&resp, 0, sizeof(resp));
@@ -1333,13 +1386,58 @@
 }
 
 
+static void ft_pull_resp_cb_finish(void *eloop_ctx, void *timeout_ctx)
+{
+	struct wpa_state_machine *sm = eloop_ctx;
+	int res;
+	u8 *resp_ies;
+	size_t resp_ies_len;
+	u16 status;
+
+	res = wpa_ft_process_auth_req(sm, wpabuf_head(sm->ft_pending_req_ies),
+				      wpabuf_len(sm->ft_pending_req_ies),
+				      &resp_ies, &resp_ies_len);
+	wpabuf_free(sm->ft_pending_req_ies);
+	sm->ft_pending_req_ies = NULL;
+	if (res < 0)
+		res = WLAN_STATUS_UNSPECIFIED_FAILURE;
+	status = res;
+	wpa_printf(MSG_DEBUG, "FT: Postponed auth callback result for " MACSTR
+		   " - status %u", MAC2STR(sm->addr), status);
+
+	sm->ft_pending_cb(sm->ft_pending_cb_ctx, sm->addr, sm->wpa_auth->addr,
+			  sm->ft_pending_auth_transaction + 1, status,
+			  resp_ies, resp_ies_len);
+	os_free(resp_ies);
+}
+
+
+static int ft_pull_resp_cb(struct wpa_state_machine *sm, void *ctx)
+{
+	struct ft_r0kh_r1kh_resp_frame *frame = ctx;
+
+	if (os_memcmp(frame->s1kh_id, sm->addr, ETH_ALEN) != 0)
+		return 0;
+	if (os_memcmp(frame->nonce, sm->ft_pending_pull_nonce,
+		      FT_R0KH_R1KH_PULL_NONCE_LEN) != 0)
+		return 0;
+	if (sm->ft_pending_cb == NULL || sm->ft_pending_req_ies == NULL)
+		return 0;
+
+	wpa_printf(MSG_DEBUG, "FT: Response to a pending pull request for "
+		   MACSTR " - process from timeout", MAC2STR(sm->addr));
+	eloop_register_timeout(0, 0, ft_pull_resp_cb_finish, sm, NULL);
+	return 1;
+}
+
+
 static int wpa_ft_rrb_rx_resp(struct wpa_authenticator *wpa_auth,
 			      const u8 *src_addr,
 			      const u8 *data, size_t data_len)
 {
 	struct ft_r0kh_r1kh_resp_frame *frame, f;
 	struct ft_remote_r0kh *r0kh;
-	int pairwise;
+	int pairwise, res;
 
 	wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull response");
 
@@ -1376,14 +1474,10 @@
 		return -1;
 	}
 
-	/* TODO: verify that <nonce,s1kh_id> matches with a pending request
-	 * and call this requests callback function to finish request
-	 * processing */
-
 	pairwise = le_to_host16(f.pairwise);
 	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - nonce",
 		    f.nonce, sizeof(f.nonce));
-	wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull - R1KH-ID=" MACSTR "S1KH-ID="
+	wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull - R1KH-ID=" MACSTR " S1KH-ID="
 		   MACSTR " pairwise=0x%x",
 		   MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id), pairwise);
 	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1 pull - PMK-R1",
@@ -1391,11 +1485,13 @@
 	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - PMKR1Name",
 			f.pmk_r1_name, WPA_PMK_NAME_LEN);
 
-	wpa_ft_store_pmk_r1(wpa_auth, f.s1kh_id, f.pmk_r1, f.pmk_r1_name,
-			    pairwise);
+	res = wpa_ft_store_pmk_r1(wpa_auth, f.s1kh_id, f.pmk_r1, f.pmk_r1_name,
+				  pairwise);
+	wpa_printf(MSG_DEBUG, "FT: Look for pending pull request");
+	wpa_auth_for_each_sta(wpa_auth, ft_pull_resp_cb, &f);
 	os_memset(f.pmk_r1, 0, PMK_LEN);
 
-	return 0;
+	return res ? 0 : -1;
 }
 
 
diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h
index 2e1bdcf..6960ff3 100644
--- a/src/ap/wpa_auth_i.h
+++ b/src/ap/wpa_auth_i.h
@@ -118,6 +118,15 @@
 	u8 sup_pmk_r1_name[WPA_PMK_NAME_LEN]; /* PMKR1Name from EAPOL-Key
 					       * message 2/4 */
 	u8 *assoc_resp_ftie;
+
+	void (*ft_pending_cb)(void *ctx, const u8 *dst, const u8 *bssid,
+			      u16 auth_transaction, u16 status,
+			      const u8 *ies, size_t ies_len);
+	void *ft_pending_cb_ctx;
+	struct wpabuf *ft_pending_req_ies;
+	u8 ft_pending_pull_nonce[FT_R0KH_R1KH_PULL_NONCE_LEN];
+	u8 ft_pending_auth_transaction;
+	u8 ft_pending_current_ap[ETH_ALEN];
 #endif /* CONFIG_IEEE80211R */
 
 	int pending_1_of_4_timeout;
diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
index 62cd03c..e0033ce 100644
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
@@ -378,6 +378,13 @@
 		}
 		bss->auth_algs = 1;
 	} else {
+#ifdef CONFIG_WPS2
+		/*
+		 * WPS 2.0 does not allow WEP to be configured, so no need to
+		 * process that option here either.
+		 */
+		bss->auth_algs = 1;
+#else /* CONFIG_WPS2 */
 		if ((cred->auth_type & WPS_AUTH_OPEN) &&
 		    (cred->auth_type & WPS_AUTH_SHARED))
 			bss->auth_algs = 3;
@@ -412,6 +419,7 @@
 			}
 			wep->keys_set = 1;
 		}
+#endif /* CONFIG_WPS2 */
 	}
 
 	/* Schedule configuration reload after short period of time to allow
@@ -586,6 +594,13 @@
 
 		fprintf(nconf, "auth_algs=1\n");
 	} else {
+#ifdef CONFIG_WPS2
+		/*
+		 * WPS 2.0 does not allow WEP to be configured, so no need to
+		 * process that option here either.
+		 */
+		fprintf(nconf, "auth_algs=1\n");
+#else /* CONFIG_WPS2 */
 		if ((cred->auth_type & WPS_AUTH_OPEN) &&
 		    (cred->auth_type & WPS_AUTH_SHARED))
 			fprintf(nconf, "auth_algs=3\n");
@@ -611,6 +626,7 @@
 			}
 			fprintf(nconf, "\n");
 		}
+#endif /* CONFIG_WPS2 */
 	}
 
 	fprintf(nconf, "# WPS configuration - END\n");