am 9ead16e2: Cumulative patch from commit d5fe4e6c18d94465e8fb4527d51df6e8539c4d6a
* commit '9ead16e203b81d44a2d84eadc2901ceeb7daf805':
Cumulative patch from commit d5fe4e6c18d94465e8fb4527d51df6e8539c4d6a
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index e4681e9..2d09b67 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -1622,6 +1622,9 @@
if (ap_sta_bind_vlan(hapd, sta, old_vlanid) < 0)
break;
+ sta->session_timeout_set = !!session_timeout_set;
+ sta->session_timeout = session_timeout;
+
/* RFC 3580, Ch. 3.17 */
if (session_timeout_set && termination_action ==
RADIUS_TERMINATION_ACTION_RADIUS_REQUEST) {
@@ -2396,6 +2399,7 @@
size_t len;
/* TODO: get PMKLifetime from WPA parameters */
static const int dot11RSNAConfigPMKLifetime = 43200;
+ unsigned int session_timeout;
#ifdef CONFIG_HS20
if (remediation && !sta->remediation) {
@@ -2430,9 +2434,13 @@
#endif /* CONFIG_HS20 */
key = ieee802_1x_get_key(sta->eapol_sm, &len);
+ if (sta->session_timeout_set)
+ session_timeout = sta->session_timeout;
+ else
+ session_timeout = dot11RSNAConfigPMKLifetime;
if (success && key && len >= PMK_LEN && !sta->remediation &&
!sta->hs20_deauth_requested &&
- wpa_auth_pmksa_add(sta->wpa_sm, key, dot11RSNAConfigPMKLifetime,
+ wpa_auth_pmksa_add(sta->wpa_sm, key, session_timeout,
sta->eapol_sm) == 0) {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
HOSTAPD_LEVEL_DEBUG,
diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c
index 4720b59..9de4cff 100644
--- a/src/ap/pmksa_cache_auth.c
+++ b/src/ap/pmksa_cache_auth.c
@@ -37,14 +37,12 @@
static void _pmksa_cache_free_entry(struct rsn_pmksa_cache_entry *entry)
{
- if (entry == NULL)
- return;
os_free(entry->identity);
wpabuf_free(entry->cui);
#ifndef CONFIG_NO_RADIUS
radius_free_class(&entry->radius_class);
#endif /* CONFIG_NO_RADIUS */
- os_free(entry);
+ bin_clear_free(entry, sizeof(*entry));
}
@@ -52,38 +50,42 @@
struct rsn_pmksa_cache_entry *entry)
{
struct rsn_pmksa_cache_entry *pos, *prev;
+ unsigned int hash;
pmksa->pmksa_count--;
pmksa->free_cb(entry, pmksa->ctx);
- pos = pmksa->pmkid[PMKID_HASH(entry->pmkid)];
+
+ /* unlink from hash list */
+ hash = PMKID_HASH(entry->pmkid);
+ pos = pmksa->pmkid[hash];
prev = NULL;
while (pos) {
if (pos == entry) {
- if (prev != NULL) {
- prev->hnext = pos->hnext;
- } else {
- pmksa->pmkid[PMKID_HASH(entry->pmkid)] =
- pos->hnext;
- }
+ if (prev != NULL)
+ prev->hnext = entry->hnext;
+ else
+ pmksa->pmkid[hash] = entry->hnext;
break;
}
prev = pos;
pos = pos->hnext;
}
+ /* unlink from entry list */
pos = pmksa->pmksa;
prev = NULL;
while (pos) {
if (pos == entry) {
if (prev != NULL)
- prev->next = pos->next;
+ prev->next = entry->next;
else
- pmksa->pmksa = pos->next;
+ pmksa->pmksa = entry->next;
break;
}
prev = pos;
pos = pos->next;
}
+
_pmksa_cache_free_entry(entry);
}
@@ -188,6 +190,7 @@
struct rsn_pmksa_cache_entry *entry)
{
struct rsn_pmksa_cache_entry *pos, *prev;
+ int hash;
/* Add the new entry; order by expiration time */
pos = pmksa->pmksa;
@@ -205,8 +208,10 @@
entry->next = prev->next;
prev->next = entry;
}
- entry->hnext = pmksa->pmkid[PMKID_HASH(entry->pmkid)];
- pmksa->pmkid[PMKID_HASH(entry->pmkid)] = entry;
+
+ hash = PMKID_HASH(entry->pmkid);
+ entry->hnext = pmksa->pmkid[hash];
+ pmksa->pmkid[hash] = entry;
pmksa->pmksa_count++;
if (prev == NULL)
@@ -342,6 +347,8 @@
_pmksa_cache_free_entry(prev);
}
eloop_cancel_timeout(pmksa_cache_expire, pmksa, NULL);
+ pmksa->pmksa_count = 0;
+ pmksa->pmksa = NULL;
for (i = 0; i < PMKID_HASH_SIZE; i++)
pmksa->pmkid[i] = NULL;
os_free(pmksa);
@@ -361,18 +368,22 @@
{
struct rsn_pmksa_cache_entry *entry;
- if (pmkid)
- entry = pmksa->pmkid[PMKID_HASH(pmkid)];
- else
- entry = pmksa->pmksa;
- while (entry) {
- if ((spa == NULL ||
- os_memcmp(entry->spa, spa, ETH_ALEN) == 0) &&
- (pmkid == NULL ||
- os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0))
- return entry;
- entry = pmkid ? entry->hnext : entry->next;
+ if (pmkid) {
+ for (entry = pmksa->pmkid[PMKID_HASH(pmkid)]; entry;
+ entry = entry->hnext) {
+ if ((spa == NULL ||
+ os_memcmp(entry->spa, spa, ETH_ALEN) == 0) &&
+ os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0)
+ return entry;
+ }
+ } else {
+ for (entry = pmksa->pmksa; entry; entry = entry->next) {
+ if (spa == NULL ||
+ os_memcmp(entry->spa, spa, ETH_ALEN) == 0)
+ return entry;
+ }
}
+
return NULL;
}
@@ -394,15 +405,13 @@
struct rsn_pmksa_cache_entry *entry;
u8 new_pmkid[PMKID_LEN];
- entry = pmksa->pmksa;
- while (entry) {
+ for (entry = pmksa->pmksa; entry; entry = entry->next) {
if (os_memcmp(entry->spa, spa, ETH_ALEN) != 0)
continue;
rsn_pmkid(entry->pmk, entry->pmk_len, aa, spa, new_pmkid,
wpa_key_mgmt_sha256(entry->akmp));
if (os_memcmp(new_pmkid, pmkid, PMKID_LEN) == 0)
return entry;
- entry = entry->next;
}
return NULL;
}
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index 03db98f..faf32d8 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -60,6 +60,7 @@
unsigned int qos_map_enabled:1;
unsigned int remediation:1;
unsigned int hs20_deauth_requested:1;
+ unsigned int session_timeout_set:1;
u16 auth_alg;
@@ -135,6 +136,8 @@
#ifdef CONFIG_SAE
struct sae_data *sae;
#endif /* CONFIG_SAE */
+
+ u32 session_timeout; /* valid only if session_timeout_set == 1 */
};
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 2bb8aab..1a16b5c 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -1390,7 +1390,8 @@
if (version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN ||
version == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
- if (aes_wrap(sm->PTK.kek, (key_data_len - 8) / 8, buf,
+ if (aes_wrap(sm->PTK.kek, 16,
+ (key_data_len - 8) / 8, buf,
(u8 *) (key + 1))) {
os_free(hdr);
os_free(buf);
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index 8a6ca71..781f15f 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -344,7 +344,8 @@
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,
+ if (aes_wrap(r0kh->key, sizeof(r0kh->key),
+ (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
f.nonce, frame.nonce) < 0)
return -1;
@@ -459,7 +460,7 @@
WPA_PUT_LE16(&subelem[2], gsm->GN & 0x03);
subelem[4] = gsm->GTK_len;
wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, subelem + 5);
- if (aes_wrap(sm->PTK.kek, key_len / 8, key, subelem + 13)) {
+ if (aes_wrap(sm->PTK.kek, 16, key_len / 8, key, subelem + 13)) {
os_free(subelem);
return NULL;
}
@@ -491,7 +492,7 @@
wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos);
pos += 6;
*pos++ = WPA_IGTK_LEN;
- if (aes_wrap(sm->PTK.kek, WPA_IGTK_LEN / 8,
+ if (aes_wrap(sm->PTK.kek, 16, WPA_IGTK_LEN / 8,
gsm->IGTK[gsm->GN_igtk - 4], pos)) {
os_free(subelem);
return NULL;
@@ -1336,7 +1337,8 @@
frame = (struct ft_r0kh_r1kh_pull_frame *) data;
/* aes_unwrap() does not support inplace decryption, so use a temporary
* buffer for the data. */
- if (aes_unwrap(r1kh->key, (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
+ if (aes_unwrap(r1kh->key, sizeof(r1kh->key),
+ (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
frame->nonce, f.nonce) < 0) {
wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 pull "
"request from " MACSTR, MAC2STR(src_addr));
@@ -1376,7 +1378,8 @@
r.pairwise = host_to_le16(pairwise);
os_memset(r.pad, 0, sizeof(r.pad));
- if (aes_wrap(r1kh->key, (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
+ if (aes_wrap(r1kh->key, sizeof(r1kh->key),
+ (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
r.nonce, resp.nonce) < 0) {
os_memset(pmk_r0, 0, PMK_LEN);
return -1;
@@ -1464,7 +1467,8 @@
frame = (struct ft_r0kh_r1kh_resp_frame *) data;
/* aes_unwrap() does not support inplace decryption, so use a temporary
* buffer for the data. */
- if (aes_unwrap(r0kh->key, (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
+ if (aes_unwrap(r0kh->key, sizeof(r0kh->key),
+ (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
frame->nonce, f.nonce) < 0) {
wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 pull "
"response from " MACSTR, MAC2STR(src_addr));
@@ -1530,7 +1534,8 @@
frame = (struct ft_r0kh_r1kh_push_frame *) data;
/* aes_unwrap() does not support inplace decryption, so use a temporary
* buffer for the data. */
- if (aes_unwrap(r0kh->key, (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
+ if (aes_unwrap(r0kh->key, sizeof(r0kh->key),
+ (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
frame->timestamp, f.timestamp) < 0) {
wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 push from "
MACSTR, MAC2STR(src_addr));
@@ -1727,7 +1732,8 @@
WPA_PUT_LE32(f.timestamp, now.sec);
f.pairwise = host_to_le16(pairwise);
os_memset(f.pad, 0, sizeof(f.pad));
- if (aes_wrap(r1kh->key, (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
+ if (aes_wrap(r1kh->key, sizeof(r1kh->key),
+ (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
f.timestamp, frame.timestamp) < 0)
return;
diff --git a/src/common/qca-vendor.h b/src/common/qca-vendor.h
index de0b222..ad3bdfd 100644
--- a/src/common/qca-vendor.h
+++ b/src/common/qca-vendor.h
@@ -60,7 +60,7 @@
QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY = 11,
QCA_NL80211_VENDOR_SUBCMD_NAN = 12,
QCA_NL80211_VENDOR_SUBMCD_STATS_EXT = 13,
- /* 14..33 - reserved for QCA */
+ /* 14..49 - reserved for QCA */
};
diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index d91594e..4812f8d 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -345,9 +345,10 @@
* @reply_len: Length of the reply buffer
* Returns: 0 on success, -1 on failure
*
- * This function will receive a pending control interface message. This
- * function will block if no messages are available. The received response will
- * be written to reply and reply_len is set to the actual length of the reply.
+ * This function will receive a pending control interface message. The received
+ * response will be written to reply and reply_len is set to the actual length
+ * of the reply.
+
* wpa_ctrl_recv() is only used for event messages, i.e., wpa_ctrl_attach()
* must have been used to register the control interface as an event monitor.
*/
diff --git a/src/crypto/aes-unwrap.c b/src/crypto/aes-unwrap.c
index 9dd5160..ec793d9 100644
--- a/src/crypto/aes-unwrap.c
+++ b/src/crypto/aes-unwrap.c
@@ -1,5 +1,5 @@
/*
- * AES key unwrap (128-bit KEK, RFC3394)
+ * AES key unwrap (RFC3394)
*
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
*
@@ -14,26 +14,29 @@
#include "aes_wrap.h"
/**
- * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
+ * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (RFC3394)
* @kek: Key encryption key (KEK)
+ * @kek_len: Length of KEK in octets
* @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
* bytes
* @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits
* @plain: Plaintext key, n * 64 bits
* Returns: 0 on success, -1 on failure (e.g., integrity verification failed)
*/
-int aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain)
+int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
+ u8 *plain)
{
- u8 a[8], *r, b[16];
+ u8 a[8], *r, b[AES_BLOCK_SIZE];
int i, j;
void *ctx;
+ unsigned int t;
/* 1) Initialize variables. */
os_memcpy(a, cipher, 8);
r = plain;
os_memcpy(r, cipher + 8, 8 * n);
- ctx = aes_decrypt_init(kek, 16);
+ ctx = aes_decrypt_init(kek, kek_len);
if (ctx == NULL)
return -1;
@@ -48,7 +51,11 @@
r = plain + (n - 1) * 8;
for (i = n; i >= 1; i--) {
os_memcpy(b, a, 8);
- b[7] ^= n * j + i;
+ t = n * j + i;
+ b[7] ^= t;
+ b[6] ^= t >> 8;
+ b[5] ^= t >> 16;
+ b[4] ^= t >> 24;
os_memcpy(b + 8, r, 8);
aes_decrypt(ctx, b, b);
diff --git a/src/crypto/aes-wrap.c b/src/crypto/aes-wrap.c
index 89d6f94..7ed34e8 100644
--- a/src/crypto/aes-wrap.c
+++ b/src/crypto/aes-wrap.c
@@ -1,5 +1,5 @@
/*
- * AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
+ * AES Key Wrap Algorithm (RFC3394)
*
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
*
@@ -14,19 +14,21 @@
#include "aes_wrap.h"
/**
- * aes_wrap - Wrap keys with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
- * @kek: 16-octet Key encryption key (KEK)
+ * aes_wrap - Wrap keys with AES Key Wrap Algorithm (RFC3394)
+ * @kek: Key encryption key (KEK)
+ * @kek_len: Length of KEK in octets
* @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
* bytes
* @plain: Plaintext key to be wrapped, n * 64 bits
* @cipher: Wrapped key, (n + 1) * 64 bits
* Returns: 0 on success, -1 on failure
*/
-int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher)
+int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
{
- u8 *a, *r, b[16];
+ u8 *a, *r, b[AES_BLOCK_SIZE];
int i, j;
void *ctx;
+ unsigned int t;
a = cipher;
r = cipher + 8;
@@ -35,7 +37,7 @@
os_memset(a, 0xa6, 8);
os_memcpy(r, plain, 8 * n);
- ctx = aes_encrypt_init(kek, 16);
+ ctx = aes_encrypt_init(kek, kek_len);
if (ctx == NULL)
return -1;
@@ -53,7 +55,11 @@
os_memcpy(b + 8, r, 8);
aes_encrypt(ctx, b, b);
os_memcpy(a, b, 8);
- a[7] ^= n * j + i;
+ t = n * j + i;
+ a[7] ^= t;
+ a[6] ^= t >> 8;
+ a[5] ^= t >> 16;
+ a[4] ^= t >> 24;
os_memcpy(r, b + 8, 8);
r += 8;
}
diff --git a/src/crypto/aes_wrap.h b/src/crypto/aes_wrap.h
index 0433c04..6b3727c 100644
--- a/src/crypto/aes_wrap.h
+++ b/src/crypto/aes_wrap.h
@@ -1,7 +1,7 @@
/*
* AES-based functions
*
- * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
+ * - AES Key Wrap Algorithm (RFC3394)
* - One-Key CBC MAC (OMAC1) hash with AES-128
* - AES-128 CTR mode encryption
* - AES-128 EAX mode encryption/decryption
@@ -18,8 +18,10 @@
#ifndef AES_WRAP_H
#define AES_WRAP_H
-int __must_check aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher);
-int __must_check aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain);
+int __must_check aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain,
+ u8 *cipher);
+int __must_check aes_unwrap(const u8 *kek, size_t kek_len, int n,
+ const u8 *cipher, u8 *plain);
int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem,
const u8 *addr[], const size_t *len,
u8 *mac);
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 8876ebf..b4c59d1 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -40,7 +40,7 @@
static BIGNUM * get_group5_prime(void)
{
-#if OPENSSL_VERSION_NUMBER < 0x00908000
+#if OPENSSL_VERSION_NUMBER < 0x00908000 || defined(OPENSSL_IS_BORINGSSL)
static const unsigned char RFC3526_PRIME_1536[] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
@@ -130,7 +130,7 @@
}
pkey[i] = next | 1;
- DES_set_key(&pkey, &ks);
+ DES_set_key((DES_cblock *) &pkey, &ks);
DES_ecb_encrypt((DES_cblock *) clear, (DES_cblock *) cypher, &ks,
DES_ENCRYPT);
}
@@ -199,8 +199,10 @@
switch (keylen) {
case 16:
return EVP_aes_128_ecb();
+#ifndef OPENSSL_IS_BORINGSSL
case 24:
return EVP_aes_192_ecb();
+#endif /* OPENSSL_IS_BORINGSSL */
case 32:
return EVP_aes_256_ecb();
}
@@ -378,9 +380,11 @@
case 16:
cipher = EVP_aes_128_cbc();
break;
+#ifndef OPENSSL_IS_BORINGSSL
case 24:
cipher = EVP_aes_192_cbc();
break;
+#endif /* OPENSSL_IS_BORINGSSL */
case 32:
cipher = EVP_aes_256_cbc();
break;
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index d2d6600..e153422 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -38,14 +38,26 @@
#define OPENSSL_SUPPORTS_CTX_APP_DATA
#endif
-#ifdef SSL_F_SSL_SET_SESSION_TICKET_EXT
-#ifdef SSL_OP_NO_TICKET
+#if OPENSSL_VERSION_NUMBER < 0x10000000L
+/* ERR_remove_thread_state replaces ERR_remove_state and the latter is
+ * deprecated. However, OpenSSL 0.9.8 doesn't include
+ * ERR_remove_thread_state. */
+#define ERR_remove_thread_state(tid) ERR_remove_state(0)
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
/*
* Session ticket override patch was merged into OpenSSL 0.9.9 tree on
* 2008-11-15. This version uses a bit different API compared to the old patch.
*/
#define CONFIG_OPENSSL_TICKET_OVERRIDE
#endif
+
+#if defined(OPENSSL_IS_BORINGSSL)
+/* stack_index_t is the return type of OpenSSL's sk_XXX_num() functions. */
+typedef size_t stack_index_t;
+#else
+typedef int stack_index_t;
#endif
#ifdef SSL_set_tlsext_status_type
@@ -853,7 +865,7 @@
ENGINE_cleanup();
#endif /* OPENSSL_NO_ENGINE */
CRYPTO_cleanup_all_ex_data();
- ERR_remove_state(0);
+ ERR_remove_thread_state(NULL);
ERR_free_strings();
EVP_cleanup();
os_free(tls_global->ocsp_stapling_response);
@@ -1102,7 +1114,8 @@
{
GENERAL_NAME *gen;
void *ext;
- int i, found = 0;
+ int found = 0;
+ stack_index_t i;
ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
@@ -1204,6 +1217,7 @@
GENERAL_NAME *gen;
void *ext;
int i;
+ stack_index_t j;
int dns_name = 0;
X509_NAME *name;
@@ -1211,8 +1225,8 @@
ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
- for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
- gen = sk_GENERAL_NAME_value(ext, i);
+ for (j = 0; ext && j < sk_GENERAL_NAME_num(ext); j++) {
+ gen = sk_GENERAL_NAME_value(ext, j);
if (gen->type != GEN_DNS)
continue;
dns_name++;
@@ -1639,7 +1653,7 @@
if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) {
BIO *bio = BIO_from_keystore(&ca_cert[11]);
STACK_OF(X509_INFO) *stack = NULL;
- int i;
+ stack_index_t i;
if (bio) {
stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
@@ -3386,9 +3400,15 @@
* commented out unless explicitly needed for EAP-FAST in order to be able to
* build this file with unmodified openssl. */
+#ifdef OPENSSL_IS_BORINGSSL
+static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
+ STACK_OF(SSL_CIPHER) *peer_ciphers,
+ const SSL_CIPHER **cipher, void *arg)
+#else /* OPENSSL_IS_BORINGSSL */
static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
STACK_OF(SSL_CIPHER) *peer_ciphers,
SSL_CIPHER **cipher, void *arg)
+#endif /* OPENSSL_IS_BORINGSSL */
{
struct tls_connection *conn = arg;
int ret;
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 501314b..6af7294 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -411,6 +411,25 @@
*/
};
+struct hostapd_freq_params {
+ int mode;
+ int freq;
+ int channel;
+ /* for HT */
+ int ht_enabled;
+ int sec_channel_offset; /* 0 = HT40 disabled, -1 = HT40 enabled,
+ * secondary channel below primary, 1 = HT40
+ * enabled, secondary channel above primary */
+
+ /* for VHT */
+ int vht_enabled;
+
+ /* valid for both HT and VHT, center_freq2 is non-zero
+ * only for bandwidth 80 and an 80+80 channel */
+ int center_freq1, center_freq2;
+ int bandwidth;
+};
+
/**
* struct wpa_driver_associate_params - Association parameters
* Data for struct wpa_driver_ops::associate().
@@ -443,11 +462,9 @@
size_t ssid_len;
/**
- * freq - Frequency of the channel the selected AP is using
- * Frequency that the selected AP is using (in MHz as
- * reported in the scan results)
+ * freq - channel parameters
*/
- int freq;
+ struct hostapd_freq_params freq;
/**
* freq_hint - Frequency of the channel the proposed AP is using
@@ -1091,25 +1108,6 @@
size_t supp_oper_classes_len;
};
-struct hostapd_freq_params {
- int mode;
- int freq;
- int channel;
- /* for HT */
- int ht_enabled;
- int sec_channel_offset; /* 0 = HT40 disabled, -1 = HT40 enabled,
- * secondary channel below primary, 1 = HT40
- * enabled, secondary channel above primary */
-
- /* for VHT */
- int vht_enabled;
-
- /* valid for both HT and VHT, center_freq2 is non-zero
- * only for bandwidth 80 and an 80+80 channel */
- int center_freq1, center_freq2;
- int bandwidth;
-};
-
struct mac_address {
u8 addr[ETH_ALEN];
};
@@ -2503,6 +2501,7 @@
* @dialog_token: Dialog Token to use in the message (if needed)
* @status_code: Status Code or Reason Code to use (if needed)
* @peer_capab: TDLS peer capability (TDLS_PEER_* bitfield)
+ * @initiator: Is the current end the TDLS link initiator
* @buf: TDLS IEs to add to the message
* @len: Length of buf in octets
* Returns: 0 on success, negative (<0) on failure
@@ -2512,7 +2511,7 @@
*/
int (*send_tdls_mgmt)(void *priv, const u8 *dst, u8 action_code,
u8 dialog_token, u16 status_code, u32 peer_capab,
- const u8 *buf, size_t len);
+ int initiator, const u8 *buf, size_t len);
/**
* tdls_oper - Ask the driver to perform high-level TDLS operations
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 5c922a0..d030474 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -331,7 +331,7 @@
int eapol_sock; /* socket for EAPOL frames */
- struct nl_sock *rtnl_sk; /* nl_sock for NETLINK_ROUTE */
+ struct nl_handle *rtnl_sk; /* nl_sock for NETLINK_ROUTE */
int default_if_indices[16];
int *if_indices;
@@ -358,7 +358,8 @@
void *timeout_ctx);
static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
enum nl80211_iftype nlmode);
-static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss, int freq);
+static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
+ struct hostapd_freq_params *freq);
static int
wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
@@ -588,6 +589,20 @@
}
+static struct i802_bss * get_bss_ifindex(struct wpa_driver_nl80211_data *drv,
+ int ifindex)
+{
+ struct i802_bss *bss;
+
+ for (bss = drv->first_bss; bss; bss = bss->next) {
+ if (bss->ifindex == ifindex)
+ return bss;
+ }
+
+ return NULL;
+}
+
+
static void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
{
if (drv->associated)
@@ -1306,6 +1321,28 @@
"event since interface %s is marked "
"removed", drv->first_bss->ifname);
} else {
+ struct i802_bss *bss;
+ u8 addr[ETH_ALEN];
+
+ /* Re-read MAC address as it may have changed */
+ bss = get_bss_ifindex(drv, ifi->ifi_index);
+ if (bss &&
+ linux_get_ifhwaddr(drv->global->ioctl_sock,
+ bss->ifname, addr) < 0) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: %s: failed to re-read MAC address",
+ bss->ifname);
+ } else if (bss &&
+ os_memcmp(addr, bss->addr, ETH_ALEN) != 0) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Own MAC address on ifindex %d (%s) changed from "
+ MACSTR " to " MACSTR,
+ ifi->ifi_index, bss->ifname,
+ MAC2STR(bss->addr),
+ MAC2STR(addr));
+ os_memcpy(bss->addr, addr, ETH_ALEN);
+ }
+
wpa_printf(MSG_DEBUG, "nl80211: Interface up");
drv->if_disabled = 0;
wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
@@ -1688,10 +1725,7 @@
return;
ifidx = nla_get_u32(ifindex);
- for (bss = drv->first_bss; bss; bss = bss->next)
- if (bss->ifindex == ifidx)
- break;
-
+ bss = get_bss_ifindex(drv, ifidx);
if (bss == NULL) {
wpa_printf(MSG_WARNING, "nl80211: Unknown ifindex (%d) for channel switch, ignoring",
ifidx);
@@ -4938,7 +4972,7 @@
"interface %s from bridge %s: %s",
bss->ifname, bss->brname, strerror(errno));
if (drv->rtnl_sk)
- nl_socket_free(drv->rtnl_sk);
+ nl80211_handle_destroy(drv->rtnl_sk);
}
if (bss->added_bridge) {
if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
@@ -8648,9 +8682,6 @@
struct wpa_driver_associate_params *params)
{
enum nl80211_iftype nlmode, old_mode;
- struct hostapd_freq_params freq = {
- .freq = params->freq,
- };
if (params->p2p) {
wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
@@ -8665,7 +8696,7 @@
return -1;
}
- if (nl80211_set_channel(drv->first_bss, &freq, 0)) {
+ if (nl80211_set_channel(drv->first_bss, ¶ms->freq, 0)) {
if (old_mode != nlmode)
wpa_driver_nl80211_set_mode(drv->first_bss, old_mode);
nl80211_remove_monitor_interface(drv);
@@ -8719,7 +8750,7 @@
wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
- if (wpa_driver_nl80211_set_mode_ibss(drv->first_bss, params->freq)) {
+ if (wpa_driver_nl80211_set_mode_ibss(drv->first_bss, ¶ms->freq)) {
wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
"IBSS mode");
return -1;
@@ -8743,8 +8774,16 @@
os_memcpy(drv->ssid, params->ssid, params->ssid_len);
drv->ssid_len = params->ssid_len;
- wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
+ wpa_printf(MSG_DEBUG, " * freq=%d", params->freq.freq);
+ wpa_printf(MSG_DEBUG, " * ht_enabled=%d", params->freq.ht_enabled);
+ wpa_printf(MSG_DEBUG, " * sec_channel_offset=%d",
+ params->freq.sec_channel_offset);
+ wpa_printf(MSG_DEBUG, " * vht_enabled=%d", params->freq.vht_enabled);
+ wpa_printf(MSG_DEBUG, " * center_freq1=%d", params->freq.center_freq1);
+ wpa_printf(MSG_DEBUG, " * center_freq2=%d", params->freq.center_freq2);
+ wpa_printf(MSG_DEBUG, " * bandwidth=%d", params->freq.bandwidth);
+ if (nl80211_put_freq_params(msg, ¶ms->freq) < 0)
+ goto nla_put_failure;
if (params->beacon_int > 0) {
wpa_printf(MSG_DEBUG, " * beacon_int=%d", params->beacon_int);
@@ -8822,10 +8861,10 @@
params->bssid_hint);
}
- if (params->freq) {
- wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
- drv->assoc_freq = params->freq;
+ if (params->freq.freq) {
+ wpa_printf(MSG_DEBUG, " * freq=%d", params->freq.freq);
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq.freq);
+ drv->assoc_freq = params->freq.freq;
} else
drv->assoc_freq = 0;
@@ -9316,13 +9355,11 @@
}
-static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss, int freq)
+static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
+ struct hostapd_freq_params *freq)
{
- struct hostapd_freq_params freq_params;
- os_memset(&freq_params, 0, sizeof(freq_params));
- freq_params.freq = freq;
return wpa_driver_nl80211_set_mode_impl(bss, NL80211_IFTYPE_ADHOC,
- &freq_params);
+ freq);
}
@@ -11605,7 +11642,8 @@
static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
u8 dialog_token, u16 status_code,
- u32 peer_capab, const u8 *buf, size_t len)
+ u32 peer_capab, int initiator, const u8 *buf,
+ size_t len)
{
struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv;
@@ -11636,6 +11674,8 @@
*/
NLA_PUT_U32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY, peer_capab);
}
+ if (initiator)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_INITIATOR);
NLA_PUT(msg, NL80211_ATTR_IE, len, buf);
return send_and_recv_msgs(drv, msg, NULL, NULL);
diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c
index 3608b52..66edfa7 100644
--- a/src/drivers/driver_test.c
+++ b/src/drivers/driver_test.c
@@ -1478,7 +1478,7 @@
struct wpa_driver_test_data *drv = dbss->drv;
wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d "
"group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d",
- __func__, priv, params->freq, params->pairwise_suite,
+ __func__, priv, params->freq.freq, params->pairwise_suite,
params->group_suite, params->key_mgmt_suite,
params->auth_alg, params->mode);
wpa_driver_update_mode(drv, params->mode == IEEE80211_MODE_AP);
diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c
index 459ac48..1b3a757 100644
--- a/src/drivers/driver_wext.c
+++ b/src/drivers/driver_wext.c
@@ -2119,7 +2119,8 @@
if (wpa_driver_wext_set_auth_param(drv, IW_AUTH_MFP, value) < 0)
ret = -1;
#endif /* CONFIG_IEEE80211W */
- if (params->freq && wpa_driver_wext_set_freq(drv, params->freq) < 0)
+ if (params->freq.freq &&
+ wpa_driver_wext_set_freq(drv, params->freq.freq) < 0)
ret = -1;
if (!drv->cfg80211 &&
wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0)
diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
index 406010d..4b28dc0 100644
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -503,6 +503,9 @@
* TX status event pertaining to the TX request.
* %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
* management frames at CCK rate or not in 2GHz band.
+ * %NL80211_ATTR_CSA_C_OFFSETS_TX is an array of offsets to CSA
+ * counters which will be updated to the current value. This attribute
+ * is used during CSA period.
* @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this
* command may be used with the corresponding cookie to cancel the wait
* time if it is known that it is no longer necessary.
@@ -719,6 +722,22 @@
* QoS mapping is relevant for IP packets, it is only valid during an
* association. This is cleared on disassociation and AP restart.
*
+ * @NL80211_CMD_ADD_TX_TS: Ask the kernel to add a traffic stream for the given
+ * %NL80211_ATTR_TSID and %NL80211_ATTR_MAC with %NL80211_ATTR_USER_PRIO
+ * and %NL80211_ATTR_ADMITTED_TIME parameters.
+ * Note that the action frame handshake with the AP shall be handled by
+ * userspace via the normal management RX/TX framework, this only sets
+ * up the TX TS in the driver/device.
+ * If the admitted time attribute is not added then the request just checks
+ * if a subsequent setup could be successful, the intent is to use this to
+ * avoid setting up a session with the AP when local restrictions would
+ * make that impossible. However, the subsequent "real" setup may still
+ * fail even if the check was successful.
+ * @NL80211_CMD_DEL_TX_TS: Remove an existing TS with the %NL80211_ATTR_TSID
+ * and %NL80211_ATTR_MAC parameters. It isn't necessary to call this
+ * before removing a station entry entirely, or before disassociating
+ * or similar, cleanup will happen in the driver/device in this case.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -890,6 +909,9 @@
NL80211_CMD_SET_QOS_MAP,
+ NL80211_CMD_ADD_TX_TS,
+ NL80211_CMD_DEL_TX_TS,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -1525,10 +1547,10 @@
* operation).
* @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
* for the time while performing a channel switch.
- * @NL80211_ATTR_CSA_C_OFF_BEACON: Offset of the channel switch counter
- * field in the beacons tail (%NL80211_ATTR_BEACON_TAIL).
- * @NL80211_ATTR_CSA_C_OFF_PRESP: Offset of the channel switch counter
- * field in the probe response (%NL80211_ATTR_PROBE_RESP).
+ * @NL80211_ATTR_CSA_C_OFF_BEACON: An array of offsets (u16) to the channel
+ * switch counters in the beacons tail (%NL80211_ATTR_BEACON_TAIL).
+ * @NL80211_ATTR_CSA_C_OFF_PRESP: An array of offsets (u16) to the channel
+ * switch counters in the probe response (%NL80211_ATTR_PROBE_RESP).
*
* @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32.
* As specified in the &enum nl80211_rxmgmt_flags.
@@ -1576,6 +1598,11 @@
* advertise values that cannot always be met. In such cases, an attempt
* to add a new station entry with @NL80211_CMD_NEW_STATION may fail.
*
+ * @NL80211_ATTR_CSA_C_OFFSETS_TX: An array of csa counter offsets (u16) which
+ * should be updated when the frame is transmitted.
+ * @NL80211_ATTR_MAX_CSA_COUNTERS: U8 attribute used to advertise the maximum
+ * supported number of csa counters.
+ *
* @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32.
* As specified in the &enum nl80211_tdls_peer_capability.
*
@@ -1583,6 +1610,34 @@
* creation then the new interface will be owned by the netlink socket
* that created it and will be destroyed when the socket is closed
*
+ * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is
+ * the TDLS link initiator.
+ *
+ * @NL80211_ATTR_USE_RRM: flag for indicating whether the current connection
+ * shall support Radio Resource Measurements (11k). This attribute can be
+ * used with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests.
+ * User space applications are expected to use this flag only if the
+ * underlying device supports these minimal RRM features:
+ * %NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES,
+ * %NL80211_FEATURE_QUIET,
+ * If this flag is used, driver must add the Power Capabilities IE to the
+ * association request. In addition, it must also set the RRM capability
+ * flag in the association request's Capability Info field.
+ *
+ * @NL80211_ATTR_WIPHY_DYN_ACK: flag attribute used to enable ACK timeout
+ * estimation algorithm (dynack). In order to activate dynack
+ * %NL80211_FEATURE_ACKTO_ESTIMATION feature flag must be set by lower
+ * drivers to indicate dynack capability. Dynack is automatically disabled
+ * setting valid value for coverage class.
+ *
+ * @NL80211_ATTR_TSID: a TSID value (u8 attribute)
+ * @NL80211_ATTR_USER_PRIO: user priority value (u8 attribute)
+ * @NL80211_ATTR_ADMITTED_TIME: admitted time in units of 32 microseconds
+ * (per second) (u16 attribute)
+ *
+ * @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see
+ * &enum nl80211_smps_mode.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1920,6 +1975,21 @@
NL80211_ATTR_IFACE_SOCKET_OWNER,
+ NL80211_ATTR_CSA_C_OFFSETS_TX,
+ NL80211_ATTR_MAX_CSA_COUNTERS,
+
+ NL80211_ATTR_TDLS_INITIATOR,
+
+ NL80211_ATTR_USE_RRM,
+
+ NL80211_ATTR_WIPHY_DYN_ACK,
+
+ NL80211_ATTR_TSID,
+ NL80211_ATTR_USER_PRIO,
+ NL80211_ATTR_ADMITTED_TIME,
+
+ NL80211_ATTR_SMPS_MODE,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -2188,6 +2258,8 @@
* Contains a nested array of signal strength attributes (u8, dBm)
* @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
* Same format as NL80211_STA_INFO_CHAIN_SIGNAL.
+ * @NL80211_STA_EXPECTED_THROUGHPUT: expected throughput considering also the
+ * 802.11 header (u32, kbps)
* @__NL80211_STA_INFO_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribute
*/
@@ -2219,6 +2291,7 @@
NL80211_STA_INFO_TX_BYTES64,
NL80211_STA_INFO_CHAIN_SIGNAL,
NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
+ NL80211_STA_INFO_EXPECTED_THROUGHPUT,
/* keep last */
__NL80211_STA_INFO_AFTER_LAST,
@@ -3036,14 +3109,20 @@
* @NL80211_BSS_BSSID: BSSID of the BSS (6 octets)
* @NL80211_BSS_FREQUENCY: frequency in MHz (u32)
* @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64)
+ * (if @NL80211_BSS_PRESP_DATA is present then this is known to be
+ * from a probe response, otherwise it may be from the same beacon
+ * that the NL80211_BSS_BEACON_TSF will be from)
* @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16)
* @NL80211_BSS_CAPABILITY: capability field (CPU order, u16)
* @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the
* raw information elements from the probe response/beacon (bin);
- * if the %NL80211_BSS_BEACON_IES attribute is present, the IEs here are
- * from a Probe Response frame; otherwise they are from a Beacon frame.
+ * if the %NL80211_BSS_BEACON_IES attribute is present and the data is
+ * different then the IEs here are from a Probe Response frame; otherwise
+ * they are from a Beacon frame.
* However, if the driver does not indicate the source of the IEs, these
* IEs may be from either frame subtype.
+ * If present, the @NL80211_BSS_PRESP_DATA attribute indicates that the
+ * data here is known to be from a probe response, without any heuristics.
* @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon
* in mBm (100 * dBm) (s32)
* @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon
@@ -3055,6 +3134,10 @@
* yet been received
* @NL80211_BSS_CHAN_WIDTH: channel width of the control channel
* (u32, enum nl80211_bss_scan_width)
+ * @NL80211_BSS_BEACON_TSF: TSF of the last received beacon (u64)
+ * (not present if no beacon frame has been received yet)
+ * @NL80211_BSS_PRESP_DATA: the data in @NL80211_BSS_INFORMATION_ELEMENTS and
+ * @NL80211_BSS_TSF is known to be from a probe response (flag attribute)
* @__NL80211_BSS_AFTER_LAST: internal
* @NL80211_BSS_MAX: highest BSS attribute
*/
@@ -3072,6 +3155,8 @@
NL80211_BSS_SEEN_MS_AGO,
NL80211_BSS_BEACON_IES,
NL80211_BSS_CHAN_WIDTH,
+ NL80211_BSS_BEACON_TSF,
+ NL80211_BSS_PRESP_DATA,
/* keep last */
__NL80211_BSS_AFTER_LAST,
@@ -3688,6 +3773,8 @@
* different channels may be used within this group.
* @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap
* of supported channel widths for radar detection.
+ * @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap
+ * of supported regulatory regions for radar detection.
* @NUM_NL80211_IFACE_COMB: number of attributes
* @MAX_NL80211_IFACE_COMB: highest attribute number
*
@@ -3721,6 +3808,7 @@
NL80211_IFACE_COMB_STA_AP_BI_MATCH,
NL80211_IFACE_COMB_NUM_CHANNELS,
NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
+ NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
/* keep last */
NUM_NL80211_IFACE_COMB,
@@ -3894,6 +3982,8 @@
* @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested
* to work properly to suppport receiving regulatory hints from
* cellular base stations.
+ * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: (no longer available, only
+ * here to reserve the value for API/ABI compatibility)
* @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of
* equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station
* mode
@@ -3932,13 +4022,33 @@
* @NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE: This driver supports dynamic
* channel bandwidth change (e.g., HT 20 <-> 40 MHz channel) during the
* lifetime of a BSS.
+ * @NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES: This device adds a DS Parameter
+ * Set IE to probe requests.
+ * @NL80211_FEATURE_WFA_TPC_IE_IN_PROBES: This device adds a WFA TPC Report IE
+ * to probe requests.
+ * @NL80211_FEATURE_QUIET: This device, in client mode, supports Quiet Period
+ * requests sent to it by an AP.
+ * @NL80211_FEATURE_TX_POWER_INSERTION: This device is capable of inserting the
+ * current tx power value into the TPC Report IE in the spectrum
+ * management TPC Report action frame, and in the Radio Measurement Link
+ * Measurement Report action frame.
+ * @NL80211_FEATURE_ACKTO_ESTIMATION: This driver supports dynamic ACK timeout
+ * estimation (dynack). %NL80211_ATTR_WIPHY_DYN_ACK flag attribute is used
+ * to enable dynack.
+ * @NL80211_FEATURE_STATIC_SMPS: Device supports static spatial
+ * multiplexing powersave, ie. can turn off all but one chain
+ * even on HT connections that should be using more chains.
+ * @NL80211_FEATURE_DYNAMIC_SMPS: Device supports dynamic spatial
+ * multiplexing powersave, ie. can turn off all but one chain
+ * and then wake the rest up as required after, for example,
+ * rts/cts handshake.
*/
enum nl80211_feature_flags {
NL80211_FEATURE_SK_TX_STATUS = 1 << 0,
NL80211_FEATURE_HT_IBSS = 1 << 1,
NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2,
NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3,
- /* bit 4 is reserved - don't use */
+ NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4,
NL80211_FEATURE_SAE = 1 << 5,
NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6,
NL80211_FEATURE_SCAN_FLUSH = 1 << 7,
@@ -3953,6 +4063,13 @@
NL80211_FEATURE_USERSPACE_MPM = 1 << 16,
NL80211_FEATURE_ACTIVE_MONITOR = 1 << 17,
NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE = 1 << 18,
+ NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES = 1 << 19,
+ NL80211_FEATURE_WFA_TPC_IE_IN_PROBES = 1 << 20,
+ NL80211_FEATURE_QUIET = 1 << 21,
+ NL80211_FEATURE_TX_POWER_INSERTION = 1 << 22,
+ NL80211_FEATURE_ACKTO_ESTIMATION = 1 << 23,
+ NL80211_FEATURE_STATIC_SMPS = 1 << 24,
+ NL80211_FEATURE_DYNAMIC_SMPS = 1 << 25,
};
/**
@@ -4027,6 +4144,25 @@
};
/**
+ * enum nl80211_smps_mode - SMPS mode
+ *
+ * Requested SMPS mode (for AP mode)
+ *
+ * @NL80211_SMPS_OFF: SMPS off (use all antennas).
+ * @NL80211_SMPS_STATIC: static SMPS (use a single antenna)
+ * @NL80211_SMPS_DYNAMIC: dynamic smps (start with a single antenna and
+ * turn on other antennas after CTS/RTS).
+ */
+enum nl80211_smps_mode {
+ NL80211_SMPS_OFF,
+ NL80211_SMPS_STATIC,
+ NL80211_SMPS_DYNAMIC,
+
+ __NL80211_SMPS_AFTER_LAST,
+ NL80211_SMPS_MAX = __NL80211_SMPS_AFTER_LAST - 1
+};
+
+/**
* enum nl80211_radar_event - type of radar event for DFS operation
*
* Type of event to be used with NL80211_ATTR_RADAR_EVENT to inform userspace
diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c
index fdcff7f..631c363 100644
--- a/src/eap_common/eap_pwd_common.c
+++ b/src/eap_common/eap_pwd_common.c
@@ -106,9 +106,11 @@
case 21:
nid = NID_secp521r1;
break;
+#ifndef OPENSSL_IS_BORINGSSL
case 25:
nid = NID_X9_62_prime192v1;
break;
+#endif /* OPENSSL_IS_BORINGSSL */
case 26:
nid = NID_secp224r1;
break;
diff --git a/src/eap_server/eap_server_fast.c b/src/eap_server/eap_server_fast.c
index 4691e72..2692bce 100644
--- a/src/eap_server/eap_server_fast.c
+++ b/src/eap_server/eap_server_fast.c
@@ -161,8 +161,8 @@
return 0;
}
- if (aes_unwrap(data->pac_opaque_encr, (pac_opaque_len - 8) / 8,
- pac_opaque, buf) < 0) {
+ if (aes_unwrap(data->pac_opaque_encr, sizeof(data->pac_opaque_encr),
+ (pac_opaque_len - 8) / 8, pac_opaque, buf) < 0) {
wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to decrypt "
"PAC-Opaque");
os_free(buf);
@@ -731,8 +731,8 @@
os_free(pac_buf);
return NULL;
}
- if (aes_wrap(data->pac_opaque_encr, pac_len / 8, pac_buf,
- pac_opaque) < 0) {
+ if (aes_wrap(data->pac_opaque_encr, sizeof(data->pac_opaque_encr),
+ pac_len / 8, pac_buf, pac_opaque) < 0) {
os_free(pac_buf);
os_free(pac_opaque);
return NULL;
diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 56c195a..b1cf32d 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -1451,7 +1451,7 @@
os_memcpy(body->sak, cipher_suite_tbl[cs_index].id, CS_ID_LEN);
sak_pos = CS_ID_LEN;
}
- if (aes_wrap(participant->kek.key,
+ if (aes_wrap(participant->kek.key, 16,
cipher_suite_tbl[cs_index].sak_len / 8,
sak->key, body->sak + sak_pos)) {
wpa_printf(MSG_ERROR, "KaY: AES wrap failed");
@@ -1611,7 +1611,7 @@
wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
return -1;
}
- if (aes_unwrap(participant->kek.key, sak_len >> 3, wrap_sak,
+ if (aes_unwrap(participant->kek.key, 16, sak_len >> 3, wrap_sak,
unwrap_sak)) {
wpa_printf(MSG_ERROR, "KaY: AES unwrap failed");
os_free(unwrap_sak);
diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c
index b5a87fc..885291a 100644
--- a/src/rsn_supp/pmksa_cache.c
+++ b/src/rsn_supp/pmksa_cache.c
@@ -35,7 +35,7 @@
static void _pmksa_cache_free_entry(struct rsn_pmksa_cache_entry *entry)
{
- os_free(entry);
+ bin_clear_free(entry, sizeof(*entry));
}
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 93ae143..8cb19a2 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -218,26 +218,29 @@
static int wpa_tdls_send_tpk_msg(struct wpa_sm *sm, const u8 *dst,
u8 action_code, u8 dialog_token,
u16 status_code, u32 peer_capab,
- const u8 *buf, size_t len)
+ int initiator, const u8 *buf, size_t len)
{
return wpa_sm_send_tdls_mgmt(sm, dst, action_code, dialog_token,
- status_code, peer_capab, buf, len);
+ status_code, peer_capab, initiator, buf,
+ len);
}
static int wpa_tdls_tpk_send(struct wpa_sm *sm, const u8 *dest, u8 action_code,
u8 dialog_token, u16 status_code, u32 peer_capab,
- const u8 *msg, size_t msg_len)
+ int initiator, const u8 *msg, size_t msg_len)
{
struct wpa_tdls_peer *peer;
wpa_printf(MSG_DEBUG, "TDLS: TPK send dest=" MACSTR " action_code=%u "
- "dialog_token=%u status_code=%u peer_capab=%u msg_len=%u",
+ "dialog_token=%u status_code=%u peer_capab=%u initiator=%d "
+ "msg_len=%u",
MAC2STR(dest), action_code, dialog_token, status_code,
- peer_capab, (unsigned int) msg_len);
+ peer_capab, initiator, (unsigned int) msg_len);
if (wpa_tdls_send_tpk_msg(sm, dest, action_code, dialog_token,
- status_code, peer_capab, msg, msg_len)) {
+ status_code, peer_capab, initiator, msg,
+ msg_len)) {
wpa_printf(MSG_INFO, "TDLS: Failed to send message "
"(action_code=%u)", action_code);
return -1;
@@ -333,6 +336,7 @@
peer->sm_tmr.dialog_token,
peer->sm_tmr.status_code,
peer->sm_tmr.peer_capab,
+ peer->initiator,
peer->sm_tmr.buf,
peer->sm_tmr.buf_len)) {
wpa_printf(MSG_INFO, "TDLS: Failed to retry "
@@ -793,7 +797,7 @@
/* request driver to send Teardown using this FTIE */
wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_TEARDOWN, 0,
- reason_code, 0, rbuf, pos - rbuf);
+ reason_code, 0, peer->initiator, rbuf, pos - rbuf);
os_free(rbuf);
return 0;
@@ -968,17 +972,19 @@
* appropriate status code mentioning reason for error/failure.
* @dst - MAC addr of Peer station
* @tdls_action - TDLS frame type for which error code is sent
+ * @initiator - was this end the initiator of the connection
* @status - status code mentioning reason
*/
static int wpa_tdls_send_error(struct wpa_sm *sm, const u8 *dst,
- u8 tdls_action, u8 dialog_token, u16 status)
+ u8 tdls_action, u8 dialog_token, int initiator,
+ u16 status)
{
wpa_printf(MSG_DEBUG, "TDLS: Sending error to " MACSTR
" (action=%u status=%u)",
MAC2STR(dst), tdls_action, status);
return wpa_tdls_tpk_send(sm, dst, tdls_action, dialog_token, status,
- 0, NULL, 0);
+ 0, initiator, NULL, 0);
}
@@ -1184,7 +1190,7 @@
MAC2STR(peer->addr));
status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST,
- 1, 0, 0, rbuf, pos - rbuf);
+ 1, 0, 0, peer->initiator, rbuf, pos - rbuf);
os_free(rbuf);
return status;
@@ -1274,7 +1280,8 @@
skip_ies:
status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE,
- dtoken, 0, 0, rbuf, pos - rbuf);
+ dtoken, 0, 0, peer->initiator, rbuf,
+ pos - rbuf);
os_free(rbuf);
return status;
@@ -1371,7 +1378,8 @@
peer_capab |= TDLS_PEER_WMM;
status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM,
- dtoken, 0, peer_capab, rbuf, pos - rbuf);
+ dtoken, 0, peer_capab, peer->initiator,
+ rbuf, pos - rbuf);
os_free(rbuf);
return status;
@@ -1457,7 +1465,7 @@
wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime);
skip_ies:
status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_DISCOVERY_RESPONSE,
- dialog_token, 0, 0, rbuf, pos - rbuf);
+ dialog_token, 0, 0, 0, rbuf, pos - rbuf);
os_free(rbuf);
return status;
@@ -1528,7 +1536,7 @@
wpa_printf(MSG_DEBUG, "TDLS: Sending Discovery Request to peer "
MACSTR, MAC2STR(addr));
return wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_DISCOVERY_REQUEST,
- 1, 0, 0, NULL, 0);
+ 1, 0, 0, 1, NULL, 0);
}
@@ -1713,8 +1721,8 @@
peer->supp_rates, peer->supp_rates_len,
peer->ht_capabilities,
peer->vht_capabilities,
- peer->qos_info, peer->ext_capab,
- peer->ext_capab_len,
+ peer->qos_info, peer->wmm_capable,
+ peer->ext_capab, peer->ext_capab_len,
peer->supp_channels,
peer->supp_channels_len,
peer->supp_oper_classes,
@@ -1858,6 +1866,8 @@
wpa_printf(MSG_DEBUG, "TDLS: Testing concurrent initiation of "
"TDLS setup - send own request");
peer->initiator = 1;
+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL,
+ NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0);
wpa_tdls_send_tpk_m1(sm, peer);
}
@@ -2036,10 +2046,18 @@
wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);
skip_rsn_check:
+#ifdef CONFIG_TDLS_TESTING
+ if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT)
+ goto skip_add_peer;
+#endif /* CONFIG_TDLS_TESTING */
+
/* add supported rates, capabilities, and qos_info to the TDLS peer */
if (wpa_tdls_addset_peer(sm, peer, 1) < 0)
goto error;
+#ifdef CONFIG_TDLS_TESTING
+skip_add_peer:
+#endif /* CONFIG_TDLS_TESTING */
peer->tpk_in_progress = 1;
wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
@@ -2051,7 +2069,7 @@
return 0;
error:
- wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken,
+ wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken, 0,
status);
if (peer)
wpa_tdls_peer_free(sm, peer);
@@ -2362,7 +2380,7 @@
return ret;
error:
- wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken,
+ wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken, 1,
status);
wpa_tdls_disable_peer_link(sm, peer);
return -1;
@@ -2587,7 +2605,7 @@
/* add the peer to the driver as a "setup in progress" peer */
if (wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL,
- NULL, 0, NULL, 0, NULL, 0, NULL, 0)) {
+ NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0)) {
wpa_tdls_disable_peer_link(sm, peer);
return -1;
}
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 9471071..b17fc88 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -1295,7 +1295,8 @@
(unsigned long) maxkeylen);
return -1;
}
- if (aes_unwrap(sm->ptk.kek, maxkeylen / 8, key_data, gd->gtk)) {
+ if (aes_unwrap(sm->ptk.kek, 16, maxkeylen / 8, key_data,
+ gd->gtk)) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: AES unwrap failed - could not decrypt "
"GTK");
@@ -1503,7 +1504,7 @@
"WPA: No memory for AES-UNWRAP buffer");
return -1;
}
- if (aes_unwrap(sm->ptk.kek, *key_data_len / 8,
+ if (aes_unwrap(sm->ptk.kek, 16, *key_data_len / 8,
key_data, buf)) {
os_free(buf);
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 07a7bf9..63032b0 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -55,14 +55,14 @@
int (*send_tdls_mgmt)(void *ctx, const u8 *dst,
u8 action_code, u8 dialog_token,
u16 status_code, u32 peer_capab,
- const u8 *buf, size_t len);
+ int initiator, const u8 *buf, size_t len);
int (*tdls_oper)(void *ctx, int oper, const u8 *peer);
int (*tdls_peer_addset)(void *ctx, const u8 *addr, int add, u16 aid,
u16 capability, const u8 *supp_rates,
size_t supp_rates_len,
const struct ieee80211_ht_capabilities *ht_capab,
const struct ieee80211_vht_capabilities *vht_capab,
- u8 qosinfo, const u8 *ext_capab,
+ u8 qosinfo, int wmm, const u8 *ext_capab,
size_t ext_capab_len, const u8 *supp_channels,
size_t supp_channels_len,
const u8 *supp_oper_classes,
diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c
index 4a75b92..3b3c9d0 100644
--- a/src/rsn_supp/wpa_ft.c
+++ b/src/rsn_supp/wpa_ft.c
@@ -566,7 +566,7 @@
return -1;
}
gtk_len = gtk_elem_len - 19;
- if (aes_unwrap(sm->ptk.kek, gtk_len / 8, gtk_elem + 11, gtk)) {
+ if (aes_unwrap(sm->ptk.kek, 16, gtk_len / 8, gtk_elem + 11, gtk)) {
wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not "
"decrypt GTK");
return -1;
@@ -645,7 +645,8 @@
return -1;
}
- if (aes_unwrap(sm->ptk.kek, WPA_IGTK_LEN / 8, igtk_elem + 9, igtk)) {
+ if (aes_unwrap(sm->ptk.kek, 16, WPA_IGTK_LEN / 8, igtk_elem + 9, igtk))
+ {
wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not "
"decrypt IGTK");
return -1;
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index e20e9da..839b545 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -268,12 +268,14 @@
static inline int wpa_sm_send_tdls_mgmt(struct wpa_sm *sm, const u8 *dst,
u8 action_code, u8 dialog_token,
u16 status_code, u32 peer_capab,
- const u8 *buf, size_t len)
+ int initiator, const u8 *buf,
+ size_t len)
{
if (sm->ctx->send_tdls_mgmt)
return sm->ctx->send_tdls_mgmt(sm->ctx->ctx, dst, action_code,
dialog_token, status_code,
- peer_capab, buf, len);
+ peer_capab, initiator, buf,
+ len);
return -1;
}
@@ -291,16 +293,16 @@
size_t supp_rates_len,
const struct ieee80211_ht_capabilities *ht_capab,
const struct ieee80211_vht_capabilities *vht_capab,
- u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len,
- const u8 *supp_channels, size_t supp_channels_len,
- const u8 *supp_oper_classes,
+ u8 qosinfo, int wmm, const u8 *ext_capab,
+ size_t ext_capab_len, const u8 *supp_channels,
+ size_t supp_channels_len, const u8 *supp_oper_classes,
size_t supp_oper_classes_len)
{
if (sm->ctx->tdls_peer_addset)
return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add,
aid, capability, supp_rates,
supp_rates_len, ht_capab,
- vht_capab, qosinfo,
+ vht_capab, qosinfo, wmm,
ext_capab, ext_capab_len,
supp_channels,
supp_channels_len,
diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c
index 2329033..93e8cf6 100644
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
@@ -549,7 +549,7 @@
ie->ht_capabilities_len = pos[1];
} else if (*pos == WLAN_EID_VHT_AID) {
if (pos[1] >= 2)
- ie->aid = WPA_GET_LE16(pos + 2);
+ ie->aid = WPA_GET_LE16(pos + 2) & 0x3fff;
} else if (*pos == WLAN_EID_VHT_CAP) {
ie->vht_capabilities = pos + 2;
ie->vht_capabilities_len = pos[1];
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index f9aa807..7c93498 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -513,7 +513,7 @@
}
if (ssid->frequency == 0)
ssid->frequency = 2462; /* default channel 11 */
- params.freq = ssid->frequency;
+ params.freq.freq = ssid->frequency;
params.wpa_proto = ssid->proto;
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 54cd1ec..98d3ce4 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -6437,7 +6437,7 @@
wpa_s->vendor_elem[frame] = NULL;
} else {
os_memmove(ie, ie + len,
- wpabuf_len(wpa_s->vendor_elem[frame]) - len);
+ end - (ie + len));
wpa_s->vendor_elem[frame]->used -= len;
}
os_free(buf);
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 3d22552..5e58c5b 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2961,6 +2961,10 @@
wpas_dbus_getter_process_credentials,
wpas_dbus_setter_process_credentials
},
+ { "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
+ wpas_dbus_getter_config_methods,
+ wpas_dbus_setter_config_methods
+ },
#endif /* CONFIG_WPS */
#ifdef CONFIG_P2P
{ "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 51cf5f3..f6a83cd 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -298,6 +298,14 @@
DBusError *error,
void *user_data);
+dbus_bool_t wpas_dbus_getter_config_methods(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
+
+dbus_bool_t wpas_dbus_setter_config_methods(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
+
DBusMessage * wpas_dbus_handler_tdls_discover(DBusMessage *message,
struct wpa_supplicant *wpa_s);
DBusMessage * wpas_dbus_handler_tdls_setup(DBusMessage *message,
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
index 4ad5e7e..8ecf7db 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
@@ -389,3 +389,60 @@
return TRUE;
}
+
+
+/**
+ * wpas_dbus_getter_config_methods - Get current WPS configuration methods
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
+ *
+ * Getter for "ConfigMethods" property. Returned boolean will be true if
+ * providing the relevant string worked, or false otherwise.
+ */
+dbus_bool_t wpas_dbus_getter_config_methods(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
+{
+ struct wpa_supplicant *wpa_s = user_data;
+ char *methods = wpa_s->conf->config_methods;
+
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+ &methods, error);
+}
+
+
+/**
+ * wpas_dbus_setter_config_methods - Set WPS configuration methods
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
+ *
+ * Setter for "ConfigMethods" property. Sets the methods string, apply such
+ * change and returns true on success. Returns false otherwise.
+ */
+dbus_bool_t wpas_dbus_setter_config_methods(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
+{
+ struct wpa_supplicant *wpa_s = user_data;
+ char *methods, *new_methods;
+
+ if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
+ &methods))
+ return FALSE;
+
+ new_methods = os_strdup(methods);
+ if (!new_methods)
+ return FALSE;
+
+ os_free(wpa_s->conf->config_methods);
+ wpa_s->conf->config_methods = new_methods;
+
+ wpa_s->conf->changed_parameters |= CFG_CHANGED_CONFIG_METHODS;
+ wpa_supplicant_update_config(wpa_s);
+
+ return TRUE;
+}
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index cba32a9..649de9b 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -532,14 +532,14 @@
static inline int wpa_drv_send_tdls_mgmt(struct wpa_supplicant *wpa_s,
const u8 *dst, u8 action_code,
u8 dialog_token, u16 status_code,
- u32 peer_capab, const u8 *buf,
- size_t len)
+ u32 peer_capab, int initiator,
+ const u8 *buf, size_t len)
{
if (wpa_s->driver->send_tdls_mgmt) {
return wpa_s->driver->send_tdls_mgmt(wpa_s->drv_priv, dst,
action_code, dialog_token,
status_code, peer_capab,
- buf, len);
+ initiator, buf, len);
}
return -1;
}
diff --git a/wpa_supplicant/eap_proxy_dummy.mak b/wpa_supplicant/eap_proxy_dummy.mak
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/wpa_supplicant/eap_proxy_dummy.mak
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 081b585..985fa6e 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -582,7 +582,7 @@
}
-static int ht_supported(const struct hostapd_hw_modes *mode)
+int ht_supported(const struct hostapd_hw_modes *mode)
{
if (!(mode->flags & HOSTAPD_MODE_FLAG_HT_INFO_KNOWN)) {
/*
@@ -600,7 +600,7 @@
}
-static int vht_supported(const struct hostapd_hw_modes *mode)
+int vht_supported(const struct hostapd_hw_modes *mode)
{
if (!(mode->flags & HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN)) {
/*
diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
index d2e839d..e596468 100644
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -331,7 +331,8 @@
if (wpa_s->global->p2p == NULL &&
(wpa_s->drv_flags &
WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
- wpas_p2p_add_p2pdev_interface(wpa_s) < 0)
+ wpas_p2p_add_p2pdev_interface(wpa_s, iface->conf_p2p_dev) <
+ 0)
exitcode = -1;
#endif /* CONFIG_P2P */
}
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index ca45b5b..640154c 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -3786,7 +3786,8 @@
}
-int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s)
+int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s,
+ const char *conf_p2p_dev)
{
struct wpa_interface iface;
struct wpa_supplicant *p2pdev_wpa_s;
@@ -3817,8 +3818,8 @@
* If a P2P Device configuration file was given, use it as the interface
* configuration file (instead of using parent's configuration file.
*/
- if (wpa_s->conf_p2p_dev) {
- iface.confname = wpa_s->conf_p2p_dev;
+ if (conf_p2p_dev) {
+ iface.confname = conf_p2p_dev;
iface.ctrl_interface = NULL;
} else {
iface.confname = wpa_s->confname;
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index d79ec03..8e23c18 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -16,7 +16,8 @@
struct p2p_channels;
struct wps_event_fail;
-int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s);
+int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s,
+ const char *conf_p2p_dev);
struct wpa_supplicant * wpas_get_p2p_go_iface(struct wpa_supplicant *wpa_s,
const u8 *ssid, size_t ssid_len);
struct wpa_supplicant * wpas_get_p2p_client_iface(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index e4f2d12..36b4f87 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -742,7 +742,7 @@
params.bssid = bssid;
params.ssid = wpa_s->sme.ssid;
params.ssid_len = wpa_s->sme.ssid_len;
- params.freq = wpa_s->sme.freq;
+ params.freq.freq = wpa_s->sme.freq;
params.bg_scan_period = wpa_s->current_ssid ?
wpa_s->current_ssid->bg_scan_period : -1;
params.wpa_ie = wpa_s->sme.assoc_req_ie_len ?
@@ -780,7 +780,7 @@
wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
" (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "",
- params.freq);
+ params.freq.freq);
wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index d128992..397d2f6 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -406,11 +406,6 @@
os_free(wpa_s->confanother);
wpa_s->confanother = NULL;
-#ifdef CONFIG_P2P
- os_free(wpa_s->conf_p2p_dev);
- wpa_s->conf_p2p_dev = NULL;
-#endif /* CONFIG_P2P */
-
wpa_sm_set_eapol(wpa_s->wpa, NULL);
eapol_sm_deinit(wpa_s->eapol);
wpa_s->eapol = NULL;
@@ -1843,7 +1838,7 @@
MAC2STR(bss->bssid), bss->freq,
ssid->bssid_set);
params.bssid = bss->bssid;
- params.freq = bss->freq;
+ params.freq.freq = bss->freq;
}
params.bssid_hint = bss->bssid;
params.freq_hint = bss->freq;
@@ -1859,8 +1854,23 @@
}
if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
- params.freq == 0)
- params.freq = ssid->frequency; /* Initial channel for IBSS */
+ 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;
+ }
+ }
+ }
if (ssid->mode == WPAS_MODE_IBSS) {
if (ssid->beacon_int)
@@ -1944,13 +1954,12 @@
if (wpa_s->num_multichan_concurrent < 2) {
int freq, num;
num = get_shared_radio_freqs(wpa_s, &freq, 1);
- if (num > 0 && freq > 0 && freq != params.freq) {
+ if (num > 0 && freq > 0 && freq != params.freq.freq) {
wpa_printf(MSG_DEBUG,
"Assoc conflicting freq found (%d != %d)",
- freq, params.freq);
- if (wpas_p2p_handle_frequency_conflicts(wpa_s,
- params.freq,
- ssid) < 0)
+ freq, params.freq.freq);
+ if (wpas_p2p_handle_frequency_conflicts(
+ wpa_s, params.freq.freq, ssid) < 0)
return;
}
}
@@ -3601,13 +3610,6 @@
wpa_s->confanother = os_rel2abs_path(iface->confanother);
wpa_config_read(wpa_s->confanother, wpa_s->conf);
-#ifdef CONFIG_P2P
- wpa_s->conf_p2p_dev = os_rel2abs_path(iface->conf_p2p_dev);
-#ifndef ANDROID_P2P
- wpa_config_read(wpa_s->conf_p2p_dev, wpa_s->conf);
-#endif
-#endif /* CONFIG_P2P */
-
/*
* Override ctrl_interface and driver_param if set on command
* line.
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index f941923..cbe3e49 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -67,7 +67,7 @@
#ifdef CONFIG_P2P
/**
- * conf_p2p_dev - Additional configuration file used to hold the
+ * conf_p2p_dev - Configuration file used to hold the
* P2P Device configuration parameters.
*
* This can also be %NULL. In such a case, if a P2P Device dedicated
@@ -408,10 +408,6 @@
char *confname;
char *confanother;
-#ifdef CONFIG_P2P
- char *conf_p2p_dev;
-#endif /* CONFIG_P2P */
-
struct wpa_config *conf;
int countermeasures;
struct os_reltime last_michael_mic_error;
@@ -993,6 +989,8 @@
int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s);
struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
struct wpa_ssid **selected_ssid);
+int ht_supported(const struct hostapd_hw_modes *mode);
+int vht_supported(const struct hostapd_hw_modes *mode);
/* eap_register.c */
int eap_register_methods(void);
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 09b5961..38279b1 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -580,11 +580,13 @@
static int wpa_supplicant_send_tdls_mgmt(void *ctx, const u8 *dst,
u8 action_code, u8 dialog_token,
u16 status_code, u32 peer_capab,
- const u8 *buf, size_t len)
+ int initiator, const u8 *buf,
+ size_t len)
{
struct wpa_supplicant *wpa_s = ctx;
return wpa_drv_send_tdls_mgmt(wpa_s, dst, action_code, dialog_token,
- status_code, peer_capab, buf, len);
+ status_code, peer_capab, initiator, buf,
+ len);
}
@@ -600,7 +602,7 @@
const u8 *supp_rates, size_t supp_rates_len,
const struct ieee80211_ht_capabilities *ht_capab,
const struct ieee80211_vht_capabilities *vht_capab,
- u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len,
+ u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len,
const u8 *supp_channels, size_t supp_channels_len,
const u8 *supp_oper_classes, size_t supp_oper_classes_len)
{
@@ -615,10 +617,10 @@
params.flags = WPA_STA_TDLS_PEER | WPA_STA_AUTHORIZED;
/*
- * TDLS Setup frames do not contain WMM IEs, hence need to depend on
- * qosinfo to check if the peer is WMM capable.
+ * Don't rely only on qosinfo for WMM capability. It may be 0 even when
+ * present. Allow the WMM IE to also indicate QoS support.
*/
- if (qosinfo)
+ if (wmm || qosinfo)
params.flags |= WPA_STA_WMM;
params.ht_capabilities = ht_capab;