EAP-PEAP server: Support vendor EAP types in Phase 2
This was already allowed with EAP-PEAP, but EAP-TEAP was hardcoded to use only the non-expanded EAP types. Extend that to allow vendor EAP types to be used. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
357c1062dc
commit
aba8dc82fc
1 changed files with 28 additions and 13 deletions
|
@ -938,15 +938,14 @@ static Boolean eap_teap_check(struct eap_sm *sm, void *priv,
|
||||||
|
|
||||||
|
|
||||||
static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data,
|
static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data,
|
||||||
enum eap_type eap_type)
|
int vendor, enum eap_type eap_type)
|
||||||
{
|
{
|
||||||
if (data->phase2_priv && data->phase2_method) {
|
if (data->phase2_priv && data->phase2_method) {
|
||||||
data->phase2_method->reset(sm, data->phase2_priv);
|
data->phase2_method->reset(sm, data->phase2_priv);
|
||||||
data->phase2_method = NULL;
|
data->phase2_method = NULL;
|
||||||
data->phase2_priv = NULL;
|
data->phase2_priv = NULL;
|
||||||
}
|
}
|
||||||
data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,
|
data->phase2_method = eap_server_get_eap_method(vendor, eap_type);
|
||||||
eap_type);
|
|
||||||
if (!data->phase2_method)
|
if (!data->phase2_method)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -962,7 +961,8 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm,
|
||||||
struct eap_teap_data *data,
|
struct eap_teap_data *data,
|
||||||
u8 *in_data, size_t in_len)
|
u8 *in_data, size_t in_len)
|
||||||
{
|
{
|
||||||
u8 next_type = EAP_TYPE_NONE;
|
int next_vendor = EAP_VENDOR_IETF;
|
||||||
|
enum eap_type next_type = EAP_TYPE_NONE;
|
||||||
struct eap_hdr *hdr;
|
struct eap_hdr *hdr;
|
||||||
u8 *pos;
|
u8 *pos;
|
||||||
size_t left;
|
size_t left;
|
||||||
|
@ -990,8 +990,9 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm,
|
||||||
m->method == EAP_TYPE_TNC) {
|
m->method == EAP_TYPE_TNC) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"EAP-TEAP: Peer Nak'ed required TNC negotiation");
|
"EAP-TEAP: Peer Nak'ed required TNC negotiation");
|
||||||
|
next_vendor = EAP_VENDOR_IETF;
|
||||||
next_type = eap_teap_req_failure(data, 0);
|
next_type = eap_teap_req_failure(data, 0);
|
||||||
eap_teap_phase2_init(sm, data, next_type);
|
eap_teap_phase2_init(sm, data, next_vendor, next_type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* EAP_SERVER_TNC */
|
#endif /* EAP_SERVER_TNC */
|
||||||
|
@ -999,14 +1000,17 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm,
|
||||||
if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
|
if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
|
||||||
sm->user->methods[sm->user_eap_method_index].method !=
|
sm->user->methods[sm->user_eap_method_index].method !=
|
||||||
EAP_TYPE_NONE) {
|
EAP_TYPE_NONE) {
|
||||||
|
next_vendor = sm->user->methods[
|
||||||
|
sm->user_eap_method_index].vendor;
|
||||||
next_type = sm->user->methods[
|
next_type = sm->user->methods[
|
||||||
sm->user_eap_method_index++].method;
|
sm->user_eap_method_index++].method;
|
||||||
wpa_printf(MSG_DEBUG, "EAP-TEAP: try EAP type %d",
|
wpa_printf(MSG_DEBUG, "EAP-TEAP: try EAP type %u:%u",
|
||||||
next_type);
|
next_vendor, next_type);
|
||||||
} else {
|
} else {
|
||||||
|
next_vendor = EAP_VENDOR_IETF;
|
||||||
next_type = eap_teap_req_failure(data, 0);
|
next_type = eap_teap_req_failure(data, 0);
|
||||||
}
|
}
|
||||||
eap_teap_phase2_init(sm, data, next_type);
|
eap_teap_phase2_init(sm, data, next_vendor, next_type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1026,8 +1030,9 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm,
|
||||||
|
|
||||||
if (!m->isSuccess(sm, priv)) {
|
if (!m->isSuccess(sm, priv)) {
|
||||||
wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 method failed");
|
wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 method failed");
|
||||||
|
next_vendor = EAP_VENDOR_IETF;
|
||||||
next_type = eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
|
next_type = eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
|
||||||
eap_teap_phase2_init(sm, data, next_type);
|
eap_teap_phase2_init(sm, data, next_vendor, next_type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1037,6 +1042,7 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm,
|
||||||
wpa_hexdump_ascii(MSG_DEBUG,
|
wpa_hexdump_ascii(MSG_DEBUG,
|
||||||
"EAP-TEAP: Phase 2 Identity not found in the user database",
|
"EAP-TEAP: Phase 2 Identity not found in the user database",
|
||||||
sm->identity, sm->identity_len);
|
sm->identity, sm->identity_len);
|
||||||
|
next_vendor = EAP_VENDOR_IETF;
|
||||||
next_type = eap_teap_req_failure(
|
next_type = eap_teap_req_failure(
|
||||||
data, TEAP_ERROR_INNER_METHOD);
|
data, TEAP_ERROR_INNER_METHOD);
|
||||||
break;
|
break;
|
||||||
|
@ -1047,23 +1053,28 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm,
|
||||||
/* TODO: Allow any inner EAP method that provides
|
/* TODO: Allow any inner EAP method that provides
|
||||||
* mutual authentication and EMSK derivation (i.e.,
|
* mutual authentication and EMSK derivation (i.e.,
|
||||||
* EAP-pwd or EAP-EKE). */
|
* EAP-pwd or EAP-EKE). */
|
||||||
|
next_vendor = EAP_VENDOR_IETF;
|
||||||
next_type = EAP_TYPE_PWD;
|
next_type = EAP_TYPE_PWD;
|
||||||
sm->user_eap_method_index = 0;
|
sm->user_eap_method_index = 0;
|
||||||
} else {
|
} else {
|
||||||
|
next_vendor = sm->user->methods[0].vendor;
|
||||||
next_type = sm->user->methods[0].method;
|
next_type = sm->user->methods[0].method;
|
||||||
sm->user_eap_method_index = 1;
|
sm->user_eap_method_index = 1;
|
||||||
}
|
}
|
||||||
wpa_printf(MSG_DEBUG, "EAP-TEAP: Try EAP type %d", next_type);
|
wpa_printf(MSG_DEBUG, "EAP-TEAP: Try EAP type %u:%u",
|
||||||
|
next_vendor, next_type);
|
||||||
break;
|
break;
|
||||||
case PHASE2_METHOD:
|
case PHASE2_METHOD:
|
||||||
case CRYPTO_BINDING:
|
case CRYPTO_BINDING:
|
||||||
eap_teap_update_icmk(sm, data);
|
eap_teap_update_icmk(sm, data);
|
||||||
eap_teap_state(data, CRYPTO_BINDING);
|
eap_teap_state(data, CRYPTO_BINDING);
|
||||||
data->eap_seq++;
|
data->eap_seq++;
|
||||||
|
next_vendor = EAP_VENDOR_IETF;
|
||||||
next_type = EAP_TYPE_NONE;
|
next_type = EAP_TYPE_NONE;
|
||||||
#ifdef EAP_SERVER_TNC
|
#ifdef EAP_SERVER_TNC
|
||||||
if (sm->tnc && !data->tnc_started) {
|
if (sm->tnc && !data->tnc_started) {
|
||||||
wpa_printf(MSG_DEBUG, "EAP-TEAP: Initialize TNC");
|
wpa_printf(MSG_DEBUG, "EAP-TEAP: Initialize TNC");
|
||||||
|
next_vendor = EAP_VENDOR_IETF;
|
||||||
next_type = EAP_TYPE_TNC;
|
next_type = EAP_TYPE_TNC;
|
||||||
data->tnc_started = 1;
|
data->tnc_started = 1;
|
||||||
}
|
}
|
||||||
|
@ -1077,7 +1088,7 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
eap_teap_phase2_init(sm, data, next_type);
|
eap_teap_phase2_init(sm, data, next_vendor, next_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1640,7 +1651,8 @@ static int eap_teap_process_phase1(struct eap_sm *sm,
|
||||||
static int eap_teap_process_phase2_start(struct eap_sm *sm,
|
static int eap_teap_process_phase2_start(struct eap_sm *sm,
|
||||||
struct eap_teap_data *data)
|
struct eap_teap_data *data)
|
||||||
{
|
{
|
||||||
u8 next_type;
|
int next_vendor;
|
||||||
|
enum eap_type next_type;
|
||||||
|
|
||||||
if (data->identity) {
|
if (data->identity) {
|
||||||
/* Used PAC and identity is from PAC-Opaque */
|
/* Used PAC and identity is from PAC-Opaque */
|
||||||
|
@ -1653,6 +1665,7 @@ static int eap_teap_process_phase2_start(struct eap_sm *sm,
|
||||||
wpa_hexdump_ascii(MSG_DEBUG,
|
wpa_hexdump_ascii(MSG_DEBUG,
|
||||||
"EAP-TEAP: Phase 2 Identity not found in the user database",
|
"EAP-TEAP: Phase 2 Identity not found in the user database",
|
||||||
sm->identity, sm->identity_len);
|
sm->identity, sm->identity_len);
|
||||||
|
next_vendor = EAP_VENDOR_IETF;
|
||||||
next_type = EAP_TYPE_NONE;
|
next_type = EAP_TYPE_NONE;
|
||||||
eap_teap_state(data, PHASE2_METHOD);
|
eap_teap_state(data, PHASE2_METHOD);
|
||||||
} else if (sm->eap_teap_pac_no_inner) {
|
} else if (sm->eap_teap_pac_no_inner) {
|
||||||
|
@ -1672,6 +1685,7 @@ static int eap_teap_process_phase2_start(struct eap_sm *sm,
|
||||||
} else {
|
} else {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"EAP-TEAP: Identity already known - skip Phase 2 Identity Request");
|
"EAP-TEAP: Identity already known - skip Phase 2 Identity Request");
|
||||||
|
next_vendor = sm->user->methods[0].vendor;
|
||||||
next_type = sm->user->methods[0].method;
|
next_type = sm->user->methods[0].method;
|
||||||
sm->user_eap_method_index = 1;
|
sm->user_eap_method_index = 1;
|
||||||
eap_teap_state(data, PHASE2_METHOD);
|
eap_teap_state(data, PHASE2_METHOD);
|
||||||
|
@ -1682,10 +1696,11 @@ static int eap_teap_process_phase2_start(struct eap_sm *sm,
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
eap_teap_state(data, PHASE2_ID);
|
eap_teap_state(data, PHASE2_ID);
|
||||||
|
next_vendor = EAP_VENDOR_IETF;
|
||||||
next_type = EAP_TYPE_IDENTITY;
|
next_type = EAP_TYPE_IDENTITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return eap_teap_phase2_init(sm, data, next_type);
|
return eap_teap_phase2_init(sm, data, next_vendor, next_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue