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