aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2014-06-02 13:50:35 -0700
committerDmitry Shmidt <dimitrysh@google.com>2014-06-02 13:50:35 -0700
commit717574375e969e8272c6d1a26137286eac158abb (patch)
treecd44844dacf9673caeedbad792d6f89f39fdf49c
parent76cd2cc44b62e858f1897ce58f4ce7d0174e8839 (diff)
downloadandroid_external_wpa_supplicant_8-717574375e969e8272c6d1a26137286eac158abb.tar.gz
android_external_wpa_supplicant_8-717574375e969e8272c6d1a26137286eac158abb.tar.bz2
android_external_wpa_supplicant_8-717574375e969e8272c6d1a26137286eac158abb.zip
Cumulative patch from commit 801e117376e13d5b3c50f1627b93a949529fdf99
801e117 Fix validation of RSN EAPOL-Key version for GCMP with PMF 3d4d234 FT: Fix GTK rekeying after FT protocol d3d0483 nl80211: Work around error case prints for nl_recvmsgs on Android 8a387a2 P2P NFC: Fix use of freed memory df48efc Fix external radio work stopping to not read freed memory 13c3303 SAE: Fix memory leak in random number generation d92bdf9 hostapd: Make sure hapd->drv_priv gets cleared on driver deinit 438e133 hostapd: Use helper function to avoid duplicate deinit calls ac1a224 hostapd: Clean up if interface setup fails 81c4fca hostapd: Reset hapd->interface_add properly 3fbd036 hostapd: Prevent double interface disabling from segfaulting ea39367 nl80211: Fix wpa_driver_nl80211_if_add() failure paths b77aeae Interworking: Re-trigger scan if no connect attempt is done b523973 RADIUS client: Trigger failover more quickly if socket is not valid 09844c0 RADIUS client: Do not flush pending messages if server did not change 5d67bf1 hostapd: Fix configuration of multiple RADIUS servers with SET 70d4084 RADIUS client: Fix socket close/re-open on server change d045cc8 RADIUS client: Fix crash issue in radius_client_timer() c1fb75a RADIUS client: Handle ENETUNREACH similarly to other failure cases 9ed4076 RADIUS client: Do not try to send message without socket cc0b7cb hostapd_cli: Fix segmentation fault with interface command 114153b P2P: Debug print channel lists for invitation processing 4eb3b76 OpenSSL: Fix OCSP certificate debug print to use wpa_printf f6fb192 HS 2.0R2: Fix subscr_remediation_method for RADIUS server 74879f3 Remove extra newline from a debug print Change-Id: I82d4f00501fabb8b325e4461178b45e7b2c0178e Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
-rw-r--r--hostapd/config_file.c4
-rw-r--r--hostapd/hostapd_cli.c4
-rw-r--r--src/ap/ap_config.c9
-rw-r--r--src/ap/ap_config.h3
-rw-r--r--src/ap/hostapd.c60
-rw-r--r--src/ap/wpa_auth.c2
-rw-r--r--src/ap/wpa_auth_ft.c1
-rw-r--r--src/common/common_module_tests.c172
-rw-r--r--src/common/ieee802_11_common.c2
-rw-r--r--src/common/sae.c4
-rw-r--r--src/crypto/tls_openssl.c38
-rw-r--r--src/drivers/driver_nl80211.c18
-rw-r--r--src/p2p/p2p.c4
-rw-r--r--src/p2p/p2p_invitation.c3
-rw-r--r--src/radius/radius_client.c117
-rw-r--r--src/radius/radius_server.c1
-rw-r--r--src/rsn_supp/wpa.c5
-rw-r--r--wpa_supplicant/Makefile19
-rw-r--r--wpa_supplicant/ctrl_iface.c4
-rw-r--r--wpa_supplicant/interworking.c5
-rw-r--r--wpa_supplicant/wpas_module_tests.c6
21 files changed, 405 insertions, 76 deletions
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index caf51a94..be403985 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3238,7 +3238,7 @@ struct hostapd_config * hostapd_config_read(const char *fname)
fclose(f);
for (i = 0; i < conf->num_bss; i++)
- hostapd_set_security_params(conf->bss[i]);
+ hostapd_set_security_params(conf->bss[i], 1);
if (hostapd_config_check(conf, 1))
errors++;
@@ -3270,7 +3270,7 @@ int hostapd_set_iface(struct hostapd_config *conf,
}
for (i = 0; i < conf->num_bss; i++)
- hostapd_set_security_params(conf->bss[i]);
+ hostapd_set_security_params(conf->bss[i], 0);
if (hostapd_config_check(conf, 0)) {
wpa_printf(MSG_ERROR, "Configuration check failed");
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index c488b4fd..1c4a84c6 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -842,8 +842,8 @@ static int hostapd_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc,
}
hostapd_cli_close_connection();
- free(ctrl_ifname);
- ctrl_ifname = strdup(argv[0]);
+ os_free(ctrl_ifname);
+ ctrl_ifname = os_strdup(argv[0]);
if (hostapd_cli_open_connection(ctrl_ifname)) {
printf("Connected to interface '%s.\n", ctrl_ifname);
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 9680817b..7535b1b7 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -859,7 +859,8 @@ int hostapd_config_check(struct hostapd_config *conf, int full_config)
}
-void hostapd_set_security_params(struct hostapd_bss_config *bss)
+void hostapd_set_security_params(struct hostapd_bss_config *bss,
+ int full_config)
{
if (bss->individual_wep_key_len == 0) {
/* individual keys are not use; can use key idx0 for
@@ -872,8 +873,10 @@ void hostapd_set_security_params(struct hostapd_bss_config *bss)
bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, bss->wpa_pairwise,
bss->rsn_pairwise);
- bss->radius->auth_server = bss->radius->auth_servers;
- bss->radius->acct_server = bss->radius->acct_servers;
+ if (full_config) {
+ bss->radius->auth_server = bss->radius->auth_servers;
+ bss->radius->acct_server = bss->radius->acct_servers;
+ }
if (bss->wpa && bss->ieee802_1x) {
bss->ssid.security_policy = SECURITY_WPA;
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index dfbe6260..905aec32 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -621,6 +621,7 @@ const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan,
struct hostapd_radius_attr *
hostapd_config_get_radius_attr(struct hostapd_radius_attr *attr, u8 type);
int hostapd_config_check(struct hostapd_config *conf, int full_config);
-void hostapd_set_security_params(struct hostapd_bss_config *bss);
+void hostapd_set_security_params(struct hostapd_bss_config *bss,
+ int full_config);
#endif /* HOSTAPD_CONFIG_H */
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index b7e118c0..ed733019 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -277,10 +277,21 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd)
authsrv_deinit(hapd);
- if (hapd->interface_added &&
- hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
- wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s",
- hapd->conf->iface);
+ if (hapd->interface_added) {
+ hapd->interface_added = 0;
+ if (hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
+ wpa_printf(MSG_WARNING,
+ "Failed to remove BSS interface %s",
+ hapd->conf->iface);
+ hapd->interface_added = 1;
+ } else {
+ /*
+ * Since this was a dynamically added interface, the
+ * driver wrapper may have removed its internal instance
+ * and hapd->drv_priv is not valid anymore.
+ */
+ hapd->drv_priv = NULL;
+ }
}
os_free(hapd->probereq_cb);
@@ -433,6 +444,14 @@ static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason)
}
+static void hostapd_bss_deinit_no_free(struct hostapd_data *hapd)
+{
+ hostapd_free_stas(hapd);
+ hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
+ hostapd_clear_wep(hapd);
+}
+
+
/**
* hostapd_validate_bssid_configuration - Validate BSSID configuration
* @iface: Pointer to interface data
@@ -1226,8 +1245,14 @@ int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
hapd = iface->bss[j];
if (j)
os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
- if (hostapd_setup_bss(hapd, j == 0))
+ if (hostapd_setup_bss(hapd, j == 0)) {
+ do {
+ hapd = iface->bss[j];
+ hostapd_bss_deinit_no_free(hapd);
+ hostapd_free_hapd_data(hapd);
+ } while (j-- > 0);
goto fail;
+ }
if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0)
prev_addr = hapd->own_addr;
}
@@ -1346,9 +1371,7 @@ static void hostapd_bss_deinit(struct hostapd_data *hapd)
{
wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__,
hapd->conf->iface);
- hostapd_free_stas(hapd);
- hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
- hostapd_clear_wep(hapd);
+ hostapd_bss_deinit_no_free(hapd);
hostapd_cleanup(hapd);
}
@@ -1601,8 +1624,10 @@ void hostapd_interface_deinit_free(struct hostapd_iface *iface)
hostapd_interface_deinit(iface);
wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
__func__, driver, drv_priv);
- if (driver && driver->hapd_deinit && drv_priv)
+ if (driver && driver->hapd_deinit && drv_priv) {
driver->hapd_deinit(drv_priv);
+ iface->bss[0]->drv_priv = NULL;
+ }
hostapd_interface_free(iface);
}
@@ -1630,6 +1655,8 @@ static void hostapd_deinit_driver(const struct wpa_driver_ops *driver,
int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
{
+ size_t j;
+
if (hapd_iface->bss[0]->drv_priv != NULL) {
wpa_printf(MSG_ERROR, "Interface %s already enabled",
hapd_iface->conf->bss[0]->iface);
@@ -1639,6 +1666,8 @@ int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
wpa_printf(MSG_DEBUG, "Enable interface %s",
hapd_iface->conf->bss[0]->iface);
+ for (j = 0; j < hapd_iface->num_bss; j++)
+ hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
wpa_printf(MSG_INFO, "Invalid configuration - cannot enable");
return -1;
@@ -1667,7 +1696,7 @@ int hostapd_reload_iface(struct hostapd_iface *hapd_iface)
wpa_printf(MSG_DEBUG, "Reload interface %s",
hapd_iface->conf->bss[0]->iface);
for (j = 0; j < hapd_iface->num_bss; j++)
- hostapd_set_security_params(hapd_iface->conf->bss[j]);
+ hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
wpa_printf(MSG_ERROR, "Updated configuration is invalid");
return -1;
@@ -1688,6 +1717,13 @@ int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
if (hapd_iface == NULL)
return -1;
+
+ if (hapd_iface->bss[0]->drv_priv == NULL) {
+ wpa_printf(MSG_INFO, "Interface %s already disabled",
+ hapd_iface->conf->bss[0]->iface);
+ return -1;
+ }
+
wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
driver = hapd_iface->bss[0]->driver;
drv_priv = hapd_iface->bss[0]->drv_priv;
@@ -1699,9 +1735,7 @@ int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
/* same as hostapd_interface_deinit without deinitializing ctrl-iface */
for (j = 0; j < hapd_iface->num_bss; j++) {
struct hostapd_data *hapd = hapd_iface->bss[j];
- hostapd_free_stas(hapd);
- hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
- hostapd_clear_wep(hapd);
+ hostapd_bss_deinit_no_free(hapd);
hostapd_free_hapd_data(hapd);
}
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index d2126103..a9cd6f65 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -565,6 +565,8 @@ int wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth,
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
"FT authentication already completed - do not "
"start 4-way handshake");
+ /* Go to PTKINITDONE state to allow GTK rekeying */
+ sm->wpa_ptk_state = WPA_PTK_PTKINITDONE;
return 0;
}
#endif /* CONFIG_IEEE80211R */
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index 77015961..a80bbb7f 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -898,6 +898,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
sm->pairwise = pairwise;
+ sm->PTK_valid = TRUE;
wpa_ft_install_ptk(sm);
buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +
diff --git a/src/common/common_module_tests.c b/src/common/common_module_tests.c
new file mode 100644
index 00000000..56b11220
--- /dev/null
+++ b/src/common/common_module_tests.c
@@ -0,0 +1,172 @@
+/*
+ * common module tests
+ * Copyright (c) 2014, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "utils/includes.h"
+
+#include "utils/common.h"
+#include "ieee802_11_common.h"
+#include "wpa_common.h"
+
+
+struct ieee802_11_parse_test_data {
+ u8 *data;
+ size_t len;
+ ParseRes result;
+ int count;
+};
+
+static const struct ieee802_11_parse_test_data parse_tests[] = {
+ { (u8 *) "", 0, ParseOK, 0 },
+ { (u8 *) " ", 1, ParseFailed, 0 },
+ { (u8 *) "\xff\x00", 2, ParseUnknown, 1 },
+ { (u8 *) "\xff\x01", 2, ParseFailed, 0 },
+ { (u8 *) "\xdd\x03\x01\x02\x03", 5, ParseUnknown, 1 },
+ { (u8 *) "\xdd\x04\x01\x02\x03\x04", 6, ParseUnknown, 1 },
+ { (u8 *) "\xdd\x04\x00\x50\xf2\x02", 6, ParseUnknown, 1 },
+ { (u8 *) "\xdd\x05\x00\x50\xf2\x02\x02", 7, ParseOK, 1 },
+ { (u8 *) "\xdd\x05\x00\x50\xf2\x02\xff", 7, ParseUnknown, 1 },
+ { (u8 *) "\xdd\x04\x00\x50\xf2\xff", 6, ParseUnknown, 1 },
+ { (u8 *) "\xdd\x04\x50\x6f\x9a\xff", 6, ParseUnknown, 1 },
+ { (u8 *) "\xdd\x04\x00\x90\x4c\x33", 6, ParseOK, 1 },
+ { (u8 *) "\xdd\x04\x00\x90\x4c\xff\xdd\x04\x00\x90\x4c\x33", 12,
+ ParseUnknown, 2 },
+ { (u8 *) "\x10\x01\x00\x21\x00", 5, ParseOK, 2 },
+ { (u8 *) "\x24\x00", 2, ParseOK, 1 },
+ { (u8 *) "\x38\x00", 2, ParseOK, 1 },
+ { (u8 *) "\x54\x00", 2, ParseOK, 1 },
+ { (u8 *) "\x5a\x00", 2, ParseOK, 1 },
+ { (u8 *) "\x65\x00", 2, ParseOK, 1 },
+ { (u8 *) "\x65\x12\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11",
+ 20, ParseOK, 1 },
+ { (u8 *) "\x6e\x00", 2, ParseOK, 1 },
+ { (u8 *) "\xc7\x00", 2, ParseOK, 1 },
+ { (u8 *) "\xc7\x01\x00", 3, ParseOK, 1 },
+ { NULL, 0, ParseOK, 0 }
+};
+
+static int ieee802_11_parse_tests(void)
+{
+ int i, ret = 0;
+
+ wpa_printf(MSG_INFO, "ieee802_11_parse tests");
+
+ for (i = 0; parse_tests[i].data; i++) {
+ const struct ieee802_11_parse_test_data *test;
+ struct ieee802_11_elems elems;
+ ParseRes res;
+
+ test = &parse_tests[i];
+ res = ieee802_11_parse_elems(test->data, test->len, &elems, 1);
+ if (res != test->result ||
+ ieee802_11_ie_count(test->data, test->len) != test->count) {
+ wpa_printf(MSG_ERROR, "ieee802_11_parse test %d failed",
+ i);
+ ret = -1;
+ }
+ }
+
+ if (ieee802_11_vendor_ie_concat((const u8 *) "\x00\x01", 2, 0) != NULL)
+ {
+ wpa_printf(MSG_ERROR,
+ "ieee802_11_vendor_ie_concat test failed");
+ ret = -1;
+ }
+
+ return ret;
+}
+
+
+struct rsn_ie_parse_test_data {
+ u8 *data;
+ size_t len;
+ int result;
+};
+
+static const struct rsn_ie_parse_test_data rsn_parse_tests[] = {
+ { (u8 *) "", 0, -1 },
+ { (u8 *) "\x30\x00", 2, -1 },
+ { (u8 *) "\x30\x02\x01\x00", 4, 0 },
+ { (u8 *) "\x30\x02\x00\x00", 4, -2 },
+ { (u8 *) "\x30\x02\x02\x00", 4, -2 },
+ { (u8 *) "\x30\x02\x00\x01", 4, -2 },
+ { (u8 *) "\x30\x02\x00\x00\x00", 5, -2 },
+ { (u8 *) "\x30\x03\x01\x00\x00", 5, -3 },
+ { (u8 *) "\x30\x06\x01\x00\x00\x00\x00\x00", 8, -1 },
+ { (u8 *) "\x30\x06\x01\x00\x00\x0f\xac\x04", 8, 0 },
+ { (u8 *) "\x30\x07\x01\x00\x00\x0f\xac\x04\x00", 9, -5 },
+ { (u8 *) "\x30\x08\x01\x00\x00\x0f\xac\x04\x00\x00", 10, -4 },
+ { (u8 *) "\x30\x08\x01\x00\x00\x0f\xac\x04\x00\x01", 10, -4 },
+ { (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
+ 14, 0 },
+ { (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x00\x01\x00\x0f\xac\x04",
+ 14, -4 },
+ { (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x06",
+ 14, -1 },
+ { (u8 *) "\x30\x10\x01\x00\x00\x0f\xac\x04\x02\x00\x00\x0f\xac\x04\x00\x0f\xac\x08",
+ 18, 0 },
+ { (u8 *) "\x30\x0d\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00",
+ 15, -7 },
+ { (u8 *) "\x30\x0e\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00\x00",
+ 16, -6 },
+ { (u8 *) "\x30\x0e\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00\x01",
+ 16, -6 },
+ { (u8 *) "\x30\x12\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01",
+ 20, 0 },
+ { (u8 *) "\x30\x16\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x02\x00\x00\x0f\xac\x01\x00\x0f\xac\x02",
+ 24, 0 },
+ { (u8 *) "\x30\x13\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00",
+ 21, 0 },
+ { (u8 *) "\x30\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00",
+ 22, 0 },
+ { (u8 *) "\x30\x16\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00",
+ 24, 0 },
+ { (u8 *) "\x30\x16\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x01",
+ 24, -9 },
+ { (u8 *) "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00\x00\x00\x00\x00",
+ 28, -10 },
+ { (u8 *) "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00\x00\x0f\xac\x06",
+ 28, 0 },
+ { (u8 *) "\x30\x1c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00\x00\x0f\xac\x06\x01\x02",
+ 30, 0 },
+ { NULL, 0, 0 }
+};
+
+static int rsn_ie_parse_tests(void)
+{
+ int i, ret = 0;
+
+ wpa_printf(MSG_INFO, "rsn_ie_parse tests");
+
+ for (i = 0; rsn_parse_tests[i].data; i++) {
+ const struct rsn_ie_parse_test_data *test;
+ struct wpa_ie_data data;
+
+ test = &rsn_parse_tests[i];
+ if (wpa_parse_wpa_ie_rsn(test->data, test->len, &data) !=
+ test->result) {
+ wpa_printf(MSG_ERROR, "rsn_ie_parse test %d failed", i);
+ ret = -1;
+ }
+ }
+
+ return ret;
+}
+
+
+int common_module_tests(void)
+{
+ int ret = 0;
+
+ wpa_printf(MSG_INFO, "common module tests");
+
+ if (ieee802_11_parse_tests() < 0 ||
+ rsn_ie_parse_tests() < 0)
+ ret = -1;
+
+ return ret;
+}
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index cdee6bc3..faa6a39b 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -116,7 +116,7 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
default:
wpa_printf(MSG_MSGDUMP, "Unknown WFA "
"information element ignored "
- "(type=%d len=%lu)\n",
+ "(type=%d len=%lu)",
pos[3], (unsigned long) elen);
return -1;
}
diff --git a/src/common/sae.c b/src/common/sae.c
index 674cb650..c1b488e9 100644
--- a/src/common/sae.c
+++ b/src/common/sae.c
@@ -134,8 +134,10 @@ static struct crypto_bignum * sae_get_rand(struct sae_data *sae)
return NULL;
if (crypto_bignum_is_zero(bn) ||
crypto_bignum_is_one(bn) ||
- crypto_bignum_cmp(bn, sae->tmp->order) >= 0)
+ crypto_bignum_cmp(bn, sae->tmp->order) >= 0) {
+ crypto_bignum_deinit(bn, 0);
continue;
+ }
break;
}
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 58a07cf5..d2d66003 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -2968,6 +2968,41 @@ static void ocsp_debug_print_resp(OCSP_RESPONSE *rsp)
}
+static void debug_print_cert(X509 *cert, const char *title)
+{
+#ifndef CONFIG_NO_STDOUT_DEBUG
+ BIO *out;
+ size_t rlen;
+ char *txt;
+ int res;
+
+ if (wpa_debug_level > MSG_DEBUG)
+ return;
+
+ out = BIO_new(BIO_s_mem());
+ if (!out)
+ return;
+
+ X509_print(out, cert);
+ rlen = BIO_ctrl_pending(out);
+ txt = os_malloc(rlen + 1);
+ if (!txt) {
+ BIO_free(out);
+ return;
+ }
+
+ res = BIO_read(out, txt, rlen);
+ if (res > 0) {
+ txt[res] = '\0';
+ wpa_printf(MSG_DEBUG, "OpenSSL: %s\n%s", title, txt);
+ }
+ os_free(txt);
+
+ BIO_free(out);
+#endif /* CONFIG_NO_STDOUT_DEBUG */
+}
+
+
static int ocsp_resp_cb(SSL *s, void *arg)
{
struct tls_connection *conn = arg;
@@ -3011,8 +3046,7 @@ static int ocsp_resp_cb(SSL *s, void *arg)
store = SSL_CTX_get_cert_store(s->ctx);
if (conn->peer_issuer) {
- wpa_printf(MSG_DEBUG, "OpenSSL: Add issuer");
- X509_print_fp(stdout, conn->peer_issuer);
+ debug_print_cert(conn->peer_issuer, "Add OCSP issuer");
if (X509_STORE_add_cert(store, conn->peer_issuer) != 1) {
tls_show_errors(MSG_INFO, __func__,
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 9f7d0f56..75686538 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -652,7 +652,7 @@ static int send_and_recv(struct nl80211_global *global,
while (err > 0) {
int res = nl_recvmsgs(nl_handle, cb);
- if (res) {
+ if (res < 0) {
wpa_printf(MSG_INFO,
"nl80211: %s->nl_recvmsgs failed: %d",
__func__, res);
@@ -910,7 +910,7 @@ static void nl80211_recv_beacons(int sock, void *eloop_ctx, void *handle)
wpa_printf(MSG_EXCESSIVE, "nl80211: Beacon event message available");
res = nl_recvmsgs(handle, w->nl_cb);
- if (res) {
+ if (res < 0) {
wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
__func__, res);
}
@@ -3276,7 +3276,7 @@ static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
wpa_printf(MSG_MSGDUMP, "nl80211: Event message available");
res = nl_recvmsgs(handle, cb);
- if (res) {
+ if (res < 0) {
wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
__func__, res);
}
@@ -10107,19 +10107,22 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
if (linux_get_ifhwaddr(drv->global->ioctl_sock, ifname,
new_addr) < 0) {
- nl80211_remove_iface(drv, ifidx);
+ if (added)
+ nl80211_remove_iface(drv, ifidx);
return -1;
}
if (nl80211_addr_in_use(drv->global, new_addr)) {
wpa_printf(MSG_DEBUG, "nl80211: Allocate new address "
"for P2P group interface");
if (nl80211_p2p_interface_addr(drv, new_addr) < 0) {
- nl80211_remove_iface(drv, ifidx);
+ if (added)
+ nl80211_remove_iface(drv, ifidx);
return -1;
}
if (linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
new_addr) < 0) {
- nl80211_remove_iface(drv, ifidx);
+ if (added)
+ nl80211_remove_iface(drv, ifidx);
return -1;
}
}
@@ -10148,7 +10151,8 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
if (linux_set_iface_flags(drv->global->ioctl_sock, ifname, 1))
{
- nl80211_remove_iface(drv, ifidx);
+ if (added)
+ nl80211_remove_iface(drv, ifidx);
os_free(new_bss);
return -1;
}
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 1a190414..1875ca4d 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -4638,10 +4638,9 @@ int p2p_process_nfc_connection_handover(struct p2p_data *p2p,
params->go_ssid_len);
}
- p2p_parse_free(&msg);
-
if (dev->flags & P2P_DEV_USER_REJECTED) {
p2p_dbg(p2p, "Do not report rejected device");
+ p2p_parse_free(&msg);
return 0;
}
@@ -4650,6 +4649,7 @@ int p2p_process_nfc_connection_handover(struct p2p_data *p2p,
!(dev->flags & P2P_DEV_REPORTED_ONCE));
dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
}
+ p2p_parse_free(&msg);
if (role == P2P_GO_IN_A_GROUP && p2p->num_groups > 0)
params->next_step = BOTH_GO;
diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c
index cb77aee3..a36898e9 100644
--- a/src/p2p/p2p_invitation.c
+++ b/src/p2p/p2p_invitation.c
@@ -227,8 +227,11 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,
goto fail;
}
+ p2p_channels_dump(p2p, "own channels", &p2p->cfg->channels);
+ p2p_channels_dump(p2p, "peer channels", &dev->channels);
p2p_channels_intersect(&p2p->cfg->channels, &dev->channels,
&intersection);
+ p2p_channels_dump(p2p, "intersection", &intersection);
if (p2p->cfg->invitation_process) {
status = p2p->cfg->invitation_process(
diff --git a/src/radius/radius_client.c b/src/radius/radius_client.c
index 76259966..10056a64 100644
--- a/src/radius/radius_client.c
+++ b/src/radius/radius_client.c
@@ -295,26 +295,34 @@ int radius_client_register(struct radius_client_data *radius,
}
-static void radius_client_handle_send_error(struct radius_client_data *radius,
- int s, RadiusType msg_type)
+/*
+ * Returns >0 if message queue was flushed (i.e., the message that triggered
+ * the error is not available anymore)
+ */
+static int radius_client_handle_send_error(struct radius_client_data *radius,
+ int s, RadiusType msg_type)
{
#ifndef CONFIG_NATIVE_WINDOWS
int _errno = errno;
wpa_printf(MSG_INFO, "send[RADIUS]: %s", strerror(errno));
if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL ||
- _errno == EBADF) {
+ _errno == EBADF || _errno == ENETUNREACH) {
hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO,
"Send failed - maybe interface status changed -"
" try to connect again");
- eloop_unregister_read_sock(s);
- close(s);
- if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM)
+ if (msg_type == RADIUS_ACCT ||
+ msg_type == RADIUS_ACCT_INTERIM) {
radius_client_init_acct(radius);
- else
+ return 0;
+ } else {
radius_client_init_auth(radius);
+ return 1;
+ }
}
#endif /* CONFIG_NATIVE_WINDOWS */
+
+ return 0;
}
@@ -353,8 +361,11 @@ static int radius_client_retransmit(struct radius_client_data *radius,
os_get_reltime(&entry->last_attempt);
buf = radius_msg_get_buf(entry->msg);
- if (send(s, wpabuf_head(buf), wpabuf_len(buf), 0) < 0)
- radius_client_handle_send_error(radius, s, entry->msg_type);
+ if (send(s, wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
+ if (radius_client_handle_send_error(radius, s, entry->msg_type)
+ > 0)
+ return 0;
+ }
entry->next_try = now + entry->next_wait;
entry->next_wait *= 2;
@@ -378,6 +389,8 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx)
struct radius_msg_list *entry, *prev, *tmp;
int auth_failover = 0, acct_failover = 0;
char abuf[50];
+ size_t prev_num_msgs;
+ int s;
entry = radius->msgs;
if (!entry)
@@ -388,6 +401,7 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx)
prev = NULL;
while (entry) {
+ prev_num_msgs = radius->num_msgs;
if (now.sec >= entry->next_try &&
radius_client_retransmit(radius, entry, now.sec)) {
if (prev)
@@ -402,7 +416,18 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx)
continue;
}
- if (entry->attempts > RADIUS_CLIENT_NUM_FAILOVER) {
+ if (prev_num_msgs != radius->num_msgs) {
+ wpa_printf(MSG_DEBUG,
+ "RADIUS: Message removed from queue - restart from beginning");
+ entry = radius->msgs;
+ prev = NULL;
+ continue;
+ }
+
+ s = entry->msg_type == RADIUS_AUTH ? radius->auth_sock :
+ radius->acct_sock;
+ if (entry->attempts > RADIUS_CLIENT_NUM_FAILOVER ||
+ (s < 0 && entry->attempts > 0)) {
if (entry->msg_type == RADIUS_ACCT ||
entry->msg_type == RADIUS_ACCT_INTERIM)
acct_failover++;
@@ -633,7 +658,7 @@ int radius_client_send(struct radius_client_data *radius,
}
if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM) {
- if (conf->acct_server == NULL) {
+ if (conf->acct_server == NULL || radius->acct_sock < 0) {
hostapd_logger(radius->ctx, NULL,
HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO,
@@ -647,7 +672,7 @@ int radius_client_send(struct radius_client_data *radius,
s = radius->acct_sock;
conf->acct_server->requests++;
} else {
- if (conf->auth_server == NULL) {
+ if (conf->auth_server == NULL || radius->auth_sock < 0) {
hostapd_logger(radius->ctx, NULL,
HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO,
@@ -951,9 +976,10 @@ radius_change_server(struct radius_client_data *radius,
hostapd_ip_txt(&nserv->addr, abuf, sizeof(abuf)),
nserv->port);
- if (!oserv || nserv->shared_secret_len != oserv->shared_secret_len ||
- os_memcmp(nserv->shared_secret, oserv->shared_secret,
- nserv->shared_secret_len) != 0) {
+ if (oserv && oserv != nserv &&
+ (nserv->shared_secret_len != oserv->shared_secret_len ||
+ os_memcmp(nserv->shared_secret, oserv->shared_secret,
+ nserv->shared_secret_len) != 0)) {
/* Pending RADIUS packets used different shared secret, so
* they need to be modified. Update accounting message
* authenticators here. Authentication messages are removed
@@ -971,7 +997,8 @@ radius_change_server(struct radius_client_data *radius,
}
/* Reset retry counters for the new server */
- for (entry = radius->msgs; entry; entry = entry->next) {
+ for (entry = radius->msgs; oserv && oserv != nserv && entry;
+ entry = entry->next) {
if ((auth && entry->msg_type != RADIUS_AUTH) ||
(!auth && entry->msg_type != RADIUS_ACCT))
continue;
@@ -1128,11 +1155,51 @@ static int radius_client_disable_pmtu_discovery(int s)
}
+static void radius_close_auth_sockets(struct radius_client_data *radius)
+{
+ radius->auth_sock = -1;
+
+ if (radius->auth_serv_sock >= 0) {
+ eloop_unregister_read_sock(radius->auth_serv_sock);
+ close(radius->auth_serv_sock);
+ radius->auth_serv_sock = -1;
+ }
+#ifdef CONFIG_IPV6
+ if (radius->auth_serv_sock6 >= 0) {
+ eloop_unregister_read_sock(radius->auth_serv_sock6);
+ close(radius->auth_serv_sock6);
+ radius->auth_serv_sock6 = -1;
+ }
+#endif /* CONFIG_IPV6 */
+}
+
+
+static void radius_close_acct_sockets(struct radius_client_data *radius)
+{
+ radius->acct_sock = -1;
+
+ if (radius->acct_serv_sock >= 0) {
+ eloop_unregister_read_sock(radius->acct_serv_sock);
+ close(radius->acct_serv_sock);
+ radius->acct_serv_sock = -1;
+ }
+#ifdef CONFIG_IPV6
+ if (radius->acct_serv_sock6 >= 0) {
+ eloop_unregister_read_sock(radius->acct_serv_sock6);
+ close(radius->acct_serv_sock6);
+ radius->acct_serv_sock6 = -1;
+ }
+#endif /* CONFIG_IPV6 */
+}
+
+
static int radius_client_init_auth(struct radius_client_data *radius)
{
struct hostapd_radius_servers *conf = radius->conf;
int ok = 0;
+ radius_close_auth_sockets(radius);
+
radius->auth_serv_sock = socket(PF_INET, SOCK_DGRAM, 0);
if (radius->auth_serv_sock < 0)
wpa_printf(MSG_INFO, "RADIUS: socket[PF_INET,SOCK_DGRAM]: %s",
@@ -1163,6 +1230,7 @@ static int radius_client_init_auth(struct radius_client_data *radius)
radius_client_receive, radius,
(void *) RADIUS_AUTH)) {
wpa_printf(MSG_INFO, "RADIUS: Could not register read socket for authentication server");
+ radius_close_auth_sockets(radius);
return -1;
}
@@ -1172,6 +1240,7 @@ static int radius_client_init_auth(struct radius_client_data *radius)
radius_client_receive, radius,
(void *) RADIUS_AUTH)) {
wpa_printf(MSG_INFO, "RADIUS: Could not register read socket for authentication server");
+ radius_close_auth_sockets(radius);
return -1;
}
#endif /* CONFIG_IPV6 */
@@ -1185,6 +1254,8 @@ static int radius_client_init_acct(struct radius_client_data *radius)
struct hostapd_radius_servers *conf = radius->conf;
int ok = 0;
+ radius_close_acct_sockets(radius);
+
radius->acct_serv_sock = socket(PF_INET, SOCK_DGRAM, 0);
if (radius->acct_serv_sock < 0)
wpa_printf(MSG_INFO, "RADIUS: socket[PF_INET,SOCK_DGRAM]: %s",
@@ -1215,6 +1286,7 @@ static int radius_client_init_acct(struct radius_client_data *radius)
radius_client_receive, radius,
(void *) RADIUS_ACCT)) {
wpa_printf(MSG_INFO, "RADIUS: Could not register read socket for accounting server");
+ radius_close_acct_sockets(radius);
return -1;
}
@@ -1224,6 +1296,7 @@ static int radius_client_init_acct(struct radius_client_data *radius)
radius_client_receive, radius,
(void *) RADIUS_ACCT)) {
wpa_printf(MSG_INFO, "RADIUS: Could not register read socket for accounting server");
+ radius_close_acct_sockets(radius);
return -1;
}
#endif /* CONFIG_IPV6 */
@@ -1285,16 +1358,8 @@ void radius_client_deinit(struct radius_client_data *radius)
if (!radius)
return;
- if (radius->auth_serv_sock >= 0)
- eloop_unregister_read_sock(radius->auth_serv_sock);
- if (radius->acct_serv_sock >= 0)
- eloop_unregister_read_sock(radius->acct_serv_sock);
-#ifdef CONFIG_IPV6
- if (radius->auth_serv_sock6 >= 0)
- eloop_unregister_read_sock(radius->auth_serv_sock6);
- if (radius->acct_serv_sock6 >= 0)
- eloop_unregister_read_sock(radius->acct_serv_sock6);
-#endif /* CONFIG_IPV6 */
+ radius_close_auth_sockets(radius);
+ radius_close_acct_sockets(radius);
eloop_cancel_timeout(radius_retry_primary_timer, radius, NULL);
diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c
index bd358ae9..78c99614 100644
--- a/src/radius/radius_server.c
+++ b/src/radius/radius_server.c
@@ -1730,6 +1730,7 @@ radius_server_init(struct radius_server_conf *conf)
data->subscr_remediation_url =
os_strdup(conf->subscr_remediation_url);
}
+ data->subscr_remediation_method = conf->subscr_remediation_method;
#ifdef CONFIG_SQLITE
if (conf->sqlite_file) {
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index d45f5dc1..ba2a8c87 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -1734,9 +1734,8 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
"version for non-CCMP group keys");
} else
goto out;
- }
- if (sm->pairwise_cipher == WPA_CIPHER_GCMP &&
- ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
+ } else if (sm->pairwise_cipher == WPA_CIPHER_GCMP &&
+ ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"WPA: GCMP is used, but EAPOL-Key "
"descriptor version (%d) is not 2", ver);
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index c0913e0a..817a69d6 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -97,15 +97,6 @@ OBJS += ../src/utils/os_$(CONFIG_OS).o
OBJS_p += ../src/utils/os_$(CONFIG_OS).o
OBJS_c += ../src/utils/os_$(CONFIG_OS).o
-ifdef CONFIG_MODULE_TESTS
-CFLAGS += -DCONFIG_MODULE_TESTS
-OBJS += wpas_module_tests.o
-OBJS += ../src/utils/utils_module_tests.o
-ifdef CONFIG_WPS
-OBJS += ../src/wps/wps_module_tests.o
-endif
-endif
-
ifdef CONFIG_WPA_TRACE
CFLAGS += -DWPA_TRACE
OBJS += ../src/utils/trace.o
@@ -1500,6 +1491,16 @@ OBJS += offchannel.o
CFLAGS += -DCONFIG_OFFCHANNEL
endif
+ifdef CONFIG_MODULE_TESTS
+CFLAGS += -DCONFIG_MODULE_TESTS
+OBJS += wpas_module_tests.o
+OBJS += ../src/utils/utils_module_tests.o
+OBJS += ../src/common/common_module_tests.o
+ifdef CONFIG_WPS
+OBJS += ../src/wps/wps_module_tests.o
+endif
+endif
+
OBJS += ../src/drivers/driver_common.o
OBJS_priv += ../src/drivers/driver_common.o
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 88a4cd95..53e23fff 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -5808,8 +5808,8 @@ static void wpas_ctrl_radio_work_timeout(void *eloop_ctx, void *timeout_ctx)
"Timing out external radio work %u (%s)",
ework->id, work->type);
wpa_msg(work->wpa_s, MSG_INFO, EXT_RADIO_WORK_TIMEOUT "%u", ework->id);
- os_free(ework);
radio_work_done(work);
+ os_free(ework);
}
@@ -5951,8 +5951,8 @@ void wpas_ctrl_radio_work_flush(struct wpa_supplicant *wpa_s)
if (work->started)
eloop_cancel_timeout(wpas_ctrl_radio_work_timeout,
work, NULL);
- os_free(ework);
radio_work_done(work);
+ os_free(ework);
}
}
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index a8ecb8cc..6d1539c6 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -2397,9 +2397,10 @@ static void interworking_select_network(struct wpa_supplicant *wpa_s)
if (interworking_find_network_match(wpa_s)) {
wpa_printf(MSG_DEBUG, "Interworking: Possible BSS "
"match for enabled network configurations");
- if (wpa_s->auto_select)
+ if (wpa_s->auto_select) {
interworking_reconnect(wpa_s);
- return;
+ return;
+ }
}
if (wpa_s->auto_network_select) {
diff --git a/wpa_supplicant/wpas_module_tests.c b/wpa_supplicant/wpas_module_tests.c
index 38493d43..e4c83b58 100644
--- a/wpa_supplicant/wpas_module_tests.c
+++ b/wpa_supplicant/wpas_module_tests.c
@@ -92,5 +92,11 @@ int wpas_module_tests(void)
ret = -1;
}
+ {
+ int common_module_tests(void);
+ if (common_module_tests() < 0)
+ ret = -1;
+ }
+
return ret;
}