summaryrefslogtreecommitdiffstats
path: root/src/modules/rlm_eap/rlm_eap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/rlm_eap/rlm_eap.c')
-rw-r--r--src/modules/rlm_eap/rlm_eap.c62
1 files changed, 43 insertions, 19 deletions
diff --git a/src/modules/rlm_eap/rlm_eap.c b/src/modules/rlm_eap/rlm_eap.c
index efb9660..18eb1c4 100644
--- a/src/modules/rlm_eap/rlm_eap.c
+++ b/src/modules/rlm_eap/rlm_eap.c
@@ -38,7 +38,9 @@ static const CONF_PARSER module_config[] = {
{ "max_eap_type", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_eap_t, max_eap_type), "52" },
{ "ignore_unknown_eap_types", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_eap_t, ignore_unknown_types), "no" },
{ "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
};
@@ -98,6 +100,21 @@ static int eap_handler_cmp(void const *a, void const *b)
return 0;
}
+/*
+ * Compare two handlers by dedup key
+ */
+static int CC_HINT(nonnull) 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.
@@ -185,6 +202,7 @@ static int mod_instantiate(CONF_SECTION *cs, void *instance)
case PW_EAP_TTLS:
case PW_EAP_PEAP:
case PW_EAP_PWD:
+ case PW_EAP_TEAP:
WARN("rlm_eap (%s): Ignoring EAP method %s because we don't have OpenSSL support",
inst->xlat_name, name);
continue;
@@ -255,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;
}
@@ -560,19 +588,16 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, REQUEST *reque
#ifdef WITH_PROXY
-static rlm_rcode_t CC_HINT(nonnull) mod_pre_proxy(void *instance, REQUEST *request)
+static rlm_rcode_t CC_HINT(nonnull) mod_pre_proxy(UNUSED void *instance, REQUEST *request)
{
VALUE_PAIR *vp;
- size_t length;
- rlm_eap_t *inst = instance;
+ size_t length, eap_length;
vp = fr_pair_find_by_num(request->packet->vps, PW_EAP_MESSAGE, 0, TAG_ANY);
if (!vp) return RLM_MODULE_NOOP;
- if (vp->vp_length < 4) return RLM_MODULE_NOOP;
-
- if ((vp->vp_octets[0] == 0) ||( vp->vp_octets[0] > 6)) {
- RDEBUG("EAP header byte zero has invalid value");
+ if (vp->vp_length < 4) {
+ RDEBUG("EAP packet is too small");
add_error_cause:
/*
@@ -582,21 +607,20 @@ static rlm_rcode_t CC_HINT(nonnull) mod_pre_proxy(void *instance, REQUEST *reque
return RLM_MODULE_REJECT;
}
+ /*
+ * The length field has to match the length of all EAP-Messages.
+ */
length = (vp->vp_octets[2] << 8) | vp->vp_octets[3];
- if (length != vp->vp_length) {
- RDEBUG("EAP length does not match attribute length");
- return RLM_MODULE_REJECT;
- }
- if (vp->vp_octets[0] != PW_EAP_REQUEST) return RLM_MODULE_NOOP;
- if (!inst->max_eap_type) return RLM_MODULE_NOOP;
-
- if (vp->vp_length < 5) return RLM_MODULE_NOOP;
-
- if (vp->vp_octets[4] == 254) return RLM_MODULE_NOOP; /* allow extended types */
+ /*
+ * Get length of all EAP-Message attributes
+ */
+ for (eap_length = 0; vp != NULL; vp = vp->next) {
+ eap_length += vp->vp_length;
+ }
- if (vp->vp_octets[4] > inst->max_eap_type) {
- RDEBUG("EAP method %u is too large", vp->vp_octets[4]);
+ if (length != eap_length) {
+ RDEBUG("EAP length does not match attribute length");
goto add_error_cause;
}