eap-radius: Forward UNITY_SPLIT_INCLUDE or UNITY_LOCAL_LAN attributes
Depending on the value of the CVPN3000-IPSec-Split-Tunneling-Policy(55) radius attribute, the subnets in the CVPN3000-IPSec-Split-Tunnel-List(27) attribute are sent in either a UNITY_SPLIT_INCLUDE (if the value is 1) or a UNITY_LOCAL_LAN (if the value is 2). So if the following attributes would be configured for a RADIUS user CVPN3000-IPSec-Split-Tunnel-List := "10.0.1.0/255.255.255.0,10.0.2.0/255.255.255.0" CVPN3000-IPSec-Split-Tunneling-Policy := 1 A UNITY_SPLIT_INCLUDE configuration payload containing these two subnets would be sent to the client during the ModeCfg exchange.
This commit is contained in:
parent
66229619cf
commit
1a809e46f8
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <radius_message.h>
|
||||
#include <radius_client.h>
|
||||
#include <bio/bio_writer.h>
|
||||
|
||||
#include <daemon.h>
|
||||
|
||||
|
@ -412,6 +413,64 @@ static void add_unity_attribute(eap_radius_provider_t *provider, u_int32_t id,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a UNITY_LOCAL_LAN or UNITY_SPLIT_INCLUDE attribute
|
||||
*/
|
||||
static void add_unity_split_attribute(eap_radius_provider_t *provider,
|
||||
u_int32_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 */
|
||||
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';
|
||||
mask = host_create_from_string(slash, 0);
|
||||
}
|
||||
if (!mask)
|
||||
{ /* default to /32 */
|
||||
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);
|
||||
mask->destroy(mask);
|
||||
net->destroy(net);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
data = writer->get_buf(writer);
|
||||
if (data.len)
|
||||
{
|
||||
provider->add_attribute(provider, id, type, data);
|
||||
}
|
||||
writer->destroy(writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Framed-IP-Address and other IKE configuration attributes
|
||||
*/
|
||||
|
@ -422,6 +481,7 @@ static void process_cfg_attributes(radius_message_t *msg)
|
|||
ike_sa_t *ike_sa;
|
||||
host_t *host;
|
||||
chunk_t data;
|
||||
configuration_attribute_type_t split_type = 0;
|
||||
int type, vendor;
|
||||
|
||||
ike_sa = charon->bus->get_sa(charon->bus);
|
||||
|
@ -460,12 +520,45 @@ static void process_cfg_attributes(radius_message_t *msg)
|
|||
ike_sa->get_unique_id(ike_sa), type, data);
|
||||
}
|
||||
break;
|
||||
case 55: /* CVPN3000-IPSec-Split-Tunneling-Policy */
|
||||
if (data.len)
|
||||
{
|
||||
switch (data.ptr[data.len - 1])
|
||||
{
|
||||
case 0: /* tunnelall */
|
||||
default:
|
||||
break;
|
||||
case 1: /* tunnelspecified */
|
||||
split_type = UNITY_SPLIT_INCLUDE;
|
||||
break;
|
||||
case 2: /* excludespecified */
|
||||
split_type = UNITY_LOCAL_LAN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
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 (vendor == PEN_ALTIGA /* aka Cisco VPN3000 */ &&
|
||||
type == 27 /* CVPN3000-IPSec-Split-Tunnel-List */)
|
||||
{
|
||||
add_unity_split_attribute(provider,
|
||||
ike_sa->get_unique_id(ike_sa), split_type, data);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue