diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2014-06-02 13:50:35 -0700 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2014-06-02 13:50:35 -0700 |
commit | 717574375e969e8272c6d1a26137286eac158abb (patch) | |
tree | cd44844dacf9673caeedbad792d6f89f39fdf49c | |
parent | 76cd2cc44b62e858f1897ce58f4ce7d0174e8839 (diff) | |
download | android_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.c | 4 | ||||
-rw-r--r-- | hostapd/hostapd_cli.c | 4 | ||||
-rw-r--r-- | src/ap/ap_config.c | 9 | ||||
-rw-r--r-- | src/ap/ap_config.h | 3 | ||||
-rw-r--r-- | src/ap/hostapd.c | 60 | ||||
-rw-r--r-- | src/ap/wpa_auth.c | 2 | ||||
-rw-r--r-- | src/ap/wpa_auth_ft.c | 1 | ||||
-rw-r--r-- | src/common/common_module_tests.c | 172 | ||||
-rw-r--r-- | src/common/ieee802_11_common.c | 2 | ||||
-rw-r--r-- | src/common/sae.c | 4 | ||||
-rw-r--r-- | src/crypto/tls_openssl.c | 38 | ||||
-rw-r--r-- | src/drivers/driver_nl80211.c | 18 | ||||
-rw-r--r-- | src/p2p/p2p.c | 4 | ||||
-rw-r--r-- | src/p2p/p2p_invitation.c | 3 | ||||
-rw-r--r-- | src/radius/radius_client.c | 117 | ||||
-rw-r--r-- | src/radius/radius_server.c | 1 | ||||
-rw-r--r-- | src/rsn_supp/wpa.c | 5 | ||||
-rw-r--r-- | wpa_supplicant/Makefile | 19 | ||||
-rw-r--r-- | wpa_supplicant/ctrl_iface.c | 4 | ||||
-rw-r--r-- | wpa_supplicant/interworking.c | 5 | ||||
-rw-r--r-- | wpa_supplicant/wpas_module_tests.c | 6 |
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; } |