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

📄 eap.c

📁 linux1.0内核的源代码,欢迎大家使用
💻 C
📖 第 1 页 / 共 3 页
字号:
 *	i.e. code+id+length+data where data = null/type+typedata *	based on code. */static int eap_wireformat(EAP_PACKET *reply){	eap_packet_t	*hdr;	uint16_t total_length = 0;	if (reply == NULL) return EAP_INVALID;	total_length = EAP_HEADER_LEN;	if (reply->code < 3) {		total_length += 1/*EAPtype*/;		if (reply->type.data && reply->type.length > 0) {			total_length += reply->type.length;		}	}	reply->packet = (unsigned char *)malloc(total_length);	hdr = (eap_packet_t *)reply->packet;	if (!hdr) {		radlog(L_ERR, "rlm_eap: out of memory");		return EAP_INVALID;	}	hdr->code = (reply->code & 0xFF);	hdr->id = (reply->id & 0xFF);	total_length = htons(total_length);	memcpy(hdr->length, &total_length, sizeof(uint16_t));	/*	 *	Request and Response packets are special.	 */	if ((reply->code == PW_EAP_REQUEST) ||	    (reply->code == PW_EAP_RESPONSE)) {		hdr->data[0] = (reply->type.type & 0xFF);		/*		 * Here since we cannot know the typedata format and length		 *		 * Type_data is expected to be wired by each EAP-Type		 *		 * Zero length/No typedata is supported as long as		 * type is defined		 */		if (reply->type.data && reply->type.length > 0) {			memcpy(&hdr->data[1], reply->type.data, reply->type.length);			free(reply->type.data);			reply->type.data = reply->packet + EAP_HEADER_LEN + 1/*EAPtype*/;		}	}	return EAP_VALID;}/* *	compose EAP reply packet in EAP-Message attr of RADIUS.  If *	EAP exceeds 253, frame it in multiple EAP-Message attrs. * *	Set the RADIUS reply codes based on EAP request codes.  Append *	any additonal VPs to RADIUS reply */int eap_compose(EAP_HANDLER *handler){	uint16_t eap_len, len;	VALUE_PAIR *eap_msg;	VALUE_PAIR *vp;	eap_packet_t *eap_packet;	unsigned char 	*ptr;	REQUEST *request = handler->request;	EAP_DS *eap_ds = handler->eap_ds;	EAP_PACKET *reply = eap_ds->request;	int rcode;	/*	 *	The Id for the EAP packet to the NAS wasn't set.	 *	Do so now.	 *	 *	LEAP requires the Id to be incremented on EAP-Success	 *	in Stage 4, so that we can carry on the conversation	 *	where the client asks us to authenticate ourselves	 *	in stage 5.	 */	if (!eap_ds->set_request_id) {		/*		 *	Id serves to suppport request/response		 *	retransmission in the EAP layer and as such		 *	must be different for 'adjacent' packets		 *	except in case of success/failure-replies.		 *		 *	RFC2716 (EAP-TLS) requires this to be		 *	incremented, RFC2284 only makes the above-		 *	mentioned restriction.		 */		reply->id = handler->eap_ds->response->id;		switch (reply->code) {			/*			 *	The Id is a simple "ack" for success			 *	and failure.			 *			 *	RFC 3748 section 4.2 says			 *			 *	... The Identifier field MUST match			 *	the Identifier field of the Response			 *	packet that it is sent in response			 *	to.			 */		case PW_EAP_SUCCESS:		case PW_EAP_FAILURE:	    		break;			/*			 *	We've sent a response to their			 *	request, the Id is incremented.			 */		default:	    		++reply->id;		}	} else {		DEBUG2("  rlm_eap: Underlying EAP-Type set EAP ID to %d",		       reply->id);	}	/*	 *	For Request & Response packets, set the EAP sub-type,	 *	if the EAP sub-module didn't already set it.	 *	 *	This allows the TLS module to be "morphic", and means	 *	that the TTLS and PEAP modules can call it to do most	 *	of their dirty work.	 */	if (((eap_ds->request->code == PW_EAP_REQUEST) ||	     (eap_ds->request->code == PW_EAP_RESPONSE)) &&	    (eap_ds->request->type.type == 0)) {		rad_assert(handler->eap_type >= PW_EAP_MD5);		rad_assert(handler->eap_type <= PW_EAP_MAX_TYPES);		eap_ds->request->type.type = handler->eap_type;	}	if (eap_wireformat(reply) == EAP_INVALID) {		return RLM_MODULE_INVALID;	}	eap_packet = (eap_packet_t *)reply->packet;	memcpy(&eap_len, &(eap_packet->length), sizeof(uint16_t));	len = eap_len = ntohs(eap_len);	ptr = (unsigned char *)eap_packet;	do {		if (eap_len > 253) {			len = 253;			eap_len -= 253;		} else {			len = eap_len;			eap_len = 0;		}		/*		 * create a value pair & append it to the request reply list		 * This memory gets freed up when request is freed up		 */		eap_msg = paircreate(PW_EAP_MESSAGE, PW_TYPE_OCTETS);		memcpy(eap_msg->strvalue, ptr, len);		eap_msg->length = len;		pairadd(&(request->reply->vps), eap_msg);		ptr += len;		eap_msg = NULL;	} while (eap_len);	/*	 *	EAP-Message is always associated with	 *	Message-Authenticator but not vice-versa.	 *	 *	Don't add a Message-Authenticator if it's already	 *	there.	 */	vp = pairfind(request->reply->vps, PW_MESSAGE_AUTHENTICATOR);	if (!vp) {		vp = paircreate(PW_MESSAGE_AUTHENTICATOR, PW_TYPE_OCTETS);		memset(vp->strvalue, 0, AUTH_VECTOR_LEN);		vp->length = AUTH_VECTOR_LEN;		pairadd(&(request->reply->vps), vp);	}	/* Set request reply code, but only if it's not already set. */	rcode = RLM_MODULE_OK;	if (!request->reply->code) switch(reply->code) {	case PW_EAP_RESPONSE:		request->reply->code = PW_AUTHENTICATION_ACK;		rcode = RLM_MODULE_HANDLED; /* leap weirdness */		break;	case PW_EAP_SUCCESS:		request->reply->code = PW_AUTHENTICATION_ACK;		rcode = RLM_MODULE_OK;		break;	case PW_EAP_FAILURE:		request->reply->code = PW_AUTHENTICATION_REJECT;		rcode = RLM_MODULE_REJECT;		break;	case PW_EAP_REQUEST:		request->reply->code = PW_ACCESS_CHALLENGE;		rcode = RLM_MODULE_HANDLED;		break;	default:		/*		 *	When we're pulling MS-CHAPv2 out of EAP-MS-CHAPv2,		 *	we do so WITHOUT setting a reply code, as the		 *	request is being proxied.		 */		if (request->options & RAD_REQUEST_OPTION_PROXY_EAP) {			return RLM_MODULE_HANDLED;		}		/* Should never enter here */		radlog(L_ERR, "rlm_eap: reply code %d is unknown, Rejecting the request.", reply->code);		request->reply->code = PW_AUTHENTICATION_REJECT;		reply->code = PW_EAP_FAILURE;		rcode = RLM_MODULE_REJECT;		break;	}	return rcode;}/* * Radius criteria, EAP-Message is invalid without Message-Authenticator * For EAP_START, send Access-Challenge with EAP Identity request. */int eap_start(rlm_eap_t *inst, REQUEST *request){	VALUE_PAIR *vp, *proxy;	VALUE_PAIR *eap_msg;	eap_msg = pairfind(request->packet->vps, PW_EAP_MESSAGE);	if (eap_msg == NULL) {		DEBUG2("  rlm_eap: No EAP-Message, not doing EAP");		return EAP_NOOP;	}	/*	 *	Look for EAP-Type = None (FreeRADIUS specific attribute)	 *	this allows you to NOT do EAP for some users.	 */	vp = pairfind(request->packet->vps, PW_EAP_TYPE);	if (vp && vp->lvalue == 0) {		DEBUG2("  rlm_eap: Found EAP-Message, but EAP-Type = None, so we're not doing EAP.");		return EAP_NOOP;	}	/*	 *	http://www.freeradius.org/rfc/rfc2869.html#EAP-Message	 *	 *	Checks for Message-Authenticator are handled by rad_recv().	 */	/*	 *	Check for a Proxy-To-Realm.  Don't get excited over LOCAL	 *	realms (sigh).	 */	proxy = pairfind(request->config_items, PW_PROXY_TO_REALM);	if (proxy) {		REALM *realm;		/*		 *	If it's a LOCAL realm, then we're not proxying		 *	to it.		 */		realm = realm_find(proxy->strvalue, 0);		if (realm && (realm->ipaddr == htonl(INADDR_NONE))) {			proxy = NULL;		}	}	/*	 *	Check the length before de-referencing the contents.	 *	 *	Lengths of zero are required by the RFC for EAP-Start,	 *	but we've never seen them in practice.	 *	 *	Lengths of two are what we see in practice as	 *	EAP-Starts.	 */	if ((eap_msg->length == 0) || (eap_msg->length == 2)) {		EAP_DS *eap_ds;		EAP_HANDLER handler;		/*		 *	It's a valid EAP-Start, but the request		 *	was marked as being proxied.  So we don't		 *	do EAP, as the home server will do it.		 */		if (proxy) {		do_proxy:			DEBUG2("  rlm_eap: Request is supposed to be proxied to Realm %s.  Not doing EAP.", proxy->strvalue);			return EAP_NOOP;		}				DEBUG2("  rlm_eap: Got EAP_START message");		if ((eap_ds = eap_ds_alloc()) == NULL) {			DEBUG2("  rlm_eap: EAP Start failed in allocation");			return EAP_FAIL;		}				/*		 *	It's an EAP-Start packet.  Tell them to stop wasting		 *	our time, and give us an EAP-Identity packet.		 *		 *	Hmm... we should probably check the contents of the		 *	EAP-Start packet for something...		 */		eap_ds->request->code = PW_EAP_REQUEST;		eap_ds->request->type.type = PW_EAP_IDENTITY;				/*		 *	We don't have a handler, but eap_compose needs one,		 *	(for various reasons), so we fake it out here.		 */		memset(&handler, 0, sizeof(handler));		handler.request = request;		handler.eap_ds = eap_ds;				eap_compose(&handler);				eap_ds_free(&eap_ds);		return EAP_FOUND;	} /* end of handling EAP-Start */	/*	 *	The EAP packet header is 4 bytes, plus one byte of	 *	EAP sub-type.  Short packets are discarded, unless	 *	we're proxying.	 */	if (eap_msg->length < (EAP_HEADER_LEN + 1)) {		if (proxy) goto do_proxy;		DEBUG2("  rlm_eap: Ignoring EAP-Message which is too short to be meaningful.");		return EAP_FAIL;	}	/*	 *	Create an EAP-Type containing the EAP-type	 *	from the packet.	 */	vp = paircreate(PW_EAP_TYPE, PW_TYPE_INTEGER);	if (vp) {		vp->lvalue = eap_msg->strvalue[4];		pairadd(&(request->packet->vps), vp);	}	/*	 *	If the request was marked to be proxied, do it now.	 *	This is done after checking for a valid length	 *	(which may not be good), and after adding the EAP-Type	 *	attribute.  This lets other modules selectively cancel	 *	proxying based on EAP-Type.	 */	if (proxy) goto do_proxy;	/*	 *	From now on, we're supposed to be handling the	 *	EAP packet.  We better understand it...	 */	/*	 *	We're allowed only a few codes.  Request, Response,	 *	Success, or Failure.	 */	if ((eap_msg->strvalue[0] == 0) ||	    (eap_msg->strvalue[0] > PW_EAP_MAX_CODES)) {		DEBUG2("  rlm_eap: Unknown EAP packet");	} else {		DEBUG2("  rlm_eap: EAP packet type %s id %d length %d",		       eap_codes[eap_msg->strvalue[0]],

⌨️ 快捷键说明

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