Replace the usage of eap_send_response() in the method implementations
with a new eap_method_respond that skips the redundant "type" parameter.
The new eap_send_packet is used inside eap_method_respond and will be
reused for sending request packets in authenticator side EAP methods.
Replace existing uses of memset to clear secrets with explicit_bzero to
make sure it doesn't get optimized away. This has some side effects as
documented in gcc docs but is still recommended.
In eap_secret_info_free make sure we clear both strings in the case of
EAP_SECRET_REMOTE_USER_PASSWORD secrets.
A method's .check_settings method checks for inconsistent setting files
and prints readable errors so there's no need to do that again in
.load_settings, although at some point after removing the duplicate
error messages from the load_settings methods we agreed to keep minimum
checks that could cause a crash e.g. in a corner case like when the
setting file got modified between the check_settings and the
load_settings call. Some error messages have been re-added to
load_settings after that (e.g. in
bb4e1ebd4f) but they're incomplete and not
useful so remove them.
eap_append_secret now takes a new cache_policy parameter which can be
used by the EAP method to signal that the value received from the agent
is to never be cached, i.e. each value can only be used once. The
parameter value should be EAP_CACHE_NEVER for this and we use this in
value EAP-GTC where the secret tokens are one time use. The
EAP_CACHE_TEMPORARY value is used in other methods, it preserves the
default behaviour where a secret can be cached for as long as the
network stays in range (this is the current implementation more than a
design choice I believe, I didn't go for a more specific enum name as
this may still change I suppose).
When the response structure is generated, not all of the memory was
initialized to 0.
==1045== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
==1045== at 0x5134D52: send (in /lib64/libc-2.25.so)
==1045== by 0x168AB5: l_checksum_update (checksum.c:338)
==1045== by 0x186777: tls_write_mac (tls-record.c:58)
==1045== by 0x1869D1: tls_tx_record_plaintext (tls-record.c:120)
==1045== by 0x186DEA: tls_tx_record (tls-record.c:201)
==1045== by 0x185A3B: l_tls_write (tls.c:2064)
==1045== by 0x14584F: eap_ttls_eap_tx_packet (eap-ttls.c:321)
==1045== by 0x14236C: eap_send_response (eap.c:165)
==1045== by 0x147904: eap_mschapv2_send_response (eap-mschapv2.c:468)
==1045== by 0x147A10: eap_mschapv2_handle_challenge (eap-mschapv2.c:492)
==1045== by 0x147E9A: eap_mschapv2_handle_request (eap-mschapv2.c:615)
==1045== by 0x142693: __eap_handle_request (eap.c:240)
==1045== Address 0x1ffeffe7f9 is on thread 1's stack
==1045== in frame #4, created by tls_tx_record (tls-record.c:177)
==1045== Uninitialised value was created by a stack allocation
==1045== at 0x1477AE: eap_mschapv2_send_response (eap-mschapv2.c:443)
==1045==
==1045== Syscall param sendmsg(msg.msg_iov[0]) points to uninitialised byte(s)
==1045== at 0x5134E3B: sendmsg (in /lib64/libc-2.25.so)
==1045== by 0x17F691: operate_cipher (cipher.c:356)
==1045== by 0x17F9D8: l_cipher_encrypt (cipher.c:446)
==1045== by 0x186BAA: tls_tx_record_plaintext (tls-record.c:152)
==1045== by 0x186DEA: tls_tx_record (tls-record.c:201)
==1045== by 0x185A3B: l_tls_write (tls.c:2064)
==1045== by 0x14584F: eap_ttls_eap_tx_packet (eap-ttls.c:321)
==1045== by 0x14236C: eap_send_response (eap.c:165)
==1045== by 0x147904: eap_mschapv2_send_response (eap-mschapv2.c:468)
==1045== by 0x147A10: eap_mschapv2_handle_challenge (eap-mschapv2.c:492)
==1045== by 0x147E9A: eap_mschapv2_handle_request (eap-mschapv2.c:615)
==1045== by 0x142693: __eap_handle_request (eap.c:240)
==1045== Address 0x1ffeffe7f9 is on thread 1's stack
==1045== in frame #4, created by tls_tx_record (tls-record.c:177)
==1045== Uninitialised value was created by a stack allocation
==1045== at 0x1477AE: eap_mschapv2_send_response (eap-mschapv2.c:443)
==1045==
Replace usages of l_settings_get_value with l_settings_get_string, which
will make sure the returned strings are unescaped but also allocates
memeory and forces us to use l_free on most of the strings. Some of
these strings we explicitly set with l_settings_set_string() in our code
so when we retrieved them with l_settings_get_value() we would receive a
different string if there were any escapable characters in the string.
I didn't replace any of the l_settings_get_value() uses where we're just
checking whether a setting is present, or those which are hexstrings or
EAP method names assuming that they can't have any special characters,
although this isn't future proof. I did use l_settings_get_string() for
file paths though.
Accept two setting IDs in eap_append_secret, first for the username and
second for the password in case of the EAP_SECRET_REMOTE_USER_PASSWORD
EAP secret type. In all other cases only the first setting is used.
Until now for EAP_SECRET_REMOTE_USER_PASSWORD secrets we'd generate the
two setting names by adding different suffixes to the ID parameter.
Using the two different setting names automatically fixes the issues
with using the EAP Identity returned by the agent in EAP-MSCHAPv2 and
EAP-PWD.
The EAP-method's .probe methods only checked the method name so do that
in eap.c instead and allocate method state in .load_settings. Rename
method's .remove method to .free to improve the naming.
Make sure that eap_set_key_material can free the whole EAP method and
EAP state machine before returning, by calling that function last. This
relies on eap_mschapv2_handle_success being the last call in about 5
stack frames above it too.