aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/charon-cmd/cmd/cmd_connection.c4
-rw-r--r--src/charon-nm/nm/nm_service.c4
-rw-r--r--src/conftest/config.c4
-rw-r--r--src/frontends/android/jni/libandroidbridge/backend/android_service.c4
-rw-r--r--src/frontends/osx/charon-xpc/xpc_dispatch.c4
-rw-r--r--src/libcharon/config/ike_cfg.c244
-rw-r--r--src/libcharon/config/ike_cfg.h13
-rw-r--r--src/libcharon/plugins/ha/ha_tunnel.c4
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_config.c9
-rw-r--r--src/libcharon/plugins/maemo/maemo_service.c5
-rw-r--r--src/libcharon/plugins/medcli/medcli_config.c10
-rw-r--r--src/libcharon/plugins/medsrv/medsrv_config.c5
-rw-r--r--src/libcharon/plugins/sql/sql_config.c6
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.c85
-rw-r--r--src/libcharon/plugins/stroke/stroke_list.c5
-rw-r--r--src/libcharon/plugins/uci/uci_config.c10
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));