vici: Add redirect command
This allows redirecting IKE_SAs by multiple different selectors, if none are given all SAs are redirected.
This commit is contained in:
parent
0d424d2107
commit
43b46b26ea
|
@ -289,6 +289,21 @@ Terminates an SA while streaming _control-log_ events.
|
||||||
The default timeout of 0 waits indefinitely for a result, and a timeout value
|
The default timeout of 0 waits indefinitely for a result, and a timeout value
|
||||||
of -1 returns a result immediately.
|
of -1 returns a result immediately.
|
||||||
|
|
||||||
|
### redirect() ###
|
||||||
|
|
||||||
|
Redirect a client-initiated IKE_SA to another gateway. Only for IKEv2 and if
|
||||||
|
supported by the peer.
|
||||||
|
|
||||||
|
{
|
||||||
|
ike = <redirect an IKE_SA by configuration name>
|
||||||
|
ike-id = <redirect an IKE_SA by its unique id>
|
||||||
|
peer-ip = <redirect an IKE_SA with matching peer IP>
|
||||||
|
peer-id = <redirect an IKE_SA with matching peer identity>
|
||||||
|
} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure>
|
||||||
|
}
|
||||||
|
|
||||||
### install() ###
|
### install() ###
|
||||||
|
|
||||||
Install a trap, drop or bypass policy defined by a CHILD_SA config.
|
Install a trap, drop or bypass policy defined by a CHILD_SA config.
|
||||||
|
|
|
@ -36,6 +36,10 @@ sub terminate {
|
||||||
return request_vars_res('terminate', @_);
|
return request_vars_res('terminate', @_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub redirect {
|
||||||
|
return request_vars_res('redirect', @_);
|
||||||
|
}
|
||||||
|
|
||||||
sub install {
|
sub install {
|
||||||
return request_vars_res('install', @_);
|
return request_vars_res('install', @_);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,14 @@ class Session(object):
|
||||||
"""
|
"""
|
||||||
return self.handler.streamed_request("terminate", "control-log", sa)
|
return self.handler.streamed_request("terminate", "control-log", sa)
|
||||||
|
|
||||||
|
def redirect(self, sa):
|
||||||
|
"""Redirect an IKE_SA.
|
||||||
|
|
||||||
|
:param sa: the SA to redirect
|
||||||
|
:type sa: dict
|
||||||
|
"""
|
||||||
|
self.handler.request("redirect", sa)
|
||||||
|
|
||||||
def install(self, policy):
|
def install(self, policy):
|
||||||
"""Install a trap, drop or bypass policy defined by a CHILD_SA config.
|
"""Install a trap, drop or bypass policy defined by a CHILD_SA config.
|
||||||
|
|
||||||
|
|
|
@ -504,6 +504,12 @@ module Vici
|
||||||
"control-log", &block))
|
"control-log", &block))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Redirect an IKE_SA.
|
||||||
|
def redirect(options)
|
||||||
|
check_success(@transp.request("redirect", Message.new(options)))
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Install a shunt/route policy.
|
# Install a shunt/route policy.
|
||||||
def install(policy)
|
def install(policy)
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2015 Tobias Brunner
|
||||||
|
* Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
* Copyright (C) 2014 Martin Willi
|
* Copyright (C) 2014 Martin Willi
|
||||||
* Copyright (C) 2014 revosec AG
|
* Copyright (C) 2014 revosec AG
|
||||||
*
|
*
|
||||||
|
@ -20,6 +23,7 @@
|
||||||
|
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
#include <collections/array.h>
|
#include <collections/array.h>
|
||||||
|
#include <processing/jobs/redirect_job.h>
|
||||||
|
|
||||||
typedef struct private_vici_control_t private_vici_control_t;
|
typedef struct private_vici_control_t private_vici_control_t;
|
||||||
|
|
||||||
|
@ -356,6 +360,118 @@ CALLBACK(terminate, vici_message_t*,
|
||||||
return builder->finalize(builder);
|
return builder->finalize(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CALLBACK(redirect, vici_message_t*,
|
||||||
|
private_vici_control_t *this, char *name, u_int id, vici_message_t *request)
|
||||||
|
{
|
||||||
|
enumerator_t *sas;
|
||||||
|
char *ike, *peer_ip, *peer_id, *gw, *errmsg = NULL;
|
||||||
|
u_int ike_id, current, found = 0;
|
||||||
|
identification_t *gateway, *identity = NULL;
|
||||||
|
host_t *address = NULL;
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
vici_builder_t *builder;
|
||||||
|
|
||||||
|
ike = request->get_str(request, NULL, "ike");
|
||||||
|
ike_id = request->get_int(request, 0, "ike-id");
|
||||||
|
peer_ip = request->get_str(request, NULL, "peer-ip");
|
||||||
|
peer_id = request->get_str(request, NULL, "peer-id");
|
||||||
|
gw = request->get_str(request, NULL, "gateway");
|
||||||
|
|
||||||
|
if (!gw || !(gateway = identification_create_from_string(gw)))
|
||||||
|
{
|
||||||
|
return send_reply(this, "missing target gateway");
|
||||||
|
}
|
||||||
|
switch (gateway->get_type(gateway))
|
||||||
|
{
|
||||||
|
case ID_IPV4_ADDR:
|
||||||
|
case ID_IPV6_ADDR:
|
||||||
|
case ID_FQDN:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return send_reply(this, "unsupported gateway identity");
|
||||||
|
}
|
||||||
|
if (peer_ip)
|
||||||
|
{
|
||||||
|
address = host_create_from_string(peer_ip, 0);
|
||||||
|
if (!address)
|
||||||
|
{
|
||||||
|
return send_reply(this, "invalid peer IP selector");
|
||||||
|
}
|
||||||
|
DBG1(DBG_CFG, "vici redirect IKE_SAs with src %H to %Y", address,
|
||||||
|
gateway);
|
||||||
|
}
|
||||||
|
if (peer_id)
|
||||||
|
{
|
||||||
|
identity = identification_create_from_string(peer_id);
|
||||||
|
if (!identity)
|
||||||
|
{
|
||||||
|
DESTROY_IF(address);
|
||||||
|
return send_reply(this, "invalid peer identity selector");
|
||||||
|
}
|
||||||
|
DBG1(DBG_CFG, "vici redirect IKE_SAs with ID '%Y' to %Y", identity,
|
||||||
|
gateway);
|
||||||
|
}
|
||||||
|
if (ike_id)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "vici redirect IKE_SA #%d to %Y", ike_id, gateway);
|
||||||
|
}
|
||||||
|
if (ike)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "vici redirect IKE_SA '%s' to %Y", ike, gateway);
|
||||||
|
}
|
||||||
|
if (!peer_ip && !peer_id && !ike && !ike_id)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "vici redirect all IKE_SAs to %Y", gateway);
|
||||||
|
}
|
||||||
|
|
||||||
|
sas = charon->controller->create_ike_sa_enumerator(charon->controller, TRUE);
|
||||||
|
while (sas->enumerate(sas, &ike_sa))
|
||||||
|
{
|
||||||
|
if (ike_sa->get_version(ike_sa) != IKEV2)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
current = ike_sa->get_unique_id(ike_sa);
|
||||||
|
if (ike_id && ike_id != current)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ike && !streq(ike, ike_sa->get_name(ike_sa)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (address &&
|
||||||
|
!address->ip_equals(address, ike_sa->get_other_host(ike_sa)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (identity &&
|
||||||
|
!identity->equals(identity, ike_sa->get_other_eap_id(ike_sa)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lib->processor->queue_job(lib->processor,
|
||||||
|
(job_t*)redirect_job_create(ike_sa->get_id(ike_sa), gateway));
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
sas->destroy(sas);
|
||||||
|
|
||||||
|
builder = vici_builder_create();
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
errmsg = "no matching SAs to redirect found";
|
||||||
|
}
|
||||||
|
builder->add_kv(builder, "success", errmsg ? "no" : "yes");
|
||||||
|
if (errmsg)
|
||||||
|
{
|
||||||
|
builder->add_kv(builder, "errmsg", "%s", errmsg);
|
||||||
|
}
|
||||||
|
gateway->destroy(gateway);
|
||||||
|
DESTROY_IF(identity);
|
||||||
|
DESTROY_IF(address);
|
||||||
|
return builder->finalize(builder);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find reqid of an existing CHILD_SA
|
* Find reqid of an existing CHILD_SA
|
||||||
*/
|
*/
|
||||||
|
@ -498,6 +614,7 @@ static void manage_commands(private_vici_control_t *this, bool reg)
|
||||||
{
|
{
|
||||||
manage_command(this, "initiate", initiate, reg);
|
manage_command(this, "initiate", initiate, reg);
|
||||||
manage_command(this, "terminate", terminate, reg);
|
manage_command(this, "terminate", terminate, reg);
|
||||||
|
manage_command(this, "redirect", redirect, reg);
|
||||||
manage_command(this, "install", install, reg);
|
manage_command(this, "install", install, reg);
|
||||||
manage_command(this, "uninstall", uninstall, reg);
|
manage_command(this, "uninstall", uninstall, reg);
|
||||||
manage_command(this, "reload-settings", reload_settings, reg);
|
manage_command(this, "reload-settings", reload_settings, reg);
|
||||||
|
|
Loading…
Reference in New Issue