From: Alan T. DeKok Date: Thu, 23 Nov 2023 16:36:29 +0000 (-0500) Subject: add dedup_key for badly behaving supplicants X-Git-Tag: release_3_2_4~115 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3a9cc7eaf366a726285d2bf61923f508dff6c1fa;p=thirdparty%2Ffreeradius-server.git add dedup_key for badly behaving supplicants --- diff --git a/src/modules/rlm_eap/eap.c b/src/modules/rlm_eap/eap.c index b355d8c256..8767c9fc0b 100644 --- a/src/modules/rlm_eap/eap.c +++ b/src/modules/rlm_eap/eap.c @@ -1216,7 +1216,7 @@ eap_handler_t *eap_handler(rlm_eap_t *inst, eap_packet_raw_t **eap_packet_p, } } } else { /* packet was EAP identity */ - handler = eap_handler_alloc(inst); + handler = eap_handler_alloc(inst, request); if (!handler) { goto error; } diff --git a/src/modules/rlm_eap/eap.h b/src/modules/rlm_eap/eap.h index 849d1c6d68..0724463d0a 100644 --- a/src/modules/rlm_eap/eap.h +++ b/src/modules/rlm_eap/eap.h @@ -60,7 +60,6 @@ typedef enum operation_t { PROCESS } operation_t; - /* * eap_handler_t is the interface for any EAP-Type. * Each handler contains information for one specific EAP-Type. @@ -105,6 +104,8 @@ typedef struct _eap_handler { char const *identity; //!< User name from EAP-Identity + char const *dedup; //!< dedup key + EAP_DS *prev_eapds; EAP_DS *eap_ds; diff --git a/src/modules/rlm_eap/mem.c b/src/modules/rlm_eap/mem.c index 270721bc72..6ef6c5c0c4 100644 --- a/src/modules/rlm_eap/mem.c +++ b/src/modules/rlm_eap/mem.c @@ -119,9 +119,10 @@ static int _eap_handler_free(eap_handler_t *handler) /* * Allocate a new eap_handler_t */ -eap_handler_t *eap_handler_alloc(rlm_eap_t *inst) +eap_handler_t *eap_handler_alloc(rlm_eap_t *inst, REQUEST *request) { - eap_handler_t *handler; + eap_handler_t *handler, *old; + char buffer[256]; handler = talloc_zero(NULL, eap_handler_t); if (!handler) { @@ -133,6 +134,20 @@ eap_handler_t *eap_handler_alloc(rlm_eap_t *inst) /* Doesn't need to be inside the critical region */ talloc_set_destructor(handler, _eap_handler_free); + if (!inst->dedup_tree) return handler; + + if (radius_xlat(buffer, sizeof(buffer), request, inst->dedup_key, NULL, NULL) < 0) return handler; + + handler->dedup = talloc_strdup(handler, buffer); + + /* + * Delete any old handler + */ + PTHREAD_MUTEX_LOCK(&(inst->session_mutex)); + old = rbtree_finddata(inst->dedup_tree, handler); + if (old) talloc_free(old); + PTHREAD_MUTEX_LOCK(&(inst->session_mutex)); + return handler; } @@ -171,6 +186,8 @@ static eap_handler_t *eaplist_delete(rlm_eap_t *inst, REQUEST *request, { rbnode_t *node; + if (inst->dedup_tree) (void) rbtree_deletebydata(inst->dedup_tree, handler); + node = rbtree_find(inst->session_tree, handler); if (!node) return NULL; @@ -182,6 +199,7 @@ static eap_handler_t *eaplist_delete(rlm_eap_t *inst, REQUEST *request, handler->state[2], handler->state[3], handler->state[4], handler->state[5], handler->state[6], handler->state[7]); + /* * Delete old handler from the tree. */ diff --git a/src/modules/rlm_eap/rlm_eap.c b/src/modules/rlm_eap/rlm_eap.c index fbd75e9dba..5df527e4a1 100644 --- a/src/modules/rlm_eap/rlm_eap.c +++ b/src/modules/rlm_eap/rlm_eap.c @@ -40,6 +40,7 @@ static const CONF_PARSER module_config[] = { { "cisco_accounting_username_bug", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_eap_t, mod_accounting_username_bug), "no" }, { "allow_empty_identities", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_eap_t, allow_empty_identities), NULL }, { "max_sessions", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_eap_t, max_sessions), "2048" }, + { "dedup_key", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_eap_t, dedup_key), "" }, CONF_PARSER_TERMINATOR }; @@ -99,6 +100,21 @@ static int eap_handler_cmp(void const *a, void const *b) return 0; } +/* + * Compare two handlers by dedup keu + */ +static int dedup_cmp(void const *a, void const *b) +{ + eap_handler_t const *one = a; + eap_handler_t const *two = b; + + if (!one->dedup && two->dedup) return -1; + if (one->dedup && !two->dedup) return +1; + + if (!one->dedup && two->dedup) return 0; + + return strcmp(one->dedup, two->dedup); +} /* * read the config section and load all the eap authentication types present. @@ -257,6 +273,16 @@ static int mod_instantiate(CONF_SECTION *cs, void *instance) } #endif + if (!inst->dedup_key || !*inst->dedup_key) { + return 0; + } + + inst->dedup_tree = rbtree_create(NULL, dedup_cmp, NULL, 0); + if (!inst->dedup_tree) { + ERROR("rlm_eap (%s): Cannot initialize dedup tree", inst->xlat_name); + return -1; + } + return 0; } diff --git a/src/modules/rlm_eap/rlm_eap.h b/src/modules/rlm_eap/rlm_eap.h index 930b763b6a..4d5e1fa269 100644 --- a/src/modules/rlm_eap/rlm_eap.h +++ b/src/modules/rlm_eap/rlm_eap.h @@ -67,11 +67,15 @@ typedef struct rlm_eap { uint32_t max_sessions; + char const *dedup_key; + #ifdef HAVE_PTHREAD_H pthread_mutex_t session_mutex; pthread_mutex_t handler_mutex; #endif + rbtree_t *dedup_tree; + char const *xlat_name; /* no xlat's yet */ fr_randctx rand_pool; } rlm_eap_t; @@ -103,7 +107,7 @@ eap_handler_t *eap_handler(rlm_eap_t *inst, eap_packet_raw_t **eap_msg, REQUEST /* Memory Management */ EAP_DS *eap_ds_alloc(eap_handler_t *handler); -eap_handler_t *eap_handler_alloc(rlm_eap_t *inst); +eap_handler_t *eap_handler_alloc(rlm_eap_t *inst, REQUEST *request); void eap_ds_free(EAP_DS **eap_ds); int eaplist_add(rlm_eap_t *inst, eap_handler_t *handler) CC_HINT(nonnull); eap_handler_t *eaplist_find(rlm_eap_t *inst, REQUEST *request, eap_packet_raw_t *eap_packet);