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

📄 rlm_eap_mschapv2.c

📁 free radius编程。完成AAA的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	/*	 *	Done doing EAP proxy stuff.	 */	handler->request->options &= ~RAD_REQUEST_OPTION_PROXY_EAP;	eapmschapv2_compose(handler, response);	data->code = PW_EAP_MSCHAPV2_SUCCESS;	/*	 *	Delete MPPE keys & encryption policy	 *	 *	FIXME: Use intelligent names...	 */	pairdelete(&handler->request->reply->vps, ((311 << 16) | 7));	pairdelete(&handler->request->reply->vps, ((311 << 16) | 8));	pairdelete(&handler->request->reply->vps, ((311 << 16) | 16));	pairdelete(&handler->request->reply->vps, ((311 << 16) | 17));	/*	 *	And we need to challenge the user, not ack/reject them,	 *	so we re-write the ACK to a challenge.  Yuck.	 */	handler->request->reply->code = PW_ACCESS_CHALLENGE;	pairfree(&response);	return 1;}/* *	Authenticate a previously sent challenge. */static int mschapv2_authenticate(void *arg, EAP_HANDLER *handler){	int rcode;	mschapv2_opaque_t *data;	EAP_DS *eap_ds = handler->eap_ds;	VALUE_PAIR *challenge, *response;	/*	 *	Get the User-Password for this user.	 */	rad_assert(handler->request != NULL);	rad_assert(handler->stage == AUTHENTICATE);	data = (mschapv2_opaque_t *) handler->opaque;	/*	 *	Sanity check the response.	 */	if (eap_ds->response->length <= 4) {		radlog(L_ERR, "rlm_eap_mschapv2: corrupted data");		return 0;	}	/*	 *	Switch over the MS-CHAP type.	 */	switch (eap_ds->response->type.data[0]) {		/*		 *	We should get an ACK from the client ONLY if we've		 *	sent them a SUCCESS packet.		 */		case PW_EAP_MSCHAPV2_ACK:		if (data->code != PW_EAP_MSCHAPV2_SUCCESS) {			radlog(L_ERR, "rlm_eap_mschapv2: Unexpected ACK received");			return 0;		}		/*		 *	It's a success.  Don't proxy it.		 */		handler->request->options &= ~RAD_REQUEST_OPTION_PROXY_EAP;		/*		 *	And upon receiving the clients ACK, we do nothing		 *	other than return EAP-Success, with no EAP-MS-CHAPv2		 *	data.		 */		return 1;		break;		/*		 *	We should get a response ONLY after we've sent		 *	a challenge.		 */	case PW_EAP_MSCHAPV2_RESPONSE:		if (data->code != PW_EAP_MSCHAPV2_CHALLENGE) {			radlog(L_ERR, "rlm_eap_mschapv2: Unexpected response received");			return 0;		}		/*		 *	Ensure that we have at least enough data		 *	to do the following checks.		 *		 *	EAP header (4), EAP type, MS-CHAP opcode,		 *	MS-CHAP ident, MS-CHAP data length (2),		 *	MS-CHAP value length.		 */		if (eap_ds->response->length < (4 + 1 + 1 + 1 + 2 + 1)) {			radlog(L_ERR, "rlm_eap_mschapv2: Response is too short");			return 0;		}		/*		 *	The 'value_size' is the size of the response,		 *	which is supposed to be the response (48		 *	bytes) plus 1 byte of flags at the end.		 */		if (eap_ds->response->type.data[4] != 49) {			radlog(L_ERR, "rlm_eap_mschapv2: Response is of incorrect length %d", eap_ds->response->type.data[4]);			return 0;		}		/*		 *	The MS-Length field is 5 + value_size + length		 *	of name, which is put after the response.		 */		if (((eap_ds->response->type.data[2] << 8) | 		     eap_ds->response->type.data[3]) < (5 + 49)) {			radlog(L_ERR, "rlm_eap_mschapv2: Response contains contradictory length %d %d",			      (eap_ds->response->type.data[2] << 8) | 			       eap_ds->response->type.data[3], 5 + 49);			return 0;		}		break;	case PW_EAP_MSCHAPV2_SUCCESS:		/*		 *	It's a success.  Don't proxy it.		 */		handler->request->options &= ~RAD_REQUEST_OPTION_PROXY_EAP;		eap_ds->request->code = PW_EAP_SUCCESS;		return 1;		break;		/*		 *	Something else, we don't know what it is.		 */	default:		radlog(L_ERR, "rlm_eap_mschapv2: Invalid response type %d",		       eap_ds->response->type.data[0]);		return 0;	}	/*	 *	We now know that the user has sent us a response	 *	to the challenge.  Let's try to authenticate it.	 *	 *	We do this by taking the challenge from 'data',	 *	the response from the EAP packet, and creating VALUE_PAIR's	 *	to pass to the 'mschap' module.  This is a little wonky,	 *	but it works.	 */	challenge = pairmake("MS-CHAP-Challenge", "0x00", T_OP_EQ);	if (!challenge) {		radlog(L_ERR, "rlm_eap_mschapv2: out of memory");		return 0;	}	challenge->length = MSCHAPV2_CHALLENGE_LEN;	memcpy(challenge->strvalue, data->challenge, MSCHAPV2_CHALLENGE_LEN);	response = pairmake("MS-CHAP2-Response", "0x00", T_OP_EQ);	if (!response) {		radlog(L_ERR, "rlm_eap_mschapv2: out of memory");		return 0;	}	response->length = MSCHAPV2_RESPONSE_LEN;	memcpy(response->strvalue + 2, &eap_ds->response->type.data[5],	       MSCHAPV2_RESPONSE_LEN - 2);	response->strvalue[0] = eap_ds->response->type.data[1];	response->strvalue[1] = eap_ds->response->type.data[5 + MSCHAPV2_RESPONSE_LEN];	/*	 *	Add the pairs to the request, and call the 'mschap'	 *	module.	 */	pairadd(&handler->request->packet->vps, challenge);	pairadd(&handler->request->packet->vps, response);	/*	 *	If this options is set, then we do NOT authenticate the	 *	user here.  Instead, now that we've added the MS-CHAP	 *	attributes to the request, we STOP, and let the outer	 *	tunnel code handle it.	 *	 *	This means that the outer tunnel code will DELETE the	 *	EAP attributes, and proxy the MS-CHAP attributes to a	 *	home server.	 */	if (handler->request->options & RAD_REQUEST_OPTION_PROXY_EAP) {		char *username = NULL;		eap_tunnel_data_t *tunnel;		rlm_eap_mschapv2_t *inst = (rlm_eap_mschapv2_t *) arg;				/*		 *	Set up the callbacks for the tunnel		 */		tunnel = rad_malloc(sizeof(*tunnel));		memset(tunnel, 0, sizeof(*tunnel));				tunnel->tls_session = arg;		tunnel->callback = mschap_postproxy;				/*		 *	Associate the callback with the request.		 */		rcode = request_data_add(handler->request,					 handler->request->proxy,					 REQUEST_DATA_EAP_TUNNEL_CALLBACK,					 tunnel, free);		rad_assert(rcode == 0);		/*		 *	The State attribute is NOT supposed to		 *	go into the proxied packet, it will confuse		 *	other RADIUS servers, and they will discard		 *	the request.		 *		 *	The PEAP module will take care of adding		 *	the State attribute back, before passing		 *	the handler & request back into the tunnel.		 */		pairdelete(&handler->request->packet->vps, PW_STATE);		/*		 *	Fix the User-Name when proxying, to strip off		 *	the NT Domain, if we're told to, and a User-Name		 *	exists, and there's a \\, meaning an NT-Domain		 *	in the user name, THEN discard the user name.		 */		if (inst->with_ntdomain_hack &&		    ((challenge = pairfind(handler->request->packet->vps,					   PW_USER_NAME)) != NULL) &&		    ((username = strchr(challenge->strvalue, '\\')) != NULL)) {			/*			 *	Wipe out the NT domain.			 *			 *	FIXME: Put it into MS-CHAP-Domain?			 */			username++; /* skip the \\ */			memmove(challenge->strvalue,				username,				strlen(username) + 1); /* include \0 */			challenge->length = strlen(challenge->strvalue);		}		/*		 *	Remember that in the post-proxy stage, we've got		 *	to do the work below, AFTER the call to MS-CHAP		 *	authentication...		 */		return 1;	}	/*	 *	This is a wild & crazy hack.	 */	rcode = module_authenticate(PW_AUTHTYPE_MS_CHAP, handler->request);	/*	 *	Delete MPPE keys & encryption policy.  We don't	 *	want these here.	 */	pairdelete(&handler->request->reply->vps, ((311 << 16) | 7));	pairdelete(&handler->request->reply->vps, ((311 << 16) | 8));	pairdelete(&handler->request->reply->vps, ((311 << 16) | 16));	pairdelete(&handler->request->reply->vps, ((311 << 16) | 17));	/*	 *	Take the response from the mschap module, and	 *	return success or failure, depending on the result.	 */	if (rcode == RLM_MODULE_OK) {		response = paircopy2(handler->request->reply->vps,				     PW_MSCHAP2_SUCCESS);		data->code = PW_EAP_MSCHAPV2_SUCCESS;	} else {		/*		 *	Don't return anything in the error message.		 */		eap_ds->request->code = PW_EAP_FAILURE;		return 1;#if 0		response = paircopy2(handler->request->reply->vps,				     PW_MSCHAP_ERROR);		data->code = PW_EAP_MSCHAPV2_FAILURE;#endif	}	/*	 *	No response, die.	 */	if (!response) {		radlog(L_ERR, "rlm_eap_mschapv2: No MS-CHAPv2-Success or MS-CHAP-Error was found.");		return 0;	}	/*	 *	Compose the response (whatever it is),	 *	and return it to the over-lying EAP module.	 */	eapmschapv2_compose(handler, response);	pairfree(&response);	return 1;}/* *	The module name should be the only globally exported symbol. *	That is, everything else should be 'static'. */EAP_TYPE rlm_eap_mschapv2 = {	"eap_mschapv2",	mschapv2_attach,		/* attach */	mschapv2_initiate,	        /* Start the initial request */	NULL,				/* authorization */	mschapv2_authenticate,		/* authentication */	mschapv2_detach			/* detach */};

⌨️ 快捷键说明

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