3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-12-30 06:02:39 +01:00

eapol: Call deauthenticate callback

This commit is contained in:
Denis Kenzior 2015-03-29 21:00:00 -05:00
parent 9f17b71375
commit e2badc9828

View File

@ -39,6 +39,7 @@
#include "eapol.h" #include "eapol.h"
#include "ie.h" #include "ie.h"
#include "util.h" #include "util.h"
#include "mpdu.h"
struct l_queue *state_machines; struct l_queue *state_machines;
eapol_tx_packet_func_t tx_packet = NULL; eapol_tx_packet_func_t tx_packet = NULL;
@ -533,6 +534,18 @@ void eapol_cancel(uint32_t ifindex)
L_UINT_TO_PTR(ifindex)); L_UINT_TO_PTR(ifindex));
} }
static inline void handshake_failed(uint32_t ifindex, struct eapol_sm *sm,
uint16_t reason_code)
{
if (!deauthenticate)
return;
deauthenticate(ifindex, sm->aa, sm->spa, reason_code, sm->user_data);
l_queue_remove(state_machines, sm);
eapol_sm_free(sm);
}
static void eapol_handle_ptk_1_of_4(uint32_t ifindex, struct eapol_sm *sm, static void eapol_handle_ptk_1_of_4(uint32_t ifindex, struct eapol_sm *sm,
const struct eapol_key *ek, const struct eapol_key *ek,
void *user_data) void *user_data)
@ -541,12 +554,17 @@ static void eapol_handle_ptk_1_of_4(uint32_t ifindex, struct eapol_sm *sm,
struct eapol_key *step2; struct eapol_key *step2;
uint8_t mic[16]; uint8_t mic[16];
if (!eapol_verify_ptk_1_of_4(ek)) if (!eapol_verify_ptk_1_of_4(ek)) {
handshake_failed(ifindex, sm, MPDU_REASON_CODE_UNSPECIFIED);
return; return;
}
if (!sm->have_snonce) { if (!sm->have_snonce) {
if (!get_nonce(sm->snonce)) if (!get_nonce(sm->snonce)) {
handshake_failed(ifindex, sm,
MPDU_REASON_CODE_UNSPECIFIED);
return; return;
}
sm->have_snonce = true; sm->have_snonce = true;
} }
@ -566,13 +584,14 @@ static void eapol_handle_ptk_1_of_4(uint32_t ifindex, struct eapol_sm *sm,
if (!eapol_calculate_mic(ptk->kck, step2, mic)) { if (!eapol_calculate_mic(ptk->kck, step2, mic)) {
l_info("MIC calculation failed. " l_info("MIC calculation failed. "
"Ensure Kernel Crypto is available."); "Ensure Kernel Crypto is available.");
goto fail; l_free(step2);
handshake_failed(ifindex, sm, MPDU_REASON_CODE_UNSPECIFIED);
return;
} }
memcpy(step2->key_mic_data, mic, sizeof(mic)); memcpy(step2->key_mic_data, mic, sizeof(mic));
tx_packet(ifindex, sm->aa, sm->spa, step2, user_data); tx_packet(ifindex, sm->aa, sm->spa, step2, user_data);
fail:
l_free(step2); l_free(step2);
} }
@ -721,8 +740,10 @@ static void eapol_handle_ptk_3_of_4(uint32_t ifindex,
const uint8_t *rsne; const uint8_t *rsne;
uint8_t gtk_key_index; uint8_t gtk_key_index;
if (!eapol_verify_ptk_3_of_4(ek)) if (!eapol_verify_ptk_3_of_4(ek)) {
handshake_failed(ifindex, sm, MPDU_REASON_CODE_UNSPECIFIED);
return; return;
}
/* /*
* 11.6.6.4: "On reception of Message 3, the Supplicant silently * 11.6.6.4: "On reception of Message 3, the Supplicant silently
@ -739,11 +760,15 @@ static void eapol_handle_ptk_3_of_4(uint32_t ifindex,
* Response frame, the STA shall disassociate. * Response frame, the STA shall disassociate.
*/ */
rsne = eapol_find_rsne(decrypted_key_data, decrypted_key_data_size); rsne = eapol_find_rsne(decrypted_key_data, decrypted_key_data_size);
if (!rsne) if (!rsne) {
handshake_failed(ifindex, sm, MPDU_REASON_CODE_IE_DIFFERENT);
return; return;
}
if (!eapol_ap_rsne_matches(rsne, sm->ap_rsn)) if (!eapol_ap_rsne_matches(rsne, sm->ap_rsn)) {
handshake_failed(ifindex, sm, MPDU_REASON_CODE_IE_DIFFERENT);
return; return;
}
/* /*
* TODO: Parse second RSNE * TODO: Parse second RSNE
@ -757,11 +782,10 @@ static void eapol_handle_ptk_3_of_4(uint32_t ifindex,
*/ */
gtk = eapol_find_gtk_kde(decrypted_key_data, decrypted_key_data_size, gtk = eapol_find_gtk_kde(decrypted_key_data, decrypted_key_data_size,
&gtk_len); &gtk_len);
if (!gtk) if (!gtk || gtk_len < 2) {
return; handshake_failed(ifindex, sm, MPDU_REASON_CODE_UNSPECIFIED);
if (gtk_len < 2)
return; return;
}
gtk_key_index = util_bit_field(gtk[0], 0, 2); gtk_key_index = util_bit_field(gtk[0], 0, 2);
/* TODO: Handle tx bit */ /* TODO: Handle tx bit */