summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2024-02-23 13:33:57 +0100
committerMichael Brown2024-02-23 17:24:44 +0100
commit25ffcd79bfd38da96f9905b78e3d5c3cab33dad3 (patch)
treef19e4a09d18890608775e3acbefbe12ca1b6da77
parent[eap] Add progress debug messages (diff)
downloadipxe-25ffcd79bfd38da96f9905b78e3d5c3cab33dad3.tar.gz
ipxe-25ffcd79bfd38da96f9905b78e3d5c3cab33dad3.tar.xz
ipxe-25ffcd79bfd38da96f9905b78e3d5c3cab33dad3.zip
[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.c39
-rw-r--r--src/config/general.h6
-rw-r--r--src/include/ipxe/eap.h2
-rw-r--r--src/include/ipxe/errfile.h1
-rw-r--r--src/net/eap.c90
-rw-r--r--src/net/eap_md5.c116
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 00000000..d3fd77aa
--- /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 6e8e86b2..de009a87 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 cf1c7c00..fe1bb528 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 f7a00dbe..1768748d 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 696b7fe9..87327d72 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 00000000..0664174f
--- /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,
+};