diff options
| author | Dmitry Shmidt <dimitrysh@google.com> | 2013-12-05 11:08:35 -0800 |
|---|---|---|
| committer | Dmitry Shmidt <dimitrysh@google.com> | 2013-12-05 14:12:55 -0800 |
| commit | 01904cfafd75a70b9f29c0220b90bdef45595491 (patch) | |
| tree | cdfdfa7b0f49480152b0a358d932bf1ceafe43c1 | |
| parent | e701d41f0adb79913ad5851f52cc6f522c0b34cd (diff) | |
| download | android_external_wpa_supplicant_8-01904cfafd75a70b9f29c0220b90bdef45595491.tar.gz android_external_wpa_supplicant_8-01904cfafd75a70b9f29c0220b90bdef45595491.tar.bz2 android_external_wpa_supplicant_8-01904cfafd75a70b9f29c0220b90bdef45595491.zip | |
Cumulative patch from commit 0ad3b9c402ee92863b720bc01f882ebcb1bd42c8
0ad3b9c Use wpa_radio data for get_shared_radio_freqs()
1b544ff Use wpa_radio data for wpas_wpa_is_in_progress()
5b81927 Use wpa_radio data for wpas_p2p_search_delay()
c67e7e2 Use wpa_radio data for channel list updates
f88f19b Use wpa_radio data for scan result updates
202dec2 Add shared per-radio structure for wpa_supplicant
73c00fd Move wpa_supplicant driver initialization into a helper function
7feff06 Add CONFIG_CODE_COVERAGE=y option for gcov
d9c753b EAP server: Handle EAP method initialization failures more cleanly
59d3438 EAP server: Initialize TLS context based on private_key
6b417a1 Reject TLS-based EAP server method if TLS context not initialized
158b090 nl80211: Fix regression in P2P group interface removal
6f72577 P2P: Handle INTERFACE_DISABLED event on a P2P GO interface
336167c AP: Fix inactivity STA timer trigger for driver offload case
1245503 Restore scan_req if sta scan is rescheduled in the scan results event
bdec7ee D-Bus: Add support to set pkcs11_{engine,module}_path
80ed037 Clear beacon_data before usage
Change-Id: I1a87557ad09419b88b993ba13f58359121e3543b
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
32 files changed, 448 insertions, 159 deletions
diff --git a/hostapd/Makefile b/hostapd/Makefile index b4704baf..ae96d35d 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -105,6 +105,14 @@ OBJS += ../src/common/wpa_common.o OBJS += ../src/eapol_auth/eapol_auth_sm.o +ifdef CONFIG_CODE_COVERAGE +CFLAGS += -O0 -fprofile-arcs -ftest-coverage +LIBS += -lgcov +LIBS_c += -lgcov +LIBS_h += -lgcov +LIBS_n += -lgcov +endif + ifndef CONFIG_NO_DUMP_STATE # define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to # a file (undefine it, if you want to save in binary size) @@ -939,6 +947,6 @@ hlr_auc_gw: $(HOBJS) clean: $(MAKE) -C ../src clean rm -f core *~ *.o hostapd hostapd_cli nt_password_hash hlr_auc_gw - rm -f *.d + rm -f *.d *.gcno *.gcda *.gcov -include $(OBJS:%.o=%.d) diff --git a/src/ap/Makefile b/src/ap/Makefile index 9c41962f..adfd3dfd 100644 --- a/src/ap/Makefile +++ b/src/ap/Makefile @@ -2,7 +2,7 @@ all: @echo Nothing to be made. clean: - rm -f *~ *.o *.d + rm -f *~ *.o *.d *.gcno *.gcda *.gcov install: @echo Nothing to be made. diff --git a/src/ap/authsrv.c b/src/ap/authsrv.c index 68ad4dc5..8bb58a6f 100644 --- a/src/ap/authsrv.c +++ b/src/ap/authsrv.c @@ -133,7 +133,7 @@ int authsrv_init(struct hostapd_data *hapd) #ifdef EAP_TLS_FUNCS if (hapd->conf->eap_server && (hapd->conf->ca_cert || hapd->conf->server_cert || - hapd->conf->dh_file)) { + hapd->conf->private_key || hapd->conf->dh_file)) { struct tls_connection_params params; hapd->ssl_ctx = tls_init(NULL); diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 69e89566..492861e0 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1980,13 +1980,15 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, } else wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); - wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout " - "for " MACSTR " (%d seconds - ap_max_inactivity)", - __func__, MAC2STR(sta->addr), - hapd->conf->ap_max_inactivity); - eloop_cancel_timeout(ap_handle_timer, hapd, sta); - eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, - ap_handle_timer, hapd, sta); + if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) { + wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout " + "for " MACSTR " (%d seconds - ap_max_inactivity)", + __func__, MAC2STR(sta->addr), + hapd->conf->ap_max_inactivity); + eloop_cancel_timeout(ap_handle_timer, hapd, sta); + eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, + ap_handle_timer, hapd, sta); + } } @@ -2049,6 +2051,7 @@ static int hostapd_build_beacon_data(struct hostapd_iface *iface, int ret; struct hostapd_data *hapd = iface->bss[0]; + os_memset(beacon, 0, sizeof(*beacon)); ret = ieee802_11_build_ap_params(hapd, ¶ms); if (ret < 0) return ret; diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c index 9d28d9ce..474597ed 100644 --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c @@ -545,13 +545,16 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr) sta->acct_interim_interval = hapd->conf->acct_interim_interval; accounting_sta_get_id(hapd, sta); + if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) { + wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout " + "for " MACSTR " (%d seconds - ap_max_inactivity)", + __func__, MAC2STR(addr), + hapd->conf->ap_max_inactivity); + eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, + ap_handle_timer, hapd, sta); + } + /* initialize STA info data */ - wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout " - "for " MACSTR " (%d seconds - ap_max_inactivity)", - __func__, MAC2STR(addr), - hapd->conf->ap_max_inactivity); - eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, - ap_handle_timer, hapd, sta); os_memcpy(sta->addr, addr, ETH_ALEN); sta->next = hapd->sta_list; hapd->sta_list = sta; diff --git a/src/common/Makefile b/src/common/Makefile index 9c41962f..adfd3dfd 100644 --- a/src/common/Makefile +++ b/src/common/Makefile @@ -2,7 +2,7 @@ all: @echo Nothing to be made. clean: - rm -f *~ *.o *.d + rm -f *~ *.o *.d *.gcno *.gcda *.gcov install: @echo Nothing to be made. diff --git a/src/crypto/Makefile b/src/crypto/Makefile index a605a65c..fcf95862 100644 --- a/src/crypto/Makefile +++ b/src/crypto/Makefile @@ -1,7 +1,7 @@ all: libcrypto.a clean: - rm -f *~ *.o *.d libcrypto.a + rm -f *~ *.o *.d *.gcno *.gcda *.gcov libcrypto.a install: @echo Nothing to be made. diff --git a/src/drivers/Makefile b/src/drivers/Makefile index 07600e52..57211540 100644 --- a/src/drivers/Makefile +++ b/src/drivers/Makefile @@ -2,7 +2,7 @@ all: @echo Nothing to be made. clean: - rm -f *~ *.o *.d + rm -f *~ *.o *.d *.gcno *.gcda *.gcov rm -f build.wpa_supplicant build.hostapd install: diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index eaca1725..64ab29a6 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -9490,7 +9490,7 @@ static int wpa_driver_nl80211_if_remove(struct i802_bss *bss, wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d added_if=%d", __func__, type, ifname, ifindex, bss->added_if); - if (ifindex > 0 && bss->added_if) + if (ifindex > 0 && (bss->added_if || bss->ifindex != ifindex)) nl80211_remove_iface(drv, ifindex); if (type != WPA_IF_AP_BSS) diff --git a/src/eap_common/Makefile b/src/eap_common/Makefile index 9c41962f..adfd3dfd 100644 --- a/src/eap_common/Makefile +++ b/src/eap_common/Makefile @@ -2,7 +2,7 @@ all: @echo Nothing to be made. clean: - rm -f *~ *.o *.d + rm -f *~ *.o *.d *.gcno *.gcda *.gcov install: @echo Nothing to be made. diff --git a/src/eap_peer/Makefile b/src/eap_peer/Makefile index 36510561..f79519b7 100644 --- a/src/eap_peer/Makefile +++ b/src/eap_peer/Makefile @@ -2,7 +2,7 @@ all: @echo Nothing to be made. clean: - rm -f *~ *.o *.so *.d + rm -f *~ *.o *.so *.d *.gcno *.gcda *.gcov install: if ls *.so >/dev/null 2>&1; then \ diff --git a/src/eap_server/Makefile b/src/eap_server/Makefile index 9c41962f..adfd3dfd 100644 --- a/src/eap_server/Makefile +++ b/src/eap_server/Makefile @@ -2,7 +2,7 @@ all: @echo Nothing to be made. clean: - rm -f *~ *.o *.d + rm -f *~ *.o *.d *.gcno *.gcda *.gcov install: @echo Nothing to be made. diff --git a/src/eap_server/eap_server.c b/src/eap_server/eap_server.c index 54b7533d..233e2726 100644 --- a/src/eap_server/eap_server.c +++ b/src/eap_server/eap_server.c @@ -343,6 +343,7 @@ SM_STATE(EAP, PROPOSE_METHOD) SM_ENTRY(EAP, PROPOSE_METHOD); +try_another_method: type = eap_sm_Policy_getNextMethod(sm, &vendor); if (vendor == EAP_VENDOR_IETF) sm->currentMethod = type; @@ -360,8 +361,14 @@ SM_STATE(EAP, PROPOSE_METHOD) "method %d", sm->currentMethod); sm->m = NULL; sm->currentMethod = EAP_TYPE_NONE; + goto try_another_method; } } + if (sm->m == NULL) { + wpa_printf(MSG_DEBUG, "EAP: Could not find suitable EAP method"); + sm->decision = DECISION_FAILURE; + return; + } if (sm->currentMethod == EAP_TYPE_IDENTITY || sm->currentMethod == EAP_TYPE_NOTIFICATION) sm->methodState = METHOD_CONTINUE; @@ -702,6 +709,15 @@ SM_STEP(EAP) SM_ENTER(EAP, METHOD_RESPONSE); break; case EAP_METHOD_REQUEST: + if (sm->m == NULL) { + /* + * This transition is not mentioned in RFC 4137, but it + * is needed to handle cleanly a case where EAP method + * initialization fails. + */ + SM_ENTER(EAP, FAILURE); + break; + } SM_ENTER(EAP, SEND_REQUEST); break; case EAP_METHOD_RESPONSE: diff --git a/src/eap_server/eap_server_tls_common.c b/src/eap_server/eap_server_tls_common.c index 9efb5b29..526e1bcc 100644 --- a/src/eap_server/eap_server_tls_common.c +++ b/src/eap_server/eap_server_tls_common.c @@ -33,6 +33,11 @@ struct wpabuf * eap_tls_msg_alloc(EapType type, size_t payload_len, int eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, int verify_peer) { + if (sm->ssl_ctx == NULL) { + wpa_printf(MSG_ERROR, "TLS context not initialized - cannot use TLS-based EAP method"); + return -1; + } + data->eap = sm; data->phase2 = sm->init_phase2; diff --git a/src/eapol_auth/Makefile b/src/eapol_auth/Makefile index 9c41962f..adfd3dfd 100644 --- a/src/eapol_auth/Makefile +++ b/src/eapol_auth/Makefile @@ -2,7 +2,7 @@ all: @echo Nothing to be made. clean: - rm -f *~ *.o *.d + rm -f *~ *.o *.d *.gcno *.gcda *.gcov install: @echo Nothing to be made. diff --git a/src/eapol_supp/Makefile b/src/eapol_supp/Makefile index 9c41962f..adfd3dfd 100644 --- a/src/eapol_supp/Makefile +++ b/src/eapol_supp/Makefile @@ -2,7 +2,7 @@ all: @echo Nothing to be made. clean: - rm -f *~ *.o *.d + rm -f *~ *.o *.d *.gcno *.gcda *.gcov install: @echo Nothing to be made. diff --git a/src/l2_packet/Makefile b/src/l2_packet/Makefile index 9c41962f..adfd3dfd 100644 --- a/src/l2_packet/Makefile +++ b/src/l2_packet/Makefile @@ -2,7 +2,7 @@ all: @echo Nothing to be made. clean: - rm -f *~ *.o *.d + rm -f *~ *.o *.d *.gcno *.gcda *.gcov install: @echo Nothing to be made. diff --git a/src/p2p/Makefile b/src/p2p/Makefile index cffba620..adfd3dfd 100644 --- a/src/p2p/Makefile +++ b/src/p2p/Makefile @@ -2,8 +2,7 @@ all: @echo Nothing to be made. clean: - for d in $(SUBDIRS); do make -C $$d clean; done - rm -f *~ *.o *.d + rm -f *~ *.o *.d *.gcno *.gcda *.gcov install: @echo Nothing to be made. diff --git a/src/radius/Makefile b/src/radius/Makefile index b199be8b..b5d063da 100644 --- a/src/radius/Makefile +++ b/src/radius/Makefile @@ -1,7 +1,7 @@ all: libradius.a clean: - rm -f *~ *.o *.d libradius.a + rm -f *~ *.o *.d *.gcno *.gcda *.gcov libradius.a install: @echo Nothing to be made. diff --git a/src/rsn_supp/Makefile b/src/rsn_supp/Makefile index 9c41962f..adfd3dfd 100644 --- a/src/rsn_supp/Makefile +++ b/src/rsn_supp/Makefile @@ -2,7 +2,7 @@ all: @echo Nothing to be made. clean: - rm -f *~ *.o *.d + rm -f *~ *.o *.d *.gcno *.gcda *.gcov install: @echo Nothing to be made. diff --git a/src/utils/Makefile b/src/utils/Makefile index b04a8a36..8aad813c 100644 --- a/src/utils/Makefile +++ b/src/utils/Makefile @@ -1,7 +1,7 @@ all: libutils.a clean: - rm -f *~ *.o *.d libutils.a + rm -f *~ *.o *.d *.gcno *.gcda *.gcov libutils.a install: @echo Nothing to be made. diff --git a/src/wps/Makefile b/src/wps/Makefile index 9c41962f..adfd3dfd 100644 --- a/src/wps/Makefile +++ b/src/wps/Makefile @@ -2,7 +2,7 @@ all: @echo Nothing to be made. clean: - rm -f *~ *.o *.d + rm -f *~ *.o *.d *.gcno *.gcda *.gcov install: @echo Nothing to be made. diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index f6a46d28..260c0ae4 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -129,6 +129,13 @@ ifdef CONFIG_EAPOL_TEST CFLAGS += -Werror -DEAPOL_TEST endif +ifdef CONFIG_CODE_COVERAGE +CFLAGS += -O0 -fprofile-arcs -ftest-coverage +LIBS += -lgcov +LIBS_c += -lgcov +LIBS_p += -lgcov +endif + ifdef CONFIG_HT_OVERRIDES CFLAGS += -DCONFIG_HT_OVERRIDES endif @@ -1672,7 +1679,8 @@ fips: clean: $(MAKE) -C ../src clean $(MAKE) -C dbus clean - rm -f core *~ *.o *.d eap_*.so $(ALL) $(WINALL) eapol_test preauth_test + rm -f core *~ *.o *.d *.gcno *.gcda *.gcov + rm -f eap_*.so $(ALL) $(WINALL) eapol_test preauth_test rm -f wpa_priv rm -f nfc_pw_token diff --git a/wpa_supplicant/dbus/Makefile b/wpa_supplicant/dbus/Makefile index d64c65ca..f355ebef 100644 --- a/wpa_supplicant/dbus/Makefile +++ b/wpa_supplicant/dbus/Makefile @@ -1,7 +1,7 @@ all: libwpadbus.a clean: - rm -f *~ *.o *.d + rm -f *~ *.o *.d *.gcno *.gcda *.gcov rm -f libwpadbus.a install: diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index 9736e8f0..f40d4219 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -2516,6 +2516,15 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { } }, #endif /* CONFIG_NO_CONFIG_BLOBS */ + { "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) + &wpas_dbus_handler_set_pkcs11_engine_and_module_path, + { + { "pkcs11_engine_path", "s", ARG_IN }, + { "pkcs11_module_path", "s", ARG_IN }, + END_ARGS + } + }, #ifdef CONFIG_WPS { "Start", WPAS_DBUS_NEW_IFACE_WPS, (WPADBusMethodHandler) &wpas_dbus_handler_wps_start, @@ -2843,6 +2852,14 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = { wpas_dbus_getter_scan_interval, wpas_dbus_setter_scan_interval }, + { "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", + wpas_dbus_getter_pkcs11_engine_path, + NULL + }, + { "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", + wpas_dbus_getter_pkcs11_module_path, + NULL + }, #ifdef CONFIG_WPS { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b", wpas_dbus_getter_process_credentials, diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index 0a805212..fdf9a0a6 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -2162,6 +2162,63 @@ DBusMessage * wpas_dbus_handler_tdls_teardown(DBusMessage *message, /** + * wpas_dbus_handler_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path + * @message: Pointer to incoming dbus message + * @wpa_s: %wpa_supplicant data structure + * Returns: A dbus message containing an error on failure or NULL on success + * + * Sets the PKCS #11 engine and module path. + */ +DBusMessage * wpas_dbus_handler_set_pkcs11_engine_and_module_path( + DBusMessage *message, struct wpa_supplicant *wpa_s) +{ + DBusMessageIter iter; + char *value = NULL; + char *pkcs11_engine_path = NULL; + char *pkcs11_module_path = NULL; + + dbus_message_iter_init(message, &iter); + dbus_message_iter_get_basic(&iter, &value); + if (value == NULL) { + return dbus_message_new_error( + message, DBUS_ERROR_INVALID_ARGS, + "Invalid pkcs11_engine_path argument"); + } + /* Empty path defaults to NULL */ + if (os_strlen(value)) + pkcs11_engine_path = value; + + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &value); + if (value == NULL) { + os_free(pkcs11_engine_path); + return dbus_message_new_error( + message, DBUS_ERROR_INVALID_ARGS, + "Invalid pkcs11_module_path argument"); + } + /* Empty path defaults to NULL */ + if (os_strlen(value)) + pkcs11_module_path = value; + + if (wpas_set_pkcs11_engine_and_module_path(wpa_s, pkcs11_engine_path, + pkcs11_module_path)) + return dbus_message_new_error( + message, DBUS_ERROR_FAILED, + "Reinit of the EAPOL state machine with the new PKCS " + "#11 engine and module path failed."); + + wpa_dbus_mark_property_changed( + wpa_s->global->dbus, wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11EnginePath"); + wpa_dbus_mark_property_changed( + wpa_s->global->dbus, wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11ModulePath"); + + return NULL; +} + + +/** * wpas_dbus_getter_capabilities - Return interface capabilities * @iter: Pointer to incoming dbus message iter * @error: Location to store error on failure @@ -3177,6 +3234,76 @@ out: /** + * wpas_dbus_getter_pkcs11_engine_path - Get PKCS #11 engine path + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: A dbus message containing the PKCS #11 engine path + * + * Getter for "PKCS11EnginePath" property. + */ +dbus_bool_t wpas_dbus_getter_pkcs11_engine_path(DBusMessageIter *iter, + DBusError *error, + void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + const char *pkcs11_engine_path; + + if (wpa_s->conf == NULL) { + wpa_printf(MSG_ERROR, + "wpas_dbus_getter_pkcs11_engine_path[dbus]: An " + "error occurred getting the PKCS #11 engine path."); + dbus_set_error_const( + error, DBUS_ERROR_FAILED, + "An error occured getting the PKCS #11 engine path."); + return FALSE; + } + + if (wpa_s->conf->pkcs11_engine_path == NULL) + pkcs11_engine_path = ""; + else + pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, + &pkcs11_engine_path, error); +} + + +/** + * wpas_dbus_getter_pkcs11_module_path - Get PKCS #11 module path + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: A dbus message containing the PKCS #11 module path + * + * Getter for "PKCS11ModulePath" property. + */ +dbus_bool_t wpas_dbus_getter_pkcs11_module_path(DBusMessageIter *iter, + DBusError *error, + void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + const char *pkcs11_module_path; + + if (wpa_s->conf == NULL) { + wpa_printf(MSG_ERROR, + "wpas_dbus_getter_pkcs11_module_path[dbus]: An " + "error occurred getting the PKCS #11 module path."); + dbus_set_error_const( + error, DBUS_ERROR_FAILED, + "An error occured getting the PKCS #11 module path."); + return FALSE; + } + + if (wpa_s->conf->pkcs11_module_path == NULL) + pkcs11_module_path = ""; + else + pkcs11_module_path = wpa_s->conf->pkcs11_module_path; + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, + &pkcs11_module_path, error); +} + + +/** * wpas_dbus_getter_blobs - Get all blobs defined for this interface * @iter: Pointer to incoming dbus message iter * @error: Location to store error on failure diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index aa3316b7..c0669445 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -122,6 +122,9 @@ DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message, DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message, struct wpa_supplicant *wpa_s); +DBusMessage * wpas_dbus_handler_set_pkcs11_engine_and_module_path( + DBusMessage *message, struct wpa_supplicant *wpa_s); + DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message, struct wpa_supplicant *wpa_s); @@ -218,6 +221,14 @@ dbus_bool_t wpas_dbus_getter_bsss(DBusMessageIter *iter, DBusError *error, dbus_bool_t wpas_dbus_getter_networks(DBusMessageIter *iter, DBusError *error, void *user_data); +dbus_bool_t wpas_dbus_getter_pkcs11_engine_path(DBusMessageIter *iter, + DBusError *error, + void *user_data); + +dbus_bool_t wpas_dbus_getter_pkcs11_module_path(DBusMessageIter *iter, + DBusError *error, + void *user_data); + dbus_bool_t wpas_dbus_getter_blobs(DBusMessageIter *iter, DBusError *error, void *user_data); diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index b9481f64..4d9eea8c 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1203,6 +1203,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) { wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation " "stopped scan processing"); + wpa_s->scan_req = wpa_s->last_scan_req; wpa_s->sta_scan_pending = 1; wpa_supplicant_req_scan(wpa_s, 5, 0); return -1; @@ -1392,7 +1393,6 @@ static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s, static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { - const char *rn, *rn2; struct wpa_supplicant *ifs; if (_wpa_supplicant_event_scan_results(wpa_s, data, 1) != 0) { @@ -1407,25 +1407,12 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, } /* - * Check other interfaces to see if they have the same radio-name. If + * Check other interfaces to see if they share the same radio. If * so, they get updated with this same scan info. */ - if (!wpa_s->driver->get_radio_name) - return; - - rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv); - if (rn == NULL || rn[0] == '\0') - return; - - wpa_dbg(wpa_s, MSG_DEBUG, "Checking for other virtual interfaces " - "sharing same radio (%s) in event_scan_results", rn); - - for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { - if (ifs == wpa_s || !ifs->driver->get_radio_name) - continue; - - rn2 = ifs->driver->get_radio_name(ifs->drv_priv); - if (rn2 && os_strcmp(rn, rn2) == 0) { + dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant, + radio_list) { + if (ifs != wpa_s) { wpa_printf(MSG_DEBUG, "%s: Updating scan results from " "sibling", ifs->ifname); _wpa_supplicant_event_scan_results(ifs, data, 0); @@ -2670,7 +2657,6 @@ static void wpas_event_deauth(struct wpa_supplicant *wpa_s, static void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s) { - const char *rn, *rn2; struct wpa_supplicant *ifs; if (wpa_s->drv_priv == NULL) @@ -2685,25 +2671,12 @@ static void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s) #endif /* CONFIG_P2P */ /* - * Check other interfaces to see if they have the same radio-name. If + * Check other interfaces to see if they share the same radio. If * so, they get updated with this same hw mode info. */ - if (!wpa_s->driver->get_radio_name) - return; - - rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv); - if (rn == NULL || rn[0] == '\0') - return; - - wpa_dbg(wpa_s, MSG_DEBUG, "Checking for other virtual interfaces " - "sharing same radio (%s) in event_channel_list_change", rn); - - for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { - if (ifs == wpa_s || !ifs->driver->get_radio_name) - continue; - - rn2 = ifs->driver->get_radio_name(ifs->drv_priv); - if (rn2 && os_strcmp(rn, rn2) == 0) { + dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant, + radio_list) { + if (ifs != wpa_s) { wpa_printf(MSG_DEBUG, "%s: Updating hw mode", ifs->ifname); free_hw_features(ifs); @@ -3199,6 +3172,20 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, break; case EVENT_INTERFACE_DISABLED: wpa_dbg(wpa_s, MSG_DEBUG, "Interface was disabled"); +#ifdef CONFIG_P2P + if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO || + (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group && + wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO)) { + /* + * The interface was externally disabled. Remove + * it assuming an external entity will start a + * new session if needed. + */ + wpas_p2p_disconnect(wpa_s); + break; + } +#endif /* CONFIG_P2P */ + wpa_supplicant_mark_disassoc(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED); break; diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 40fbffbd..790d442f 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -6308,7 +6308,6 @@ int wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s) unsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s) { - const char *rn, *rn2; struct wpa_supplicant *ifs; if (wpa_s->wpa_state > WPA_SCANNING) { @@ -6318,20 +6317,9 @@ unsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s) return P2P_CONCURRENT_SEARCH_DELAY; } - if (!wpa_s->driver->get_radio_name) - return 0; - rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv); - if (rn == NULL || rn[0] == '\0') - return 0; - - for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { - if (ifs == wpa_s || !ifs->driver->get_radio_name) - continue; - - rn2 = ifs->driver->get_radio_name(ifs->drv_priv); - if (!rn2 || os_strcmp(rn, rn2) != 0) - continue; - if (ifs->wpa_state > WPA_SCANNING) { + dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant, + radio_list) { + if (ifs != wpa_s && ifs->wpa_state > WPA_SCANNING) { wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search " "delay due to concurrent operation on " "interface %s", diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index 625ff286..f38dfbb2 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -545,7 +545,6 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; struct wpa_ssid *ssid; - enum scan_req_type scan_req = NORMAL_SCAN_REQ; int ret; struct wpabuf *extra_ie = NULL; struct wpa_driver_scan_params params; @@ -630,7 +629,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) max_ssids = WPAS_MAX_SCAN_SSIDS; } - scan_req = wpa_s->scan_req; + wpa_s->last_scan_req = wpa_s->scan_req; wpa_s->scan_req = NORMAL_SCAN_REQ; os_memset(¶ms, 0, sizeof(params)); @@ -648,7 +647,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) goto scan; } - if (scan_req != MANUAL_SCAN_REQ && wpa_s->connect_without_scan) { + if (wpa_s->last_scan_req != MANUAL_SCAN_REQ && + wpa_s->connect_without_scan) { for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { if (ssid == wpa_s->connect_without_scan) break; @@ -687,7 +687,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) } } - if (scan_req != MANUAL_SCAN_REQ && wpa_s->conf->ap_scan == 2) { + if (wpa_s->last_scan_req != MANUAL_SCAN_REQ && + wpa_s->conf->ap_scan == 2) { wpa_s->connect_without_scan = NULL; wpa_s->prev_scan_wildcard = 0; wpa_supplicant_assoc_try(wpa_s, ssid); @@ -843,7 +844,8 @@ scan: * station interface when we are not configured to prefer station * connection and a concurrent operation is already in process. */ - if (wpa_s->scan_for_connection && scan_req == NORMAL_SCAN_REQ && + if (wpa_s->scan_for_connection && + wpa_s->last_scan_req == NORMAL_SCAN_REQ && !scan_params->freqs && !params.freqs && wpas_is_p2p_prioritized(wpa_s) && wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE && @@ -874,7 +876,7 @@ scan: if (prev_state != wpa_s->wpa_state) wpa_supplicant_set_state(wpa_s, prev_state); /* Restore scan_req since we will try to scan again */ - wpa_s->scan_req = scan_req; + wpa_s->scan_req = wpa_s->last_scan_req; wpa_supplicant_req_scan(wpa_s, 1, 0); } else { wpa_s->scan_for_connection = 0; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 4e8d016a..fffecd41 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1973,6 +1973,59 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s, /** + * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path + * @wpa_s: wpa_supplicant structure for a network interface + * @pkcs11_engine_path: PKCS #11 engine path or NULL + * @pkcs11_module_path: PKCS #11 module path or NULL + * Returns: 0 on success; -1 on failure + * + * Sets the PKCS #11 engine and module path. Both have to be NULL or a valid + * path. If resetting the EAPOL state machine with the new PKCS #11 engine and + * module path fails the paths will be reset to the default value (NULL). + */ +int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s, + const char *pkcs11_engine_path, + const char *pkcs11_module_path) +{ + char *pkcs11_engine_path_copy = NULL; + char *pkcs11_module_path_copy = NULL; + + if (pkcs11_engine_path != NULL) { + pkcs11_engine_path_copy = os_strdup(pkcs11_engine_path); + if (pkcs11_engine_path_copy == NULL) + return -1; + } + if (pkcs11_module_path != NULL) { + pkcs11_module_path_copy = os_strdup(pkcs11_module_path); + if (pkcs11_engine_path_copy == NULL) { + os_free(pkcs11_engine_path_copy); + return -1; + } + } + + os_free(wpa_s->conf->pkcs11_engine_path); + os_free(wpa_s->conf->pkcs11_module_path); + wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy; + wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy; + + wpa_sm_set_eapol(wpa_s->wpa, NULL); + eapol_sm_deinit(wpa_s->eapol); + wpa_s->eapol = NULL; + if (wpa_supplicant_init_eapol(wpa_s)) { + /* Error -> Reset paths to the default value (NULL) once. */ + if (pkcs11_engine_path != NULL && pkcs11_module_path != NULL) + wpas_set_pkcs11_engine_and_module_path(wpa_s, NULL, + NULL); + + return -1; + } + wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol); + + return 0; +} + + +/** * wpa_supplicant_set_ap_scan - Set AP scan mode for interface * @wpa_s: wpa_supplicant structure for a network interface * @ap_scan: AP scan mode @@ -2834,10 +2887,112 @@ int wpas_init_ext_pw(struct wpa_supplicant *wpa_s) } +static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s, + const char *rn) +{ + struct wpa_supplicant *iface = wpa_s->global->ifaces; + struct wpa_radio *radio; + + while (rn && iface) { + radio = iface->radio; + if (radio && os_strcmp(rn, radio->name) == 0) { + wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s", + wpa_s->ifname, rn); + dl_list_add(&radio->ifaces, &wpa_s->radio_list); + return radio; + } + } + + wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s", + wpa_s->ifname, rn ? rn : "N/A"); + radio = os_zalloc(sizeof(*radio)); + if (radio == NULL) + return NULL; + + if (rn) + os_strlcpy(radio->name, rn, sizeof(radio->name)); + dl_list_init(&radio->ifaces); + dl_list_add(&radio->ifaces, &wpa_s->radio_list); + + return radio; +} + + +static void radio_remove_interface(struct wpa_supplicant *wpa_s) +{ + struct wpa_radio *radio = wpa_s->radio; + + if (!radio) + return; + + wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s", + wpa_s->ifname, radio->name); + dl_list_del(&wpa_s->radio_list); + wpa_s->radio = NULL; + + if (!dl_list_empty(&radio->ifaces)) + return; /* Interfaces remain for this radio */ + + wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name); + os_free(radio); +} + + +static int wpas_init_driver(struct wpa_supplicant *wpa_s, + struct wpa_interface *iface) +{ + const char *ifname, *driver, *rn; + + driver = iface->driver; +next_driver: + if (wpa_supplicant_set_driver(wpa_s, driver) < 0) + return -1; + + wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname); + if (wpa_s->drv_priv == NULL) { + const char *pos; + pos = driver ? os_strchr(driver, ',') : NULL; + if (pos) { + wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize " + "driver interface - try next driver wrapper"); + driver = pos + 1; + goto next_driver; + } + wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver " + "interface"); + return -1; + } + if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) { + wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected " + "driver_param '%s'", wpa_s->conf->driver_param); + return -1; + } + + ifname = wpa_drv_get_ifname(wpa_s); + if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) { + wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced " + "interface name with '%s'", ifname); + os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname)); + } + + if (wpa_s->driver->get_radio_name) + rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv); + else + rn = NULL; + if (rn && rn[0] == '\0') + rn = NULL; + + wpa_s->radio = radio_add_interface(wpa_s, rn); + if (wpa_s->radio == NULL) + return -1; + + return 0; +} + + static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, struct wpa_interface *iface) { - const char *ifname, *driver; struct wpa_driver_capa capa; wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver " @@ -2929,37 +3084,8 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, * L2 receive handler so that association events are processed before * EAPOL-Key packets if both become available for the same select() * call. */ - driver = iface->driver; -next_driver: - if (wpa_supplicant_set_driver(wpa_s, driver) < 0) - return -1; - - wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname); - if (wpa_s->drv_priv == NULL) { - const char *pos; - pos = driver ? os_strchr(driver, ',') : NULL; - if (pos) { - wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize " - "driver interface - try next driver wrapper"); - driver = pos + 1; - goto next_driver; - } - wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver " - "interface"); - return -1; - } - if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) { - wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected " - "driver_param '%s'", wpa_s->conf->driver_param); + if (wpas_init_driver(wpa_s, iface) < 0) return -1; - } - - ifname = wpa_drv_get_ifname(wpa_s); - if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) { - wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced " - "interface name with '%s'", ifname); - os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname)); - } if (wpa_supplicant_init_wpa(wpa_s) < 0) return -1; @@ -3131,6 +3257,8 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_P2P */ + radio_remove_interface(wpa_s); + if (wpa_s->drv_priv) wpa_drv_deinit(wpa_s); @@ -3987,32 +4115,13 @@ static int wpas_conn_in_progress(struct wpa_supplicant *wpa_s) */ int wpas_wpa_is_in_progress(struct wpa_supplicant *wpa_s, int include_current) { - const char *rn, *rn2; struct wpa_supplicant *ifs; - if (!wpa_s->driver->get_radio_name) { - if (include_current && wpas_conn_in_progress(wpa_s)) { - wpa_dbg(wpa_s, MSG_DEBUG, "Connection is in progress on interface %s - defer", - wpa_s->ifname); - return 1; - } - - return 0; - } - - rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv); - if (rn == NULL || rn[0] == '\0') - return 0; - - for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { + dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant, + radio_list) { if (!include_current && ifs == wpa_s) continue; - if (!ifs->driver->get_radio_name) - continue; - rn2 = ifs->driver->get_radio_name(ifs->drv_priv); - if (!rn2 || os_strcmp(rn, rn2) != 0) - continue; if (wpas_conn_in_progress(ifs)) { wpa_dbg(wpa_s, MSG_DEBUG, "Connection is in progress " "on interface %s - defer", ifs->ifname); @@ -4043,7 +4152,6 @@ void dump_freq_array(struct wpa_supplicant *wpa_s, const char *title, int get_shared_radio_freqs(struct wpa_supplicant *wpa_s, int *freq_array, unsigned int len) { - const char *rn, *rn2; struct wpa_supplicant *ifs; u8 bssid[ETH_ALEN]; int freq; @@ -4072,20 +4180,9 @@ int get_shared_radio_freqs(struct wpa_supplicant *wpa_s, return idx; } - rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv); - if (rn == NULL || rn[0] == '\0') { - dump_freq_array(wpa_s, "get_radio_name failed", - freq_array, idx); - return idx; - } - - for (ifs = wpa_s->global->ifaces; ifs && idx < len; - ifs = ifs->next) { - if (wpa_s == ifs || !ifs->driver->get_radio_name) - continue; - - rn2 = ifs->driver->get_radio_name(ifs->drv_priv); - if (!rn2 || os_strcmp(rn, rn2) != 0) + dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant, + radio_list) { + if (wpa_s == ifs) continue; if (ifs->current_ssid == NULL || ifs->assoc_freq == 0) diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index eed1053a..8cc813c8 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -271,6 +271,19 @@ struct wpa_global { /** + * struct wpa_radio - Internal data for per-radio information + * + * This structure is used to share data about configured interfaces + * (struct wpa_supplicant) that share the same physical radio, e.g., to allow + * better coordination of offchannel operations. + */ +struct wpa_radio { + char name[16]; /* from driver_ops get_radio_name() or empty if not + * available */ + struct dl_list ifaces; /* struct wpa_supplicant::radio_list entries */ +}; + +/** * offchannel_send_action_result - Result of offchannel send Action frame */ enum offchannel_send_action_result { @@ -307,6 +320,8 @@ struct wpa_ssid_value { */ struct wpa_supplicant { struct wpa_global *global; + struct wpa_radio *radio; /* shared radio context */ + struct dl_list radio_list; /* list head: struct wpa_radio::ifaces */ struct wpa_supplicant *parent; struct wpa_supplicant *next; struct l2_packet_data *l2; @@ -463,7 +478,7 @@ struct wpa_supplicant { * to be run. */ MANUAL_SCAN_REQ - } scan_req; + } scan_req, last_scan_req; struct os_time scan_trigger_time; int scan_runs; /* number of scan runs since WPS was started */ int *next_scan_freqs; @@ -772,6 +787,9 @@ void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); +int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s, + const char *pkcs11_engine_path, + const char *pkcs11_module_path); int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan); int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s, |
