From 91d35987fd44dd30bf0b1af3a38215980e192382 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Tue, 11 Oct 2016 01:36:48 -0500 Subject: [PATCH] eapol: Add provision to use EAPOL-Start --- src/eapol.c | 36 ++++++++++++++++++++++++++++++++++++ src/eapol.h | 1 + 2 files changed, 37 insertions(+) diff --git a/src/eapol.c b/src/eapol.c index 7f0ed0b9..b9413b67 100644 --- a/src/eapol.c +++ b/src/eapol.c @@ -726,11 +726,13 @@ struct eapol_sm { eapol_sm_event_func_t event_func; void *user_data; struct l_timeout *timeout; + struct l_timeout *eapol_start_timeout; bool have_snonce:1; bool have_replay:1; bool ptk_complete:1; bool wpa_ie:1; bool have_pmk:1; + bool use_eapol_start:1; struct eap_state *eap; }; @@ -742,6 +744,7 @@ static void eapol_sm_destroy(void *value) l_free(sm->own_ie); l_timeout_remove(sm->timeout); + l_timeout_remove(sm->eapol_start_timeout); if (sm->eap) eap_free(sm->eap); @@ -920,6 +923,22 @@ static void eapol_timeout(struct l_timeout *timeout, void *user_data) MPDU_REASON_CODE_4WAY_HANDSHAKE_TIMEOUT); } +static void send_eapol_start(struct l_timeout *timeout, void *user_data) +{ + struct eapol_sm *sm = user_data; + uint8_t buf[sizeof(struct eapol_frame)]; + struct eapol_frame *frame = (struct eapol_frame *) buf; + + l_timeout_remove(sm->eapol_start_timeout); + sm->eapol_start_timeout = NULL; + + frame->header.protocol_version = sm->protocol_version; + frame->header.packet_type = 1; + l_put_be16(0, &frame->header.packet_len); + + pae_write(sm->ifindex, sm->aa, sm->spa, frame); +} + static void eapol_handle_ptk_1_of_4(uint32_t ifindex, struct eapol_sm *sm, const struct eapol_key *ek) { @@ -1611,6 +1630,11 @@ void eapol_sm_set_8021x_config(struct eapol_sm *sm, struct l_settings *settings) eap_set_event_func(sm->eap, eapol_eap_event_cb); } +void eapol_sm_set_use_eapol_start(struct eapol_sm *sm, bool enabled) +{ + sm->use_eapol_start = enabled; +} + static void eapol_rx_packet(struct eapol_sm *sm, const uint8_t *frame, size_t len) { @@ -1638,6 +1662,9 @@ static void eapol_rx_packet(struct eapol_sm *sm, switch (eh->packet_type) { case 0: /* EAPOL-EAP */ + l_timeout_remove(sm->eapol_start_timeout); + sm->eapol_start_timeout = 0; + if (!sm->eap) { /* If we're not configured for EAP, send a NAK */ sm->eap = eap_new(eapol_eap_msg_cb, @@ -1742,6 +1769,15 @@ void eapol_start(uint32_t ifindex, struct eapol_sm *sm) sm->ifindex = ifindex; sm->timeout = l_timeout_create(2, eapol_timeout, sm, NULL); + if (sm->use_eapol_start) { + /* + * We start a short timeout, if EAP packets are not received + * from AP, then we send the EAPoL-Start + */ + sm->eapol_start_timeout = + l_timeout_create(1, send_eapol_start, sm, NULL); + } + l_queue_push_head(state_machines, sm); } diff --git a/src/eapol.h b/src/eapol.h index 425050a1..e5a50764 100644 --- a/src/eapol.h +++ b/src/eapol.h @@ -191,6 +191,7 @@ void eapol_sm_set_authenticator_address(struct eapol_sm *sm, const uint8_t *aa); void eapol_sm_set_pmk(struct eapol_sm *sm, const uint8_t *pmk); void eapol_sm_set_8021x_config(struct eapol_sm *sm, struct l_settings *settings); +void eapol_sm_set_use_eapol_start(struct eapol_sm *sm, bool enabled); void eapol_sm_set_ap_rsn(struct eapol_sm *sm, const uint8_t *rsn_ie, size_t len); bool eapol_sm_set_own_rsn(struct eapol_sm *sm, const uint8_t *rsn_ie,