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

📄 mem.c

📁 新的radius程序
💻 C
字号:
/* * mem.c  Memory allocation, deallocation stuff. * * Version:     $Id: mem.c,v 1.14.4.3 2007/02/09 15:42:03 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,2001  The FreeRADIUS server project * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com> */#include <stdio.h>#include "rlm_eap.h"static const char rcsid[] = "$Id: mem.c,v 1.14.4.3 2007/02/09 15:42:03 aland Exp $";/* * Allocate a new EAP_PACKET */EAP_PACKET *eap_packet_alloc(void){	EAP_PACKET   *rp;	rp = rad_malloc(sizeof(EAP_PACKET));	memset(rp, 0, sizeof(EAP_PACKET));	return rp;}/* * Free EAP_PACKET */void eap_packet_free(EAP_PACKET **eap_packet_ptr){	EAP_PACKET *eap_packet;	if (!eap_packet_ptr) return;	eap_packet = *eap_packet_ptr;	if (!eap_packet) return;   	if (eap_packet->type.data) {		/*		 * This is just a pointer in the packet		 * so we do not free it but we NULL it		free(eap_packet->type.data);		*/		eap_packet->type.data = NULL;	}	if (eap_packet->packet) {		free(eap_packet->packet);		eap_packet->packet = NULL;	}	free(eap_packet);	*eap_packet_ptr = NULL;}/* * Allocate a new EAP_PACKET */EAP_DS *eap_ds_alloc(void){	EAP_DS	*eap_ds;	eap_ds = rad_malloc(sizeof(EAP_DS));	memset(eap_ds, 0, sizeof(EAP_DS));	if ((eap_ds->response = eap_packet_alloc()) == NULL) {		eap_ds_free(&eap_ds);		return NULL;	}	if ((eap_ds->request = eap_packet_alloc()) == NULL) {		eap_ds_free(&eap_ds);		return NULL;	}	return eap_ds;}void eap_ds_free(EAP_DS **eap_ds_p){	EAP_DS *eap_ds;	if (!eap_ds_p) return;	eap_ds = *eap_ds_p;	if (!eap_ds) return;	if (eap_ds->response) eap_packet_free(&(eap_ds->response));	if (eap_ds->request) eap_packet_free(&(eap_ds->request));	free(eap_ds);	*eap_ds_p = NULL;}/* * Allocate a new EAP_HANDLER */EAP_HANDLER *eap_handler_alloc(void){	EAP_HANDLER	*handler;	handler = rad_malloc(sizeof(EAP_HANDLER));	memset(handler, 0, sizeof(EAP_HANDLER));	return handler;}void eap_handler_free(EAP_HANDLER *handler){	if (!handler)		return;	if (handler->identity) {		free(handler->identity);		handler->identity = NULL;	}	if (handler->prev_eapds) eap_ds_free(&(handler->prev_eapds));	if (handler->eap_ds) eap_ds_free(&(handler->eap_ds));	if ((handler->opaque) && (handler->free_opaque)) {		handler->free_opaque(handler->opaque);		handler->opaque = NULL;	}	else if ((handler->opaque) && (handler->free_opaque == NULL))                radlog(L_ERR, "Possible memory leak ...");	handler->opaque = NULL;	handler->free_opaque = NULL;	free(handler);}void eaptype_free(EAP_TYPES *i){	if (i->type->detach) (i->type->detach)(i->type_data);	i->type_data = NULL;	if (i->handle) lt_dlclose(i->handle);	free(i);}void eaplist_free(rlm_eap_t *inst){	EAP_HANDLER *node, *next;       	for (node = inst->session_head; node != NULL; node = next) {		next = node->next;		eap_handler_free(node);	}	inst->session_head = inst->session_tail = NULL;}/* *	Add a handler to the set of active sessions. * *	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		status;	VALUE_PAIR	*state;		rad_assert(handler != NULL);	rad_assert(handler->request != NULL);	/*	 *	Generate State, since we've been asked to add it to	 *	the list.	 */	state = generate_state(handler->request->timestamp);	pairadd(&(handler->request->reply->vps), state);	/*	 *	Create a unique 'key' for the handler, based	 *	on State, Client-IP-Address, and EAP ID.	 */	rad_assert(state->length == EAP_STATE_LEN);	/*	 *	The time at which this request was made was the time	 *	at which it was received by the RADIUS server.	 */	handler->timestamp = handler->request->timestamp;	handler->status = 1;	memcpy(handler->state, state->strvalue, sizeof(handler->state));	handler->src_ipaddr = handler->request->packet->src_ipaddr;	handler->eap_id = handler->eap_ds->request->id;	/*	 *	We don't need this any more.	 */	handler->request = NULL;	/*	 *	Playing with a data structure shared among threads	 *	means that we need a lock, to avoid conflict.	 */	pthread_mutex_lock(&(inst->session_mutex));	/*	 *	Big-time failure.	 */	status = rbtree_insert(inst->session_tree, handler);	if (status) {		EAP_HANDLER *prev;		prev = inst->session_tail;		if (prev) {			prev->next = handler;			handler->prev = prev;			handler->next = NULL;			inst->session_tail = handler;		} else {			inst->session_head = inst->session_tail = handler;			handler->next = handler->prev = NULL;		}	}	/*	 *	Now that we've finished mucking with the list,	 *	unlock it.	 */	pthread_mutex_unlock(&(inst->session_mutex));	if (!status) {		radlog(L_ERR, "rlm_eap: Failed to remember handler!");		eap_handler_free(handler);		return 0;	}	return 1;}/* *	Find a a previous EAP-Request sent by us, which matches *	the current EAP-Response. * *	Then, release the handle from the list, and return it to *	the caller. * *	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_packet_t *eap_packet){	int		i;	VALUE_PAIR	*state;	rbnode_t	*node;	EAP_HANDLER	*handler, myHandler;	/*	 *	We key the sessions off of the 'state' attribute, so it	 *	must exist.	 */	state = pairfind(request->packet->vps, PW_STATE);	if (!state ||	    (state->length != EAP_STATE_LEN)) {		return NULL;	}	myHandler.src_ipaddr = request->packet->src_ipaddr;	myHandler.eap_id = eap_packet->id;	memcpy(myHandler.state, state->strvalue, sizeof(myHandler.state));	/*	 *	Playing with a data structure shared among threads	 *	means that we need a lock, to avoid conflict.	 */	pthread_mutex_lock(&(inst->session_mutex));	/*	 *	Check the first few handlers in the list, and delete	 *	them if they're too old.  We don't need to check them	 *	all, as incoming requests will quickly cause older	 *	handlers to be deleted.	 *	 */	for (i = 0; i < 2; i++) {		handler = inst->session_head;		if (handler &&		    ((request->timestamp - handler->timestamp) > inst->timer_limit)) {			node = rbtree_find(inst->session_tree, handler);			rad_assert(node != NULL);			rbtree_delete(inst->session_tree, node);						inst->session_head = handler->next;			if (handler->next) handler->next->prev = NULL;			eap_handler_free(handler);		}	}	handler = NULL;	node = rbtree_find(inst->session_tree, &myHandler);	if (node) {		handler = rbtree_node2data(inst->session_tree, node);		/*		 *	Check against replays.  The client can re-play		 *	a State attribute verbatim, so we wish to		 *	ensure that the attribute falls within the		 *	valid time window, which is the second at		 *	which it was sent out.		 *		 *	Hmm... I'm not sure that this step is		 *	necessary, or even that it does anything.		 */		if (verify_state(state, handler->timestamp) != 0) {			handler = NULL;		} else {			/*			 *	It's OK, delete it from the tree.			 */			rbtree_delete(inst->session_tree, node);			/*			 *	And unsplice it from the linked list.			 */			if (handler->prev) {				handler->prev->next = handler->next;			} else {				inst->session_head = handler->next;			}			if (handler->next) {				handler->next->prev = handler->prev;			} else {				inst->session_tail = handler->prev;			}			handler->prev = handler->next = NULL;		}	}	pthread_mutex_unlock(&(inst->session_mutex));	/*	 *	Not found.	 */	if (!node) {		DEBUG2("  rlm_eap: Request not found in the list");		return NULL;	}	/*	 *	Found, but state verification failed.	 */	if (!handler) {		radlog(L_ERR, "rlm_eap: State verification failed.");		return NULL;	}	DEBUG2("  rlm_eap: Request found, released from the list");	/*	 *	Remember what the previous request was.	 */	eap_ds_free(&(handler->prev_eapds));	handler->prev_eapds = handler->eap_ds;	handler->eap_ds = NULL;		return handler;}

⌨️ 快捷键说明

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