Annotation of embedaddon/strongswan/src/conftest/config.c, revision 1.1
1.1 ! misho 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, ¤t))
! 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(PROTO_ESP));
! 196: child_cfg->add_proposal(child_cfg,
! 197: proposal_create_default_aead(PROTO_ESP));
! 198: }
! 199:
! 200: token = settings->get_str(settings, "configs.%s.%s.lts", NULL, config, child);
! 201: if (token)
! 202: {
! 203: enumerator = enumerator_create_token(token, ",", " ");
! 204: while (enumerator->enumerate(enumerator, &token))
! 205: {
! 206: ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
! 207: if (ts)
! 208: {
! 209: child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
! 210: }
! 211: else
! 212: {
! 213: DBG1(DBG_CFG, "invalid local ts: %s, skipped", token);
! 214: }
! 215: }
! 216: enumerator->destroy(enumerator);
! 217: }
! 218: else
! 219: {
! 220: ts = traffic_selector_create_dynamic(0, 0, 65535);
! 221: child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
! 222: }
! 223:
! 224: token = settings->get_str(settings, "configs.%s.%s.rts", NULL, config, child);
! 225: if (token)
! 226: {
! 227: enumerator = enumerator_create_token(token, ",", " ");
! 228: while (enumerator->enumerate(enumerator, &token))
! 229: {
! 230: ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
! 231: if (ts)
! 232: {
! 233: child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
! 234: }
! 235: else
! 236: {
! 237: DBG1(DBG_CFG, "invalid remote ts: %s, skipped", token);
! 238: }
! 239: }
! 240: enumerator->destroy(enumerator);
! 241: }
! 242: else
! 243: {
! 244: ts = traffic_selector_create_dynamic(0, 0, 65535);
! 245: child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
! 246: }
! 247: return child_cfg;
! 248: }
! 249:
! 250: /**
! 251: * Load peer config for a given section name
! 252: */
! 253: static peer_cfg_t *load_peer_config(private_config_t *this,
! 254: settings_t *settings, char *config)
! 255: {
! 256: ike_cfg_t *ike_cfg;
! 257: peer_cfg_t *peer_cfg;
! 258: auth_cfg_t *auth;
! 259: child_cfg_t *child_cfg;
! 260: enumerator_t *enumerator;
! 261: identification_t *lid, *rid;
! 262: char *child, *policy, *pool;
! 263: uintptr_t strength;
! 264: peer_cfg_create_t peer = {
! 265: .cert_policy = CERT_ALWAYS_SEND,
! 266: .unique = UNIQUE_NO,
! 267: .keyingtries = 1,
! 268: .no_mobike = TRUE,
! 269: };
! 270:
! 271: ike_cfg = load_ike_config(this, settings, config);
! 272: peer_cfg = peer_cfg_create(config, ike_cfg, &peer);
! 273:
! 274: auth = auth_cfg_create();
! 275: auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
! 276: lid = identification_create_from_string(
! 277: settings->get_str(settings, "configs.%s.lid", "%any", config));
! 278: auth->add(auth, AUTH_RULE_IDENTITY, lid);
! 279: peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
! 280:
! 281: auth = auth_cfg_create();
! 282: auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
! 283: rid = identification_create_from_string(
! 284: settings->get_str(settings, "configs.%s.rid", "%any", config));
! 285: strength = settings->get_int(settings, "configs.%s.rsa_strength", 0, config);
! 286: if (strength)
! 287: {
! 288: auth->add(auth, AUTH_RULE_RSA_STRENGTH, strength);
! 289: }
! 290: strength = settings->get_int(settings, "configs.%s.ecdsa_strength", 0, config);
! 291: if (strength)
! 292: {
! 293: auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength);
! 294: }
! 295: policy = settings->get_str(settings, "configs.%s.cert_policy", NULL, config);
! 296: if (policy)
! 297: {
! 298: auth->add(auth, AUTH_RULE_CERT_POLICY, strdup(policy));
! 299: }
! 300: auth->add(auth, AUTH_RULE_IDENTITY, rid);
! 301: peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
! 302: pool = settings->get_str(settings, "configs.%s.named_pool", NULL, config);
! 303: if (pool)
! 304: {
! 305: peer_cfg->add_pool(peer_cfg, pool);
! 306: }
! 307:
! 308: DBG1(DBG_CFG, "loaded config %s: %Y - %Y", config, lid, rid);
! 309:
! 310: enumerator = settings->create_section_enumerator(settings,
! 311: "configs.%s", config);
! 312: while (enumerator->enumerate(enumerator, &child))
! 313: {
! 314: child_cfg = load_child_config(this, settings, config, child);
! 315: peer_cfg->add_child_cfg(peer_cfg, child_cfg);
! 316: }
! 317: enumerator->destroy(enumerator);
! 318: return peer_cfg;
! 319: }
! 320:
! 321: METHOD(config_t, load, void,
! 322: private_config_t *this, settings_t *settings)
! 323: {
! 324: enumerator_t *enumerator;
! 325: char *config;
! 326:
! 327: enumerator = settings->create_section_enumerator(settings, "configs");
! 328: while (enumerator->enumerate(enumerator, &config))
! 329: {
! 330: this->configs->insert_last(this->configs,
! 331: load_peer_config(this, settings, config));
! 332: }
! 333: enumerator->destroy(enumerator);
! 334: }
! 335:
! 336: METHOD(config_t, destroy, void,
! 337: private_config_t *this)
! 338: {
! 339: this->configs->destroy_offset(this->configs, offsetof(peer_cfg_t, destroy));
! 340: free(this);
! 341: }
! 342:
! 343: /**
! 344: * See header
! 345: */
! 346: config_t *config_create()
! 347: {
! 348: private_config_t *this;
! 349:
! 350: INIT(this,
! 351: .public = {
! 352: .backend = {
! 353: .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
! 354: .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
! 355: .get_peer_cfg_by_name = _get_peer_cfg_by_name,
! 356: },
! 357: .load = _load,
! 358: .destroy = _destroy,
! 359: },
! 360: .configs = linked_list_create(),
! 361: );
! 362:
! 363: return &this->public;
! 364: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>