@@ -66,6 +66,7 @@ struct eap_peap_data {
66
66
u8 cmk [20 ];
67
67
int soh ; /* Whether IF-TNCCS-SOH (Statement of Health; Microsoft NAP)
68
68
* is enabled. */
69
+ enum { NO_AUTH , FOR_INITIAL , ALWAYS } phase2_auth ;
69
70
};
70
71
71
72
@@ -114,6 +115,19 @@ eap_peap_parse_phase1(struct eap_peap_data *data,
114
115
wpa_printf (MSG_DEBUG , "EAP-PEAP: Require cryptobinding" );
115
116
}
116
117
118
+ if (os_strstr (phase1 , "phase2_auth=0" )) {
119
+ data -> phase2_auth = NO_AUTH ;
120
+ wpa_printf (MSG_DEBUG ,
121
+ "EAP-PEAP: Do not require Phase 2 authentication" );
122
+ } else if (os_strstr (phase1 , "phase2_auth=1" )) {
123
+ data -> phase2_auth = FOR_INITIAL ;
124
+ wpa_printf (MSG_DEBUG ,
125
+ "EAP-PEAP: Require Phase 2 authentication for initial connection" );
126
+ } else if (os_strstr (phase1 , "phase2_auth=2" )) {
127
+ data -> phase2_auth = ALWAYS ;
128
+ wpa_printf (MSG_DEBUG ,
129
+ "EAP-PEAP: Require Phase 2 authentication for all cases" );
130
+ }
117
131
#ifdef EAP_TNC
118
132
if (os_strstr (phase1 , "tnc=soh2" )) {
119
133
data -> soh = 2 ;
@@ -145,6 +159,7 @@ eap_peap_init(struct eap_sm *sm)
145
159
data -> force_peap_version = -1 ;
146
160
data -> peap_outer_success = 2 ;
147
161
data -> crypto_binding = OPTIONAL_BINDING ;
162
+ data -> phase2_auth = FOR_INITIAL ;
148
163
149
164
if (config && config -> phase1 &&
150
165
eap_peap_parse_phase1 (data , config -> phase1 ) < 0 ) {
@@ -449,6 +464,18 @@ eap_tlv_validate_cryptobinding(struct eap_sm *sm,
449
464
return 0 ;
450
465
}
451
466
467
+ static bool peap_phase2_sufficient (struct eap_sm * sm ,
468
+ struct eap_peap_data * data )
469
+ {
470
+ if ((data -> phase2_auth == ALWAYS ||
471
+ (data -> phase2_auth == FOR_INITIAL &&
472
+ !tls_connection_resumed (sm -> ssl_ctx , data -> ssl .conn ) &&
473
+ !data -> ssl .client_cert_conf ) ||
474
+ data -> phase2_eap_started ) &&
475
+ !data -> phase2_eap_success )
476
+ return false;
477
+ return true;
478
+ }
452
479
453
480
/**
454
481
* eap_tlv_process - Process a received EAP-TLV message and generate a response
@@ -565,6 +592,11 @@ eap_tlv_process(struct eap_sm *sm, struct eap_peap_data *data,
565
592
" - force failed Phase 2" );
566
593
resp_status = EAP_TLV_RESULT_FAILURE ;
567
594
ret -> decision = DECISION_FAIL ;
595
+ } else if (!peap_phase2_sufficient (sm , data )) {
596
+ wpa_printf (MSG_INFO ,
597
+ "EAP-PEAP: Server indicated Phase 2 success, but sufficient Phase 2 authentication has not been completed" );
598
+ resp_status = EAP_TLV_RESULT_FAILURE ;
599
+ ret -> decision = DECISION_FAIL ;
568
600
} else {
569
601
resp_status = EAP_TLV_RESULT_SUCCESS ;
570
602
ret -> decision = DECISION_UNCOND_SUCC ;
@@ -939,8 +971,7 @@ eap_peap_decrypt(struct eap_sm *sm, struct eap_peap_data *data,
939
971
/* EAP-Success within TLS tunnel is used to indicate
940
972
* shutdown of the TLS channel. The authentication has
941
973
* been completed. */
942
- if (data -> phase2_eap_started &&
943
- !data -> phase2_eap_success ) {
974
+ if (!peap_phase2_sufficient (sm , data )) {
944
975
wpa_printf (MSG_DEBUG , "EAP-PEAP: Phase 2 "
945
976
"Success used to indicate success, "
946
977
"but Phase 2 EAP was not yet "
@@ -1194,7 +1225,7 @@ eap_peap_has_reauth_data(struct eap_sm *sm, void *priv)
1194
1225
{
1195
1226
struct eap_peap_data * data = priv ;
1196
1227
return tls_connection_established (sm -> ssl_ctx , data -> ssl .conn ) &&
1197
- data -> phase2_success ;
1228
+ data -> phase2_success && data -> phase2_auth != ALWAYS ;
1198
1229
}
1199
1230
1200
1231
0 commit comments