diff options
author | Michael Brown <mcb30@ipxe.org> | 2024-02-23 12:33:57 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2024-02-23 16:24:44 +0000 |
commit | 25ffcd79bfd38da96f9905b78e3d5c3cab33dad3 (patch) | |
tree | f19e4a09d18890608775e3acbefbe12ca1b6da77 | |
parent | 834f319f87bd2a1135c51375774f6bfe17a244cc (diff) | |
download | ipxe-25ffcd79bfd38da96f9905b78e3d5c3cab33dad3.tar.gz |
[eap] Allow MD5-Challenge authentication method to be disabled
RFC 3748 states that implementations must support the MD5-Challenge
method. However, some network environments may wish to disable it as
a matter of policy.
Allow support for MD5-Challenge to be controllable via the build
configuration option EAP_METHOD_MD5 in config/general.h.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/config/config_eap.c | 39 | ||||
-rw-r--r-- | src/config/general.h | 6 | ||||
-rw-r--r-- | src/include/ipxe/eap.h | 2 | ||||
-rw-r--r-- | src/include/ipxe/errfile.h | 1 | ||||
-rw-r--r-- | src/net/eap.c | 90 | ||||
-rw-r--r-- | src/net/eap_md5.c | 116 |
6 files changed, 172 insertions, 82 deletions
diff --git a/src/config/config_eap.c b/src/config/config_eap.c new file mode 100644 index 000000000..d3fd77aa2 --- /dev/null +++ b/src/config/config_eap.c @@ -0,0 +1,39 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <config/general.h> + +/** @file + * + * EAP configuration options + * + */ + +PROVIDE_REQUIRING_SYMBOL(); + +/* + * Drag in EAP authentication methods + */ +#ifdef EAP_METHOD_MD5 +REQUIRE_OBJECT ( eap_md5 ); +#endif diff --git a/src/config/general.h b/src/config/general.h index 6e8e86b2b..de009a878 100644 --- a/src/config/general.h +++ b/src/config/general.h @@ -92,6 +92,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define CRYPTO_80211_WPA2 /* Add support for stronger WPA cryptography */ /* + * 802.1x EAP authentication methods + * + */ +#define EAP_METHOD_MD5 /* MD5-Challenge port authentication */ + +/* * Name resolution modules * */ diff --git a/src/include/ipxe/eap.h b/src/include/ipxe/eap.h index cf1c7c00d..fe1bb5282 100644 --- a/src/include/ipxe/eap.h +++ b/src/include/ipxe/eap.h @@ -166,6 +166,8 @@ struct eap_method { /** Declare an EAP method */ #define __eap_method __table_entry ( EAP_METHODS, 01 ) +extern int eap_tx_response ( struct eap_supplicant *supplicant, + const void *rsp, size_t rsp_len ); extern int eap_rx ( struct eap_supplicant *supplicant, const void *data, size_t len ); diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h index f7a00dbe7..1768748d9 100644 --- a/src/include/ipxe/errfile.h +++ b/src/include/ipxe/errfile.h @@ -297,6 +297,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define ERRFILE_httpntlm ( ERRFILE_NET | 0x004a0000 ) #define ERRFILE_eap ( ERRFILE_NET | 0x004b0000 ) #define ERRFILE_lldp ( ERRFILE_NET | 0x004c0000 ) +#define ERRFILE_eap_md5 ( ERRFILE_NET | 0x004d0000 ) #define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 ) #define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 ) diff --git a/src/net/eap.c b/src/net/eap.c index 696b7fe99..87327d723 100644 --- a/src/net/eap.c +++ b/src/net/eap.c @@ -28,8 +28,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <string.h> #include <byteswap.h> #include <ipxe/netdevice.h> -#include <ipxe/md5.h> -#include <ipxe/chap.h> #include <ipxe/eap.h> /** @file @@ -46,8 +44,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * @v rsp_len Length of response type data * @ret rc Return status code */ -static int eap_tx_response ( struct eap_supplicant *supplicant, - const void *rsp, size_t rsp_len ) { +int eap_tx_response ( struct eap_supplicant *supplicant, + const void *rsp, size_t rsp_len ) { struct net_device *netdev = supplicant->netdev; struct eap_message *msg; size_t len; @@ -168,84 +166,6 @@ struct eap_method eap_identity_method __eap_method = { }; /** - * Handle EAP MD5-Challenge - * - * @v req Request type data - * @v req_len Length of request type data - * @ret rc Return status code - */ -static int eap_rx_md5 ( struct eap_supplicant *supplicant, - const void *req, size_t req_len ) { - struct net_device *netdev = supplicant->netdev; - const struct eap_md5 *md5req = req; - struct { - uint8_t len; - uint8_t value[MD5_DIGEST_SIZE]; - } __attribute__ (( packed )) md5rsp; - struct chap_response chap; - void *secret; - int secret_len; - int rc; - - /* Sanity checks */ - if ( req_len < sizeof ( *md5req ) ) { - DBGC ( netdev, "EAP %s underlength MD5-Challenge:\n", - netdev->name ); - DBGC_HDA ( netdev, 0, req, req_len ); - rc = -EINVAL; - goto err_sanity; - } - if ( ( req_len - sizeof ( *md5req ) ) < md5req->len ) { - DBGC ( netdev, "EAP %s truncated MD5-Challenge:\n", - netdev->name ); - DBGC_HDA ( netdev, 0, req, req_len ); - rc = -EINVAL; - goto err_sanity; - } - - /* Construct response */ - if ( ( rc = chap_init ( &chap, &md5_algorithm ) ) != 0 ) { - DBGC ( netdev, "EAP %s could not initialise CHAP: %s\n", - netdev->name, strerror ( rc ) ); - goto err_chap; - } - chap_set_identifier ( &chap, supplicant->id ); - secret_len = fetch_raw_setting_copy ( netdev_settings ( netdev ), - &password_setting, &secret ); - if ( secret_len < 0 ) { - rc = secret_len; - DBGC ( netdev, "EAP %s has no secret: %s\n", - netdev->name, strerror ( rc ) ); - goto err_secret; - } - chap_update ( &chap, secret, secret_len ); - chap_update ( &chap, md5req->value, md5req->len ); - chap_respond ( &chap ); - assert ( chap.response_len == sizeof ( md5rsp.value ) ); - md5rsp.len = sizeof ( md5rsp.value ); - memcpy ( md5rsp.value, chap.response, sizeof ( md5rsp.value ) ); - - /* Transmit response */ - if ( ( rc = eap_tx_response ( supplicant, &md5rsp, - sizeof ( md5rsp ) ) ) != 0 ) - goto err_tx; - - err_tx: - free ( secret ); - err_secret: - chap_finish ( &chap ); - err_chap: - err_sanity: - return rc; -} - -/** EAP MD5-Challenge method */ -struct eap_method eap_md5_method __eap_method = { - .type = EAP_TYPE_MD5, - .rx = eap_rx_md5, -}; - -/** * Handle EAP Request * * @v supplicant EAP supplicant @@ -370,3 +290,9 @@ int eap_rx ( struct eap_supplicant *supplicant, const void *data, return -ENOTSUP; } } + +/* Drag in objects via eap_rx() */ +REQUIRING_SYMBOL ( eap_rx ); + +/* Drag in EAP configuration */ +REQUIRE_OBJECT ( config_eap ); diff --git a/src/net/eap_md5.c b/src/net/eap_md5.c new file mode 100644 index 000000000..0664174f9 --- /dev/null +++ b/src/net/eap_md5.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <ipxe/md5.h> +#include <ipxe/chap.h> +#include <ipxe/eap.h> + +/** @file + * + * EAP MD5-Challenge authentication method + * + */ + +/** + * Handle EAP MD5-Challenge + * + * @v supplicant EAP supplicant + * @v req Request type data + * @v req_len Length of request type data + * @ret rc Return status code + */ +static int eap_rx_md5 ( struct eap_supplicant *supplicant, + const void *req, size_t req_len ) { + struct net_device *netdev = supplicant->netdev; + const struct eap_md5 *md5req = req; + struct { + uint8_t len; + uint8_t value[MD5_DIGEST_SIZE]; + } __attribute__ (( packed )) md5rsp; + struct chap_response chap; + void *secret; + int secret_len; + int rc; + + /* Sanity checks */ + if ( req_len < sizeof ( *md5req ) ) { + DBGC ( netdev, "EAP %s underlength MD5-Challenge:\n", + netdev->name ); + DBGC_HDA ( netdev, 0, req, req_len ); + rc = -EINVAL; + goto err_sanity; + } + if ( ( req_len - sizeof ( *md5req ) ) < md5req->len ) { + DBGC ( netdev, "EAP %s truncated MD5-Challenge:\n", + netdev->name ); + DBGC_HDA ( netdev, 0, req, req_len ); + rc = -EINVAL; + goto err_sanity; + } + + /* Construct response */ + if ( ( rc = chap_init ( &chap, &md5_algorithm ) ) != 0 ) { + DBGC ( netdev, "EAP %s could not initialise CHAP: %s\n", + netdev->name, strerror ( rc ) ); + goto err_chap; + } + chap_set_identifier ( &chap, supplicant->id ); + secret_len = fetch_raw_setting_copy ( netdev_settings ( netdev ), + &password_setting, &secret ); + if ( secret_len < 0 ) { + rc = secret_len; + DBGC ( netdev, "EAP %s has no secret: %s\n", + netdev->name, strerror ( rc ) ); + goto err_secret; + } + chap_update ( &chap, secret, secret_len ); + chap_update ( &chap, md5req->value, md5req->len ); + chap_respond ( &chap ); + assert ( chap.response_len == sizeof ( md5rsp.value ) ); + md5rsp.len = sizeof ( md5rsp.value ); + memcpy ( md5rsp.value, chap.response, sizeof ( md5rsp.value ) ); + + /* Transmit response */ + if ( ( rc = eap_tx_response ( supplicant, &md5rsp, + sizeof ( md5rsp ) ) ) != 0 ) + goto err_tx; + + err_tx: + free ( secret ); + err_secret: + chap_finish ( &chap ); + err_chap: + err_sanity: + return rc; +} + +/** EAP MD5-Challenge method */ +struct eap_method eap_md5_method __eap_method = { + .type = EAP_TYPE_MD5, + .rx = eap_rx_md5, +}; |