Cumulative patch from commit 21cb63fffd1e766c8b989125394ed0bfb05e5a4b

21cb63f OpenSSL: Fix client certificate chain building after PKCS#12 use
12a81b6 ACS: Remove unreachable case from a debug print
896607d Remove a pointer check that can never be true
a95cc47 ACS: Be more consistent with iface->current_mode checks
6014e59 P2P: Print find_start in debug log when ignoring old scan results
64845c1 l2_packet: Extend bridge workaround RX processing to cover two frames
4a539ab l2_packet: Improve bridge workaround RX processing
7a36f11 EAP-PAX: Check hmac_sha1_vector() return value
1d20c66 P2P: Clear groups first on FLUSH command
27446e4 mesh: Do not force another peering exchange on driver event
cc64fe7 mesh: Do not clear link state on driver event if exchange was started
b5f5c32 mesh: Add some more details to MPM debug messages
7d41907 nl80211: Add a missing space to a debug message
6174de6 mesh: Connection and group started/removed events into debug log
2da4a56 Add more hostapd.conf documentation for hw_mode with HT/VHT
acc3943 EAP-PEAP peer: Cryptobinding in fast-reconnect case with inner EAP
cba9ebf P2P: Try SD Query with each non-ACK peer only once per search iteration
e9ccfc3 Clear wpa_supplicant state to DISCONNECTED on FLUSH command
aeb408f HS 2.0: Add some documentation for OSEN and network block use
4f6cd3f Fix wpa_supplicant AP mode P2P IE handling if P2P is disabled
92acb40 Fix wpa_supplicant build with CONFIG_L2_PACKET=pcap
15c5606 Update copyright notices for the new year 2016
6e379c6 WPS: Testing mechanism to force auth/encr type flags
ea31912 WPS: Add a workaround for WPA2PSK missing from Enrollee auth flags
db671e0 WPS: Do not build Credential with unsupported encr combination on AP
d7c3347 HS 2.0: Postpone WNM-Notification sending by 100 ms
750f5d9 EAP-FAST: Enable AES256-based TLS cipher suites with OpenSSL
1ebb24b OpenSSL: Share a single openssl_tls_prf() implementation
dea2051 OpenSSL: Clean up function to fetch client/server random
9a42d85 OpenSSL: Drop support for OpenSSL 1.0.0
de213e8 OpenSSL: Drop support for OpenSSL 0.9.8
e79eb0c P2P: Fix P2P_FIND while waiting for listen ROC to start in the driver
944f693 P2P: Stop offchannel TX wait on P2P_STOP_FIND/P2P_LISTEN
8edd9f1 P2P: Add an option to specify group SSID in P2P_CONNECT join case
70e0cb3 P2P: Provide group SSID, if specified, to P2P Client join step
438be60 P2P: Do not accept any GO BSS entry if SSID is specified for join
35510d5 P2P: Use join SSID in the skip-PD cases
8b8d4f4 P2P: Do not accept any BSS entry for join if SSID is already known
b875276 P2P: Use group SSID, if known, for join operation even if no BSS entry
aa256cb P2PS: Add group SSID, if known, to the P2PS-PROV-DONE event
071e3bf FST: Fix handling of Rx FST Setup Request when session already exists

Change-Id: Ia48764e8663232291160fb24153fa367b9ed3015
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/acs.c b/src/ap/acs.c
index 03d797f..5e83805 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -599,8 +599,7 @@
 	wpa_printf(MSG_DEBUG, "ACS: Survey analysis for selected bandwidth %d MHz",
 		   n_chans == 1 ? 20 :
 		   n_chans == 2 ? 40 :
-		   n_chans == 4 ? 80 :
-		   -1);
+		   80);
 
 	for (i = 0; i < iface->current_mode->num_channels; i++) {
 		double total_weight;
@@ -933,6 +932,9 @@
 		return HOSTAPD_CHAN_ACS;
 	}
 
+	if (!iface->current_mode)
+		return HOSTAPD_CHAN_INVALID;
+
 	acs_cleanup(iface);
 
 	err = acs_request_scan(iface);
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 9490e21..3276d12 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -731,7 +731,7 @@
 	}
 
 #ifdef CONFIG_P2P
-	if (hapd->p2p && elems.wps_ie) {
+	if (hapd->p2p && hapd->p2p_group && elems.wps_ie) {
 		struct wpabuf *wps;
 		wps = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA);
 		if (wps && !p2p_group_match_dev_type(hapd->p2p_group, wps)) {
@@ -744,7 +744,7 @@
 		wpabuf_free(wps);
 	}
 
-	if (hapd->p2p && elems.p2p) {
+	if (hapd->p2p && hapd->p2p_group && elems.p2p) {
 		struct wpabuf *p2p;
 		p2p = ieee802_11_vendor_ie_concat(ie, ie_len, P2P_IE_VENDOR_TYPE);
 		if (p2p && !p2p_group_match_dev_id(hapd->p2p_group, p2p)) {
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index aad0d81..9f53660 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -956,8 +956,6 @@
 
 	for (i = 0; i < iface->current_mode->num_channels; i++) {
 		chan = &iface->current_mode->channels[i];
-		if (!chan)
-			return NULL;
 		if ((unsigned int) chan->freq == freq)
 			return chan;
 	}
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 01b514e..ec6f8a7 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1737,7 +1737,7 @@
 #endif /* CONFIG_WPS */
 
 #ifdef CONFIG_P2P
-	if (sta->p2p_ie) {
+	if (sta->p2p_ie && hapd->p2p_group) {
 		struct wpabuf *p2p_resp_ie;
 		enum p2p_status_code status;
 		switch (status_code) {
@@ -2010,7 +2010,7 @@
 	/* Stop Accounting and IEEE 802.1X sessions, but leave the STA
 	 * authenticated. */
 	accounting_sta_stop(hapd, sta);
-	ieee802_1x_free_station(sta);
+	ieee802_1x_free_station(hapd, sta);
 	if (sta->ipaddr)
 		hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *) &sta->ipaddr);
 	ap_sta_ip6addr_del(hapd, sta);
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index e3b3d94..607f941 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -34,6 +34,9 @@
 #include "ieee802_1x.h"
 
 
+#ifdef CONFIG_HS20
+static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx);
+#endif /* CONFIG_HS20 */
 static void ieee802_1x_finished(struct hostapd_data *hapd,
 				struct sta_info *sta, int success,
 				int remediation);
@@ -1048,7 +1051,7 @@
 		 * Clear any possible EAPOL authenticator state to support
 		 * reassociation change from WPS to PSK.
 		 */
-		ieee802_1x_free_station(sta);
+		ieee802_1x_free_station(hapd, sta);
 		return;
 	}
 
@@ -1059,7 +1062,7 @@
 		 * Clear any possible EAPOL authenticator state to support
 		 * reassociation change from WPA-EAP to PSK.
 		 */
-		ieee802_1x_free_station(sta);
+		ieee802_1x_free_station(hapd, sta);
 		return;
 	}
 
@@ -1146,10 +1149,14 @@
 }
 
 
-void ieee802_1x_free_station(struct sta_info *sta)
+void ieee802_1x_free_station(struct hostapd_data *hapd, struct sta_info *sta)
 {
 	struct eapol_state_machine *sm = sta->eapol_sm;
 
+#ifdef CONFIG_HS20
+	eloop_cancel_timeout(ieee802_1x_wnm_notif_send, hapd, sta);
+#endif /* CONFIG_HS20 */
+
 	if (sm == NULL)
 		return;
 
@@ -2528,6 +2535,34 @@
 }
 
 
+#ifdef CONFIG_HS20
+static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx)
+{
+	struct hostapd_data *hapd = eloop_ctx;
+	struct sta_info *sta = timeout_ctx;
+
+	if (sta->remediation) {
+		wpa_printf(MSG_DEBUG, "HS 2.0: Send WNM-Notification to "
+			   MACSTR " to indicate Subscription Remediation",
+			   MAC2STR(sta->addr));
+		hs20_send_wnm_notification(hapd, sta->addr,
+					   sta->remediation_method,
+					   sta->remediation_url);
+		os_free(sta->remediation_url);
+		sta->remediation_url = NULL;
+	}
+
+	if (sta->hs20_deauth_req) {
+		wpa_printf(MSG_DEBUG, "HS 2.0: Send WNM-Notification to "
+			   MACSTR " to indicate imminent deauthentication",
+			   MAC2STR(sta->addr));
+		hs20_send_wnm_notification_deauth_req(hapd, sta->addr,
+						      sta->hs20_deauth_req);
+	}
+}
+#endif /* CONFIG_HS20 */
+
+
 static void ieee802_1x_finished(struct hostapd_data *hapd,
 				struct sta_info *sta, int success,
 				int remediation)
@@ -2547,26 +2582,12 @@
 		sta->remediation_method = 1; /* SOAP-XML SPP */
 	}
 
-	if (success) {
-		if (sta->remediation) {
-			wpa_printf(MSG_DEBUG, "HS 2.0: Send WNM-Notification "
-				   "to " MACSTR " to indicate Subscription "
-				   "Remediation",
-				   MAC2STR(sta->addr));
-			hs20_send_wnm_notification(hapd, sta->addr,
-						   sta->remediation_method,
-						   sta->remediation_url);
-			os_free(sta->remediation_url);
-			sta->remediation_url = NULL;
-		}
-
-		if (sta->hs20_deauth_req) {
-			wpa_printf(MSG_DEBUG, "HS 2.0: Send WNM-Notification "
-				   "to " MACSTR " to indicate imminent "
-				   "deauthentication", MAC2STR(sta->addr));
-			hs20_send_wnm_notification_deauth_req(
-				hapd, sta->addr, sta->hs20_deauth_req);
-		}
+	if (success && (sta->remediation || sta->hs20_deauth_req)) {
+		wpa_printf(MSG_DEBUG, "HS 2.0: Schedule WNM-Notification to "
+			   MACSTR " in 100 ms", MAC2STR(sta->addr));
+		eloop_cancel_timeout(ieee802_1x_wnm_notif_send, hapd, sta);
+		eloop_register_timeout(0, 100000, ieee802_1x_wnm_notif_send,
+				       hapd, sta);
 	}
 #endif /* CONFIG_HS20 */
 
diff --git a/src/ap/ieee802_1x.h b/src/ap/ieee802_1x.h
index 14d6955..ec80199 100644
--- a/src/ap/ieee802_1x.h
+++ b/src/ap/ieee802_1x.h
@@ -21,7 +21,7 @@
 void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
 			size_t len);
 void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta);
-void ieee802_1x_free_station(struct sta_info *sta);
+void ieee802_1x_free_station(struct hostapd_data *hapd, struct sta_info *sta);
 
 void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta);
 void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd,
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 500beff..68fff4c 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -253,7 +253,7 @@
 	eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta);
 	sae_clear_retransmit_timer(hapd, sta);
 
-	ieee802_1x_free_station(sta);
+	ieee802_1x_free_station(hapd, sta);
 	wpa_auth_sta_deinit(sta->wpa_sm);
 	rsn_preauth_free_station(hapd, sta);
 #ifndef CONFIG_NO_RADIUS
@@ -487,7 +487,7 @@
 			sta->acct_terminate_cause =
 				RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;
 		accounting_sta_stop(hapd, sta);
-		ieee802_1x_free_station(sta);
+		ieee802_1x_free_station(hapd, sta);
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 			       HOSTAPD_LEVEL_INFO, "disassociated due to "
 			       "inactivity");
@@ -722,7 +722,7 @@
 	eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC, 0,
 			       ap_handle_timer, hapd, sta);
 	accounting_sta_stop(hapd, sta);
-	ieee802_1x_free_station(sta);
+	ieee802_1x_free_station(hapd, sta);
 
 	sta->disassoc_reason = reason;
 	sta->flags |= WLAN_STA_PENDING_DISASSOC_CB;
@@ -761,7 +761,7 @@
 	eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,
 			       ap_handle_timer, hapd, sta);
 	accounting_sta_stop(hapd, sta);
-	ieee802_1x_free_station(sta);
+	ieee802_1x_free_station(hapd, sta);
 
 	sta->deauth_reason = reason;
 	sta->flags |= WLAN_STA_PENDING_DEAUTH_CB;
diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
index 66a43eb..ba58f3e 100644
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
@@ -1,6 +1,6 @@
 /*
  * hostapd / WPS integration
- * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2008-2016, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -445,6 +445,8 @@
 	os_memcpy(hapd->wps->ssid, cred->ssid, cred->ssid_len);
 	hapd->wps->ssid_len = cred->ssid_len;
 	hapd->wps->encr_types = cred->encr_type;
+	hapd->wps->encr_types_rsn = cred->encr_type;
+	hapd->wps->encr_types_wpa = cred->encr_type;
 	hapd->wps->auth_types = cred->auth_type;
 	hapd->wps->ap_encr_type = cred->encr_type;
 	hapd->wps->ap_auth_type = cred->auth_type;
@@ -1068,10 +1070,14 @@
 		if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
 			wps->auth_types |= WPS_AUTH_WPA2;
 
-		if (conf->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP))
+		if (conf->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) {
 			wps->encr_types |= WPS_ENCR_AES;
-		if (conf->rsn_pairwise & WPA_CIPHER_TKIP)
+			wps->encr_types_rsn |= WPS_ENCR_AES;
+		}
+		if (conf->rsn_pairwise & WPA_CIPHER_TKIP) {
 			wps->encr_types |= WPS_ENCR_TKIP;
+			wps->encr_types_rsn |= WPS_ENCR_TKIP;
+		}
 	}
 
 	if (conf->wpa & WPA_PROTO_WPA) {
@@ -1080,10 +1086,14 @@
 		if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
 			wps->auth_types |= WPS_AUTH_WPA;
 
-		if (conf->wpa_pairwise & WPA_CIPHER_CCMP)
+		if (conf->wpa_pairwise & WPA_CIPHER_CCMP) {
 			wps->encr_types |= WPS_ENCR_AES;
-		if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
+			wps->encr_types_wpa |= WPS_ENCR_AES;
+		}
+		if (conf->wpa_pairwise & WPA_CIPHER_TKIP) {
 			wps->encr_types |= WPS_ENCR_TKIP;
+			wps->encr_types_wpa |= WPS_ENCR_TKIP;
+		}
 	}
 
 	if (conf->ssid.security_policy == SECURITY_PLAINTEXT) {
@@ -1123,6 +1133,8 @@
 		/* Override parameters to enable security by default */
 		wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
 		wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP;
+		wps->encr_types_rsn = WPS_ENCR_AES | WPS_ENCR_TKIP;
+		wps->encr_types_wpa = WPS_ENCR_AES | WPS_ENCR_TKIP;
 	}
 
 	wps->ap_settings = conf->ap_settings;