Merge branch 'eap-mschapv2-eap-identity'
This replaces the EAP-Identity with the EAP-MSCHAPv2 username, which ensures the client is known with an authenticated identity. Previously a client with a valid username could use a different identity (e.g. the name of a different user) in the EAP-Identity exchange. Since we use the EAP-Identity for uniqueness checks etc. this could be problematic. The EAP-MSCHAPv2 username is now explicitly logged if it is different from the EAP-Identity (or IKE identity). Fixes #1182.
This commit is contained in:
@@ -81,6 +81,11 @@ struct private_eap_mschapv2_t
|
|||||||
* Number of retries
|
* Number of retries
|
||||||
*/
|
*/
|
||||||
int retries;
|
int retries;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide EAP-Identity
|
||||||
|
*/
|
||||||
|
auth_cfg_t *auth;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1058,7 +1063,10 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
|
|||||||
name_len = min(data.len - RESPONSE_PAYLOAD_LEN, 255);
|
name_len = min(data.len - RESPONSE_PAYLOAD_LEN, 255);
|
||||||
snprintf(buf, sizeof(buf), "%.*s", name_len, res->name);
|
snprintf(buf, sizeof(buf), "%.*s", name_len, res->name);
|
||||||
userid = identification_create_from_string(buf);
|
userid = identification_create_from_string(buf);
|
||||||
DBG2(DBG_IKE, "EAP-MS-CHAPv2 username: '%Y'", userid);
|
if (!userid->equals(userid, this->peer))
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "EAP-MS-CHAPv2 username: '%Y'", userid);
|
||||||
|
}
|
||||||
/* userid can only be destroyed after the last use of username */
|
/* userid can only be destroyed after the last use of username */
|
||||||
username = extract_username(userid->get_encoding(userid));
|
username = extract_username(userid->get_encoding(userid));
|
||||||
|
|
||||||
@@ -1084,7 +1092,6 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
|
|||||||
chunk_clear(&nt_hash);
|
chunk_clear(&nt_hash);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
userid->destroy(userid);
|
|
||||||
chunk_clear(&nt_hash);
|
chunk_clear(&nt_hash);
|
||||||
|
|
||||||
if (memeq_const(res->response.nt_response, this->nt_response.ptr,
|
if (memeq_const(res->response.nt_response, this->nt_response.ptr,
|
||||||
@@ -1109,9 +1116,11 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
|
|||||||
chunk_free(&hex);
|
chunk_free(&hex);
|
||||||
memcpy(eap->data, msg, AUTH_RESPONSE_LEN + sizeof(SUCCESS_MESSAGE));
|
memcpy(eap->data, msg, AUTH_RESPONSE_LEN + sizeof(SUCCESS_MESSAGE));
|
||||||
*out = eap_payload_create_data(chunk_create((void*) eap, len));
|
*out = eap_payload_create_data(chunk_create((void*) eap, len));
|
||||||
|
|
||||||
|
this->auth->add(this->auth, AUTH_RULE_EAP_IDENTITY, userid);
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
}
|
}
|
||||||
|
userid->destroy(userid);
|
||||||
return process_server_retry(this, out);
|
return process_server_retry(this, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1197,11 +1206,18 @@ METHOD(eap_method_t, is_mutual, bool,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(eap_method_t, get_auth, auth_cfg_t*,
|
||||||
|
private_eap_mschapv2_t *this)
|
||||||
|
{
|
||||||
|
return this->auth;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(eap_method_t, destroy, void,
|
METHOD(eap_method_t, destroy, void,
|
||||||
private_eap_mschapv2_t *this)
|
private_eap_mschapv2_t *this)
|
||||||
{
|
{
|
||||||
this->peer->destroy(this->peer);
|
this->peer->destroy(this->peer);
|
||||||
this->server->destroy(this->server);
|
this->server->destroy(this->server);
|
||||||
|
this->auth->destroy(this->auth);
|
||||||
chunk_free(&this->challenge);
|
chunk_free(&this->challenge);
|
||||||
chunk_free(&this->nt_response);
|
chunk_free(&this->nt_response);
|
||||||
chunk_free(&this->auth_response);
|
chunk_free(&this->auth_response);
|
||||||
@@ -1224,11 +1240,13 @@ static private_eap_mschapv2_t *eap_mschapv2_create_generic(identification_t *ser
|
|||||||
.get_msk = _get_msk,
|
.get_msk = _get_msk,
|
||||||
.get_identifier = _get_identifier,
|
.get_identifier = _get_identifier,
|
||||||
.set_identifier = _set_identifier,
|
.set_identifier = _set_identifier,
|
||||||
|
.get_auth = _get_auth,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.peer = peer->clone(peer),
|
.peer = peer->clone(peer),
|
||||||
.server = server->clone(server),
|
.server = server->clone(server),
|
||||||
|
.auth = auth_cfg_create(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -951,9 +951,9 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
|
|||||||
{
|
{
|
||||||
entry_t entry;
|
entry_t entry;
|
||||||
|
|
||||||
while (array_remove(other->entries, ARRAY_HEAD, &entry))
|
while (array_remove(other->entries, ARRAY_TAIL, &entry))
|
||||||
{
|
{ /* keep order but prefer new values (esp. for single valued ones) */
|
||||||
array_insert(this->entries, ARRAY_TAIL, &entry);
|
array_insert(this->entries, ARRAY_HEAD, &entry);
|
||||||
}
|
}
|
||||||
array_compress(other->entries);
|
array_compress(other->entries);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user