diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2016-02-10 10:27:55 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-02-10 10:27:55 +0000 |
commit | c6204db945c56037fd900dae22702ff232eff4b4 (patch) | |
tree | 80f954a05ff1a43c8873665e40ffbdb6cab8ffb2 | |
parent | a3b4dfeccdb95a9e69f4e1120f426f7ea76ced91 (diff) | |
parent | b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36e (diff) | |
download | wpa_supplicant_8-c6204db945c56037fd900dae22702ff232eff4b4.tar.gz |
Cumulative patch from commit c06c9099f0d0827feae5622097bd8ac946eca5ea
am: b97e428f8a
* commit 'b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36e':
Cumulative patch from commit c06c9099f0d0827feae5622097bd8ac946eca5ea
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) { |