} tls_info_t;
/*
- * tls_session_t Structure gets stored as opaque in EAP_HANDLER
+ * tls_session_t Structure gets stored as opaque in eap_handler_t
* This contains EAP-REQUEST specific data
* (ie FR_TLS_DATA(fragment), EAPTLS-ALERT, EAPTLS-REQUEST ...)
*
void *ref;
} lt_dlmodule_t;
-typedef struct eap_type_data_t EAP_TYPE;
-typedef struct rlm_sql_module_t rlm_sql_module_t;
/*
* FIXME: Write hackery to auto-generate this data.
extern module_t rlm_sql;
/* and so on ... */
-extern EAP_TYPE rlm_eap_md5;
-extern rlm_sql_module_t rlm_sql_mysql;
+extern struct eap_type_data_t rlm_eap_md5;
+extern struct rlm_sql_module_t rlm_sql_mysql;
/* and so on ... */
static const lt_dlmodule_t lt_dlmodules[] = {
#include <freeradius-devel/ident.h>
#include <freeradius-devel/modpriv.h>
+
RCSID("$Id$")
#include "rlm_eap.h"
static const char *eap_codes[] = {
- "", /* 0 is invalid */
- "request",
- "response",
- "success",
- "failure"
+ "", /* 0 is invalid */
+ "request",
+ "response",
+ "success",
+ "failure"
};
-static int eaptype_free(void *ctx)
+static int eap_module_free(void *ctx)
{
- EAP_TYPES *node;
+ eap_module_t *inst;
- node = talloc_get_type_abort(ctx, EAP_TYPES);
+ inst = talloc_get_type_abort(ctx, eap_module_t);
- if (node->type->detach) (node->type->detach)(node->type_data);
+ if (inst->type->detach) (inst->type->detach)(inst->instance);
#ifndef NDEBUG
/*
*/
if (!mainconfig.debug_memory)
#endif
- if (node->handle) lt_dlclose(node->handle);
+ if (inst->handle) lt_dlclose(inst->handle);
return 0;
}
* Load all the required eap authentication types.
* Get all the supported EAP-types from config file.
*/
-int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs)
+int eap_module_load(eap_module_t **instance, eap_type_t method,
+ CONF_SECTION *cs)
{
- char buffer[64];
- char namebuf[64];
- const char *eaptype_name;
- EAP_TYPES *node;
-
- eaptype_name = eap_type_data_type2name(eap_type, namebuf, sizeof(namebuf));
- snprintf(buffer, sizeof(buffer), "rlm_eap_%s", eaptype_name);
+ eap_module_t *inst;
+ const char *mod_name;
/* Make room for the EAP-Type */
- *type = node = talloc_zero(cs, EAP_TYPES);
- if (!node) return -1;
+ *instance = inst = talloc_zero(cs, eap_module_t);
+ if (!inst) return -1;
- talloc_set_destructor((void *) node, eaptype_free);
+ talloc_set_destructor((void *) inst, eap_module_free);
/* fill in the structure */
- node->cs = cs;
-
+ inst->cs = cs;
+ inst->typename = eap_type2name(method);
+
/*
- * In general, this is a terrible idea. It works here
- * solely because the eap_type2name function returns a
- * 'static const char *' pointer sometimes, and we can
- * ONLY link to module which are named in that static
- * array.
+ * The name of the module were trying to load
*/
- node->typename = eaptype_name;
- node->type_data = NULL;
+ mod_name = talloc_asprintf(inst, "rlm_eap_%s", inst->typename);
+ inst->instance = NULL;
#if !defined(WITH_LIBLTDL) && defined(HAVE_DLFCN_H) && defined(RTLD_SELF)
- node->type = (EAP_TYPE *)lt_dlsym(RTLD_SELF, buffer);
- if (node->type) goto open_self;
+ inst->type = (rlm_eap_module_t *)lt_dlsym(RTLD_SELF, buffer);
+ if (inst->type) goto open_self;
#endif
- /* Link the loaded EAP-Type */
- node->handle = lt_dlopenext(buffer);
- if (node->handle == NULL) {
- radlog(L_ERR, "rlm_eap: Failed to link EAP-Type/%s: %s",
- eaptype_name, lt_dlerror());
+ /*
+ * Link the loaded EAP-Type
+ */
+ inst->handle = lt_dlopenext(mod_name);
+ if (inst->handle == NULL) {
+ radlog(L_ERR, "rlm_eap: Failed to link %s: %s",
+ mod_name, lt_dlerror());
+
return -1;
}
- node->type = (EAP_TYPE *)lt_dlsym(node->handle, buffer);
- if (!node->type) {
- radlog(L_ERR, "rlm_eap: Failed linking to %s structure in %s: %s",
- buffer, eaptype_name, lt_dlerror());
+ inst->type = (rlm_eap_module_t *)lt_dlsym(inst->handle, mod_name);
+ if (!inst->type) {
+ radlog(L_ERR, "rlm_eap: Failed linking to structure in %s: %s",
+ inst->typename, lt_dlerror());
+
return -1;
}
#if !defined(WITH_LIBLTDL) && defined(HAVE_DLFCN_H) && defined(RTLD_SELF)
open_self:
#endif
- cf_log_module(cs, "Linked to sub-module %s", buffer);
-
- cf_log_module(cs, "Instantiating eap-%s", eaptype_name);
-
- if ((node->type->attach) &&
- ((node->type->attach)(node->cs, &(node->type_data)) < 0)) {
-
- radlog(L_ERR, "rlm_eap: Failed to initialize type %s",
- eaptype_name);
- talloc_steal(node, node->type_data);
+ cf_log_module(cs, "Linked to sub-module %s", mod_name);
+
+ /*
+ * Call the attach method in the EAP Method module
+ */
+ if ((inst->type->attach) &&
+ ((inst->type->attach)(inst->cs, &(inst->instance)) < 0)) {
+ radlog(L_ERR, "rlm_eap: Failed to initialise %s",
+ mod_name);
+
+ talloc_steal(inst, inst->instance);
+
return -1;
}
- if (node->type_data) {
- talloc_steal(node, node->type_data);
+ if (inst->instance) {
+ talloc_steal(inst, inst->instance);
}
- *type = node;
+
return 0;
}
/*
- * Call the appropriate handle with the right eap_type.
+ * Call the appropriate handle with the right eap_method.
*/
-static int eaptype_call(EAP_TYPES *atype, EAP_HANDLER *handler)
+static int eap_module_call(eap_module_t *module, eap_handler_t *handler)
{
int rcode = 1;
REQUEST *request = handler->request;
- const char *module = request->module;
+
+ const char *caller = request->module;
- RDEBUG2("processing type %s", atype->typename);
- request->module = atype->typename;
+ RDEBUG2("Calling %s to process EAP data", module->type->name);
+
+ request->module = module->type->name;
- rad_assert(atype != NULL);
+ rad_assert(module != NULL);
switch (handler->stage) {
case INITIATE:
- if (!atype->type->initiate(atype->type_data, handler))
+ if (!module->type->initiate(module->instance, handler)) {
rcode = 0;
+ }
+
break;
case AUTHORIZE:
/*
* The called function updates the EAP reply packet.
*/
- if (!atype->type->authorize ||
- !atype->type->authorize(atype->type_data, handler))
+ if (!module->type->authorize ||
+ !module->type->authorize(module->instance, handler)) {
rcode = 0;
+ }
+
break;
case AUTHENTICATE:
/*
* The called function updates the EAP reply packet.
*/
- if (!atype->type->authenticate ||
- !atype->type->authenticate(atype->type_data, handler))
+ if (!module->type->authenticate ||
+ !module->type->authenticate(module->instance, handler)) {
rcode = 0;
+ }
+
break;
default:
/* Should never enter here */
- RDEBUG("Internal sanity check failed on eap_type");
+ RDEBUG("Internal sanity check failed on eap");
rcode = 0;
break;
}
- request->module = module;
+ request->module = caller;
return rcode;
}
-/*
- * Based on TYPE, call the appropriate EAP-type handler
- * Default to the configured EAP-Type
- * for all Unsupported EAP-Types
+/** Process NAK data from EAP peer
+ *
*/
-int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
+static eap_type_t eap_process_nak(rlm_eap_t *inst, REQUEST *request,
+ eap_type_t type,
+ eap_type_data_t *nak)
{
- size_t i;
- unsigned int default_eap_type = inst->default_eap_type;
- eap_type_data_t *eaptype;
- VALUE_PAIR *vp;
- char namebuf[64];
- const char *eaptype_name;
- REQUEST *request = handler->request;
+ unsigned int i;
+ VALUE_PAIR *vp;
+ eap_type_t method = PW_EAP_INVALID;
+
+ /*
+ * The NAK data is the preferred EAP type(s) of
+ * the client.
+ *
+ * RFC 3748 says to list one or more proposed
+ * alternative types, one per octet, or to use
+ * 0 for no alternative.
+ */
+ if (!nak->data) {
+ RDEBUGE("Peer sent empty (invalid) NAK. "
+ "Can't select method to continue with");
- eaptype = &handler->eap_ds->response->type;
+ return EAP_INVALID;
+ }
+ /*
+ * Pick one type out of the one they asked for,
+ * as they may have asked for many.
+ */
+ vp = pairfind(request->config_items, PW_EAP_TYPE, 0, TAG_ANY);
+ for (i = 0; i < nak->length; i++) {
+ /*
+ * Type 0 is valid, and means there are no
+ * common choices.
+ */
+ if (nak->data[i] == 0) {
+ RDEBUG("Peer NAK'd indicating it is not willing to "
+ "continue ");
+
+ return PW_EAP_INVALID;
+ }
+
+ /*
+ * It is invalid to request identity,
+ * notification & nak in nak.
+ */
+ if (nak->data[i] < PW_EAP_MD5) {
+ RDEBUGE("Peer NAK'd asking for bad "
+ "type %s (%d)",
+ eap_type2name(nak->data[i]),
+ nak->data[i]);
+
+ return PW_EAP_INVALID;
+ }
+
+ if ((nak->data[i] >= PW_EAP_MAX_TYPES) ||
+ !inst->methods[nak->data[i]]) {
+ RDEBUG2("Peer NAK'd asking for "
+ "unsupported type %s (%d), skipping...",
+ eap_type2name(nak->data[i]),
+ nak->data[i]);
+
+ continue;
+ }
+
+ /*
+ * Prevent a firestorm if the client is confused.
+ */
+ if (type == nak->data[i]) {
+ RDEBUG2("Peer NAK'd our request for "
+ "%s (%d) with a request for "
+ "%s (%d), skipping...",
+ eap_type2name(nak->data[i]),
+ nak->data[i],
+ eap_type2name(nak->data[i]),
+ nak->data[i]);
+
+ continue;
+ }
+
+ /*
+ * Enforce per-user configuration of EAP
+ * types.
+ */
+ if (vp && (vp->vp_integer != nak->data[i])) {
+ RDEBUG2("Peer wants %s (%d), while we "
+ "require %s (%d), skipping",
+ eap_type2name(nak->data[i]),
+ nak->data[i],
+ eap_type2name(vp->vp_integer),
+ vp->vp_integer);
+
+ continue;
+ }
+
+ RDEBUG("Found mutually acceptable type %s (%d)",
+ eap_type2name(nak->data[i]), nak->data[i]);
+
+ method = nak->data[i];
+
+ break;
+ }
+
+ if (method == PW_EAP_INVALID) {
+ RDEBUGE("No mutually acceptable types found");
+ }
+
+ return method;
+}
+
+/** Select the correct callback based on a response
+ *
+ * Based on the EAP response from the supplicant, call the appropriate
+ * method callback.
+ *
+ * Default to the configured EAP-Type for all Unsupported EAP-Types.
+ *
+ * @param inst Configuration data for this instance of rlm_eap.
+ * @param handler State data that persists over multiple rounds of EAP.
+ * @return a status code.
+ */
+eap_code_t eap_method_select(rlm_eap_t *inst, eap_handler_t *handler)
+{
+ eap_type_data_t *type = &handler->eap_ds->response->type;
+ REQUEST *request = handler->request;
+
+ eap_type_t next = inst->default_method;
+ VALUE_PAIR *vp;
+
/*
* Don't trust anyone.
*/
- if ((eaptype->type == 0) ||
- (eaptype->type >= PW_EAP_MAX_TYPES)) {
- RDEBUG2("Asked to select bad type");
+ if ((type->num == 0) || (type->num >= PW_EAP_MAX_TYPES)) {
+ RDEBUGE("Peer sent type (%d), which is outside known range");
+
return EAP_INVALID;
}
*/
if (handler->request->parent && handler->request->parent->parent) {
RDEBUG2("Multiple levels of TLS nesting is invalid.");
+
return EAP_INVALID;
}
+ RDEBUG2("EAP Peer sent %s (%d)", eap_type2name(type->num),
+ type->num);
/*
* Figure out what to do.
*/
- switch(eaptype->type) {
+ switch(type->num) {
case PW_EAP_IDENTITY:
- RDEBUG2("EAP Identity");
-
/*
* Allow per-user configuration of EAP types.
*/
- vp = pairfind(handler->request->config_items, PW_EAP_TYPE, 0, TAG_ANY);
- if (vp) default_eap_type = vp->vp_integer;
-
- do_initiate:
+ vp = pairfind(handler->request->config_items, PW_EAP_TYPE, 0,
+ TAG_ANY);
+ if (vp) next = vp->vp_integer;
+
/*
* Ensure it's valid.
*/
- if ((default_eap_type < PW_EAP_MD5) ||
- (default_eap_type >= PW_EAP_MAX_TYPES) ||
- (inst->types[default_eap_type] == NULL)) {
- RDEBUG2("No such EAP type %s",
- eap_type_data_type2name(default_eap_type,
- namebuf, sizeof(namebuf)));
+ if ((next < PW_EAP_MD5) ||
+ (next >= PW_EAP_MAX_TYPES) ||
+ (inst->methods[next] == NULL)) {
+ RDEBUG2E("Tried to start unsupported method (%d)",
+ next);
+
return EAP_INVALID;
}
- handler->stage = INITIATE;
- handler->eap_type = default_eap_type;
+ do_initiate:
+ /*
+ * If any of these fail, we messed badly somewhere
+ */
+ rad_assert(next >= PW_EAP_MD5);
+ rad_assert(next < PW_EAP_MAX_TYPES);
+ rad_assert(inst->methods[next]);
- if ((default_eap_type == PW_EAP_TNC) &&
- !handler->request->parent) {
- RDEBUG2E("EAP-TNC must be run inside of a TLS method.");
- return EAP_INVALID;
- }
+ handler->stage = INITIATE;
+ handler->type = next;
- if (eaptype_call(inst->types[default_eap_type],
- handler) == 0) {
- RDEBUG2("Default EAP type %s failed in initiate",
- eap_type_data_type2name(default_eap_type,
- namebuf, sizeof(namebuf)));
+ if (eap_module_call(inst->methods[next], handler) == 0) {
+ RDEBUG2E("Failed starting EAP %s (%d) session. "
+ "EAP sub-module failed",
+ eap_type2name(next),
+ next);
+
return EAP_INVALID;
}
break;
case PW_EAP_NAK:
- /*
- * The NAK data is the preferred EAP type(s) of
- * the client.
- *
- * RFC 3748 says to list one or more proposed
- * alternative types, one per octet, or to use
- * 0 for no alternative.
- */
- RDEBUG2("EAP NAK");
-
/*
* Delete old data, if necessary.
*/
handler->free_opaque = NULL;
handler->opaque = NULL;
}
-
- if (eaptype->data == NULL) {
- RDEBUG2E("Client sent empty NAK packet, cannot decide what EAP type it wants.");
- return EAP_INVALID;
- }
-
- /*
- * Pick one type out of the one they asked for,
- * as they may have asked for many.
- */
- default_eap_type = 0;
- vp = pairfind(handler->request->config_items, PW_EAP_TYPE, 0, TAG_ANY);
- for (i = 0; i < eaptype->length; i++) {
- /*
- * It is invalid to request identity,
- * notification & nak in nak.
- *
- * Type 0 is valid, and means there are no
- * common choices.
- */
- if (eaptype->data[i] < PW_EAP_MD5) {
- RDEBUG2E("Client sent NAK asking for bad type %d",
- eaptype->data[i]);
- return EAP_INVALID;
- }
-
- if ((eaptype->data[i] >= PW_EAP_MAX_TYPES) ||
- !inst->types[eaptype->data[i]]) {
- DICT_VALUE *dv;
-
- dv = dict_valbyattr(PW_EAP_TYPE, 0, eaptype->data[i]);
- if (dv) {
- RDEBUG2E("Client NAK asked for unsupported type %s",
- dv->name);
- } else {
- RDEBUG2E("Client NAK asked for unsupported type %d",
- eaptype->data[i]);
- }
- continue;
- }
-
- eaptype_name = eap_type_data_type2name(eaptype->data[i],
- namebuf,
- sizeof(namebuf));
-
- /*
- * Prevent a firestorm if the client is confused.
- */
- if (handler->eap_type == eaptype->data[i]) {
- RDEBUG2E("Client NAK'd our request for %s with a request for %s. Ignoring it.",
- eaptype_name, eaptype_name);
- continue;
- }
-
- /*
- * Enforce per-user configuration of EAP
- * types.
- */
- if (vp && (vp->vp_integer != eaptype->data[i])) {
- char mynamebuf[64];
- RDEBUG2("Client wants %s, while we require %s. Skipping the requested type.",
- eaptype_name,
- eap_type_data_type2name(vp->vp_integer,
- mynamebuf,
- sizeof(mynamebuf)));
- continue;
- }
-
- default_eap_type = eaptype->data[i];
- break;
- }
+
+ next = eap_process_nak(inst, handler->request,
+ handler->type, type);
/*
* We probably want to return 'fail' here...
*/
- if (!default_eap_type) {
- RDEBUG2("No common EAP types found.");
+ if (!next) {
return EAP_INVALID;
}
- eaptype_name = eap_type_data_type2name(default_eap_type,
- namebuf, sizeof(namebuf));
- RDEBUG2("EAP-NAK asked for EAP-Type/%s",
- eaptype_name);
goto do_initiate;
break;
* Key off of the configured sub-modules.
*/
default:
- eaptype_name = eap_type_data_type2name(eaptype->type,
- namebuf,
- sizeof(namebuf));
- RDEBUG2("EAP/%s", eaptype_name);
+ RDEBUG2("EAP %s (%d)",
+ eap_type2name(type->num),
+ type->num);
/*
* We haven't configured it, it doesn't exit.
*/
- if (!inst->types[eaptype->type]) {
- RDEBUG2E("Client ask for unsupported EAP type %d",
- eaptype->type);
+ if (!inst->methods[type->num]) {
+ RDEBUG2E("Client asked for unsupported "
+ "type %s (%d)",
+ eap_type2name(type->num),
+ type->num);
+
return EAP_INVALID;
}
rad_assert(handler->stage == AUTHENTICATE);
- handler->eap_type = eaptype->type;
- if (eaptype_call(inst->types[eaptype->type],
- handler) == 0) {
- RDEBUG2("Handler failed in EAP/%s",
- eaptype_name);
+ handler->type = type->num;
+ if (eap_module_call(inst->methods[type->num],
+ handler) == 0) {
+ RDEBUG2E("Failed continuing EAP %s (%d) session. "
+ "EAP sub-module failed",
+ eap_type2name(type->num),
+ type->num);
+
return EAP_INVALID;
}
break;
* Set the RADIUS reply codes based on EAP request codes. Append
* any additonal VPs to RADIUS reply
*/
-rlm_rcode_t eap_compose(EAP_HANDLER *handler)
+rlm_rcode_t eap_compose(eap_handler_t *handler)
{
VALUE_PAIR *vp;
eap_packet_raw_t *eap_packet;
*/
if (((eap_ds->request->code == PW_EAP_REQUEST) ||
(eap_ds->request->code == PW_EAP_RESPONSE)) &&
- (eap_ds->request->type.type == 0)) {
- rad_assert(handler->eap_type >= PW_EAP_MD5);
- rad_assert(handler->eap_type < PW_EAP_MAX_TYPES);
+ (eap_ds->request->type.num == 0)) {
+ rad_assert(handler->type >= PW_EAP_MD5);
+ rad_assert(handler->type < PW_EAP_MAX_TYPES);
- eap_ds->request->type.type = handler->eap_type;
+ eap_ds->request->type.num = handler->type;
}
/*
*/
if ((eap_msg->length == 0) || (eap_msg->length == 2)) {
EAP_DS *eap_ds;
- EAP_HANDLER handler;
+ eap_handler_t handler;
/*
* It's a valid EAP-Start, but the request
*/
if (proxy) {
do_proxy:
- RDEBUG2("Request is supposed to be proxied to Realm %s. Not doing EAP.", proxy->vp_strvalue);
+ RDEBUG2("Request is supposed to be proxied to "
+ "Realm %s. Not doing EAP.", proxy->vp_strvalue);
return EAP_NOOP;
}
* EAP-Start packet for something...
*/
eap_ds->request->code = PW_EAP_REQUEST;
- eap_ds->request->type.type = PW_EAP_IDENTITY;
+ eap_ds->request->type.num = PW_EAP_IDENTITY;
/*
* We don't have a handler, but eap_compose needs one,
* internally, so they never have handlers.
*/
if ((eap_msg->vp_octets[4] >= PW_EAP_MD5) &&
- inst->ignore_unknown_eap_types &&
+ inst->ignore_unknown_types &&
((eap_msg->vp_octets[4] == 0) ||
(eap_msg->vp_octets[4] >= PW_EAP_MAX_TYPES) ||
- (inst->types[eap_msg->vp_octets[4]] == NULL))) {
+ (inst->methods[eap_msg->vp_octets[4]] == NULL))) {
RDEBUG2(" Ignoring Unknown EAP type");
return EAP_NOOP;
}
*/
if ((eap_msg->vp_octets[4] == PW_EAP_NAK) &&
(eap_msg->length >= (EAP_HEADER_LEN + 2)) &&
- inst->ignore_unknown_eap_types &&
+ inst->ignore_unknown_types &&
((eap_msg->vp_octets[5] == 0) ||
(eap_msg->vp_octets[5] >= PW_EAP_MAX_TYPES) ||
- (inst->types[eap_msg->vp_octets[5]] == NULL))) {
+ (inst->methods[eap_msg->vp_octets[5]] == NULL))) {
RDEBUG2("Ignoring NAK with request for unknown EAP type");
return EAP_NOOP;
}
/*
* compose EAP FAILURE packet in EAP-Message
*/
-void eap_fail(EAP_HANDLER *handler)
+void eap_fail(eap_handler_t *handler)
{
/*
* Delete any previous replies.
/*
* compose EAP SUCCESS packet in EAP-Message
*/
-void eap_success(EAP_HANDLER *handler)
+void eap_success(eap_handler_t *handler)
{
handler->eap_ds->request->code = PW_EAP_SUCCESS;
eap_compose(handler);
eap_ds->response->packet = (unsigned char *)eap_packet;
eap_ds->response->code = eap_packet->code;
eap_ds->response->id = eap_packet->id;
- eap_ds->response->type.type = eap_packet->data[0];
+ eap_ds->response->type.num = eap_packet->data[0];
memcpy(&len, eap_packet->length, sizeof(uint16_t));
len = ntohs(len);
* username contains REQUEST->username which might have been stripped.
* identity contains the one sent in EAP-Identity response
*/
-EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_raw_t **eap_packet_p,
+eap_handler_t *eap_handler(rlm_eap_t *inst, eap_packet_raw_t **eap_packet_p,
REQUEST *request)
{
- EAP_HANDLER *handler = NULL;
+ eap_handler_t *handler = NULL;
eap_packet_raw_t *eap_packet = *eap_packet_p;
VALUE_PAIR *vp;
}
/*
- * EAP_HANDLER MUST be found in the list if it is not
+ * eap_handler_t MUST be found in the list if it is not
* EAP-Identity response
*/
if (eap_packet->data[0] != PW_EAP_IDENTITY) {
* OK to blindly return data for another type.
*/
if ((eap_packet->data[0] != PW_EAP_NAK) &&
- (eap_packet->data[0] != handler->eap_type)) {
+ (eap_packet->data[0] != handler->type)) {
RDEBUG("Response appears to match, but EAP type is wrong.");
free(*eap_packet_p);
*eap_packet_p = NULL;
/*
- * EAP_HANDLER is the interface for any EAP-Type.
+ * eap_handler_t is the interface for any EAP-Type.
* Each handler contains information for one specific EAP-Type.
* This way we don't need to change any interfaces in future.
* It is also a list of EAP-request handlers waiting for EAP-response
struct _eap_handler *prev, *next;
uint8_t state[EAP_STATE_LEN];
fr_ipaddr_t src_ipaddr;
- unsigned int eap_id;
- unsigned int eap_type;
+
+ uint8_t eap_id; //!< EAP Identifier used to match
+ //!< requests and responses.
+ eap_type_t type; //!< EAP type number.
time_t timestamp;
REQUEST *request;
- char *identity; /* User name from EAP-Identity */
+ char *identity; //!< User name from EAP-Identity
EAP_DS *prev_eapds;
EAP_DS *eap_ds;
int tls;
int finished;
VALUE_PAIR *certs;
-} EAP_HANDLER;
+} eap_handler_t;
/*
* Interface to call EAP sub mdoules
*/
-typedef struct eap_type_data_t {
- const char *name;
- int (*attach)(CONF_SECTION *conf, void **type_data);
- int (*initiate)(void *type_data, EAP_HANDLER *handler);
- int (*authorize)(void *type_data, EAP_HANDLER *handler);
- int (*authenticate)(void *type_data, EAP_HANDLER *handler);
- int (*detach)(void *type_data);
-} EAP_TYPE;
-
-#define REQUEST_DATA_EAP_HANDLER (1)
+typedef struct rlm_eap_module {
+ const char *name;
+ int (*attach)(CONF_SECTION *conf, void **instance);
+ int (*initiate)(void *instance, eap_handler_t *handler);
+ int (*authorize)(void *instance, eap_handler_t *handler);
+ int (*authenticate)(void *instance, eap_handler_t *handler);
+ int (*detach)(void *instance);
+} rlm_eap_module_t;
+
+#define REQUEST_DATA_eap_handler_t (1)
#define REQUEST_DATA_EAP_TUNNEL_CALLBACK PW_EAP_MESSAGE
#define REQUEST_DATA_EAP_MSCHAP_TUNNEL_CALLBACK ((PW_EAP_MESSAGE << 16) | PW_EAP_MSCHAPV2)
#define RAD_REQUEST_OPTION_PROXY_EAP (1 << 16)
/*
* This is for tunneled callbacks
*/
-typedef int (*eap_tunnel_callback_t)(EAP_HANDLER *handler, void *tls_session);
+typedef int (*eap_tunnel_callback_t)(eap_handler_t *handler, void *tls_session);
+
typedef struct eap_tunnel_data_t {
void *tls_session;
eap_tunnel_callback_t callback;
*
* Fragment length is Framed-MTU - 4.
*/
-tls_session_t *eaptls_session(fr_tls_server_conf_t *tls_conf, EAP_HANDLER *handler, int client_cert)
+tls_session_t *eaptls_session(fr_tls_server_conf_t *tls_conf, eap_handler_t *handler, int client_cert)
{
tls_session_t *ssn;
int verify_mode = 0;
return 1;
}
-int eaptls_success(EAP_HANDLER *handler, int peap_flag)
+int eaptls_success(eap_handler_t *handler, int peap_flag)
{
EAPTLS_PACKET reply;
REQUEST *request = handler->request;
}
eaptls_gen_eap_key(handler->request->reply, tls_session->ssl,
- handler->eap_type, &handler->request->reply->vps);
+ handler->type, &handler->request->reply->vps);
return 1;
}
-int eaptls_fail(EAP_HANDLER *handler, int peap_flag)
+int eaptls_fail(eap_handler_t *handler, int peap_flag)
{
EAPTLS_PACKET reply;
tls_session_t *tls_session = handler->opaque;
* EAP-Type=EAP-TLS and no data. This serves as a fragment
* ACK. The EAP peer MUST wait.
*/
-static fr_tls_status_t eaptls_verify(EAP_HANDLER *handler)
+static fr_tls_status_t eaptls_verify(eap_handler_t *handler)
{
EAP_DS *eap_ds = handler->eap_ds;
EAP_DS *prev_eap_ds = handler->prev_eapds;
* NULL, of if it's NOT an EAP-Response, or if the packet
* is too short. See eap_validation()., in ../../eap.c
*
- * Also, eaptype_select() takes care of selecting the
+ * Also, eap_method_select() takes care of selecting the
* appropriate type, so we don't need to check
- * eap_ds->response->type.type == PW_EAP_TLS, or anything
+ * eap_ds->response->type.num == PW_EAP_TLS, or anything
* else.
*/
eaptls_packet = (eaptls_packet_t *)eap_ds->response->type.data;
* then how to let SSL API know about these sessions.)
*/
static fr_tls_status_t eaptls_operation(fr_tls_status_t status,
- EAP_HANDLER *handler)
+ eap_handler_t *handler)
{
tls_session_t *tls_session;
/*
* Process an EAP request
*/
-fr_tls_status_t eaptls_process(EAP_HANDLER *handler)
+fr_tls_status_t eaptls_process(eap_handler_t *handler)
{
tls_session_t *tls_session = (tls_session_t *) handler->opaque;
EAPTLS_PACKET *tlspacket;
uint8_t *ptr;
/*
- * Don't set eap_ds->request->type.type, as the main EAP
+ * Don't set eap_ds->request->type.num, as the main EAP
* handler will do that for us. This allows the TLS
* module to be called from TTLS & PEAP.
*/
/*
* Externally exported TLS functions.
*/
-fr_tls_status_t eaptls_process(EAP_HANDLER *handler);
+fr_tls_status_t eaptls_process(eap_handler_t *handler);
-int eaptls_success(EAP_HANDLER *handler, int peap_flag);
-int eaptls_fail(EAP_HANDLER *handler, int peap_flag);
+int eaptls_success(eap_handler_t *handler, int peap_flag);
+int eaptls_fail(eap_handler_t *handler, int peap_flag);
int eaptls_request(EAP_DS *eap_ds, tls_session_t *ssn);
/* EAP-TLS framework */
EAPTLS_PACKET *eaptls_alloc(void);
void eaptls_free(EAPTLS_PACKET **eaptls_packet_ptr);
-tls_session_t *eaptls_session(fr_tls_server_conf_t *tls_conf, EAP_HANDLER *handler, int client_cert);
+tls_session_t *eaptls_session(fr_tls_server_conf_t *tls_conf, eap_handler_t *handler, int client_cert);
int eaptls_start(EAP_DS *eap_ds, int peap);
int eaptls_compose(EAP_DS *eap_ds, EAPTLS_PACKET *reply);
#define _EAP_TYPES_H
#include <freeradius-devel/ident.h>
-RCSIDH(eap_types_h, "$Id$")
+RCSIDH(eap_methods_h, "$Id$")
#include <freeradius-devel/radiusd.h>
#include <freeradius-devel/modules.h>
PW_EAP_MAX_CODES
} eap_code_t;
-typedef enum eap_type {
- PW_EAP_IDENTITY = 1, /* 1 */
+typedef enum eap_method {
+ PW_EAP_INVALID = 0, /* 0 */
+ PW_EAP_IDENTITY, /* 1 */
PW_EAP_NOTIFICATION, /* 2 */
PW_EAP_NAK, /* 3 */
PW_EAP_MD5, /* 4 */
} eap_type_t;
typedef enum eap_rcode {
- EAP_NOTFOUND, //!< Not found.
- EAP_FOUND, //!< Found, continue.
+ EAP_NOTFOUND, //!< EAP handler data not found.
+ EAP_FOUND, //!< EAP handler data found, continue.
EAP_OK, //!< Ok, continue.
EAP_FAIL, //!< Failed, don't reply.
EAP_NOOP, //!< Succeeded without doing anything.
EAP_MAX_RCODES
} eap_rcode_t;
+extern const FR_NAME_NUMBER eap_rcode_table[];
+
/*
* EAP-Type specific data.
*/
typedef struct eap_type_data {
- uint8_t type;
- size_t length;
- uint8_t *data;
+ eap_type_t num;
+ size_t length;
+ uint8_t *data;
} eap_type_data_t;
/*
* = 1 + 1 + 2 + 1 + X
*/
typedef struct eap_packet {
- unsigned char code;
- unsigned char id;
- unsigned int length;
+ eap_code_t code;
+ uint8_t id;
+ size_t length;
eap_type_data_t type;
- unsigned char *packet;
+ uint8_t *packet;
} eap_packet_t;
/*
/*
* interfaces in eapcommon.c
*/
-extern int eaptype_name2type(const char *name);
-extern const char *eap_type_data_type2name(unsigned int type, char *buffer, size_t buflen);
+extern eap_type_t eap_name2type(const char *name);
+extern const char *eap_type2name(eap_type_t method);
extern int eap_wireformat(eap_packet_t *reply);
extern int eap_basic_compose(RADIUS_PACKET *packet, eap_packet_t *reply);
extern VALUE_PAIR *eap_packet2vp(RADIUS_PACKET *packet,
#include <freeradius-devel/libradius.h>
#include "eap_types.h"
-static const char *eap_types[] = {
- "",
- "identity",
- "notification",
- "nak", /* NAK */
- "md5",
- "otp",
- "gtc",
- "7",
- "8",
- "9",
- "10",
- "11",
- "12",
- "tls", /* 13 */
- "14",
- "15",
- "16",
- "leap", /* 17 */
- "sim", /* 18 GSM-SIM authentication */
- "19",
- "20",
- "ttls", /* 21 */
- "22",
- "23",
- "24",
- "peap", /* 25 */
- "mschapv2", /* 26 */
- "27",
- "28",
- "cisco_mschapv2", /* 29 */
- "30",
- "31",
- "32",
- "33",
- "34",
- "35",
- "36",
- "37",
- "tnc", /* 38 */
- "39",
- "40",
- "41",
- "42",
- "fast",
- "44",
- "45",
- "pax",
- "psk",
- "sake",
- "ikev2",
- "50",
- "51",
- "pwd",
- "eke"
-}; /* MUST have PW_EAP_MAX_TYPES */
-
-/*
- * Return an EAP-Type for a particular name.
+const FR_NAME_NUMBER eap_rcode_table[] = {
+ { "notfound", EAP_NOTFOUND },
+ { "found", EAP_OK },
+ { "ok", EAP_FAIL },
+ { "fail", EAP_NOOP },
+ { "noop", EAP_INVALID },
+ { "invalid", EAP_VALID },
+ { "valid", EAP_MAX_RCODES },
+
+ { NULL , -1 }
+};
+
+/** Return an EAP-Type for a particular name
+ * .
*/
-int eaptype_name2type(const char *name)
+eap_type_t eap_name2type(const char *name)
{
- int i;
+ DICT_VALUE *dv;
- for (i = 0; i < PW_EAP_MAX_TYPES; i++) {
- if (strcmp(name, eap_types[i]) == 0) {
- return i;
- }
+ dv = dict_valbyname(PW_EAP_TYPE, 0, name);
+ if (dv) {
+ return dv->value;
}
-
+
return -1;
}
-/*
- * Returns a text string containing the name of the EAP type.
+/** Return an EAP-name for a particular type
+ * .
*/
-const char *eap_type_data_type2name(unsigned int type, char *buffer, size_t buflen)
+const char *eap_type2name(eap_type_t method)
{
- DICT_VALUE *dval;
+ DICT_VALUE *dv;
- if (type >= PW_EAP_MAX_TYPES) {
- /*
- * Prefer the dictionary name over a number,
- * if it exists.
- */
- dval = dict_valbyattr(PW_EAP_TYPE, 0, type);
- if (dval) {
- snprintf(buffer, buflen, "%s", dval->name);
- }
-
- snprintf(buffer, buflen, "%d", type);
- return buffer;
- } else if ((*eap_types[type] >= '0') && (*eap_types[type] <= '9')) {
- /*
- * Prefer the dictionary name, if it exists.
- */
- dval = dict_valbyattr(PW_EAP_TYPE, 0, type);
- if (dval) {
- snprintf(buffer, buflen, "%s", dval->name);
- return buffer;
- } /* else it wasn't in the dictionary */
- } /* else the name in the array was non-numeric */
-
- /*
- * Return the name, whatever it is.
- */
- return eap_types[type];
+ dv = dict_valbyattr(PW_EAP_TYPE, 0, method);
+ if (dv) {
+ return dv->name;
+ }
+
+ return "unknown";
}
/*
*/
int eap_wireformat(eap_packet_t *reply)
{
- eap_packet_raw_t *hdr;
+ eap_packet_raw_t *header;
uint16_t total_length = 0;
if (reply == NULL) return EAP_INVALID;
total_length = EAP_HEADER_LEN;
if (reply->code < 3) {
- total_length += 1/*EAPtype*/;
+ total_length += 1/* EAP Method */;
if (reply->type.data && reply->type.length > 0) {
total_length += reply->type.length;
}
}
reply->packet = (unsigned char *)malloc(total_length);
- hdr = (eap_packet_raw_t *)reply->packet;
- if (!hdr) {
+ header = (eap_packet_raw_t *)reply->packet;
+ if (!header) {
radlog(L_ERR, "rlm_eap: out of memory");
return EAP_INVALID;
}
- hdr->code = (reply->code & 0xFF);
- hdr->id = (reply->id & 0xFF);
+ header->code = (reply->code & 0xFF);
+ header->id = (reply->id & 0xFF);
+
total_length = htons(total_length);
- memcpy(hdr->length, &total_length, sizeof(total_length));
+ memcpy(header->length, &total_length, sizeof(total_length));
/*
* Request and Response packets are special.
*/
if ((reply->code == PW_EAP_REQUEST) ||
(reply->code == PW_EAP_RESPONSE)) {
- hdr->data[0] = (reply->type.type & 0xFF);
+ header->data[0] = (reply->type.num & 0xFF);
/*
* Here since we cannot know the typedata format and length
* type is defined
*/
if (reply->type.data && reply->type.length > 0) {
- memcpy(&hdr->data[1], reply->type.data, reply->type.length);
+ memcpy(&header->data[1], reply->type.data, reply->type.length);
free(reply->type.data);
reply->type.data = reply->packet + EAP_HEADER_LEN + 1/*EAPtype*/;
}
if (ep->code != PW_EAP_SUCCESS)
ep->code = eapcode;
ep->id = (id & 0xff);
- ep->type.type = PW_EAP_SIM;
+ ep->type.num = PW_EAP_SIM;
/*
* if no attributes were found, do very little.
}
/*
- * Allocate a new EAP_HANDLER
+ * Allocate a new eap_handler_t
*/
-EAP_HANDLER *eap_handler_alloc(rlm_eap_t *inst)
+eap_handler_t *eap_handler_alloc(rlm_eap_t *inst)
{
- EAP_HANDLER *handler;
+ eap_handler_t *handler;
- handler = rad_malloc(sizeof(EAP_HANDLER));
- memset(handler, 0, sizeof(EAP_HANDLER));
+ handler = rad_malloc(sizeof(eap_handler_t));
+ memset(handler, 0, sizeof(eap_handler_t));
if (inst->handler_tree) {
PTHREAD_MUTEX_LOCK(&(inst->handler_mutex));
return handler;
}
-void eap_opaque_free(EAP_HANDLER *handler)
+void eap_opaque_free(eap_handler_t *handler)
{
if (!handler)
return;
eap_handler_free(handler->inst_holder, handler);
}
-void eap_handler_free(rlm_eap_t *inst, EAP_HANDLER *handler)
+void eap_handler_free(rlm_eap_t *inst, eap_handler_t *handler)
{
if (!handler)
return;
typedef struct check_handler_t {
rlm_eap_t *inst;
- EAP_HANDLER *handler;
+ eap_handler_t *handler;
int trips;
} check_handler_t;
void eaplist_free(rlm_eap_t *inst)
{
- EAP_HANDLER *node, *next;
+ eap_handler_t *node, *next;
for (node = inst->session_head; node != NULL; node = next) {
next = node->next;
}
-static EAP_HANDLER *eaplist_delete(rlm_eap_t *inst, REQUEST *request,
- EAP_HANDLER *handler)
+static eap_handler_t *eaplist_delete(rlm_eap_t *inst, REQUEST *request,
+ eap_handler_t *handler)
{
rbnode_t *node;
static void eaplist_expire(rlm_eap_t *inst, REQUEST *request, time_t timestamp)
{
int i;
- EAP_HANDLER *handler;
+ eap_handler_t *handler;
/*
* Check the first few handlers in the list, and delete
* Since we're adding it to the list, we guess that this means
* the packet needs a State attribute. So add one.
*/
-int eaplist_add(rlm_eap_t *inst, EAP_HANDLER *handler)
+int eaplist_add(rlm_eap_t *inst, eap_handler_t *handler)
{
int status = 0;
VALUE_PAIR *state;
*/
state->vp_octets[4] = handler->trips ^ handler->state[0];
state->vp_octets[5] = handler->eap_id ^ handler->state[1];
- state->vp_octets[6] = handler->eap_type ^ handler->state[2];
+ state->vp_octets[6] = handler->type ^ handler->state[2];
/*
* and copy the state back again.
}
if (status) {
- EAP_HANDLER *prev;
+ eap_handler_t *prev;
prev = inst->session_tail;
if (prev) {
* Also since we fill the eap_ds with the present EAP-Response we
* got to free the prev_eapds & move the eap_ds to prev_eapds
*/
-EAP_HANDLER *eaplist_find(rlm_eap_t *inst, REQUEST *request,
+eap_handler_t *eaplist_find(rlm_eap_t *inst, REQUEST *request,
eap_packet_raw_t *eap_packet)
{
VALUE_PAIR *state;
- EAP_HANDLER *handler, myHandler;
+ eap_handler_t *handler, myHandler;
/*
* We key the sessions off of the 'state' attribute, so it
struct eapsim_keys eapsim_mk;
-static void map_eap_types(RADIUS_PACKET *req);
-static void unmap_eap_types(RADIUS_PACKET *rep);
+static void map_eap_methods(RADIUS_PACKET *req);
+static void unmap_eap_methods(RADIUS_PACKET *rep);
static int map_eapsim_types(RADIUS_PACKET *r);
static int unmap_eapsim_types(RADIUS_PACKET *r);
* if there are EAP types, encode them into an EAP-Message
*
*/
- map_eap_types(rep);
+ map_eap_methods(rep);
/*
* Fix up Digest-Attributes issues
send_packet(rep, &req);
/* okay got back the packet, go and decode the EAP-Message. */
- unmap_eap_types(req);
+ unmap_eap_methods(req);
debug_packet(req, R_RECV);
* just deserves an assert?
*
*/
-static void map_eap_types(RADIUS_PACKET *req)
+static void map_eap_methods(RADIUS_PACKET *req)
{
VALUE_PAIR *vp, *vpnext;
int id, eapcode;
eap_packet_t ep;
- int eap_type;
+ int eap_method;
vp = pairfind(req->vps, ATTRIBUTE_EAP_ID, 0, TAG_ANY);
if(vp == NULL) {
return;
}
- eap_type = vp->da->attribute - ATTRIBUTE_EAP_BASE;
+ eap_method = vp->da->attribute - ATTRIBUTE_EAP_BASE;
- switch(eap_type) {
+ switch(eap_method) {
case PW_EAP_IDENTITY:
case PW_EAP_NOTIFICATION:
case PW_EAP_NAK:
memset(&ep, 0, sizeof(ep));
ep.code = eapcode;
ep.id = id;
- ep.type.type = eap_type;
+ ep.type.num = eap_method;
ep.type.length = vp->length;
ep.type.data = malloc(vp->length);
memcpy(ep.type.data,vp->vp_octets, vp->length);
* given a radius request with an EAP-Message body, decode it specific
* attributes.
*/
-static void unmap_eap_types(RADIUS_PACKET *rep)
+static void unmap_eap_methods(RADIUS_PACKET *rep)
{
VALUE_PAIR *eap1;
eap_packet_raw_t *e;
}
map_eapsim_types(req);
- map_eap_types(req);
+ map_eap_methods(req);
if (fr_debug_flag > 1) {
printf("Mapped to:\n");
pairadd(&req2->vps, vp);
/* only call unmap for sim types here */
- unmap_eap_types(req2);
+ unmap_eap_methods(req2);
unmap_eapsim_types(req2);
if (fr_debug_flag > 1) {
static const CONF_PARSER module_config[] = {
{ "default_eap_type", PW_TYPE_STRING_PTR,
- offsetof(rlm_eap_t, default_eap_type_name), NULL, "md5" },
+ offsetof(rlm_eap_t, default_method_name), NULL, "md5" },
{ "timer_expire", PW_TYPE_INTEGER,
offsetof(rlm_eap_t, timer_limit), NULL, "60"},
{ "ignore_unknown_eap_types", PW_TYPE_BOOLEAN,
- offsetof(rlm_eap_t, ignore_unknown_eap_types), NULL, "no" },
+ offsetof(rlm_eap_t, ignore_unknown_types), NULL, "no" },
{ "cisco_accounting_username_bug", PW_TYPE_BOOLEAN,
offsetof(rlm_eap_t, cisco_accounting_username_bug), NULL, "no" },
{ "max_sessions", PW_TYPE_INTEGER,
static int eap_handler_cmp(const void *a, const void *b)
{
int rcode;
- const EAP_HANDLER *one = a;
- const EAP_HANDLER *two = b;
+ const eap_handler_t *one = a;
+ const eap_handler_t *two = b;
if (one->eap_id < two->eap_id) return -1;
if (one->eap_id > two->eap_id) return +1;
* EAP work.
*/
if (fr_ipaddr_cmp(&one->src_ipaddr, &two->src_ipaddr) != 0) {
- DEBUGW("EAP packets are arriving from two different upstream servers. Has there been a proxy fail-over?");
+ DEBUGW("EAP packets are arriving from two different upstream "
+ "servers. Has there been a proxy fail-over?");
}
return 0;
*/
static int eap_instantiate(CONF_SECTION *cs, void **instance)
{
- int i, eap_type;
- int num_types;
+ int i;
+ eap_type_t method;
+ int num_methods;
CONF_SECTION *scs;
rlm_eap_t *inst;
if (!inst->xlat_name) inst->xlat_name = "EAP";
/* Load all the configured EAP-Types */
- num_types = 0;
- for(scs=cf_subsection_find_next(cs, NULL, NULL);
- scs != NULL;
- scs=cf_subsection_find_next(cs, scs, NULL)) {
+ num_methods = 0;
+ for(scs = cf_subsection_find_next(cs, NULL, NULL);
+ scs != NULL;
+ scs = cf_subsection_find_next(cs, scs, NULL)) {
- const char *auth_type;
+ const char *name;
- auth_type = cf_section_name1(scs);
+ name = cf_section_name1(scs);
+ if (!name) continue;
- if (!auth_type) continue;
+ if (!strcmp(name, TLS_CONFIG_SECTION)) continue;
- if (!strcmp(auth_type, TLS_CONFIG_SECTION)) continue;
-
- eap_type = eaptype_name2type(auth_type);
- if (eap_type < 0) {
- radlog(L_ERR, "rlm_eap: Unknown EAP type %s",
- auth_type);
+ method = eap_name2type(name);
+ if (method == PW_EAP_INVALID) {
+ radlog(L_ERR, "rlm_eap: Unknown EAP method %s",
+ name);
eap_detach(inst);
+
return -1;
}
* etc. configurations from eap.conf in order to
* have EAP without the TLS types.
*/
- if ((eap_type == PW_EAP_TLS) ||
- (eap_type == PW_EAP_TTLS) ||
- (eap_type == PW_EAP_PEAP)) {
- DEBUG2("Ignoring EAP-Type/%s because we do not have OpenSSL support.", auth_type);
+ if ((method == PW_EAP_TLS) ||
+ (method == PW_EAP_TTLS) ||
+ (method == PW_EAP_PEAP)) {
+ DEBUG2("Ignoring EAP method %s because we do not have "
+ "OpenSSL support", name);
continue;
}
#endif
/*
* Load the type.
*/
- if (eaptype_load(&inst->types[eap_type], eap_type, scs) < 0) {
- talloc_steal(inst, inst->types[eap_type]);
+ if (eap_module_load(&inst->methods[method], method, scs) < 0) {
+ talloc_steal(inst, inst->methods[method]);
eap_detach(inst);
+
return -1;
}
- talloc_steal(inst, inst->types[eap_type]);
- num_types++; /* successfully loaded one more types */
+ talloc_steal(inst, inst->methods[method]);
+ num_methods++; /* successfully loaded one more methods */
}
- if (num_types == 0) {
- radlog(L_ERR, "rlm_eap: No EAP type configured, module cannot do anything.");
+ if (num_methods == 0) {
+ radlog(L_ERR, "rlm_eap: No EAP method configured, module "
+ "cannot do anything.");
+
eap_detach(inst);
+
return -1;
}
/*
* Ensure that the default EAP type is loaded.
*/
- eap_type = eaptype_name2type(inst->default_eap_type_name);
- if (eap_type < 0) {
- radlog(L_ERR, "rlm_eap: Unknown default EAP type %s",
- inst->default_eap_type_name);
+ method = eap_name2type(inst->default_method_name);
+ if (method == PW_EAP_INVALID) {
+ radlog(L_ERR, "rlm_eap: Unknown default EAP method %s",
+ inst->default_method_name);
eap_detach(inst);
return -1;
}
- if (inst->types[eap_type] == NULL) {
- radlog(L_ERR, "rlm_eap: No such sub-type for default EAP type %s",
- inst->default_eap_type_name);
+ if (inst->methods[method] == NULL) {
+ radlog(L_ERR, "rlm_eap: No such sub-type for default EAP "
+ "method %s", inst->default_method_name);
eap_detach(inst);
+
return -1;
}
- inst->default_eap_type = eap_type; /* save the numerical type */
+ inst->default_method = method; /* save the numerical method */
/*
* List of sessions are set to NULL by the memset
*/
static rlm_rcode_t eap_authenticate(void *instance, REQUEST *request)
{
- rlm_eap_t *inst;
- EAP_HANDLER *handler;
+ rlm_eap_t *inst;
+ eap_handler_t *handler;
eap_packet_raw_t *eap_packet;
- int rcode;
- rlm_rcode_t module_rcode;
+ eap_rcode_t status;
+ rlm_rcode_t rcode;
inst = (rlm_eap_t *) instance;
if (!pairfind(request->packet->vps, PW_EAP_MESSAGE, 0, TAG_ANY)) {
- RDEBUGE("You set 'Auth-Type = EAP' for a request that does not contain an EAP-Message attribute!");
+ RDEBUGE("You set 'Auth-Type = EAP' for a request that does "
+ "not contain an EAP-Message attribute!");
return RLM_MODULE_INVALID;
}
}
/*
- * Select the appropriate eap_type or default to the
+ * Select the appropriate method or default to the
* configured one
*/
- rcode = eaptype_select(inst, handler);
+ status = eap_method_select(inst, handler);
/*
* If it failed, die.
*/
- if (rcode == EAP_INVALID) {
+ if (status == EAP_INVALID) {
eap_fail(handler);
eap_handler_free(inst, handler);
RDEBUG2("Failed in EAP select");
* send a response.
*/
handler->inst_holder = inst;
- rcode = request_data_add(request,
- inst, REQUEST_DATA_EAP_HANDLER,
- handler,
- (void *) eap_opaque_free);
- rad_assert(rcode == 0);
+ status = request_data_add(request,
+ inst, REQUEST_DATA_eap_handler_t,
+ handler, (void *) eap_opaque_free);
+ rad_assert(status == 0);
return RLM_MODULE_HANDLED;
}
* send a response.
*/
handler->inst_holder = inst;
- rcode = request_data_add(request,
- inst, REQUEST_DATA_EAP_HANDLER,
- handler,
- (void *) eap_opaque_free);
- rad_assert(rcode == 0);
+ status = request_data_add(request,
+ inst, REQUEST_DATA_eap_handler_t,
+ handler,
+ (void *) eap_opaque_free);
+ rad_assert(status == 0);
/*
* Some simple sanity checks. These should really
* We are done, wrap the EAP-request in RADIUS to send
* with all other required radius attributes
*/
- module_rcode = eap_compose(handler);
+ rcode = eap_compose(handler);
/*
* Add to the list only if it is EAP-Request, OR if
* it's LEAP, and a response.
*/
if (((handler->eap_ds->request->code == PW_EAP_REQUEST) &&
- (handler->eap_ds->request->type.type >= PW_EAP_MD5)) ||
+ (handler->eap_ds->request->type.num >= PW_EAP_MD5)) ||
/*
* LEAP is a little different. At Stage 4,
* isn't put into the list.
*/
((handler->eap_ds->response->code == PW_EAP_RESPONSE) &&
- (handler->eap_ds->response->type.type == PW_EAP_LEAP) &&
+ (handler->eap_ds->response->type.num == PW_EAP_LEAP) &&
(handler->eap_ds->request->code == PW_EAP_SUCCESS) &&
- (handler->eap_ds->request->type.type == 0))) {
+ (handler->eap_ds->request->type.num == 0))) {
/*
* Return FAIL if we can't remember the handler.
}
}
- return module_rcode;
+ return rcode;
}
/*
* each EAP sub-module to look for handler->request->username,
* and to get excited if it doesn't appear.
*/
-
vp = pairfind(request->config_items, PW_AUTH_TYPE, 0, TAG_ANY);
- if ((!vp) ||
- (vp->vp_integer != PW_AUTHTYPE_REJECT)) {
+ if ((!vp) || (vp->vp_integer != PW_AUTHTYPE_REJECT)) {
vp = pairmake("Auth-Type", inst->xlat_name, T_OP_EQ);
if (!vp) {
RDEBUG2("Failed to create Auth-Type %s: %s\n",
size_t i;
size_t len;
VALUE_PAIR *vp;
- EAP_HANDLER *handler;
+ eap_handler_t *handler;
/*
* Just in case the admin lists EAP in post-proxy-type Fail.
* If there was a handler associated with this request,
* then it's a tunneled request which was proxied...
*/
- handler = request_data_get(request, inst, REQUEST_DATA_EAP_HANDLER);
+ handler = request_data_get(request, inst, REQUEST_DATA_eap_handler_t);
if (handler != NULL) {
rlm_rcode_t rcode;
eap_tunnel_data_t *data;
* it's LEAP, and a response.
*/
if ((handler->eap_ds->request->code == PW_EAP_REQUEST) &&
- (handler->eap_ds->request->type.type >= PW_EAP_MD5)) {
+ (handler->eap_ds->request->type.num >= PW_EAP_MD5)) {
if (!eaplist_add(inst, handler)) {
eap_fail(handler);
eap_handler_free(inst, handler);
{
rlm_eap_t *inst = instance;
VALUE_PAIR *vp;
- EAP_HANDLER *handler;
+ eap_handler_t *handler;
eap_packet_raw_t *eap_packet;
/*
/*
* Keep track of which sub modules we've loaded.
*/
-typedef struct eap_types_t {
- const char *typename;
- EAP_TYPE *type;
- lt_dlhandle handle;
- CONF_SECTION *cs;
- void *type_data;
-} EAP_TYPES;
+typedef struct eap_module {
+ const char *typename;
+ rlm_eap_module_t *type;
+ lt_dlhandle handle;
+ CONF_SECTION *cs;
+ void *instance;
+} eap_module_t;
/*
* This structure contains eap's persistent data.
* types = All supported EAP-Types
* mutex = ensure only one thread is updating the sessions[] struct
*/
-typedef struct rlm_eap_t {
+typedef struct rlm_eap {
rbtree_t *session_tree;
- EAP_HANDLER *session_head, *session_tail;
+ eap_handler_t *session_head, *session_tail;
rbtree_t *handler_tree; /* for debugging only */
- EAP_TYPES *types[PW_EAP_MAX_TYPES];
+ eap_module_t *methods[PW_EAP_MAX_TYPES];
/*
* Configuration items.
*/
int timer_limit;
- char *default_eap_type_name;
- int default_eap_type;
- int ignore_unknown_eap_types;
+
+ const char *default_method_name;
+ eap_type_t default_method;
+
+ int ignore_unknown_types;
int cisco_accounting_username_bug;
+
int max_sessions;
#ifdef HAVE_PTHREAD_H
/* function definitions */
/* EAP-Type */
-int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs);
-int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *h);
+int eap_module_load(eap_module_t **instance, eap_type_t method,
+ CONF_SECTION *cs);
+eap_code_t eap_method_select(rlm_eap_t *inst, eap_handler_t *handler);
/* EAP */
int eap_start(rlm_eap_t *inst, REQUEST *request);
-void eap_fail(EAP_HANDLER *handler);
-void eap_success(EAP_HANDLER *handler);
-rlm_rcode_t eap_compose(EAP_HANDLER *handler);
-EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_raw_t **eap_msg, REQUEST *request);
+void eap_fail(eap_handler_t *handler);
+void eap_success(eap_handler_t *handler);
+rlm_rcode_t eap_compose(eap_handler_t *handler);
+eap_handler_t *eap_handler(rlm_eap_t *inst, eap_packet_raw_t **eap_msg, REQUEST *request);
/* Memory Management */
eap_packet_t *eap_packet_alloc(void);
EAP_DS *eap_ds_alloc(void);
-EAP_HANDLER *eap_handler_alloc(rlm_eap_t *inst);
+eap_handler_t *eap_handler_alloc(rlm_eap_t *inst);
void eap_packet_free(eap_packet_t **eap_packet);
void eap_ds_free(EAP_DS **eap_ds);
-void eap_opaque_free(EAP_HANDLER *handler);
-void eap_handler_free(rlm_eap_t *inst, EAP_HANDLER *handler);
+void eap_opaque_free(eap_handler_t *handler);
+void eap_handler_free(rlm_eap_t *inst, eap_handler_t *handler);
-int eaplist_add(rlm_eap_t *inst, EAP_HANDLER *handler);
-EAP_HANDLER *eaplist_find(rlm_eap_t *inst, REQUEST *request,
+int eaplist_add(rlm_eap_t *inst, eap_handler_t *handler);
+eap_handler_t *eaplist_find(rlm_eap_t *inst, REQUEST *request,
eap_packet_raw_t *eap_packet);
void eaplist_free(rlm_eap_t *inst);
/*
* Initiate the EAP-GTC session by sending a challenge to the peer.
*/
-static int gtc_initiate(void *type_data, EAP_HANDLER *handler)
+static int gtc_initiate(void *instance, eap_handler_t *handler)
{
char challenge_str[1024];
int length;
EAP_DS *eap_ds = handler->eap_ds;
- rlm_eap_gtc_t *inst = (rlm_eap_gtc_t *) type_data;
+ rlm_eap_gtc_t *inst = (rlm_eap_gtc_t *) instance;
if (!radius_xlat(challenge_str, sizeof(challenge_str), inst->challenge, handler->request, NULL, NULL)) {
radlog(L_ERR, "rlm_eap_gtc: xlat of \"%s\" failed", inst->challenge);
/*
* Authenticate a previously sent challenge.
*/
-static int gtc_authenticate(void *type_data, EAP_HANDLER *handler)
+static int gtc_authenticate(void *instance, eap_handler_t *handler)
{
VALUE_PAIR *vp;
EAP_DS *eap_ds = handler->eap_ds;
- rlm_eap_gtc_t *inst = (rlm_eap_gtc_t *) type_data;
+ rlm_eap_gtc_t *inst = (rlm_eap_gtc_t *) instance;
REQUEST *request = handler->request;
/*
* The module name should be the only globally exported symbol.
* That is, everything else should be 'static'.
*/
-EAP_TYPE rlm_eap_gtc = {
+rlm_eap_module_t rlm_eap_gtc = {
"eap_gtc",
gtc_attach, /* attach */
gtc_initiate, /* Start the initial request */
pairadd(vp, reply_attr);
}
-static int set_mppe_keys(EAP_HANDLER *handler)
+static int set_mppe_keys(eap_handler_t *handler)
{
unsigned char *p;
struct IKEv2Session *session;
// Compose Radius like message from table of output bytes
static int ComposeRadMsg(uint8_t *out,u_int32_t olen, EAP_DS *eap_ds){
- eap_ds->request->type.type = PW_EAP_IKEV2;
+ eap_ds->request->type.num = PW_EAP_IKEV2;
eap_ds->request->code = ((struct EAPHeader *)out)->Code;
if(eap_ds->request->code<=PW_EAP_REQUEST && olen>4) {
int lenn=(int)ntohs(((struct EAPHeader *)out)->Length);
* Free memory after EAP-IKEv2 module usage
*/
-static int ikev2_detach(void *type_data)
+static int ikev2_detach(void *instance)
{
- struct ikev2_ctx *data = (struct ikev2_ctx *) type_data;
+ struct ikev2_ctx *data = (struct ikev2_ctx *) instance;
if (data) {
Free_ikev2_ctx(data);
data=NULL;
* Configure EAP-ikev2 handler
*/
-static int ikev2_attach(CONF_SECTION *conf, void **type_data)
+static int ikev2_attach(CONF_SECTION *conf, void **instance)
{
char *default_authtype=NULL;
char *usersfilename=NULL;
if (i2 == NULL) {
return -1;
}
- *type_data =i2;
+ *instance =i2;
if (cf_section_parse(conf,i2, module_config) < 0) {
return -1;
*/
-static int ikev2_initiate(void *type_data, EAP_HANDLER *handler)
+static int ikev2_initiate(void *instance, eap_handler_t *handler)
{
radlog( L_INFO,IKEv2_LOG_PREFIX "Initiate connection!");
// This is the way for silent discarding behavior
// handler->request->reply->code=0;
// return 0;
- struct ikev2_ctx *i2=(struct ikev2_ctx*)type_data;
+ struct ikev2_ctx *i2=(struct ikev2_ctx*)instance;
struct IKEv2Session *session;
/*
* Authenticate a previously sent challenge.
*/
-static int ikev2_authenticate(void *type_data, EAP_HANDLER *handler)
+static int ikev2_authenticate(void *instance, eap_handler_t *handler)
{
- struct ikev2_ctx *i2=(struct ikev2_ctx*)type_data;
+ struct ikev2_ctx *i2=(struct ikev2_ctx*)instance;
radlog( L_INFO, IKEv2_LOG_PREFIX "authenticate" );
rad_assert(handler->request != NULL);
if (!eap_ds ||
!eap_ds->response ||
(eap_ds->response->code != PW_IKEV2_RESPONSE) ||
- eap_ds->response->type.type != PW_EAP_IKEV2 ||
+ eap_ds->response->type.num != PW_EAP_IKEV2 ||
!eap_ds->response->type.data){
radlog(L_ERR, IKEv2_LOG_PREFIX "corrupted data");
return -1;
hdr->Code=eap_ds->response->code;
hdr->Id=eap_ds->response->id;
hdr->Length=htons(eap_ds->response->length);
- hdr->Type=eap_ds->response->type.type;
+ hdr->Type=eap_ds->response->type.num;
memcpy(in+5,eap_ds->response->type.data,eap_ds->response->length-5);
//koniec: skladanie pakietu
* The module name should be the only globally exported symbol.
* That is, everything else should be 'static'.
*/
-EAP_TYPE rlm_eap_ikev2 = {
+rlm_eap_module_t rlm_eap_ikev2 = {
"eap_ikev2",
ikev2_attach, /* attach */
ikev2_initiate, /* Start the initial request */
#include "eap_leap.h"
/*
- * Allocate a new Leap_packet_t
+ * Allocate a new leap_packet_t
*/
-Leap_packet_t *eapleap_alloc(void)
+leap_packet_t *eapleap_alloc(void)
{
- Leap_packet_t *rp;
+ leap_packet_t *rp;
- if ((rp = malloc(sizeof(Leap_packet_t))) == NULL) {
+ if ((rp = malloc(sizeof(leap_packet_t))) == NULL) {
radlog(L_ERR, "rlm_eap_leap: out of memory");
return NULL;
}
- memset(rp, 0, sizeof(Leap_packet_t));
+ memset(rp, 0, sizeof(leap_packet_t));
return rp;
}
/*
- * Free Leap_packet_t
+ * Free leap_packet_t
*/
-void eapleap_free(Leap_packet_t **leap_packet_ptr)
+void eapleap_free(leap_packet_t **leap_packet_ptr)
{
- Leap_packet_t *leap_packet;
+ leap_packet_t *leap_packet;
if (!leap_packet_ptr) return;
leap_packet = *leap_packet_ptr;
/*
* Extract the data from the LEAP packet.
*/
-Leap_packet_t *eapleap_extract(EAP_DS *eap_ds)
+leap_packet_t *eapleap_extract(EAP_DS *eap_ds)
{
leap_packet_raw_t *data;
- Leap_packet_t *packet;
+ leap_packet_t *packet;
int name_len;
/*
!eap_ds->response ||
((eap_ds->response->code != PW_EAP_RESPONSE) &&
(eap_ds->response->code != PW_EAP_REQUEST)) ||
- eap_ds->response->type.type != PW_EAP_LEAP ||
+ eap_ds->response->type.num != PW_EAP_LEAP ||
!eap_ds->response->type.data ||
(eap_ds->response->length < LEAP_HEADER_LEN) ||
(eap_ds->response->type.data[0] != 0x01)) { /* version 1 */
/*
* Verify the MS-CHAP response from the user.
*/
-int eapleap_stage4(Leap_packet_t *packet, VALUE_PAIR* password,
+int eapleap_stage4(leap_packet_t *packet, VALUE_PAIR* password,
leap_session_t *session)
{
unsigned char ntpwdhash[16];
/*
* Verify ourselves to the AP
*/
-Leap_packet_t *eapleap_stage6(Leap_packet_t *packet, REQUEST *request,
+leap_packet_t *eapleap_stage6(leap_packet_t *packet, REQUEST *request,
VALUE_PAIR *user_name, VALUE_PAIR* password,
leap_session_t *session, VALUE_PAIR **reply_vps)
{
size_t i;
unsigned char ntpwdhash[16], ntpwdhashhash[16];
unsigned char buffer[256];
- Leap_packet_t *reply;
+ leap_packet_t *reply;
unsigned char *p;
VALUE_PAIR *vp;
* If an EAP LEAP request needs to be initiated then
* create such a packet.
*/
-Leap_packet_t *eapleap_initiate(UNUSED EAP_DS *eap_ds, VALUE_PAIR *user_name)
+leap_packet_t *eapleap_initiate(UNUSED EAP_DS *eap_ds, VALUE_PAIR *user_name)
{
int i;
- Leap_packet_t *reply;
+ leap_packet_t *reply;
reply = eapleap_alloc();
if (reply == NULL) {
/*
* compose the LEAP reply packet in the EAP reply typedata
*/
-int eapleap_compose(EAP_DS *eap_ds, Leap_packet_t *reply)
+int eapleap_compose(EAP_DS *eap_ds, leap_packet_t *reply)
{
leap_packet_raw_t *data;
switch (reply->code) {
case PW_EAP_REQUEST:
case PW_EAP_RESPONSE:
- eap_ds->request->type.type = PW_EAP_LEAP;
+ eap_ds->request->type.num = PW_EAP_LEAP;
eap_ds->request->type.length = reply->length;
eap_ds->request->type.data = malloc(reply->length);
unsigned char *challenge;
int name_len;
char *name;
-} Leap_packet_t;
+} leap_packet_t;
/*
* The information which must be kept around
/* function declarations here */
-Leap_packet_t *eapleap_alloc(void);
-void eapleap_free(Leap_packet_t **leap_packet_ptr);
+leap_packet_t *eapleap_alloc(void);
+void eapleap_free(leap_packet_t **leap_packet_ptr);
-int eapleap_compose(EAP_DS *auth, Leap_packet_t *reply);
-Leap_packet_t *eapleap_extract(EAP_DS *auth);
-Leap_packet_t *eapleap_initiate(EAP_DS *eap_ds, VALUE_PAIR *user_name);
-int eapleap_stage4(Leap_packet_t *packet, VALUE_PAIR* password,
+int eapleap_compose(EAP_DS *auth, leap_packet_t *reply);
+leap_packet_t *eapleap_extract(EAP_DS *auth);
+leap_packet_t *eapleap_initiate(EAP_DS *eap_ds, VALUE_PAIR *user_name);
+int eapleap_stage4(leap_packet_t *packet, VALUE_PAIR* password,
leap_session_t *session);
-Leap_packet_t *eapleap_stage6(Leap_packet_t *packet, REQUEST *request,
+leap_packet_t *eapleap_stage6(leap_packet_t *packet, REQUEST *request,
VALUE_PAIR *user_name, VALUE_PAIR* password,
leap_session_t *session,
VALUE_PAIR **reply_vps);
* ie access challenge to the user/peer.
* Frame eap reply packet.
- * len = header + type + leap_typedata
- * leap_typedata = value_size + value
+ * len = header + type + leap_methoddata
+ * leap_methoddata = value_size + value
*/
-static int leap_initiate(UNUSED void *instance, EAP_HANDLER *handler)
+static int leap_initiate(UNUSED void *instance, eap_handler_t *handler)
{
leap_session_t *session;
- Leap_packet_t *reply;
+ leap_packet_t *reply;
DEBUG2(" rlm_eap_leap: Stage 2");
return 1;
}
-static int leap_authenticate(UNUSED void *instance, EAP_HANDLER *handler)
+static int leap_authenticate(UNUSED void *instance, eap_handler_t *handler)
{
int rcode;
leap_session_t *session;
- Leap_packet_t *packet;
- Leap_packet_t *reply;
+ leap_packet_t *packet;
+ leap_packet_t *reply;
VALUE_PAIR *password;
if (!handler->opaque) {
* The module name should be the only globally exported symbol.
* That is, everything else should be 'static'.
*/
-EAP_TYPE rlm_eap_leap = {
+rlm_eap_module_t rlm_eap_leap = {
"eap_leap",
NULL, /* attach */
leap_initiate, /* Start the initial request, after Identity */
if (!eap_ds ||
!eap_ds->response ||
(eap_ds->response->code != PW_MD5_RESPONSE) ||
- eap_ds->response->type.type != PW_EAP_MD5 ||
+ eap_ds->response->type.num != PW_EAP_MD5 ||
!eap_ds->response->type.data ||
(eap_ds->response->length <= MD5_HEADER_LEN) ||
(eap_ds->response->type.data[0] <= 0)) {
* and EAP-Success, and EAP-Failure.
*/
if (reply->code < 3) {
- eap_ds->request->type.type = PW_EAP_MD5;
+ eap_ds->request->type.num = PW_EAP_MD5;
rad_assert(reply->length > 0);
/*
* Initiate the EAP-MD5 session by sending a challenge to the peer.
*/
-static int md5_initiate(void *type_data, EAP_HANDLER *handler)
+static int md5_initiate(void *instance, eap_handler_t *handler)
{
int i;
MD5_PACKET *reply;
- type_data = type_data; /* -Wunused */
+ instance = instance; /* -Wunused */
/*
* Allocate an EAP-MD5 packet.
/*
* Authenticate a previously sent challenge.
*/
-static int md5_authenticate(UNUSED void *arg, EAP_HANDLER *handler)
+static int md5_authenticate(UNUSED void *arg, eap_handler_t *handler)
{
MD5_PACKET *packet;
MD5_PACKET *reply;
* The module name should be the only globally exported symbol.
* That is, everything else should be 'static'.
*/
-EAP_TYPE rlm_eap_md5 = {
+rlm_eap_module_t rlm_eap_md5 = {
"eap_md5",
NULL, /* attach */
md5_initiate, /* Start the initial request */
};
-static void fix_mppe_keys(EAP_HANDLER *handler, mschapv2_opaque_t *data)
+static void fix_mppe_keys(eap_handler_t *handler, mschapv2_opaque_t *data)
{
pairmove2(&data->mppe_keys, &handler->request->reply->vps, 7, VENDORPEC_MICROSOFT, TAG_ANY);
pairmove2(&data->mppe_keys, &handler->request->reply->vps, 8, VENDORPEC_MICROSOFT, TAG_ANY);
/*
* Compose the response.
*/
-static int eapmschapv2_compose(EAP_HANDLER *handler, VALUE_PAIR *reply)
+static int eapmschapv2_compose(eap_handler_t *handler, VALUE_PAIR *reply)
{
uint8_t *ptr;
int16_t length;
EAP_DS *eap_ds = handler->eap_ds;
eap_ds->request->code = PW_EAP_REQUEST;
- eap_ds->request->type.type = PW_EAP_MSCHAPV2;
+ eap_ds->request->type.num = PW_EAP_MSCHAPV2;
/*
* Always called with vendor Microsoft
/*
* Initiate the EAP-MSCHAPV2 session by sending a challenge to the peer.
*/
-static int mschapv2_initiate(void *type_data, EAP_HANDLER *handler)
+static int mschapv2_initiate(void *instance, eap_handler_t *handler)
{
int i;
VALUE_PAIR *challenge;
mschapv2_opaque_t *data;
- type_data = type_data; /* -Wunused */
+ instance = instance; /* -Wunused */
challenge = pairmake("MS-CHAP-Challenge", "0x00", T_OP_EQ);
if (!challenge) {
*
* Called from rlm_eap.c, eap_postproxy().
*/
-static int mschap_postproxy(EAP_HANDLER *handler, void *tunnel_data)
+static int mschap_postproxy(eap_handler_t *handler, void *tunnel_data)
{
VALUE_PAIR *response = NULL;
mschapv2_opaque_t *data;
/*
* Authenticate a previously sent challenge.
*/
-static int mschapv2_authenticate(void *arg, EAP_HANDLER *handler)
+static int mschapv2_authenticate(void *arg, eap_handler_t *handler)
{
int rcode, ccode;
mschapv2_opaque_t *data;
* The module name should be the only globally exported symbol.
* That is, everything else should be 'static'.
*/
-EAP_TYPE rlm_eap_mschapv2 = {
+rlm_eap_module_t rlm_eap_mschapv2 = {
"eap_mschapv2",
mschapv2_attach, /* attach */
mschapv2_initiate, /* Start the initial request */
VALUE_PAIR *accept_vps;
int status;
int home_access_accept;
- int default_eap_type;
+ int default_method;
int copy_request_to_tunnel;
int use_tunneled_reply;
int proxy_tunneled_request_as_eap;
/*
* Process the PEAP portion of an EAP-PEAP request.
*/
-int eappeap_process(EAP_HANDLER *handler, tls_session_t *tls_session);
+int eappeap_process(eap_handler_t *handler, tls_session_t *tls_session);
#endif /* _EAP_PEAP_H */
*
* Result-TLV = Failure
*/
-static int eappeap_failure(EAP_HANDLER *handler, tls_session_t *tls_session)
+static int eappeap_failure(eap_handler_t *handler, tls_session_t *tls_session)
{
uint8_t tlv_packet[11];
REQUEST *request = handler->request;
*
* Result-TLV = Success
*/
-static int eappeap_success(EAP_HANDLER *handler, tls_session_t *tls_session)
+static int eappeap_success(eap_handler_t *handler, tls_session_t *tls_session)
{
uint8_t tlv_packet[11];
REQUEST *request = handler->request;
}
-static int eappeap_identity(EAP_HANDLER *handler, tls_session_t *tls_session)
+static int eappeap_identity(eap_handler_t *handler, tls_session_t *tls_session)
{
eap_packet_raw_t eap_packet;
/*
* Send an MS SoH request
*/
-static int eappeap_soh(EAP_HANDLER *handler, tls_session_t *tls_session)
+static int eappeap_soh(eap_handler_t *handler, tls_session_t *tls_session)
{
uint8_t tlv_packet[20];
static VALUE_PAIR* eapsoh_verify(REQUEST *request, const uint8_t *data, unsigned int data_len) {
VALUE_PAIR *vp;
- uint8_t eap_type_base;
+ uint8_t eap_method_base;
uint32_t eap_vendor;
- uint32_t eap_type;
+ uint32_t eap_method;
int rv;
vp = pairmake("SoH-Supported", "no", T_OP_EQ);
goto done;
}
- eap_type_base = *data++;
- if (eap_type_base != 254) {
- RDEBUG("SoH - response is not extended EAP: %i", eap_type_base);
+ eap_method_base = *data++;
+ if (eap_method_base != 254) {
+ RDEBUG("SoH - response is not extended EAP: %i", eap_method_base);
goto done;
}
goto done;
}
- eap_type = soh_pull_be_32(data); data += 4;
- if (eap_type != 0x21) {
- RDEBUG("SoH - response eap type %08x is not EAP-SoH", eap_type);
+ eap_method = soh_pull_be_32(data); data += 4;
+ if (eap_method != 0x21) {
+ RDEBUG("SoH - response eap type %08x is not EAP-SoH", eap_method);
goto done;
}
const uint8_t *data, unsigned int data_len)
{
const eap_packet_raw_t *eap_packet = (const eap_packet_raw_t *) data;
- uint8_t eap_type;
- char buffer[256];
+ eap_type_t eap_method;
/*
* No data, OR only 1 byte of EAP type.
return 0;
}
- eap_type = *data;
- switch (eap_type) {
+ eap_method = *data;
+ switch (eap_method) {
case PW_EAP_IDENTITY:
if (data_len == 1) {
RDEBUG2("Identity - ");
*/
case PW_EAP_MSCHAPV2:
default:
- RDEBUG2("EAP type %s",
- eap_type_data_type2name(eap_type,
- buffer, sizeof(buffer)));
+ RDEBUG2("EAP type %s (%d)", eap_type2name(eap_method),
+ eap_method);
return 1;
break;
}
/*
* Use a reply packet to determine what to do.
*/
-static int process_reply(EAP_HANDLER *handler, tls_session_t *tls_session,
+static int process_reply(eap_handler_t *handler, tls_session_t *tls_session,
REQUEST *request, RADIUS_PACKET *reply)
{
int rcode = RLM_MODULE_REJECT;
/*
* Do post-proxy processing,
*/
-static int eappeap_postproxy(EAP_HANDLER *handler, void *data)
+static int eappeap_postproxy(eap_handler_t *handler, void *data)
{
int rcode;
tls_session_t *tls_session = (tls_session_t *) data;
/*
* Process the pseudo-EAP contents of the tunneled data.
*/
-int eappeap_process(EAP_HANDLER *handler, tls_session_t *tls_session)
+int eappeap_process(eap_handler_t *handler, tls_session_t *tls_session)
{
peap_tunnel_t *t = tls_session->opaque;
REQUEST *fake;
pairadd(&fake->packet->vps, vp);
- if (t->default_eap_type != 0) {
+ if (t->default_method != 0) {
RDEBUG2("Setting default EAP type for tunneled EAP session.");
vp = pairmake("EAP-Type", "0", T_OP_EQ);
- vp->vp_integer = t->default_eap_type;
+ vp->vp_integer = t->default_method;
pairadd(&fake->config_items, vp);
}
break; }
* If there's a default EAP type,
* set it here.
*/
- if (t->default_eap_type != 0) {
+ if (t->default_method != 0) {
DEBUG2(" PEAP: Setting default EAP type for tunneled EAP session.");
vp = pairmake("EAP-Type", "0", T_OP_EQ);
- vp->vp_integer = t->default_eap_type;
+ vp->vp_integer = t->default_method;
pairadd(&fake->config_items, vp);
}
}
/*
* Default tunneled EAP type
*/
- char *default_eap_type_name;
- int default_eap_type;
+ char *default_method_name;
+ int default_method;
/*
* Use the reply attributes from the tunneled session in
{ "tls", PW_TYPE_STRING_PTR,
offsetof(rlm_eap_peap_t, tls_conf_name), NULL, NULL },
- { "default_eap_type", PW_TYPE_STRING_PTR,
- offsetof(rlm_eap_peap_t, default_eap_type_name), NULL, "mschapv2" },
+ { "default_method", PW_TYPE_STRING_PTR,
+ offsetof(rlm_eap_peap_t, default_method_name), NULL, "mschapv2" },
{ "copy_request_to_tunnel", PW_TYPE_BOOLEAN,
offsetof(rlm_eap_peap_t, copy_request_to_tunnel), NULL, "no" },
* Convert the name to an integer, to make it easier to
* handle.
*/
- inst->default_eap_type = eaptype_name2type(inst->default_eap_type_name);
- if (inst->default_eap_type < 0) {
+ inst->default_method = eap_name2type(inst->default_method_name);
+ if (inst->default_method < 0) {
radlog(L_ERR, "rlm_eap_peap: Unknown EAP type %s",
- inst->default_eap_type_name);
+ inst->default_method_name);
return -1;
}
t = rad_malloc(sizeof(*t));
memset(t, 0, sizeof(*t));
- t->default_eap_type = inst->default_eap_type;
+ t->default_method = inst->default_method;
t->copy_request_to_tunnel = inst->copy_request_to_tunnel;
t->use_tunneled_reply = inst->use_tunneled_reply;
#ifdef WITH_PROXY
/*
* Send an initial eap-tls request to the peer, using the libeap functions.
*/
-static int eappeap_initiate(void *type_arg, EAP_HANDLER *handler)
+static int eappeap_initiate(void *type_arg, eap_handler_t *handler)
{
int status;
tls_session_t *ssn;
/*
* Do authentication, by letting EAP-TLS do most of the work.
*/
-static int eappeap_authenticate(void *arg, EAP_HANDLER *handler)
+static int eappeap_authenticate(void *arg, eap_handler_t *handler)
{
int rcode;
fr_tls_status_t status;
* The module name should be the only globally exported symbol.
* That is, everything else should be 'static'.
*/
-EAP_TYPE rlm_eap_peap = {
+rlm_eap_module_t rlm_eap_peap = {
"eap_peap",
eappeap_attach, /* attach */
eappeap_initiate, /* Start the initial request */
len = (sess->out_buf_len - sess->out_buf_pos) + sizeof(pwd_hdr);
rad_assert(len > 0);
eap_ds->request->code = PW_EAP_REQUEST;
- eap_ds->request->type.type = PW_EAP_PWD;
+ eap_ds->request->type.num = PW_EAP_PWD;
eap_ds->request->type.length = (len > sess->mtu) ? sess->mtu : len;
eap_ds->request->type.data = malloc(eap_ds->request->type.length);
memset(eap_ds->request->type.data, 0, eap_ds->request->type.length);
}
static int
-eap_pwd_initiate (void *type_data, EAP_HANDLER *handler)
+eap_pwd_initiate (void *instance, eap_handler_t *handler)
{
pwd_session_t *pwd_session;
- eap_pwd_t *inst = (eap_pwd_t *)type_data;
+ eap_pwd_t *inst = (eap_pwd_t *)instance;
VALUE_PAIR *vp;
pwd_id_packet *pack;
}
static int
-eap_pwd_authenticate (void *arg, EAP_HANDLER *handler)
+eap_pwd_authenticate (void *arg, eap_handler_t *handler)
{
pwd_session_t *pwd_session;
pwd_hdr *hdr;
*/
exch = EAP_PWD_GET_EXCHANGE(hdr);
eap_ds->request->code = PW_EAP_REQUEST;
- eap_ds->request->type.type = PW_EAP_PWD;
+ eap_ds->request->type.num = PW_EAP_PWD;
eap_ds->request->type.length = sizeof(pwd_hdr);
if ((eap_ds->request->type.data = malloc(sizeof(pwd_hdr))) == NULL) {
radlog(L_ERR, "rlm_eap_pwd: fragment ACK, out of memory");
}
-EAP_TYPE rlm_eap_pwd = {
+rlm_eap_module_t rlm_eap_pwd = {
"eap_pwd",
eap_pwd_attach, /* attach */
eap_pwd_initiate, /* initiate to a client */
/*
* build a reply to be sent.
*/
-static int eap_sim_compose(EAP_HANDLER *handler)
+static int eap_sim_compose(eap_handler_t *handler)
{
/* we will set the ID on requests, since we have to HMAC it */
handler->eap_ds->set_request_id = 1;
handler->eap_ds->request);
}
-static int eap_sim_sendstart(EAP_HANDLER *handler)
+static int eap_sim_sendstart(eap_handler_t *handler)
{
VALUE_PAIR **vps, *newvp;
uint16_t *words;
* module to generate/calculate things.
*
*/
-static int eap_sim_sendchallenge(EAP_HANDLER *handler)
+static int eap_sim_sendchallenge(eap_handler_t *handler)
{
struct eap_sim_server_state *ess;
VALUE_PAIR **invps, **outvps, *newvp;
* radius attributes derived from the MSK.
*
*/
-static int eap_sim_sendsuccess(EAP_HANDLER *handler)
+static int eap_sim_sendsuccess(eap_handler_t *handler)
{
unsigned char *p;
struct eap_sim_server_state *ess;
/*
* run the server state machine.
*/
-static void eap_sim_stateenter(EAP_HANDLER *handler,
+static void eap_sim_stateenter(eap_handler_t *handler,
struct eap_sim_server_state *ess,
enum eapsim_serverstates newstate)
{
* Initiate the EAP-SIM session by starting the state machine
* and initiating the state.
*/
-static int eap_sim_initiate(void *type_data, EAP_HANDLER *handler)
+static int eap_sim_initiate(void *instance, eap_handler_t *handler)
{
struct eap_sim_server_state *ess;
VALUE_PAIR *vp;
outvps = handler->request->reply->vps;
- type_data = type_data; /* shut up compiler */
+ instance = instance; /* shut up compiler */
vp = pairfind(outvps, ATTRIBUTE_EAP_SIM_RAND1, 0, TAG_ANY);
if(vp == NULL) {
* challenge, else, resend the Request/Start.
*
*/
-static int process_eap_sim_start(EAP_HANDLER *handler, VALUE_PAIR *vps)
+static int process_eap_sim_start(eap_handler_t *handler, VALUE_PAIR *vps)
{
VALUE_PAIR *nonce_vp, *selectedversion_vp;
struct eap_sim_server_state *ess;
* calculated from the packet with the SRESx appended.
*
*/
-static int process_eap_sim_challenge(EAP_HANDLER *handler, VALUE_PAIR *vps)
+static int process_eap_sim_challenge(eap_handler_t *handler, VALUE_PAIR *vps)
{
struct eap_sim_server_state *ess;
uint8_t srescat[EAPSIM_SRES_SIZE*3];
/*
* Authenticate a previously sent challenge.
*/
-static int eap_sim_authenticate(void *arg, EAP_HANDLER *handler)
+static int eap_sim_authenticate(void *arg, eap_handler_t *handler)
{
struct eap_sim_server_state *ess;
VALUE_PAIR *vp, *vps;
* The module name should be the only globally exported symbol.
* That is, everything else should be 'static'.
*/
-EAP_TYPE rlm_eap_sim = {
+rlm_eap_module_t rlm_eap_sim = {
"eap_sim",
NULL, /* XXX attach */
eap_sim_initiate, /* Start the initial request */
/*
* Send an initial eap-tls request to the peer, using the libeap functions.
*/
-static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler)
+static int eaptls_initiate(void *type_arg, eap_handler_t *handler)
{
int status;
tls_session_t *ssn;
/*
* Do authentication, by letting EAP-TLS do most of the work.
*/
-static int eaptls_authenticate(void *type_arg, EAP_HANDLER *handler)
+static int eaptls_authenticate(void *type_arg, eap_handler_t *handler)
{
fr_tls_status_t status;
tls_session_t *tls_session = (tls_session_t *) handler->opaque;
* The module name should be the only globally exported symbol.
* That is, everything else should be 'static'.
*/
-EAP_TYPE rlm_eap_tls = {
+rlm_eap_module_t rlm_eap_tls = {
"eap_tls",
eaptls_attach, /* attach */
eaptls_initiate, /* Start the initial request */
* For this package, only 'Identifier' has to be set dynamically. Any
* other information is static.
*/
-static int tnc_initiate(void *instance, EAP_HANDLER *handler)
+static int tnc_initiate(void *instance, eap_handler_t *handler)
{
rlm_eap_tnc_t *inst = instance;
REQUEST *request = NULL;
*eap_tnc_request = SET_START(1);
handler->eap_ds->request->code = PW_EAP_REQUEST;
- handler->eap_ds->request->type.type = PW_EAP_TNC;
+ handler->eap_ds->request->type.num = PW_EAP_TNC;
handler->eap_ds->request->type.length = 1;
* based on the TNC_ConnectionState determined by NAA-TNCS.
*
* @param instance The configuration data.
- * @param handler The EAP_HANDLER.
+ * @param handler The eap_handler_t.
* @return True, if successfully, else false.
*/
-static int tnc_authenticate(UNUSED void *instance, EAP_HANDLER *handler)
+static int tnc_authenticate(UNUSED void *instance, eap_handler_t *handler)
{
TNC_ConnectionID conn_id;
TNC_Result result;
TNC_ConnectionState connection_state;
uint8_t code = 0;
- if (handler->eap_ds->response->type.type != PW_EAP_TNC) {
+ if (handler->eap_ds->response->type.num != PW_EAP_TNC) {
radlog(L_ERR, "rlm_eap_tnc: Incorrect response type");
return 0;
code = PW_EAP_SUCCESS;
pairadd(&handler->request->config_items,
pairmake("TNC-Status", "Access", T_OP_SET));
-
break;
case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
* Build the TNC EAP request
*/
handler->eap_ds->request->code = code;
- handler->eap_ds->request->type.type = PW_EAP_TNC;
+ handler->eap_ds->request->type.num = PW_EAP_TNC;
handler->eap_ds->request->type.length = datalen;
* The module name should be the only globally exported symbol.
* That is, everything else should be 'static'.
*/
-EAP_TYPE rlm_eap_tnc = {
+rlm_eap_module_t rlm_eap_tnc = {
"eap_tnc",
tnc_attach, /* attach */
tnc_initiate, /* Start the initial request */
VALUE_PAIR *state;
VALUE_PAIR *accept_vps;
int authenticated;
- int default_eap_type;
+ int default_method;
int copy_request_to_tunnel;
int use_tunneled_reply;
const char *virtual_server;
/*
* Process the TTLS portion of an EAP-TTLS request.
*/
-int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session);
+int eapttls_process(eap_handler_t *handler, tls_session_t *tls_session);
#endif /* _EAP_TTLS_H */
/*
* Default tunneled EAP type
*/
- char *default_eap_type_name;
- int default_eap_type;
+ char *default_method_name;
+ int default_method;
/*
* Use the reply attributes from the tunneled session in
offsetof(rlm_eap_ttls_t, tls_conf_name), NULL, NULL },
{ "default_eap_type", PW_TYPE_STRING_PTR,
- offsetof(rlm_eap_ttls_t, default_eap_type_name), NULL, "md5" },
+ offsetof(rlm_eap_ttls_t, default_method_name), NULL, "md5" },
{ "copy_request_to_tunnel", PW_TYPE_BOOLEAN,
offsetof(rlm_eap_ttls_t, copy_request_to_tunnel), NULL, "no" },
* Convert the name to an integer, to make it easier to
* handle.
*/
- inst->default_eap_type = eaptype_name2type(inst->default_eap_type_name);
- if (inst->default_eap_type < 0) {
+ inst->default_method = eap_name2type(inst->default_method_name);
+ if (inst->default_method < 0) {
radlog(L_ERR, "rlm_eap_ttls: Unknown EAP type %s",
- inst->default_eap_type_name);
+ inst->default_method_name);
return -1;
}
t = rad_malloc(sizeof(*t));
memset(t, 0, sizeof(*t));
- t->default_eap_type = inst->default_eap_type;
+ t->default_method = inst->default_method;
t->copy_request_to_tunnel = inst->copy_request_to_tunnel;
t->use_tunneled_reply = inst->use_tunneled_reply;
t->virtual_server = inst->virtual_server;
/*
* Send an initial eap-tls request to the peer, using the libeap functions.
*/
-static int eapttls_initiate(void *type_arg, EAP_HANDLER *handler)
+static int eapttls_initiate(void *type_arg, eap_handler_t *handler)
{
int status;
tls_session_t *ssn;
/*
* Do authentication, by letting EAP-TLS do most of the work.
*/
-static int eapttls_authenticate(void *arg, EAP_HANDLER *handler)
+static int eapttls_authenticate(void *arg, eap_handler_t *handler)
{
int rcode;
fr_tls_status_t status;
* The module name should be the only globally exported symbol.
* That is, everything else should be 'static'.
*/
-EAP_TYPE rlm_eap_ttls = {
+rlm_eap_module_t rlm_eap_ttls = {
"eap_ttls",
eapttls_attach, /* attach */
eapttls_initiate, /* Start the initial request */
/*
* Use a reply packet to determine what to do.
*/
-static int process_reply(EAP_HANDLER *handler, tls_session_t *tls_session,
+static int process_reply(eap_handler_t *handler, tls_session_t *tls_session,
REQUEST *request, RADIUS_PACKET *reply)
{
int rcode = RLM_MODULE_REJECT;
/*
* Do post-proxy processing,
*/
-static int eapttls_postproxy(EAP_HANDLER *handler, void *data)
+static int eapttls_postproxy(eap_handler_t *handler, void *data)
{
int rcode;
tls_session_t *tls_session = (tls_session_t *) data;
/*
* Process the "diameter" contents of the tunneled data.
*/
-int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
+int eapttls_process(eap_handler_t *handler, tls_session_t *tls_session)
{
int rcode = PW_AUTHENTICATION_REJECT;
REQUEST *fake;
* If there's a default EAP type,
* set it here.
*/
- if (t->default_eap_type != 0) {
+ if (t->default_method != 0) {
RDEBUG("Setting default EAP type for tunneled EAP session.");
vp = paircreate(request, PW_EAP_TYPE, 0);
rad_assert(vp != NULL);
- vp->vp_integer = t->default_eap_type;
+ vp->vp_integer = t->default_method;
pairadd(&fake->config_items, vp);
}
switch (fake->reply->code) {
case 0: /* No reply code, must be proxied... */
#ifdef WITH_PROXY
- vp = pairfind(fake->config_items, PW_PROXY_TO_REALM, 0, TAG_ANY);
+ vp = pairfind(fake->config_items, PW_PROXY_TO_REALM, 0, TAG_ANY);
if (vp) {
eap_tunnel_data_t *tunnel;
RDEBUG("Tunneled authentication will be proxied to %s", vp->vp_strvalue);