From 76ddfae6eba148a528629cb12146bc8abf2b42d8 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 16 Aug 2019 23:54:51 +0300 Subject: [PATCH] EAP-TEAP server: Testing mechanism for Result TLV in a separate message The new eap_teap_separate_result=1 hostapd configuration parameter can be used to test TEAP exchange where the Intermediate-Result TLV and Crypto-Binding TLV are send in one message exchange while the Result TLV exchange in done after that in a separate message exchange. Signed-off-by: Jouni Malinen --- hostapd/config_file.c | 2 ++ hostapd/hostapd.conf | 5 +++++ src/ap/ap_config.h | 1 + src/ap/authsrv.c | 1 + src/ap/ieee802_1x.c | 2 +- src/eap_server/eap.h | 1 + src/eap_server/eap_i.h | 1 + src/eap_server/eap_server.c | 1 + src/eap_server/eap_server_teap.c | 23 ++++++++++++++++++++--- src/eapol_auth/eapol_auth_sm.c | 3 +++ src/eapol_auth/eapol_auth_sm.h | 1 + src/radius/radius_server.c | 3 +++ src/radius/radius_server.h | 1 + 13 files changed, 41 insertions(+), 4 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index e09e6e141..1ef7d57cc 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2620,6 +2620,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, bss->eap_teap_auth = val; } else if (os_strcmp(buf, "eap_teap_pac_no_inner") == 0) { bss->eap_teap_pac_no_inner = atoi(pos); + } else if (os_strcmp(buf, "eap_teap_separate_result") == 0) { + bss->eap_teap_separate_result = atoi(pos); #endif /* EAP_SERVER_TEAP */ #ifdef EAP_SERVER_SIM } else if (os_strcmp(buf, "eap_sim_db") == 0) { diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index adfc7bdf9..f36e1fa3a 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1201,6 +1201,11 @@ eap_server=0 # 1 = skip inner authentication (inner EAP/Basic-Password-Auth) #eap_teap_pac_no_inner=0 +# EAP-TEAP behavior with Result TLV +# 0 = include with Intermediate-Result TLV (default) +# 1 = send in a separate message (for testing purposes) +#eap_teap_separate_result=0 + # EAP-SIM and EAP-AKA protected success/failure indication using AT_RESULT_IND # (default: 0 = disabled). #eap_sim_aka_result_ind=1 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index ea581a822..daf787e16 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -429,6 +429,7 @@ struct hostapd_bss_config { int pac_key_refresh_time; int eap_teap_auth; int eap_teap_pac_no_inner; + int eap_teap_separate_result; int eap_sim_aka_result_ind; int eap_sim_id; int tnc; diff --git a/src/ap/authsrv.c b/src/ap/authsrv.c index 4f5fe7db4..21e4c22d8 100644 --- a/src/ap/authsrv.c +++ b/src/ap/authsrv.c @@ -122,6 +122,7 @@ static int hostapd_setup_radius_srv(struct hostapd_data *hapd) srv.pac_key_refresh_time = conf->pac_key_refresh_time; srv.eap_teap_auth = conf->eap_teap_auth; srv.eap_teap_pac_no_inner = conf->eap_teap_pac_no_inner; + srv.eap_teap_separate_result = conf->eap_teap_separate_result; srv.eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; srv.eap_sim_id = conf->eap_sim_id; srv.tnc = conf->tnc; diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c index e0614710f..a7a090190 100644 --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c @@ -2435,7 +2435,7 @@ int ieee802_1x_init(struct hostapd_data *hapd) conf.pac_key_lifetime = hapd->conf->pac_key_lifetime; conf.pac_key_refresh_time = hapd->conf->pac_key_refresh_time; conf.eap_teap_auth = hapd->conf->eap_teap_auth; - conf.eap_teap_pac_no_inner = hapd->conf->eap_teap_pac_no_inner; + conf.eap_teap_separate_result = hapd->conf->eap_teap_separate_result; conf.eap_sim_aka_result_ind = hapd->conf->eap_sim_aka_result_ind; conf.eap_sim_id = hapd->conf->eap_sim_id; conf.tnc = hapd->conf->tnc; diff --git a/src/eap_server/eap.h b/src/eap_server/eap.h index a9cf5c97b..8ce499aea 100644 --- a/src/eap_server/eap.h +++ b/src/eap_server/eap.h @@ -123,6 +123,7 @@ struct eap_config { int pac_key_refresh_time; int eap_teap_auth; int eap_teap_pac_no_inner; + int eap_teap_separate_result; int eap_sim_aka_result_ind; int eap_sim_id; int tnc; diff --git a/src/eap_server/eap_i.h b/src/eap_server/eap_i.h index f9ab32d69..ba910d238 100644 --- a/src/eap_server/eap_i.h +++ b/src/eap_server/eap_i.h @@ -192,6 +192,7 @@ struct eap_sm { int pac_key_refresh_time; int eap_teap_auth; int eap_teap_pac_no_inner; + int eap_teap_separate_result; int eap_sim_aka_result_ind; int eap_sim_id; int tnc; diff --git a/src/eap_server/eap_server.c b/src/eap_server/eap_server.c index 568eebd7e..3ba3f67a1 100644 --- a/src/eap_server/eap_server.c +++ b/src/eap_server/eap_server.c @@ -1871,6 +1871,7 @@ struct eap_sm * eap_server_sm_init(void *eapol_ctx, sm->pac_key_refresh_time = conf->pac_key_refresh_time; sm->eap_teap_auth = conf->eap_teap_auth; sm->eap_teap_pac_no_inner = conf->eap_teap_pac_no_inner; + sm->eap_teap_separate_result = conf->eap_teap_separate_result; sm->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; sm->eap_sim_id = conf->eap_sim_id; sm->tnc = conf->tnc; diff --git a/src/eap_server/eap_server_teap.c b/src/eap_server/eap_server_teap.c index ac2339aa4..c1bdfcdf7 100644 --- a/src/eap_server/eap_server_teap.c +++ b/src/eap_server/eap_server_teap.c @@ -31,7 +31,7 @@ struct eap_teap_data { enum { START, PHASE1, PHASE1B, PHASE2_START, PHASE2_ID, PHASE2_BASIC_AUTH, PHASE2_METHOD, CRYPTO_BINDING, REQUEST_PAC, - FAILURE_SEND_RESULT, SUCCESS, FAILURE + FAILURE_SEND_RESULT, SUCCESS_SEND_RESULT, SUCCESS, FAILURE } state; u8 teap_version; @@ -100,6 +100,8 @@ static const char * eap_teap_state_txt(int state) return "REQUEST_PAC"; case FAILURE_SEND_RESULT: return "FAILURE_SEND_RESULT"; + case SUCCESS_SEND_RESULT: + return "SUCCESS_SEND_RESULT"; case SUCCESS: return "SUCCESS"; case FAILURE: @@ -565,7 +567,7 @@ static struct wpabuf * eap_teap_build_crypto_binding( return NULL; if (data->send_new_pac || data->anon_provisioning || - data->phase2_method) + data->phase2_method || sm->eap_teap_separate_result) data->final_result = 0; else data->final_result = 1; @@ -901,6 +903,10 @@ static struct wpabuf * eap_teap_buildReq(struct eap_sm *sm, void *priv, u8 id) req = wpabuf_concat( req, eap_teap_tlv_error(data->error_code)); break; + case SUCCESS_SEND_RESULT: + req = eap_teap_tlv_result(TEAP_STATUS_SUCCESS, 0); + data->final_result = 1; + break; default: wpa_printf(MSG_DEBUG, "EAP-TEAP: %s - unexpected state %d", __func__, data->state); @@ -1498,8 +1504,11 @@ static void eap_teap_process_phase2_tlvs(struct eap_sm *sm, wpa_printf(MSG_DEBUG, "EAP-TEAP: Server triggered re-keying of Tunnel PAC"); eap_teap_state(data, REQUEST_PAC); - } else if (data->final_result) + } else if (data->final_result) { eap_teap_state(data, SUCCESS); + } else if (sm->eap_teap_separate_result) { + eap_teap_state(data, SUCCESS_SEND_RESULT); + } } if (tlv.basic_auth_resp) { @@ -1523,6 +1532,13 @@ static void eap_teap_process_phase2_tlvs(struct eap_sm *sm, eap_teap_process_phase2_eap(sm, data, tlv.eap_payload_tlv, tlv.eap_payload_tlv_len); } + + if (data->state == SUCCESS_SEND_RESULT && + tlv.result == TEAP_STATUS_SUCCESS) { + wpa_printf(MSG_DEBUG, + "EAP-TEAP: Peer agreed with final success - authentication completed"); + eap_teap_state(data, SUCCESS); + } } @@ -1693,6 +1709,7 @@ static void eap_teap_process_msg(struct eap_sm *sm, void *priv, case PHASE2_METHOD: case CRYPTO_BINDING: case REQUEST_PAC: + case SUCCESS_SEND_RESULT: eap_teap_process_phase2(sm, data, data->ssl.tls_in); break; case FAILURE_SEND_RESULT: diff --git a/src/eapol_auth/eapol_auth_sm.c b/src/eapol_auth/eapol_auth_sm.c index 7206d32d7..5a2abb518 100644 --- a/src/eapol_auth/eapol_auth_sm.c +++ b/src/eapol_auth/eapol_auth_sm.c @@ -837,6 +837,8 @@ eapol_auth_alloc(struct eapol_authenticator *eapol, const u8 *addr, eap_conf.pac_key_refresh_time = eapol->conf.pac_key_refresh_time; eap_conf.eap_teap_auth = eapol->conf.eap_teap_auth; eap_conf.eap_teap_pac_no_inner = eapol->conf.eap_teap_pac_no_inner; + eap_conf.eap_teap_separate_result = + eapol->conf.eap_teap_separate_result; eap_conf.eap_sim_aka_result_ind = eapol->conf.eap_sim_aka_result_ind; eap_conf.eap_sim_id = eapol->conf.eap_sim_id; eap_conf.tnc = eapol->conf.tnc; @@ -1236,6 +1238,7 @@ static int eapol_auth_conf_clone(struct eapol_auth_config *dst, dst->pac_key_refresh_time = src->pac_key_refresh_time; dst->eap_teap_auth = src->eap_teap_auth; dst->eap_teap_pac_no_inner = src->eap_teap_pac_no_inner; + dst->eap_teap_separate_result = src->eap_teap_separate_result; dst->eap_sim_aka_result_ind = src->eap_sim_aka_result_ind; dst->eap_sim_id = src->eap_sim_id; dst->tnc = src->tnc; diff --git a/src/eapol_auth/eapol_auth_sm.h b/src/eapol_auth/eapol_auth_sm.h index bcdd50971..fc467da59 100644 --- a/src/eapol_auth/eapol_auth_sm.h +++ b/src/eapol_auth/eapol_auth_sm.h @@ -38,6 +38,7 @@ struct eapol_auth_config { int pac_key_refresh_time; int eap_teap_auth; int eap_teap_pac_no_inner; + int eap_teap_separate_result; int eap_sim_aka_result_ind; int eap_sim_id; int tnc; diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c index 70efd11b4..100cf52ae 100644 --- a/src/radius/radius_server.c +++ b/src/radius/radius_server.c @@ -240,6 +240,7 @@ struct radius_server_data { int eap_teap_auth; int eap_teap_pac_no_inner; + int eap_teap_separate_result; /** * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication @@ -799,6 +800,7 @@ radius_server_get_new_session(struct radius_server_data *data, eap_conf.pac_key_refresh_time = data->pac_key_refresh_time; eap_conf.eap_teap_auth = data->eap_teap_auth; eap_conf.eap_teap_pac_no_inner = data->eap_teap_pac_no_inner; + eap_conf.eap_teap_separate_result = data->eap_teap_separate_result; eap_conf.eap_sim_aka_result_ind = data->eap_sim_aka_result_ind; eap_conf.eap_sim_id = data->eap_sim_id; eap_conf.tnc = data->tnc; @@ -2394,6 +2396,7 @@ radius_server_init(struct radius_server_conf *conf) data->pac_key_refresh_time = conf->pac_key_refresh_time; data->eap_teap_auth = conf->eap_teap_auth; data->eap_teap_pac_no_inner = conf->eap_teap_pac_no_inner; + data->eap_teap_separate_result = conf->eap_teap_separate_result; data->get_eap_user = conf->get_eap_user; data->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; data->eap_sim_id = conf->eap_sim_id; diff --git a/src/radius/radius_server.h b/src/radius/radius_server.h index 54896946e..c8c17dbb6 100644 --- a/src/radius/radius_server.h +++ b/src/radius/radius_server.h @@ -130,6 +130,7 @@ struct radius_server_conf { int eap_teap_auth; int eap_teap_pac_no_inner; + int eap_teap_separate_result; /** * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication