Hi, Regarding https://wiki.strongswan.org/issues/2548, the following patch is working for me and it may help someone else. I am new here so let me know if not conforming to your common practices.
>From a2049bfc44bb2a18cafed84fb8da2c2d7b9b87f3 Mon, 26 Feb 2018 11:59:39 +0100 From: Alan H. Kayahan <[email protected]> Date: Mon, 26 Feb 2018 10:55:40 +0100 Subject: [PATCH] CVPN3000-IPSec-Split-Tunnel-List(RADIUS) -> INTERNAL_IPV4_SUBNET (IKEv2) CVPN3000-IPSec-Split-Tunnel-List is a RADIUS attribute that carries split-tunneling information in the form of Address1/Netmask1, Addressn/Netmaskn. Strongswan translates this RADIUS attribute to the respective IKEv1 UNITY attributes only. This patch allows translating CVPN3000-IPSec-Split-Tunnel-List to INTERNAL_IPV4_SUBNET when IKEv2 is used. diff --git a/src/libcharon/plugins/eap_radius/eap_radius.c b/src/libcharon/plugins/eap_radius/eap_radius.c index fbbf6da..5998c52 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius.c +++ b/src/libcharon/plugins/eap_radius/eap_radius.c @@ -445,36 +445,40 @@ case 31: /* MS-Secondary-NBNS-Server */ provider->add_attribute(provider, id, INTERNAL_IP4_NBNS, data); break; case RAT_FRAMED_IPV6_DNS_SERVER: provider->add_attribute(provider, id, INTERNAL_IP6_DNS, data); break; } } /** - * Add a UNITY_LOCAL_LAN or UNITY_SPLIT_INCLUDE attribute + * Add a UNITY_LOCAL_LAN or UNITY_SPLIT_INCLUDE attribute if IKEv1 + * Add INTERNAL_IP4_SUBNET attribute(s) if IKEv2 */ -static void add_unity_split_attribute(eap_radius_provider_t *provider, +static void add_unity_split_attribute(bool translate, eap_radius_provider_t *provider, uint32_t id, configuration_attribute_type_t type, chunk_t data) { enumerator_t *enumerator; bio_writer_t *writer; char buffer[256], *token, *slash; if (snprintf(buffer, sizeof(buffer), "%.*s", (int)data.len, data.ptr) >= sizeof(buffer)) { return; } - writer = bio_writer_create(16); /* two IPv4 addresses and 6 bytes padding */ + /* writer for IKEv1: 16 bytes - Two IPv4 addresses and 6 bytes padding + * writer for IKEv2: 8 bytes - Two IPv4 addresses + */ + writer = translate ? bio_writer_create(16) : bio_writer_create(8); enumerator = enumerator_create_token(buffer, ",", " "); while (enumerator->enumerate(enumerator, &token)) { host_t *net, *mask = NULL; chunk_t padding; slash = strchr(token, '/'); if (slash) { *slash++ = '\0'; @@ -485,31 +489,41 @@ mask = host_create_from_string("255.255.255.255", 0); } net = host_create_from_string(token, 0); if (!net || net->get_family(net) != AF_INET || mask->get_family(mask) != AF_INET) { mask->destroy(mask); DESTROY_IF(net); continue; } - writer->write_data(writer, net->get_address(net)); - writer->write_data(writer, mask->get_address(mask)); - padding = writer->skip(writer, 6); /* 6 bytes pdding */ - memset(padding.ptr, 0, padding.len); + if (!translate) { + writer->write_data(writer, net->get_address(net)); + writer->write_data(writer, mask->get_address(mask)); + padding = writer->skip(writer, 6); /* 6 bytes padding */ + memset(padding.ptr, 0, padding.len); + } /*If adding to IKEv2 CP, each split-tunnel CIDR has to be contained in its own configuration attribute.*/ + else { + writer->write_data(writer, net->get_address(net)); + writer->write_data(writer, mask->get_address(mask)); + data = writer->extract_buf(writer); + if (data.len) + { + provider->add_attribute(provider, id, INTERNAL_IP4_SUBNET, data); + } + } mask->destroy(mask); net->destroy(net); } enumerator->destroy(enumerator); - data = writer->get_buf(writer); - if (data.len) + if (!translate && data.len) { provider->add_attribute(provider, id, type, data); } writer->destroy(writer); } /** * Handle Framed-IP-Address and other IKE configuration attributes */ static void process_cfg_attributes(radius_message_t *msg) @@ -611,36 +625,36 @@ if (data.len == 4) { add_nameserver_attribute(provider, ike_sa->get_unique_id(ike_sa), type, data); } break; } } } enumerator->destroy(enumerator); - - if (split_type != 0 && - ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY)) - { - enumerator = msg->create_vendor_enumerator(msg); - while (enumerator->enumerate(enumerator, &vendor, &type, &data)) + //If IKEv2, translate CVPN3000-IPSec-Split-Tunnel-List to INTERNAL_IPV4_SUBNET + bool translate = (ike_sa->get_version(ike_sa) == IKEV2) ? true : false ; + if (translate || (split_type != 0 && ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY))) { - if (vendor == PEN_ALTIGA /* aka Cisco VPN3000 */ && - type == 27 /* CVPN3000-IPSec-Split-Tunnel-List */) + enumerator = msg->create_vendor_enumerator(msg); + while (enumerator->enumerate(enumerator, &vendor, &type, &data)) { - add_unity_split_attribute(provider, - ike_sa->get_unique_id(ike_sa), split_type, data); + if (vendor == PEN_ALTIGA /* aka Cisco VPN3000 */ && + type == 27 /* CVPN3000-IPSec-Split-Tunnel-List */) + { + add_unity_split_attribute(translate,provider, + ike_sa->get_unique_id(ike_sa), split_type, data); + } } + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); - } } } /** * See header. */ void eap_radius_process_attributes(radius_message_t *message) { process_class(message); if (lib->settings->get_bool(lib->settings,
