/*
 * read the config section and load all the eap authentication types present.
 */
static int eap_instantiate(CONF_SECTION *cs, void **instance)
{
	int i, num_types;
	int		has_tls, do_tls;
	rlm_eap_t	*inst;
	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;
}
Exemple #2
0
/*
 * read the config section and load all the eap authentication types present.
 */
static int eap_instantiate(CONF_SECTION *cs, void **instance)
{
	int		i, eap_type;
	int		num_types;
	CONF_SECTION 	*scs;
	rlm_eap_t	*inst;

	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);
	inst->rand_pool.randcnt = 0;

	inst->xlat_name = cf_section_name2(cs);
	if (!inst->xlat_name) inst->xlat_name = "EAP";

	/* Load all the configured EAP-Types */
	num_types = 0;
	for(scs=cf_subsection_find_next(cs, NULL, NULL);
		scs != NULL;
		scs=cf_subsection_find_next(cs, scs, NULL)) {

		const char	*auth_type;

		auth_type = cf_section_name1(scs);

		if (!auth_type)  continue;

		if (!strcmp(auth_type, TLS_CONFIG_SECTION))  continue;

		eap_type = eaptype_name2type(auth_type);
		if (eap_type < 0) {
			radlog(L_ERR, "rlm_eap: Unknown EAP type %s",
			       auth_type);
			eap_detach(inst);
			return -1;
		}

#ifndef HAVE_OPENSSL_SSL_H
		/*
		 *	This allows the default configuration to be
		 *	shipped with EAP-TLS, etc. enabled.  If the
		 *	system doesn't have OpenSSL, they will be
		 *	ignored.
		 *
		 *	If the system does have OpenSSL, then this
		 *	code will not be used.  The administrator will
		 *	then have to delete the tls,
		 *	etc. configurations from eap.conf in order to
		 *	have EAP without the TLS types.
		 */
		if ((eap_type == PW_EAP_TLS) ||
		    (eap_type == PW_EAP_TTLS) ||
		    (eap_type == PW_EAP_PEAP)) {
			DEBUG2("Ignoring EAP-Type/%s because we do not have OpenSSL support.", auth_type);
			continue;
		}
#endif

		/*
		 *	Load the type.
		 */
		if (eaptype_load(&inst->types[eap_type], eap_type, scs) < 0) {
			eap_detach(inst);
			return -1;
		}

		num_types++;	/* successfully loaded one more types */
	}

	if (num_types == 0) {
		radlog(L_ERR|L_CONS, "rlm_eap: No EAP type configured, module cannot do anything.");
		eap_detach(inst);
		return -1;
	}

	/*
	 *	Ensure that the default EAP type is loaded.
	 */
	eap_type = eaptype_name2type(inst->default_eap_type_name);
	if (eap_type < 0) {
		radlog(L_ERR|L_CONS, "rlm_eap: Unknown default EAP type %s",
		       inst->default_eap_type_name);
		eap_detach(inst);
		return -1;
	}

	if (inst->types[eap_type] == NULL) {
		radlog(L_ERR|L_CONS, "rlm_eap: No such sub-type for default EAP type %s",
		       inst->default_eap_type_name);
		eap_detach(inst);
		return -1;
	}
	inst->default_eap_type = eap_type; /* save the numerical type */

	/*
	 *	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_eap: Cannot initialize tree");
		eap_detach(inst);
		return -1;
	}

	if (fr_debug_flag) {
		inst->handler_tree = rbtree_create(eap_handler_ptr_cmp, NULL, 0);
		if (!inst->handler_tree) {
			radlog(L_ERR|L_CONS, "rlm_eap: Cannot initialize tree");
			eap_detach(inst);
			return -1;
		}

#ifdef HAVE_PTHREAD_H
		if (pthread_mutex_init(&(inst->handler_mutex), NULL) < 0) {
			radlog(L_ERR|L_CONS, "rlm_eap: Failed initializing mutex: %s", strerror(errno));
			eap_detach(inst);
			return -1;
		}
#endif
	}

#ifdef HAVE_PTHREAD_H
	if (pthread_mutex_init(&(inst->session_mutex), NULL) < 0) {
		radlog(L_ERR|L_CONS, "rlm_eap: Failed initializing mutex: %s", strerror(errno));
		eap_detach(inst);
		return -1;
	}
#endif

	*instance = inst;
	return 0;
}