Cumulative patch from commit 3e7f1c7980c6e9fc7173f78aa72b2761fcd8924d (DO NOT MERGE)
3e7f1c7 GnuTLS: Add TLS event callbacks for chain success/failure and peer cert
0eb2ed0 GnuTLS: Add support for OCSP stapling as a client
cf08e9b Add MESH to modes capabilities
db5adfe Add SAE to auth_alg capabilities
0e1bb94 GnuTLS: Verify that server certificate EKU is valid for a server
d4d1f5c GnuTLS: Fix tls_disable_time_checks=1 processing
594d1fc GnuTLS: Add support for private_key and client_cert as blobs
79b1dd9 GnuTLS: Fix DER encoding certificate parsing
a165145 Add "GET tls_library" to provide information on TLS library and version
c3bb84b GnuTLS: Add event callbacks
8ddcd6b GnuTLS: Add support for domain_suffix_match
4bc13bf GnuTLS: Check for any unknown verification failure
e0d431a GnuTLS: Add more debug prints for version and session status
65ec7f4 GnuTLS: Move peer certificate validation into callback function
7c82457 GnuTLS: Remove support for versions older than 2.12.x
e1d63f6 GnuTLS: Remove old version number checks for 1.3.2
ae0a23a GnuTLS: Remove GNUTLS_INTERNAL_STRUCTURE_HACK
db4cf40 GnuTLS: Add support for ca_cert as a blob
224104d TLS: Reject openssl_ciphers parameter in non-OpenSSL cases
b09baf3 Work around Windows build issues
6dbbef9 Define host_to_le32() for Windows builds
7d28e46 Fix os_win32 build
0b40247 Remove Network Security Service (NSS) support
d166947 schannel: Reject subject_match, altsubject_match, suffix_match
59051f8 TLS: Reject subject_match, altsubject_match, suffix_match
f8717ac GnuTLS: Reject subject_match, altsubject_match, suffix_match
e24aef1 Fix a typo in domain_suffix_match documentation
394b547 Improve subject_match and domain_suffix_match documentation
8a42a07 trace: Fix out-of-memory testing logic
79cd993 Add address masks to BSSID lists
b83e455 Add network specific BSSID black and white lists
b3d6a0a Add generic parser for MAC address lists
21c74e8 nl80211: Use a helper function to put mesh_id
85e1fad nl80211: Use a helper function for putting beacon interval
6dfc557 Remove mesh_ht_mode network block parameter
54fe48b mesh: Use the shared function with IBSS to determine channel parameters
f7e889f mesh: Convert channel configuration to use common routines
6334330 mesh: Use a separate variable to track whether HT is enabled
1fc4ab2 nl80211: Move debug prints into nl80211_put_freq_params()
cae87ab nl80211: Add a helper function for putting basic rates
6b8b077 ibss/mesh: Enable HT40 if supported
a828f62 Make check_40mhz_2g4 common
fdd989d Make check_20mhz_bss common
0e550fe Make check_40mhz_5g common
6d5d098 Make get_pri_sec_chan() common
5144274 Introduce common allowed_ht40_channel_pair()
5f10b7f Use common hw_get_freq/hw_get_chan helpers in hostapd
269dfe2 Introduce common hw features
1830817 IBSS: Add WPA_DRIVER_FLAGS_HT_IBSS
f3b8ad4 SAE: Implement retransmission timer
a206e2a SAE: Centralize function for sending initial COMMIT
28c91ee bsd: Fix parsing of ieee80211req_scan_result on FreeBSD and DragonFly
96d1d97 Android: Remove hardcoded ICU include paths from hs20-osu-client
a354bcc D-Bus: Use NoMemory error message from CreateInterface
635874b Handle interface disabled/enabled more consistently
8f2cf37 P2P: Indicate reason=UNAVAILABLE for group netdev going down
86a7fbb Verify that eloop_register_read_sock() succeeds for ctrl_iface setup
27d9701 Fix a memory leak on WPA authenticator error path
c1c07dc Fix hostapd interface addition error path
a156ffd Add support for testing memory allocation failures
52b3943 D-Bus: Fix interface unregistration on error path
96dc9a6 D-Bus (old): Fix interface unregistration on error path
ef03557 Fix memory leak on wpa_supplicant_init_wpa() error path
52a8058 TDLS: Fix an interface addition error path
f2d5728 D-Bus: Fix string array dict entry parser in out-of-memory case
c61bc23 D-Bus: Fix byte array dict entry parser in out-of-memory case
dacf605 D-Bus: Fix Introspect() in case of os_strdup() failure
68a8669 D-Bus (old): Fix wpsReg error message
f0614bc D-Bus (old): Fix message handler error paths
a2af1c7 D-Bus (old): Fix memory leak on error path
3d2e2d5 trace: Fix compiler warning on 32-bit builds with bfd support
b9f6560 eloop: Fix WPA_TRACE tracking in case of realloc failure
e10422c Fix memory leak on hostapd BSS addition error path
2801659 Fix hostapd initialization error path on allocation failure
d58ade2 nl80211: Fix compilation with libnl 1.1 and 2.0
51f3427 crypto: Clear temporary stack buffers after use
77a2c39 crypto: Clear temporary heap allocations before freeing
a15a7fc DH: Clear memory explicitly on private key deinit
77c45e2 Add wpabuf_clear_free() to allow clearing of freed memory
a90c7d9 OpenSSL: Fix pbkdf2_sha1() wrapper
f6ebbcf AES-SIV: Make aes_s2v() static
dcf8fbc nl80211: Simplify event processing error paths
38751d8 nl80211: Remove cfg80211 state mismatch workaround for authentication
64ae244 nl80211: Check support for rekey offload on first use
Change-Id: Ice94c3cf8e39a6d2cac993aacd0f6d45b31c7c15
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 7d7f1b6..512918b 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -1005,23 +1005,6 @@
CONFIG_INTERNAL_DH_GROUP5=y
endif
-ifeq ($(CONFIG_TLS), nss)
-ifdef TLS_FUNCS
-OBJS += src/crypto/tls_nss.c
-LIBS += -lssl3
-endif
-OBJS += src/crypto/crypto_nss.c
-OBJS_p += src/crypto/crypto_nss.c
-ifdef NEED_FIPS186_2_PRF
-OBJS += src/crypto/fips_prf_internal.c
-OBJS += src/crypto/sha1-internal.c
-endif
-LIBS += -lnss3
-LIBS_p += -lnss3
-CONFIG_INTERNAL_MD4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-
ifeq ($(CONFIG_TLS), internal)
ifndef CONFIG_CRYPTO
CONFIG_CRYPTO=internal
@@ -1401,6 +1384,7 @@
endif
OBJS += src/common/ieee802_11_common.c
+OBJS += src/common/hw_features_common.c
ifdef NEED_EAP_COMMON
OBJS += src/eap_common/eap_common.c
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 06ba18f..9e1ffc8 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -1020,23 +1020,6 @@
CONFIG_INTERNAL_DH_GROUP5=y
endif
-ifeq ($(CONFIG_TLS), nss)
-ifdef TLS_FUNCS
-OBJS += ../src/crypto/tls_nss.o
-LIBS += -lssl3
-endif
-OBJS += ../src/crypto/crypto_nss.o
-OBJS_p += ../src/crypto/crypto_nss.o
-ifdef NEED_FIPS186_2_PRF
-OBJS += ../src/crypto/fips_prf_internal.o
-SHA1OBJS += ../src/crypto/sha1-internal.o
-endif
-LIBS += -lnss3
-LIBS_p += -lnss3
-CONFIG_INTERNAL_MD4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-
ifeq ($(CONFIG_TLS), internal)
ifndef CONFIG_CRYPTO
CONFIG_CRYPTO=internal
@@ -1421,6 +1404,7 @@
endif
OBJS += ../src/common/ieee802_11_common.o
+OBJS += ../src/common/hw_features_common.o
ifdef NEED_EAP_COMMON
OBJS += ../src/eap_common/eap_common.o
@@ -1523,6 +1507,7 @@
OBJS += wpas_module_tests.o
OBJS += ../src/utils/utils_module_tests.o
OBJS += ../src/common/common_module_tests.o
+OBJS += ../src/crypto/crypto_module_tests.o
ifdef CONFIG_WPS
OBJS += ../src/wps/wps_module_tests.o
endif
diff --git a/wpa_supplicant/README-HS20 b/wpa_supplicant/README-HS20
index 58c2475..161dc06 100644
--- a/wpa_supplicant/README-HS20
+++ b/wpa_supplicant/README-HS20
@@ -172,7 +172,7 @@
# If set, this FQDN is used as a suffix match requirement for the AAA
# server certificate in SubjectAltName dNSName element(s). If a
# matching dNSName is found, this constraint is met. If no dNSName
-# values are present, this constraint is matched against SubjetName CN
+# values are present, this constraint is matched against SubjectName CN
# using same suffix match comparison. Suffix match here means that the
# host/domain name is compared one label at a time starting from the
# top-level domain and all the labels in @domain_suffix_match shall be
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 4ebf684..a810632 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -235,6 +235,99 @@
#endif /* NO_CONFIG_WRITE */
+static int wpa_config_parse_addr_list(const struct parse_data *data,
+ int line, const char *value,
+ u8 **list, size_t *num, char *name,
+ u8 abort_on_error, u8 masked)
+{
+ const char *pos;
+ u8 *buf, *n, addr[2 * ETH_ALEN];
+ size_t count;
+
+ buf = NULL;
+ count = 0;
+
+ pos = value;
+ while (pos && *pos) {
+ while (*pos == ' ')
+ pos++;
+
+ if (hwaddr_masked_aton(pos, addr, &addr[ETH_ALEN], masked)) {
+ if (abort_on_error || count == 0) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid %s address '%s'",
+ line, name, value);
+ os_free(buf);
+ return -1;
+ }
+ /* continue anyway since this could have been from a
+ * truncated configuration file line */
+ wpa_printf(MSG_INFO,
+ "Line %d: Ignore likely truncated %s address '%s'",
+ line, name, pos);
+ } else {
+ n = os_realloc_array(buf, count + 1, 2 * ETH_ALEN);
+ if (n == NULL) {
+ os_free(buf);
+ return -1;
+ }
+ buf = n;
+ os_memmove(buf + 2 * ETH_ALEN, buf,
+ count * 2 * ETH_ALEN);
+ os_memcpy(buf, addr, 2 * ETH_ALEN);
+ count++;
+ wpa_printf(MSG_MSGDUMP,
+ "%s: addr=" MACSTR " mask=" MACSTR,
+ name, MAC2STR(addr),
+ MAC2STR(&addr[ETH_ALEN]));
+ }
+
+ pos = os_strchr(pos, ' ');
+ }
+
+ os_free(*list);
+ *list = buf;
+ *num = count;
+
+ return 0;
+}
+
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_addr_list(const struct parse_data *data,
+ const u8 *list, size_t num, char *name)
+{
+ char *value, *end, *pos;
+ int res;
+ size_t i;
+
+ if (list == NULL || num == 0)
+ return NULL;
+
+ value = os_malloc(2 * 20 * num);
+ if (value == NULL)
+ return NULL;
+ pos = value;
+ end = value + 2 * 20 * num;
+
+ for (i = num; i > 0; i--) {
+ const u8 *a = list + (i - 1) * 2 * ETH_ALEN;
+ const u8 *m = a + ETH_ALEN;
+
+ if (i < num)
+ *pos++ = ' ';
+ res = hwaddr_mask_txt(pos, end - pos, a, m);
+ if (res < 0) {
+ os_free(value);
+ return NULL;
+ }
+ pos += res;
+ }
+
+ return value;
+}
+#endif /* NO_CONFIG_WRITE */
+
static int wpa_config_parse_bssid(const struct parse_data *data,
struct wpa_ssid *ssid, int line,
const char *value)
@@ -280,6 +373,50 @@
#endif /* NO_CONFIG_WRITE */
+static int wpa_config_parse_bssid_blacklist(const struct parse_data *data,
+ struct wpa_ssid *ssid, int line,
+ const char *value)
+{
+ return wpa_config_parse_addr_list(data, line, value,
+ &ssid->bssid_blacklist,
+ &ssid->num_bssid_blacklist,
+ "bssid_blacklist", 1, 1);
+}
+
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_bssid_blacklist(const struct parse_data *data,
+ struct wpa_ssid *ssid)
+{
+ return wpa_config_write_addr_list(data, ssid->bssid_blacklist,
+ ssid->num_bssid_blacklist,
+ "bssid_blacklist");
+}
+#endif /* NO_CONFIG_WRITE */
+
+
+static int wpa_config_parse_bssid_whitelist(const struct parse_data *data,
+ struct wpa_ssid *ssid, int line,
+ const char *value)
+{
+ return wpa_config_parse_addr_list(data, line, value,
+ &ssid->bssid_whitelist,
+ &ssid->num_bssid_whitelist,
+ "bssid_whitelist", 1, 1);
+}
+
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_bssid_whitelist(const struct parse_data *data,
+ struct wpa_ssid *ssid)
+{
+ return wpa_config_write_addr_list(data, ssid->bssid_whitelist,
+ ssid->num_bssid_whitelist,
+ "bssid_whitelist");
+}
+#endif /* NO_CONFIG_WRITE */
+
+
static int wpa_config_parse_psk(const struct parse_data *data,
struct wpa_ssid *ssid, int line,
const char *value)
@@ -1453,53 +1590,10 @@
struct wpa_ssid *ssid, int line,
const char *value)
{
- const char *pos;
- u8 *buf, *n, addr[ETH_ALEN];
- size_t count;
-
- buf = NULL;
- count = 0;
-
- pos = value;
- while (pos && *pos) {
- while (*pos == ' ')
- pos++;
-
- if (hwaddr_aton(pos, addr)) {
- if (count == 0) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid "
- "p2p_client_list address '%s'.",
- line, value);
- os_free(buf);
- return -1;
- }
- /* continue anyway since this could have been from a
- * truncated configuration file line */
- wpa_printf(MSG_INFO, "Line %d: Ignore likely "
- "truncated p2p_client_list address '%s'",
- line, pos);
- } else {
- n = os_realloc_array(buf, count + 1, ETH_ALEN);
- if (n == NULL) {
- os_free(buf);
- return -1;
- }
- buf = n;
- os_memmove(buf + ETH_ALEN, buf, count * ETH_ALEN);
- os_memcpy(buf, addr, ETH_ALEN);
- count++;
- wpa_hexdump(MSG_MSGDUMP, "p2p_client_list",
- addr, ETH_ALEN);
- }
-
- pos = os_strchr(pos, ' ');
- }
-
- os_free(ssid->p2p_client_list);
- ssid->p2p_client_list = buf;
- ssid->num_p2p_clients = count;
-
- return 0;
+ return wpa_config_parse_addr_list(data, line, value,
+ &ssid->p2p_client_list,
+ &ssid->num_p2p_clients,
+ "p2p_client_list", 0, 0);
}
@@ -1507,34 +1601,9 @@
static char * wpa_config_write_p2p_client_list(const struct parse_data *data,
struct wpa_ssid *ssid)
{
- char *value, *end, *pos;
- int res;
- size_t i;
-
- if (ssid->p2p_client_list == NULL || ssid->num_p2p_clients == 0)
- return NULL;
-
- value = os_malloc(20 * ssid->num_p2p_clients);
- if (value == NULL)
- return NULL;
- pos = value;
- end = value + 20 * ssid->num_p2p_clients;
-
- for (i = ssid->num_p2p_clients; i > 0; i--) {
- res = os_snprintf(pos, end - pos, MACSTR " ",
- MAC2STR(ssid->p2p_client_list +
- (i - 1) * ETH_ALEN));
- if (os_snprintf_error(end - pos, res)) {
- os_free(value);
- return NULL;
- }
- pos += res;
- }
-
- if (pos > value)
- pos[-1] = '\0';
-
- return value;
+ return wpa_config_write_addr_list(data, ssid->p2p_client_list,
+ ssid->num_p2p_clients,
+ "p2p_client_list");
}
#endif /* NO_CONFIG_WRITE */
@@ -1597,32 +1666,6 @@
#ifdef CONFIG_MESH
-static int wpa_config_parse_mesh_ht_mode(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- int htval = 0;
-
- if (os_strcmp(value, "NOHT") == 0)
- htval = CHAN_NO_HT;
- else if (os_strcmp(value, "HT20") == 0)
- htval = CHAN_HT20;
- else if (os_strcmp(value, "HT40-") == 0)
- htval = CHAN_HT40MINUS;
- else if (os_strcmp(value, "HT40+") == 0)
- htval = CHAN_HT40PLUS;
- else {
- wpa_printf(MSG_ERROR,
- "Line %d: no ht_mode configured.", line);
- return -1;
- }
-
- wpa_printf(MSG_MSGDUMP, "mesh_ht_mode: 0x%x", htval);
- ssid->mesh_ht_mode = htval;
- return 0;
-}
-
-
static int wpa_config_parse_mesh_basic_rates(const struct parse_data *data,
struct wpa_ssid *ssid, int line,
const char *value)
@@ -1648,32 +1691,6 @@
#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_mesh_ht_mode(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- char *val;
-
- switch (ssid->mesh_ht_mode) {
- default:
- val = NULL;
- break;
- case CHAN_NO_HT:
- val = "NOHT";
- break;
- case CHAN_HT20:
- val = "HT20";
- break;
- case CHAN_HT40MINUS:
- val = "HT40-";
- break;
- case CHAN_HT40PLUS:
- val = "HT40+";
- break;
- }
- return val ? os_strdup(val) : NULL;
-}
-
-
static char * wpa_config_write_mesh_basic_rates(const struct parse_data *data,
struct wpa_ssid *ssid)
{
@@ -1776,6 +1793,8 @@
{ STR_RANGE(ssid, 0, MAX_SSID_LEN) },
{ INT_RANGE(scan_ssid, 0, 1) },
{ FUNC(bssid) },
+ { FUNC(bssid_blacklist) },
+ { FUNC(bssid_whitelist) },
{ FUNC_KEY(psk) },
{ FUNC(proto) },
{ FUNC(key_mgmt) },
@@ -1856,7 +1875,6 @@
{ INT_RANGE(mixed_cell, 0, 1) },
{ INT_RANGE(frequency, 0, 65000) },
#ifdef CONFIG_MESH
- { FUNC(mesh_ht_mode) },
{ FUNC(mesh_basic_rates) },
{ INT(dot11MeshMaxRetries) },
{ INT(dot11MeshRetryTimeout) },
@@ -2088,6 +2106,8 @@
os_free(ssid->freq_list);
os_free(ssid->bgscan);
os_free(ssid->p2p_client_list);
+ os_free(ssid->bssid_blacklist);
+ os_free(ssid->bssid_whitelist);
#ifdef CONFIG_HT_OVERRIDES
os_free(ssid->ht_mcs);
#endif /* CONFIG_HT_OVERRIDES */
@@ -2347,7 +2367,6 @@
ssid->eap.sim_num = DEFAULT_USER_SELECTED_SIM;
#endif /* IEEE8021X_EAPOL */
#ifdef CONFIG_MESH
- ssid->mesh_ht_mode = DEFAULT_MESH_HT_MODE;
ssid->dot11MeshMaxRetries = DEFAULT_MESH_MAX_RETRIES;
ssid->dot11MeshRetryTimeout = DEFAULT_MESH_RETRY_TIMEOUT;
ssid->dot11MeshConfirmTimeout = DEFAULT_MESH_CONFIRM_TIMEOUT;
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index b3f7eef..dca17c2 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -166,7 +166,7 @@
* If set, this FQDN is used as a suffix match requirement for the AAA
* server certificate in SubjectAltName dNSName element(s). If a
* matching dNSName is found, this constraint is met. If no dNSName
- * values are present, this constraint is matched against SubjetName CN
+ * values are present, this constraint is matched against SubjectName CN
* using same suffix match comparison. Suffix match here means that the
* host/domain name is compared one label at a time starting from the
* top-level domain and all the labels in @domain_suffix_match shall be
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 5c8b24b..d8cbe8b 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -754,7 +754,6 @@
#endif /* CONFIG_HS20 */
write_int(f, "mac_addr", ssid->mac_addr, -1);
#ifdef CONFIG_MESH
- STR(mesh_ht_mode);
STR(mesh_basic_rates);
INT_DEF(dot11MeshMaxRetries, DEFAULT_MESH_MAX_RETRIES);
INT_DEF(dot11MeshRetryTimeout, DEFAULT_MESH_RETRY_TIMEOUT);
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index c5cd6e7..f744895 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -27,7 +27,6 @@
#define DEFAULT_FRAGMENT_SIZE 1398
#define DEFAULT_BG_SCAN_PERIOD -1
-#define DEFAULT_MESH_HT_MODE CHAN_UNDEFINED /* undefined */
#define DEFAULT_MESH_MAX_RETRIES 2
#define DEFAULT_MESH_RETRY_TIMEOUT 40
#define DEFAULT_MESH_CONFIRM_TIMEOUT 40
@@ -133,6 +132,18 @@
u8 bssid[ETH_ALEN];
/**
+ * bssid_blacklist - List of inacceptable BSSIDs
+ */
+ u8 *bssid_blacklist;
+ size_t num_bssid_blacklist;
+
+ /**
+ * bssid_blacklist - List of acceptable BSSIDs
+ */
+ u8 *bssid_whitelist;
+ size_t num_bssid_whitelist;
+
+ /**
* bssid_set - Whether BSSID is configured for this network
*/
int bssid_set;
@@ -409,15 +420,6 @@
int frequency;
/**
- * mesh_ht_mode - definition of HT mode in mesh mode
- *
- * Use the given HT mode for mesh networks. The driver will
- * adapt to other stations if neccesary, but advertise the
- * configured HT mode (HT20/HT40-/HT40+/NOHT).
- */
- int mesh_ht_mode;
-
- /**
* 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 acdc90d..9c3f93d 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -19,6 +19,7 @@
#include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
#include "common/wpa_ctrl.h"
+#include "crypto/tls.h"
#include "ap/hostapd.h"
#include "eap_peer/eap.h"
#include "eapol_supp/eapol_supp_sm.h"
@@ -493,6 +494,8 @@
wpa_s->last_gtk_len);
return res;
#endif /* CONFIG_TESTING_GET_GTK */
+ } else if (os_strcmp(cmd, "tls_library") == 0) {
+ res = tls_get_library_version(buf, buflen);
}
if (os_snprintf_error(buflen, res))
@@ -3496,7 +3499,8 @@
}
-static int ctrl_iface_get_capability_auth_alg(int res, char *strict,
+static int ctrl_iface_get_capability_auth_alg(struct wpa_supplicant *wpa_s,
+ int res, char *strict,
struct wpa_driver_capa *capa,
char *buf, size_t buflen)
{
@@ -3540,6 +3544,16 @@
pos += ret;
}
+#ifdef CONFIG_SAE
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) {
+ ret = os_snprintf(pos, end - pos, "%sSAE",
+ pos == buf ? "" : " ");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+#endif /* CONFIG_SAE */
+
return pos - buf;
}
@@ -3580,6 +3594,16 @@
pos += ret;
}
+#ifdef CONFIG_MESH
+ if (capa->flags & WPA_DRIVER_FLAGS_MESH) {
+ ret = os_snprintf(pos, end - pos, "%sMESH",
+ pos == buf ? "" : " ");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+#endif /* CONFIG_MESH */
+
return pos - buf;
}
@@ -3738,8 +3762,8 @@
buf, buflen);
if (os_strcmp(field, "auth_alg") == 0)
- return ctrl_iface_get_capability_auth_alg(res, strict, &capa,
- buf, buflen);
+ return ctrl_iface_get_capability_auth_alg(wpa_s, res, strict,
+ &capa, buf, buflen);
if (os_strcmp(field, "modes") == 0)
return ctrl_iface_get_capability_modes(res, strict, &capa,
@@ -6859,6 +6883,44 @@
return res < 0 ? -1 : 0;
}
+
+static int wpas_ctrl_test_alloc_fail(struct wpa_supplicant *wpa_s, char *cmd)
+{
+#ifdef WPA_TRACE_BFD
+ extern char wpa_trace_fail_func[256];
+ extern unsigned int wpa_trace_fail_after;
+ char *pos;
+
+ wpa_trace_fail_after = atoi(cmd);
+ pos = os_strchr(cmd, ':');
+ if (pos) {
+ pos++;
+ os_strlcpy(wpa_trace_fail_func, pos,
+ sizeof(wpa_trace_fail_func));
+ } else {
+ wpa_trace_fail_after = 0;
+ }
+ return 0;
+#else /* WPA_TRACE_BFD */
+ return -1;
+#endif /* WPA_TRACE_BFD */
+}
+
+
+static int wpas_ctrl_get_alloc_fail(struct wpa_supplicant *wpa_s,
+ char *buf, size_t buflen)
+{
+#ifdef WPA_TRACE_BFD
+ extern char wpa_trace_fail_func[256];
+ extern unsigned int wpa_trace_fail_after;
+
+ return os_snprintf(buf, buflen, "%u:%s", wpa_trace_fail_after,
+ wpa_trace_fail_func);
+#else /* WPA_TRACE_BFD */
+ return -1;
+#endif /* WPA_TRACE_BFD */
+}
+
#endif /* CONFIG_TESTING_OPTIONS */
@@ -7841,6 +7903,11 @@
} else if (os_strncmp(buf, "DATA_TEST_FRAME ", 16) == 0) {
if (wpas_ctrl_iface_data_test_frame(wpa_s, buf + 16) < 0)
reply_len = -1;
+ } else if (os_strncmp(buf, "TEST_ALLOC_FAIL ", 16) == 0) {
+ if (wpas_ctrl_test_alloc_fail(wpa_s, buf + 16) < 0)
+ reply_len = -1;
+ } else if (os_strcmp(buf, "GET_ALLOC_FAIL") == 0) {
+ reply_len = wpas_ctrl_get_alloc_fail(wpa_s, reply, reply_size);
#endif /* CONFIG_TESTING_OPTIONS */
} else if (os_strncmp(buf, "VENDOR_ELEM_ADD ", 16) == 0) {
if (wpas_ctrl_vendor_elem_add(wpa_s, buf + 16) < 0)
diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.c b/wpa_supplicant/dbus/dbus_dict_helpers.c
index 317661a..a0c44eb 100644
--- a/wpa_supplicant/dbus/dbus_dict_helpers.c
+++ b/wpa_supplicant/dbus/dbus_dict_helpers.c
@@ -700,7 +700,6 @@
if (!buffer)
return FALSE;
- entry->bytearray_value = buffer;
entry->array_len = 0;
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) {
char byte;
@@ -718,13 +717,13 @@
}
buffer = nbuffer;
}
- entry->bytearray_value = buffer;
dbus_message_iter_get_basic(iter, &byte);
- entry->bytearray_value[count] = byte;
+ buffer[count] = byte;
entry->array_len = ++count;
dbus_message_iter_next(iter);
}
+ entry->bytearray_value = buffer;
wpa_hexdump_key(MSG_MSGDUMP, "dbus: byte array contents",
entry->bytearray_value, entry->array_len);
@@ -749,18 +748,16 @@
struct wpa_dbus_dict_entry *entry)
{
dbus_uint32_t count = 0;
- dbus_bool_t success = FALSE;
char **buffer, **nbuffer;
entry->strarray_value = NULL;
+ entry->array_len = 0;
entry->array_type = DBUS_TYPE_STRING;
buffer = os_calloc(STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE);
if (buffer == NULL)
return FALSE;
- entry->strarray_value = buffer;
- entry->array_len = 0;
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
const char *value;
char *str;
@@ -770,15 +767,13 @@
buffer, count + STR_ARRAY_CHUNK_SIZE,
STR_ARRAY_ITEM_SIZE);
if (nbuffer == NULL) {
- os_free(buffer);
wpa_printf(MSG_ERROR,
"dbus: %s out of memory trying to retrieve the string array",
__func__);
- goto done;
+ goto fail;
}
buffer = nbuffer;
}
- entry->strarray_value = buffer;
dbus_message_iter_get_basic(iter, &value);
wpa_printf(MSG_MSGDUMP, "%s: string_array value: %s",
@@ -788,12 +783,13 @@
wpa_printf(MSG_ERROR,
"dbus: %s out of memory trying to duplicate the string array",
__func__);
- goto done;
+ goto fail;
}
- entry->strarray_value[count] = str;
- entry->array_len = ++count;
+ buffer[count++] = str;
dbus_message_iter_next(iter);
}
+ entry->strarray_value = buffer;
+ entry->array_len = count;
wpa_printf(MSG_MSGDUMP, "%s: string_array length %u",
__func__, entry->array_len);
@@ -803,10 +799,15 @@
entry->strarray_value = NULL;
}
- success = TRUE;
+ return TRUE;
-done:
- return success;
+fail:
+ while (count > 0) {
+ count--;
+ os_free(buffer[count]);
+ }
+ os_free(buffer);
+ return FALSE;
}
@@ -1115,6 +1116,8 @@
os_free(entry->bytearray_value);
break;
case DBUS_TYPE_STRING:
+ if (!entry->strarray_value)
+ break;
for (i = 0; i < entry->array_len; i++)
os_free(entry->strarray_value[i]);
os_free(entry->strarray_value);
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index b21b7a8..b30cc38 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -3227,7 +3227,7 @@
if (wpa_s == NULL || wpa_s->global == NULL)
return 0;
ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL)
+ if (ctrl_iface == NULL || wpa_s->dbus_new_path == NULL)
return 0;
wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 166db5d..9aff2c1 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -537,28 +537,28 @@
driver = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (driver == NULL)
- goto error;
+ goto oom;
} else if (os_strcmp(entry.key, "Ifname") == 0 &&
entry.type == DBUS_TYPE_STRING) {
os_free(ifname);
ifname = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (ifname == NULL)
- goto error;
+ goto oom;
} else if (os_strcmp(entry.key, "ConfigFile") == 0 &&
entry.type == DBUS_TYPE_STRING) {
os_free(confname);
confname = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (confname == NULL)
- goto error;
+ goto oom;
} else if (os_strcmp(entry.key, "BridgeIfname") == 0 &&
entry.type == DBUS_TYPE_STRING) {
os_free(bridge_ifname);
bridge_ifname = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (bridge_ifname == NULL)
- goto error;
+ goto oom;
} else {
wpa_dbus_dict_entry_clear(&entry);
goto error;
@@ -610,6 +610,9 @@
error:
reply = wpas_dbus_error_invalid_args(message, NULL);
goto out;
+oom:
+ reply = wpas_dbus_error_no_memory(message);
+ goto out;
}
diff --git a/wpa_supplicant/dbus/dbus_new_introspect.c b/wpa_supplicant/dbus/dbus_new_introspect.c
index e0dd9e2..6209c67 100644
--- a/wpa_supplicant/dbus/dbus_new_introspect.c
+++ b/wpa_supplicant/dbus/dbus_new_introspect.c
@@ -37,14 +37,16 @@
iface = os_zalloc(sizeof(struct interfaces));
if (!iface)
return NULL;
+ iface->dbus_interface = os_strdup(dbus_interface);
iface->xml = wpabuf_alloc(6000);
- if (iface->xml == NULL) {
+ if (iface->dbus_interface == NULL || iface->xml == NULL) {
+ os_free(iface->dbus_interface);
+ wpabuf_free(iface->xml);
os_free(iface);
return NULL;
}
wpabuf_printf(iface->xml, "<interface name=\"%s\">", dbus_interface);
dl_list_add_tail(list, &iface->list);
- iface->dbus_interface = os_strdup(dbus_interface);
return iface;
}
diff --git a/wpa_supplicant/dbus/dbus_old.c b/wpa_supplicant/dbus/dbus_old.c
index 2899132..45bb402 100644
--- a/wpa_supplicant/dbus/dbus_old.c
+++ b/wpa_supplicant/dbus/dbus_old.c
@@ -292,13 +292,13 @@
}
/* If the message was handled, send back the reply */
+out:
if (reply) {
if (!dbus_message_get_no_reply(message))
dbus_connection_send(connection, reply, NULL);
dbus_message_unref(reply);
}
-out:
os_free(iface_obj_path);
os_free(network);
os_free(bssid);
@@ -712,7 +712,7 @@
if (wpa_s == NULL || wpa_s->global == NULL)
return 0;
ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL)
+ if (ctrl_iface == NULL || wpa_s->dbus_path == NULL)
return 0;
con = ctrl_iface->con;
diff --git a/wpa_supplicant/dbus/dbus_old_handlers.c b/wpa_supplicant/dbus/dbus_old_handlers.c
index 504de2a..955ea78 100644
--- a/wpa_supplicant/dbus/dbus_old_handlers.c
+++ b/wpa_supplicant/dbus/dbus_old_handlers.c
@@ -1134,25 +1134,27 @@
entry.type == DBUS_TYPE_STRING) {
os_free(opensc_engine_path);
opensc_engine_path = os_strdup(entry.str_value);
+ wpa_dbus_dict_entry_clear(&entry);
if (opensc_engine_path == NULL)
goto error;
} else if (!strcmp(entry.key, "pkcs11_engine_path") &&
entry.type == DBUS_TYPE_STRING) {
os_free(pkcs11_engine_path);
pkcs11_engine_path = os_strdup(entry.str_value);
+ wpa_dbus_dict_entry_clear(&entry);
if (pkcs11_engine_path == NULL)
goto error;
} else if (!strcmp(entry.key, "pkcs11_module_path") &&
entry.type == DBUS_TYPE_STRING) {
os_free(pkcs11_module_path);
pkcs11_module_path = os_strdup(entry.str_value);
+ wpa_dbus_dict_entry_clear(&entry);
if (pkcs11_module_path == NULL)
goto error;
} else {
wpa_dbus_dict_entry_clear(&entry);
goto error;
}
- wpa_dbus_dict_entry_clear(&entry);
}
os_free(wpa_s->conf->opensc_engine_path);
diff --git a/wpa_supplicant/dbus/dbus_old_handlers_wps.c b/wpa_supplicant/dbus/dbus_old_handlers_wps.c
index 3cf9dc3..5309a53 100644
--- a/wpa_supplicant/dbus/dbus_old_handlers_wps.c
+++ b/wpa_supplicant/dbus/dbus_old_handlers_wps.c
@@ -144,7 +144,7 @@
if (ret < 0) {
return dbus_message_new_error(message,
- WPAS_ERROR_WPS_PBC_ERROR,
+ WPAS_ERROR_WPS_REG_ERROR,
"Could not request credentials");
}
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 8464ed4..afda42a 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -698,6 +698,33 @@
}
+static int match_mac_mask(const u8 *addr_a, const u8 *addr_b, const u8 *mask)
+{
+ size_t i;
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ if ((addr_a[i] & mask[i]) != (addr_b[i] & mask[i]))
+ return 0;
+ }
+ return 1;
+}
+
+
+static int addr_in_list(const u8 *addr, const u8 *list, size_t num)
+{
+ size_t i;
+
+ for (i = 0; i < num; i++) {
+ const u8 *a = list + i * ETH_ALEN * 2;
+ const u8 *m = a + ETH_ALEN;
+
+ if (match_mac_mask(a, addr, m))
+ return 1;
+ }
+ return 0;
+}
+
+
static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
int i, struct wpa_bss *bss,
struct wpa_ssid *group,
@@ -822,6 +849,24 @@
continue;
}
+ /* check blacklist */
+ if (ssid->num_bssid_blacklist &&
+ addr_in_list(bss->bssid, ssid->bssid_blacklist,
+ ssid->num_bssid_blacklist)) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ " skip - BSSID blacklisted");
+ continue;
+ }
+
+ /* if there is a whitelist, only accept those APs */
+ if (ssid->num_bssid_whitelist &&
+ !addr_in_list(bss->bssid, ssid->bssid_whitelist,
+ ssid->num_bssid_whitelist)) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ " skip - BSSID not in whitelist");
+ continue;
+ }
+
if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
continue;
@@ -3383,6 +3428,7 @@
if (!wpa_s->ap_iface) {
wpa_supplicant_set_state(wpa_s,
WPA_DISCONNECTED);
+ wpa_s->scan_req = NORMAL_SCAN_REQ;
wpa_supplicant_req_scan(wpa_s, 0, 0);
} else
wpa_supplicant_set_state(wpa_s,
@@ -3400,11 +3446,24 @@
(wpa_s->current_ssid && wpa_s->current_ssid->p2p_group &&
wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO)) {
/*
+ * Mark interface disabled if this happens to end up not
+ * being removed as a separate P2P group interface.
+ */
+ wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
+ /*
* The interface was externally disabled. Remove
* it assuming an external entity will start a
* new session if needed.
*/
- wpas_p2p_disconnect(wpa_s);
+ if (wpa_s->current_ssid &&
+ wpa_s->current_ssid->p2p_group)
+ wpas_p2p_interface_unavailable(wpa_s);
+ else
+ wpas_p2p_disconnect(wpa_s);
+ /*
+ * wpa_s instance may have been freed, so must not use
+ * it here anymore.
+ */
break;
}
if (wpa_s->p2p_scan_work && wpa_s->global->p2p &&
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index 7a4f3de..5fdf4e0 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -318,15 +318,13 @@
os_memset(¶ms, 0, sizeof(params));
params.meshid = ssid->ssid;
params.meshid_len = ssid->ssid_len;
- params.freq = ssid->frequency;
+ ibss_mesh_setup_freq(wpa_s, ssid, ¶ms.freq);
+ wpa_s->mesh_ht_enabled = !!params.freq.ht_enabled;
if (ssid->beacon_int > 0)
params.beacon_int = ssid->beacon_int;
else if (wpa_s->conf->beacon_int > 0)
params.beacon_int = wpa_s->conf->beacon_int;
params.max_peer_links = wpa_s->conf->max_peer_links;
-#ifdef CONFIG_IEEE80211N
- params.ht_mode = ssid->mesh_ht_mode;
-#endif /* CONFIG_IEEE80211N */
if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
params.flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH;
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index e7c53ea..4a259ff 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -229,8 +229,7 @@
2 + 96 + /* AMPE */
2 + 16; /* MIC */
#ifdef CONFIG_IEEE80211N
- if (type != PLINK_CLOSE &&
- wpa_s->current_ssid->mesh_ht_mode > CHAN_NO_HT) {
+ if (type != PLINK_CLOSE && wpa_s->mesh_ht_enabled) {
buf_len += 2 + 26 + /* HT capabilities */
2 + 22; /* HT operation */
}
@@ -323,8 +322,7 @@
}
#ifdef CONFIG_IEEE80211N
- if (type != PLINK_CLOSE &&
- wpa_s->current_ssid->mesh_ht_mode > CHAN_NO_HT) {
+ if (type != PLINK_CLOSE && wpa_s->mesh_ht_enabled) {
pos = hostapd_eid_ht_capabilities(bss, ht_capa_oper);
pos = hostapd_eid_ht_operation(bss, pos);
wpabuf_put_data(buf, ht_capa_oper, pos - ht_capa_oper);
diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
index e6ae7c3..aee325a 100644
--- a/wpa_supplicant/mesh_rsn.c
+++ b/wpa_supplicant/mesh_rsn.c
@@ -18,6 +18,7 @@
#include "ap/hostapd.h"
#include "ap/wpa_auth.h"
#include "ap/sta_info.h"
+#include "ap/ieee802_11.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
#include "wpas_glue.h"
@@ -245,80 +246,23 @@
}
-struct wpabuf *
-mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, struct sta_info *sta)
+static int mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid,
+ struct sta_info *sta)
{
- struct wpabuf *buf;
- int len;
-
if (ssid->passphrase == NULL) {
wpa_msg(wpa_s, MSG_DEBUG, "SAE: No password available");
- return NULL;
+ return -1;
}
if (mesh_rsn_sae_group(wpa_s, sta->sae) < 0) {
wpa_msg(wpa_s, MSG_DEBUG, "SAE: Failed to select group");
- return NULL;
+ return -1;
}
- if (sae_prepare_commit(wpa_s->own_addr, sta->addr,
- (u8 *) ssid->passphrase,
- os_strlen(ssid->passphrase), sta->sae) < 0) {
- wpa_msg(wpa_s, MSG_DEBUG, "SAE: Could not pick PWE");
- return NULL;
- }
-
- len = wpa_s->mesh_rsn->sae_token ?
- wpabuf_len(wpa_s->mesh_rsn->sae_token) : 0;
- buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + len);
- if (buf == NULL)
- return NULL;
-
- sae_write_commit(sta->sae, buf, wpa_s->mesh_rsn->sae_token);
-
- return buf;
-}
-
-
-static void mesh_rsn_send_auth(struct wpa_supplicant *wpa_s,
- const u8 *dst, const u8 *src,
- u16 auth_transaction, u16 resp,
- struct wpabuf *data)
-{
- struct ieee80211_mgmt *auth;
- u8 *buf;
- size_t len, ielen = 0;
-
- if (data)
- ielen = wpabuf_len(data);
- len = IEEE80211_HDRLEN + sizeof(auth->u.auth) + ielen;
- buf = os_zalloc(len);
- if (buf == NULL)
- return;
-
- auth = (struct ieee80211_mgmt *) buf;
- auth->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_AUTH);
- os_memcpy(auth->da, dst, ETH_ALEN);
- os_memcpy(auth->sa, src, ETH_ALEN);
- os_memcpy(auth->bssid, src, ETH_ALEN);
-
- auth->u.auth.auth_alg = host_to_le16(WLAN_AUTH_SAE);
- auth->u.auth.auth_transaction = host_to_le16(auth_transaction);
- auth->u.auth.status_code = host_to_le16(resp);
-
- if (data)
- os_memcpy(auth->u.auth.variable, wpabuf_head(data), ielen);
-
- wpa_msg(wpa_s, MSG_DEBUG, "authentication frame: STA=" MACSTR
- " auth_transaction=%d resp=%d (IE len=%lu)",
- MAC2STR(dst), auth_transaction, resp, (unsigned long) ielen);
- if (wpa_drv_send_mlme(wpa_s, buf, len, 0) < 0)
- wpa_printf(MSG_INFO, "send_auth_reply: send_mlme failed: %s",
- strerror(errno));
-
- os_free(buf);
+ return sae_prepare_commit(wpa_s->own_addr, sta->addr,
+ (u8 *) ssid->passphrase,
+ os_strlen(ssid->passphrase), sta->sae);
}
@@ -326,9 +270,10 @@
int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s,
struct sta_info *sta)
{
+ struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct wpabuf *buf;
unsigned int rnd;
+ int ret;
if (!ssid) {
wpa_msg(wpa_s, MSG_DEBUG,
@@ -342,25 +287,21 @@
return -1;
}
- buf = mesh_rsn_build_sae_commit(wpa_s, ssid, sta);
- if (!buf)
+ if (mesh_rsn_build_sae_commit(wpa_s, ssid, sta))
return -1;
wpa_msg(wpa_s, MSG_DEBUG,
"AUTH: started authentication with SAE peer: " MACSTR,
MAC2STR(sta->addr));
- sta->sae->state = SAE_COMMITTED;
wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
-
- mesh_rsn_send_auth(wpa_s, sta->addr, wpa_s->own_addr,
- 1, WLAN_STATUS_SUCCESS, buf);
+ ret = auth_sae_init_committed(hapd, sta);
+ if (ret)
+ return ret;
rnd = rand() % MESH_AUTH_TIMEOUT;
eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer,
wpa_s, sta);
- wpabuf_free(buf);
-
return 0;
}
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 42e5014..59f95c3 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -837,7 +837,7 @@
return;
for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) {
- if (os_memcmp(s->p2p_client_list + i * ETH_ALEN, addr,
+ if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN, addr,
ETH_ALEN) != 0)
continue;
@@ -845,32 +845,42 @@
return; /* already the most recent entry */
/* move the entry to mark it most recent */
- os_memmove(s->p2p_client_list + i * ETH_ALEN,
- s->p2p_client_list + (i + 1) * ETH_ALEN,
- (s->num_p2p_clients - i - 1) * ETH_ALEN);
+ os_memmove(s->p2p_client_list + i * 2 * ETH_ALEN,
+ s->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
+ (s->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
os_memcpy(s->p2p_client_list +
- (s->num_p2p_clients - 1) * ETH_ALEN, addr, ETH_ALEN);
+ (s->num_p2p_clients - 1) * 2 * ETH_ALEN, addr,
+ ETH_ALEN);
+ os_memset(s->p2p_client_list +
+ (s->num_p2p_clients - 1) * 2 * ETH_ALEN + ETH_ALEN,
+ 0xff, ETH_ALEN);
found = 1;
break;
}
if (!found && s->num_p2p_clients < P2P_MAX_STORED_CLIENTS) {
n = os_realloc_array(s->p2p_client_list,
- s->num_p2p_clients + 1, ETH_ALEN);
+ s->num_p2p_clients + 1, 2 * ETH_ALEN);
if (n == NULL)
return;
- os_memcpy(n + s->num_p2p_clients * ETH_ALEN, addr, ETH_ALEN);
+ os_memcpy(n + s->num_p2p_clients * 2 * ETH_ALEN, addr,
+ ETH_ALEN);
+ os_memset(n + s->num_p2p_clients * 2 * ETH_ALEN + ETH_ALEN,
+ 0xff, ETH_ALEN);
s->p2p_client_list = n;
s->num_p2p_clients++;
} else if (!found && s->p2p_client_list) {
/* Not enough room for an additional entry - drop the oldest
* entry */
os_memmove(s->p2p_client_list,
- s->p2p_client_list + ETH_ALEN,
- (s->num_p2p_clients - 1) * ETH_ALEN);
+ s->p2p_client_list + 2 * ETH_ALEN,
+ (s->num_p2p_clients - 1) * 2 * ETH_ALEN);
os_memcpy(s->p2p_client_list +
- (s->num_p2p_clients - 1) * ETH_ALEN,
+ (s->num_p2p_clients - 1) * 2 * ETH_ALEN,
addr, ETH_ALEN);
+ os_memset(s->p2p_client_list +
+ (s->num_p2p_clients - 1) * 2 * ETH_ALEN + ETH_ALEN,
+ 0xff, ETH_ALEN);
}
if (wpa_s->parent->conf->update_config &&
@@ -3348,7 +3358,7 @@
return;
for (i = 0; ssid->p2p_client_list && i < ssid->num_p2p_clients; i++) {
- if (os_memcmp(ssid->p2p_client_list + i * ETH_ALEN, peer,
+ if (os_memcmp(ssid->p2p_client_list + i * 2 * ETH_ALEN, peer,
ETH_ALEN) == 0)
break;
}
@@ -3368,9 +3378,9 @@
"group %d client list%s",
MAC2STR(peer), ssid->id,
inv ? " due to invitation result" : "");
- os_memmove(ssid->p2p_client_list + i * ETH_ALEN,
- ssid->p2p_client_list + (i + 1) * ETH_ALEN,
- (ssid->num_p2p_clients - i - 1) * ETH_ALEN);
+ os_memmove(ssid->p2p_client_list + i * 2 * ETH_ALEN,
+ ssid->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
+ (ssid->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
ssid->num_p2p_clients--;
if (wpa_s->parent->conf->update_config &&
wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
@@ -7047,7 +7057,7 @@
if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL)
continue;
for (i = 0; i < s->num_p2p_clients; i++) {
- if (os_memcmp(s->p2p_client_list + i * ETH_ALEN,
+ if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN,
addr, ETH_ALEN) == 0)
return s; /* peer is P2P client in persistent
* group */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index e5dc43f..9994a7a 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -33,6 +33,7 @@
#include "rsn_supp/pmksa_cache.h"
#include "common/wpa_ctrl.h"
#include "common/ieee802_11_defs.h"
+#include "common/hw_features_common.h"
#include "p2p/p2p.h"
#include "blacklist.h"
#include "wpas_glue.h"
@@ -1649,6 +1650,137 @@
}
+void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
+ const struct wpa_ssid *ssid,
+ struct hostapd_freq_params *freq)
+{
+ enum hostapd_hw_mode hw_mode;
+ struct hostapd_hw_modes *mode = NULL;
+ int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
+ 184, 192 };
+ struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
+ u8 channel;
+ int i, chan_idx, ht40 = -1, res;
+ unsigned int j;
+
+ freq->freq = ssid->frequency;
+
+ /* For IBSS check HT_IBSS flag */
+ if (ssid->mode == WPAS_MODE_IBSS &&
+ !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_HT_IBSS))
+ return;
+
+ hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
+ for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
+ if (wpa_s->hw.modes[i].mode == hw_mode) {
+ mode = &wpa_s->hw.modes[i];
+ break;
+ }
+ }
+
+ if (!mode)
+ return;
+
+ freq->ht_enabled = ht_supported(mode);
+ if (!freq->ht_enabled)
+ return;
+
+ /* Setup higher BW only for 5 GHz */
+ if (mode->mode != HOSTAPD_MODE_IEEE80211A)
+ return;
+
+ for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
+ pri_chan = &mode->channels[chan_idx];
+ if (pri_chan->chan == channel)
+ break;
+ pri_chan = NULL;
+ }
+ if (!pri_chan)
+ return;
+
+ /* Check primary channel flags */
+ if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
+ return;
+
+ /* Check/setup HT40+/HT40- */
+ for (j = 0; j < ARRAY_SIZE(ht40plus); j++) {
+ if (ht40plus[j] == channel) {
+ ht40 = 1;
+ break;
+ }
+ }
+
+ /* Find secondary channel */
+ for (i = 0; i < mode->num_channels; i++) {
+ sec_chan = &mode->channels[i];
+ if (sec_chan->chan == channel + ht40 * 4)
+ break;
+ sec_chan = NULL;
+ }
+ if (!sec_chan)
+ return;
+
+ /* Check secondary channel flags */
+ if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
+ return;
+
+ freq->channel = pri_chan->chan;
+
+ switch (ht40) {
+ case -1:
+ if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
+ return;
+ freq->sec_channel_offset = -1;
+ break;
+ case 1:
+ if (!(pri_chan->flag & HOSTAPD_CHAN_HT40PLUS))
+ return;
+ freq->sec_channel_offset = 1;
+ break;
+ default:
+ break;
+ }
+
+ if (freq->sec_channel_offset) {
+ struct wpa_scan_results *scan_res;
+
+ scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
+ if (scan_res == NULL) {
+ /* Back to HT20 */
+ freq->sec_channel_offset = 0;
+ return;
+ }
+
+ res = check_40mhz_5g(mode, scan_res, pri_chan->chan,
+ sec_chan->chan);
+ switch (res) {
+ case 0:
+ /* Back to HT20 */
+ freq->sec_channel_offset = 0;
+ break;
+ case 1:
+ /* Configuration allowed */
+ break;
+ case 2:
+ /* Switch pri/sec channels */
+ freq->freq = hw_get_freq(mode, sec_chan->chan);
+ freq->sec_channel_offset = -freq->sec_channel_offset;
+ freq->channel = sec_chan->chan;
+ break;
+ default:
+ freq->sec_channel_offset = 0;
+ break;
+ }
+
+ wpa_scan_results_free(scan_res);
+ }
+
+ wpa_printf(MSG_DEBUG,
+ "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
+ freq->channel, freq->sec_channel_offset);
+}
+
+
static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
{
struct wpa_connect_work *cwork = work->ctx;
@@ -1962,23 +2094,8 @@
/* Initial frequency for IBSS/mesh */
if ((ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) &&
- ssid->frequency > 0 && params.freq.freq == 0) {
- enum hostapd_hw_mode hw_mode;
- u8 channel;
-
- params.freq.freq = ssid->frequency;
-
- hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
- for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
- if (wpa_s->hw.modes[i].mode == hw_mode) {
- struct hostapd_hw_modes *mode;
-
- mode = &wpa_s->hw.modes[i];
- params.freq.ht_enabled = ht_supported(mode);
- break;
- }
- }
- }
+ ssid->frequency > 0 && params.freq.freq == 0)
+ ibss_mesh_setup_freq(wpa_s, ssid, ¶ms.freq);
if (ssid->mode == WPAS_MODE_IBSS) {
if (ssid->beacon_int)
@@ -5080,6 +5197,13 @@
}
+#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
+/* Workaround different, undefined for Windows, error codes used here */
+#define ENOTCONN -1
+#define EOPNOTSUPP -1
+#define ECANCELED -1
+#endif
+
/**
* wpas_rrm_send_neighbor_rep_request - Request a neighbor report from our AP
* @wpa_s: Pointer to wpa_supplicant
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index e78c0dd..7d189c7 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -865,6 +865,9 @@
# sertificate is only accepted if it contains this string in the subject.
# The subject string is in following format:
# /C=US/ST=CA/L=San Francisco/CN=Test AS/emailAddress=as@example.com
+# Note: Since this is a substring match, this cannot be used securily to
+# do a suffix match against a possible domain name in the CN entry. For
+# such a use case, domain_suffix_match should be used instead.
# altsubject_match: Semicolon separated string of entries to be matched against
# the alternative subject name of the authentication server certificate.
# If this string is set, the server sertificate is only accepted if it
@@ -873,6 +876,20 @@
# Example: EMAIL:server@example.com
# Example: DNS:server.example.com;DNS:server2.example.com
# Following types are supported: EMAIL, DNS, URI
+# domain_suffix_match: Constraint for server domain name. If set, this FQDN is
+# used as a suffix match requirement for the AAAserver certificate in
+# SubjectAltName dNSName element(s). If a matching dNSName is found, this
+# constraint is met. If no dNSName values are present, this constraint is
+# matched against SubjectName CN using same suffix match comparison.
+#
+# Suffix match here means that the host/domain name is compared one label
+# at a time starting from the top-level domain and all the labels in
+# domain_suffix_match shall be included in the certificate. The
+# certificate may include additional sub-level labels in addition to the
+# required labels.
+#
+# For example, domain_suffix_match=example.com would match
+# test.example.com but would not match test-example.com.
# phase1: Phase1 (outer authentication, i.e., TLS tunnel) parameters
# (string with field-value pairs, e.g., "peapver=0" or
# "peapver=1 peaplabel=1")
@@ -939,9 +956,12 @@
# private_key2_passwd: Password for private key file
# dh_file2: File path to DH/DSA parameters file (in PEM format)
# subject_match2: Substring to be matched against the subject of the
-# authentication server certificate.
-# altsubject_match2: Substring to be matched against the alternative subject
-# name of the authentication server certificate.
+# authentication server certificate. See subject_match for more details.
+# altsubject_match2: Semicolon separated string of entries to be matched
+# against the alternative subject name of the authentication server
+# certificate. See altsubject_match documentation for more details.
+# domain_suffix_match2: Constraint for server domain name. See
+# domain_suffix_match for more details.
#
# fragment_size: Maximum EAP fragment size in bytes (default 1398).
# This value limits the fragment size for EAP methods that support
@@ -1431,6 +1451,21 @@
key_mgmt=NONE
}
+# Example configuration blacklisting two APs - these will be ignored
+# for this network.
+network={
+ ssid="example"
+ psk="very secret passphrase"
+ bssid_blacklist=02:11:22:33:44:55 02:22:aa:44:55:66
+}
+
+# Example configuration limiting AP selection to a specific set of APs;
+# any other AP not matching the masked address will be ignored.
+network={
+ ssid="example"
+ psk="very secret passphrase"
+ bssid_whitelist=02:55:ae:bc:00:00/ff:ff:ff:ff:00:00 00:00:77:66:55:44/00:00:ff:ff:ff:ff
+}
# Example config file that will only scan on channel 36.
freq_list=5180
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index c541ccb..e396a5d 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -703,6 +703,7 @@
struct mesh_rsn *mesh_rsn;
int mesh_if_idx;
unsigned int mesh_if_created:1;
+ unsigned int mesh_ht_enabled:1;
#endif /* CONFIG_MESH */
unsigned int off_channel_freq;
@@ -1074,6 +1075,10 @@
const char *field,
const char *value);
+void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
+ const struct wpa_ssid *ssid,
+ struct hostapd_freq_params *freq);
+
/* events.c */
void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s);
int wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 3098058..209e2bc 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -1040,6 +1040,7 @@
if (wpa_s->wpa == NULL) {
wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
"machine");
+ os_free(ctx);
return -1;
}
#endif /* CONFIG_NO_WPA */
diff --git a/wpa_supplicant/wpas_module_tests.c b/wpa_supplicant/wpas_module_tests.c
index e4c83b5..6af1678 100644
--- a/wpa_supplicant/wpas_module_tests.c
+++ b/wpa_supplicant/wpas_module_tests.c
@@ -98,5 +98,11 @@
ret = -1;
}
+ {
+ int crypto_module_tests(void);
+ if (crypto_module_tests() < 0)
+ ret = -1;
+ }
+
return ret;
}