#include "rlm_eap.h"
+#include <sys/stat.h>
+
static const CONF_PARSER module_config[] = {
{ "default_eap_type", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_eap_t, default_method_name), "md5" },
{ "timer_expire", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_eap_t, timer_limit), "60" },
{ "ignore_unknown_eap_types", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_eap_t, ignore_unknown_types), "no" },
- { "mod_accounting_username_bug", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_eap_t, mod_accounting_username_bug), "no" },
+ { "cisco_accounting_username_bug", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_eap_t, mod_accounting_username_bug), "no" },
{ "max_sessions", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_eap_t, max_sessions), "2048" },
-
- { NULL, -1, 0, NULL, NULL } /* end the list */
+ CONF_PARSER_TERMINATOR
};
/*
#ifdef HAVE_PTHREAD_H
pthread_mutex_destroy(&(inst->session_mutex));
- if (inst->handler_tree) pthread_mutex_destroy(&(inst->handler_mutex));
#endif
rbtree_free(inst->session_tree);
- if (inst->handler_tree) {
- rbtree_free(inst->handler_tree);
- /*
- * Must be NULL else when nodes are freed they try to
- * delete themselves from the tree.
- */
- inst->handler_tree = NULL;
- }
inst->session_tree = NULL;
eaplist_free(inst);
/*
- * Compare two handler pointers
- */
-static int eap_handler_ptr_cmp(void const *a, void const *b)
-{
- if (a < b) return -1;
- if (a > b) return +1;
- return 0;
-}
-
-
-/*
* read the config section and load all the eap authentication types present.
*/
static int mod_instantiate(CONF_SECTION *cs, void *instance)
inst->xlat_name = cf_section_name2(cs);
if (!inst->xlat_name) inst->xlat_name = "EAP";
+ if (!dict_valbyname(PW_AUTH_TYPE, 0, inst->xlat_name)) {
+ cf_log_err_cs(cs, "Failed to find 'Auth-Type %s' section. Cannot authenticate users.",
+ inst->xlat_name);
+ return -1;
+ }
+
/* Load all the configured EAP-Types */
num_methods = 0;
for(scs = cf_subsection_find_next(cs, NULL, NULL);
scs != NULL;
scs = cf_subsection_find_next(cs, scs, NULL)) {
-
char const *name;
name = cf_section_name1(scs);
if (!strcmp(name, TLS_CONFIG_SECTION)) continue;
+ /*
+ * Easier sometimes than commenting out blocks,
+ * or deleting blocks.
+ */
+ if (!strcmp(name, "disable")) continue;
+
method = eap_name2type(name);
if (method == PW_EAP_INVALID) {
cf_log_err_cs(cs, "No dictionary definition for EAP method %s", name);
* etc. configurations from eap.conf in order to
* have EAP without the TLS types.
*/
- if ((method == PW_EAP_TLS) ||
- (method == PW_EAP_TTLS) ||
- (method == PW_EAP_PEAP)) {
- DEBUG2("rlm_eap (%s): Ignoring EAP method %s because we do not have OpenSSL support",
- inst->xlat_name, name);
+ switch (method) {
+ case PW_EAP_TLS:
+ case PW_EAP_TTLS:
+ case PW_EAP_PEAP:
+ case PW_EAP_PWD:
+ WARN("rlm_eap (%s): Ignoring EAP method %s because we don't have OpenSSL support",
+ inst->xlat_name, name);
continue;
+
+ default:
+ break;
}
#endif
/*
* Load the type.
*/
- ret = eap_module_load(inst, &inst->methods[method], method, scs);
+ ret = eap_module_instantiate(inst, &inst->methods[method], method, scs);
(void) talloc_get_type_abort(inst->methods[method], eap_module_t);
}
fr_link_talloc_ctx_free(inst, inst->session_tree);
- if (fr_debug_flag) {
- inst->handler_tree = rbtree_create(NULL, eap_handler_ptr_cmp, NULL, 0);
- if (!inst->handler_tree) {
- ERROR("rlm_eap (%s): Cannot initialize tree", inst->xlat_name);
- return -1;
- }
- fr_link_talloc_ctx_free(inst, inst->handler_tree);
-
-#ifdef HAVE_PTHREAD_H
- if (pthread_mutex_init(&(inst->handler_mutex), NULL) < 0) {
- ERROR("rlm_eap (%s): Failed initializing mutex: %s", inst->xlat_name, fr_syserror(errno));
- return -1;
- }
-#endif
- }
-
#ifdef HAVE_PTHREAD_H
if (pthread_mutex_init(&(inst->session_mutex), NULL) < 0) {
ERROR("rlm_eap (%s): Failed initializing mutex: %s", inst->xlat_name, fr_syserror(errno));
inst = (rlm_eap_t *) instance;
- if (!pairfind(request->packet->vps, PW_EAP_MESSAGE, 0, TAG_ANY)) {
- REDEBUG("You set 'Auth-Type = EAP' for a request that does "
- "not contain an EAP-Message attribute!");
+ if (!fr_pair_find_by_num(request->packet->vps, PW_EAP_MESSAGE, 0, TAG_ANY)) {
+ REDEBUG("You set 'Auth-Type = %s' for a request that does "
+ "not contain an EAP-Message attribute!", inst->xlat_name);
return RLM_MODULE_INVALID;
}
* Some simple sanity checks. These should really
* be handled by the radius library...
*/
- vp = pairfind(request->proxy->vps, PW_EAP_MESSAGE, 0, TAG_ANY);
+ vp = fr_pair_find_by_num(request->proxy->vps, PW_EAP_MESSAGE, 0, TAG_ANY);
if (vp) {
- vp = pairfind(request->proxy->vps, PW_MESSAGE_AUTHENTICATOR, 0, TAG_ANY);
+ vp = fr_pair_find_by_num(request->proxy->vps, PW_MESSAGE_AUTHENTICATOR, 0, TAG_ANY);
if (!vp) {
- pairmake(request->proxy,
+ fr_pair_make(request->proxy,
&request->proxy->vps,
"Message-Authenticator",
NULL, T_OP_EQ);
* set to 127.0.0.1 for tunneled requests, and
* we don't want to tell the world that...
*/
- pairdelete(&request->proxy->vps, PW_FREERADIUS_PROXIED_TO, VENDORPEC_FREERADIUS, TAG_ANY);
+ fr_pair_delete_by_num(&request->proxy->vps, PW_FREERADIUS_PROXIED_TO, VENDORPEC_FREERADIUS, TAG_ANY);
- RDEBUG2("Tunneled session will be proxied. Not doing EAP");
+ RWDEBUG2("Tunneled session will be proxied. Not doing EAP");
return RLM_MODULE_HANDLED;
}
#endif
}
/*
+ * Enable the cached entry on success.
+ */
+ if (handler->eap_ds->request->code == PW_EAP_SUCCESS) {
+ VALUE_PAIR *vp;
+
+ vp = fr_pair_find_by_num(request->state, PW_TLS_CACHE_FILENAME, 0, TAG_ANY);
+ if (vp) (void) chmod(vp->vp_strvalue, S_IRUSR | S_IWUSR);
+ }
+
+ /*
+ * Disable the cached entry on failure.
+ */
+ if (handler->eap_ds->request->code == PW_EAP_FAILURE) {
+ VALUE_PAIR *vp;
+
+ vp = fr_pair_find_by_num(request->state, PW_TLS_CACHE_FILENAME, 0, TAG_ANY);
+ if (vp) (void) unlink(vp->vp_strvalue);
+ }
+
+ /*
* If it's an Access-Accept, RFC 2869, Section 2.3.1
* says that we MUST include a User-Name attribute in the
* Access-Accept.
/*
* Doesn't exist, add it in.
*/
- vp = pairfind(request->reply->vps, PW_USER_NAME, 0, TAG_ANY);
+ vp = fr_pair_find_by_num(request->reply->vps, PW_USER_NAME, 0, TAG_ANY);
if (!vp) {
- vp = paircopyvp(request->reply, request->username);
- pairadd(&request->reply->vps, vp);
+ vp = fr_pair_copy(request->reply, request->username);
+ fr_pair_add(&request->reply->vps, vp);
}
/*
* each EAP sub-module to look for handler->request->username,
* and to get excited if it doesn't appear.
*/
- vp = pairfind(request->config, PW_AUTH_TYPE, 0, TAG_ANY);
- if ((!vp) || (vp->vp_integer != PW_AUTHTYPE_REJECT)) {
- vp = pairmake_config("Auth-Type", inst->xlat_name, T_OP_EQ);
+ vp = fr_pair_find_by_num(request->config, PW_AUTH_TYPE, 0, TAG_ANY);
+ if ((!vp) || (vp->vp_integer != PW_AUTH_TYPE_REJECT)) {
+ vp = pair_make_config("Auth-Type", inst->xlat_name, T_OP_EQ);
if (!vp) {
RDEBUG2("Failed to create Auth-Type %s: %s\n",
inst->xlat_name, fr_strerror());
{
size_t i;
size_t len;
+ ssize_t ret;
char *p;
VALUE_PAIR *vp;
eap_handler_t *handler;
/*
* Doesn't exist, add it in.
*/
- vp = pairfind(request->reply->vps, PW_USER_NAME, 0, TAG_ANY);
+ vp = fr_pair_find_by_num(request->reply->vps, PW_USER_NAME, 0, TAG_ANY);
if (!vp) {
- pairmake_reply("User-Name",
+ pair_make_reply("User-Name",
request->username->vp_strvalue,
T_OP_EQ);
}
i = 34;
p = talloc_memdup(vp, vp->vp_strvalue, vp->vp_length + 1);
talloc_set_type(p, uint8_t);
- len = rad_tunnel_pwdecode((uint8_t *)p + 17, &i, request->home_server->secret, request->proxy->vector);
+ ret = rad_tunnel_pwdecode((uint8_t *)p + 17, &i, request->home_server->secret, request->proxy->vector);
+ if (ret < 0) {
+ REDEBUG("Decoding leap:session-key failed");
+ talloc_free(p);
+ return RLM_MODULE_FAIL;
+ }
+ len = i;
- /*
- * FIXME: Assert that i == 16.
- */
+ if (i != 16) {
+ REDEBUG("Decoded key length is incorrect, must be 16 bytes");
+ talloc_free(p);
+ return RLM_MODULE_FAIL;
+ }
/*
* Encrypt the session key again, using the request data.
*/
- rad_tunnel_pwencode(p + 17, &len,
- request->client->secret,
- request->packet->vector);
- pairstrsteal(vp, p);
+ ret = rad_tunnel_pwencode(p + 17, &len, request->client->secret, request->packet->vector);
+ if (ret < 0) {
+ REDEBUG("Decoding leap:session-key failed");
+ talloc_free(p);
+ return RLM_MODULE_FAIL;
+ }
+
+ fr_pair_value_strsteal(vp, p);
return RLM_MODULE_UPDATED;
}
/*
* Only build a failure message if something previously rejected the request
*/
- vp = pairfind(request->config, PW_POSTAUTHTYPE, 0, TAG_ANY);
+ vp = fr_pair_find_by_num(request->config, PW_POST_AUTH_TYPE, 0, TAG_ANY);
- if (!vp || (vp->vp_integer != PW_POSTAUTHTYPE_REJECT)) return RLM_MODULE_NOOP;
+ if (!vp || (vp->vp_integer != PW_POST_AUTH_TYPE_REJECT)) return RLM_MODULE_NOOP;
- if (!pairfind(request->packet->vps, PW_EAP_MESSAGE, 0, TAG_ANY)) {
- RDEBUG2("Request didn't contain an EAP-Message, not inserting EAP-Failure");
+ if (!fr_pair_find_by_num(request->packet->vps, PW_EAP_MESSAGE, 0, TAG_ANY)) {
+ RDEBUG3("Request didn't contain an EAP-Message, not inserting EAP-Failure");
return RLM_MODULE_NOOP;
}
- if (pairfind(request->reply->vps, PW_EAP_MESSAGE, 0, TAG_ANY)) {
- RDEBUG2("Reply already contained an EAP-Message, not inserting EAP-Failure");
+ if (fr_pair_find_by_num(request->reply->vps, PW_EAP_MESSAGE, 0, TAG_ANY)) {
+ RDEBUG3("Reply already contained an EAP-Message, not inserting EAP-Failure");
return RLM_MODULE_NOOP;
}
* Make sure there's a message authenticator attribute in the response
* RADIUS protocol code will calculate the correct value later...
*/
- vp = pairfind(request->reply->vps, PW_MESSAGE_AUTHENTICATOR, 0, TAG_ANY);
+ vp = fr_pair_find_by_num(request->reply->vps, PW_MESSAGE_AUTHENTICATOR, 0, TAG_ANY);
if (!vp) {
- pairmake_reply("Message-Authenticator", "0x00", T_OP_EQ);
+ pair_make_reply("Message-Authenticator", "0x00", T_OP_EQ);
}
return RLM_MODULE_UPDATED;
*/
extern module_t rlm_eap;
module_t rlm_eap = {
- RLM_MODULE_INIT,
- "eap",
- 0, /* type */
- sizeof(rlm_eap_t),
- module_config,
- mod_instantiate, /* instantiation */
- mod_detach, /* detach */
- {
- mod_authenticate, /* authentication */
- mod_authorize, /* authorization */
- NULL, /* preaccounting */
- NULL, /* accounting */
- NULL, /* checksimul */
- NULL, /* pre-proxy */
+ .magic = RLM_MODULE_INIT,
+ .name = "eap",
+ .inst_size = sizeof(rlm_eap_t),
+ .config = module_config,
+ .instantiate = mod_instantiate,
+ .detach = mod_detach,
+ .methods = {
+ [MOD_AUTHENTICATE] = mod_authenticate,
+ [MOD_AUTHORIZE] = mod_authorize,
#ifdef WITH_PROXY
- mod_post_proxy, /* post-proxy */
-#else
- NULL,
+ [MOD_POST_PROXY] = mod_post_proxy,
#endif
- mod_post_auth /* post-auth */
+ [MOD_POST_AUTH] = mod_post_auth
},
};