File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / conftest / config.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:20:08 2021 UTC (3 years, 4 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, HEAD
strongswan 5.9.2

    1: /*
    2:  * Copyright (C) 2010 Martin Willi
    3:  * Copyright (C) 2010 revosec AG
    4:  *
    5:  * This program is free software; you can redistribute it and/or modify it
    6:  * under the terms of the GNU General Public License as published by the
    7:  * Free Software Foundation; either version 2 of the License, or (at your
    8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
    9:  *
   10:  * This program is distributed in the hope that it will be useful, but
   11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13:  * for more details.
   14:  */
   15: 
   16: #include "config.h"
   17: 
   18: #include <daemon.h>
   19: #include <conftest.h>
   20: 
   21: typedef struct private_config_t private_config_t;
   22: 
   23: /**
   24:  * Private data of an config_t object.
   25:  */
   26: struct private_config_t {
   27: 
   28: 	/**
   29: 	 * Public config_t interface.
   30: 	 */
   31: 	config_t public;
   32: 
   33: 	/**
   34: 	 * List of loaded peer configs
   35: 	 */
   36: 	linked_list_t *configs;
   37: };
   38: 
   39: CALLBACK(ike_filter, bool,
   40: 	void *data, enumerator_t *orig, va_list args)
   41: {
   42: 	peer_cfg_t *cfg;
   43: 	ike_cfg_t **out;
   44: 
   45: 	VA_ARGS_VGET(args, out);
   46: 
   47: 	if (orig->enumerate(orig, &cfg))
   48: 	{
   49: 		*out = cfg->get_ike_cfg(cfg);
   50: 		return TRUE;
   51: 	}
   52: 	return FALSE;
   53: }
   54: 
   55: METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
   56: 	private_config_t *this, host_t *me, host_t *other)
   57: {
   58: 
   59: 	return enumerator_create_filter(
   60: 							this->configs->create_enumerator(this->configs),
   61: 							ike_filter, NULL, NULL);
   62: }
   63: 
   64: METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
   65: 	private_config_t *this, identification_t *me, identification_t *other)
   66: {
   67: 	return this->configs->create_enumerator(this->configs);
   68: }
   69: 
   70: METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
   71: 	private_config_t *this, char *name)
   72: {
   73: 	enumerator_t *e1, *e2;
   74: 	peer_cfg_t *current, *found = NULL;
   75: 	child_cfg_t *child;
   76: 
   77: 	e1 = this->configs->create_enumerator(this->configs);
   78: 	while (e1->enumerate(e1, &current))
   79: 	{
   80: 		e2 = current->create_child_cfg_enumerator(current);
   81: 		while (e2->enumerate(e2, &child))
   82: 		{
   83: 			if (streq(child->get_name(child), name))
   84: 			{
   85: 				found = current;
   86: 				found->get_ref(found);
   87: 				break;
   88: 			}
   89: 		}
   90: 		e2->destroy(e2);
   91: 		if (found)
   92: 		{
   93: 			break;
   94: 		}
   95: 	}
   96: 	e1->destroy(e1);
   97: 	return found;
   98: }
   99: 
  100: /**
  101:  * Load IKE config for a given section name
  102:  */
  103: static ike_cfg_t *load_ike_config(private_config_t *this,
  104: 								  settings_t *settings, char *config)
  105: {
  106: 	enumerator_t *enumerator;
  107: 	ike_cfg_t *ike_cfg;
  108: 	proposal_t *proposal;
  109: 	char *token;
  110: 	ike_cfg_create_t ike = {
  111: 		.version = IKEV2,
  112: 		.local = settings->get_str(settings, "configs.%s.lhost",
  113: 								   "%any", config),
  114: 		.local_port = settings->get_int(settings, "configs.%s.lport",
  115: 									500, config),
  116: 		.remote = settings->get_str(settings, "configs.%s.rhost",
  117: 									"%any", config),
  118: 		.remote_port = settings->get_int(settings, "configs.%s.rport",
  119: 									500, config),
  120: 		.force_encap = settings->get_bool(settings, "configs.%s.fake_nat",
  121: 									FALSE, config),
  122: 	};
  123: 
  124: 	ike_cfg = ike_cfg_create(&ike);
  125: 	token = settings->get_str(settings, "configs.%s.proposal", NULL, config);
  126: 	if (token)
  127: 	{
  128: 		enumerator = enumerator_create_token(token, ",", " ");
  129: 		while (enumerator->enumerate(enumerator, &token))
  130: 		{
  131: 			proposal = proposal_create_from_string(PROTO_IKE, token);
  132: 			if (proposal)
  133: 			{
  134: 				ike_cfg->add_proposal(ike_cfg, proposal);
  135: 			}
  136: 			else
  137: 			{
  138: 				DBG1(DBG_CFG, "parsing proposal '%s' failed, skipped", token);
  139: 			}
  140: 		}
  141: 		enumerator->destroy(enumerator);
  142: 	}
  143: 	else
  144: 	{
  145: 		ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
  146: 		ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
  147: 	}
  148: 	return ike_cfg;
  149: }
  150: /**
  151:  * Load CHILD config for given section names
  152:  */
  153: static child_cfg_t *load_child_config(private_config_t *this,
  154: 							settings_t *settings, char *config, char *child)
  155: {
  156: 	child_cfg_create_t data = {
  157: 		.mode = MODE_TUNNEL,
  158: 	};
  159: 	child_cfg_t *child_cfg;
  160: 	enumerator_t *enumerator;
  161: 	proposal_t *proposal;
  162: 	traffic_selector_t *ts;
  163: 	char *token;
  164: 
  165: 	if (settings->get_bool(settings, "configs.%s.%s.transport",
  166: 						   FALSE, config, child))
  167: 	{
  168: 		data.mode = MODE_TRANSPORT;
  169: 	}
  170: 	data.tfc = settings->get_int(settings, "configs.%s.%s.tfc_padding",
  171: 								  0, config, child);
  172: 	child_cfg = child_cfg_create(child, &data);
  173: 
  174: 	token = settings->get_str(settings, "configs.%s.%s.proposal",
  175: 							  NULL, config, child);
  176: 	if (token)
  177: 	{
  178: 		enumerator = enumerator_create_token(token, ",", " ");
  179: 		while (enumerator->enumerate(enumerator, &token))
  180: 		{
  181: 			proposal = proposal_create_from_string(PROTO_ESP, token);
  182: 			if (proposal)
  183: 			{
  184: 				child_cfg->add_proposal(child_cfg, proposal);
  185: 			}
  186: 			else
  187: 			{
  188: 				DBG1(DBG_CFG, "parsing proposal '%s' failed, skipped", token);
  189: 			}
  190: 		}
  191: 		enumerator->destroy(enumerator);
  192: 	}
  193: 	else
  194: 	{
  195: 		child_cfg->add_proposal(child_cfg, proposal_create_default_aead(PROTO_ESP));
  196: 		child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
  197: 	}
  198: 
  199: 	token = settings->get_str(settings, "configs.%s.%s.lts", NULL, config, child);
  200: 	if (token)
  201: 	{
  202: 		enumerator = enumerator_create_token(token, ",", " ");
  203: 		while (enumerator->enumerate(enumerator, &token))
  204: 		{
  205: 			ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
  206: 			if (ts)
  207: 			{
  208: 				child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
  209: 			}
  210: 			else
  211: 			{
  212: 				DBG1(DBG_CFG, "invalid local ts: %s, skipped", token);
  213: 			}
  214: 		}
  215: 		enumerator->destroy(enumerator);
  216: 	}
  217: 	else
  218: 	{
  219: 		ts = traffic_selector_create_dynamic(0, 0, 65535);
  220: 		child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
  221: 	}
  222: 
  223: 	token = settings->get_str(settings, "configs.%s.%s.rts", NULL, config, child);
  224: 	if (token)
  225: 	{
  226: 		enumerator = enumerator_create_token(token, ",", " ");
  227: 		while (enumerator->enumerate(enumerator, &token))
  228: 		{
  229: 			ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
  230: 			if (ts)
  231: 			{
  232: 				child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
  233: 			}
  234: 			else
  235: 			{
  236: 				DBG1(DBG_CFG, "invalid remote ts: %s, skipped", token);
  237: 			}
  238: 		}
  239: 		enumerator->destroy(enumerator);
  240: 	}
  241: 	else
  242: 	{
  243: 		ts = traffic_selector_create_dynamic(0, 0, 65535);
  244: 		child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
  245: 	}
  246: 	return child_cfg;
  247: }
  248: 
  249: /**
  250:  * Load peer config for a given section name
  251:  */
  252: static peer_cfg_t *load_peer_config(private_config_t *this,
  253: 									settings_t *settings, char *config)
  254: {
  255: 	ike_cfg_t *ike_cfg;
  256: 	peer_cfg_t *peer_cfg;
  257: 	auth_cfg_t *auth;
  258: 	child_cfg_t *child_cfg;
  259: 	enumerator_t *enumerator;
  260: 	identification_t *lid, *rid;
  261: 	char *child, *policy, *pool;
  262: 	uintptr_t strength;
  263: 	peer_cfg_create_t peer = {
  264: 		.cert_policy = CERT_ALWAYS_SEND,
  265: 		.unique = UNIQUE_NO,
  266: 		.keyingtries = 1,
  267: 		.no_mobike = TRUE,
  268: 	};
  269: 
  270: 	ike_cfg = load_ike_config(this, settings, config);
  271: 	peer_cfg = peer_cfg_create(config, ike_cfg, &peer);
  272: 
  273: 	auth = auth_cfg_create();
  274: 	auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
  275: 	lid = identification_create_from_string(
  276: 				settings->get_str(settings, "configs.%s.lid", "%any", config));
  277: 	auth->add(auth, AUTH_RULE_IDENTITY, lid);
  278: 	peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
  279: 
  280: 	auth = auth_cfg_create();
  281: 	auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
  282: 	rid = identification_create_from_string(
  283: 				settings->get_str(settings, "configs.%s.rid", "%any", config));
  284: 	strength = settings->get_int(settings, "configs.%s.rsa_strength", 0, config);
  285: 	if (strength)
  286: 	{
  287: 		auth->add(auth, AUTH_RULE_RSA_STRENGTH, strength);
  288: 	}
  289: 	strength = settings->get_int(settings, "configs.%s.ecdsa_strength", 0, config);
  290: 	if (strength)
  291: 	{
  292: 		auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength);
  293: 	}
  294: 	policy = settings->get_str(settings, "configs.%s.cert_policy", NULL, config);
  295: 	if (policy)
  296: 	{
  297: 		auth->add(auth, AUTH_RULE_CERT_POLICY, strdup(policy));
  298: 	}
  299: 	auth->add(auth, AUTH_RULE_IDENTITY, rid);
  300: 	peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
  301: 	pool = settings->get_str(settings, "configs.%s.named_pool", NULL, config);
  302: 	if (pool)
  303: 	{
  304: 		peer_cfg->add_pool(peer_cfg, pool);
  305: 	}
  306: 
  307: 	DBG1(DBG_CFG, "loaded config %s: %Y - %Y", config, lid, rid);
  308: 
  309: 	enumerator = settings->create_section_enumerator(settings,
  310: 													 "configs.%s", config);
  311: 	while (enumerator->enumerate(enumerator, &child))
  312: 	{
  313: 		child_cfg = load_child_config(this, settings, config, child);
  314: 		peer_cfg->add_child_cfg(peer_cfg, child_cfg);
  315: 	}
  316: 	enumerator->destroy(enumerator);
  317: 	return peer_cfg;
  318: }
  319: 
  320: METHOD(config_t, load, void,
  321: 	private_config_t *this, settings_t *settings)
  322: {
  323: 	enumerator_t *enumerator;
  324: 	char *config;
  325: 
  326: 	enumerator = settings->create_section_enumerator(settings, "configs");
  327: 	while (enumerator->enumerate(enumerator, &config))
  328: 	{
  329: 		this->configs->insert_last(this->configs,
  330: 								load_peer_config(this, settings, config));
  331: 	}
  332: 	enumerator->destroy(enumerator);
  333: }
  334: 
  335: METHOD(config_t, destroy, void,
  336: 	private_config_t *this)
  337: {
  338: 	this->configs->destroy_offset(this->configs, offsetof(peer_cfg_t, destroy));
  339: 	free(this);
  340: }
  341: 
  342: /**
  343:  * See header
  344:  */
  345: config_t *config_create()
  346: {
  347: 	private_config_t *this;
  348: 
  349: 	INIT(this,
  350: 		.public = {
  351: 			.backend = {
  352: 				.create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
  353: 				.create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
  354: 				.get_peer_cfg_by_name = _get_peer_cfg_by_name,
  355: 			},
  356: 			.load = _load,
  357: 			.destroy = _destroy,
  358: 		},
  359: 		.configs = linked_list_create(),
  360: 	);
  361: 
  362: 	return &this->public;
  363: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>