We are running into an issue where calling eapol_sm_init results in a
write to a null pointer in dl_list_add:
static inline void dl_list_add(struct dl_list *list, struct dl_list
*item)
{
item->next = list->next;
item->prev = list;
list->next->prev = item;
list->next = item;
}
item->next is null in the above when called from function
eloop_register_timeout through macro dl_list_for_each in line 273:
/* Maintain timeouts in order of increasing time */
dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout,
list) {
if (os_reltime_before(&timeout->time, &tmp->time)) {
dl_list_add(tmp->list.prev, &timeout->list);
return 0;
}
}
#define dl_list_for_each(item, list, type, member) \
for (item = dl_list_entry((list)->next, type, member); \
&item->member != (list); \
item = dl_list_entry(item->member.next, type, member))
So, the code is:
for (tmp = dl_list_entry((&loop.timeout)->next, struct
eloop_timeout, list); \
&tmp->list != (&loop.timeout); \
tmp = dl_list_entry(tmp->list.next, struct eloop_timeout,
list))
And eloop.timeout.next is NULL.
We are implementing EAPOL authentication using the hostap eap library
and eapol state machine code. We only need EAPOL over wired LAN, so
no WPA or WPS needed. Our initialization looks like this:
if (ERROR_SUCCESS != EAPRegisterMethods())
break;
os_memset(&_eap_ctx, 0, sizeof(_eap_ctx));
_eap_ctx.eap_config.identity = (u8 *)os_strdup("Identity");
_eap_ctx.eap_config.identity_len = strlen((const
char*)_eap_ctx.eap_config.identity);
_eap_ctx.eap_config.password = (u8 *)os_strdup("password");
_eap_ctx.eap_config.password_len = strlen((const
char*)_eap_ctx.eap_config.password);
_eap_ctx.eap_config.ca_cert =
os_strdup("\\Windows\\ca.pem");
//_eap_ctx.eap_config.ca_path = os_strdup("\\Windows");
_eap_ctx.eap_config.fragment_size = 1398;
os_memset(&_eap_cb, 0, sizeof(_eap_cb));
_eap_cb.get_config = peer_get_config;
_eap_cb.get_bool = (Boolean(__cdecl *)(void *,
eapol_bool_var))peer_get_bool;
_eap_cb.set_bool = (void(__cdecl *)(void *, eapol_bool_var,
Boolean))peer_set_bool;
_eap_cb.get_int = peer_get_int;
_eap_cb.set_int = peer_set_int;
_eap_cb.get_eapReqData = peer_get_eapReqData;
_eap_cb.set_config_blob = peer_set_config_blob;
_eap_cb.get_config_blob = peer_get_config_blob;
_eap_cb.notify_pending = peer_notify_pending;
os_memset(&_eap_conf, 0, sizeof(_eap_conf));
_eap_ctx.eap = eap_peer_sm_init(&_eap_ctx, &_eap_cb,
&_eap_ctx, &_eap_conf);
if (_eap_ctx.eap == NULL)
break;
/* Enable "port" to allow authentication */
_eap_ctx.portEnabled = true;
os_memset(&_eapol_ctx, 0, sizeof(_eapol_ctx));
_eapol_ctx.ctx = this; // This can be
pointing to any structure we define as context
_eapol_ctx.preauth = 0; // Not using IEEE
802.11i/RSN pre-authentication
_eapol_ctx.cb = NULL; // Not using IEEE
802.11i/RSN pre-authentication, so no need for this callback
_eapol_ctx.cb_ctx = NULL; // Not using IEEE
802.11i/RSN pre-authentication, so no need for context
_eapol_ctx.msg_ctx = this; // Callback context
for wpa_msg() calls
_eapol_ctx.scard_ctx = NULL; // Callback context
for PC/SC scard_*() function calls
_eapol_ctx.eapol_send_ctx = this; // Callback context
for eapol_send() calls
_eapol_ctx.eapol_done_cb = eapol_done_cb;
_eapol_ctx.eapol_send = eapol_send;
_eapol_ctx.set_wep_key = NULL; // Not using WEP
_eapol_ctx.set_config_blob = NULL;
_eapol_ctx.get_config_blob = NULL;
_eapol_ctx.aborted_cached = NULL;
_eapol_ctx.opensc_engine_path = NULL; // No idea what to
set here
_eapol_ctx.pkcs11_engine_path = NULL; // No idea what to
set here
_eapol_ctx.pkcs11_module_path = NULL; // No idea what to
set here
_eapol_ctx.openssl_ciphers = NULL; // No idea what to
set here
_eapol_ctx.wps = NULL; // Not using WPS
_eapol_ctx.eap_param_needed = NULL; // Not using WEP
_eapol_ctx.port_cb = port_cb;
_eapol_ctx.cert_cb = cert_cb;
_eapol_ctx.cert_in_cb = 1;
_eapol_ctx.status_cb = status_cb;
_eapol_ctx.eap_error_cb = eap_error_cb;
_eapol_ctx.set_anon_id = NULL; // Not sure this is
needed
_eapol_ctx.confirm_auth_cb = NULL; // Not sure this is
needed
_peapol_sm = eapol_sm_init(&_eapol_ctx);
if (!_peapol_sm)
break;
os_memset(&_eapol_conf, 0, sizeof(_eapol_conf));
_eapol_conf.accept_802_1x_keys = 0;
_eapol_conf.required_keys = 0; //
EAPOL_REQUIRE_KEY_UNICAST | EAPOL_REQUIRE_KEY_BROADCAST
_eapol_conf.fast_reauth = 1;
_eapol_conf.workaround = 0;
_eapol_conf.eap_disabled = 0;
_eapol_conf.external_sim = 0;
_eapol_conf.wps = 0;
eapol_sm_notify_config(_peapol_sm, &_eap_ctx.eap_config,
&_eapol_conf);
eapol_sm_notify_portValid(_peapol_sm, false);
eapol_sm_notify_portEnabled(_peapol_sm, true);
As you can see, not everything is clear so I'm probably just missing
something. In the above code we don't get past the call to
eapol_sm_init. Hope somebody can shed some light or point me in the
right direction...
Many thanks in advance!
Regards,
Michel Verhagen
On 12/03/2021 10:10, Michel Verhagen wrote:
Thanks Alan!
That does make sense indeed. I'll try to use eapol_supp for better
handling of the EAPOL layer on top of EAP. I hope this code can be
used with just the code I ported for the EAP library to compile.
Is there any documentation explaining what all the context
parameters do (see test_eapol function in eapol_test.c), which are
required and for which functionality etc? All I need is to implement
an EAPOL client with certificates, so no WPA/WEP or any of the
wireless stuff.
I'll come back with more questions probably, thanks for pointing me
in the right direction!
On 12/03/2021 01:23, Alan DeKok wrote:
On Mar 10, 2021, at 11:56 PM, Michel Verhagen <mike@xxxxxxxxxx> wrote:
I'm using the EAP library to implement EAPOL on an embedded
device. Got it to go, with EAP-MD5 and EAP-TTLS and certificates,
so all good. However, I'm trying to get the library to prepare me
an EAPOL START packet. I'd like to initiate the start of the EAP
handshake, because depending on the settings of the authenticator,
it can take a long time before the EAP handshake sequence is
initiated.
I haven't used the library myself, but the problem, here is
likely layering.
i.e. you're using an EAP library. EAP runs on EAPoL, PPP, PANA,
RADIUS, Diameter, ..., where the library just does EAP.
EAPoL is managed by the IEEE 802.1X state machine. Which uses
EAP, but isn't part of the EAP library.
I thought setting _eap_ctx.eapRestart to 1 (true) or even
eapTriggerStart to 1 and calling eap_peer_step would get me the
packet data to send, but I can't see eapTriggerStart used anywhere
in the code.
See src/eapol_supp/eapol_supp_sm.c, which runs the EAPoL
supplicant state machine. It checks eapTriggerStart, and ends up
calling eapol_sm_txStart().
Does anybody know how to get the EAP library to prepare an EAP
Start packet?
You can't. EAP isn't the same as the Ethernet layer EAPoL state
machine.
I can of course prepare and send that packet myself, but it looks
like the EAP library should be able to do this as well...
No. The EAP library does EAP. The 802.1X / supplicant state
machine does Ethernet, and EAPoL.
Alan DeKok.
_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap
_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap