aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2017-02-20 11:36:30 +0100
committerTobias Brunner <tobias@strongswan.org>2017-02-27 18:23:56 +0100
commitda82786b2d8cef68ca6462bf7898a6b19c0b4608 (patch)
tree56f19b0c217c2847870ed2a231c21ae09eab6fc0
parent2e52bbb4b220ce604f84124ba6cf9d8656e81b1b (diff)
downloadstrongswan-da82786b2d8cef68ca6462bf7898a6b19c0b4608.tar.bz2
strongswan-da82786b2d8cef68ca6462bf7898a6b19c0b4608.tar.xz
child-cfg: Always apply hosts to traffic selectors if proposing transport mode
Usually, %dynamic is used as traffic selector for transport mode SAs, however, if wildcard traps are used then the remote TS will be a subnet. With strongSwan at the remote end that usually works fine as the local %dynamic TS narrows the proposed TS appropriately. But some implementations reject non-host TS for transport mode SAs. Another problem could be if several distinct subnets are configured for a wildcard trap, as we'd then propose unrelated subnets on that transport mode SA, which might be problematic even for strongSwan (switch to tunnel mode and duplicate policies). Closes strongswan/strongswan#61.
-rw-r--r--src/libcharon/config/child_cfg.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c
index d35c20ec5..3c6dd5198 100644
--- a/src/libcharon/config/child_cfg.c
+++ b/src/libcharon/config/child_cfg.c
@@ -306,25 +306,30 @@ METHOD(child_cfg_t, get_traffic_selectors, linked_list_t*,
{
e1 = this->other_ts->create_enumerator(this->other_ts);
}
- /* In a first step, replace "dynamic" TS with the host list */
+ /* in a first step, replace "dynamic" TS with the host list */
while (e1->enumerate(e1, &ts1))
{
- if (hosts && hosts->get_count(hosts) &&
- ts1->is_dynamic(ts1))
- {
- e2 = hosts->create_enumerator(hosts);
- while (e2->enumerate(e2, &host))
+ if (hosts && hosts->get_count(hosts))
+ { /* set hosts if TS is dynamic or as initiator in transport mode */
+ bool dynamic = ts1->is_dynamic(ts1);
+ if (dynamic || (this->mode == MODE_TRANSPORT && !this->proxy_mode &&
+ !supplied))
{
- ts2 = ts1->clone(ts1);
- ts2->set_address(ts2, host);
- derived->insert_last(derived, ts2);
+ e2 = hosts->create_enumerator(hosts);
+ while (e2->enumerate(e2, &host))
+ {
+ ts2 = ts1->clone(ts1);
+ if (dynamic || !host->is_anyaddr(host))
+ { /* don't make regular TS larger than they were */
+ ts2->set_address(ts2, host);
+ }
+ derived->insert_last(derived, ts2);
+ }
+ e2->destroy(e2);
+ continue;
}
- e2->destroy(e2);
- }
- else
- {
- derived->insert_last(derived, ts1->clone(ts1));
}
+ derived->insert_last(derived, ts1->clone(ts1));
}
e1->destroy(e1);