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

📄 xlat.c

📁 radius server在linux下的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * xlat.c	Translate strings.  This is the first version of xlat * 		incorporated to RADIUS * * Version:	$Id: xlat.c,v 1.72.2.3 2004/09/09 14:31:07 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  The FreeRADIUS server project * Copyright 2000  Alan DeKok <aland@ox.org> */static const char rcsid[] ="$Id: xlat.c,v 1.72.2.3 2004/09/09 14:31:07 aland Exp $";#include	"autoconf.h"#include	"libradius.h"#include	<stdio.h>#include	<stdlib.h>#include	<string.h>#include	<ctype.h>#include	"radiusd.h"#include	"rad_assert.h"typedef struct xlat_t {	char		module[MAX_STRING_LEN];	int		length;	void		*instance;	RAD_XLAT_FUNC	do_xlat;	int		internal;	/* not allowed to re-define these */} xlat_t;static rbtree_t *xlat_root = NULL;/* *	Define all xlat's in the structure. */static const char *internal_xlat[] = {"check",				      "request",				      "reply",				      "proxy-request",				      "proxy-reply",				      NULL};#if REQUEST_MAX_REGEX > 8#error Please fix the following line#endifstatic int xlat_inst[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };	/* up to 8 for regex *//* *	Convert the value on a VALUE_PAIR to string */static int valuepair2str(char * out,int outlen,VALUE_PAIR * pair,			 int type, RADIUS_ESCAPE_STRING func){	char buffer[MAX_STRING_LEN * 4];	if (pair != NULL) {		vp_prints_value(buffer, sizeof(buffer), pair, 0);		return func(out, outlen, buffer);	}	switch (type) {	case PW_TYPE_STRING :		strNcpy(out,"_",outlen);		break;	case PW_TYPE_INTEGER :		strNcpy(out,"0",outlen);		break;	case PW_TYPE_IPADDR :		strNcpy(out,"?.?.?.?",outlen);		break;	case PW_TYPE_DATE :		strNcpy(out,"0",outlen);		break;	default :		strNcpy(out,"unknown_type",outlen);	}	return strlen(out);}/* *	Dynamically translate for check:, request:, reply:, etc. */static int xlat_packet(void *instance, REQUEST *request,		       char *fmt, char *out, size_t outlen,		       RADIUS_ESCAPE_STRING func){	DICT_ATTR	*da;	VALUE_PAIR	*vp;	VALUE_PAIR	*vps = NULL;	RADIUS_PACKET	*packet = NULL;	switch (*(int*) instance) {	case 0:		vps = request->config_items;		break;	case 1:		vps = request->packet->vps;		packet = request->packet;		break;	case 2:		vps = request->reply->vps;		packet = request->reply;		break;	case 3:		if (request->proxy) vps = request->proxy->vps;		packet = request->proxy;		break;	case 4:		if (request->proxy_reply) vps = request->proxy_reply->vps;		packet = request->proxy_reply;		break;	default:		/* WTF? */		return 0;	}	/*	 *	The "format" string is the attribute name.	 */	da = dict_attrbyname(fmt);	if (!da) return 0;	vp = pairfind(vps, da->attr);	if (!vp) {		/*		 *	Some "magic" handlers, which are never in VP's, but		 *	which are in the packet.		 *		 *	FIXME: Add SRC/DST IP address!		 */		if (packet) {			switch (da->attr) {			case PW_PACKET_TYPE:			{				DICT_VALUE *dval;								dval = dict_valbyattr(da->attr, packet->code);				if (dval) {					snprintf(out, outlen, "%s", dval->name);				} else {					snprintf(out, outlen, "%d", packet->code);				}				return strlen(out);			}			break;						default:				break;			}		}		/*		 *	Not found, die.		 */		return 0;	}	if (!vps) return 0;	/* silently fail */	/*	 *	Convert the VP to a string, and return it.	 */	return valuepair2str(out, outlen, vp, da->type, func);}#ifdef HAVE_REGEX_H/* *	Pull %{0} to %{8} out of the packet. */static int xlat_regex(void *instance, REQUEST *request,		      char *fmt, char *out, size_t outlen,		      RADIUS_ESCAPE_STRING func){	char *regex;	/*	 *	We cheat: fmt is "0" to "8", but those numbers	 *	are already in the "instance".	 */	fmt = fmt;		/* -Wunused */	func = func;		/* -Wunused FIXME: do escaping? */		regex = request_data_get(request, request,				 REQUEST_DATA_REGEX | *(int *)instance);	if (!regex) return 0;	/*	 *	Copy UP TO "freespace" bytes, including	 *	a zero byte.	 */	strNcpy(out, regex, outlen);	free(regex); /* was strdup'd */	return strlen(out);}#endif				/* HAVE_REGEX_H *//* *	Compare two xlat_t structs, based ONLY on the module name. */static int xlat_cmp(const void *a, const void *b){	if (((const xlat_t *)a)->length != ((const xlat_t *)b)->length) {		return ((const xlat_t *)a)->length - ((const xlat_t *)b)->length;	}	return memcmp(((const xlat_t *)a)->module,		      ((const xlat_t *)b)->module,		      ((const xlat_t *)a)->length);}/* *	find the appropriate registered xlat function. */static xlat_t *xlat_find(const char *module){	char *p;	xlat_t my_xlat;	strNcpy(my_xlat.module, module, sizeof(my_xlat.module));	/*	 *	We get passed the WHOLE string, and all we want here	 *	is the first piece.	 */	p = strchr(my_xlat.module, ':');	if (p) *p = '\0';	my_xlat.length = strlen(my_xlat.module);	return rbtree_finddata(xlat_root, &my_xlat);}/* *      Register an xlat function. */int xlat_register(const char *module, RAD_XLAT_FUNC func, void *instance){	xlat_t	*c;	xlat_t	my_xlat;	if ((module == NULL) || (strlen(module) == 0)) {		DEBUG("xlat_register: Invalid module name");		return -1;	}	/*	 *	First time around, build up the tree...	 *	 *	FIXME: This code should be hoisted out of this function,	 *	and into a global "initialization".  But it isn't critical...	 */	if (!xlat_root) {		int i;#ifdef HAVE_REGEX_H		char buffer[2];#endif		xlat_root = rbtree_create(xlat_cmp, free, 0);		if (!xlat_root) {			DEBUG("xlat_register: Failed to create tree.");			return -1;		}		/*		 *	Register the internal packet xlat's.		 */		for (i = 0; internal_xlat[i] != NULL; i++) {			xlat_register(internal_xlat[i], xlat_packet, &xlat_inst[i]);			c = xlat_find(internal_xlat[i]);			rad_assert(c != NULL);			c->internal = TRUE;		}#ifdef HAVE_REGEX_H		/*		 *	Register xlat's for regexes.		 */		buffer[1] = '\0';		for (i = 0; i <= REQUEST_MAX_REGEX; i++) {			buffer[0] = '0' + i;			xlat_register(buffer, xlat_regex, &xlat_inst[i]);			c = xlat_find(buffer);			rad_assert(c != NULL);			c->internal = TRUE;		}#endif /* HAVE_REGEX_H */	}	/*	 *	If it already exists, replace the instance.	 */	strNcpy(my_xlat.module, module, sizeof(my_xlat.module));	my_xlat.length = strlen(my_xlat.module);	c = rbtree_finddata(xlat_root, &my_xlat);	if (c) {		if (c->internal) {			DEBUG("xlat_register: Cannot re-define internal xlat");			return -1;		}		c->do_xlat = func;		c->instance = instance;		return 0;	}	/*	 *	Doesn't exist.  Create it.	 */	c = rad_malloc(sizeof(xlat_t));	memset(c, 0, sizeof(*c));	c->do_xlat = func;	strNcpy(c->module, module, sizeof(c->module));	c->length = strlen(c->module);	c->instance = instance;	rbtree_insert(xlat_root, c);	return 0;}/* *      Unregister an xlat function. * *	We can only have one function to call per name, so the *	passing of "func" here is extraneous. */void xlat_unregister(const char *module, RAD_XLAT_FUNC func){	rbnode_t	*node;	xlat_t		my_xlat;	func = func;		/* -Wunused */	strNcpy(my_xlat.module, module, sizeof(my_xlat.module));	my_xlat.length = strlen(my_xlat.module);	node = rbtree_find(xlat_root, &my_xlat);	if (!node) return;	rbtree_delete(xlat_root, node);}/* *	Decode an attribute name into a string. */static void decode_attribute(const char **from, char **to, int freespace,			     int *open, REQUEST *request,			     RADIUS_ESCAPE_STRING func){	char attrname[256];	const char *p;	char *q, *pa;	int stop=0, found=0, retlen=0;	int openbraces = *open;	xlat_t *c;	p = *from;	q = *to;	pa = &attrname[0];	*q = '\0';	/*	 * Skip the '{' at the front of 'p'	 * Increment open braces	 */	p++;	openbraces++;	/*	 *  Copy over the rest of the string.	 */	while ((*p) && (!stop)) {		switch(*p) {			/*			 *  Allow braces inside things, too.			 */			case '\\':				p++; /* skip it */				*pa++ = *p++;				break;			case '{':

⌨️ 快捷键说明

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