Starting EAP sequence
Michel Verhagen
mike at guruce.com
Tue Mar 30 08:14:10 BST 2021
Now that I have everything building and now that I am using the
eapol_supp_sm state machine code, I'm back at my original question: How
do I get the EAPOL state machine to generate an EAPOL START packet?
The eapol_supp_sm code will do this when eapTriggerStart is set, but
this variable is not accessible from outside the eapol_supp_sm code. The
struct containing this variable is not publicly defined and I simply
can't set eapTriggerStart to 1 from my code (compiler error C2027: use
of undefined type 'eapol_sm').
I've tried calling eapol_sm_request_reauth, but the code there only
issues the EAPOL Start packet if sm->SUPP_PAE_state ==
SUPP_PAE_AUTHENTICATED, and of course when I am just starting the EAPOL
state machine, the port status is NOT authenticated.
I also tried calling eapol_sm_notify_portControl with ForceAuthorized,
but that sets m->SUPP_PAE_state to SUPP_PAE_S_FORCE_AUTH.
Surely there must be a way to get the EAPOL state machine to set
eapTriggerStart so that when running the state machine the code ends up
calling the send callback function with an EAPOL Start packet?
Any help would be much appreciated!
Regards,
Michel Verhagen
On 30/03/2021 17:53, Michel Verhagen wrote:
> Issue resolved; problem was missing call to eloop_init.
>
> Regards,
>
> Michel Verhagen
>
> On 30/03/2021 17:04, Michel Verhagen wrote:.
>> 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 at guruce.com> 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 at lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/hostap
>>
>>
>> _______________________________________________
>> Hostap mailing list
>> Hostap at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/hostap
>
>
>
> _______________________________________________
> Hostap mailing list
> Hostap at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/hostap
More information about the Hostap
mailing list