Cumulative patch from commit 324ade51e168f28430f4429849becd0f08d507c0
324ade5 TLS: Make tls_cert_chain_failure_event() more robust
c6231b5 TLS: Remove storing of never-read value
15a6813 Remove unnecessary cleanup assignment in SHA1Final()
ef3866a nl80211: Don't call linux_iface_up() for a dedicated P2P Device
c2ed779 mesh: Document Mesh Peering Management element structure in more detail
b2817cd mesh: Check PMKID in AMPE Action frames
6c33eed mesh: Fix PMKID to match the standard
ede7770 wpa_supplicant: Do not wait for monitor on P2P Device interface
1c94570 Do not wait for monitor to attach if no control interface
f98674a Clone default LIBS value to LIBS_* for other tools
7d2f674 Add "GET_CAPABILITY acs" to allow ACS build option to be detected
d990971 wpa_supplicant: Enable Automatic Channel Selection support for AP mode
96bc508 Handle survey event properly in wpa_supplicant
d39f796 EAP-TNC peer: Remove dead code related to fragmentation
662512e P2PS: Remove dead code
abbbaa4 TNC: Print received IF-TNCCS message as debug ASCII hexdump
d745f02 EAP-TNC peer: Allow fragment_size to be configured
a67e7e5 RADIUS: Add EACCES to list of recognized send() errno values
5bd9be4 Fix RADIUS Called-Station-Id to not escape SSID
0764dd6 TLS client: Multi-OCSP check to cover intermediate CAs
d6b536f Add ocsp=3 configuration parameter for multi-OCSP
0268383 TLS: Move variable declaration to the beginning of the block
b567775 TLS client: OCSP stapling with ocsp_multi option (RFC 6961)
8ea6a27 TLS server: OCSP stapling with ocsp_multi option (RFC 6961)
5addb0d Server configuration for OCSP stapling with ocsp_multi (RFC 6961)
bca0872 TLS server: OCSP stapling
9532bd2 GnuTLS: OCSP stapling on the server side
6241766 Use wpa_msg() for the "RSN: PMKID mismatch" message
e161451 EAP-EKE: Merge identical error return paths
13cb0a6 EAP-EKE: Reject too long Prot() data when building a frame
0ab0de8 Document previously missing key_mgmt values
Change-Id: I9ac7d0da03d8baf4542e276ab20cb56e44bfa33c
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index f62b30a..95690bf 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -856,6 +856,12 @@
endif
endif
+ifdef CONFIG_ACS
+L_CFLAGS += -DCONFIG_ACS
+OBJS += src/ap/acs.c
+LIBS += -lm
+endif
+
ifdef CONFIG_PCSC
# PC/SC interface for smartcards (USIM, GSM SIM)
L_CFLAGS += -DPCSC_FUNCS -I/usr/include/PCSC
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 6bab7d1..8fa35e5 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -6,6 +6,17 @@
CFLAGS = -MMD -O2 -Wall -g
endif
+ifdef LIBS
+# If LIBS is set with some global build system defaults, clone those for
+# LIBS_c and LIBS_p to cover wpa_passphrase and wpa_cli as well.
+ifndef LIBS_c
+LIBS_c := $(LIBS)
+endif
+ifndef LIBS_p
+LIBS_p := $(LIBS)
+endif
+endif
+
export LIBDIR ?= /usr/local/lib/
export INCDIR ?= /usr/local/include/
export BINDIR ?= /usr/local/sbin/
@@ -884,6 +895,12 @@
endif
endif
+ifdef CONFIG_ACS
+CFLAGS += -DCONFIG_ACS
+OBJS += ../src/ap/acs.o
+LIBS += -lm
+endif
+
ifdef CONFIG_PCSC
# PC/SC interface for smartcards (USIM, GSM SIM)
CFLAGS += -DPCSC_FUNCS -I/usr/include/PCSC
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 27fa2a9..105fb1c 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -213,6 +213,14 @@
if (wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf))
return -1;
+#ifdef CONFIG_ACS
+ if (ssid->acs) {
+ /* Setting channel to 0 in order to enable ACS */
+ conf->channel = 0;
+ wpa_printf(MSG_DEBUG, "Use automatic channel selection");
+ }
+#endif /* CONFIG_ACS */
+
if (ieee80211_is_dfs(ssid->frequency) && wpa_s->conf->country[0]) {
conf->ieee80211h = 1;
conf->ieee80211d = 1;
@@ -558,6 +566,11 @@
{
struct wpa_supplicant *wpa_s = ctx;
+#ifdef CONFIG_ACS
+ if (wpa_s->current_ssid && wpa_s->current_ssid->acs)
+ wpa_s->assoc_freq = wpa_s->ap_iface->freq;
+#endif /* CONFIG_ACS */
+
wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
if (wpa_s->ap_configured_cb)
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index f2ae4fd..85717e9 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1920,6 +1920,9 @@
{ INT_RANGE(mixed_cell, 0, 1) },
{ INT_RANGE(frequency, 0, 65000) },
{ INT_RANGE(fixed_freq, 0, 1) },
+#ifdef CONFIG_ACS
+ { INT_RANGE(acs, 0, 1) },
+#endif /* CONFIG_ACS */
#ifdef CONFIG_MESH
{ FUNC(mesh_basic_rates) },
{ INT(dot11MeshMaxRetries) },
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 80e3e56..6ea113e 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -747,6 +747,9 @@
INT(no_auto_peer);
INT(frequency);
INT(fixed_freq);
+#ifdef CONFIG_ACS
+ INT(acs);
+#endif /* CONFIG_ACS */
write_int(f, "proactive_key_caching", ssid->proactive_key_caching, -1);
INT(disabled);
INT(peerkey);
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index de8157a..b296826 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -431,6 +431,18 @@
*/
int fixed_freq;
+#ifdef CONFIG_ACS
+ /**
+ * ACS - Automatic Channel Selection for AP mode
+ *
+ * If present, it will be handled together with frequency.
+ * frequency will be used to determine hardware mode only, when it is
+ * used for both hardware mode and channel when used alone. This will
+ * force the channel to be set to 0, thus enabling ACS.
+ */
+ int acs;
+#endif /* CONFIG_ACS */
+
/**
* mesh_basic_rates - BSS Basic rate set for mesh network
*
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index d1274f6..ecf8d2d 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -3937,6 +3937,15 @@
}
#endif /* CONFIG_FIPS */
+#ifdef CONFIG_ACS
+ if (os_strcmp(field, "acs") == 0) {
+ res = os_snprintf(buf, buflen, "ACS");
+ if (os_snprintf_error(buflen, res))
+ return -1;
+ return res;
+ }
+#endif /* CONFIG_ACS */
+
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
field);
diff --git a/wpa_supplicant/ctrl_iface_unix.c b/wpa_supplicant/ctrl_iface_unix.c
index 2c71b2d..7b36751 100644
--- a/wpa_supplicant/ctrl_iface_unix.c
+++ b/wpa_supplicant/ctrl_iface_unix.c
@@ -1058,6 +1058,9 @@
struct sockaddr_un from;
socklen_t fromlen = sizeof(from);
+ if (priv->sock == -1)
+ return;
+
for (;;) {
wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to "
"attach", priv->wpa_s->ifname);
diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
index e2e4bdc..8b1d121 100644
--- a/wpa_supplicant/defconfig
+++ b/wpa_supplicant/defconfig
@@ -513,3 +513,29 @@
# OS X builds. This is only for building eapol_test.
#CONFIG_OSX=y
+
+# Automatic Channel Selection
+# This will allow wpa_supplicant to pick the channel automatically when channel
+# is set to "0".
+#
+# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative
+# to "channel=0". This would enable us to eventually add other ACS algorithms in
+# similar way.
+#
+# Automatic selection is currently only done through initialization, later on
+# we hope to do background checks to keep us moving to more ideal channels as
+# time goes by. ACS is currently only supported through the nl80211 driver and
+# your driver must have survey dump capability that is filled by the driver
+# during scanning.
+#
+# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with
+# a newly to create wpa_supplicant.conf variable acs_num_scans.
+#
+# Supported ACS drivers:
+# * ath9k
+# * ath5k
+# * ath10k
+#
+# For more details refer to:
+# http://wireless.kernel.org/en/users/Documentation/acs
+#CONFIG_ACS=y
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 1ac177e..3c60cc1 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -3942,6 +3942,22 @@
data->mesh_peer.ie_len);
#endif /* CONFIG_MESH */
break;
+ case EVENT_SURVEY:
+#ifdef CONFIG_AP
+ if (!wpa_s->ap_iface)
+ break;
+ hostapd_event_get_survey(wpa_s->ap_iface,
+ &data->survey_results);
+#endif /* CONFIG_AP */
+ break;
+ case EVENT_ACS_CHANNEL_SELECTED:
+#ifdef CONFIG_ACS
+ if (!wpa_s->ap_iface)
+ break;
+ hostapd_acs_channel_selected(wpa_s->ap_iface->bss[0],
+ &data->acs_selected_channels);
+#endif /* CONFIG_ACS */
+ break;
default:
wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
break;
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index 7ebd4d2..4caa55c 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -20,11 +20,11 @@
#include "mesh_rsn.h"
struct mesh_peer_mgmt_ie {
- const u8 *proto_id;
- const u8 *llid;
- const u8 *plid;
- const u8 *reason;
- const u8 *pmk;
+ const u8 *proto_id; /* Mesh Peering Protocol Identifier (2 octets) */
+ const u8 *llid; /* Local Link ID (2 octets) */
+ const u8 *plid; /* Peer Link ID (conditional, 2 octets) */
+ const u8 *reason; /* Reason Code (conditional, 2 octets) */
+ const u8 *chosen_pmk; /* Chosen PMK (optional, 16 octets) */
};
static void plink_timer(void *eloop_ctx, void *user_data);
@@ -72,10 +72,10 @@
{
os_memset(mpm_ie, 0, sizeof(*mpm_ie));
- /* remove optional PMK at end */
- if (len >= 16) {
- len -= 16;
- mpm_ie->pmk = ie + len - 16;
+ /* Remove optional Chosen PMK field at end */
+ if (len >= SAE_PMKID_LEN) {
+ mpm_ie->chosen_pmk = ie + len - SAE_PMKID_LEN;
+ len -= SAE_PMKID_LEN;
}
if ((action_field == PLINK_OPEN && len != 4) ||
@@ -101,8 +101,8 @@
len -= 2;
}
- /* plid, present for confirm, and possibly close */
- if (len)
+ /* Peer Link ID, present for confirm, and possibly close */
+ if (len >= 2)
mpm_ie->plid = ie;
return 0;
@@ -1014,6 +1014,7 @@
if ((mconf->security & MESH_CONF_SEC_AMPE) &&
mesh_rsn_process_ampe(wpa_s, sta, &elems,
&mgmt->u.action.category,
+ peer_mgmt_ie.chosen_pmk,
ies, ie_len)) {
wpa_printf(MSG_DEBUG, "MPM: RSN process rejected frame");
return;
diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
index 747f1ae..5d88274 100644
--- a/wpa_supplicant/mesh_rsn.c
+++ b/wpa_supplicant/mesh_rsn.c
@@ -328,10 +328,7 @@
void mesh_rsn_get_pmkid(struct mesh_rsn *rsn, struct sta_info *sta, u8 *pmkid)
{
- /* don't expect wpa auth to cache the pmkid for now */
- rsn_pmkid(sta->sae->pmk, PMK_LEN, rsn->wpa_s->own_addr,
- sta->addr, pmkid,
- wpa_key_mgmt_sha256(wpa_auth_sta_key_mgmt(sta->wpa_sm)));
+ os_memcpy(pmkid, sta->sae->pmkid, SAE_PMKID_LEN);
}
@@ -503,6 +500,7 @@
int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
struct ieee802_11_elems *elems, const u8 *cat,
+ const u8 *chosen_pmk,
const u8 *start, size_t elems_len)
{
int ret = 0;
@@ -516,6 +514,12 @@
const size_t aad_len[] = { ETH_ALEN, ETH_ALEN,
(elems->mic - 2) - cat };
+ if (chosen_pmk && os_memcmp(chosen_pmk, sta->sae->pmkid, PMKID_LEN)) {
+ wpa_msg(wpa_s, MSG_DEBUG,
+ "Mesh RSN: Invalid PMKID (Chosen PMK did not match calculated PMKID)");
+ return -1;
+ }
+
if (!elems->mic || elems->mic_len < AES_BLOCK_SIZE) {
wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing mic ie");
return -1;
diff --git a/wpa_supplicant/mesh_rsn.h b/wpa_supplicant/mesh_rsn.h
index b1471b2..89601d4 100644
--- a/wpa_supplicant/mesh_rsn.h
+++ b/wpa_supplicant/mesh_rsn.h
@@ -30,6 +30,7 @@
const u8 *cat, struct wpabuf *buf);
int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
struct ieee802_11_elems *elems, const u8 *cat,
+ const u8 *chosen_pmk,
const u8 *start, size_t elems_len);
void mesh_auth_timer(void *eloop_ctx, void *user_data);
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 45dae50..d6acbd0 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -774,13 +774,6 @@
case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW:
case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT:
- /*
- * Peer has an active GO, so if the role allows it and
- * we do not have any active roles, become client.
- */
- if ((role & P2PS_SETUP_CLIENT) && !go_wpa_s && !cli_wpa_s)
- return P2PS_SETUP_CLIENT;
-
if (cli_wpa_s)
conncap = P2PS_SETUP_GROUP_OWNER;
else {
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 29683bc..e588992 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -5227,7 +5227,7 @@
if (global->params.wait_for_monitor) {
for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
- if (wpa_s->ctrl_iface)
+ if (wpa_s->ctrl_iface && !wpa_s->p2p_mgmt)
wpa_supplicant_ctrl_iface_wait(
wpa_s->ctrl_iface);
}
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index e33b720..e204061 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -586,6 +586,8 @@
# 0 = do not use OCSP stapling (TLS certificate status extension)
# 1 = try to use OCSP stapling, but not require response
# 2 = require valid OCSP stapling response
+# 3 = require valid OCSP stapling response for all not-trusted
+# certificates in the server certificate chain
#
# sim_num: Identifier for which SIM to use in multi-SIM devices
#
@@ -748,8 +750,18 @@
# IEEE8021X = IEEE 802.1X using EAP authentication and (optionally) dynamically
# generated WEP keys
# NONE = WPA is not used; plaintext or static WEP could be used
+# WPA-NONE = WPA-None for IBSS (deprecated; use proto=RSN key_mgmt=WPA-PSK
+# instead)
+# FT-PSK = Fast BSS Transition (IEEE 802.11r) with pre-shared key
+# FT-EAP = Fast BSS Transition (IEEE 802.11r) with EAP authentication
# WPA-PSK-SHA256 = Like WPA-PSK but using stronger SHA256-based algorithms
# WPA-EAP-SHA256 = Like WPA-EAP but using stronger SHA256-based algorithms
+# SAE = Simultaneous authentication of equals; pre-shared key/password -based
+# authentication with stronger security than WPA-PSK especially when using
+# not that strong password
+# FT-SAE = SAE with FT
+# WPA-EAP-SUITE-B = Suite B 128-bit level
+# WPA-EAP-SUITE-B-192 = Suite B 192-bit level
# If not set, this defaults to: WPA-PSK WPA-EAP
#
# ieee80211w: whether management frame protection is enabled
@@ -1074,6 +1086,8 @@
# 0 = do not use OCSP stapling (TLS certificate status extension)
# 1 = try to use OCSP stapling, but not require response
# 2 = require valid OCSP stapling response
+# 3 = require valid OCSP stapling response for all not-trusted
+# certificates in the server certificate chain
#
# openssl_ciphers: OpenSSL specific cipher configuration
# This can be used to override the global openssl_ciphers configuration