eap-peap: Don't allow authenticated client to skip EAP-TNC with unexpected EAP-SUCCESS
EAP-PEAP transports results as separate AVPs, we expect one after the
first phase 2 authentication (if not using certificates). However, with
the previous caching of the result of that, the client could then send
another confirmation as response to the EAP-TNC request to skip it.
Since no group membership is set if EAP-TNC is not complete, it shouldn't
really affect its outcome, though.
Fixes: 1be296dfb2 ("implemented the PEAP tunneling protocol as an EAP plugin")
This commit is contained in:
@@ -106,7 +106,8 @@ static status_t start_phase2_auth(private_eap_peap_server_t *this)
|
|||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, type);
|
DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, type);
|
||||||
this->ph2_method = charon->eap->create_instance(charon->eap, type, 0,
|
this->phase2_result = EAP_FAILURE;
|
||||||
|
this->ph2_method = charon->eap->create_instance(charon->eap, type, 0,
|
||||||
EAP_SERVER, this->server, this->peer);
|
EAP_SERVER, this->server, this->peer);
|
||||||
if (this->ph2_method == NULL)
|
if (this->ph2_method == NULL)
|
||||||
{
|
{
|
||||||
@@ -125,7 +126,7 @@ static status_t start_phase2_auth(private_eap_peap_server_t *this)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
|
DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +139,7 @@ static status_t start_phase2_tnc(private_eap_peap_server_t *this)
|
|||||||
"%s.plugins.eap-peap.phase2_tnc", FALSE, lib->ns))
|
"%s.plugins.eap-peap.phase2_tnc", FALSE, lib->ns))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, EAP_TNC);
|
DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, EAP_TNC);
|
||||||
|
this->phase2_result = EAP_FAILURE;
|
||||||
this->ph2_method = charon->eap->create_instance(charon->eap, EAP_TNC,
|
this->ph2_method = charon->eap->create_instance(charon->eap, EAP_TNC,
|
||||||
0, EAP_SERVER, this->server, this->peer);
|
0, EAP_SERVER, this->server, this->peer);
|
||||||
if (this->ph2_method == NULL)
|
if (this->ph2_method == NULL)
|
||||||
@@ -218,9 +220,14 @@ METHOD(tls_application_t, process, status_t,
|
|||||||
DBG1(DBG_IKE, "received tunneled EAP-PEAP AVP [EAP/%N]",
|
DBG1(DBG_IKE, "received tunneled EAP-PEAP AVP [EAP/%N]",
|
||||||
eap_code_short_names, code);
|
eap_code_short_names, code);
|
||||||
in->destroy(in);
|
in->destroy(in);
|
||||||
/* if EAP_SUCCESS check if to continue phase2 with EAP-TNC */
|
|
||||||
return (this->phase2_result == EAP_SUCCESS && code == EAP_SUCCESS) ?
|
if (this->phase2_result == EAP_SUCCESS && code == EAP_SUCCESS)
|
||||||
start_phase2_tnc(this) : FAILED;
|
{
|
||||||
|
/* only accept SUCCESS once after a successful inner method */
|
||||||
|
this->phase2_result = EAP_FAILURE;
|
||||||
|
return start_phase2_tnc(this);
|
||||||
|
}
|
||||||
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->ph2_method)
|
if (this->ph2_method)
|
||||||
@@ -292,7 +299,7 @@ METHOD(tls_application_t, process, status_t,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->ph2_method == 0)
|
if (this->ph2_method == NULL)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "no %N phase2 method installed", eap_type_names, EAP_PEAP);
|
DBG1(DBG_IKE, "no %N phase2 method installed", eap_type_names, EAP_PEAP);
|
||||||
in->destroy(in);
|
in->destroy(in);
|
||||||
|
|||||||
Reference in New Issue
Block a user