vici: Match subnets and ranges against peer IP in redirect command
This commit is contained in:
@@ -297,7 +297,8 @@ supported by the peer.
|
|||||||
{
|
{
|
||||||
ike = <redirect an IKE_SA by configuration name>
|
ike = <redirect an IKE_SA by configuration name>
|
||||||
ike-id = <redirect an IKE_SA by its unique id>
|
ike-id = <redirect an IKE_SA by its unique id>
|
||||||
peer-ip = <redirect an IKE_SA with matching peer IP>
|
peer-ip = <redirect an IKE_SA with matching peer IP, may also be a
|
||||||
|
subnet in CIDR notation or an IP range>
|
||||||
peer-id = <redirect an IKE_SA with matching peer identity, may contain
|
peer-id = <redirect an IKE_SA with matching peer identity, may contain
|
||||||
wildcards>
|
wildcards>
|
||||||
} => {
|
} => {
|
||||||
|
|||||||
@@ -360,6 +360,36 @@ CALLBACK(terminate, vici_message_t*,
|
|||||||
return builder->finalize(builder);
|
return builder->finalize(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a peer-ip specified, which can be a subnet in CIDR notation, a range
|
||||||
|
* or a single IP address.
|
||||||
|
*/
|
||||||
|
static traffic_selector_t *parse_peer_ip(char *ip)
|
||||||
|
{
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
host_t *from, *to;
|
||||||
|
ts_type_t type;
|
||||||
|
|
||||||
|
if (host_create_from_range(ip, &from, &to))
|
||||||
|
{
|
||||||
|
if (to->get_family(to) == AF_INET)
|
||||||
|
{
|
||||||
|
type = TS_IPV4_ADDR_RANGE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = TS_IPV6_ADDR_RANGE;
|
||||||
|
}
|
||||||
|
ts = traffic_selector_create_from_bytes(0, type,
|
||||||
|
from->get_address(from), 0,
|
||||||
|
to->get_address(to), 0xFFFF);
|
||||||
|
from->destroy(from);
|
||||||
|
to->destroy(to);
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
return traffic_selector_create_from_cidr(ip, 0, 0, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
CALLBACK(redirect, vici_message_t*,
|
CALLBACK(redirect, vici_message_t*,
|
||||||
private_vici_control_t *this, char *name, u_int id, vici_message_t *request)
|
private_vici_control_t *this, char *name, u_int id, vici_message_t *request)
|
||||||
{
|
{
|
||||||
@@ -367,7 +397,7 @@ CALLBACK(redirect, vici_message_t*,
|
|||||||
char *ike, *peer_ip, *peer_id, *gw, *errmsg = NULL;
|
char *ike, *peer_ip, *peer_id, *gw, *errmsg = NULL;
|
||||||
u_int ike_id, current, found = 0;
|
u_int ike_id, current, found = 0;
|
||||||
identification_t *gateway, *identity = NULL, *other_id;
|
identification_t *gateway, *identity = NULL, *other_id;
|
||||||
host_t *address = NULL;
|
traffic_selector_t *ts = NULL;
|
||||||
ike_sa_t *ike_sa;
|
ike_sa_t *ike_sa;
|
||||||
vici_builder_t *builder;
|
vici_builder_t *builder;
|
||||||
|
|
||||||
@@ -392,12 +422,12 @@ CALLBACK(redirect, vici_message_t*,
|
|||||||
}
|
}
|
||||||
if (peer_ip)
|
if (peer_ip)
|
||||||
{
|
{
|
||||||
address = host_create_from_string(peer_ip, 0);
|
ts = parse_peer_ip(peer_ip);
|
||||||
if (!address)
|
if (!ts)
|
||||||
{
|
{
|
||||||
return send_reply(this, "invalid peer IP selector");
|
return send_reply(this, "invalid peer IP selector");
|
||||||
}
|
}
|
||||||
DBG1(DBG_CFG, "vici redirect IKE_SAs with src %H to %Y", address,
|
DBG1(DBG_CFG, "vici redirect IKE_SAs with src %R to %Y", ts,
|
||||||
gateway);
|
gateway);
|
||||||
}
|
}
|
||||||
if (peer_id)
|
if (peer_id)
|
||||||
@@ -405,7 +435,7 @@ CALLBACK(redirect, vici_message_t*,
|
|||||||
identity = identification_create_from_string(peer_id);
|
identity = identification_create_from_string(peer_id);
|
||||||
if (!identity)
|
if (!identity)
|
||||||
{
|
{
|
||||||
DESTROY_IF(address);
|
DESTROY_IF(ts);
|
||||||
return send_reply(this, "invalid peer identity selector");
|
return send_reply(this, "invalid peer identity selector");
|
||||||
}
|
}
|
||||||
DBG1(DBG_CFG, "vici redirect IKE_SAs with ID '%Y' to %Y", identity,
|
DBG1(DBG_CFG, "vici redirect IKE_SAs with ID '%Y' to %Y", identity,
|
||||||
@@ -413,15 +443,15 @@ CALLBACK(redirect, vici_message_t*,
|
|||||||
}
|
}
|
||||||
if (ike_id)
|
if (ike_id)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "vici redirect IKE_SA #%d to %Y", ike_id, gateway);
|
DBG1(DBG_CFG, "vici redirect IKE_SA #%d to '%Y'", ike_id, gateway);
|
||||||
}
|
}
|
||||||
if (ike)
|
if (ike)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "vici redirect IKE_SA '%s' to %Y", ike, gateway);
|
DBG1(DBG_CFG, "vici redirect IKE_SA '%s' to '%Y'", ike, gateway);
|
||||||
}
|
}
|
||||||
if (!peer_ip && !peer_id && !ike && !ike_id)
|
if (!peer_ip && !peer_id && !ike && !ike_id)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "vici redirect all IKE_SAs to %Y", gateway);
|
DBG1(DBG_CFG, "vici redirect all IKE_SAs to '%Y'", gateway);
|
||||||
}
|
}
|
||||||
|
|
||||||
sas = charon->controller->create_ike_sa_enumerator(charon->controller, TRUE);
|
sas = charon->controller->create_ike_sa_enumerator(charon->controller, TRUE);
|
||||||
@@ -440,8 +470,7 @@ CALLBACK(redirect, vici_message_t*,
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (address &&
|
if (ts && !ts->includes(ts, ike_sa->get_other_host(ike_sa)))
|
||||||
!address->ip_equals(address, ike_sa->get_other_host(ike_sa)))
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -471,7 +500,7 @@ CALLBACK(redirect, vici_message_t*,
|
|||||||
}
|
}
|
||||||
gateway->destroy(gateway);
|
gateway->destroy(gateway);
|
||||||
DESTROY_IF(identity);
|
DESTROY_IF(identity);
|
||||||
DESTROY_IF(address);
|
DESTROY_IF(ts);
|
||||||
return builder->finalize(builder);
|
return builder->finalize(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ static void __attribute__ ((constructor))reg()
|
|||||||
{
|
{
|
||||||
command_register((command_t) {
|
command_register((command_t) {
|
||||||
redirect, 'd', "redirect", "redirect an IKE_SA",
|
redirect, 'd', "redirect", "redirect an IKE_SA",
|
||||||
{"--ike <name> | --ike-id <id> | --peer-ip <ip>",
|
{"--ike <name> | --ike-id <id> | --peer-ip <ip|subnet|range>",
|
||||||
"--peer-id <id|wildcards> | --gateway <ip|fqdn> [--raw|--pretty]"},
|
"--peer-id <id|wildcards> | --gateway <ip|fqdn> [--raw|--pretty]"},
|
||||||
{
|
{
|
||||||
{"help", 'h', 0, "show usage information"},
|
{"help", 'h', 0, "show usage information"},
|
||||||
|
|||||||
Reference in New Issue
Block a user