📄 rlm_eap.c
字号:
/* * rlm_eap.c contains handles that are called from modules. * * Version: $Id: rlm_eap.c,v 1.26 2004/03/12 16:14:53 aland 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 2004/03/12 16:14:53 aland 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 */};static int eap_init(void){ return 0;}/* * 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; 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; }#ifdef HAVE_PTHREAD_H pthread_mutex_destroy(&(inst->session_mutex)); pthread_mutex_destroy(&(inst->module_mutex));#endif if (inst->default_eap_type_name) free(inst->default_eap_type_name); free(inst); return 0;}/* * 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();#ifdef HAVE_PTHREAD_H pthread_mutex_init(&(inst->session_mutex), NULL); pthread_mutex_init(&(inst->module_mutex), NULL);#endif *instance = inst; return 0;}/* * Dumb wrapper. * FIXME: this should be done more intelligently... */static void my_handler_free(void *data){ EAP_HANDLER *handler = (EAP_HANDLER *) data; eap_handler_free(&handler);}/* * 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;#ifdef HAVE_PTHREAD_H int locked = FALSE;#endif 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; } }#ifdef HAVE_PTHREAD_H else { /* it's a normal request from a NAS */ /* * The OpenSSL code isn't strictly thread-safe, * as we've got to provide callback functions. * * Rather than doing that, we just ensure that the * sub-modules are locked via a mutex. * * Don't lock it if we're calling ourselves recursively, * we've already got the lock. */ pthread_mutex_lock(&(inst->module_mutex)); locked = TRUE; /* for recursive calls to the module */ }#endif /* * Select the appropriate eap_type or default to the * configured one */ rcode = eaptype_select(inst, handler);#ifdef HAVE_PTHREAD_H if (locked) pthread_mutex_unlock(&(inst->module_mutex));#endif /* * 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, my_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, my_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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -