diff options
author | Tobias Brunner <tobias@strongswan.org> | 2017-02-20 11:36:30 +0100 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2017-02-27 18:23:56 +0100 |
commit | da82786b2d8cef68ca6462bf7898a6b19c0b4608 (patch) | |
tree | 56f19b0c217c2847870ed2a231c21ae09eab6fc0 | |
parent | 2e52bbb4b220ce604f84124ba6cf9d8656e81b1b (diff) | |
download | strongswan-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.c | 33 |
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); |