⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eap.c

📁 linux1.0内核的源代码,欢迎大家使用
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * eap.c    rfc2284 & rfc2869 implementation * * Version:     $Id: eap.c,v 1.52.4.1 2006/02/06 16:23:49 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> *//* *  EAP PACKET FORMAT *  --- ------ ------ *  0                   1                   2                   3 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |     Code      |  Identifier   |            Length             | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |    Data ... * +-+-+-+-+ * * * EAP Request and Response Packet Format * --- ------- --- -------- ------ ------ *  0                   1                   2                   3 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |     Code      |  Identifier   |            Length             | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |     Type      |  Type-Data ... * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- * * * EAP Success and Failure Packet Format * --- ------- --- ------- ------ ------ *  0                   1                   2                   3 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |     Code      |  Identifier   |            Length             | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */#include "rlm_eap.h"static const char rcsid[] = "$Id: eap.c,v 1.52.4.1 2006/02/06 16:23:49 nbk Exp $";static const char *eap_codes[] = {  "",				/* 0 is invalid */  "request",  "response",  "success",  "failure"};/* * 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){	char		buffer[64];	char		namebuf[64];	const char	*eaptype_name;	lt_dlhandle	handle;	EAP_TYPES	*node;	eaptype_name = eaptype_type2name(eap_type, namebuf, sizeof(namebuf));	snprintf(buffer, sizeof(buffer), "rlm_eap_%s", eaptype_name);	/* Link the loaded EAP-Type */	handle = lt_dlopenext(buffer);	if (handle == NULL) {		radlog(L_ERR, "rlm_eap: Failed to link EAP-Type/%s: %s",		       eaptype_name, lt_dlerror());		return -1;	}	/* Make room for the EAP-Type */	node = (EAP_TYPES *)malloc(sizeof(EAP_TYPES));	if (node == NULL) {		radlog(L_ERR, "rlm_eap: out of memory");		return -1;	}	memset(node, 0, sizeof(*node));	/* fill in the structure */	node->handle = handle;	node->cs = cs;	/*	 *	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.	 */	node->typename = eaptype_name;	node->type_data = NULL;	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());		lt_dlclose(node->handle);	/* ignore any errors */		free(node);		return -1;	}	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);		lt_dlclose(node->handle);		free(node);		return -1;	}	DEBUG("rlm_eap: Loaded and initialized type %s", eaptype_name);	*type = node;	return 0;}/* * Call the appropriate handle with the right eap_type. */static int eaptype_call(EAP_TYPES *atype, EAP_HANDLER *handler){	int rcode = 1;	DEBUG2("  rlm_eap: processing type %s", atype->typename);	rad_assert(atype != NULL);	switch (handler->stage) {	case INITIATE:		if (!atype->type->initiate(atype->type_data, 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))			rcode = 0;		break;	case AUTHENTICATE:		/*		 *   The called function updates the EAP reply packet.		 */		if (!atype->type->authenticate ||		    !atype->type->authenticate(atype->type_data, handler))			rcode = 0;		break;	default:		/* Should never enter here */		radlog(L_DBG, "rlm_eap: Invalid operation on eap_type");		rcode = 0;		break;	}	return rcode;}/* * Based on TYPE, call the appropriate EAP-type handler * Default to the configured EAP-Type * for all Unsupported EAP-Types */int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler){	unsigned int	default_eap_type = inst->default_eap_type;	eaptype_t	*eaptype;	VALUE_PAIR	*vp;	char		namebuf[64];	const char	*eaptype_name;	eaptype = &handler->eap_ds->response->type;	/*	 *	Don't trust anyone.	 */	if ((eaptype->type == 0) ||	    (eaptype->type > PW_EAP_MAX_TYPES)) {		DEBUG2(" rlm_eap: Asked to select bad type");		return EAP_INVALID;	}	/*	 *	Figure out what to do.	 */	switch(eaptype->type) {	case PW_EAP_IDENTITY:		DEBUG2("  rlm_eap: EAP Identity");		/*		 *	Allow per-user configuration of EAP types.		 */		vp = pairfind(handler->request->config_items,			      PW_EAP_TYPE);		if (vp) default_eap_type = vp->lvalue;	do_initiate:		/*		 *	Ensure it's valid.		 */		if ((default_eap_type < PW_EAP_MD5) ||		    (default_eap_type > PW_EAP_MAX_TYPES) ||		    (inst->types[default_eap_type] == NULL)) {			DEBUG2(" rlm_eap: No such EAP type %s",			       eaptype_type2name(default_eap_type,						 namebuf, sizeof(namebuf)));			return EAP_INVALID;		}		handler->stage = INITIATE;		handler->eap_type = default_eap_type;		/*		 *	Wild & crazy stuff!  For TTLS & PEAP, we		 *	initiate a TLS session, and then pass that		 *	session data to TTLS or PEAP for the		 *	authenticate stage.		 *		 *	Handler->eap_type holds the TRUE type.		 */		if ((default_eap_type == PW_EAP_TTLS) ||		    (default_eap_type == PW_EAP_PEAP)) {			default_eap_type = PW_EAP_TLS;		}		/*		 *	We don't do TLS inside of TLS, as it's a bad		 *	idea...		 */		if (((handler->request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) != 0) &&		    (default_eap_type == PW_EAP_TLS)) {			DEBUG2(" rlm_eap: Unable to tunnel TLS inside of TLS");			return EAP_INVALID;		}		if (eaptype_call(inst->types[default_eap_type],				 handler) == 0) {			DEBUG2(" rlm_eap: Default EAP type %s failed in initiate",			       eaptype_type2name(default_eap_type,						 namebuf, sizeof(namebuf)));			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.		 */		DEBUG2("  rlm_eap: EAP NAK");		/*		 *	Delete old data, if necessary.		 */		if (handler->opaque && handler->free_opaque) {			handler->free_opaque(handler->opaque);			handler->free_opaque = NULL;			handler->opaque = NULL;		}		/*		 *	It is invalid to request identity,		 *	notification & nak in nak		 */		if (eaptype->data == NULL) {			DEBUG2(" rlm_eap: Empty NAK packet, cannot decide what EAP type the client wants.");			return EAP_INVALID;		}		/*		 *	FIXME: Pick one type out of the one they asked		 *	for, as they may have asked for many.		 */		if ((eaptype->data[0] < PW_EAP_MD5) ||		    (eaptype->data[0] > PW_EAP_MAX_TYPES)) {			DEBUG2(" rlm_eap: NAK asked for bad type %d",			       eaptype->data[0]);			return EAP_INVALID;		}		default_eap_type = eaptype->data[0];		eaptype_name = eaptype_type2name(default_eap_type,						 namebuf, sizeof(namebuf));		DEBUG2(" rlm_eap: EAP-NAK asked for EAP-Type/%s",		       eaptype_name);		/*		 *	Prevent a firestorm if the client is confused.		 */		if (handler->eap_type == default_eap_type) {			DEBUG2(" rlm_eap: ERROR! Our request for %s was NAK'd with a request for %s, what is the client thinking?",			       eaptype_name, eaptype_name);			return EAP_INVALID;		}		/*		 *	Enforce per-user configuration of EAP types.		 */		vp = pairfind(handler->request->config_items,			      PW_EAP_TYPE);		if (vp && (vp->lvalue != default_eap_type)) {			char	mynamebuf[64];			DEBUG2("  rlm_eap: Client wants %s, while we require %s, rejecting the user.",			       eaptype_name,			       eaptype_type2name(vp->lvalue,						 mynamebuf,						 sizeof(mynamebuf)));			return EAP_INVALID;		}		goto do_initiate;		break;		/*		 *	Key off of the configured sub-modules.		 */		default:			eaptype_name = eaptype_type2name(eaptype->type,							 namebuf,							 sizeof(namebuf));			DEBUG2("  rlm_eap: EAP/%s", eaptype_name);			/*			 *	We haven't configured it, it doesn't exit.			 */			if (!inst->types[eaptype->type]) {				DEBUG2(" rlm_eap: EAP type %d is unsupported",				       eaptype->type);				return EAP_INVALID;			}			rad_assert(handler->stage == AUTHENTICATE);			handler->eap_type = eaptype->type;			if (eaptype_call(inst->types[eaptype->type],					 handler) == 0) {				DEBUG2(" rlm_eap: Handler failed in EAP/%s",				       eaptype_name);				return EAP_INVALID;			}		break;	}	return EAP_OK;}/* *	EAP packet format to be sent over the wire *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -