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

📄 vqp.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		return NULL;	}	ptr = packet->data;	if (0) {		int i;		for (i = 0; i < packet->data_len; i++) {			if ((i & 0x0f) == 0) fprintf(stderr, "%02x: ", i);			fprintf(stderr, "%02x ", ptr[i]);			if ((i & 0x0f) == 0x0f) fprintf(stderr, "\n");		}	  	}	if (ptr[3] > VQP_MAX_ATTRIBUTES) {		librad_log("Too many VQP attributes");		rad_free(&packet);		return NULL;	}	if (packet->data_len > VQP_HDR_LEN) {		int attrlen;		/*		 *	Skip the header.		 */		ptr += VQP_HDR_LEN;		length = packet->data_len - VQP_HDR_LEN;		while (length > 0) {			if (length < 7) {				librad_log("Packet contains malformed attribute");				rad_free(&packet);				return NULL;			}			/*			 *	Attributes are 4 bytes			 *	0x00000c01 ... 0x00000c08			 */			if ((ptr[0] != 0) || (ptr[1] != 0) ||			    (ptr[2] != 0x0c) || (ptr[3] < 1) || (ptr[3] > 8)) {				librad_log("Packet contains invalid attribute");				rad_free(&packet);				return NULL;			}						/*			 *	Length is 2 bytes			 *			 *	We support lengths 1..253, for internal			 *	server reasons.  Also, there's no reason			 *	for bigger lengths to exist... admins			 *	won't be typing in a 32K vlan name.			 */			if ((ptr[4] != 0) || (ptr[5] > 253)) {				librad_log("Packet contains attribute with invalid length %02x %02x", ptr[4], ptr[5]);				rad_free(&packet);				return NULL;			}			attrlen = ptr[5];			ptr += 6 + attrlen;			length -= (6 + attrlen);		}	}	packet->sockfd = sockfd;	packet->vps = NULL;	/*	 *	This is more than a bit of a hack.	 */	packet->code = PW_AUTHENTICATION_REQUEST;	memcpy(&id, packet->data + 4, 4);	packet->id = ntohl(id);	/*	 *	FIXME: Create a fake "request authenticator", to	 *	avoid duplicates?  Or is the VQP sequence number	 *	adequate for this purpose?	 */	return packet;}/* *	We do NOT  mirror the old-style RADIUS code  that does encode, *	sign && send in one function.  For VQP, the caller MUST perform *	each task manually, and separately. */int vqp_send(RADIUS_PACKET *packet){	if (!packet || !packet->data || (packet->data_len < 8)) return -1;	/*	 *	Don't print out the attributes, they were printed out	 *	when it was encoded.	 */	/*	 *	And send it on it's way.	 */	return vqp_sendto(packet->sockfd, packet->data, packet->data_len, 0,			  &packet->src_ipaddr, &packet->dst_ipaddr,			  packet->dst_port);}int vqp_decode(RADIUS_PACKET *packet){	uint8_t *ptr, *end;	int attribute, length;	VALUE_PAIR *vp, **tail;	if (!packet || !packet->data) return -1;	if (packet->data_len < VQP_HDR_LEN) return -1;	tail = &packet->vps;	vp = paircreate(PW_VQP_PACKET_TYPE, PW_TYPE_OCTETS);	if (!vp) {		librad_log("No memory");		return -1;	}	vp->lvalue = packet->data[1];	debug_pair(vp);	*tail = vp;	tail = &(vp->next);	vp = paircreate(PW_VQP_ERROR_CODE, PW_TYPE_OCTETS);	if (!vp) {		librad_log("No memory");		return -1;	}	vp->lvalue = packet->data[2];	debug_pair(vp);	*tail = vp;	tail = &(vp->next);	vp = paircreate(PW_VQP_SEQUENCE_NUMBER, PW_TYPE_OCTETS);	if (!vp) {		librad_log("No memory");		return -1;	}	vp->lvalue = packet->id; /* already set by vqp_recv */	debug_pair(vp);	*tail = vp;	tail = &(vp->next);	ptr = packet->data + VQP_HDR_LEN;	end = packet->data + packet->data_len;	/*	 *	Note that vqp_recv() MUST ensure that the packet is	 *	formatted in a way we expect, and that vqp_recv() MUST	 *	be called before vqp_decode().	 */	while (ptr < end) {		attribute = (ptr[2] << 8) | ptr[3];		length = ptr[5];		ptr += 6;		/*		 *	Hack to get the dictionaries to work correctly.		 */		attribute |= 0x2000;		vp = paircreate(attribute, PW_TYPE_OCTETS);		if (!vp) {			pairfree(&packet->vps);			librad_log("No memory");			return -1;		}		switch (vp->type) {		case PW_TYPE_IPADDR:			if (length == 4) {				memcpy(&vp->vp_ipaddr, ptr, 4);				vp->length = 4;				break;			}			vp->type = PW_TYPE_OCTETS;			/* FALL-THROUGH */		default:		case PW_TYPE_STRING:		case PW_TYPE_OCTETS:			memcpy(vp->vp_octets, ptr, length);			vp->length = length;			break;		}		ptr += length;		debug_pair(vp);		*tail = vp;		tail = &(vp->next);	}	/*	 *	FIXME: Map attributes to Calling-Station-Id, etc...	 */	return 0;}/* *	These are the MUST HAVE contents for a VQP packet. * *	We don't allow the caller to give less than these, because *	it won't work.  We don't encode more than these, because the *	clients will ignore it. * *	FIXME: Be more generous?  Look for CISCO + VQP attributes? */static int contents[5][VQP_MAX_ATTRIBUTES] = {	{ 0,      0,      0,      0,      0,      0 },	{ 0x0c01, 0x0c02, 0x0c03, 0x0c04, 0x0c07, 0x0c05 }, /* Join request */	{ 0x0c03, 0x0c08, 0,      0,      0,      0 },	/* Join Response */	{ 0x0c01, 0x0c02, 0x0c03, 0x0c04, 0x0c07, 0x0c08 }, /* Reconfirm */	{ 0x0c03, 0x0c08, 0,      0,      0,      0 }};int vqp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original){	int i, code, length;	VALUE_PAIR *vp;	uint8_t *ptr;	VALUE_PAIR	*vps[VQP_MAX_ATTRIBUTES];	if (!packet) {		librad_log("Failed encoding VQP");		return -1;	}	if (packet->data) return 0;	vp = pairfind(packet->vps, PW_VQP_PACKET_TYPE);	if (!vp) {		librad_log("Failed to find VQP-Packet-Type in response packet");		return -1;	}	code = vp->lvalue;	if ((code < 1) || (code > 4)) {		librad_log("Invalid value %d for VQP-Packet-Type", code);		return -1;	}	length = VQP_HDR_LEN;	memset(vps, 0, sizeof(vps));	vp = pairfind(packet->vps, PW_VQP_ERROR_CODE);	/*	 *	FIXME: Map attributes from calling-station-Id, etc.	 *	 *	Maybe do this via rlm_vqp?  That's probably the	 *	best place to add the code...	 */	/*	 *	No error: encode attributes.	 */	if (!vp) for (i = 0; i < VQP_MAX_ATTRIBUTES; i++) {		if (!contents[code][i]) break;		vps[i] = pairfind(packet->vps, contents[code][i] | 0x2000);		/*		 *	FIXME: Print the name...		 */		if (!vps[i]) {			librad_log("Failed to find VQP attribute %02x",				   contents[code][i]);			return -1;		}		length += 6;		length += vps[i]->length;	}	packet->data = malloc(length);	if (!packet->data) {		librad_log("No memory");		return -1;	}	packet->data_len = length;	ptr = packet->data;	ptr[0] = VQP_VERSION;	ptr[1] = code;	if (!vp) {		ptr[2] = 0;	} else {		ptr[2] = vp->lvalue & 0xff;		return 0;	}	/*	 *	The number of attributes is hard-coded.	 */	if ((code == 1) || (code == 3)) {		uint32_t sequence;		ptr[3] = VQP_MAX_ATTRIBUTES;		sequence = htonl(packet->id);		memcpy(ptr + 4, &sequence, 4);	} else {		if (!original) {			librad_log("Cannot send VQP response without request");			return -1;		}		/*		 *	Packet Sequence Number		 */		memcpy(ptr + 4, original->data + 4, 4);		ptr[3] = 2;	}	ptr += 8;	/*	 *	Encode the VP's.	 */	for (i = 0; i < VQP_MAX_ATTRIBUTES; i++) {		if (!vps[i]) break;		vp = vps[i];		debug_pair(vp);		/*		 *	Type.  Note that we look at only the lower 8		 *	bits, as the upper 8 bits have been hacked.		 *	See also dictionary.vqp		 */		ptr[0] = 0;		ptr[1] = 0;		ptr[2] = 0x0c;		ptr[3] = vp->attribute & 0xff;		/* Length */		ptr[4] = 0;		ptr[5] = vp->length & 0xff;		ptr += 6;		/* Data */		switch (vp->type) {		case PW_TYPE_IPADDR:			memcpy(ptr, &vp->vp_ipaddr, 4);			break;		default:		case PW_TYPE_OCTETS:		case PW_TYPE_STRING:			memcpy(ptr, vp->vp_octets, vp->length);			break;		}		ptr += vp->length;	}	return 0;}#endif

⌨️ 快捷键说明

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