Merge "Fix issue caused by NULL at msg pointer"
diff --git a/src/common/dpp.h b/src/common/dpp.h
index ee29a08..3094be8 100644
--- a/src/common/dpp.h
+++ b/src/common/dpp.h
@@ -296,6 +296,7 @@
enum dpp_status_error auth_resp_status;
enum dpp_status_error conf_resp_status;
enum dpp_status_error force_conf_resp_status;
+ enum dpp_status_error conn_result_status;
u8 peer_mac_addr[ETH_ALEN];
u8 i_nonce[DPP_MAX_NONCE_LEN];
u8 r_nonce[DPP_MAX_NONCE_LEN];
@@ -340,6 +341,7 @@
int connect_on_tx_status;
int waiting_conf_result;
int waiting_conn_status_result;
+ int tx_conn_status_result_started;
int auth_success;
bool reconfig_success;
struct wpabuf *conf_req;
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index db46d95..a7dee37 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -1731,6 +1731,9 @@
wpa_hexdump_ascii(MSG_DEBUG,
"EAP: using IMSI privacy anonymous identity",
identity, identity_len);
+ } else if (config->strict_conservative_peer_mode) {
+ wpa_printf(MSG_DEBUG, "EAP: never use real identity in conservative peer mode.");
+ return NULL;
} else {
identity = config->identity;
identity_len = config->identity_len;
@@ -2816,6 +2819,24 @@
return config->identity;
}
+
+/**
+ * eap_get_config_strict_conservative_peer_mode - get the value of
+ * strict conservative peer mode in eap_peer_config.
+ * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
+*/
+int eap_get_config_strict_conservative_peer_mode(struct eap_sm *sm)
+{
+ struct eap_peer_config *config;
+ config = eap_get_config(sm);
+ if (config) {
+ return config->strict_conservative_peer_mode;
+ }
+
+ return 0;
+}
+
+
static const u8 * strnchr(const u8 *str, size_t len, u8 needle) {
const u8 *cur = str;
@@ -3080,6 +3101,19 @@
return sm ? sm->eapKeyAvailable : 0;
}
+/**
+ * eap_notify_permanent_id_req_denied - Notify that the AT_PERMANENT_ID_REQ
+ * is denied from eap_peer when the strict conservative mode is enabled.
+ * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
+*/
+void eap_notify_permanent_id_req_denied(struct eap_sm *sm)
+{
+ if (!sm || !sm->eapol_cb->notify_permanent_id_req_denied)
+ return;
+
+ sm->eapol_cb->notify_permanent_id_req_denied(sm->eapol_ctx);
+}
+
/**
* eap_notify_success - Notify EAP state machine about external success trigger
diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
index aae1a41..8f83d0b 100644
--- a/src/eap_peer/eap.h
+++ b/src/eap_peer/eap.h
@@ -233,6 +233,15 @@
const char *cert_hash);
/**
+ * notify_permanent_id_req_denied - Notify that the
+ * AT_PERMANENT_ID_REQ from the server was denied. This
+ * notification happens when the peer is in strict
+ * conservative mode.
+ * @ctx: eapol_ctx from eap_peer_sm_init() call
+ */
+ void (*notify_permanent_id_req_denied)(void* ctx);
+
+ /**
* notify_status - Notification of the current EAP state
* @ctx: eapol_ctx from eap_peer_sm_init() call
* @status: Step in the process of EAP authentication
@@ -366,11 +375,13 @@
void eap_set_force_disabled(struct eap_sm *sm, int disabled);
void eap_set_external_sim(struct eap_sm *sm, int external_sim);
int eap_key_available(struct eap_sm *sm);
+void eap_notify_permanent_id_req_denied(struct eap_sm *sm);
void eap_notify_success(struct eap_sm *sm);
void eap_notify_lower_layer_success(struct eap_sm *sm);
const u8 * eap_get_eapSessionId(struct eap_sm *sm, size_t *len);
const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len);
struct wpabuf * eap_get_eapRespData(struct eap_sm *sm);
+int eap_get_config_strict_conservative_peer_mode(struct eap_sm *sm);
void eap_register_scard_ctx(struct eap_sm *sm, void *ctx);
void eap_invalidate_cached_session(struct eap_sm *sm);
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index 7f660e6..49338cf 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -708,6 +708,12 @@
identity_len = data->pseudonym_len;
eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID);
} else if (id_req != NO_ID_REQ) {
+ if (id_req == PERMANENT_ID && eap_get_config_strict_conservative_peer_mode(sm)) {
+ wpa_printf(MSG_INFO, "EAP-AKA: permanent_id_req is denied in "
+ "the strict conservative peer mode");
+ eap_notify_permanent_id_req_denied(sm);
+ return eap_aka_client_error(data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET);
+ }
identity = eap_get_config_identity(sm, &identity_len);
if (identity) {
int ids = CLEAR_PSEUDONYM | CLEAR_REAUTH_ID;
diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h
index 26744ab..59fac90 100644
--- a/src/eap_peer/eap_config.h
+++ b/src/eap_peer/eap_config.h
@@ -338,6 +338,18 @@
char *imsi_privacy_attr;
/**
+ * strict_conservative_peer_mode - Whether the strict conservative peer
+ * mode is enabled or not
+ *
+ * This field is used to handle the reponse of AT_PERMANENT_ID_REQ
+ * for EAP-SIM/AKA/AKA', in conservative peer mode, a client error would
+ * be sent to the server, but it allows to send the permanent identity
+ * in some special cases according to 4.6.2 of RFC 4187; With the strict
+ * mode, it never sends the permanent identity to server for privacy concern.
+ */
+ int strict_conservative_peer_mode;
+
+ /**
* machine_identity - EAP Identity for machine credential
*
* This field is used to set the machine identity or NAI for cases where
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index 71e9108..6f18ebf 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -576,6 +576,12 @@
identity_len = data->pseudonym_len;
eap_sim_clear_identities(sm, data, CLEAR_REAUTH_ID);
} else if (id_req != NO_ID_REQ) {
+ if (id_req == PERMANENT_ID && eap_get_config_strict_conservative_peer_mode(sm)) {
+ wpa_printf(MSG_INFO, "EAP-SIM: permanent_id_req is denied in "
+ "the strict conservative peer mode");
+ eap_notify_permanent_id_req_denied(sm);
+ return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET);
+ }
identity = eap_get_config_identity(sm, &identity_len);
if (identity) {
int ids = CLEAR_PSEUDONYM | CLEAR_REAUTH_ID;
diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c
index 6173960..a0bc6ab 100644
--- a/src/eapol_supp/eapol_supp_sm.c
+++ b/src/eapol_supp/eapol_supp_sm.c
@@ -2031,6 +2031,13 @@
sm->ctx->cert_cb(sm->ctx->ctx, cert, cert_hash);
}
+static void eapol_sm_notify_permanent_id_req_denied(void *ctx)
+{
+ struct eapol_sm *sm = ctx;
+ if (sm->ctx->permanent_id_req_denied_cb)
+ sm->ctx->permanent_id_req_denied_cb(sm->ctx->ctx);
+}
+
static void eapol_sm_notify_status(void *ctx, const char *status,
const char *parameter)
@@ -2118,6 +2125,7 @@
eapol_sm_notify_pending,
eapol_sm_eap_param_needed,
eapol_sm_notify_cert,
+ eapol_sm_notify_permanent_id_req_denied,
eapol_sm_notify_status,
eapol_sm_notify_eap_error,
#ifdef CONFIG_EAP_PROXY
diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h
index bbe2b6f..ad94cf5 100644
--- a/src/eapol_supp/eapol_supp_sm.h
+++ b/src/eapol_supp/eapol_supp_sm.h
@@ -255,6 +255,14 @@
const char *cert_hash);
/**
+ * permanent_id_req_denied_cb - Notify that the AT_PERMANENT_ID_REQ
+ * from the server was denied. This notification happens when the
+ * peer is in the strict conservative mode.
+ * @ctx: Callback context (ctx)
+ */
+ void (*permanent_id_req_denied_cb)(void *ctx);
+
+ /**
* cert_in_cb - Include server certificates in callback
*/
int cert_in_cb;
diff --git a/wpa_supplicant/aidl/aidl.cpp b/wpa_supplicant/aidl/aidl.cpp
index a7945cc..6bc13ad 100644
--- a/wpa_supplicant/aidl/aidl.cpp
+++ b/wpa_supplicant/aidl/aidl.cpp
@@ -186,6 +186,21 @@
wpa_s, ssid, rtype, default_txt);
}
+void wpas_aidl_notify_permanent_id_req_denied(
+ struct wpa_supplicant *wpa_s)
+{
+ if (!wpa_s || !wpa_s->global->aidl)
+ return;
+
+ wpa_printf(MSG_DEBUG, "Notifying permanent_id_req denied to aidl control.");
+
+ AidlManager *aidl_manager = AidlManager::getInstance();
+ if (!aidl_manager)
+ return;
+
+ return aidl_manager->notifyPermanentIdReqDenied(wpa_s);
+}
+
void wpas_aidl_notify_anqp_query_done(
struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
const struct wpa_bss_anqp *anqp)
@@ -671,7 +686,7 @@
}
void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
+ struct wpa_ssid *ssid, bool conn_status_requested)
{
if (!wpa_s || !ssid)
return;
@@ -684,7 +699,7 @@
if (!aidl_manager)
return;
- aidl_manager->notifyDppConfigReceived(wpa_s, ssid);
+ aidl_manager->notifyDppConfigReceived(wpa_s, ssid, conn_status_requested);
}
void wpas_aidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
@@ -692,6 +707,21 @@
wpas_aidl_notify_dpp_success(wpa_s, DppEventType::CONFIGURATION_SENT);
}
+void wpas_aidl_notify_dpp_connection_status_sent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result)
+{
+ if (!wpa_s)
+ return;
+
+ wpa_printf(MSG_DEBUG, "wpas_aidl_notify_dpp_connection_status_sent %d ", result);
+
+ AidlManager *aidl_manager = AidlManager::getInstance();
+ if (!aidl_manager)
+ return;
+
+ aidl_manager->notifyDppConnectionStatusSent(wpa_s, result);
+}
+
/* DPP Progress notifications */
void wpas_aidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
{
diff --git a/wpa_supplicant/aidl/aidl.h b/wpa_supplicant/aidl/aidl.h
index 2f3c7a0..40eb860 100644
--- a/wpa_supplicant/aidl/aidl.h
+++ b/wpa_supplicant/aidl/aidl.h
@@ -37,6 +37,7 @@
int wpas_aidl_notify_network_request(
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
enum wpa_ctrl_req_type rtype, const char *default_txt);
+ void wpas_aidl_notify_permanent_id_req_denied(struct wpa_supplicant *wpa_s);
void wpas_aidl_notify_anqp_query_done(
struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
const struct wpa_bss_anqp *anqp);
@@ -103,8 +104,10 @@
void wpas_aidl_notify_eap_error(
struct wpa_supplicant *wpa_s, int error_code);
void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
+ struct wpa_ssid *ssid, bool conn_status_requested);
void wpas_aidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s);
+ void wpas_aidl_notify_dpp_connection_status_sent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result);
void wpas_aidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s);
void wpas_aidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s);
void wpas_aidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s);
@@ -171,6 +174,8 @@
{
return 0;
}
+static void wpas_aidl_notify_permanent_id_req_denied(struct wpa_supplicant *wpa_s)
+{}
static void wpas_aidl_notify_anqp_query_done(
struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
const struct wpa_bss_anqp *anqp)
@@ -252,12 +257,13 @@
struct wpa_supplicant *wpa_s, int error_code)
{}
static void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
+ struct wpa_ssid *ssid, bool conn_status_requested)
{}
-static void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
static void wpas_aidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
{}
+void wpas_aidl_notify_dpp_connection_status_sent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result)
+{}
static void wpas_aidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
{}
static void wpas_aidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s)
diff --git a/wpa_supplicant/aidl/aidl_manager.cpp b/wpa_supplicant/aidl/aidl_manager.cpp
index 33ad650..e7cb3a6 100644
--- a/wpa_supplicant/aidl/aidl_manager.cpp
+++ b/wpa_supplicant/aidl/aidl_manager.cpp
@@ -762,6 +762,30 @@
}
/**
+ * Notify that the AT_PERMANENT_ID_REQ is denied from eap_peer when the strict
+ * conservative peer mode is enabled.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+*/
+void AidlManager::notifyPermanentIdReqDenied(struct wpa_supplicant *wpa_s)
+{
+ if (!wpa_s->current_ssid) {
+ wpa_printf(MSG_ERROR, "Current network NULL. Drop permanent_id_req_denied event!");
+ return;
+ }
+ struct wpa_ssid *current_ssid = wpa_s->current_ssid;
+
+ callWithEachStaNetworkCallback(
+ misc_utils::charBufToString(wpa_s->ifname),
+ current_ssid->id,
+ std::bind(
+ &ISupplicantStaNetworkCallback::
+ onPermanentIdReqDenied,
+ std::placeholders::_1));
+}
+
+/**
* Notify all listeners about the end of an ANQP query.
*
* @param wpa_s |wpa_supplicant| struct corresponding to the interface.
@@ -1570,19 +1594,18 @@
* @param config Configuration object
*/
void AidlManager::notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *config)
+ struct wpa_ssid *config, bool conn_status_requested)
{
- DppAkm securityAkm;
- DppConnectionKeys aidl_keys{};
std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+ DppConfigurationData aidl_dpp_config_data = {};
if ((config->key_mgmt & WPA_KEY_MGMT_SAE) &&
(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
- securityAkm = DppAkm::SAE;
+ aidl_dpp_config_data.securityAkm = DppAkm::SAE;
} else if (config->key_mgmt & WPA_KEY_MGMT_PSK) {
- securityAkm = DppAkm::PSK;
+ aidl_dpp_config_data.securityAkm = DppAkm::PSK;
} else if (config->key_mgmt & WPA_KEY_MGMT_DPP) {
- securityAkm = DppAkm::DPP;
+ aidl_dpp_config_data.securityAkm = DppAkm::DPP;
} else {
/* Unsupported AKM */
wpa_printf(MSG_ERROR, "DPP: Error: Unsupported AKM 0x%X",
@@ -1591,29 +1614,31 @@
return;
}
- std::string passphrase = misc_utils::charBufToString(config->passphrase);
+ aidl_dpp_config_data.password = misc_utils::charBufToString(config->passphrase);
+ aidl_dpp_config_data.psk = byteArrToVec(config->psk, 32);
std::vector<uint8_t> aidl_ssid(
config->ssid,
config->ssid + config->ssid_len);
+ aidl_dpp_config_data.ssid = aidl_ssid;
- if (securityAkm == DppAkm::DPP) {
+ if (aidl_dpp_config_data.securityAkm == DppAkm::DPP) {
std::string connector_str = misc_utils::charBufToString(config->dpp_connector);
- aidl_keys.connector = std::vector<uint8_t>(connector_str.begin(),
- connector_str.end());
- aidl_keys.cSign = byteArrToVec(config->dpp_csign, config->dpp_csign_len);
- aidl_keys.netAccessKey = byteArrToVec(config->dpp_netaccesskey,
- config->dpp_netaccesskey_len);
+ aidl_dpp_config_data.dppConnectionKeys.connector
+ = std::vector<uint8_t>(connector_str.begin(), connector_str.end());
+ aidl_dpp_config_data.dppConnectionKeys.cSign
+ = byteArrToVec(config->dpp_csign, config->dpp_csign_len);
+ aidl_dpp_config_data.dppConnectionKeys.netAccessKey
+ = byteArrToVec(config->dpp_netaccesskey, config->dpp_netaccesskey_len);
}
+ aidl_dpp_config_data.connStatusRequested = conn_status_requested;
/* At this point, the network is already registered, notify about new
* received configuration
*/
callWithEachStaIfaceCallback(aidl_ifname,
std::bind(
- &ISupplicantStaIfaceCallback::onDppSuccessConfigReceived,
- std::placeholders::_1, aidl_ssid, passphrase,
- byteArrToVec(config->psk, 32), securityAkm,
- aidl_keys));
+ &ISupplicantStaIfaceCallback::onDppConfigReceived,
+ std::placeholders::_1, aidl_dpp_config_data));
}
/**
@@ -1630,6 +1655,55 @@
std::placeholders::_1));
}
+DppStatusErrorCode convertSupplicantDppStatusErrorCodeToAidl(
+ enum dpp_status_error code)
+{
+ switch (code) {
+ case DPP_STATUS_OK:
+ return DppStatusErrorCode::SUCCESS;
+ case DPP_STATUS_NOT_COMPATIBLE:
+ return DppStatusErrorCode::NOT_COMPATIBLE;
+ case DPP_STATUS_AUTH_FAILURE:
+ return DppStatusErrorCode::AUTH_FAILURE;
+ case DPP_STATUS_UNWRAP_FAILURE:
+ return DppStatusErrorCode::UNWRAP_FAILURE;
+ case DPP_STATUS_BAD_GROUP:
+ return DppStatusErrorCode::BAD_GROUP;
+ case DPP_STATUS_CONFIGURE_FAILURE:
+ return DppStatusErrorCode::CONFIGURE_FAILURE;
+ case DPP_STATUS_RESPONSE_PENDING:
+ return DppStatusErrorCode::RESPONSE_PENDING;
+ case DPP_STATUS_INVALID_CONNECTOR:
+ return DppStatusErrorCode::INVALID_CONNECTOR;
+ case DPP_STATUS_CONFIG_REJECTED:
+ return DppStatusErrorCode::CONFIG_REJECTED;
+ case DPP_STATUS_NO_MATCH:
+ return DppStatusErrorCode::NO_MATCH;
+ case DPP_STATUS_NO_AP:
+ return DppStatusErrorCode::NO_AP;
+ case DPP_STATUS_CONFIGURE_PENDING:
+ return DppStatusErrorCode::CONFIGURE_PENDING;
+ case DPP_STATUS_CSR_NEEDED:
+ return DppStatusErrorCode::CSR_NEEDED;
+ case DPP_STATUS_CSR_BAD:
+ return DppStatusErrorCode::CSR_BAD;
+ case DPP_STATUS_NEW_KEY_NEEDED:
+ return DppStatusErrorCode::NEW_KEY_NEEDED;
+ default:
+ return DppStatusErrorCode::UNKNOWN;
+ }
+}
+
+void AidlManager::notifyDppConnectionStatusSent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result)
+{
+ std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+ callWithEachStaIfaceCallback(aidl_ifname,
+ std::bind(&ISupplicantStaIfaceCallback::onDppConnectionStatusResultSent,
+ std::placeholders::_1,
+ convertSupplicantDppStatusErrorCodeToAidl(result)));
+}
+
/**
* Notify listener about a DPP failure event
*
@@ -1917,24 +1991,33 @@
callWithEachStaIfaceCallback(misc_utils::charBufToString(wpa_s->ifname), func);
}
-void AidlManager::notifyFrequencyChanged(struct wpa_supplicant *wpa_group_s, int frequency)
+void AidlManager::notifyFrequencyChanged(struct wpa_supplicant *wpa_s, int frequency)
{
- if (!wpa_group_s || !wpa_group_s->parent)
+ if (!wpa_s)
return;
- // For group notifications, need to use the parent iface for callbacks.
- struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
- if (!wpa_s) {
+ std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+ struct wpa_supplicant *wpa_p2pdev_s = getTargetP2pIfaceForGroup(wpa_s);
+ if (wpa_p2pdev_s) {
+ // Notify frequency changed event on P2P interface
+ const std::function<
+ ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
+ func = std::bind(&ISupplicantP2pIfaceCallback::onGroupFrequencyChanged,
+ std::placeholders::_1, aidl_ifname, frequency);
+ // For group notifications, need to use the parent iface for callbacks.
+ callWithEachP2pIfaceCallback(misc_utils::charBufToString(wpa_p2pdev_s->ifname), func);
+ } else if (wpa_s->current_ssid) {
+ // Notify frequency changed event on STA interface
+ const std::function<
+ ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+ func = std::bind(
+ &ISupplicantStaIfaceCallback::onBssFrequencyChanged,
+ std::placeholders::_1, frequency);
+ callWithEachStaIfaceCallback(aidl_ifname, func);
+ } else {
wpa_printf(MSG_INFO, "Drop frequency changed event");
return;
- }
-
- const std::function<
- ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
- func = std::bind(&ISupplicantP2pIfaceCallback::onGroupFrequencyChanged,
- std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname),
- frequency);
- callWithEachP2pIfaceCallback(misc_utils::charBufToString(wpa_s->ifname), func);
+ }
}
void AidlManager::notifyCertification(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/aidl/aidl_manager.h b/wpa_supplicant/aidl/aidl_manager.h
index 1ed6899..5224ef2 100644
--- a/wpa_supplicant/aidl/aidl_manager.h
+++ b/wpa_supplicant/aidl/aidl_manager.h
@@ -61,6 +61,8 @@
int notifyNetworkRequest(
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
const char *param);
+ void notifyPermanentIdReqDenied(
+ struct wpa_supplicant *wpa_s);
void notifyAnqpQueryDone(
struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
const struct wpa_bss_anqp *anqp);
@@ -125,8 +127,11 @@
const u8 *p2p_dev_addr);
void notifyEapError(struct wpa_supplicant *wpa_s, int error_code);
void notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *config);
+ struct wpa_ssid *config,
+ bool conn_status_requested);
void notifyDppConfigSent(struct wpa_supplicant *wpa_s);
+ void notifyDppConnectionStatusSent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result);
void notifyDppSuccess(struct wpa_supplicant *wpa_s, DppEventType code);
void notifyDppFailure(struct wpa_supplicant *wpa_s,
DppFailureCode code);
diff --git a/wpa_supplicant/aidl/sta_iface.cpp b/wpa_supplicant/aidl/sta_iface.cpp
index d88f6f0..eb3e559 100644
--- a/wpa_supplicant/aidl/sta_iface.cpp
+++ b/wpa_supplicant/aidl/sta_iface.cpp
@@ -1956,6 +1956,21 @@
wpa_printf(MSG_DEBUG, "Add MLO Link ID %d info", i);
link.linkId = i;
link.staLinkMacAddress.assign(wpa_s->links[i].addr, wpa_s->links[i].addr + ETH_ALEN);
+ // TODO (b/259710591): Once suppllicant implements TID-to-link
+ // mapping, copy it here. Mapping can be changed in two
+ // scenarios
+ // 1. Mandatory mapping from AP
+ // 2. Negotiated mapping
+ // After association, framework call this API to get
+ // MloLinksInfo. If there is an update in mapping later, notify
+ // framework on the change using the callback,
+ // ISupplicantStaIfaceCallback.onMloLinksInfoChanged() with
+ // reason code as TID_TO_LINK_MAP. In absence of an advertised
+ // mapping by the AP, a default TID-to-link mapping is assumed
+ // unless an individual TID-to-link mapping is successfully
+ // negotiated.
+ link.tidsUplinkMap = 0xFF;
+ link.tidsDownlinkMap = 0xFF;
linksInfo.links.push_back(link);
}
diff --git a/wpa_supplicant/aidl/sta_network.cpp b/wpa_supplicant/aidl/sta_network.cpp
index f9f980c..db13509 100644
--- a/wpa_supplicant/aidl/sta_network.cpp
+++ b/wpa_supplicant/aidl/sta_network.cpp
@@ -304,6 +304,15 @@
in_identity);
}
+::ndk::ScopedAStatus StaNetwork::setStrictConservativePeerMode(
+ bool in_enable)
+{
+ return validateAndCall(
+ this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+ &StaNetwork::setStrictConservativePeerModeInternal,
+ in_enable);
+}
+
::ndk::ScopedAStatus StaNetwork::setEapAnonymousIdentity(
const std::vector<uint8_t>& in_identity)
{
@@ -1246,6 +1255,13 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus StaNetwork::setStrictConservativePeerModeInternal(bool enable)
+{
+ struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+ wpa_ssid->eap.strict_conservative_peer_mode = enable ? 1 : 0;
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus StaNetwork::setEapAnonymousIdentityInternal(
const std::vector<uint8_t> &identity)
{
@@ -2163,10 +2179,19 @@
KeyMgmtMask mask)
{
uint32_t key_mgmt_mask = static_cast<uint32_t>(mask);
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
if (key_mgmt_mask & ~kAllowedKeyMgmtMask) {
return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
}
+#ifdef CONFIG_SAE
+ struct wpa_driver_capa capa;
+ int res = wpa_drv_get_capa(wpa_s, &capa);
+ if ((res == 0) && (key_mgmt_mask & WPA_KEY_MGMT_SAE) &&
+ (capa.key_mgmt_iftype[WPA_IF_STATION] & WPA_DRIVER_CAPA_KEY_MGMT_SAE_EXT_KEY)) {
+ key_mgmt_mask |= WPA_KEY_MGMT_SAE_EXT_KEY;
+ }
+#endif
setFastTransitionKeyMgmt(key_mgmt_mask);
if (key_mgmt_mask & WPA_KEY_MGMT_OWE) {
@@ -2500,6 +2525,11 @@
(capa.key_mgmt_iftype[WPA_IF_STATION] & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE)) {
key_mgmt_mask |= WPA_KEY_MGMT_FT_SAE;
}
+ if ((key_mgmt_mask & WPA_KEY_MGMT_SAE_EXT_KEY) &&
+ (capa.key_mgmt_iftype[WPA_IF_STATION] &
+ WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE_EXT_KEY)) {
+ key_mgmt_mask |= WPA_KEY_MGMT_FT_SAE_EXT_KEY;
+ }
#endif
#ifdef CONFIG_FILS
if ((key_mgmt_mask & WPA_KEY_MGMT_FILS_SHA256) &&
diff --git a/wpa_supplicant/aidl/sta_network.h b/wpa_supplicant/aidl/sta_network.h
index 6661130..f794844 100644
--- a/wpa_supplicant/aidl/sta_network.h
+++ b/wpa_supplicant/aidl/sta_network.h
@@ -85,6 +85,8 @@
const std::vector<uint8_t>& in_identity) override;
::ndk::ScopedAStatus setEapEncryptedImsiIdentity(
const std::vector<uint8_t>& in_identity) override;
+ ::ndk::ScopedAStatus setStrictConservativePeerMode(
+ bool in_enable) override;
::ndk::ScopedAStatus setEapAnonymousIdentity(
const std::vector<uint8_t>& in_identity) override;
::ndk::ScopedAStatus setEapPassword(
@@ -212,6 +214,8 @@
const std::vector<uint8_t>& identity);
ndk::ScopedAStatus setEapEncryptedImsiIdentityInternal(
const std::vector<uint8_t>& identity);
+ ndk::ScopedAStatus setStrictConservativePeerModeInternal(
+ bool enable);
ndk::ScopedAStatus setEapAnonymousIdentityInternal(
const std::vector<uint8_t>& identity);
ndk::ScopedAStatus setEapPasswordInternal(
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 065b6fb..2b1bdeb 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2529,6 +2529,7 @@
{ INTe(sim_num, sim_num) },
{ STRe(imsi_privacy_cert, imsi_privacy_cert) },
{ STRe(imsi_privacy_attr, imsi_privacy_attr) },
+ { INTe(strict_conservative_peer_mode, strict_conservative_peer_mode) },
{ STRe(openssl_ciphers, openssl_ciphers) },
{ INTe(erp, erp) },
#endif /* IEEE8021X_EAPOL */
@@ -3953,6 +3954,11 @@
return 0;
}
+ if (os_strcmp(var, "strict_conservative_peer_mode") == 0) {
+ cred->strict_conservative_peer_mode = atoi(val);
+ return 0;
+ }
+
if (line) {
wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.",
line, var);
@@ -4109,6 +4115,9 @@
if (os_strcmp(var, "imsi_privacy_attr") == 0)
return alloc_strdup(cred->imsi_privacy_attr);
+ if (os_strcmp(var, "strict_conservative_peer_mode") == 0)
+ return alloc_int_str(cred->strict_conservative_peer_mode);
+
if (os_strcmp(var, "milenage") == 0) {
if (!(cred->milenage))
return NULL;
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index a81e9eb..0316e9b 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -202,6 +202,18 @@
char *imsi_privacy_attr;
/**
+ * strict_conservative_peer_mode - Whether the strict conservative peer
+ * mode is enabled or not
+ *
+ * This field is used to handle the reponse of AT_PERMANENT_ID_REQ
+ * for EAP-SIM/AKA/AKA', in convervative peer mode, a client error would
+ * be sent to the server, but it allows to send the permanent identity
+ * in some special cases according to 4.6.2 of RFC 4187; With the strict
+ * mode, it never send the permanent identity to server for privacy concern.
+ */
+ int strict_conservative_peer_mode;
+
+ /**
* engine - Use an engine for private key operations
*/
int engine;
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 260df8f..372a57b 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1044,6 +1044,9 @@
if (cred->imsi_privacy_attr)
fprintf(f, "\timsi_privacy_attr=\"%s\"\n",
cred->imsi_privacy_attr);
+ if (cred->strict_conservative_peer_mode)
+ fprintf(f,"\tstrict_conservative_peer_mode=\"%d\"\n",
+ cred->strict_conservative_peer_mode);
}
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index 55dcd70..593da3a 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -419,12 +419,21 @@
DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
MAC2STR(auth->peer_mac_addr), auth->curr_freq,
DPP_PA_CONNECTION_STATUS_RESULT);
- offchannel_send_action(wpa_s, auth->curr_freq,
- auth->peer_mac_addr, wpa_s->own_addr, broadcast,
- wpabuf_head(msg), wpabuf_len(msg),
- 500, wpas_dpp_tx_status, 0);
+ if (offchannel_send_action(wpa_s, auth->curr_freq,
+ auth->peer_mac_addr, wpa_s->own_addr, broadcast,
+ wpabuf_head(msg), wpabuf_len(msg),
+ 500, wpas_dpp_tx_status, 0) < 0) {
+ wpas_notify_dpp_connection_status_sent(wpa_s, result);
+ wpabuf_free(msg);
+ dpp_auth_deinit(wpa_s->dpp_auth);
+ wpa_s->dpp_auth = NULL;
+ return;
+ }
+
wpabuf_free(msg);
+ auth->conn_result_status = result;
+ auth->tx_conn_status_result_started = 1;
/* This exchange will be terminated in the TX status handler */
auth->remove_on_tx_status = 1;
@@ -491,6 +500,9 @@
#endif /* CONFIG_DPP2 */
if (wpa_s->dpp_auth->remove_on_tx_status) {
+ if (auth->tx_conn_status_result_started) {
+ wpas_notify_dpp_connection_status_sent(wpa_s, auth->conn_result_status);
+ }
wpa_printf(MSG_DEBUG,
"DPP: Terminate authentication exchange due to a request to do so on TX status");
eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
@@ -1476,7 +1488,7 @@
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_NETWORK_ID "%d", ssid->id);
- wpas_notify_dpp_config_received(wpa_s, ssid);
+ wpas_notify_dpp_config_received(wpa_s, ssid, auth->conn_status_requested ? 1 : 0);
if (wpa_s->conf->dpp_config_processing == 2)
ssid->disabled = 0;
@@ -1829,7 +1841,7 @@
wpabuf_free(msg);
/* This exchange will be terminated in the TX status handler */
- if (wpa_s->conf->dpp_config_processing < 2 ||
+ if (wpa_s->conf->dpp_config_processing < 1 ||
wpa_s->dpp_conf_backup_received)
auth->remove_on_tx_status = 1;
return;
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index 6198bd7..acd9044 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -1077,6 +1077,12 @@
goto fail;
}
+ if (cred->strict_conservative_peer_mode) {
+ if (wpa_config_set_quoted(ssid, "strict_conservative_peer_mode",
+ "1") < 0)
+ goto fail;
+ }
+
wpa_s->next_ssid = ssid;
wpa_config_update_prio_list(wpa_s->conf);
if (!only_add)
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index a544c94..7e6d042 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -280,6 +280,12 @@
}
+void wpas_notify_permanent_id_req_denied(struct wpa_supplicant *wpa_s)
+{
+ wpas_aidl_notify_permanent_id_req_denied(wpa_s);
+}
+
+
void wpas_notify_scanning(struct wpa_supplicant *wpa_s)
{
if (wpa_s->p2p_mgmt)
@@ -1103,13 +1109,13 @@
/* DPP Success notifications */
void wpas_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
+ struct wpa_ssid *ssid, bool conn_status_requested)
{
#ifdef CONFIG_DPP
if (!wpa_s)
return;
- wpas_aidl_notify_dpp_config_received(wpa_s, ssid);
+ wpas_aidl_notify_dpp_config_received(wpa_s, ssid, conn_status_requested);
#endif /* CONFIG_DPP */
}
@@ -1123,6 +1129,17 @@
#endif /* CONFIG_DPP */
}
+void wpas_notify_dpp_connection_status_sent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result)
+{
+#ifdef CONFIG_DPP2
+ if (!wpa_s)
+ return;
+
+ wpas_aidl_notify_dpp_connection_status_sent(wpa_s, result);
+#endif /* CONFIG_DPP2 */
+}
+
/* DPP Progress notifications */
void wpas_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
{
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 996be84..e1b9f17 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -48,6 +48,7 @@
struct wpa_ssid *ssid,
enum wpa_ctrl_req_type rtype,
const char *default_txt);
+void wpas_notify_permanent_id_req_denied(struct wpa_supplicant *wpa_s);
void wpas_notify_scanning(struct wpa_supplicant *wpa_s);
void wpas_notify_scan_done(struct wpa_supplicant *wpa_s, int success);
void wpas_notify_scan_results(struct wpa_supplicant *wpa_s);
@@ -180,8 +181,10 @@
void wpas_notify_hs20_rx_terms_and_conditions_acceptance(
struct wpa_supplicant *wpa_s, const char *url);
void wpas_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
+ struct wpa_ssid *ssid, bool conn_status_requested);
void wpas_notify_dpp_config_sent(struct wpa_supplicant *wpa_s);
+void wpas_notify_dpp_connection_status_sent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result);
void wpas_notify_dpp_auth_success(struct wpa_supplicant *wpa_s);
void wpas_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s);
void wpas_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s);
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 8262eef..b6a1a74 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -1175,6 +1175,14 @@
# unencrypted identity with EAP types that support different tunnelled
# identity, e.g., EAP-TTLS). This field can also be used with
# EAP-SIM/AKA/AKA' to store the pseudonym identity.
+# strict_conservative_peer_mode: Whether the strict conservative peer mode
+# is enabled. This field is used to handle the reponse of AT_PERMANENT_ID_REQ
+# for EAP-SIM/AKA/AKA'. In non-strict convervative peer mode, a client
+# error would be sent to the server, but the mode will send the permanent
+# identity in some special cases according to 4.6.2 of RFC 4187; With the
+# strict mode, the permanent identity is never sent to the server.
+# 0 = disabled (default)
+# 1 = enabled
# password: Password string for EAP. This field can include either the
# plaintext password (using ASCII or hex string) or a NtPasswordHash
# (16-byte MD4 hash of password) in hash:<32 hex digits> format.
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index e13ea8f..a733ae3 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -1093,6 +1093,12 @@
wpa_drv_set_supp_port(wpa_s, authorized);
}
+static void wpa_supplicant_permanent_id_req_denied_cb(void *ctx)
+{
+ struct wpas_supplicant *wpa_s = ctx;
+
+ wpas_notify_permanent_id_req_denied(wpa_s);
+}
static void wpa_supplicant_cert_cb(void *ctx, struct tls_cert_data *cert,
const char *cert_hash)
@@ -1238,6 +1244,7 @@
ctx->port_cb = wpa_supplicant_port_cb;
ctx->cb = wpa_supplicant_eapol_cb;
ctx->cert_cb = wpa_supplicant_cert_cb;
+ ctx->permanent_id_req_denied_cb = wpa_supplicant_permanent_id_req_denied_cb;
ctx->cert_in_cb = wpa_s->conf->cert_in_cb;
ctx->status_cb = wpa_supplicant_status_cb;
ctx->eap_error_cb = wpa_supplicant_eap_error_cb;