aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2016-02-10 10:27:55 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-02-10 10:27:55 +0000
commitc6204db945c56037fd900dae22702ff232eff4b4 (patch)
tree80f954a05ff1a43c8873665e40ffbdb6cab8ffb2
parenta3b4dfeccdb95a9e69f4e1120f426f7ea76ced91 (diff)
parentb97e428f8acf1ecb93f38f8d0063d2f2fd0bc36e (diff)
downloadandroid_external_wpa_supplicant_8-c6204db945c56037fd900dae22702ff232eff4b4.tar.gz
android_external_wpa_supplicant_8-c6204db945c56037fd900dae22702ff232eff4b4.tar.bz2
android_external_wpa_supplicant_8-c6204db945c56037fd900dae22702ff232eff4b4.zip
Cumulative patch from commit c06c9099f0d0827feae5622097bd8ac946eca5ea
am: b97e428f8a * commit 'b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36e': Cumulative patch from commit c06c9099f0d0827feae5622097bd8ac946eca5ea
-rw-r--r--hostapd/Makefile4
-rw-r--r--hostapd/hostapd_cli.c2
-rw-r--r--hostapd/main.c13
-rw-r--r--src/ap/accounting.c106
-rw-r--r--src/ap/accounting.h7
-rw-r--r--src/ap/gas_serv.c20
-rw-r--r--src/ap/hostapd.c21
-rw-r--r--src/ap/hostapd.h5
-rw-r--r--src/ap/hw_features.c1
-rw-r--r--src/ap/ieee802_11_auth.c5
-rw-r--r--src/ap/ieee802_11_vht.c20
-rw-r--r--src/ap/ieee802_1x.c40
-rw-r--r--src/ap/pmksa_cache_auth.c15
-rw-r--r--src/ap/pmksa_cache_auth.h3
-rw-r--r--src/ap/sta_info.c7
-rw-r--r--src/ap/sta_info.h3
-rw-r--r--src/common/wpa_common.c6
-rw-r--r--src/common/wpa_ctrl.c2
-rw-r--r--src/crypto/tls_openssl.c130
-rw-r--r--src/crypto/tls_openssl_ocsp.c2
-rw-r--r--src/drivers/driver.h25
-rw-r--r--src/drivers/driver_bsd.c90
-rw-r--r--src/eap_peer/eap_fast_pac.c4
-rw-r--r--src/eapol_auth/eapol_auth_sm.c21
-rw-r--r--src/eapol_auth/eapol_auth_sm_i.h6
-rw-r--r--src/p2p/p2p_go_neg.c4
-rw-r--r--src/p2p/p2p_invitation.c2
-rw-r--r--src/p2p/p2p_pd.c2
-rw-r--r--src/radius/radius.c37
-rw-r--r--src/radius/radius.h5
-rw-r--r--src/utils/eloop.c292
-rw-r--r--src/utils/eloop.h8
-rw-r--r--src/utils/eloop_win.c6
-rw-r--r--src/utils/http_curl.c16
-rw-r--r--src/utils/wpabuf.h16
-rw-r--r--wpa_supplicant/Makefile4
-rw-r--r--wpa_supplicant/README3
-rw-r--r--wpa_supplicant/ap.c1
-rw-r--r--wpa_supplicant/dbus/dbus-wpa_supplicant.conf2
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers.c1
-rw-r--r--wpa_supplicant/eapol_test.c2
-rw-r--r--wpa_supplicant/mesh_mpm.c4
-rw-r--r--wpa_supplicant/mesh_mpm.h2
-rw-r--r--wpa_supplicant/wnm_sta.c17
-rw-r--r--wpa_supplicant/wpa_cli.c2
-rw-r--r--wpa_supplicant/wpa_priv.c2
-rw-r--r--wpa_supplicant/wpa_supplicant.c3
47 files changed, 698 insertions, 291 deletions
diff --git a/hostapd/Makefile b/hostapd/Makefile
index 45afedf4..fd3105e5 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -140,6 +140,10 @@ ifdef CONFIG_ELOOP_EPOLL
CFLAGS += -DCONFIG_ELOOP_EPOLL
endif
+ifdef CONFIG_ELOOP_KQUEUE
+CFLAGS += -DCONFIG_ELOOP_KQUEUE
+endif
+
OBJS += ../src/utils/common.o
OBJS_c += ../src/utils/common.o
OBJS += ../src/utils/wpa_debug.o
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index 52dfc9f3..7e6ac237 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -1444,7 +1444,7 @@ int main(int argc, char *argv[])
}
}
- if (daemonize && os_daemonize(pid_file))
+ if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())
return -1;
if (interactive)
diff --git a/hostapd/main.c b/hostapd/main.c
index 4913cbde..1b9002cf 100644
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -408,9 +408,16 @@ static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize,
}
#endif /* EAP_SERVER_TNC */
- if (daemonize && os_daemonize(pid_file)) {
- wpa_printf(MSG_ERROR, "daemon: %s", strerror(errno));
- return -1;
+ if (daemonize) {
+ if (os_daemonize(pid_file)) {
+ wpa_printf(MSG_ERROR, "daemon: %s", strerror(errno));
+ return -1;
+ }
+ if (eloop_sock_requeue()) {
+ wpa_printf(MSG_ERROR, "eloop_sock_requeue: %s",
+ strerror(errno));
+ return -1;
+ }
}
eloop_run();
diff --git a/src/ap/accounting.c b/src/ap/accounting.c
index c60b3a6c..f3ce1215 100644
--- a/src/ap/accounting.c
+++ b/src/ap/accounting.c
@@ -41,6 +41,7 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
size_t len;
int i;
struct wpabuf *b;
+ struct os_time now;
msg = radius_msg_new(RADIUS_CODE_ACCOUNTING_REQUEST,
radius_client_get_id(hapd->radius));
@@ -49,25 +50,9 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
return NULL;
}
- if (sta) {
- radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
-
- if ((hapd->conf->wpa & 2) &&
- !hapd->conf->disable_pmksa_caching &&
- sta->eapol_sm && sta->eapol_sm->acct_multi_session_id_hi) {
- os_snprintf(buf, sizeof(buf), "%08X+%08X",
- sta->eapol_sm->acct_multi_session_id_hi,
- sta->eapol_sm->acct_multi_session_id_lo);
- if (!radius_msg_add_attr(
- msg, RADIUS_ATTR_ACCT_MULTI_SESSION_ID,
- (u8 *) buf, os_strlen(buf))) {
- wpa_printf(MSG_INFO,
- "Could not add Acct-Multi-Session-Id");
- goto fail;
- }
- }
- } else {
- radius_msg_make_authenticator(msg, (u8 *) hapd, sizeof(*hapd));
+ if (radius_msg_make_authenticator(msg) < 0) {
+ wpa_printf(MSG_INFO, "Could not make Request Authenticator");
+ goto fail;
}
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_STATUS_TYPE,
@@ -76,17 +61,18 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
goto fail;
}
- if (!hostapd_config_get_radius_attr(hapd->conf->radius_acct_req_attr,
- RADIUS_ATTR_ACCT_AUTHENTIC) &&
- !radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC,
- hapd->conf->ieee802_1x ?
- RADIUS_ACCT_AUTHENTIC_RADIUS :
- RADIUS_ACCT_AUTHENTIC_LOCAL)) {
- wpa_printf(MSG_INFO, "Could not add Acct-Authentic");
- goto fail;
- }
-
if (sta) {
+ if (!hostapd_config_get_radius_attr(
+ hapd->conf->radius_acct_req_attr,
+ RADIUS_ATTR_ACCT_AUTHENTIC) &&
+ !radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC,
+ hapd->conf->ieee802_1x ?
+ RADIUS_ACCT_AUTHENTIC_RADIUS :
+ RADIUS_ACCT_AUTHENTIC_LOCAL)) {
+ wpa_printf(MSG_INFO, "Could not add Acct-Authentic");
+ goto fail;
+ }
+
/* Use 802.1X identity if available */
val = ieee802_1x_get_identity(sta->eapol_sm, &len);
@@ -158,6 +144,14 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
}
}
+ os_get_time(&now);
+ if (now.sec > 1000000000 &&
+ !radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP,
+ now.sec)) {
+ wpa_printf(MSG_INFO, "Could not add Event-Timestamp");
+ goto fail;
+ }
+
return msg;
fail:
@@ -226,8 +220,8 @@ void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta)
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO,
- "starting accounting session %08X-%08X",
- sta->acct_session_id_hi, sta->acct_session_id_lo);
+ "starting accounting session %016lX",
+ (long unsigned int) sta->acct_session_id);
os_get_reltime(&sta->acct_session_start);
sta->last_rx_bytes = sta->last_tx_bytes = 0;
@@ -260,7 +254,6 @@ static void accounting_sta_report(struct hostapd_data *hapd,
int cause = sta->acct_terminate_cause;
struct hostap_sta_driver_data data;
struct os_reltime now_r, diff;
- struct os_time now;
u32 gigawords;
if (!hapd->conf->radius->acct_server)
@@ -275,7 +268,6 @@ static void accounting_sta_report(struct hostapd_data *hapd,
}
os_get_reltime(&now_r);
- os_get_time(&now);
os_reltime_sub(&now_r, &sta->acct_session_start, &diff);
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_SESSION_TIME,
diff.sec)) {
@@ -332,12 +324,6 @@ static void accounting_sta_report(struct hostapd_data *hapd,
}
}
- if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP,
- now.sec)) {
- wpa_printf(MSG_INFO, "Could not add Event-Timestamp");
- goto fail;
- }
-
if (eloop_terminated())
cause = RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_REBOOT;
@@ -384,22 +370,17 @@ void accounting_sta_stop(struct hostapd_data *hapd, struct sta_info *sta)
eloop_cancel_timeout(accounting_interim_update, hapd, sta);
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO,
- "stopped accounting session %08X-%08X",
- sta->acct_session_id_hi,
- sta->acct_session_id_lo);
+ "stopped accounting session %016lX",
+ (long unsigned int) sta->acct_session_id);
sta->acct_session_started = 0;
}
}
-void accounting_sta_get_id(struct hostapd_data *hapd,
- struct sta_info *sta)
+int accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta)
{
- sta->acct_session_id_lo = hapd->acct_session_id_lo++;
- if (hapd->acct_session_id_lo == 0) {
- hapd->acct_session_id_hi++;
- }
- sta->acct_session_id_hi = hapd->acct_session_id_hi;
+ return radius_gen_session_id((u8 *) &sta->acct_session_id,
+ sizeof(sta->acct_session_id));
}
@@ -446,12 +427,14 @@ static void accounting_report_state(struct hostapd_data *hapd, int on)
if (!msg)
return;
- if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_TERMINATE_CAUSE,
- RADIUS_ACCT_TERMINATE_CAUSE_NAS_REBOOT))
- {
- wpa_printf(MSG_INFO, "Could not add Acct-Terminate-Cause");
- radius_msg_free(msg);
- return;
+ if (hapd->acct_session_id) {
+ char buf[20];
+
+ os_snprintf(buf, sizeof(buf), "%016lX",
+ (long unsigned int) hapd->acct_session_id);
+ if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID,
+ (u8 *) buf, os_strlen(buf)))
+ wpa_printf(MSG_ERROR, "Could not add Acct-Session-Id");
}
if (radius_client_send(hapd->radius, msg, RADIUS_ACCT, NULL) < 0)
@@ -466,16 +449,9 @@ static void accounting_report_state(struct hostapd_data *hapd, int on)
*/
int accounting_init(struct hostapd_data *hapd)
{
- struct os_time now;
-
- /* Acct-Session-Id should be unique over reboots. Using a random number
- * is preferred. If that is not available, take the current time. Mix
- * in microseconds to make this more likely to be unique. */
- os_get_time(&now);
- if (os_get_random((u8 *) &hapd->acct_session_id_hi,
- sizeof(hapd->acct_session_id_hi)) < 0)
- hapd->acct_session_id_hi = now.sec;
- hapd->acct_session_id_hi ^= now.usec;
+ if (radius_gen_session_id((u8 *) &hapd->acct_session_id,
+ sizeof(hapd->acct_session_id)) < 0)
+ return -1;
if (radius_client_register(hapd->radius, RADIUS_ACCT,
accounting_receive, hapd))
diff --git a/src/ap/accounting.h b/src/ap/accounting.h
index dcc54ee9..de5a33f3 100644
--- a/src/ap/accounting.h
+++ b/src/ap/accounting.h
@@ -10,9 +10,10 @@
#define ACCOUNTING_H
#ifdef CONFIG_NO_ACCOUNTING
-static inline void accounting_sta_get_id(struct hostapd_data *hapd,
- struct sta_info *sta)
+static inline int accounting_sta_get_id(struct hostapd_data *hapd,
+ struct sta_info *sta)
{
+ return 0;
}
static inline void accounting_sta_start(struct hostapd_data *hapd,
@@ -34,7 +35,7 @@ static inline void accounting_deinit(struct hostapd_data *hapd)
{
}
#else /* CONFIG_NO_ACCOUNTING */
-void accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta);
+int accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta);
void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta);
void accounting_sta_stop(struct hostapd_data *hapd, struct sta_info *sta);
int accounting_init(struct hostapd_data *hapd);
diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c
index b9d61762..179dc7a7 100644
--- a/src/ap/gas_serv.c
+++ b/src/ap/gas_serv.c
@@ -786,6 +786,24 @@ static void anqp_add_icon_binary_file(struct hostapd_data *hapd,
#endif /* CONFIG_HS20 */
+static size_t anqp_get_required_len(struct hostapd_data *hapd,
+ const u16 *infoid,
+ unsigned int num_infoid)
+{
+ size_t len = 0;
+ unsigned int i;
+
+ for (i = 0; i < num_infoid; i++) {
+ struct anqp_element *elem = get_anqp_elem(hapd, infoid[i]);
+
+ if (elem)
+ len += 2 + 2 + wpabuf_len(elem->payload);
+ }
+
+ return len;
+}
+
+
static struct wpabuf *
gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
unsigned int request,
@@ -803,7 +821,7 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
len += 1000;
if (request & ANQP_REQ_ICON_REQUEST)
len += 65536;
- len += num_extra_req * 1000;
+ len += anqp_get_required_len(hapd, extra_req, num_extra_req);
buf = wpabuf_alloc(len);
if (buf == NULL)
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 2aa4f8c6..a848f35e 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -673,7 +673,7 @@ static struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd,
if (attr->acct_session_id) {
num_attr++;
- if (attr->acct_session_id_len != 17) {
+ if (attr->acct_session_id_len != 16) {
wpa_printf(MSG_DEBUG,
"RADIUS DAS: Acct-Session-Id cannot match");
return NULL;
@@ -683,10 +683,9 @@ static struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd,
for (sta = hapd->sta_list; sta; sta = sta->next) {
if (!sta->radius_das_match)
continue;
- os_snprintf(buf, sizeof(buf), "%08X-%08X",
- sta->acct_session_id_hi,
- sta->acct_session_id_lo);
- if (os_memcmp(attr->acct_session_id, buf, 17) != 0)
+ os_snprintf(buf, sizeof(buf), "%016lX",
+ (long unsigned int) sta->acct_session_id);
+ if (os_memcmp(attr->acct_session_id, buf, 16) != 0)
sta->radius_das_match = 0;
else
count++;
@@ -702,7 +701,7 @@ static struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd,
if (attr->acct_multi_session_id) {
num_attr++;
- if (attr->acct_multi_session_id_len != 17) {
+ if (attr->acct_multi_session_id_len != 16) {
wpa_printf(MSG_DEBUG,
"RADIUS DAS: Acct-Multi-Session-Id cannot match");
return NULL;
@@ -713,14 +712,14 @@ static struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd,
if (!sta->radius_das_match)
continue;
if (!sta->eapol_sm ||
- !sta->eapol_sm->acct_multi_session_id_hi) {
+ !sta->eapol_sm->acct_multi_session_id) {
sta->radius_das_match = 0;
continue;
}
- os_snprintf(buf, sizeof(buf), "%08X+%08X",
- sta->eapol_sm->acct_multi_session_id_hi,
- sta->eapol_sm->acct_multi_session_id_lo);
- if (os_memcmp(attr->acct_multi_session_id, buf, 17) !=
+ os_snprintf(buf, sizeof(buf), "%016lX",
+ (long unsigned int)
+ sta->eapol_sm->acct_multi_session_id);
+ if (os_memcmp(attr->acct_multi_session_id, buf, 16) !=
0)
sta->radius_das_match = 0;
else
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 7b59f802..0f31dd45 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -138,7 +138,7 @@ struct hostapd_data {
void *msg_ctx_parent; /* parent interface ctx for wpa_msg() calls */
struct radius_client_data *radius;
- u32 acct_session_id_hi, acct_session_id_lo;
+ u64 acct_session_id;
struct radius_das_data *radius_das;
struct iapp_data *iapp;
@@ -258,7 +258,8 @@ struct hostapd_data {
#ifdef CONFIG_MESH
int num_plinks;
int max_plinks;
- void (*mesh_sta_free_cb)(struct sta_info *sta);
+ void (*mesh_sta_free_cb)(struct hostapd_data *hapd,
+ struct sta_info *sta);
struct wpabuf *mesh_pending_auth;
struct os_reltime mesh_pending_auth_time;
#endif /* CONFIG_MESH */
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index 36070668..16887acd 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -329,6 +329,7 @@ static void ieee80211n_check_scan(struct hostapd_iface *iface)
res = ieee80211n_allowed_ht40_channel_pair(iface);
if (!res) {
iface->conf->secondary_channel = 0;
+ res = 1;
wpa_printf(MSG_INFO, "Fallback to 20 MHz");
}
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index b7e7ce35..ec0037a5 100644
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -165,7 +165,10 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
if (msg == NULL)
return -1;
- radius_msg_make_authenticator(msg, addr, ETH_ALEN);
+ if (radius_msg_make_authenticator(msg) < 0) {
+ wpa_printf(MSG_INFO, "Could not make Request Authenticator");
+ goto fail;
+ }
os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT, MAC2STR(addr));
if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, (u8 *) buf,
diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c
index 3236016d..08418980 100644
--- a/src/ap/ieee802_11_vht.c
+++ b/src/ap/ieee802_11_vht.c
@@ -81,6 +81,26 @@ u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid)
hapd->iconf->vht_oper_centr_freq_seg1_idx;
oper->vht_op_info_chwidth = hapd->iconf->vht_oper_chwidth;
+ if (hapd->iconf->vht_oper_chwidth == 2) {
+ /*
+ * Convert 160 MHz channel width to new style as interop
+ * workaround.
+ */
+ oper->vht_op_info_chwidth = 1;
+ oper->vht_op_info_chan_center_freq_seg1_idx =
+ oper->vht_op_info_chan_center_freq_seg0_idx;
+ if (hapd->iconf->channel <
+ hapd->iconf->vht_oper_centr_freq_seg0_idx)
+ oper->vht_op_info_chan_center_freq_seg0_idx -= 8;
+ else
+ oper->vht_op_info_chan_center_freq_seg0_idx += 8;
+ } else if (hapd->iconf->vht_oper_chwidth == 3) {
+ /*
+ * Convert 80+80 MHz channel width to new style as interop
+ * workaround.
+ */
+ oper->vht_op_info_chwidth = 1;
+ }
/* VHT Basic MCS set comes from hw */
/* Hard code 1 stream, MCS0-7 is a min Basic VHT MCS rates */
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 607f9418..d399b1e5 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -438,9 +438,9 @@ static int add_common_radius_sta_attr(struct hostapd_data *hapd,
return -1;
}
- if (sta->acct_session_id_hi || sta->acct_session_id_lo) {
- os_snprintf(buf, sizeof(buf), "%08X-%08X",
- sta->acct_session_id_hi, sta->acct_session_id_lo);
+ if (sta->acct_session_id) {
+ os_snprintf(buf, sizeof(buf), "%016lX",
+ (long unsigned int) sta->acct_session_id);
if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID,
(u8 *) buf, os_strlen(buf))) {
wpa_printf(MSG_ERROR, "Could not add Acct-Session-Id");
@@ -448,6 +448,21 @@ static int add_common_radius_sta_attr(struct hostapd_data *hapd,
}
}
+ if ((hapd->conf->wpa & 2) &&
+ !hapd->conf->disable_pmksa_caching &&
+ sta->eapol_sm && sta->eapol_sm->acct_multi_session_id) {
+ os_snprintf(buf, sizeof(buf), "%016lX",
+ (long unsigned int)
+ sta->eapol_sm->acct_multi_session_id);
+ if (!radius_msg_add_attr(
+ msg, RADIUS_ATTR_ACCT_MULTI_SESSION_ID,
+ (u8 *) buf, os_strlen(buf))) {
+ wpa_printf(MSG_INFO,
+ "Could not add Acct-Multi-Session-Id");
+ return -1;
+ }
+ }
+
#ifdef CONFIG_IEEE80211R
if (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) &&
sta->wpa_sm &&
@@ -587,7 +602,10 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
return;
}
- radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
+ if (radius_msg_make_authenticator(msg) < 0) {
+ wpa_printf(MSG_INFO, "Could not make Request Authenticator");
+ goto fail;
+ }
if (sm->identity &&
!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
@@ -1165,10 +1183,8 @@ void ieee802_1x_free_station(struct hostapd_data *hapd, struct sta_info *sta)
#ifndef CONFIG_NO_RADIUS
radius_msg_free(sm->last_recv_radius);
radius_free_class(&sm->radius_class);
- wpabuf_free(sm->radius_cui);
#endif /* CONFIG_NO_RADIUS */
- os_free(sm->identity);
eapol_auth_free(sm);
}
@@ -2495,12 +2511,12 @@ int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
/* TODO: dot1xAuthSessionOctetsTx */
/* TODO: dot1xAuthSessionFramesRx */
/* TODO: dot1xAuthSessionFramesTx */
- "dot1xAuthSessionId=%08X-%08X\n"
+ "dot1xAuthSessionId=%016lX\n"
"dot1xAuthSessionAuthenticMethod=%d\n"
"dot1xAuthSessionTime=%u\n"
"dot1xAuthSessionTerminateCause=999\n"
"dot1xAuthSessionUserName=%s\n",
- sta->acct_session_id_hi, sta->acct_session_id_lo,
+ (long unsigned int) sta->acct_session_id,
(wpa_key_mgmt_wpa_ieee8021x(
wpa_auth_sta_key_mgmt(sta->wpa_sm))) ?
1 : 2,
@@ -2510,11 +2526,11 @@ int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
return len;
len += ret;
- if (sm->acct_multi_session_id_hi) {
+ if (sm->acct_multi_session_id) {
ret = os_snprintf(buf + len, buflen - len,
- "authMultiSessionId=%08X+%08X\n",
- sm->acct_multi_session_id_hi,
- sm->acct_multi_session_id_lo);
+ "authMultiSessionId=%016lX\n",
+ (long unsigned int)
+ sm->acct_multi_session_id);
if (os_snprintf_error(buflen - len, ret))
return len;
len += ret;
diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c
index 83e4bdab..eb37c788 100644
--- a/src/ap/pmksa_cache_auth.c
+++ b/src/ap/pmksa_cache_auth.c
@@ -148,8 +148,7 @@ static void pmksa_cache_from_eapol_data(struct rsn_pmksa_cache_entry *entry,
entry->eap_type_authsrv = eapol->eap_type_authsrv;
entry->vlan_id = ((struct sta_info *) eapol->sta)->vlan_id;
- entry->acct_multi_session_id_hi = eapol->acct_multi_session_id_hi;
- entry->acct_multi_session_id_lo = eapol->acct_multi_session_id_lo;
+ entry->acct_multi_session_id = eapol->acct_multi_session_id;
}
@@ -188,8 +187,7 @@ void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache_entry *entry,
eapol->eap_type_authsrv = entry->eap_type_authsrv;
((struct sta_info *) eapol->sta)->vlan_id = entry->vlan_id;
- eapol->acct_multi_session_id_hi = entry->acct_multi_session_id_hi;
- eapol->acct_multi_session_id_lo = entry->acct_multi_session_id_lo;
+ eapol->acct_multi_session_id = entry->acct_multi_session_id;
}
@@ -471,12 +469,11 @@ static int das_attr_match(struct rsn_pmksa_cache_entry *entry,
if (attr->acct_multi_session_id) {
char buf[20];
- if (attr->acct_multi_session_id_len != 17)
+ if (attr->acct_multi_session_id_len != 16)
return 0;
- os_snprintf(buf, sizeof(buf), "%08X+%08X",
- entry->acct_multi_session_id_hi,
- entry->acct_multi_session_id_lo);
- if (os_memcmp(attr->acct_multi_session_id, buf, 17) != 0)
+ os_snprintf(buf, sizeof(buf), "%016lX",
+ (long unsigned int) entry->acct_multi_session_id);
+ if (os_memcmp(attr->acct_multi_session_id, buf, 16) != 0)
return 0;
match++;
}
diff --git a/src/ap/pmksa_cache_auth.h b/src/ap/pmksa_cache_auth.h
index b2da379b..4dc841f4 100644
--- a/src/ap/pmksa_cache_auth.h
+++ b/src/ap/pmksa_cache_auth.h
@@ -31,8 +31,7 @@ struct rsn_pmksa_cache_entry {
int vlan_id;
int opportunistic;
- u32 acct_multi_session_id_hi;
- u32 acct_multi_session_id_lo;
+ u64 acct_multi_session_id;
};
struct rsn_pmksa_cache;
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 8bba73cc..3d7c8391 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -238,7 +238,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
#ifdef CONFIG_MESH
if (hapd->mesh_sta_free_cb)
- hapd->mesh_sta_free_cb(sta);
+ hapd->mesh_sta_free_cb(hapd, sta);
#endif /* CONFIG_MESH */
if (set_beacon)
@@ -625,7 +625,10 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
return NULL;
}
sta->acct_interim_interval = hapd->conf->acct_interim_interval;
- accounting_sta_get_id(hapd, sta);
+ if (accounting_sta_get_id(hapd, sta) < 0) {
+ os_free(sta);
+ return NULL;
+ }
if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) {
wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index e3b4915a..359f480b 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -101,8 +101,7 @@ struct sta_info {
/* IEEE 802.1X related data */
struct eapol_state_machine *eapol_sm;
- u32 acct_session_id_hi;
- u32 acct_session_id_lo;
+ u64 acct_session_id;
struct os_reltime acct_session_start;
int acct_session_started;
int acct_terminate_cause; /* Acct-Terminate-Cause */
diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
index b5f57b3e..d6295b2d 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -600,8 +600,10 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
if (left >= RSN_SELECTOR_LEN) {
data->group_cipher = rsn_selector_to_bitfield(pos);
if (!wpa_cipher_valid_group(data->group_cipher)) {
- wpa_printf(MSG_DEBUG, "%s: invalid group cipher 0x%x",
- __func__, data->group_cipher);
+ wpa_printf(MSG_DEBUG,
+ "%s: invalid group cipher 0x%x (%08x)",
+ __func__, data->group_cipher,
+ WPA_GET_BE32(pos));
return -1;
}
pos += RSN_SELECTOR_LEN;
diff --git a/src/common/wpa_ctrl.c b/src/common/wpa_ctrl.c
index 5733aa60..623c2a76 100644
--- a/src/common/wpa_ctrl.c
+++ b/src/common/wpa_ctrl.c
@@ -532,6 +532,8 @@ retry_send:
FD_ZERO(&rfds);
FD_SET(ctrl->s, &rfds);
res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
+ if (res < 0 && errno == EINTR)
+ continue;
if (res < 0)
return res;
if (FD_ISSET(ctrl->s, &rfds)) {
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index b16b5197..e34a3d07 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -105,6 +105,66 @@ static BIO * BIO_from_keystore(const char *key)
free(value);
return bio;
}
+
+
+static int tls_add_ca_from_keystore(X509_STORE *ctx, const char *key_alias)
+{
+ BIO *bio = BIO_from_keystore(key_alias);
+ STACK_OF(X509_INFO) *stack = NULL;
+ stack_index_t i;
+
+ if (bio) {
+ stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+ }
+
+ if (!stack) {
+ wpa_printf(MSG_WARNING, "TLS: Failed to parse certificate: %s",
+ key_alias);
+ return -1;
+ }
+
+ for (i = 0; i < sk_X509_INFO_num(stack); ++i) {
+ X509_INFO *info = sk_X509_INFO_value(stack, i);
+
+ if (info->x509)
+ X509_STORE_add_cert(ctx, info->x509);
+ if (info->crl)
+ X509_STORE_add_crl(ctx, info->crl);
+ }
+
+ sk_X509_INFO_pop_free(stack, X509_INFO_free);
+
+ return 0;
+}
+
+
+static int tls_add_ca_from_keystore_encoded(X509_STORE *ctx,
+ const char *encoded_key_alias)
+{
+ int rc = -1;
+ int len = os_strlen(encoded_key_alias);
+ unsigned char *decoded_alias;
+
+ if (len & 1) {
+ wpa_printf(MSG_WARNING, "Invalid hex-encoded alias: %s",
+ encoded_key_alias);
+ return rc;
+ }
+
+ decoded_alias = os_malloc(len / 2 + 1);
+ if (decoded_alias) {
+ if (!hexstr2bin(encoded_key_alias, decoded_alias, len / 2)) {
+ decoded_alias[len / 2] = '\0';
+ rc = tls_add_ca_from_keystore(
+ ctx, (const char *) decoded_alias);
+ }
+ os_free(decoded_alias);
+ }
+
+ return rc;
+}
+
#endif /* ANDROID */
static int tls_openssl_ref_count = 0;
@@ -1989,30 +2049,40 @@ static int tls_connection_ca_cert(struct tls_data *data,
}
#ifdef ANDROID
+ /* Single alias */
if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) {
- BIO *bio = BIO_from_keystore(&ca_cert[11]);
- STACK_OF(X509_INFO) *stack = NULL;
- stack_index_t i;
-
- if (bio) {
- stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
- BIO_free(bio);
- }
- if (!stack)
+ if (tls_add_ca_from_keystore(ssl_ctx->cert_store,
+ &ca_cert[11]) < 0)
return -1;
+ SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
+ return 0;
+ }
- for (i = 0; i < sk_X509_INFO_num(stack); ++i) {
- X509_INFO *info = sk_X509_INFO_value(stack, i);
- if (info->x509) {
- X509_STORE_add_cert(ssl_ctx->cert_store,
- info->x509);
- }
- if (info->crl) {
- X509_STORE_add_crl(ssl_ctx->cert_store,
- info->crl);
+ /* Multiple aliases separated by space */
+ if (ca_cert && os_strncmp("keystores://", ca_cert, 12) == 0) {
+ char *aliases = os_strdup(&ca_cert[12]);
+ const char *delim = " ";
+ int rc = 0;
+ char *savedptr;
+ char *alias;
+
+ if (!aliases)
+ return -1;
+ alias = strtok_r(aliases, delim, &savedptr);
+ for (; alias; alias = strtok_r(NULL, delim, &savedptr)) {
+ if (tls_add_ca_from_keystore_encoded(
+ ssl_ctx->cert_store, alias)) {
+ wpa_printf(MSG_WARNING,
+ "OpenSSL: %s - Failed to add ca_cert %s from keystore",
+ __func__, alias);
+ rc = -1;
+ break;
}
}
- sk_X509_INFO_pop_free(stack, X509_INFO_free);
+ os_free(aliases);
+ if (rc)
+ return rc;
+
SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
return 0;
}
@@ -2393,13 +2463,18 @@ static int tls_parse_pkcs12(struct tls_data *data, SSL *ssl, PKCS12 *p12,
if (certs) {
#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
- SSL_clear_chain_certs(ssl);
+ if (ssl)
+ SSL_clear_chain_certs(ssl);
+ else
+ SSL_CTX_clear_chain_certs(data->ssl);
while ((cert = sk_X509_pop(certs)) != NULL) {
X509_NAME_oneline(X509_get_subject_name(cert), buf,
sizeof(buf));
wpa_printf(MSG_DEBUG, "TLS: additional certificate"
" from PKCS12: subject='%s'", buf);
- if (SSL_add1_chain_cert(ssl, cert) != 1) {
+ if ((ssl && SSL_add1_chain_cert(ssl, cert) != 1) ||
+ (!ssl && SSL_CTX_add1_chain_cert(data->ssl,
+ cert) != 1)) {
tls_show_errors(MSG_DEBUG, __func__,
"Failed to add additional certificate");
res = -1;
@@ -2411,9 +2486,16 @@ static int tls_parse_pkcs12(struct tls_data *data, SSL *ssl, PKCS12 *p12,
}
sk_X509_free(certs);
#ifndef OPENSSL_IS_BORINGSSL
- res = SSL_build_cert_chain(ssl,
- SSL_BUILD_CHAIN_FLAG_CHECK |
- SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR);
+ if (ssl)
+ res = SSL_build_cert_chain(
+ ssl,
+ SSL_BUILD_CHAIN_FLAG_CHECK |
+ SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR);
+ else
+ res = SSL_CTX_build_cert_chain(
+ data->ssl,
+ SSL_BUILD_CHAIN_FLAG_CHECK |
+ SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR);
if (!res) {
tls_show_errors(MSG_DEBUG, __func__,
"Failed to build certificate chain");
diff --git a/src/crypto/tls_openssl_ocsp.c b/src/crypto/tls_openssl_ocsp.c
index 37c87f40..4e1c6b94 100644
--- a/src/crypto/tls_openssl_ocsp.c
+++ b/src/crypto/tls_openssl_ocsp.c
@@ -562,6 +562,8 @@ enum ocsp_result check_ocsp_resp(SSL_CTX *ssl_ctx, SSL *ssl, X509 *cert,
if (basic->certs) {
untrusted = sk_X509_dup(basic->certs);
+ if (!untrusted)
+ goto fail;
num = sk_X509_num(basic->certs);
for (i = 0; i < num; i++) {
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 6fd72c5a..aad0e041 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -293,6 +293,18 @@ struct wpa_interface_info {
#define WPAS_MAX_SCAN_SSIDS 16
/**
+ * struct wpa_driver_scan_ssid - SSIDs to scan for
+ * @ssid - specific SSID to scan for (ProbeReq)
+ * %NULL or zero-length SSID is used to indicate active scan
+ * with wildcard SSID.
+ * @ssid_len - Length of the SSID in octets
+ */
+struct wpa_driver_scan_ssid {
+ const u8 *ssid;
+ size_t ssid_len;
+};
+
+/**
* struct wpa_driver_scan_params - Scan parameters
* Data for struct wpa_driver_ops::scan2().
*/
@@ -300,18 +312,7 @@ struct wpa_driver_scan_params {
/**
* ssids - SSIDs to scan for
*/
- struct wpa_driver_scan_ssid {
- /**
- * ssid - specific SSID to scan for (ProbeReq)
- * %NULL or zero-length SSID is used to indicate active scan
- * with wildcard SSID.
- */
- const u8 *ssid;
- /**
- * ssid_len: Length of the SSID in octets
- */
- size_t ssid_len;
- } ssids[WPAS_MAX_SCAN_SSIDS];
+ struct wpa_driver_scan_ssid ssids[WPAS_MAX_SCAN_SSIDS];
/**
* num_ssids - Number of entries in ssids array
diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index 780c19bc..99f35040 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -62,6 +62,7 @@ struct bsd_driver_data {
struct l2_packet_data *sock_xmit;/* raw packet xmit socket */
char ifname[IFNAMSIZ+1]; /* interface name */
+ int flags;
unsigned int ifindex; /* interface index */
void *ctx;
struct wpa_driver_capa capa; /* driver capability */
@@ -93,6 +94,9 @@ bsd_set80211(void *priv, int op, int val, const void *arg, int arg_len)
struct bsd_driver_data *drv = priv;
struct ieee80211req ireq;
+ if (drv->ifindex == 0)
+ return -1;
+
os_memset(&ireq, 0, sizeof(ireq));
os_strlcpy(ireq.i_name, drv->ifname, sizeof(ireq.i_name));
ireq.i_type = op;
@@ -287,6 +291,7 @@ bsd_ctrl_iface(void *priv, int enable)
strerror(errno));
return -1;
}
+ drv->flags = ifr.ifr_flags;
if (enable) {
if (ifr.ifr_flags & IFF_UP)
@@ -304,6 +309,7 @@ bsd_ctrl_iface(void *priv, int enable)
return -1;
}
+ drv->flags = ifr.ifr_flags;
return 0;
}
@@ -773,12 +779,12 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
rtm->rtm_version);
return;
}
- drv = bsd_get_drvindex(global, rtm->rtm_index);
- if (drv == NULL)
- return;
switch (rtm->rtm_type) {
case RTM_IEEE80211:
ifan = (struct if_announcemsghdr *) rtm;
+ drv = bsd_get_drvindex(global, ifan->ifan_index);
+ if (drv == NULL)
+ return;
switch (ifan->ifan_what) {
case RTM_IEEE80211_ASSOC:
case RTM_IEEE80211_REASSOC:
@@ -878,7 +884,8 @@ bsd_deinit(void *priv)
{
struct bsd_driver_data *drv = priv;
- bsd_ctrl_iface(drv, 0);
+ if (drv->ifindex != 0)
+ bsd_ctrl_iface(drv, 0);
if (drv->sock_xmit != NULL)
l2_packet_deinit(drv->sock_xmit);
os_free(drv);
@@ -966,7 +973,7 @@ wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy)
int ret = 0;
wpa_printf(MSG_DEBUG, "%s: wpa=%d privacy=%d",
- __FUNCTION__, wpa, privacy);
+ __func__, wpa, privacy);
if (!wpa && wpa_driver_bsd_set_wpa_ie(priv, NULL, 0) < 0)
ret = -1;
@@ -981,7 +988,7 @@ wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy)
static int
wpa_driver_bsd_set_wpa(void *priv, int enabled)
{
- wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
+ wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
return wpa_driver_bsd_set_wpa_internal(priv, enabled ? 3 : 0, enabled);
}
@@ -1189,6 +1196,7 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
struct bsd_driver_global *global = sock_ctx;
struct bsd_driver_data *drv;
struct if_announcemsghdr *ifan;
+ struct if_msghdr *ifm;
struct rt_msghdr *rtm;
union wpa_event_data event;
struct ieee80211_michael_event *mic;
@@ -1210,19 +1218,20 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
rtm->rtm_version);
return;
}
- drv = bsd_get_drvindex(global, rtm->rtm_index);
- if (drv == NULL)
- return;
- ctx = drv->ctx;
os_memset(&event, 0, sizeof(event));
switch (rtm->rtm_type) {
case RTM_IFANNOUNCE:
ifan = (struct if_announcemsghdr *) rtm;
+ drv = bsd_get_drvindex(global, ifan->ifan_index);
+ if (drv == NULL)
+ return;
os_strlcpy(event.interface_status.ifname, drv->ifname,
sizeof(event.interface_status.ifname));
switch (ifan->ifan_what) {
case IFAN_DEPARTURE:
event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
+ drv->ifindex = 0;
+ break;
default:
return;
}
@@ -1230,37 +1239,41 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
event.interface_status.ifname,
ifan->ifan_what == IFAN_DEPARTURE ?
"removed" : "added");
- wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
+ wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
break;
case RTM_IEEE80211:
ifan = (struct if_announcemsghdr *) rtm;
+ drv = bsd_get_drvindex(global, ifan->ifan_index);
+ if (drv == NULL)
+ return;
switch (ifan->ifan_what) {
case RTM_IEEE80211_ASSOC:
case RTM_IEEE80211_REASSOC:
if (drv->is_ap)
break;
- wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
+ wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
break;
case RTM_IEEE80211_DISASSOC:
if (drv->is_ap)
break;
- wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL);
+ wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
break;
case RTM_IEEE80211_SCAN:
if (drv->is_ap)
break;
- wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
+ wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS,
+ NULL);
break;
case RTM_IEEE80211_LEAVE:
leave = (struct ieee80211_leave_event *) &ifan[1];
- drv_event_disassoc(ctx, leave->iev_addr);
+ drv_event_disassoc(drv->ctx, leave->iev_addr);
break;
case RTM_IEEE80211_JOIN:
#ifdef RTM_IEEE80211_REJOIN
case RTM_IEEE80211_REJOIN:
#endif
join = (struct ieee80211_join_event *) &ifan[1];
- bsd_new_sta(drv, ctx, join->iev_addr);
+ bsd_new_sta(drv, drv->ctx, join->iev_addr);
break;
case RTM_IEEE80211_REPLAY:
/* ignore */
@@ -1275,20 +1288,30 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
os_memset(&event, 0, sizeof(event));
event.michael_mic_failure.unicast =
!IEEE80211_IS_MULTICAST(mic->iev_dst);
- wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE,
- &event);
+ wpa_supplicant_event(drv->ctx,
+ EVENT_MICHAEL_MIC_FAILURE, &event);
break;
}
break;
case RTM_IFINFO:
- if ((rtm->rtm_flags & RTF_UP) == 0) {
- os_strlcpy(event.interface_status.ifname, drv->ifname,
- sizeof(event.interface_status.ifname));
- event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
+ ifm = (struct if_msghdr *) rtm;
+ drv = bsd_get_drvindex(global, ifm->ifm_index);
+ if (drv == NULL)
+ return;
+ if ((ifm->ifm_flags & IFF_UP) == 0 &&
+ (drv->flags & IFF_UP) != 0) {
wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
- event.interface_status.ifname);
- wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
+ drv->ifname);
+ wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED,
+ NULL);
+ } else if ((ifm->ifm_flags & IFF_UP) != 0 &&
+ (drv->flags & IFF_UP) == 0) {
+ wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' UP",
+ drv->ifname);
+ wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
+ NULL);
}
+ drv->flags = ifm->ifm_flags;
break;
}
}
@@ -1559,16 +1582,21 @@ wpa_driver_bsd_deinit(void *priv)
{
struct bsd_driver_data *drv = priv;
- wpa_driver_bsd_set_wpa(drv, 0);
+ if (drv->ifindex != 0) {
+ wpa_driver_bsd_set_wpa(drv, 0);
- /* NB: mark interface down */
- bsd_ctrl_iface(drv, 0);
+ /* NB: mark interface down */
+ bsd_ctrl_iface(drv, 0);
- wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy);
+ wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa,
+ drv->prev_privacy);
- if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0)
- wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state",
- __func__);
+ if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)
+ < 0)
+ wpa_printf(MSG_DEBUG,
+ "%s: failed to restore roaming state",
+ __func__);
+ }
if (drv->sock_xmit != NULL)
l2_packet_deinit(drv->sock_xmit);
diff --git a/src/eap_peer/eap_fast_pac.c b/src/eap_peer/eap_fast_pac.c
index 0220caed..c8158603 100644
--- a/src/eap_peer/eap_fast_pac.c
+++ b/src/eap_peer/eap_fast_pac.c
@@ -802,8 +802,10 @@ int eap_fast_load_pac_bin(struct eap_sm *sm, struct eap_fast_pac **pac_root,
while (pos < end) {
u16 val;
- if (end - pos < 2 + EAP_FAST_PAC_KEY_LEN + 2 + 2)
+ if (end - pos < 2 + EAP_FAST_PAC_KEY_LEN + 2 + 2) {
+ pac = NULL;
goto parse_fail;
+ }
pac = os_zalloc(sizeof(*pac));
if (pac == NULL)
diff --git a/src/eapol_auth/eapol_auth_sm.c b/src/eapol_auth/eapol_auth_sm.c
index ff33d286..ff673bb2 100644
--- a/src/eapol_auth/eapol_auth_sm.c
+++ b/src/eapol_auth/eapol_auth_sm.c
@@ -866,10 +866,13 @@ eapol_auth_alloc(struct eapol_authenticator *eapol, const u8 *addr,
sm->radius_cui = wpabuf_alloc_copy(radius_cui,
os_strlen(radius_cui));
- sm->acct_multi_session_id_lo = eapol->acct_multi_session_id_lo++;
- if (eapol->acct_multi_session_id_lo == 0)
- eapol->acct_multi_session_id_hi++;
- sm->acct_multi_session_id_hi = eapol->acct_multi_session_id_hi;
+#ifndef CONFIG_NO_RADIUS
+ if (radius_gen_session_id((u8 *) &sm->acct_multi_session_id,
+ sizeof(sm->acct_multi_session_id)) < 0) {
+ eapol_auth_free(sm);
+ return NULL;
+ }
+#endif /* CONFIG_NO_RADIUS */
return sm;
}
@@ -884,6 +887,9 @@ void eapol_auth_free(struct eapol_state_machine *sm)
eloop_cancel_timeout(eapol_sm_step_cb, sm, NULL);
if (sm->eap)
eap_server_sm_deinit(sm->eap);
+
+ wpabuf_free(sm->radius_cui);
+ os_free(sm->identity);
os_free(sm);
}
@@ -1271,7 +1277,6 @@ struct eapol_authenticator * eapol_auth_init(struct eapol_auth_config *conf,
struct eapol_auth_cb *cb)
{
struct eapol_authenticator *eapol;
- struct os_time now;
eapol = os_zalloc(sizeof(*eapol));
if (eapol == NULL)
@@ -1300,12 +1305,6 @@ struct eapol_authenticator * eapol_auth_init(struct eapol_auth_config *conf,
eapol->cb.erp_get_key = cb->erp_get_key;
eapol->cb.erp_add_key = cb->erp_add_key;
- /* Acct-Multi-Session-Id should be unique over reboots. If reliable
- * clock is not available, this could be replaced with reboot counter,
- * etc. */
- os_get_time(&now);
- eapol->acct_multi_session_id_hi = now.sec;
-
return eapol;
}
diff --git a/src/eapol_auth/eapol_auth_sm_i.h b/src/eapol_auth/eapol_auth_sm_i.h
index aa3e117e..04386b2c 100644
--- a/src/eapol_auth/eapol_auth_sm_i.h
+++ b/src/eapol_auth/eapol_auth_sm_i.h
@@ -30,9 +30,6 @@ struct eapol_authenticator {
u8 *default_wep_key;
u8 default_wep_key_idx;
-
- u32 acct_multi_session_id_hi;
- u32 acct_multi_session_id_lo;
};
@@ -173,8 +170,7 @@ struct eapol_state_machine {
int remediation;
- u32 acct_multi_session_id_hi;
- u32 acct_multi_session_id_lo;
+ u64 acct_multi_session_id;
};
#endif /* EAPOL_AUTH_SM_I_H */
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index 049ce6e9..fe0096f1 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -1060,7 +1060,7 @@ fail:
P2P_PENDING_GO_NEG_RESPONSE_FAILURE;
if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
p2p->cfg->dev_addr,
- wpabuf_head(resp), wpabuf_len(resp), 500) < 0) {
+ wpabuf_head(resp), wpabuf_len(resp), 100) < 0) {
p2p_dbg(p2p, "Failed to send Action frame");
}
@@ -1394,7 +1394,7 @@ fail:
if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, sa,
wpabuf_head(dev->go_neg_conf),
- wpabuf_len(dev->go_neg_conf), 200) < 0) {
+ wpabuf_len(dev->go_neg_conf), 50) < 0) {
p2p_dbg(p2p, "Failed to send Action frame");
p2p_go_neg_failed(p2p, -1);
p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c
index 70da15a9..bbba001a 100644
--- a/src/p2p/p2p_invitation.c
+++ b/src/p2p/p2p_invitation.c
@@ -418,7 +418,7 @@ fail:
p2p->pending_action_state = P2P_PENDING_INVITATION_RESPONSE;
if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
p2p->cfg->dev_addr,
- wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
+ wpabuf_head(resp), wpabuf_len(resp), 50) < 0) {
p2p_dbg(p2p, "Failed to send Action frame");
}
diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c
index d70a43c2..e6535d41 100644
--- a/src/p2p/p2p_pd.c
+++ b/src/p2p/p2p_pd.c
@@ -997,7 +997,7 @@ out:
if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
p2p->cfg->dev_addr,
wpabuf_head(resp), wpabuf_len(resp),
- 200) < 0)
+ 50) < 0)
p2p_dbg(p2p, "Failed to send Action frame");
else
p2p->send_action_in_progress = 1;
diff --git a/src/radius/radius.c b/src/radius/radius.c
index 266b29f7..a6304e1c 100644
--- a/src/radius/radius.c
+++ b/src/radius/radius.c
@@ -893,25 +893,11 @@ int radius_msg_copy_attr(struct radius_msg *dst, struct radius_msg *src,
/* Create Request Authenticator. The value should be unique over the lifetime
* of the shared secret between authenticator and authentication server.
- * Use one-way MD5 hash calculated from current timestamp and some data given
- * by the caller. */
-void radius_msg_make_authenticator(struct radius_msg *msg,
- const u8 *data, size_t len)
+ */
+int radius_msg_make_authenticator(struct radius_msg *msg)
{
- struct os_time tv;
- long int l;
- const u8 *addr[3];
- size_t elen[3];
-
- os_get_time(&tv);
- l = os_random();
- addr[0] = (u8 *) &tv;
- elen[0] = sizeof(tv);
- addr[1] = data;
- elen[1] = len;
- addr[2] = (u8 *) &l;
- elen[2] = sizeof(l);
- md5_vector(3, addr, elen, msg->hdr->authenticator);
+ return os_get_random((u8 *) &msg->hdr->authenticator,
+ sizeof(msg->hdr->authenticator));
}
@@ -1211,7 +1197,9 @@ int radius_msg_add_mppe_keys(struct radius_msg *msg,
vhdr = (struct radius_attr_vendor *) pos;
vhdr->vendor_type = RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY;
pos = (u8 *) (vhdr + 1);
- salt = os_random() | 0x8000;
+ if (os_get_random((u8 *) &salt, sizeof(salt)) < 0)
+ return 0;
+ salt |= 0x8000;
WPA_PUT_BE16(pos, salt);
pos += 2;
encrypt_ms_key(send_key, send_key_len, salt, req_authenticator, secret,
@@ -1670,3 +1658,14 @@ u8 radius_msg_find_unlisted_attr(struct radius_msg *msg, u8 *attrs)
return 0;
}
+
+
+int radius_gen_session_id(u8 *id, size_t len)
+{
+ /*
+ * Acct-Session-Id and Acct-Multi-Session-Id should be globally and
+ * temporarily unique. A high quality random number is required
+ * therefore. This could be be improved by switching to a GUID.
+ */
+ return os_get_random(id, len);
+}
diff --git a/src/radius/radius.h b/src/radius/radius.h
index f14de530..313fc650 100644
--- a/src/radius/radius.h
+++ b/src/radius/radius.h
@@ -251,8 +251,7 @@ int radius_msg_verify_msg_auth(struct radius_msg *msg, const u8 *secret,
size_t secret_len, const u8 *req_auth);
int radius_msg_copy_attr(struct radius_msg *dst, struct radius_msg *src,
u8 type);
-void radius_msg_make_authenticator(struct radius_msg *msg,
- const u8 *data, size_t len);
+int radius_msg_make_authenticator(struct radius_msg *msg);
struct radius_ms_mppe_keys *
radius_msg_get_ms_keys(struct radius_msg *msg, struct radius_msg *sent_msg,
const u8 *secret, size_t secret_len);
@@ -320,4 +319,6 @@ int radius_copy_class(struct radius_class_data *dst,
u8 radius_msg_find_unlisted_attr(struct radius_msg *msg, u8 *attrs);
+int radius_gen_session_id(u8 *id, size_t len);
+
#endif /* RADIUS_H */
diff --git a/src/utils/eloop.c b/src/utils/eloop.c
index 8647229b..831da122 100644
--- a/src/utils/eloop.c
+++ b/src/utils/eloop.c
@@ -18,7 +18,12 @@
#error Do not define both of poll and epoll
#endif
-#if !defined(CONFIG_ELOOP_POLL) && !defined(CONFIG_ELOOP_EPOLL)
+#if defined(CONFIG_ELOOP_POLL) && defined(CONFIG_ELOOP_KQUEUE)
+#error Do not define both of poll and kqueue
+#endif
+
+#if !defined(CONFIG_ELOOP_POLL) && !defined(CONFIG_ELOOP_EPOLL) && \
+ !defined(CONFIG_ELOOP_KQUEUE)
#define CONFIG_ELOOP_SELECT
#endif
@@ -30,6 +35,10 @@
#include <sys/epoll.h>
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+#include <sys/event.h>
+#endif /* CONFIG_ELOOP_KQUEUE */
+
struct eloop_sock {
int sock;
void *eloop_data;
@@ -75,13 +84,20 @@ struct eloop_data {
struct pollfd *pollfds;
struct pollfd **pollfds_map;
#endif /* CONFIG_ELOOP_POLL */
+#if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE)
+ int max_fd;
+ struct eloop_sock *fd_table;
+#endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */
#ifdef CONFIG_ELOOP_EPOLL
int epollfd;
int epoll_max_event_num;
- int epoll_max_fd;
- struct eloop_sock *epoll_table;
struct epoll_event *epoll_events;
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ int kqueuefd;
+ int kqueue_nevents;
+ struct kevent *kqueue_events;
+#endif /* CONFIG_ELOOP_KQUEUE */
struct eloop_sock_table readers;
struct eloop_sock_table writers;
struct eloop_sock_table exceptions;
@@ -149,14 +165,24 @@ int eloop_init(void)
#ifdef CONFIG_ELOOP_EPOLL
eloop.epollfd = epoll_create1(0);
if (eloop.epollfd < 0) {
- wpa_printf(MSG_ERROR, "%s: epoll_create1 failed. %s\n",
+ wpa_printf(MSG_ERROR, "%s: epoll_create1 failed. %s",
+ __func__, strerror(errno));
+ return -1;
+ }
+#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ eloop.kqueuefd = kqueue();
+ if (eloop.kqueuefd < 0) {
+ wpa_printf(MSG_ERROR, "%s: kqueue failed: %s",
__func__, strerror(errno));
return -1;
}
+#endif /* CONFIG_ELOOP_KQUEUE */
+#if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE)
eloop.readers.type = EVENT_TYPE_READ;
eloop.writers.type = EVENT_TYPE_WRITE;
eloop.exceptions.type = EVENT_TYPE_EXCEPTION;
-#endif /* CONFIG_ELOOP_EPOLL */
+#endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */
#ifdef WPA_TRACE
signal(SIGSEGV, eloop_sigsegv_handler);
#endif /* WPA_TRACE */
@@ -164,15 +190,80 @@ int eloop_init(void)
}
+#ifdef CONFIG_ELOOP_EPOLL
+static int eloop_sock_queue(int sock, eloop_event_type type)
+{
+ struct epoll_event ev;
+
+ os_memset(&ev, 0, sizeof(ev));
+ switch (type) {
+ case EVENT_TYPE_READ:
+ ev.events = EPOLLIN;
+ break;
+ case EVENT_TYPE_WRITE:
+ ev.events = EPOLLOUT;
+ break;
+ /*
+ * Exceptions are always checked when using epoll, but I suppose it's
+ * possible that someone registered a socket *only* for exception
+ * handling.
+ */
+ case EVENT_TYPE_EXCEPTION:
+ ev.events = EPOLLERR | EPOLLHUP;
+ break;
+ }
+ ev.data.fd = sock;
+ if (epoll_ctl(eloop.epollfd, EPOLL_CTL_ADD, sock, &ev) < 0) {
+ wpa_printf(MSG_ERROR, "%s: epoll_ctl(ADD) for fd=%d failed: %s",
+ __func__, sock, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+#endif /* CONFIG_ELOOP_EPOLL */
+
+
+#ifdef CONFIG_ELOOP_KQUEUE
+static int eloop_sock_queue(int sock, eloop_event_type type)
+{
+ int filter;
+ struct kevent ke;
+
+ switch (type) {
+ case EVENT_TYPE_READ:
+ filter = EVFILT_READ;
+ break;
+ case EVENT_TYPE_WRITE:
+ filter = EVFILT_WRITE;
+ break;
+ default:
+ filter = 0;
+ }
+ EV_SET(&ke, sock, filter, EV_ADD, 0, 0, NULL);
+ if (kevent(eloop.kqueuefd, &ke, 1, NULL, 0, NULL) == -1) {
+ wpa_printf(MSG_ERROR, "%s: kevent(ADD) for fd=%d failed: %s",
+ __func__, sock, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+#endif /* CONFIG_ELOOP_KQUEUE */
+
+
static int eloop_sock_table_add_sock(struct eloop_sock_table *table,
int sock, eloop_sock_handler handler,
void *eloop_data, void *user_data)
{
#ifdef CONFIG_ELOOP_EPOLL
+ struct epoll_event *temp_events;
+#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ struct kevent *temp_events;
+#endif /* CONFIG_ELOOP_EPOLL */
+#if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE)
struct eloop_sock *temp_table;
- struct epoll_event ev, *temp_events;
int next;
-#endif /* CONFIG_ELOOP_EPOLL */
+#endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */
struct eloop_sock *tmp;
int new_max_sock;
@@ -208,26 +299,28 @@ static int eloop_sock_table_add_sock(struct eloop_sock_table *table,
eloop.pollfds = n;
}
#endif /* CONFIG_ELOOP_POLL */
-#ifdef CONFIG_ELOOP_EPOLL
- if (new_max_sock >= eloop.epoll_max_fd) {
- next = eloop.epoll_max_fd == 0 ? 16 : eloop.epoll_max_fd * 2;
- temp_table = os_realloc_array(eloop.epoll_table, next,
+#if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE)
+ if (new_max_sock >= eloop.max_fd) {
+ next = eloop.max_fd == 0 ? 16 : eloop.max_fd * 2;
+ temp_table = os_realloc_array(eloop.fd_table, next,
sizeof(struct eloop_sock));
if (temp_table == NULL)
return -1;
- eloop.epoll_max_fd = next;
- eloop.epoll_table = temp_table;
+ eloop.max_fd = next;
+ eloop.fd_table = temp_table;
}
+#endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */
+#ifdef CONFIG_ELOOP_EPOLL
if (eloop.count + 1 > eloop.epoll_max_event_num) {
next = eloop.epoll_max_event_num == 0 ? 8 :
eloop.epoll_max_event_num * 2;
temp_events = os_realloc_array(eloop.epoll_events, next,
sizeof(struct epoll_event));
if (temp_events == NULL) {
- wpa_printf(MSG_ERROR, "%s: malloc for epoll failed. "
- "%s\n", __func__, strerror(errno));
+ wpa_printf(MSG_ERROR, "%s: malloc for epoll failed: %s",
+ __func__, strerror(errno));
return -1;
}
@@ -235,6 +328,22 @@ static int eloop_sock_table_add_sock(struct eloop_sock_table *table,
eloop.epoll_events = temp_events;
}
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ if (eloop.count + 1 > eloop.kqueue_nevents) {
+ next = eloop.kqueue_nevents == 0 ? 8 : eloop.kqueue_nevents * 2;
+ temp_events = os_malloc(next * sizeof(*temp_events));
+ if (!temp_events) {
+ wpa_printf(MSG_ERROR,
+ "%s: malloc for kqueue failed: %s",
+ __func__, strerror(errno));
+ return -1;
+ }
+
+ os_free(eloop.kqueue_events);
+ eloop.kqueue_events = temp_events;
+ eloop.kqueue_nevents = next;
+ }
+#endif /* CONFIG_ELOOP_KQUEUE */
eloop_trace_sock_remove_ref(table);
tmp = os_realloc_array(table->table, table->count + 1,
@@ -256,33 +365,12 @@ static int eloop_sock_table_add_sock(struct eloop_sock_table *table,
table->changed = 1;
eloop_trace_sock_add_ref(table);
-#ifdef CONFIG_ELOOP_EPOLL
- os_memset(&ev, 0, sizeof(ev));
- switch (table->type) {
- case EVENT_TYPE_READ:
- ev.events = EPOLLIN;
- break;
- case EVENT_TYPE_WRITE:
- ev.events = EPOLLOUT;
- break;
- /*
- * Exceptions are always checked when using epoll, but I suppose it's
- * possible that someone registered a socket *only* for exception
- * handling.
- */
- case EVENT_TYPE_EXCEPTION:
- ev.events = EPOLLERR | EPOLLHUP;
- break;
- }
- ev.data.fd = sock;
- if (epoll_ctl(eloop.epollfd, EPOLL_CTL_ADD, sock, &ev) < 0) {
- wpa_printf(MSG_ERROR, "%s: epoll_ctl(ADD) for fd=%d "
- "failed. %s\n", __func__, sock, strerror(errno));
+#if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE)
+ if (eloop_sock_queue(sock, table->type) < 0)
return -1;
- }
- os_memcpy(&eloop.epoll_table[sock], &table->table[table->count - 1],
+ os_memcpy(&eloop.fd_table[sock], &table->table[table->count - 1],
sizeof(struct eloop_sock));
-#endif /* CONFIG_ELOOP_EPOLL */
+#endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */
return 0;
}
@@ -290,6 +378,9 @@ static int eloop_sock_table_add_sock(struct eloop_sock_table *table,
static void eloop_sock_table_remove_sock(struct eloop_sock_table *table,
int sock)
{
+#ifdef CONFIG_ELOOP_KQUEUE
+ struct kevent ke;
+#endif /* CONFIG_ELOOP_KQUEUE */
int i;
if (table == NULL || table->table == NULL || table->count == 0)
@@ -313,12 +404,21 @@ static void eloop_sock_table_remove_sock(struct eloop_sock_table *table,
eloop_trace_sock_add_ref(table);
#ifdef CONFIG_ELOOP_EPOLL
if (epoll_ctl(eloop.epollfd, EPOLL_CTL_DEL, sock, NULL) < 0) {
- wpa_printf(MSG_ERROR, "%s: epoll_ctl(DEL) for fd=%d "
- "failed. %s\n", __func__, sock, strerror(errno));
+ wpa_printf(MSG_ERROR, "%s: epoll_ctl(DEL) for fd=%d failed: %s",
+ __func__, sock, strerror(errno));
return;
}
- os_memset(&eloop.epoll_table[sock], 0, sizeof(struct eloop_sock));
+ os_memset(&eloop.fd_table[sock], 0, sizeof(struct eloop_sock));
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ EV_SET(&ke, sock, 0, EV_DELETE, 0, 0, NULL);
+ if (kevent(eloop.kqueuefd, &ke, 1, NULL, 0, NULL) < 0) {
+ wpa_printf(MSG_ERROR, "%s: kevent(DEL) for fd=%d failed: %s",
+ __func__, sock, strerror(errno));
+ return;
+ }
+ os_memset(&eloop.fd_table[sock], 0, sizeof(struct eloop_sock));
+#endif /* CONFIG_ELOOP_KQUEUE */
}
@@ -511,7 +611,7 @@ static void eloop_sock_table_dispatch(struct epoll_event *events, int nfds)
int i;
for (i = 0; i < nfds; i++) {
- table = &eloop.epoll_table[events[i].data.fd];
+ table = &eloop.fd_table[events[i].data.fd];
if (table->handler == NULL)
continue;
table->handler(table->sock, table->eloop_data,
@@ -525,6 +625,67 @@ static void eloop_sock_table_dispatch(struct epoll_event *events, int nfds)
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+
+static void eloop_sock_table_dispatch(struct kevent *events, int nfds)
+{
+ struct eloop_sock *table;
+ int i;
+
+ for (i = 0; i < nfds; i++) {
+ table = &eloop.fd_table[events[i].ident];
+ if (table->handler == NULL)
+ continue;
+ table->handler(table->sock, table->eloop_data,
+ table->user_data);
+ if (eloop.readers.changed ||
+ eloop.writers.changed ||
+ eloop.exceptions.changed)
+ break;
+ }
+}
+
+
+static int eloop_sock_table_requeue(struct eloop_sock_table *table)
+{
+ int i, r;
+
+ r = 0;
+ for (i = 0; i < table->count && table->table; i++) {
+ if (eloop_sock_queue(table->table[i].sock, table->type) == -1)
+ r = -1;
+ }
+ return r;
+}
+
+#endif /* CONFIG_ELOOP_KQUEUE */
+
+
+int eloop_sock_requeue(void)
+{
+ int r = 0;
+
+#ifdef CONFIG_ELOOP_KQUEUE
+ close(eloop.kqueuefd);
+ eloop.kqueuefd = kqueue();
+ if (eloop.kqueuefd < 0) {
+ wpa_printf(MSG_ERROR, "%s: kqueue failed: %s",
+ __func__, strerror(errno));
+ return -1;
+ }
+
+ if (eloop_sock_table_requeue(&eloop.readers) < 0)
+ r = -1;
+ if (eloop_sock_table_requeue(&eloop.writers) < 0)
+ r = -1;
+ if (eloop_sock_table_requeue(&eloop.exceptions) < 0)
+ r = -1;
+#endif /* CONFIG_ELOOP_KQUEUE */
+
+ return r;
+}
+
+
static void eloop_sock_table_destroy(struct eloop_sock_table *table)
{
if (table) {
@@ -905,6 +1066,9 @@ void eloop_run(void)
#ifdef CONFIG_ELOOP_EPOLL
int timeout_ms = -1;
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ struct timespec ts;
+#endif /* CONFIG_ELOOP_KQUEUE */
int res;
struct os_reltime tv, now;
@@ -949,6 +1113,10 @@ void eloop_run(void)
_tv.tv_sec = tv.sec;
_tv.tv_usec = tv.usec;
#endif /* CONFIG_ELOOP_SELECT */
+#ifdef CONFIG_ELOOP_KQUEUE
+ ts.tv_sec = tv.sec;
+ ts.tv_nsec = tv.usec * 1000L;
+#endif /* CONFIG_ELOOP_KQUEUE */
}
#ifdef CONFIG_ELOOP_POLL
@@ -974,6 +1142,15 @@ void eloop_run(void)
eloop.count, timeout_ms);
}
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ if (eloop.count == 0) {
+ res = 0;
+ } else {
+ res = kevent(eloop.kqueuefd, NULL, 0,
+ eloop.kqueue_events, eloop.kqueue_nevents,
+ timeout ? &ts : NULL);
+ }
+#endif /* CONFIG_ELOOP_KQUEUE */
if (res < 0 && errno != EINTR && errno != 0) {
wpa_printf(MSG_ERROR, "eloop: %s: %s",
#ifdef CONFIG_ELOOP_POLL
@@ -985,6 +1162,10 @@ void eloop_run(void)
#ifdef CONFIG_ELOOP_EPOLL
"epoll"
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ "kqueue"
+#endif /* CONFIG_ELOOP_EKQUEUE */
+
, strerror(errno));
goto out;
}
@@ -995,6 +1176,7 @@ void eloop_run(void)
eloop_process_pending_signals();
+
/* check if some registered timeouts have occurred */
timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
list);
@@ -1040,6 +1222,9 @@ void eloop_run(void)
#ifdef CONFIG_ELOOP_EPOLL
eloop_sock_table_dispatch(eloop.epoll_events, res);
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ eloop_sock_table_dispatch(eloop.kqueue_events, res);
+#endif /* CONFIG_ELOOP_KQUEUE */
}
eloop.terminate = 0;
@@ -1092,11 +1277,17 @@ void eloop_destroy(void)
os_free(eloop.pollfds);
os_free(eloop.pollfds_map);
#endif /* CONFIG_ELOOP_POLL */
+#if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE)
+ os_free(eloop.fd_table);
+#endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */
#ifdef CONFIG_ELOOP_EPOLL
- os_free(eloop.epoll_table);
os_free(eloop.epoll_events);
close(eloop.epollfd);
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ os_free(eloop.kqueue_events);
+ close(eloop.kqueuefd);
+#endif /* CONFIG_ELOOP_KQUEUE */
}
@@ -1135,6 +1326,17 @@ void eloop_wait_for_read_sock(int sock)
FD_SET(sock, &rfds);
select(sock + 1, &rfds, NULL, NULL, NULL);
#endif /* defined(CONFIG_ELOOP_SELECT) || defined(CONFIG_ELOOP_EPOLL) */
+#ifdef CONFIG_ELOOP_KQUEUE
+ int kfd;
+ struct kevent ke1, ke2;
+
+ kfd = kqueue();
+ if (kfd == -1)
+ return;
+ EV_SET(&ke1, sock, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, NULL);
+ kevent(kfd, &ke1, 1, &ke2, 1, NULL);
+ close(kfd);
+#endif /* CONFIG_ELOOP_KQUEUE */
}
#ifdef CONFIG_ELOOP_SELECT
diff --git a/src/utils/eloop.h b/src/utils/eloop.h
index 07b8c0dc..97af16f0 100644
--- a/src/utils/eloop.h
+++ b/src/utils/eloop.h
@@ -313,6 +313,14 @@ int eloop_register_signal_reconfig(eloop_signal_handler handler,
void *user_data);
/**
+ * eloop_sock_requeue - Requeue sockets
+ *
+ * Requeue sockets after forking because some implementations require this,
+ * such as epoll and kqueue.
+ */
+int eloop_sock_requeue(void);
+
+/**
* eloop_run - Start the event loop
*
* Start the event loop and continue running as long as there are any
diff --git a/src/utils/eloop_win.c b/src/utils/eloop_win.c
index de47fb21..9c8b12be 100644
--- a/src/utils/eloop_win.c
+++ b/src/utils/eloop_win.c
@@ -692,3 +692,9 @@ void eloop_wait_for_read_sock(int sock)
WSAEventSelect(sock, event, 0);
WSACloseEvent(event);
}
+
+
+int eloop_sock_requeue(void)
+{
+ return 0;
+}
diff --git a/src/utils/http_curl.c b/src/utils/http_curl.c
index 9c49680c..bf32ab87 100644
--- a/src/utils/http_curl.c
+++ b/src/utils/http_curl.c
@@ -644,13 +644,25 @@ static void i2r_LogotypeImageInfo(LogotypeImageInfo *info, BIO *out, int indent)
} else {
BIO_printf(out, "%*stype: default (1)\n", indent, "");
}
+ val = ASN1_INTEGER_get(info->fileSize);
+ BIO_printf(out, "%*sfileSize: %ld\n", indent, "", val);
val = ASN1_INTEGER_get(info->xSize);
BIO_printf(out, "%*sxSize: %ld\n", indent, "", val);
val = ASN1_INTEGER_get(info->ySize);
BIO_printf(out, "%*sySize: %ld\n", indent, "", val);
if (info->resolution) {
- BIO_printf(out, "%*sresolution\n", indent, "");
- /* TODO */
+ BIO_printf(out, "%*sresolution [%d]\n", indent, "",
+ info->resolution->type);
+ switch (info->resolution->type) {
+ case 0:
+ val = ASN1_INTEGER_get(info->resolution->d.numBits);
+ BIO_printf(out, "%*snumBits: %ld\n", indent, "", val);
+ break;
+ case 1:
+ val = ASN1_INTEGER_get(info->resolution->d.tableSize);
+ BIO_printf(out, "%*stableSize: %ld\n", indent, "", val);
+ break;
+ }
}
if (info->language) {
BIO_printf(out, "%*slanguage: ", indent, "");
diff --git a/src/utils/wpabuf.h b/src/utils/wpabuf.h
index c3ef1bae..9cd8a077 100644
--- a/src/utils/wpabuf.h
+++ b/src/utils/wpabuf.h
@@ -81,7 +81,7 @@ static inline const void * wpabuf_head(const struct wpabuf *buf)
static inline const u8 * wpabuf_head_u8(const struct wpabuf *buf)
{
- return wpabuf_head(buf);
+ return (const u8 *) wpabuf_head(buf);
}
/**
@@ -96,42 +96,42 @@ static inline void * wpabuf_mhead(struct wpabuf *buf)
static inline u8 * wpabuf_mhead_u8(struct wpabuf *buf)
{
- return wpabuf_mhead(buf);
+ return (u8 *) wpabuf_mhead(buf);
}
static inline void wpabuf_put_u8(struct wpabuf *buf, u8 data)
{
- u8 *pos = wpabuf_put(buf, 1);
+ u8 *pos = (u8 *) wpabuf_put(buf, 1);
*pos = data;
}
static inline void wpabuf_put_le16(struct wpabuf *buf, u16 data)
{
- u8 *pos = wpabuf_put(buf, 2);
+ u8 *pos = (u8 *) wpabuf_put(buf, 2);
WPA_PUT_LE16(pos, data);
}
static inline void wpabuf_put_le32(struct wpabuf *buf, u32 data)
{
- u8 *pos = wpabuf_put(buf, 4);
+ u8 *pos = (u8 *) wpabuf_put(buf, 4);
WPA_PUT_LE32(pos, data);
}
static inline void wpabuf_put_be16(struct wpabuf *buf, u16 data)
{
- u8 *pos = wpabuf_put(buf, 2);
+ u8 *pos = (u8 *) wpabuf_put(buf, 2);
WPA_PUT_BE16(pos, data);
}
static inline void wpabuf_put_be24(struct wpabuf *buf, u32 data)
{
- u8 *pos = wpabuf_put(buf, 3);
+ u8 *pos = (u8 *) wpabuf_put(buf, 3);
WPA_PUT_BE24(pos, data);
}
static inline void wpabuf_put_be32(struct wpabuf *buf, u32 data)
{
- u8 *pos = wpabuf_put(buf, 4);
+ u8 *pos = (u8 *) wpabuf_put(buf, 4);
WPA_PUT_BE32(pos, data);
}
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 8fa35e5c..234a0bf4 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -170,6 +170,10 @@ ifdef CONFIG_ELOOP_EPOLL
CFLAGS += -DCONFIG_ELOOP_EPOLL
endif
+ifdef CONFIG_ELOOP_KQUEUE
+CFLAGS += -DCONFIG_ELOOP_KQUEUE
+endif
+
ifdef CONFIG_EAPOL_TEST
CFLAGS += -Werror -DEAPOL_TEST
endif
diff --git a/wpa_supplicant/README b/wpa_supplicant/README
index 61be5434..32233128 100644
--- a/wpa_supplicant/README
+++ b/wpa_supplicant/README
@@ -409,7 +409,7 @@ Command line options
--------------------
usage:
- wpa_supplicant [-BddfhKLqqtuvwW] [-P<pid file>] [-g<global ctrl>] \
+ wpa_supplicant [-BddfhKLqqtuvW] [-P<pid file>] [-g<global ctrl>] \
[-G<group>] \
-i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] [-p<driver_param>] \
[-b<br_ifname> [-N -i<ifname> -c<conf> [-C<ctrl>] [-D<driver>] \
@@ -435,7 +435,6 @@ options:
-q = decrease debugging verbosity (-qq even less)
-u = enable DBus control interface
-v = show version
- -w = wait for interface to be added, if needed
-W = wait for a control interface monitor before starting
-N = start describing new interface
-m = Configuration file for the P2P Device
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 105fb1c6..98b95961 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -92,6 +92,7 @@ no_vht:
conf->vht_oper_centr_freq_seg0_idx =
conf->channel + conf->secondary_channel * 2;
#endif /* CONFIG_P2P */
+ conf->vht_oper_chwidth = VHT_CHANWIDTH_USE_HT;
}
#endif /* CONFIG_IEEE80211N */
diff --git a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
index c091234f..382dcb34 100644
--- a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
+++ b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
@@ -17,11 +17,9 @@
<policy context="default">
<deny own="fi.epitest.hostap.WPASupplicant"/>
<deny send_destination="fi.epitest.hostap.WPASupplicant"/>
- <deny send_interface="fi.epitest.hostap.WPASupplicant"/>
<deny own="fi.w1.wpa_supplicant1"/>
<deny send_destination="fi.w1.wpa_supplicant1"/>
- <deny send_interface="fi.w1.wpa_supplicant1"/>
<deny receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/>
</policy>
</busconfig>
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 6b77008a..09461c5d 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -2645,6 +2645,7 @@ dbus_bool_t wpas_dbus_getter_capabilities(
!wpa_dbus_dict_string_array_add_element(
&iter_array, "ap")) ||
(res >= 0 && (capa.flags & WPA_DRIVER_FLAGS_P2P_CAPABLE) &&
+ !wpa_s->conf->p2p_disabled &&
!wpa_dbus_dict_string_array_add_element(
&iter_array, "p2p")) ||
!wpa_dbus_dict_end_string_array(&iter_dict,
diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c
index 7c7d54a2..1aede79a 100644
--- a/wpa_supplicant/eapol_test.c
+++ b/wpa_supplicant/eapol_test.c
@@ -193,7 +193,7 @@ static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e,
return;
}
- radius_msg_make_authenticator(msg, (u8 *) e, sizeof(*e));
+ radius_msg_make_authenticator(msg);
hdr = (const struct eap_hdr *) eap;
pos = (const u8 *) (hdr + 1);
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index d509d7d7..27be46cd 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -1095,8 +1095,10 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
/* called by ap_free_sta */
-void mesh_mpm_free_sta(struct sta_info *sta)
+void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
{
+ if (sta->plink_state == PLINK_ESTAB)
+ hapd->num_plinks--;
eloop_cancel_timeout(plink_timer, ELOOP_ALL_CTX, sta);
eloop_cancel_timeout(mesh_auth_timer, ELOOP_ALL_CTX, sta);
}
diff --git a/wpa_supplicant/mesh_mpm.h b/wpa_supplicant/mesh_mpm.h
index 7ebaef0c..9af75635 100644
--- a/wpa_supplicant/mesh_mpm.h
+++ b/wpa_supplicant/mesh_mpm.h
@@ -14,7 +14,7 @@ void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
struct ieee802_11_elems *elems);
void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh);
void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr);
-void mesh_mpm_free_sta(struct sta_info *sta);
+void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta);
void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s,
struct sta_info *sta,
enum mesh_plink_state state);
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index e1596cbb..ffc9052f 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -429,6 +429,7 @@ static int wnm_nei_get_chan(struct wpa_supplicant *wpa_s, u8 op_class, u8 chan)
{
struct wpa_bss *bss = wpa_s->current_bss;
const char *country = NULL;
+ int freq;
if (bss) {
const u8 *elem = wpa_bss_get_ie(bss, WLAN_EID_COUNTRY);
@@ -437,7 +438,21 @@ static int wnm_nei_get_chan(struct wpa_supplicant *wpa_s, u8 op_class, u8 chan)
country = (const char *) (elem + 2);
}
- return ieee80211_chan_to_freq(country, op_class, chan);
+ freq = ieee80211_chan_to_freq(country, op_class, chan);
+ if (freq <= 0 && op_class == 0) {
+ /*
+ * Some APs do not advertise correct operating class
+ * information. Try to determine the most likely operating
+ * frequency based on the channel number.
+ */
+ if (chan >= 1 && chan <= 13)
+ freq = 2407 + chan * 5;
+ else if (chan == 14)
+ freq = 2484;
+ else if (chan >= 36 && chan <= 169)
+ freq = 5000 + chan * 5;
+ }
+ return freq;
}
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 1aea0a65..265f72c9 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -4441,7 +4441,7 @@ int main(int argc, char *argv[])
}
}
- if (daemonize && os_daemonize(pid_file))
+ if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())
return -1;
if (action_file)
diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c
index fa5a6ded..3f91cc16 100644
--- a/wpa_supplicant/wpa_priv.c
+++ b/wpa_supplicant/wpa_priv.c
@@ -1128,7 +1128,7 @@ int main(int argc, char *argv[])
interfaces = iface;
}
- if (daemonize && os_daemonize(pid_file))
+ if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())
goto out;
eloop_register_signal_terminate(wpa_priv_terminate, NULL);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 03b13533..c3c1f147 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -5221,7 +5221,8 @@ int wpa_supplicant_run(struct wpa_global *global)
struct wpa_supplicant *wpa_s;
if (global->params.daemonize &&
- wpa_supplicant_daemon(global->params.pid_file))
+ (wpa_supplicant_daemon(global->params.pid_file) ||
+ eloop_sock_requeue()))
return -1;
if (global->params.wait_for_monitor) {