Cumulative patch from commit 10222ca19217b743687be311183f58a250d3a55f
10222ca Android: Sync Android.mk with Makefile
aebfbcb Android: Sync Android.mk with Makefile
890b3a4 Android: Sync Android.mk with Makefile
736abfc Android: Set proper path to keystore include dir
bbd84e5 Android: Add CONFIG_ACS option to makefile
5e42035 Android: Fix CONFIG_EAP_PROXY option and move it to right place
643fab3 Android: Add CONFIG_IEEE80211AC option to makefile
4ba8309 Android: Add CONFIG_EAP_UNAUTH_TLS option to makefile
53414a7 Android: Add liblog
1d415f1 Android: Switch keystore to binder
4e5a4d3 Android: Get rid of LOCAL_MODULE_TAGS := user
206d813 Android: Restore OpenSSL ENGINE support
6dfdb80 Android: Remove obsolete keystore path
1176ab6 Android: Use keystore ENGINE for private key operations
6dc94a6 Android: Use correct header file path for capability.h
91f9e60 GAS: Replenish AP station session timer to 5 seconds
e5e74e5 eloop: Add support for replenishing a registered timeout
b7997e0 Android: Remove obsolete WPA_UNICODE_SSID define
2d39a4d hostapd: Allow hostapd_cli to work on Android
1c6edec nl80211: Work around nl_socket_set_nonblocking on Android
c101bb9 hostapd: Add option to send OBSS scan params
60cdfd7 Android: Fix compilation without BOARD_WPA_SUPPLICANT_DRIVER
e40634e Prohibit PNO start during assoc process and in connect state
3526ff0 Android: Add ANDROID_P2P define under BOARD_WLAN_DEVICE
d0b2735 Android: Fix CFLAGS -> L_CFLAGS
9ec8766 P2P: Allow GO P2P Device Address to be used for scan result matching
83eefb4 P2P: Add debug print of P2P Group ID SSID
b6881b5 WPS NFC: Add more debug for NFC Password Token matching
67a88a7 WPS NFC: Add debug log entry on OOB Dev Pw attribute addition
08b2677 Interworking: Use SSID from the BSS entry
5058975 Interworking: Reject BSS based on disallow_aps
6ede8a7 Interworking: Avoid duplicated network blocks
d28f4e4 Interworking: Do not reconnect if already connected
5e1a456 hostapd: Do not start secondary BSS unless interface is enabled
36501a2 hostapd: Verify hostapd_setup_bss calls
54246f8 hostapd: Share a single function for BSS deinit
6d1ca81 Remove unused hostapd_cleanup_iface_pre()
747c85f hostapd: Add more debug prints to deinit path
6023a78 Restore hapd->interface_added tracking to core hostapd
486d2ff hostapd: Deinit ctrl_iface in case of add interface failure
8540e0b hostapd: Fix DETACH command debug prints to avoid use of freed memory
cdf3fb1 Fix removal of a BSS that has not yet been fully initialized
2f99d90 Remove all BSSs on removal of the first one
1493380 drivers: Do not call hostapd_logger()
1281c0a Remove a compiler warning from -O0 build
Change-Id: I0f4905d5310c51c9a4375d811a2e874651687d4f
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index 8667221..93652d8 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -1,6 +1,6 @@
/*
* Interworking (IEEE 802.11u)
- * Copyright (c) 2011-2012, Qualcomm Atheros, Inc.
+ * Copyright (c) 2011-2013, Qualcomm Atheros, Inc.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -19,6 +19,7 @@
#include "eap_peer/eap.h"
#include "eap_peer/eap_methods.h"
#include "eapol_supp/eapol_supp_sm.h"
+#include "rsn_supp/wpa.h"
#include "wpa_supplicant_i.h"
#include "config.h"
#include "config_ssid.h"
@@ -750,6 +751,59 @@
#endif /* INTERWORKING_3GPP */
+static int already_connected(struct wpa_supplicant *wpa_s,
+ struct wpa_cred *cred, struct wpa_bss *bss)
+{
+ struct wpa_ssid *ssid;
+
+ if (wpa_s->wpa_state < WPA_ASSOCIATED || wpa_s->current_ssid == NULL)
+ return 0;
+
+ ssid = wpa_s->current_ssid;
+ if (ssid->parent_cred != cred)
+ return 0;
+
+ if (ssid->ssid_len != bss->ssid_len ||
+ os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) != 0)
+ return 0;
+
+ return 1;
+}
+
+
+static void remove_duplicate_network(struct wpa_supplicant *wpa_s,
+ struct wpa_cred *cred,
+ struct wpa_bss *bss)
+{
+ struct wpa_ssid *ssid;
+
+ for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
+ if (ssid->parent_cred != cred)
+ continue;
+ if (ssid->ssid_len != bss->ssid_len ||
+ os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) != 0)
+ continue;
+
+ break;
+ }
+
+ if (ssid == NULL)
+ return;
+
+ wpa_printf(MSG_DEBUG, "Interworking: Remove duplicate network entry for the same credential");
+
+ if (ssid == wpa_s->current_ssid) {
+ wpa_sm_set_config(wpa_s->wpa, NULL);
+ eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
+ wpa_supplicant_deauthenticate(wpa_s,
+ WLAN_REASON_DEAUTH_LEAVING);
+ }
+
+ wpas_notify_network_removed(wpa_s, ssid);
+ wpa_config_remove_network(wpa_s->conf, ssid->id);
+}
+
+
static int interworking_set_hs20_params(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid)
{
@@ -771,7 +825,6 @@
{
#ifdef INTERWORKING_3GPP
struct wpa_ssid *ssid;
- const u8 *ie;
int eap_type;
int res;
char prefix;
@@ -779,12 +832,17 @@
if (bss->anqp == NULL || bss->anqp->anqp_3gpp == NULL)
return -1;
- ie = wpa_bss_get_ie(bss, WLAN_EID_SSID);
- if (ie == NULL)
- return -1;
wpa_printf(MSG_DEBUG, "Interworking: Connect with " MACSTR " (3GPP)",
MAC2STR(bss->bssid));
+ if (already_connected(wpa_s, cred, bss)) {
+ wpa_msg(wpa_s, MSG_INFO, INTERWORKING_ALREADY_CONNECTED MACSTR,
+ MAC2STR(bss->bssid));
+ return 0;
+ }
+
+ remove_duplicate_network(wpa_s, cred, bss);
+
ssid = wpa_config_add_network(wpa_s->conf);
if (ssid == NULL)
return -1;
@@ -794,11 +852,11 @@
wpa_config_set_network_defaults(ssid);
ssid->priority = cred->priority;
ssid->temporary = 1;
- ssid->ssid = os_zalloc(ie[1] + 1);
+ ssid->ssid = os_zalloc(bss->ssid_len + 1);
if (ssid->ssid == NULL)
goto fail;
- os_memcpy(ssid->ssid, ie + 2, ie[1]);
- ssid->ssid_len = ie[1];
+ os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len);
+ ssid->ssid_len = bss->ssid_len;
if (interworking_set_hs20_params(wpa_s, ssid) < 0)
goto fail;
@@ -1137,13 +1195,21 @@
static int interworking_connect_roaming_consortium(
struct wpa_supplicant *wpa_s, struct wpa_cred *cred,
- struct wpa_bss *bss, const u8 *ssid_ie)
+ struct wpa_bss *bss)
{
struct wpa_ssid *ssid;
wpa_printf(MSG_DEBUG, "Interworking: Connect with " MACSTR " based on "
"roaming consortium match", MAC2STR(bss->bssid));
+ if (already_connected(wpa_s, cred, bss)) {
+ wpa_msg(wpa_s, MSG_INFO, INTERWORKING_ALREADY_CONNECTED MACSTR,
+ MAC2STR(bss->bssid));
+ return 0;
+ }
+
+ remove_duplicate_network(wpa_s, cred, bss);
+
ssid = wpa_config_add_network(wpa_s->conf);
if (ssid == NULL)
return -1;
@@ -1152,11 +1218,11 @@
wpa_config_set_network_defaults(ssid);
ssid->priority = cred->priority;
ssid->temporary = 1;
- ssid->ssid = os_zalloc(ssid_ie[1] + 1);
+ ssid->ssid = os_zalloc(bss->ssid_len + 1);
if (ssid->ssid == NULL)
goto fail;
- os_memcpy(ssid->ssid, ssid_ie + 2, ssid_ie[1]);
- ssid->ssid_len = ssid_ie[1];
+ os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len);
+ ssid->ssid_len = bss->ssid_len;
if (interworking_set_hs20_params(wpa_s, ssid) < 0)
goto fail;
@@ -1193,13 +1259,12 @@
struct nai_realm_eap *eap = NULL;
u16 count, i;
char buf[100];
- const u8 *ie;
if (wpa_s->conf->cred == NULL || bss == NULL)
return -1;
- ie = wpa_bss_get_ie(bss, WLAN_EID_SSID);
- if (ie == NULL || ie[1] == 0) {
- wpa_printf(MSG_DEBUG, "Interworking: No SSID known for "
+ if (disallowed_bssid(wpa_s, bss->bssid) ||
+ disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len)) {
+ wpa_printf(MSG_DEBUG, "Interworking: Reject connection to disallowed BSS "
MACSTR, MAC2STR(bss->bssid));
return -1;
}
@@ -1239,7 +1304,7 @@
(cred == NULL || cred_rc->priority >= cred->priority) &&
(cred_3gpp == NULL || cred_rc->priority >= cred_3gpp->priority))
return interworking_connect_roaming_consortium(wpa_s, cred_rc,
- bss, ie);
+ bss);
if (cred_3gpp &&
(cred == NULL || cred_3gpp->priority >= cred->priority)) {
@@ -1279,6 +1344,15 @@
wpa_printf(MSG_DEBUG, "Interworking: Connect with " MACSTR,
MAC2STR(bss->bssid));
+ if (already_connected(wpa_s, cred, bss)) {
+ wpa_msg(wpa_s, MSG_INFO, INTERWORKING_ALREADY_CONNECTED MACSTR,
+ MAC2STR(bss->bssid));
+ nai_realm_free(realm, count);
+ return 0;
+ }
+
+ remove_duplicate_network(wpa_s, cred, bss);
+
ssid = wpa_config_add_network(wpa_s->conf);
if (ssid == NULL) {
nai_realm_free(realm, count);
@@ -1289,11 +1363,11 @@
wpa_config_set_network_defaults(ssid);
ssid->priority = cred->priority;
ssid->temporary = 1;
- ssid->ssid = os_zalloc(ie[1] + 1);
+ ssid->ssid = os_zalloc(bss->ssid_len + 1);
if (ssid->ssid == NULL)
goto fail;
- os_memcpy(ssid->ssid, ie + 2, ie[1]);
- ssid->ssid_len = ie[1];
+ os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len);
+ ssid->ssid_len = bss->ssid_len;
if (interworking_set_hs20_params(wpa_s, ssid) < 0)
goto fail;
@@ -1518,6 +1592,13 @@
{
struct wpa_cred *cred, *cred2;
+ if (disallowed_bssid(wpa_s, bss->bssid) ||
+ disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len)) {
+ wpa_printf(MSG_DEBUG, "Interworking: Ignore disallowed BSS "
+ MACSTR, MAC2STR(bss->bssid));
+ return NULL;
+ }
+
cred = interworking_credentials_available_realm(wpa_s, bss);
cred2 = interworking_credentials_available_3gpp(wpa_s, bss);
if (cred && cred2 && cred2->priority >= cred->priority)
@@ -1804,6 +1885,9 @@
ie = wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB);
if (ie == NULL || ie[1] < 4 || !(ie[5] & 0x80))
continue; /* AP does not support Interworking */
+ if (disallowed_bssid(wpa_s, bss->bssid) ||
+ disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len))
+ continue; /* Disallowed BSS */
if (!(bss->flags & WPA_BSS_ANQP_FETCH_TRIED)) {
if (bss->anqp == NULL) {