コード例 #1
0
ファイル: eap_tls.c プロジェクト: roocell/freeradius-server
/*
 *	Parse TLS configuration
 *
 *	If the option given by 'attr' is set, we find the config section
 *	of that name and use that for the TLS configuration. If not, we
 *	fall back to compatibility mode and read the TLS options from
 *	the 'tls' section.
 */
fr_tls_server_conf_t *eaptls_conf_parse(CONF_SECTION *cs, char const *attr)
{
	char const 		*tls_conf_name;
	CONF_PAIR		*cp;
	CONF_SECTION		*parent;
	CONF_SECTION		*tls_cs;
	fr_tls_server_conf_t	*tls_conf;

	if (!cs)
		return NULL;

	rad_assert(attr != NULL);

	parent = cf_item_parent(cf_section_to_item(cs));

	cp = cf_pair_find(cs, attr);
	if (cp) {
		tls_conf_name = cf_pair_value(cp);

		tls_cs = cf_section_sub_find_name2(parent, TLS_CONFIG_SECTION, tls_conf_name);

		if (!tls_cs) {
			ERROR("Cannot find tls config \"%s\"", tls_conf_name);
			return NULL;
		}
	} else {
		/*
		 *	If we can't find the section given by the 'attr', we
		 *	fall-back to looking for the "tls" section, as in
		 *	previous versions.
		 *
		 *	We don't fall back if the 'attr' is specified, but we can't
		 *	find the section - that is just a config error.
		 */
		INFO("TLS section \"%s\" missing, trying to use legacy configuration", attr);
		tls_cs = cf_section_sub_find(parent, "tls");
	}

	if (!tls_cs)
		return NULL;

	tls_conf = tls_server_conf_parse(tls_cs);

	if (!tls_conf)
		return NULL;

	/*
	 *	The EAP RFC's say 1020, but we're less picky.
	 */
	if (tls_conf->fragment_size < 100) {
		ERROR("Configured fragment size is too small, must be >= 100");
		return NULL;
	}

	/*
	 *	The maximum size for a RADIUS packet is 4096,
	 *	minus the header (20), Message-Authenticator (18),
	 *	and State (18), etc. results in about 4000 bytes of data
	 *	that can be devoted *solely* to EAP.
	 */
	if (tls_conf->fragment_size > 4000) {
		ERROR("Configured fragment size is too large, must be <= 4000");
		return NULL;
	}

	/*
	 *	Account for the EAP header (4), and the EAP-TLS header
	 *	(6), as per Section 4.2 of RFC 2716.  What's left is
	 *	the maximum amount of data we read from a TLS buffer.
	 */
	tls_conf->fragment_size -= 10;

	return tls_conf;
}
コード例 #2
0
ファイル: cf_util.c プロジェクト: zi0r/freeradius-server
/** Allocate a #CONF_SECTION
 *
 * @param[in] ctx	to allocate
 * @param[in] parent	#CONF_SECTION to hang this #CONF_SECTION off of.
 *			If parent is not NULL, the new section will be added as a child.
 * @param[in] name1	Primary name.
 * @param[in] name2	Secondary name.
 * @param[in] filename	Caller file name for debugging.  May be overridden later.
 * @param[in] lineno	Caller line number for debugging.  May be overridden later.
 * @return
 *	- NULL on error.
 *	- A new #CONF_SECTION parented by parent.
 */
CONF_SECTION *_cf_section_alloc(TALLOC_CTX *ctx, CONF_SECTION *parent,
				char const *name1, char const *name2,
				char const *filename, int lineno)
{
	CONF_SECTION *cs;
	char buffer[1024];

	if (!name1) return NULL;

	if (name2 && parent) {
		char const *p;

		p = strchr(name2, '$');
		if (p && (p[1] != '{')) p = NULL;

		if (p) {
			name2 = cf_expand_variables(parent->item.filename,
						    &parent->item.lineno,
						    parent,
						    buffer, sizeof(buffer), name2, NULL);
			if (!name2) {
				ERROR("Failed expanding section name");
				return NULL;
			}
		}
	}

	cs = talloc_zero(ctx, CONF_SECTION);
	if (!cs) return NULL;

	cs->item.type = CONF_ITEM_SECTION;
	cs->item.parent = cf_section_to_item(parent);
	fr_cursor_init(&cs->item.cursor, &cs->item.child);

	MEM(cs->name1 = talloc_typed_strdup(cs, name1));
	if (name2) {
		MEM(cs->name2 = talloc_typed_strdup(cs, name2));
		cs->name2_quote = T_BARE_WORD;
	}
	talloc_set_destructor(cs, _cf_section_free);

	if (filename) cf_filename_set(cs, filename);
	if (lineno) cf_lineno_set(cs, lineno);

	if (parent) {
		CONF_DATA const *cd;
		CONF_PARSER *rule;

		cs->depth = parent->depth + 1;
		cf_item_add(parent, &(cs->item));

		cd = cf_data_find(CF_TO_ITEM(parent), CONF_PARSER, cf_section_name1(parent));
		if (cd) {
			rule = cf_data_value(cd);

			/*
			 *	The parent has an ON_READ rule.  Check
			 *	if that rule has a child which matches
			 *	this section.
			 */
			if ((FR_BASE_TYPE(rule->type) == FR_TYPE_SUBSECTION) &&
			    ((rule->type & FR_TYPE_ON_READ) != 0) &&
			    rule->subcs) {
				CONF_PARSER const *rule_p;

				for (rule_p = rule->subcs; rule_p->name; rule_p++) {
					if ((FR_BASE_TYPE(rule_p->type) == FR_TYPE_SUBSECTION) &&
					    ((rule_p->type & FR_TYPE_ON_READ) != 0) &&
					    (strcmp(rule_p->name, name1) == 0)) {
						(void) _cf_section_rule_push(cs, rule_p, cd->item.filename, cd->item.lineno);
						(void) rule_p->func(ctx, NULL, NULL, cf_section_to_item(cs), rule_p);
						return cs;
					}
				}
			}
		}

		/*
		 *	Call any ON_READ callback.  And push this rule
		 *	to the child section, so that the child can
		 *	pick it up.
		 */
		cd = cf_data_find(CF_TO_ITEM(parent), CONF_PARSER, name1);
		if (cd) {
			rule = cf_data_value(cd);
			if (rule->func &&
			    (FR_BASE_TYPE(rule->type) == FR_TYPE_SUBSECTION) &&
			    ((rule->type & FR_TYPE_ON_READ) != 0)) {
				(void) cf_section_rules_push(cs, rule);

				(void) rule->func(ctx, NULL, NULL, cf_section_to_item(cs), rule);
			}
		}
	}

	return cs;
}