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

📄 peap.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * peap.c contains the interfaces that are called from eap * * Version:     $Id: peap.c,v 1.36 2008/03/07 09:53:26 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * *   Copyright 2003 Alan DeKok <aland@freeradius.org> *   Copyright 2006 The FreeRADIUS server project */#include <freeradius-devel/ident.h>RCSID("$Id: peap.c,v 1.36 2008/03/07 09:53:26 aland Exp $")#include "eap_peap.h"/* *	Send protected EAP-Failure * *       Result-TLV = Failure */static int eappeap_failure(EAP_HANDLER *handler, tls_session_t *tls_session){	uint8_t tlv_packet[11];	DEBUG2("  rlm_eap_peap: FAILURE");	tlv_packet[0] = PW_EAP_REQUEST;	tlv_packet[1] = handler->eap_ds->response->id +1;	tlv_packet[2] = 0;	tlv_packet[3] = 11;	/* length of this packet */	tlv_packet[4] = PW_EAP_TLV;	tlv_packet[5] = 0x80;	tlv_packet[6] = EAP_TLV_ACK_RESULT;	tlv_packet[7] = 0;	tlv_packet[8] = 2;	/* length of the data portion */	tlv_packet[9] = 0;	tlv_packet[10] = EAP_TLV_FAILURE;	(tls_session->record_plus)(&tls_session->clean_in, tlv_packet, 11);	/*	 *	FIXME: Check the return code.	 */	tls_handshake_send(tls_session);	return 1;}/* *	Send protected EAP-Success * *       Result-TLV = Success */static int eappeap_success(EAP_HANDLER *handler, tls_session_t *tls_session){	uint8_t tlv_packet[11];	DEBUG2("  rlm_eap_peap: SUCCESS");	tlv_packet[0] = PW_EAP_REQUEST;	tlv_packet[1] = handler->eap_ds->response->id +1;	tlv_packet[2] = 0;	tlv_packet[3] = 11;	/* length of this packet */	tlv_packet[4] = PW_EAP_TLV;	tlv_packet[5] = 0x80;	/* mandatory AVP */	tlv_packet[6] = EAP_TLV_ACK_RESULT;	tlv_packet[7] = 0;	tlv_packet[8] = 2;	/* length of the data portion */	tlv_packet[9] = 0;	tlv_packet[10] = EAP_TLV_SUCCESS;	(tls_session->record_plus)(&tls_session->clean_in, tlv_packet, 11);	/*	 *	FIXME: Check the return code.	 */	tls_handshake_send(tls_session);	return 1;}/* *	Verify the tunneled EAP message. */static int eapmessage_verify(const uint8_t *data, unsigned int data_len){	const eap_packet_t *eap_packet = (const eap_packet_t *) data;	uint8_t eap_type;	char buffer[256];	if (!data || (data_len <= 1)) {		return 0;	}	eap_type = *data;	switch (eap_type) {	case PW_EAP_IDENTITY:		DEBUG2("  rlm_eap_peap: Identity - %*s",		       data_len - 1, data + 1);		return 1;		break;		/*		 *	If the first byte of the packet is		 *	EAP-Response, and the EAP data is a TLV,		 *	then it looks OK...		 */	case PW_EAP_RESPONSE:		if (eap_packet->data[0] == PW_EAP_TLV) {			DEBUG2("  rlm_eap_peap: Received EAP-TLV response.");			return 1;		}		DEBUG2("  rlm_eap_peap: Got something weird.");		break;		/*		 *	We normally do Microsoft MS-CHAPv2 (26), versus		 *	Cisco MS-CHAPv2 (29).		 */	case PW_EAP_MSCHAPV2:	default:		DEBUG2("  rlm_eap_peap: EAP type %s",		       eaptype_type2name(eap_type,					 buffer, sizeof(buffer)));		return 1;		break;	}	return 0;}/* *	Convert a pseudo-EAP packet to a list of VALUE_PAIR's. */static VALUE_PAIR *eap2vp(EAP_DS *eap_ds,			  const uint8_t *data, size_t data_len){	size_t total;	VALUE_PAIR *vp = NULL, *head, **tail;	if (data_len > 65535) return NULL; /* paranoia */	vp = paircreate(PW_EAP_MESSAGE, PW_TYPE_OCTETS);	if (!vp) {		DEBUG2("  rlm_eap_peap: Failure in creating VP");		return NULL;	}	total = data_len;	if (total > 249) total = 249;	/*	 *	Hand-build an EAP packet from the crap in PEAP version 0.	 */	vp->vp_octets[0] = PW_EAP_RESPONSE;	vp->vp_octets[1] = eap_ds->response->id;	vp->vp_octets[2] = (data_len + EAP_HEADER_LEN) >> 8;	vp->vp_octets[3] = (data_len + EAP_HEADER_LEN) & 0xff;	memcpy(vp->vp_octets + EAP_HEADER_LEN, data, total);	vp->length = EAP_HEADER_LEN + total;	head = vp;	tail = &(vp->next);	while (total < data_len) {		int vp_len;		vp = paircreate(PW_EAP_MESSAGE, PW_TYPE_OCTETS);		if (!vp) {			DEBUG2("  rlm_eap_peap: Failure in creating VP");			pairfree(&head);			return NULL;		}		vp_len = (data_len - total);		if (vp_len > 253) vp_len = 253;		memcpy(vp->vp_octets, data + total, vp_len);		vp->length = vp_len;				total += vp_len;		*tail = vp;		tail = &(vp->next);	}	return head;}/* *	Convert a list of VALUE_PAIR's to an EAP packet, through the *	simple expedient of dumping the EAP message */static int vp2eap(tls_session_t *tls_session, VALUE_PAIR *vp){	/*	 *	Skip the id, code, and length.  Just write the EAP	 *	type & data to the client.	 */#ifndef NDEBUG	if ((debug_flag > 2) && fr_log_fp) {		size_t i, total;		VALUE_PAIR *this;		total = 0;		for (this = vp; this != NULL; this = this->next) {			int start = 0;			if (this == vp) start = EAP_HEADER_LEN;						for (i = start; i < vp->length; i++) {				if ((total & 0x0f) == 0) fprintf(fr_log_fp, "  PEAP tunnel data out %04x: ", total);				fprintf(fr_log_fp, "%02x ", vp->vp_octets[i]);								if ((total & 0x0f) == 0x0f) fprintf(fr_log_fp, "\n");				total++;			}		}		if ((total & 0x0f) != 0) fprintf(fr_log_fp, "\n");	}#endif	/*	 *	Send the EAP data, WITHOUT the header.	 */	(tls_session->record_plus)(&tls_session->clean_in,				   vp->vp_octets + EAP_HEADER_LEN,				   vp->length - EAP_HEADER_LEN);		/*	 *	Send the rest of the EAP data.	 */	for (vp = vp->next; vp != NULL; vp = vp->next) {		(tls_session->record_plus)(&tls_session->clean_in,					   vp->vp_octets, vp->length);	}	tls_handshake_send(tls_session);	return 1;}/* *	See if there's a TLV in the response. */static int eappeap_check_tlv(const uint8_t *data){	const eap_packet_t *eap_packet = (const eap_packet_t *) data;	/*	 *	Look for success or failure.	 */	if ((eap_packet->code == PW_EAP_RESPONSE) &&	    (eap_packet->data[0] == PW_EAP_TLV)) {		if (data[10] == EAP_TLV_SUCCESS) {			return 1;		}		if (data[10] == EAP_TLV_FAILURE) {			DEBUG2("  rlm_eap_peap: Client rejected our response.  The password is probably incorrect.");			return 0;		}	}	return 0;}/* *	Use a reply packet to determine what to do. */static int process_reply(EAP_HANDLER *handler, tls_session_t *tls_session,			 UNUSED REQUEST *request, RADIUS_PACKET *reply){	int rcode = RLM_MODULE_REJECT;	VALUE_PAIR *vp;	peap_tunnel_t *t = tls_session->opaque;#ifndef NDEBUG	if ((debug_flag > 0) && fr_log_fp) {		fprintf(fr_log_fp, "  PEAP: Processing from tunneled session code %p %d\n",		       reply, reply->code);		debug_pair_list(reply->vps);	}#endif	switch (reply->code) {	case PW_AUTHENTICATION_ACK:		DEBUG2("  PEAP: Tunneled authentication was successful.");		t->status = PEAP_STATUS_SENT_TLV_SUCCESS;		eappeap_success(handler, tls_session);		rcode = RLM_MODULE_HANDLED;		/*		 *	If we've been told to use the attributes from		 *	the reply, then do so.		 *		 *	WARNING: This may leak information about the		 *	tunneled user!		 */		if (t->use_tunneled_reply) {			DEBUG2("  Saving tunneled attributes for later");			/*			 *	Clean up the tunneled reply.			 */			pairdelete(&reply->vps, PW_PROXY_STATE);			pairdelete(&reply->vps, PW_EAP_MESSAGE);			pairdelete(&reply->vps, PW_MESSAGE_AUTHENTICATOR);			t->accept_vps = reply->vps;			reply->vps = NULL;		}		break;	case PW_AUTHENTICATION_REJECT:		DEBUG2("  PEAP: Tunneled authentication was rejected.");		t->status = PEAP_STATUS_SENT_TLV_FAILURE;		eappeap_failure(handler, tls_session);		rcode = RLM_MODULE_HANDLED;		break;	case PW_ACCESS_CHALLENGE:		DEBUG2("  PEAP: Got tunneled Access-Challenge");		/*		 *	Keep the State attribute, if necessary.		 *		 *	Get rid of the old State, too.		 */		pairfree(&t->state);		pairmove2(&t->state, &(reply->vps), PW_STATE);		/*		 *	PEAP takes only EAP-Message attributes inside		 *	of the tunnel.  Any Reply-Message in the		 *	Access-Challenge is ignored.		 */		vp = NULL;		pairmove2(&vp, &(reply->vps), PW_EAP_MESSAGE);		/*		 *	Handle EAP-MSCHAP-V2, where Access-Accept's		 *	from the home server may contain MS-CHAP-Success,		 *	which the module turns into challenges, so that		 *	the client may respond to the challenge with		 *	an "ack" packet.		 */		if (t->home_access_accept && t->use_tunneled_reply) {			DEBUG2("  Saving tunneled attributes for later");			/*			 *	Clean up the tunneled reply.			 */			pairdelete(&reply->vps, PW_PROXY_STATE);			pairdelete(&reply->vps, PW_MESSAGE_AUTHENTICATOR);			t->accept_vps = reply->vps;			reply->vps = NULL;		}		/*		 *	Handle the ACK, by tunneling any necessary reply		 *	VP's back to the client.		 */		if (vp) {			vp2eap(tls_session, vp);			pairfree(&vp);		}		rcode = RLM_MODULE_HANDLED;		break;	default:		DEBUG2("  PEAP: Unknown RADIUS packet type %d: rejecting tunneled user", reply->code);		rcode = RLM_MODULE_REJECT;		break;	}	return rcode;}/* *	Do post-proxy processing, */static int eappeap_postproxy(EAP_HANDLER *handler, void *data){	int rcode;	tls_session_t *tls_session = (tls_session_t *) data;	REQUEST *fake;	DEBUG2("  PEAP: Passing reply from proxy back into the tunnel.");	/*	 *	If there was a fake request associated with the proxied	 *	request, do more processing of it.	 */	fake = (REQUEST *) request_data_get(handler->request,					    handler->request->proxy,					    REQUEST_DATA_EAP_MSCHAP_TUNNEL_CALLBACK);	/*	 *	Do the callback, if it exists, and if it was a success.	 */	if (fake && (handler->request->proxy_reply->code == PW_AUTHENTICATION_ACK)) {		REQUEST *request = handler->request;		peap_tunnel_t *t = tls_session->opaque;		t->home_access_accept = TRUE;		/*		 *	Terrible hacks.		 */		rad_assert(fake->packet == NULL);		fake->packet = request->proxy;		fake->packet->src_ipaddr = request->packet->src_ipaddr;		request->proxy = NULL;		rad_assert(fake->reply == NULL);		fake->reply = request->proxy_reply;		request->proxy_reply = NULL;		/*		 *	Perform a post-auth stage, which will get the EAP		 *	handler, too...		 */		fake->options &= ~RAD_REQUEST_OPTION_PROXY_EAP;		DEBUG2("  PEAP: Passing reply back for EAP-MS-CHAP-V2");		rcode = module_post_proxy(0, fake);		/*		 *	FIXME: If rcode returns fail, do something		 *	intelligent...		 */		rcode = rad_postauth(fake);#ifndef NDEBUG		if ((debug_flag > 0) && fr_log_fp) {			fprintf(fr_log_fp, "  PEAP: Final reply from tunneled session code %d\n",			       fake->reply->code);			debug_pair_list(fake->reply->vps);		}#endif		/*		 *	Terrible hacks.		 */		request->proxy = fake->packet;		fake->packet = NULL;		request->proxy_reply = fake->reply;		fake->reply = NULL;		/*		 *	And we're done with this request.		 */		switch (rcode) {                case RLM_MODULE_FAIL:			request_free(&fake);			eaptls_fail(handler->eap_ds, 0);			return 0;			break;

⌨️ 快捷键说明

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