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

📄 peap.c

📁 freeradius-server-2.1.3.tar.gz安装源文件
💻 C
📖 第 1 页 / 共 2 页
字号:
	/*	 *	If there was no EAP-Message in the reply packet, then	 *	we know that we're supposed to re-run the "authenticate"	 *	stage, in order to get the right kind of handling...	 */	/*	 *	Process the reply from the home server.	 */	rcode = process_reply(handler, tls_session, handler->request,			      handler->request->proxy_reply);	/*	 *	The proxy code uses the reply from the home server as	 *	the basis for the reply to the NAS.  We don't want that,	 *	so we toss it, after we've had our way with it.	 */	pairfree(&handler->request->proxy_reply->vps);	switch (rcode) {	case RLM_MODULE_REJECT:		RDEBUG2("Reply was rejected");		eaptls_fail(handler, 0);		return 0;	case RLM_MODULE_HANDLED:		RDEBUG2("Reply was handled");		eaptls_request(handler->eap_ds, tls_session);		return 1;	case RLM_MODULE_OK:		RDEBUG2("Reply was OK");		/*		 *	Success: Automatically return MPPE keys.		 */		return eaptls_success(handler, 0);	default:		RDEBUG2("Reply was unknown.");		break;	}	eaptls_fail(handler, 0);	return 0;}/* *	Free a request. */static void my_request_free(void *data){	REQUEST *request = (REQUEST *)data;	request_free(&request);}/* *	Process the pseudo-EAP contents of the tunneled data. */int eappeap_process(EAP_HANDLER *handler, tls_session_t *tls_session){	peap_tunnel_t *t = tls_session->opaque;	REQUEST *fake;	VALUE_PAIR *vp;	int rcode = RLM_MODULE_REJECT;	const uint8_t	*data;	unsigned int data_len;#ifndef NDEBUG	size_t i;#endif	REQUEST *request = handler->request;	EAP_DS *eap_ds = handler->eap_ds;	/*	 *	Just look at the buffer directly, without doing	 *	record_minus.  This lets us avoid another data copy.	 */	data_len = tls_session->clean_out.used;	tls_session->clean_out.used = 0;	data = tls_session->clean_out.data;#ifndef NDEBUG	if ((debug_flag > 2) && fr_log_fp) {		for (i = 0; i < data_len; i++) {			if ((i & 0x0f) == 0) fprintf(fr_log_fp, "  PEAP tunnel data in %04x: ", i);			fprintf(fr_log_fp, "%02x ", data[i]);			if ((i & 0x0f) == 0x0f) fprintf(fr_log_fp, "\n");		}		if ((data_len & 0x0f) != 0) fprintf(fr_log_fp, "\n");	}#endif	if (!eapmessage_verify(request, data, data_len)) {		RDEBUG2("Tunneled data is invalid.");		return RLM_MODULE_REJECT;	}	/*	 *	If we authenticated the user, then it's OK.	 */	if (t->status == PEAP_STATUS_SENT_TLV_SUCCESS) {		if (eappeap_check_tlv(request, data)) {			RDEBUG2("Success");			return RLM_MODULE_OK;		}		/*		 *	Otherwise, the client rejected the session		 *	resumption.  If the session is being re-used,		 *	we need to do a full authentication.		 *		 *	We do this by sending an EAP-Identity request		 *	inside of the PEAP tunnel.		 */		if ((t->session_resumption_state != PEAP_RESUMPTION_NO) &&		    SSL_session_reused(tls_session->ssl)) {			eap_packet_t eap_packet;						RDEBUG2("Client rejected session resumption.  Re-starting full authentication");			eap_packet.code = PW_EAP_REQUEST;			eap_packet.id = handler->eap_ds->response->id + 1;			eap_packet.length[0] = 0;			eap_packet.length[1] = EAP_HEADER_LEN + 1;			eap_packet.data[0] = PW_EAP_IDENTITY;						/*			 *	Mark session resumption status.			 */			t->status = 0;			t->session_resumption_state = PEAP_RESUMPTION_NO;						(tls_session->record_plus)(&tls_session->clean_in,						   &eap_packet,						   sizeof(eap_packet));			tls_handshake_send(tls_session);			return RLM_MODULE_HANDLED;		}		return RLM_MODULE_REJECT;	}	if (t->status == PEAP_STATUS_SENT_TLV_FAILURE) {		RDEBUG2(" Had sent TLV failure.  User was rejected earlier in this session.");		return RLM_MODULE_REJECT;	}	fake = request_alloc_fake(request);	rad_assert(fake->packet->vps == NULL);	fake->packet->vps = eap2vp(request, eap_ds, data, data_len);	if (!fake->packet->vps) {		request_free(&fake);		RDEBUG2("Unable to convert tunneled EAP packet to internal server data structures");		return PW_AUTHENTICATION_REJECT;	}	if ((debug_flag > 0) && fr_log_fp) {		RDEBUG("Got tunneled request");				debug_pair_list(fake->packet->vps);		fprintf(fr_log_fp, "server %s {\n",			(fake->server == NULL) ? "" : fake->server);	}	/*	 *	Tell the request that it's a fake one.	 */	vp = pairmake("Freeradius-Proxied-To", "127.0.0.1", T_OP_EQ);	if (vp) {		pairadd(&fake->packet->vps, vp);	}	/*	 *	Update other items in the REQUEST data structure.	 */	if (!t->username) {		/*		 *	There's no User-Name in the tunneled session,		 *	so we add one here, by pulling it out of the		 *	EAP-Identity packet.		 */		if ((data[0] == PW_EAP_IDENTITY) && (data_len > 1)) {			t->username = pairmake("User-Name", "", T_OP_EQ);			rad_assert(t->username != NULL);			memcpy(t->username->vp_strvalue, data + 1, data_len - 1);			t->username->length = data_len - 1;			t->username->vp_strvalue[t->username->length] = 0;			DEBUG2("  PEAP: Got tunneled identity of %s", t->username->vp_strvalue);			/*			 *	If there's a default EAP type,			 *	set it here.			 */			if (t->default_eap_type != 0) {				DEBUG2("  PEAP: Setting default EAP type for tunneled EAP session.");				vp = pairmake("EAP-Type", "0", T_OP_EQ);				vp->vp_integer = t->default_eap_type;				pairadd(&fake->config_items, vp);			}		}	} /* else there WAS a t->username */	if (t->username) {		vp = paircopy(t->username);		pairadd(&fake->packet->vps, vp);		fake->username = pairfind(fake->packet->vps, PW_USER_NAME);		DEBUG2("  PEAP: Setting User-Name to %s",		       fake->username->vp_strvalue);	}	/*	 *	Add the State attribute, too, if it exists.	 */	if (t->state) {		vp = paircopy(t->state);		if (vp) pairadd(&fake->packet->vps, vp);	}	/*	 *	If this is set, we copy SOME of the request attributes	 *	from outside of the tunnel to inside of the tunnel.	 *	 *	We copy ONLY those attributes which do NOT already	 *	exist in the tunneled request.	 *	 *	This code is copied from ../rlm_eap_ttls/ttls.c	 */	if (t->copy_request_to_tunnel) {		VALUE_PAIR *copy;		for (vp = request->packet->vps; vp != NULL; vp = vp->next) {			/*			 *	The attribute is a server-side thingy,			 *	don't copy it.			 */			if ((vp->attribute > 255) &&			    (((vp->attribute >> 16) & 0xffff) == 0)) {				continue;			}			/*			 *	The outside attribute is already in the			 *	tunnel, don't copy it.			 *			 *	This works for BOTH attributes which			 *	are originally in the tunneled request,			 *	AND attributes which are copied there			 *	from below.			 */			if (pairfind(fake->packet->vps, vp->attribute)) {				continue;			}			/*			 *	Some attributes are handled specially.			 */			switch (vp->attribute) {				/*				 *	NEVER copy Message-Authenticator,				 *	EAP-Message, or State.  They're				 *	only for outside of the tunnel.				 */			case PW_USER_NAME:			case PW_USER_PASSWORD:			case PW_CHAP_PASSWORD:			case PW_CHAP_CHALLENGE:			case PW_PROXY_STATE:			case PW_MESSAGE_AUTHENTICATOR:			case PW_EAP_MESSAGE:			case PW_STATE:				continue;				break;				/*				 *	By default, copy it over.				 */			default:				break;			}			/*			 *	Don't copy from the head, we've already			 *	checked it.			 */			copy = paircopy2(vp, vp->attribute);			pairadd(&fake->packet->vps, copy);		}	}	if ((vp = pairfind(request->config_items, PW_VIRTUAL_SERVER)) != NULL) {		fake->server = vp->vp_strvalue;	} else if (t->virtual_server) {		fake->server = t->virtual_server;	} /* else fake->server == request->server */	if ((debug_flag > 0) && fr_log_fp) {		fprintf(fr_log_fp, "Sending tunneled request\n");		debug_pair_list(fake->packet->vps);		fprintf(fr_log_fp, "server %s {\n",			(fake->server == NULL) ? "" : fake->server);	}	/*	 *	Call authentication recursively, which will	 *	do PAP, CHAP, MS-CHAP, etc.	 */	rad_authenticate(fake);	/*	 *	Note that we don't do *anything* with the reply	 *	attributes.	 */	if ((debug_flag > 0) && fr_log_fp) {		fprintf(fr_log_fp, "} # server %s\n",			(fake->server == NULL) ? "" : fake->server);		RDEBUG("Got tunneled reply code %d", fake->reply->code);				debug_pair_list(fake->reply->vps);	}	/*	 *	Decide what to do with the reply.	 */	switch (fake->reply->code) {	case 0:			/* No reply code, must be proxied... */		vp = pairfind(fake->config_items, PW_PROXY_TO_REALM);		if (vp) {			eap_tunnel_data_t *tunnel;			/*			 *	The tunneled request was NOT handled,			 *	it has to be proxied.  This means that			 *	the "authenticate" stage was never			 *	performed.			 *			 *	If we are told to NOT proxy the			 *	tunneled request as EAP, then this			 *	means that we've got to decode it,			 *	which means that we MUST run the			 *	"authenticate" portion by hand, here.			 *			 *	Once the tunneled EAP session is ALMOST			 *	done, THEN we proxy it...			 */			if (!t->proxy_tunneled_request_as_eap) {				fake->options |= RAD_REQUEST_OPTION_PROXY_EAP;				/*				 *	Hmm... should we check for				 *	Auth-Type & EAP-Message here?				 */				/*				 *	Run the EAP authentication.				 */				DEBUG2("  PEAP: Calling authenticate in order to initiate tunneled EAP session.");				rcode = module_authenticate(PW_AUTHTYPE_EAP, fake);				if (rcode == RLM_MODULE_OK) {					/*					 *	Authentication succeeded! Rah!					 */					fake->reply->code = PW_AUTHENTICATION_ACK;					goto do_process;				}				if (rcode != RLM_MODULE_HANDLED) {					DEBUG2("  PEAP: Can't handle the return code %d", rcode);					rcode = RLM_MODULE_REJECT;					goto done;				}				/*				 *	The module decided it wasn't				 *	done.  Handle it like normal.				 */				if ((fake->options & RAD_REQUEST_OPTION_PROXY_EAP) == 0) {					DEBUG2("    PEAP: Cancelling proxy to realm %s until the tunneled EAP session has been established", vp->vp_strvalue);					goto do_process;				}				/*				 *	The module has decoded the				 *	EAP-Message into another set				 *	of attributes.				 */				pairdelete(&fake->packet->vps,					   PW_EAP_MESSAGE);			}			DEBUG2("  PEAP: Tunneled authentication will be proxied to %s", vp->vp_strvalue);			/*			 *	Tell the original request that it's going			 *	to be proxied.			 */			pairmove2(&(request->config_items),				  &(fake->config_items),				  PW_PROXY_TO_REALM);			/*			 *	Seed the proxy packet with the			 *	tunneled request.			 */			rad_assert(request->proxy == NULL);			request->proxy = fake->packet;			fake->packet = NULL;			rad_free(&fake->reply);			fake->reply = NULL;			/*			 *	Set up the callbacks for the tunnel			 */			tunnel = rad_malloc(sizeof(*tunnel));			memset(tunnel, 0, sizeof(*tunnel));			tunnel->tls_session = tls_session;			tunnel->callback = eappeap_postproxy;			/*			 *	Associate the callback with the request.			 */			rcode = request_data_add(request,						 request->proxy,						 REQUEST_DATA_EAP_TUNNEL_CALLBACK,						 tunnel, free);			rad_assert(rcode == 0);			/*			 *	We're not proxying it as EAP, so we've got			 *	to do the callback later.			 */			if ((fake->options & RAD_REQUEST_OPTION_PROXY_EAP) != 0) {				DEBUG2("  PEAP: Remembering to do EAP-MS-CHAP-V2 post-proxy.");				/*				 *	rlm_eap.c has taken care of associating				 *	the handler with the fake request.				 *				 *	So we associate the fake request with				 *	this request.				 */				rcode = request_data_add(request,							 request->proxy,							 REQUEST_DATA_EAP_MSCHAP_TUNNEL_CALLBACK,							 fake, my_request_free);				rad_assert(rcode == 0);				/*				 *	Do NOT free the fake request!				 */				return RLM_MODULE_UPDATED;			}			/*			 *	Didn't authenticate the packet, but			 *	we're proxying it.			 */			rcode = RLM_MODULE_UPDATED;		} else {			DEBUG2("  PEAP: Unknown RADIUS packet type %d: rejecting tunneled user", fake->reply->code);			rcode = RLM_MODULE_REJECT;		}		break;	default:	do_process:		rcode = process_reply(handler, tls_session, request,				      fake->reply);		break;	} done:	request_free(&fake);	return rcode;}

⌨️ 快捷键说明

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