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

📄 valuepair.c

📁 linux 下的radius 最新版。linux 下的radius 最新版.linux 下的radius 最新版
💻 C
📖 第 1 页 / 共 2 页
字号:
			 */			if ((p = strrchr(value, '+')) != NULL && !p[1]) {				cs = s = strdup(value);				p = strrchr(s, '+');				*p = 0;				vp->flags.addport = 1;			} else {				p = NULL;				cs = value;			}			vp->lvalue = librad_dodns ? ip_getaddr(cs) :						    ip_addr(cs);			if (s) free(s);			vp->length = 4;			break;		case PW_TYPE_INTEGER:			/*			 * 	If it starts with a digit, it must			 * 	be a number (or a range).			 *			 *	Note that ALL integers are unsigned!			 */			if (strspn(value, "0123456789") == strlen(value)) {				vp->lvalue = (uint32_t) strtoul(value, NULL, 10);				vp->length = 4;			}			/*			 *	Look for the named value for the given			 *	attribute.			 */			else if ((dval = dict_valbyname(vp->attribute, value)) == NULL) {				librad_log("Unknown value %s for attribute %s",					   value, vp->name);				return NULL;			} else {				vp->lvalue = dval->value;				vp->length = 4;			}			break;		case PW_TYPE_DATE:			if (gettime(value, (time_t *)&vp->lvalue) < 0) {				librad_log("failed to parse time string "					   "\"%s\"", value);				return NULL;			}			vp->length = 4;			break;		case PW_TYPE_ABINARY:#ifdef ASCEND_BINARY			if (strncasecmp(value, "0x", 2) == 0) {				vp->type = PW_TYPE_OCTETS;				goto do_octets;			}						/*			 *	Special case to convert filter to binary			 */			strNcpy(vp->strvalue, value, sizeof(vp->strvalue));		  	if (ascend_parse_filter(vp) < 0 ) {			  fprintf(stderr, "FUCK %s\n", value);				librad_log("failed to parse Ascend binary attribute: %s",					   librad_errstr);				return NULL;			}			break;			/*			 *	If Ascend binary is NOT defined,			 *	then fall through to raw octets, so that			 *	the user can at least make them by hand...			 */	do_octets:#endif			/* raw octets: 0x01020304... */		case PW_TYPE_OCTETS:			if (strncasecmp(value, "0x", 2) == 0) {				uint8_t *us;				cp = value + 2;				us = vp->strvalue;				vp->length = 0;				/*				 *	There is only one character,				 *	die.				 */				if ((strlen(cp) & 0x01) != 0) {					librad_log("Hex string is not an even length string.");					return NULL;				}												while (*cp && vp->length < MAX_STRING_LEN) {					unsigned int tmp;					if (sscanf(cp, "%02x", &tmp) != 1) {						librad_log("Non-hex characters at %c%c", cp[0], cp[1]);						return NULL;					}					cp += 2;					*(us++) = tmp;					vp->length++;				}				*us = '\0';			}			break;		case PW_TYPE_IFID:			if (ifid_aton(value, vp->strvalue) == NULL) {				librad_log("failed to parse interface-id "					   "string \"%s\"", value);				return NULL;			}			vp->length = 8;			vp->strvalue[vp->length] = '\0';			break;		case PW_TYPE_IPV6ADDR:			if (ipv6_addr(value, vp->strvalue) < 0) {				librad_log("failed to parse IPv6 address "					   "string \"%s\"", value);				return NULL;			}			vp->length = 16; /* length of IPv6 address */			vp->strvalue[vp->length] = '\0';			break;			/*			 *  Anything else.			 */		default:			librad_log("unknown attribute type %d", vp->type);			return NULL;	}	return vp;}/* *	Create a VALUE_PAIR from an ASCII attribute and value, *	where the attribute name is in the form: * *	Attr-%d *	Vendor-%d-Attr-%d */static VALUE_PAIR *pairmake_any(const char *attribute, const char *value,				int operator){	int		attr;	const char	*p;	VALUE_PAIR	*vp;	DICT_ATTR	*da;	/*	 *	Unknown attributes MUST be of type 'octets'	 */	if (value && (strncasecmp(value, "0x", 2) != 0)) {		goto error;	}	/*	 *	Attr-%d	 */	if (strncasecmp(attribute, "Attr-", 5) == 0) {		attr = atoi(attribute + 5);		p = attribute + 5;		p += strspn(p, "0123456789");		if (*p != 0) goto error;		/*		 *	Vendor-%d-Attr-%d		 */	} else if (strncasecmp(attribute, "Vendor-", 7) == 0) {		int vendor;		vendor = atoi(attribute + 7);		if ((vendor == 0) || (vendor > 65535)) goto error;		p = attribute + 7;		p += strspn(p, "0123456789");		/*		 *	Not Vendor-%d-Attr-%d		 */		if (strncasecmp(p, "-Attr-", 6) != 0) goto error;		p += 6;		attr = atoi(p);		p += strspn(p, "0123456789");		if (*p != 0) goto error;		if ((attr == 0) || (attr > 65535)) goto error;		attr |= (vendor << 16);		/*		 *	VendorName-Attr-%d		 */	} else if (((p = strchr(attribute, '-')) != NULL) &&		   (strncasecmp(p, "-Attr-", 6) == 0)) {		int vendor;		char buffer[256];		if ((p - attribute) >= sizeof(buffer)) goto error;		memcpy(buffer, attribute, p - attribute);		buffer[p - attribute] = '\0';		vendor = dict_vendorbyname(buffer);		if (vendor == 0) goto error;		p += 6;		attr = atoi(p);		p += strspn(p, "0123456789");		if (*p != 0) goto error;		if ((attr == 0) || (attr > 65535)) goto error;		attr |= (vendor << 16);	} else {		/* very much unknown: die */	error:		librad_log("Unknown attribute \"%s\"", attribute);		return NULL;	}	/*	 *	We've now parsed the attribute properly, and verified	 *	it to have value 'octets'.  Let's create it.	 */	if ((vp = (VALUE_PAIR *)malloc(sizeof(VALUE_PAIR))) == NULL) {		librad_log("out of memory");		return NULL;	}	memset(vp, 0, sizeof(VALUE_PAIR));	vp->type = PW_TYPE_OCTETS;	/*	 *	It may not be valid hex characters.  If not, die.	 */	if (pairparsevalue(vp, value) == NULL) {		pairfree(&vp);		return NULL;	}	/*	 *	Dictionary type over-rides what the caller says.	 *	This "converts" the parsed value into the appropriate	 *	type.	 *	 *	Also, normalize the name of the attribute...	 *	 *	Much of this code is copied from paircreate()	 */	if ((da = dict_attrbyvalue(attr)) != NULL) {		strcpy(vp->name, da->name);		vp->type = da->type;		vp->flags = da->flags;		/*		 *	Sanity check the type for length.  We don't		 *	want to look at attributes which are of the		 *	wrong length.		 */		switch (vp->type) {		case PW_TYPE_DATE:		case PW_TYPE_INTEGER:		case PW_TYPE_IPADDR: /* always kept in network byte order */			if (vp->length != 4) {			length_error:				pairfree(&vp);				librad_log("Attribute has invalid length");				return NULL;			}			memcpy(&vp->lvalue, vp->strvalue, sizeof(vp->lvalue));			break;		case PW_TYPE_IFID:			if (vp->length != 8) goto length_error;			break;		case PW_TYPE_IPV6ADDR:			if (vp->length != 16) goto length_error;			break;#ifdef ASCEND_BINARY		case PW_TYPE_ABINARY:			if (vp->length != 32) goto length_error;			break;#endif		default:	/* string, octets, etc. */			break;		}	} else if (VENDOR(attr) == 0) {		sprintf(vp->name, "Attr-%u", attr);	} else {		sprintf(vp->name, "Vendor-%u-Attr-%u",			VENDOR(attr), attr & 0xffff);	}	vp->attribute = attr;	vp->operator = (operator == 0) ? T_OP_EQ : operator;	vp->next = NULL;	return vp;}/* *	Create a VALUE_PAIR from an ASCII attribute and value. */VALUE_PAIR *pairmake(const char *attribute, const char *value, int operator){	DICT_ATTR	*da;	VALUE_PAIR	*vp;	char            *tc, *ts;	signed char     tag;	int             found_tag;#ifdef HAVE_REGEX_H	int		res;	regex_t		cre;#endif	/*	 *    Check for tags in 'Attribute:Tag' format.	 */	found_tag = 0;	tag = 0;	ts = strrchr( attribute, ':' );	if (ts && ts[1]) {	         /* Colon found with something behind it */	         if (ts[1] == '*' && ts[2] == 0) {		         /* Wildcard tag for check items */		         tag = TAG_ANY;			 *ts = 0;		 } else if ((ts[1] >= '0') && (ts[1] <= '9')) {		         /* It's not a wild card tag */		         tag = strtol(ts + 1, &tc, 0);			 if (tc && !*tc && TAG_VALID_ZERO(tag))				 *ts = 0;			 else tag = 0;		 } else {			 librad_log("Invalid tag for attribute %s", attribute);			 return NULL;		 }		 found_tag = 1;	}	/*	 *	It's not found in the dictionary, so we use	 *	another method to create the attribute.	 */	if ((da = dict_attrbyname(attribute)) == NULL) {		return pairmake_any(attribute, value, operator);	}	if ((vp = (VALUE_PAIR *)malloc(sizeof(VALUE_PAIR))) == NULL) {		librad_log("out of memory");		return NULL;	}	memset(vp, 0, sizeof(VALUE_PAIR));	vp->attribute = da->attr;	vp->type = da->type;	vp->operator = (operator == 0) ? T_OP_EQ : operator;	strcpy(vp->name, da->name);	vp->flags = da->flags;	vp->next = NULL;	/*      Check for a tag in the 'Merit' format of:	 *      :Tag:Value.  Print an error if we already found	 *      a tag in the Attribute.	 */	if (value && (*value == ':' && da->flags.has_tag)) {	        /* If we already found a tag, this is invalid */	        if(found_tag) {		        pairbasicfree(vp);			librad_log("Duplicate tag %s for attribute %s",				   value, vp->name);			DEBUG("Duplicate tag %s for attribute %s\n",				   value, vp->name);			return NULL;		}	        /* Colon found and attribute allows a tag */	        if (value[1] == '*' && value[2] == ':') {		       /* Wildcard tag for check items */		       tag = TAG_ANY;		       value += 3;		} else {	               /* Real tag */		       tag = strtol(value + 1, &tc, 0);		       if (tc && *tc==':' && TAG_VALID_ZERO(tag))			    value = tc + 1;		       else tag = 0;		}		found_tag = 1;	}	if (found_tag) {	  vp->flags.tag = tag;	}	switch (vp->operator) {	default:		break;		/*		 *      For =* and !* operators, the value is irrelevant		 *      so we return now.		 */	case T_OP_CMP_TRUE:	case T_OP_CMP_FALSE:		vp->strvalue[0] = '\0';		vp->length = 0;	        return vp;		break;		/*		 *	Regular expression comparison of integer attributes		 *	does a STRING comparison of the names of their		 *	integer attributes.		 */	case T_OP_REG_EQ:	/* =~ */	case T_OP_REG_NE:	/* !~ */		if (vp->type == PW_TYPE_INTEGER) {			return vp;		}#ifdef HAVE_REGEX_H		/*		 *	Regular expression match with no regular		 *	expression is wrong.		 */		if (!value) {			pairfree(&vp);			return NULL;		}		res = regcomp(&cre, value, REG_EXTENDED|REG_NOSUB);		if (res != 0) {			char	msg[128];			regerror(res, &cre, msg, sizeof(msg));			librad_log("Illegal regular expression in attribute: %s: %s",				vp->name, msg);			pairbasicfree(vp);			return NULL;		}		regfree(&cre);#else		librad_log("Regelar expressions not enabled in this build, error in attribute %s",				vp->name);		pairbasicfree(vp);		return NULL;#endif	}	if (value && (pairparsevalue(vp, value) == NULL)) {		pairbasicfree(vp);		return NULL;	}	return vp;}/* *	Read a valuepair from a buffer, and advance pointer. *	Sets *eol to T_EOL if end of line was encountered. */VALUE_PAIR *pairread(char **ptr, LRAD_TOKEN *eol){	char		buf[64];	char		attr[64];	char		value[520];	char		*p;	LRAD_TOKEN	token, t, xlat;	VALUE_PAIR	*vp;	*eol = T_INVALID;	/* Get attribute. */	token = gettoken(ptr, attr, sizeof(attr));	/*  If it's a comment, then exit, as we haven't read a pair */	if (token == T_HASH) {		*eol = token;		librad_log("Read a comment instead of a token");		return NULL;	}	/*  It's not a comment, so it MUST be an attribute */	if ((token == T_EOL) ||	    (attr[0] == 0)) {		librad_log("No token read where we expected an attribute name");		return NULL;	}	/* Now we should have an '=' here. */	token = gettoken(ptr, buf, sizeof(buf));	if (token < T_EQSTART || token > T_EQEND) {		librad_log("expecting '='");		return NULL;	}	/* Read value.  Note that empty string values are allowed */	xlat = gettoken(ptr, value, sizeof(value));	if (xlat == T_EOL) {		librad_log("failed to get value");		return NULL;	}	/*	 *	Peek at the next token. Must be T_EOL, T_COMMA, or T_HASH	 */	p = *ptr;	t = gettoken(&p, buf, sizeof(buf));	if (t != T_EOL && t != T_COMMA && t != T_HASH) {		librad_log("Expected end of line or comma");		return NULL;	}	*eol = t;	if (t == T_COMMA) {		*ptr = p;	}	switch (xlat) {		/*		 *	Make the full pair now.		 */	default:		vp = pairmake(attr, value, token);		break;		/*		 *	Perhaps do xlat's		 */	case T_DOUBLE_QUOTED_STRING:		p = strchr(value, '%');		if (p && (p[1] == '{')) {			vp = pairmake(attr, NULL, token);			if (!vp) {				*eol = T_INVALID;				return NULL;			}			strNcpy(vp->strvalue, value, sizeof(vp->strvalue));			vp->flags.do_xlat = 1;			vp->length = 0;		} else {			vp = pairmake(attr, value, token);		}		break;		/*		 *	Mark the pair to be allocated later.		 */	case T_BACK_QUOTED_STRING:		vp = pairmake(attr, NULL, token);		if (!vp) {			*eol = T_INVALID;			return NULL;		}		vp->flags.do_xlat = 1;		strNcpy(vp->strvalue, value, sizeof(vp->strvalue));		vp->length = 0;		break;	}	/*	 *      If we didn't make a pair, return an error.	 */	if (!vp) {		*eol = T_INVALID;		return NULL;	}	return vp;}/* *	Read one line of attribute/value pairs. This might contain *	multiple pairs seperated by comma's. */LRAD_TOKEN userparse(char *buffer, VALUE_PAIR **first_pair){	VALUE_PAIR	*vp;	char		*p;	LRAD_TOKEN	last_token = T_INVALID;	LRAD_TOKEN	previous_token;	/*	 *	We allow an empty line.	 */	if (buffer[0] == 0)		return T_EOL;	p = buffer;	do {		previous_token = last_token;		if ((vp = pairread(&p, &last_token)) == NULL) {			return last_token;		}		pairadd(first_pair, vp);	} while (*p && (last_token == T_COMMA));	/*	 *	Don't tell the caller that there was a comment.	 */	if (last_token == T_HASH) {		return previous_token;	}	/*	 *	And return the last token which we read.	 */	return last_token;}/* *	Read valuepairs from the fp up to End-Of-File. * *	Hmm... this function is only used by radclient.. */VALUE_PAIR *readvp2(FILE *fp, int *pfiledone, const char *errprefix){	char buf[8192];	LRAD_TOKEN last_token = T_EOL;	VALUE_PAIR *vp;	VALUE_PAIR *list;	int error = 0;	list = NULL;	while (!error && fgets(buf, sizeof(buf), fp) != NULL) {		/*		 *      If we get a '\n' by itself, we assume that's		 *      the end of that VP		 */		if ((buf[0] == '\n') && (list)) {			return list;		}		if ((buf[0] == '\n') && (!list)) {			continue;		}		/*		 *	Comments get ignored		 */		if (buf[0] == '#') continue;		/*		 *	Read all of the attributes on the current line.		 */		vp = NULL;		last_token = userparse(buf, &vp);		if (!vp) {			if (last_token != T_EOL) {				librad_perror(errprefix);				error = 1;				break;			}			break;		}		pairadd(&list, vp);		buf[0] = '\0';	}	if (error) pairfree(&list);	*pfiledone = 1;	return error ? NULL: list;}

⌨️ 快捷键说明

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