📄 rlm_eap.c
字号:
/* * rlm_eap.c contains handles that are called from modules. * * Version: $Id: rlm_eap.c,v 1.26.2.1.2.1 2006/02/06 16:23:52 nbk Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Copyright 2000-2003 The FreeRADIUS server project * Copyright 2001 hereUare Communications, Inc. <raghud@hereuare.com> * Copyright 2003 Alan DeKok <aland@freeradius.org> */#include "autoconf.h"#include "rlm_eap.h"#include "modules.h"static const char rcsid[] = "$Id: rlm_eap.c,v 1.26.2.1.2.1 2006/02/06 16:23:52 nbk Exp $";static const CONF_PARSER module_config[] = { { "default_eap_type", PW_TYPE_STRING_PTR, offsetof(rlm_eap_t, default_eap_type_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" }, { "cisco_accounting_username_bug", PW_TYPE_BOOLEAN, offsetof(rlm_eap_t, cisco_accounting_username_bug), NULL, "no" }, { NULL, -1, 0, NULL, NULL } /* end the list */};/* * delete all the allocated space by eap module */static int eap_detach(void *instance){ rlm_eap_t *inst; int i; inst = (rlm_eap_t *)instance; rbtree_free(inst->session_tree); inst->session_tree = NULL; eaplist_free(inst); for (i = 0; i < PW_EAP_MAX_TYPES; i++) { if (inst->types[i]) eaptype_free(inst->types[i]); inst->types[i] = NULL; } pthread_mutex_destroy(&(inst->session_mutex)); if (inst->default_eap_type_name) free(inst->default_eap_type_name); free(inst); return 0;}/* * Compare two handlers. */static int eap_handler_cmp(const void *a, const void *b){ const EAP_HANDLER *one = a; const EAP_HANDLER *two = b; if (one->eap_id < two->eap_id) return -1; if (one->eap_id > two->eap_id) return +1; if (one->src_ipaddr < two->src_ipaddr) return -1; if (one->src_ipaddr > two->src_ipaddr) return +1; return memcmp(one->state, two->state, sizeof(one->state));}/* * read the config section and load all the eap authentication types present. */static int eap_instantiate(CONF_SECTION *cs, void **instance){ int eap_type; int num_types; CONF_SECTION *scs; rlm_eap_t *inst; inst = (rlm_eap_t *) malloc(sizeof(*inst)); if (!inst) { return -1; } memset(inst, 0, sizeof(*inst)); if (cf_section_parse(cs, inst, module_config) < 0) { eap_detach(inst); return -1; } /* 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)) { char *auth_type; auth_type = cf_section_name1(scs); if (!auth_type) continue; eap_type = eaptype_name2type(auth_type); if (eap_type < 0) { radlog(L_ERR|L_CONS, "rlm_eap: Unknown EAP type %s", auth_type); eap_detach(inst); return -1; } /* * If we're asked to load TTLS or PEAP, ensure * that we've first loaded TLS. */ if (((eap_type == PW_EAP_TTLS) || (eap_type == PW_EAP_PEAP)) && (inst->types[PW_EAP_TLS] == NULL)) { radlog(L_ERR, "rlm_eap: Unable to load EAP-Type/%s, as EAP-Type/TLS is required first.", auth_type); return -1; } /* * Load the type. */ if (eaptype_load(&inst->types[eap_type], eap_type, scs) < 0) { eap_detach(inst); return -1; } num_types++; /* successfully loaded one more types */ } if (num_types == 0) { radlog(L_ERR|L_CONS, "rlm_eap: No EAP type 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|L_CONS, "rlm_eap: Unknown default EAP type %s", inst->default_eap_type_name); eap_detach(inst); return -1; } if (inst->types[eap_type] == NULL) { radlog(L_ERR|L_CONS, "rlm_eap: No such sub-type for default EAP type %s", inst->default_eap_type_name); eap_detach(inst); return -1; } inst->default_eap_type = eap_type; /* save the numerical type */ /* * List of sessions are set to NULL by the memset * of 'inst', above. */ /* Generate a state key, specific to eap */ generate_key(); /* * Lookup sessions in the tree. We don't free them in * the tree, as that's taken care of elsewhere... */ inst->session_tree = rbtree_create(eap_handler_cmp, NULL, 0); if (!inst->session_tree) { radlog(L_ERR|L_CONS, "rlm_eap: Cannot initialize tree"); eap_detach(inst); return -1; } pthread_mutex_init(&(inst->session_mutex), NULL); *instance = inst; return 0;}/* * For backwards compatibility. */static int eap_authenticate(void *instance, REQUEST *request){ rlm_eap_t *inst; EAP_HANDLER *handler; eap_packet_t *eap_packet; int rcode; inst = (rlm_eap_t *) instance; /* * Get the eap packet to start with */ eap_packet = eap_attribute(request->packet->vps); if (eap_packet == NULL) { radlog(L_ERR, "rlm_eap: Malformed EAP Message"); return RLM_MODULE_FAIL; } /* * Create the eap handler. The eap_packet will end up being * "swallowed" into the handler, so we can't access it after * this call. */ handler = eap_handler(inst, &eap_packet, request); if (handler == NULL) { DEBUG2(" rlm_eap: Failed in handler"); return RLM_MODULE_INVALID; } /* * If it's a recursive request, then disallow * TLS, TTLS, and PEAP, inside of the TLS tunnel. */ if ((request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) != 0) { switch(handler->eap_ds->response->type.type) { case PW_EAP_TLS: case PW_EAP_TTLS: case PW_EAP_PEAP: DEBUG2(" rlm_eap: Unable to tunnel TLS inside of TLS"); eap_fail(handler); eap_handler_free(handler); return RLM_MODULE_INVALID; break; default: /* It may be OK, allow it to proceed */ break; } } /* * Select the appropriate eap_type or default to the * configured one */ rcode = eaptype_select(inst, handler); /* * If it failed, die. */ if (rcode == EAP_INVALID) { eap_fail(handler); eap_handler_free(handler); DEBUG2(" rlm_eap: Failed in EAP select"); return RLM_MODULE_INVALID; } /* * If we're doing horrible tunneling work, remember it. */ if ((request->options & RAD_REQUEST_OPTION_PROXY_EAP) != 0) { DEBUG2(" Not-EAP proxy set. Not composing EAP"); /* * Add the handle to the proxied list, so that we * can retrieve it in the post-proxy stage, and * send a response. */ rcode = request_data_add(request, inst, REQUEST_DATA_EAP_HANDLER, handler, eap_handler_free); rad_assert(rcode == 0); return RLM_MODULE_HANDLED; } /* * Maybe the request was marked to be proxied. If so, * proxy it. */ if (request->proxy != NULL) { VALUE_PAIR *vp = NULL; rad_assert(request->proxy_reply == NULL); /* * Add the handle to the proxied list, so that we * can retrieve it in the post-proxy stage, and * send a response. */ rcode = request_data_add(request, inst, REQUEST_DATA_EAP_HANDLER, handler, eap_handler_free); rad_assert(rcode == 0); /* * Some simple sanity checks. These should really * be handled by the radius library... */ vp = pairfind(request->proxy->vps, PW_EAP_MESSAGE); if (vp) { vp = pairfind(request->proxy->vps, PW_MESSAGE_AUTHENTICATOR); if (!vp) { vp = pairmake("Message-Authenticator", "0x00", T_OP_EQ); rad_assert(vp != NULL); pairadd(&(request->proxy->vps), vp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -