mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-26 02:19:26 +01:00
eapol: Add eapol_frame_watch_add / remove
Allow other files to receive EAPoL frames on specified interfaces.
This commit is contained in:
parent
509324666c
commit
f05c3c30d1
@ -113,6 +113,7 @@ monitor_iwmon_SOURCES = monitor/main.c linux/nl80211.h \
|
|||||||
src/mpdu.h src/mpdu.c \
|
src/mpdu.h src/mpdu.c \
|
||||||
src/util.h src/util.c \
|
src/util.h src/util.c \
|
||||||
src/crypto.h src/crypto.c \
|
src/crypto.h src/crypto.c \
|
||||||
|
src/watchlist.h src/watchlist.c \
|
||||||
src/eapol.h src/eapol.c \
|
src/eapol.h src/eapol.c \
|
||||||
src/handshake.h src/handshake.c \
|
src/handshake.h src/handshake.c \
|
||||||
src/eap.h src/eap.c \
|
src/eap.h src/eap.c \
|
||||||
@ -150,6 +151,7 @@ endif
|
|||||||
unit_test_eap_sim_SOURCES = unit/test-eap-sim.c \
|
unit_test_eap_sim_SOURCES = unit/test-eap-sim.c \
|
||||||
src/crypto.h src/crypto.c src/simutil.h src/simutil.c \
|
src/crypto.h src/crypto.c src/simutil.h src/simutil.c \
|
||||||
src/ie.h src/ie.c \
|
src/ie.h src/ie.c \
|
||||||
|
src/watchlist.h src/watchlist.c \
|
||||||
src/eapol.h src/eapol.c \
|
src/eapol.h src/eapol.c \
|
||||||
src/handshake.h src/handshake.c \
|
src/handshake.h src/handshake.c \
|
||||||
src/eap.h src/eap.c \
|
src/eap.h src/eap.c \
|
||||||
@ -205,6 +207,7 @@ unit_test_mpdu_LDADD = ell/libell-internal.la
|
|||||||
unit_test_eapol_SOURCES = unit/test-eapol.c \
|
unit_test_eapol_SOURCES = unit/test-eapol.c \
|
||||||
src/crypto.h src/crypto.c \
|
src/crypto.h src/crypto.c \
|
||||||
src/ie.h src/ie.c \
|
src/ie.h src/ie.c \
|
||||||
|
src/watchlist.h src/watchlist.c \
|
||||||
src/eapol.h src/eapol.c \
|
src/eapol.h src/eapol.c \
|
||||||
src/handshake.h src/handshake.c \
|
src/handshake.h src/handshake.c \
|
||||||
src/eap.h src/eap.c \
|
src/eap.h src/eap.c \
|
||||||
@ -223,6 +226,7 @@ unit_test_ssid_security_LDADD = ell/libell-internal.la
|
|||||||
unit_test_wsc_SOURCES = unit/test-wsc.c src/wscutil.h src/wscutil.c \
|
unit_test_wsc_SOURCES = unit/test-wsc.c src/wscutil.h src/wscutil.c \
|
||||||
src/crypto.h src/crypto.c \
|
src/crypto.h src/crypto.c \
|
||||||
src/ie.h src/ie.c \
|
src/ie.h src/ie.c \
|
||||||
|
src/watchlist.h src/watchlist.c \
|
||||||
src/eapol.h src/eapol.c \
|
src/eapol.h src/eapol.c \
|
||||||
src/handshake.h src/handshake.c \
|
src/handshake.h src/handshake.c \
|
||||||
src/eap.h src/eap.c \
|
src/eap.h src/eap.c \
|
||||||
|
62
src/eapol.c
62
src/eapol.c
@ -42,9 +42,11 @@
|
|||||||
#include "mpdu.h"
|
#include "mpdu.h"
|
||||||
#include "eap.h"
|
#include "eap.h"
|
||||||
#include "handshake.h"
|
#include "handshake.h"
|
||||||
|
#include "watchlist.h"
|
||||||
|
|
||||||
struct l_queue *state_machines;
|
struct l_queue *state_machines;
|
||||||
struct l_queue *preauths;
|
struct l_queue *preauths;
|
||||||
|
struct watchlist frame_watches;
|
||||||
|
|
||||||
eapol_deauthenticate_func_t deauthenticate = NULL;
|
eapol_deauthenticate_func_t deauthenticate = NULL;
|
||||||
eapol_rekey_offload_func_t rekey_offload = NULL;
|
eapol_rekey_offload_func_t rekey_offload = NULL;
|
||||||
@ -53,6 +55,8 @@ static struct l_io *pae_io;
|
|||||||
eapol_tx_packet_func_t tx_packet = NULL;
|
eapol_tx_packet_func_t tx_packet = NULL;
|
||||||
void *tx_user_data;
|
void *tx_user_data;
|
||||||
|
|
||||||
|
uint32_t next_frame_watch_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BPF filter to match skb->dev->type == 1 (ARPHRD_ETHER) and
|
* BPF filter to match skb->dev->type == 1 (ARPHRD_ETHER) and
|
||||||
* match skb->protocol == 0x888e (PAE) or 0x88c7 (preauthentication).
|
* match skb->protocol == 0x888e (PAE) or 0x88c7 (preauthentication).
|
||||||
@ -1747,6 +1751,41 @@ eap_error:
|
|||||||
(int) sm->handshake->ifindex);
|
(int) sm->handshake->ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct eapol_frame_watch {
|
||||||
|
uint32_t ifindex;
|
||||||
|
struct watchlist_item super;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void eapol_frame_watch_free(struct watchlist_item *item)
|
||||||
|
{
|
||||||
|
struct eapol_frame_watch *efw =
|
||||||
|
container_of(item, struct eapol_frame_watch, super);
|
||||||
|
|
||||||
|
l_free(efw);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct watchlist_ops eapol_frame_watch_ops = {
|
||||||
|
.item_free = eapol_frame_watch_free,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t eapol_frame_watch_add(uint32_t ifindex,
|
||||||
|
eapol_frame_watch_func_t handler,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
struct eapol_frame_watch *efw;
|
||||||
|
|
||||||
|
efw = l_new(struct eapol_frame_watch, 1);
|
||||||
|
efw->ifindex = ifindex;
|
||||||
|
|
||||||
|
return watchlist_link(&frame_watches, &efw->super,
|
||||||
|
handler, user_data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool eapol_frame_watch_remove(uint32_t id)
|
||||||
|
{
|
||||||
|
return watchlist_remove(&frame_watches, id);
|
||||||
|
}
|
||||||
|
|
||||||
struct preauth_sm {
|
struct preauth_sm {
|
||||||
uint32_t ifindex;
|
uint32_t ifindex;
|
||||||
uint8_t aa[6];
|
uint8_t aa[6];
|
||||||
@ -1962,7 +2001,15 @@ void eapol_preauth_cancel(uint32_t ifindex)
|
|||||||
L_UINT_TO_PTR(ifindex));
|
L_UINT_TO_PTR(ifindex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void __eapol_rx_packet(uint32_t ifindex, const uint8_t *aa, uint16_t proto,
|
static bool eapol_frame_watch_match_ifindex(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
struct eapol_frame_watch *efw =
|
||||||
|
container_of(a, struct eapol_frame_watch, super);
|
||||||
|
|
||||||
|
return efw->ifindex == L_PTR_TO_UINT(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __eapol_rx_packet(uint32_t ifindex, const uint8_t *src, uint16_t proto,
|
||||||
const uint8_t *frame, size_t len)
|
const uint8_t *frame, size_t len)
|
||||||
{
|
{
|
||||||
const struct eapol_header *eh;
|
const struct eapol_header *eh;
|
||||||
@ -1984,15 +2031,21 @@ void __eapol_rx_packet(uint32_t ifindex, const uint8_t *aa, uint16_t proto,
|
|||||||
if (len < (size_t) 4 + L_BE16_TO_CPU(eh->packet_len))
|
if (len < (size_t) 4 + L_BE16_TO_CPU(eh->packet_len))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
WATCHLIST_NOTIFY_MATCHES(&frame_watches,
|
||||||
|
eapol_frame_watch_match_ifindex,
|
||||||
|
L_UINT_TO_PTR(ifindex),
|
||||||
|
eapol_frame_watch_func_t, proto, src,
|
||||||
|
(const struct eapol_frame *) eh);
|
||||||
|
|
||||||
if (proto == ETH_P_PAE) {
|
if (proto == ETH_P_PAE) {
|
||||||
struct eapol_sm *sm = eapol_find_sm(ifindex, aa);
|
struct eapol_sm *sm = eapol_find_sm(ifindex, src);
|
||||||
|
|
||||||
if (!sm)
|
if (!sm)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
eapol_rx_packet(sm, frame, len);
|
eapol_rx_packet(sm, frame, len);
|
||||||
} else if (proto == 0x88c7) {
|
} else if (proto == 0x88c7) {
|
||||||
struct preauth_sm *sm = preauth_find_sm(ifindex, aa);
|
struct preauth_sm *sm = preauth_find_sm(ifindex, src);
|
||||||
|
|
||||||
if (!sm)
|
if (!sm)
|
||||||
return;
|
return;
|
||||||
@ -2005,6 +2058,7 @@ bool eapol_init()
|
|||||||
{
|
{
|
||||||
state_machines = l_queue_new();
|
state_machines = l_queue_new();
|
||||||
preauths = l_queue_new();
|
preauths = l_queue_new();
|
||||||
|
watchlist_init(&frame_watches, &eapol_frame_watch_ops);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2021,5 +2075,7 @@ bool eapol_exit()
|
|||||||
|
|
||||||
l_queue_destroy(preauths, preauth_sm_destroy);
|
l_queue_destroy(preauths, preauth_sm_destroy);
|
||||||
|
|
||||||
|
watchlist_destroy(&frame_watches);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,9 @@ typedef void (*eapol_deauthenticate_func_t)(uint32_t ifindex, const uint8_t *aa,
|
|||||||
void *user_data);
|
void *user_data);
|
||||||
typedef void (*eapol_preauth_cb_t)(const uint8_t *pmk, void *user_data);
|
typedef void (*eapol_preauth_cb_t)(const uint8_t *pmk, void *user_data);
|
||||||
typedef void (*eapol_preauth_destroy_func_t)(void *user_data);
|
typedef void (*eapol_preauth_destroy_func_t)(void *user_data);
|
||||||
|
typedef void (*eapol_frame_watch_func_t)(uint16_t proto, const uint8_t *from,
|
||||||
|
const struct eapol_frame *frame,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
bool eapol_calculate_mic(const uint8_t *kck, const struct eapol_key *frame,
|
bool eapol_calculate_mic(const uint8_t *kck, const struct eapol_key *frame,
|
||||||
uint8_t *mic);
|
uint8_t *mic);
|
||||||
@ -190,6 +193,11 @@ void eapol_sm_set_event_func(struct eapol_sm *sm, eapol_sm_event_func_t func);
|
|||||||
void eapol_register(struct eapol_sm *sm);
|
void eapol_register(struct eapol_sm *sm);
|
||||||
void eapol_start(struct eapol_sm *sm);
|
void eapol_start(struct eapol_sm *sm);
|
||||||
|
|
||||||
|
uint32_t eapol_frame_watch_add(uint32_t ifindex,
|
||||||
|
eapol_frame_watch_func_t handler,
|
||||||
|
void *user_data);
|
||||||
|
bool eapol_frame_watch_remove(uint32_t id);
|
||||||
|
|
||||||
struct preauth_sm *eapol_preauth_start(const uint8_t *aa,
|
struct preauth_sm *eapol_preauth_start(const uint8_t *aa,
|
||||||
const struct handshake_state *hs,
|
const struct handshake_state *hs,
|
||||||
eapol_preauth_cb_t cb, void *user_data,
|
eapol_preauth_cb_t cb, void *user_data,
|
||||||
|
Loading…
Reference in New Issue
Block a user