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

📄 peap.c

📁 radius服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
		DEBUG2("  PEAP: Reply was OK");		eaptls_success(handler->eap_ds, 0);		eaptls_gen_mppe_keys(&handler->request->reply->vps,				     tls_session->ssl,				     "client EAP encryption");		return 1;	default:		DEBUG2("  PEAP: Reply was unknown.");		break;	}	eaptls_fail(handler->eap_ds, 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){	int err;	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;	unsigned char buffer[1024];#ifndef NDEBUG	int i;#endif	REQUEST *request = handler->request;	EAP_DS *eap_ds = handler->eap_ds;	/*	 *	Grab the dirty data, and copy it to our buffer.	 *	 *	I *really* don't like these 'record_t' things...	 */	data_len = record_minus(&tls_session->dirty_in, buffer, sizeof(buffer));	data = buffer;	/*	 *	Write the data from the dirty buffer (i.e. packet	 *	data) into the buffer which we will give to SSL for	 *	decoding.	 *	 *	Some of this code COULD technically go into the TLS	 *	module, in eaptls_process(), where it returns EAPTLS_OK.	 *	 *	Similarly, the writing of data to the SSL context could	 *	go there, too...	 */	BIO_write(tls_session->into_ssl, buffer, data_len);	record_init(&tls_session->clean_out);	/*	 *	Read (and decrypt) the tunneled data from the SSL session,	 *	and put it into the decrypted data buffer.	 */	err = SSL_read(tls_session->ssl, tls_session->clean_out.data,		       sizeof(tls_session->clean_out.data));	if (err < 0) {		/*		 *	FIXME: Call SSL_get_error() to see what went		 *	wrong.		 */		radlog(L_INFO, "rlm_eap_peap: SSL_read Error");		return RLM_MODULE_REJECT;	}	/*	 *	If there's no data, maybe this is an ACK to an	 *	MS-CHAP2-Success.	 */	if (err == 0) {		/*		 *	FIXME: Call SSL_get_error() to see what went		 *	wrong.		 */		radlog(L_INFO, "rlm_eap_peap: No data inside of the tunnel.");		return RLM_MODULE_REJECT;	}	data_len = tls_session->clean_out.used = err;	data = tls_session->clean_out.data;#ifndef NDEBUG	if (debug_flag > 2) {		for (i = 0; i < data_len; i++) {			if ((i & 0x0f) == 0) printf("  PEAP tunnel data in %04x: ", i);			printf("%02x ", data[i]);			if ((i & 0x0f) == 0x0f) printf("\n");		}		if ((data_len & 0x0f) != 0) printf("\n");	}#endif	if (!eapmessage_verify(data, data_len)) {		return RLM_MODULE_REJECT;	}	DEBUG2("  rlm_eap_peap: Tunneled data is valid.");	/*	 *	If we authenticated the user, then it's OK.	 */	if (t->status == PEAP_STATUS_SENT_TLV_SUCCESS) {		if (eappeap_check_tlv(data)) {			DEBUG2("  rlm_eap_peap: Success");			return RLM_MODULE_OK;		}		return RLM_MODULE_REJECT;	} else if (t->status == PEAP_STATUS_SENT_TLV_FAILURE) {		DEBUG2("  rlm_eap_peap:  Had sent TLV failure, rejecting.");		return RLM_MODULE_REJECT;	}	fake = request_alloc_fake(request);	rad_assert(fake->packet->vps == NULL);	fake->packet->vps = eap2vp(eap_ds, data, data_len);	if (!fake->packet->vps) {		DEBUG2("  rlm_eap_peap: Unable to convert tunneled EAP packet to internal server data structures");		return PW_AUTHENTICATION_REJECT;	}#ifndef NDEBUG	if (debug_flag > 0) {	  printf("  PEAP: Got tunneled EAP-Message\n");	  for (vp = fake->packet->vps; vp != NULL; vp = vp->next) {	    putchar('\t');vp_print(stdout, vp);putchar('\n');	  }	}#endif	/*	 *	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->strvalue, data + 1, data_len - 1);			t->username->length = data_len - 1;			t->username->strvalue[t->username->length] = 0;			DEBUG2("  PEAP: Got tunneled identity of %s", t->username->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->lvalue = 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->strvalue);	}	/*	 *	Add the State attribute, too, if it exists.	 */	if (t->state) {		DEBUG2("  PEAP: Adding old state with %02x %02x",		       t->state->strvalue[0], t->state->strvalue[1]);		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);		}	}#ifndef NDEBUG	if (debug_flag > 0) {		printf("  PEAP: Sending tunneled request\n");		for (vp = fake->packet->vps; vp != NULL; vp = vp->next) {			putchar('\t');vp_print(stdout, vp);putchar('\n');		}	}#endif	/*	 *	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.	 */#ifndef NDEBUG	if (debug_flag > 0) {		printf("  PEAP: Got tunneled reply RADIUS code %d\n",		 fake->reply->code);		for (vp = fake->reply->vps; vp != NULL; vp = vp->next) {			putchar('\t');vp_print(stdout, vp);putchar('\n');		}	}#endif	/*	 *	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->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->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 + -