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) {
# 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
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;
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;
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;
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;
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;
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;
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;
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:
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;
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);
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) {
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);
+ }
}
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:
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;
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;
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;
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
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;
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;
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