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

📄 rlm_eap2.c

📁 freeradius-server-2.1.3.tar.gz安装源文件
💻 C
📖 第 1 页 / 共 2 页
字号:
	CONF_SECTION	*scs;	inst = (rlm_eap_t *) malloc(sizeof(*inst));	if (!inst) {		return -1;	}	memset(inst, 0, sizeof(*inst));	if (cf_section_parse(cs, inst, module_config) < 0) {		eap_detach(inst);		return -1;	}	/*	 *	Create our own random pool.	 */	for (i = 0; i < 256; i++) {		inst->rand_pool.randrsl[i] = fr_rand();	}	fr_randinit(&inst->rand_pool, 1);	/*	 *	List of sessions are set to NULL by the memset	 *	of 'inst', above.	 */	/*	 *	Lookup sessions in the tree.  We don't free them in	 *	the tree, as that's taken care of elsewhere...	 */	inst->session_tree = rbtree_create(eap_handler_cmp, NULL, 0);	if (!inst->session_tree) {		radlog(L_ERR|L_CONS, "rlm_eap2: Cannot initialize tree");		eap_detach(inst);		return -1;	}	/*	 *	This registers ALL available methods.	 *	 *	FIXME: we probably want to selectively register	 *	some methods.	 */	if (eap_server_register_methods() < 0) {		eap_detach(inst);		return -1;	}	/* Load all the configured EAP-Types */	num_types = 0;	has_tls = do_tls = 0;	for (scs=cf_subsection_find_next(cs, NULL, NULL);		scs != NULL;		scs=cf_subsection_find_next(cs, scs, NULL)) {		const char	*auth_type;		char		buffer[64], *p;		auth_type = cf_section_name1(scs);		if (!auth_type)  continue;		if (num_types >= EAP_MAX_METHODS) {			radlog(L_INFO, "WARNING: Ignoring EAP type %s: too many types defined", auth_type);			continue;		}		/*		 *	Hostapd doesn't do case-insensitive comparisons.		 *	So we mash everything to uppercase for it.		 */		strlcpy(buffer, auth_type, sizeof(buffer));		for (p = buffer; *p; p++) {			if (!islower((int)*p)) continue;			*p = toupper((int)*p);		}		inst->methods[num_types] = eap_server_get_type(buffer,							       &inst->vendors[num_types]);		if (inst->methods[num_types] == EAP_TYPE_NONE) {			radlog(L_ERR|L_CONS, "rlm_eap2: Unknown EAP type %s",			       auth_type);			eap_detach(inst);			return -1;		}		switch (inst->methods[num_types]) {		case EAP_TYPE_TLS:			has_tls = TRUE;			/* FALL-THROUGH */		case EAP_TYPE_TTLS:		case EAP_TYPE_PEAP:		case EAP_TYPE_FAST:			do_tls = TRUE;			break;		default:			break;		}		num_types++;	/* successfully loaded one more types */	}	inst->num_types = num_types;	if (do_tls && !has_tls) {		radlog(L_ERR|L_CONS, "rlm_eap2: TLS has not been configured.  Cannot do methods that need TLS.");		eap_detach(inst);		return -1;	}	if (do_tls) {		/*		 *	Initialize TLS.		 */		if (eap_example_server_init_tls(inst) < 0) {			radlog(L_ERR|L_CONS, "rlm_eap2: Cannot initialize TLS");			eap_detach(inst);			return -1;		}	}	pthread_mutex_init(&(inst->session_mutex), NULL);	*instance = inst;	return 0;}static int eap_req2vp(EAP_HANDLER *handler){	int		encoded, total, size;	const uint8_t	*ptr;	VALUE_PAIR	*head = NULL;	VALUE_PAIR	**tail = &head;	VALUE_PAIR	*vp;	ptr = wpabuf_head(handler->server_ctx.eap_if->eapReqData);	encoded = total = wpabuf_len(handler->server_ctx.eap_if->eapReqData);	do {		size = total;		if (size > 253) size = 253;		vp = paircreate(PW_EAP_MESSAGE, PW_TYPE_OCTETS);		if (!vp) {			pairfree(&head);			return -1;		}		memcpy(vp->vp_octets, ptr, size);		vp->length = size;		*tail = vp;		tail = &(vp->next);		ptr += size;		total -= size;	} while (total > 0);	pairdelete(&handler->request->reply->vps, PW_EAP_MESSAGE);	pairadd(&handler->request->reply->vps, head);	return encoded;}static int eap_example_server_step(EAP_HANDLER *handler){	int res, process = 0;	REQUEST *request = handler->request;	res = eap_server_sm_step(handler->server_ctx.eap);	if (handler->server_ctx.eap_if->eapReq) {		DEBUG("==> Request");		process = 1;		handler->server_ctx.eap_if->eapReq = 0;	}	if (handler->server_ctx.eap_if->eapSuccess) {		DEBUG("==> Success");		process = 1;		res = 0;		if (handler->server_ctx.eap_if->eapKeyAvailable) {			int length = handler->server_ctx.eap_if->eapKeyDataLen;			VALUE_PAIR *vp;			if (length > 64) {				length = 32;			} else {				length /= 2;				/*				 *	FIXME: Length is zero?				 */			}			vp = radius_pairmake(request, &request->reply->vps,					     "MS-MPPE-Recv-Key", "", T_OP_EQ);			if (vp) {				memcpy(vp->vp_octets,				       handler->server_ctx.eap_if->eapKeyData,				       length);				vp->length = length;			}						vp = radius_pairmake(request, &request->reply->vps,					     "MS-MPPE-Send-Key", "", T_OP_EQ);			if (vp) {				memcpy(vp->vp_octets,				       handler->server_ctx.eap_if->eapKeyData + length,				       length);				vp->length = length;			}		}	}	if (handler->server_ctx.eap_if->eapFail) {		DEBUG("==> Fail");		process = 1;	}	if (process) {		if (wpabuf_head(handler->server_ctx.eap_if->eapReqData)) {			if (!eap_req2vp(handler)) return -1;		} else {			return -1;		}	}	return res;}/* * Handles multiple EAP-Message attrs * ie concatenates all to get the complete EAP packet. * * NOTE: Sometimes Framed-MTU might contain the length of EAP-Message, *      refer fragmentation in rfc2869. */static int eap_vp2data(VALUE_PAIR *vps, void **data, int *data_len){	VALUE_PAIR *first, *vp;	unsigned char *ptr;	uint16_t len;	int total_len;	/*	 *	Get only EAP-Message attribute list	 */	first = pairfind(vps, PW_EAP_MESSAGE);	if (first == NULL) {		radlog(L_ERR, "rlm_eap2: EAP-Message not found");		return -1;	}	/*	 *	Sanity check the length before doing anything.	 */	if (first->length < 4) {		radlog(L_ERR, "rlm_eap2: EAP packet is too short.");		return -1;	}	/*	 *	Get the Actual length from the EAP packet	 *	First EAP-Message contains the EAP packet header	 */	memcpy(&len, first->vp_strvalue + 2, sizeof(len));	len = ntohs(len);	/*	 *	Take out even more weird things.	 */	if (len < 4) {		radlog(L_ERR, "rlm_eap2: EAP packet has invalid length.");		return -1;	}	/*	 *	Sanity check the length, BEFORE malloc'ing memory.	 */	total_len = 0;	for (vp = first; vp; vp = pairfind(vp->next, PW_EAP_MESSAGE)) {		total_len += vp->length;		if (total_len > len) {			radlog(L_ERR, "rlm_eap2: Malformed EAP packet.  Length in packet header does not match actual length");			return -1;		}	}	/*	 *	If the length is SMALLER, die, too.	 */	if (total_len < len) {		radlog(L_ERR, "rlm_eap2: Malformed EAP packet.  Length in packet header does not match actual length");		return -1;	}	/*	 *	Now that we know the lengths are OK, allocate memory.	 */	*data = malloc(len);	if (!*data) {		radlog(L_ERR, "rlm_eap2: out of memory");		return -1;	}	*data_len = len;	/*	 *	Copy the data from EAP-Message's over to our EAP packet.	 */	ptr = *data;	/* RADIUS ensures order of attrs, so just concatenate all */	for (vp = first; vp; vp = pairfind(vp->next, PW_EAP_MESSAGE)) {		memcpy(ptr, vp->vp_strvalue, vp->length);		ptr += vp->length;	}	return 0;}/* *	FIXME: Add an "authorize" section which sets Auth-Type = EAP2 *	FIXME: Also in "authorize", set User-Name if not already set. *//* *	Do EAP. */static int eap_authenticate(void *instance, REQUEST *request){	rlm_eap_t	*inst;	EAP_HANDLER	*handler;	void		*data;	int		data_len;	int		rcode;	VALUE_PAIR	*vp;	inst = (rlm_eap_t *) instance;	vp = pairfind(request->packet->vps, PW_EAP_MESSAGE);	if (!vp) {		RDEBUG("No EAP-Message.  Not doing EAP.");		return RLM_MODULE_FAIL;	}	/*	 *	Get the eap packet  to start with	 */	data = NULL;	data_len = 0;	if (eap_vp2data(request->packet->vps, &data, &data_len) < 0) {		radlog(L_ERR, "rlm_eap2: Malformed EAP Message");		return RLM_MODULE_FAIL;	}	vp = pairfind(request->packet->vps, PW_STATE);	if (vp) {		handler = eaplist_find(inst, request);		if (!handler) {			RDEBUG("No handler found");			return RLM_MODULE_FAIL;		}	} else {		handler = malloc(sizeof(*handler));		if (!handler) return RLM_MODULE_FAIL;		memset(handler, 0, sizeof(*handler));		handler->inst = inst;		handler->eap_cb.get_eap_user = server_get_eap_user;		handler->eap_cb.get_eap_req_id_text = server_get_eap_req_id_text;		handler->eap_conf.eap_server = 1;		handler->eap_conf.ssl_ctx = inst->tls_ctx;		handler->server_ctx.eap = eap_server_sm_init(handler,							     &handler->eap_cb,							     &handler->eap_conf);		if (handler->server_ctx.eap == NULL) {			free(handler);			return RLM_MODULE_FAIL;		}				handler->server_ctx.eap_if = eap_get_interface(handler->server_ctx.eap);				/* Enable "port" and request EAP to start authentication. */		handler->server_ctx.eap_if->portEnabled = TRUE;		handler->server_ctx.eap_if->eapRestart = TRUE;	}	handler->request = request;	wpabuf_free(handler->server_ctx.eap_if->eapRespData);	handler->server_ctx.eap_if->eapRespData = wpabuf_alloc_copy(data, data_len);	if (handler->server_ctx.eap_if->eapRespData) {		handler->server_ctx.eap_if->eapResp = TRUE;	}		if (eap_example_server_step(handler) < 0) {		RDEBUG("Failed in EAP library");		goto fail;	}	if (handler->server_ctx.eap_if->eapSuccess) {		request->reply->code = PW_AUTHENTICATION_ACK;		rcode = RLM_MODULE_OK;	} else if (handler->server_ctx.eap_if->eapFail) {	fail:		request->reply->code = PW_AUTHENTICATION_REJECT;		rcode = RLM_MODULE_REJECT;	} else {		request->reply->code = PW_ACCESS_CHALLENGE;		rcode = RLM_MODULE_HANDLED;	}	if (handler->server_ctx.eap_if->eapFail ||	    handler->server_ctx.eap_if->eapSuccess) {		RDEBUG2("Freeing handler");		/* handler is not required any more, free it now */		eap_handler_free(handler);		handler = NULL;	} else {		eaplist_add(inst, handler);	}	/*	 *	If it's an Access-Accept, RFC 2869, Section 2.3.1	 *	says that we MUST include a User-Name attribute in the	 *	Access-Accept.	 */	if ((request->reply->code == PW_AUTHENTICATION_ACK) &&	    request->username) {		/*		 *	Doesn't exist, add it in.		 */		vp = pairfind(request->reply->vps, PW_USER_NAME);		if (!vp) {			vp = pairmake("User-Name", request->username->vp_strvalue,				      T_OP_EQ);			rad_assert(vp != NULL);			pairadd(&(request->reply->vps), vp);		}		/*		 *	Cisco AP1230 has a bug and needs a zero		 *	terminated string in Access-Accept.		 */		if ((inst->cisco_accounting_username_bug) &&		    (vp->length < (int) sizeof(vp->vp_strvalue))) {			vp->vp_strvalue[vp->length] = '\0';			vp->length++;		}	}	vp = pairfind(request->reply->vps, PW_MESSAGE_AUTHENTICATOR);	if (!vp) {		vp = paircreate(PW_MESSAGE_AUTHENTICATOR, PW_TYPE_OCTETS);		memset(vp->vp_strvalue, 0, AUTH_VECTOR_LEN);		vp->length = AUTH_VECTOR_LEN;		pairadd(&(request->reply->vps), vp);	}	return rcode;}/* *	The module name should be the only globally exported symbol. *	That is, everything else should be 'static'. */module_t rlm_eap2 = {	RLM_MODULE_INIT,	"eap2",	RLM_TYPE_CHECK_CONFIG_SAFE,   	/* type */	eap_instantiate,		/* instantiation */	eap_detach,			/* detach */	{		eap_authenticate,	/* authentication */		NULL,			/* authorization */		NULL,			/* preaccounting */		NULL,			/* accounting */		NULL,			/* checksimul */		NULL,			/* pre-proxy */		NULL,			/* post-proxy */		NULL			/* post-auth */	},};

⌨️ 快捷键说明

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