diff options
-rw-r--r-- | src/charon-cmd/cmd/cmd_connection.c | 4 | ||||
-rw-r--r-- | src/charon-nm/nm/nm_service.c | 4 | ||||
-rw-r--r-- | src/conftest/config.c | 4 | ||||
-rw-r--r-- | src/frontends/android/jni/libandroidbridge/backend/android_service.c | 4 | ||||
-rw-r--r-- | src/frontends/osx/charon-xpc/xpc_dispatch.c | 4 | ||||
-rw-r--r-- | src/libcharon/config/ike_cfg.c | 244 | ||||
-rw-r--r-- | src/libcharon/config/ike_cfg.h | 13 | ||||
-rw-r--r-- | src/libcharon/plugins/ha/ha_tunnel.c | 4 | ||||
-rw-r--r-- | src/libcharon/plugins/load_tester/load_tester_config.c | 9 | ||||
-rw-r--r-- | src/libcharon/plugins/maemo/maemo_service.c | 5 | ||||
-rw-r--r-- | src/libcharon/plugins/medcli/medcli_config.c | 10 | ||||
-rw-r--r-- | src/libcharon/plugins/medsrv/medsrv_config.c | 5 | ||||
-rw-r--r-- | src/libcharon/plugins/sql/sql_config.c | 6 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_config.c | 85 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_list.c | 5 | ||||
-rw-r--r-- | src/libcharon/plugins/uci/uci_config.c | 10 |
16 files changed, 306 insertions, 110 deletions
diff --git a/src/charon-cmd/cmd/cmd_connection.c b/src/charon-cmd/cmd/cmd_connection.c index a697da804..180e8da98 100644 --- a/src/charon-cmd/cmd/cmd_connection.c +++ b/src/charon-cmd/cmd/cmd_connection.c @@ -163,8 +163,8 @@ static peer_cfg_t* create_peer_cfg(private_cmd_connection_t *this) { remote_port = IKEV2_NATT_PORT; } - ike_cfg = ike_cfg_create(version, TRUE, FALSE, "0.0.0.0", FALSE, local_port, - this->host, FALSE, remote_port, FRAGMENTATION_NO, 0); + ike_cfg = ike_cfg_create(version, TRUE, FALSE, "0.0.0.0", local_port, + this->host, remote_port, FRAGMENTATION_NO, 0); ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); peer_cfg = peer_cfg_create("cmd", ike_cfg, CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */ diff --git a/src/charon-nm/nm/nm_service.c b/src/charon-nm/nm/nm_service.c index f97c11c18..f37367532 100644 --- a/src/charon-nm/nm/nm_service.c +++ b/src/charon-nm/nm/nm_service.c @@ -527,9 +527,9 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, /** * Set up configurations */ - ike_cfg = ike_cfg_create(IKEV2, TRUE, encap, "0.0.0.0", FALSE, + ike_cfg = ike_cfg_create(IKEV2, TRUE, encap, "0.0.0.0", charon->socket->get_port(charon->socket, FALSE), - (char*)address, FALSE, IKEV2_UDP_PORT, + (char*)address, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0); ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); peer_cfg = peer_cfg_create(priv->name, ike_cfg, diff --git a/src/conftest/config.c b/src/conftest/config.c index 1aa931004..5aa742d79 100644 --- a/src/conftest/config.c +++ b/src/conftest/config.c @@ -103,9 +103,9 @@ static ike_cfg_t *load_ike_config(private_config_t *this, ike_cfg = ike_cfg_create(IKEV2, TRUE, settings->get_bool(settings, "configs.%s.fake_nat", FALSE, config), - settings->get_str(settings, "configs.%s.lhost", "%any", config), FALSE, + settings->get_str(settings, "configs.%s.lhost", "%any", config), settings->get_int(settings, "configs.%s.lport", 500, config), - settings->get_str(settings, "configs.%s.rhost", "%any", config), FALSE, + settings->get_str(settings, "configs.%s.rhost", "%any", config), settings->get_int(settings, "configs.%s.rport", 500, config), FRAGMENTATION_NO, 0); token = settings->get_str(settings, "configs.%s.proposal", NULL, config); diff --git a/src/frontends/android/jni/libandroidbridge/backend/android_service.c b/src/frontends/android/jni/libandroidbridge/backend/android_service.c index 59a4e14cf..ccf5ce8e7 100644 --- a/src/frontends/android/jni/libandroidbridge/backend/android_service.c +++ b/src/frontends/android/jni/libandroidbridge/backend/android_service.c @@ -525,9 +525,9 @@ static job_requeue_t initiate(private_android_service_t *this) } }; - ike_cfg = ike_cfg_create(IKEV2, TRUE, TRUE, "0.0.0.0", FALSE, + ike_cfg = ike_cfg_create(IKEV2, TRUE, TRUE, "0.0.0.0", charon->socket->get_port(charon->socket, FALSE), - this->gateway, FALSE, IKEV2_UDP_PORT, + this->gateway, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0); ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); diff --git a/src/frontends/osx/charon-xpc/xpc_dispatch.c b/src/frontends/osx/charon-xpc/xpc_dispatch.c index 0757e9baf..df9126c8b 100644 --- a/src/frontends/osx/charon-xpc/xpc_dispatch.c +++ b/src/frontends/osx/charon-xpc/xpc_dispatch.c @@ -84,8 +84,8 @@ static peer_cfg_t* create_peer_cfg(char *name, char *host) { remote_port = IKEV2_NATT_PORT; } - ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, "0.0.0.0", FALSE, local_port, - host, FALSE, remote_port, FRAGMENTATION_NO, 0); + ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, "0.0.0.0", local_port, + host, remote_port, FRAGMENTATION_NO, 0); ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); peer_cfg = peer_cfg_create(name, ike_cfg, CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */ diff --git a/src/libcharon/config/ike_cfg.c b/src/libcharon/config/ike_cfg.c index 572f1f96d..cb6f6ca0e 100644 --- a/src/libcharon/config/ike_cfg.c +++ b/src/libcharon/config/ike_cfg.c @@ -50,24 +50,34 @@ struct private_ike_cfg_t { ike_version_t version; /** - * Address of local host + * Address list string for local host */ char *me; /** - * Address of remote host + * Address list string for remote host */ char *other; /** - * Allow override of local address + * Local single host or DNS names, as allocated char* */ - bool my_allow_any; + linked_list_t *my_hosts; /** - * Allow override of remote address + * Remote single host or DNS names, as allocated char* */ - bool other_allow_any; + linked_list_t *other_hosts; + + /** + * Local ranges/subnets this config matches to, as traffic_selector_t* + */ + linked_list_t *my_ranges; + + /** + * Remote ranges/subnets this config matches to, as traffic_selector_t* + */ + linked_list_t *other_ranges; /** * our source port @@ -129,60 +139,113 @@ METHOD(ike_cfg_t, fragmentation, fragmentation_t, return this->fragmentation; } +/** + * Common function for resolve_me/other + */ +static host_t* resolve(linked_list_t *hosts, int family, u_int16_t port) +{ + enumerator_t *enumerator; + host_t *host = NULL; + bool tried = FALSE; + char *str; + + enumerator = hosts->create_enumerator(hosts); + while (enumerator->enumerate(enumerator, &str)) + { + host = host_create_from_dns(str, family, port); + if (host) + { + break; + } + tried = TRUE; + } + enumerator->destroy(enumerator); + + if (!host && !tried) + { + /* we have no single host configured, return %any */ + host = host_create_any(family ?: AF_INET); + host->set_port(host, port); + } + return host; +} + METHOD(ike_cfg_t, resolve_me, host_t*, private_ike_cfg_t *this, int family) { - return host_create_from_dns(this->me, family, this->my_port); + return resolve(this->my_hosts, family, this->my_port); } METHOD(ike_cfg_t, resolve_other, host_t*, private_ike_cfg_t *this, int family) { - return host_create_from_dns(this->other, family, this->other_port); + return resolve(this->other_hosts, family, this->other_port); } -METHOD(ike_cfg_t, match_me, u_int, - private_ike_cfg_t *this, host_t *host) +/** + * Common function for match_me/other + */ +static u_int match(linked_list_t *hosts, linked_list_t *ranges, host_t *cand) { - host_t *me; - int quality = 0; - - me = resolve_me(this, host->get_family(host)); - if (me) + enumerator_t *enumerator; + traffic_selector_t *ts; + char *str; + host_t *host; + u_int8_t mask; + u_int quality = 0; + + /* try single hosts first */ + enumerator = hosts->create_enumerator(hosts); + while (enumerator->enumerate(enumerator, &str)) { - if (me->ip_equals(me, host)) + host = host_create_from_dns(str, cand->get_family(cand), 0); + if (host) { - quality = 2; + if (host->ip_equals(host, cand)) + { + quality = max(quality, 128 + 1); + } + if (host->is_anyaddr(host)) + { + quality = max(quality, 1); + } + host->destroy(host); } - else if (this->my_allow_any) + } + enumerator->destroy(enumerator); + + /* then ranges/subnets */ + enumerator = ranges->create_enumerator(ranges); + while (enumerator->enumerate(enumerator, &ts)) + { + if (ts->includes(ts, cand)) { - quality = 1; + if (ts->to_subnet(ts, &host, &mask)) + { + quality = max(quality, mask + 1); + host->destroy(host); + } + else + { + quality = max(quality, 1); + } } - me->destroy(me); } + enumerator->destroy(enumerator); + return quality; } -METHOD(ike_cfg_t, match_other, u_int, +METHOD(ike_cfg_t, match_me, u_int, private_ike_cfg_t *this, host_t *host) { - host_t *other; - int quality = 0; + return match(this->my_hosts, this->my_ranges, host); +} - other = resolve_other(this, host->get_family(host)); - if (other) - { - if (other->ip_equals(other, host)) - { - quality = 2; - } - else if (this->other_allow_any) - { - quality = 1; - } - other->destroy(other); - } - return quality; +METHOD(ike_cfg_t, match_other, u_int, + private_ike_cfg_t *this, host_t *host) +{ + return match(this->other_hosts, this->other_ranges, host); } METHOD(ike_cfg_t, get_my_addr, char*, @@ -361,16 +424,110 @@ METHOD(ike_cfg_t, destroy, void, offsetof(proposal_t, destroy)); free(this->me); free(this->other); + this->my_hosts->destroy_function(this->my_hosts, free); + this->other_hosts->destroy_function(this->other_hosts, free); + this->my_ranges->destroy_offset(this->my_ranges, + offsetof(traffic_selector_t, destroy)); + this->other_ranges->destroy_offset(this->other_ranges, + offsetof(traffic_selector_t, destroy)); free(this); } } /** + * Try to parse a string as subnet + */ +static traffic_selector_t* make_subnet(char *str) +{ + char *pos; + + pos = strchr(str, '/'); + if (!pos) + { + return NULL; + } + return traffic_selector_create_from_cidr(str, 0, 0, 0); +} + +/** + * Try to parse a string as an IP range + */ +static traffic_selector_t* make_range(char *str) +{ + traffic_selector_t *ts; + ts_type_t type; + char *pos; + host_t *from, *to; + + pos = strchr(str, '-'); + if (!pos) + { + return NULL; + } + to = host_create_from_string(pos + 1, 0); + if (!to) + { + return NULL; + } + str = strndup(str, pos - str); + from = host_create_from_string_and_family(str, to->get_family(to), 0); + free(str); + if (!from) + { + to->destroy(to); + return NULL; + } + if (to->get_family(to) == AF_INET) + { + type = TS_IPV4_ADDR_RANGE; + } + else + { + type = TS_IPV6_ADDR_RANGE; + } + ts = traffic_selector_create_from_bytes(0, type, + from->get_address(from), 0, + to->get_address(to), 0); + from->destroy(from); + to->destroy(to); + return ts; +} + +/** + * Parse address string into lists of single hosts and ranges/subnets + */ +static void parse_addresses(char *str, linked_list_t *hosts, + linked_list_t *ranges) +{ + enumerator_t *enumerator; + traffic_selector_t *ts; + + enumerator = enumerator_create_token(str, ",", " "); + while (enumerator->enumerate(enumerator, &str)) + { + ts = make_subnet(str); + if (ts) + { + ranges->insert_last(ranges, ts); + continue; + } + ts = make_range(str); + if (ts) + { + ranges->insert_last(ranges, ts); + continue; + } + hosts->insert_last(hosts, strdup(str)); + } + enumerator->destroy(enumerator); +} + +/** * Described in header. */ ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap, - char *me, bool my_allow_any, u_int16_t my_port, - char *other, bool other_allow_any, u_int16_t other_port, + char *me, u_int16_t my_port, + char *other, u_int16_t other_port, fragmentation_t fragmentation, u_int8_t dscp) { private_ike_cfg_t *this; @@ -404,14 +561,19 @@ ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap, .force_encap = force_encap, .fragmentation = fragmentation, .me = strdup(me), + .my_ranges = linked_list_create(), + .my_hosts = linked_list_create(), .other = strdup(other), - .my_allow_any = my_allow_any, - .other_allow_any = other_allow_any, + .other_ranges = linked_list_create(), + .other_hosts = linked_list_create(), .my_port = my_port, .other_port = other_port, .dscp = dscp, .proposals = linked_list_create(), ); + parse_addresses(me, this->my_hosts, this->my_ranges); + parse_addresses(other, this->other_hosts, this->other_ranges); + return &this->public; } diff --git a/src/libcharon/config/ike_cfg.h b/src/libcharon/config/ike_cfg.h index 0540e93f3..f9e4fbebc 100644 --- a/src/libcharon/config/ike_cfg.h +++ b/src/libcharon/config/ike_cfg.h @@ -230,24 +230,27 @@ struct ike_cfg_t { /** * Creates a ike_cfg_t object. * - * Supplied hosts become owned by ike_cfg, the name gets cloned. + * Supplied hosts become owned by ike_cfg, strings get cloned. + * + * me and other are comma separated lists of IP addresses, DNS names, IP ranges + * or subnets. When initiating, the first non-range/subnet address is used + * as address. When responding, a match is performed against all items in the + * list. * * @param version IKE major version to use for this config * @param certreq TRUE to send a certificate request * @param force_encap enforce UDP encapsulation by faking NATD notify * @param me address/DNS name of local peer - * @param my_allow_any allow override of local address by any address * @param my_port IKE port to use as source, 500 uses IKEv2 port floating * @param other address/DNS name of remote peer - * @param other_allow_any allow override of remote address by any address * @param other_port IKE port to use as dest, 500 uses IKEv2 port floating * @param fragmentation use IKEv1 fragmentation * @param dscp DSCP value to send IKE packets with * @return ike_cfg_t object. */ ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap, - char *me, bool my_allow_any, u_int16_t my_port, - char *other, bool other_allow_any, u_int16_t other_port, + char *me, u_int16_t my_port, + char *other, u_int16_t other_port, fragmentation_t fragmentation, u_int8_t dscp); #endif /** IKE_CFG_H_ @}*/ diff --git a/src/libcharon/plugins/ha/ha_tunnel.c b/src/libcharon/plugins/ha/ha_tunnel.c index 26d152c8f..74147e553 100644 --- a/src/libcharon/plugins/ha/ha_tunnel.c +++ b/src/libcharon/plugins/ha/ha_tunnel.c @@ -203,9 +203,9 @@ static void setup_tunnel(private_ha_tunnel_t *this, lib->credmgr->add_set(lib->credmgr, &this->creds.public); /* create config and backend */ - ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local, FALSE, + ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local, charon->socket->get_port(charon->socket, FALSE), - remote, FALSE, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0); + remote, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0); ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); peer_cfg = peer_cfg_create("ha", ike_cfg, CERT_NEVER_SEND, UNIQUE_KEEP, 0, 86400, 0, 7200, 3600, FALSE, FALSE, diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c index 26c9871f0..620d482ad 100644 --- a/src/libcharon/plugins/load_tester/load_tester_config.c +++ b/src/libcharon/plugins/load_tester/load_tester_config.c @@ -544,16 +544,15 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num) if (this->port && num) { ike_cfg = ike_cfg_create(this->version, TRUE, FALSE, - local, FALSE, this->port + num - 1, - remote, FALSE, IKEV2_NATT_PORT, + local, this->port + num - 1, + remote, IKEV2_NATT_PORT, FRAGMENTATION_NO, 0); } else { - ike_cfg = ike_cfg_create(this->version, TRUE, FALSE, - local, FALSE, + ike_cfg = ike_cfg_create(this->version, TRUE, FALSE, local, charon->socket->get_port(charon->socket, FALSE), - remote, FALSE, IKEV2_UDP_PORT, + remote, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0); } ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal)); diff --git a/src/libcharon/plugins/maemo/maemo_service.c b/src/libcharon/plugins/maemo/maemo_service.c index f04bc5a4c..f0f3105c4 100644 --- a/src/libcharon/plugins/maemo/maemo_service.c +++ b/src/libcharon/plugins/maemo/maemo_service.c @@ -323,10 +323,9 @@ static gboolean initiate_connection(private_maemo_service_t *this, NULL); } - ike_cfg = ike_cfg_create(IKEV2, TRUE, FALSE, "0.0.0.0", FALSE, + ike_cfg = ike_cfg_create(IKEV2, TRUE, FALSE, "0.0.0.0", charon->socket->get_port(charon->socket, FALSE), - hostname, FALSE, IKEV2_UDP_PORT, FRAGMENTATION_NO, - 0); + hostname, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0); ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); peer_cfg = peer_cfg_create(this->current, ike_cfg, diff --git a/src/libcharon/plugins/medcli/medcli_config.c b/src/libcharon/plugins/medcli/medcli_config.c index e852e3f47..d048b003b 100644 --- a/src/libcharon/plugins/medcli/medcli_config.c +++ b/src/libcharon/plugins/medcli/medcli_config.c @@ -102,10 +102,9 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*, DESTROY_IF(e); return NULL; } - ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, - "0.0.0.0", FALSE, + ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, "0.0.0.0", charon->socket->get_port(charon->socket, FALSE), - address, FALSE, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0); + address, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0); ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); med_cfg = peer_cfg_create( "mediation", ike_cfg, @@ -377,10 +376,9 @@ medcli_config_t *medcli_config_create(database_t *db) .db = db, .rekey = lib->settings->get_time(lib->settings, "medcli.rekey", 1200), .dpd = lib->settings->get_time(lib->settings, "medcli.dpd", 300), - .ike = ike_cfg_create(IKEV2, FALSE, FALSE, - "0.0.0.0", FALSE, + .ike = ike_cfg_create(IKEV2, FALSE, FALSE, "0.0.0.0", charon->socket->get_port(charon->socket, FALSE), - "0.0.0.0", FALSE, IKEV2_UDP_PORT, + "0.0.0.0", IKEV2_UDP_PORT, FRAGMENTATION_NO, 0), ); this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE)); diff --git a/src/libcharon/plugins/medsrv/medsrv_config.c b/src/libcharon/plugins/medsrv/medsrv_config.c index 45487a976..ac6076ae8 100644 --- a/src/libcharon/plugins/medsrv/medsrv_config.c +++ b/src/libcharon/plugins/medsrv/medsrv_config.c @@ -139,10 +139,9 @@ medsrv_config_t *medsrv_config_create(database_t *db) .db = db, .rekey = lib->settings->get_time(lib->settings, "medsrv.rekey", 1200), .dpd = lib->settings->get_time(lib->settings, "medsrv.dpd", 300), - .ike = ike_cfg_create(IKEV2, FALSE, FALSE, - "0.0.0.0", FALSE, + .ike = ike_cfg_create(IKEV2, FALSE, FALSE, "0.0.0.0", charon->socket->get_port(charon->socket, FALSE), - "0.0.0.0", FALSE, IKEV2_UDP_PORT, + "0.0.0.0", IKEV2_UDP_PORT, FRAGMENTATION_NO, 0), ); this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE)); diff --git a/src/libcharon/plugins/sql/sql_config.c b/src/libcharon/plugins/sql/sql_config.c index e6b69a4f4..a8d34f2d4 100644 --- a/src/libcharon/plugins/sql/sql_config.c +++ b/src/libcharon/plugins/sql/sql_config.c @@ -258,11 +258,9 @@ static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e, { ike_cfg_t *ike_cfg; - ike_cfg = ike_cfg_create(IKEV2, certreq, force_encap, - local, FALSE, + ike_cfg = ike_cfg_create(IKEV2, certreq, force_encap, local, charon->socket->get_port(charon->socket, FALSE), - remote, FALSE, IKEV2_UDP_PORT, - FRAGMENTATION_NO, 0); + remote, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0); add_ike_proposals(this, ike_cfg, id); return ike_cfg; } diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index 1ab32afb1..bd3f76b0e 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -191,53 +191,86 @@ static void add_proposals(private_stroke_config_t *this, char *string, */ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg) { + enumerator_t *enumerator; stroke_end_t tmp_end; ike_cfg_t *ike_cfg; host_t *host; u_int16_t ikeport; + char me[256], other[256], *token; + bool swapped = FALSE;; - host = host_create_from_dns(msg->add_conn.other.address, 0, 0); - if (host) + enumerator = enumerator_create_token(msg->add_conn.other.address, ",", " "); + while (enumerator->enumerate(enumerator, &token)) { - if (hydra->kernel_interface->get_interface(hydra->kernel_interface, - host, NULL)) + if (!strchr(token, '/')) { - DBG2(DBG_CFG, "left is other host, swapping ends"); - tmp_end = msg->add_conn.me; - msg->add_conn.me = msg->add_conn.other; - msg->add_conn.other = tmp_end; - host->destroy(host); - } - else - { - host->destroy(host); - host = host_create_from_dns(msg->add_conn.me.address, 0, 0); + host = host_create_from_dns(token, 0, 0); if (host) { - if (!hydra->kernel_interface->get_interface( + if (hydra->kernel_interface->get_interface( hydra->kernel_interface, host, NULL)) { - DBG1(DBG_CFG, "left nor right host is our side, " - "assuming left=local"); + DBG2(DBG_CFG, "left is other host, swapping ends"); + tmp_end = msg->add_conn.me; + msg->add_conn.me = msg->add_conn.other; + msg->add_conn.other = tmp_end; + host->destroy(host); + swapped = TRUE; } host->destroy(host); } } } + enumerator->destroy(enumerator); + + if (!swapped) + { + enumerator = enumerator_create_token(msg->add_conn.me.address, ",", " "); + while (enumerator->enumerate(enumerator, &token)) + { + if (!strchr(token, '/')) + { + host = host_create_from_dns(token, 0, 0); + if (host) + { + if (!hydra->kernel_interface->get_interface( + hydra->kernel_interface, host, NULL)) + { + DBG1(DBG_CFG, "left nor right host is our side, " + "assuming left=local"); + } + host->destroy(host); + } + } + } + enumerator->destroy(enumerator); + } + + if (msg->add_conn.me.allow_any) + { + snprintf(me, sizeof(me), "%s,0.0.0.0/0,::/0", + msg->add_conn.me.address); + } + if (msg->add_conn.other.allow_any) + { + snprintf(other, sizeof(other), "%s,0.0.0.0/0,::/0", + msg->add_conn.other.address); + } ikeport = msg->add_conn.me.ikeport; ikeport = (ikeport == IKEV2_UDP_PORT) ? charon->socket->get_port(charon->socket, FALSE) : ikeport; ike_cfg = ike_cfg_create(msg->add_conn.version, msg->add_conn.other.sendcert != CERT_NEVER_SEND, msg->add_conn.force_encap, - msg->add_conn.me.address, - msg->add_conn.me.allow_any, + msg->add_conn.me.allow_any ? + me : msg->add_conn.me.address, ikeport, - msg->add_conn.other.address, - msg->add_conn.other.allow_any, + msg->add_conn.other.allow_any ? + other : msg->add_conn.other.address, msg->add_conn.other.ikeport, msg->add_conn.fragmentation, msg->add_conn.ikedscp); + add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL); return ike_cfg; } @@ -824,7 +857,15 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this, } else { - if (strchr(ike_cfg->get_my_addr(ike_cfg), ':')) + char *addr, *next, *hit; + + /* guess virtual IP family based on local address. If + * multiple addresses are specified, we look at the first + * only, as with leftallowany a ::/0 is always appended. */ + addr = ike_cfg->get_my_addr(ike_cfg); + next = strchr(addr, ','); + hit = strchr(addr, ':'); + if (hit && (!next || hit < next)) { vip = host_create_any(AF_INET6); } diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index a788ce581..a5825519b 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -544,7 +544,6 @@ METHOD(stroke_list_t, status, void, while (enumerator->enumerate(enumerator, &peer_cfg)) { char *my_addr, *other_addr; - bool my_allow_any, other_allow_any; if (name && !streq(name, peer_cfg->get_name(peer_cfg))) { @@ -553,8 +552,8 @@ METHOD(stroke_list_t, status, void, ike_cfg = peer_cfg->get_ike_cfg(peer_cfg); ike_version = peer_cfg->get_ike_version(peer_cfg); - my_addr = ike_cfg->get_my_addr(ike_cfg, &my_allow_any); - other_addr = ike_cfg->get_other_addr(ike_cfg, &other_allow_any); + my_addr = ike_cfg->get_my_addr(ike_cfg); + other_addr = ike_cfg->get_other_addr(ike_cfg); fprintf(out, "%12s: %s...%s %N", peer_cfg->get_name(peer_cfg), my_addr, other_addr, ike_version_names, ike_version); diff --git a/src/libcharon/plugins/uci/uci_config.c b/src/libcharon/plugins/uci/uci_config.c index 040d8a84f..2a8e40380 100644 --- a/src/libcharon/plugins/uci/uci_config.c +++ b/src/libcharon/plugins/uci/uci_config.c @@ -152,10 +152,9 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool, &ike_proposal, &esp_proposal, &ike_rekey, &esp_rekey)) { DESTROY_IF(this->peer_cfg); - ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, - local_addr, FALSE, + ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local_addr, charon->socket->get_port(charon->socket, FALSE), - remote_addr, FALSE, IKEV2_UDP_PORT, + remote_addr, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0); ike_cfg->add_proposal(ike_cfg, create_proposal(ike_proposal, PROTO_IKE)); this->peer_cfg = peer_cfg_create( @@ -251,10 +250,9 @@ METHOD(enumerator_t, ike_enumerator_enumerate, bool, &local_addr, &remote_addr, &ike_proposal)) { DESTROY_IF(this->ike_cfg); - this->ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, - local_addr, FALSE, + this->ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local_addr, charon->socket->get_port(charon->socket, FALSE), - remote_addr, FALSE, IKEV2_UDP_PORT, + remote_addr, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0); this->ike_cfg->add_proposal(this->ike_cfg, create_proposal(ike_proposal, PROTO_IKE)); |