vici: Add a control backend, currently to initiate connections by name
This commit is contained in:
parent
ecc4b51048
commit
5f95657c65
|
@ -19,6 +19,7 @@ libstrongswan_vici_la_SOURCES = \
|
|||
vici_builder.h vici_builder.c \
|
||||
vici_dispatcher.h vici_dispatcher.c \
|
||||
vici_query.h vici_query.c \
|
||||
vici_control.h vici_control.c \
|
||||
vici_plugin.h vici_plugin.c
|
||||
|
||||
libstrongswan_vici_la_LDFLAGS = -module -avoid-version
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Martin Willi
|
||||
* Copyright (C) 2014 revosec AG
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "vici_control.h"
|
||||
#include "vici_builder.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <daemon.h>
|
||||
|
||||
typedef struct private_vici_control_t private_vici_control_t;
|
||||
|
||||
/**
|
||||
* Private data of an vici_control_t object.
|
||||
*/
|
||||
struct private_vici_control_t {
|
||||
|
||||
/**
|
||||
* Public vici_control_t interface.
|
||||
*/
|
||||
vici_control_t public;
|
||||
|
||||
/**
|
||||
* Dispatcher
|
||||
*/
|
||||
vici_dispatcher_t *dispatcher;
|
||||
};
|
||||
|
||||
/**
|
||||
* Log callback helper data
|
||||
*/
|
||||
typedef struct {
|
||||
/** dispatcher to send log messages over */
|
||||
vici_dispatcher_t *dispatcher;
|
||||
/** connection ID to send messages to */
|
||||
u_int id;
|
||||
/** loglevel */
|
||||
level_t level;
|
||||
} log_info_t;
|
||||
|
||||
/**
|
||||
* Log using vici event messages
|
||||
*/
|
||||
static bool log_vici(log_info_t *info, debug_t group, level_t level,
|
||||
ike_sa_t *ike_sa, char *text)
|
||||
{
|
||||
if (level <= info->level)
|
||||
{
|
||||
vici_message_t *message;
|
||||
vici_builder_t *builder;
|
||||
|
||||
builder = vici_builder_create();
|
||||
builder->add_kv(builder, "group", "%N", debug_names, group);
|
||||
builder->add_kv(builder, "level", "%d", level);
|
||||
if (ike_sa)
|
||||
{
|
||||
builder->add_kv(builder, "ikesa-name", "%s",
|
||||
ike_sa->get_name(ike_sa));
|
||||
builder->add_kv(builder, "ikesa-uniqueid", "%u",
|
||||
ike_sa->get_unique_id(ike_sa));
|
||||
}
|
||||
builder->add_kv(builder, "msg", "%s", text);
|
||||
|
||||
message = builder->finalize(builder);
|
||||
if (message)
|
||||
{
|
||||
info->dispatcher->raise_event(info->dispatcher, "control-log",
|
||||
info->id, message);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a (error) reply message
|
||||
*/
|
||||
static vici_message_t* send_reply(private_vici_control_t *this, char *fmt, ...)
|
||||
{
|
||||
vici_builder_t *builder;
|
||||
va_list args;
|
||||
|
||||
builder = vici_builder_create();
|
||||
builder->add_kv(builder, "success", fmt ? "no" : "yes");
|
||||
if (fmt)
|
||||
{
|
||||
va_start(args, fmt);
|
||||
builder->vadd_kv(builder, "errmsg", fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
return builder->finalize(builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the child_cfg having name from peer_cfg
|
||||
*/
|
||||
static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
|
||||
{
|
||||
child_cfg_t *current, *found = NULL;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
|
||||
while (enumerator->enumerate(enumerator, ¤t))
|
||||
{
|
||||
if (streq(current->get_name(current), name))
|
||||
{
|
||||
found = current;
|
||||
found->get_ref(found);
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return found;
|
||||
}
|
||||
|
||||
CALLBACK(initiate, vici_message_t*,
|
||||
private_vici_control_t *this, char *name, u_int id, vici_message_t *request)
|
||||
{
|
||||
child_cfg_t *child_cfg = NULL;
|
||||
peer_cfg_t *peer_cfg;
|
||||
enumerator_t *enumerator;
|
||||
char *child;
|
||||
u_int timeout;
|
||||
log_info_t log = {
|
||||
.dispatcher = this->dispatcher,
|
||||
.id = id,
|
||||
};
|
||||
|
||||
child = request->get_str(request, NULL, "child");
|
||||
timeout = request->get_int(request, 0, "timeout");
|
||||
log.level = request->get_int(request, 1, "loglevel");
|
||||
|
||||
if (!child)
|
||||
{
|
||||
return send_reply(this, "missing configuration name");
|
||||
}
|
||||
enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
|
||||
NULL, NULL, NULL, NULL, IKE_ANY);
|
||||
while (enumerator->enumerate(enumerator, &peer_cfg))
|
||||
{
|
||||
child_cfg = get_child_from_peer(peer_cfg, child);
|
||||
if (child_cfg)
|
||||
{
|
||||
peer_cfg->get_ref(peer_cfg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (!child_cfg)
|
||||
{
|
||||
return send_reply(this, "CHILD_SA config '%s' not found", child);
|
||||
}
|
||||
switch (charon->controller->initiate(charon->controller,
|
||||
peer_cfg, child_cfg, (controller_cb_t)log_vici, &log, timeout))
|
||||
{
|
||||
case SUCCESS:
|
||||
return send_reply(this, NULL);
|
||||
case OUT_OF_RES:
|
||||
return send_reply(this, "CHILD_SA '%s' not established after %dms",
|
||||
child, timeout);
|
||||
case FAILED:
|
||||
default:
|
||||
return send_reply(this, "establishing CHILD_SA '%s' failed", child);
|
||||
}
|
||||
}
|
||||
|
||||
static void manage_command(private_vici_control_t *this,
|
||||
char *name, vici_command_cb_t cb, bool reg)
|
||||
{
|
||||
this->dispatcher->manage_command(this->dispatcher, name,
|
||||
reg ? cb : NULL, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Un-)register dispatcher functions
|
||||
*/
|
||||
static void manage_commands(private_vici_control_t *this, bool reg)
|
||||
{
|
||||
manage_command(this, "initiate", initiate, reg);
|
||||
this->dispatcher->manage_event(this->dispatcher, "control-log", reg);
|
||||
}
|
||||
|
||||
METHOD(vici_control_t, destroy, void,
|
||||
private_vici_control_t *this)
|
||||
{
|
||||
manage_commands(this, FALSE);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
vici_control_t *vici_control_create(vici_dispatcher_t *dispatcher)
|
||||
{
|
||||
private_vici_control_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.dispatcher = dispatcher,
|
||||
);
|
||||
|
||||
manage_commands(this, TRUE);
|
||||
|
||||
return &this->public;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Martin Willi
|
||||
* Copyright (C) 2014 revosec AG
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup vici_control vici_control
|
||||
* @{ @ingroup vici
|
||||
*/
|
||||
|
||||
#include "vici_dispatcher.h"
|
||||
|
||||
#ifndef VICI_CONTROL_H_
|
||||
#define VICI_CONTROL_H_
|
||||
|
||||
typedef struct vici_control_t vici_control_t;
|
||||
|
||||
/**
|
||||
* Control helper, provides initiate/terminate and other commands.
|
||||
*/
|
||||
struct vici_control_t {
|
||||
|
||||
/**
|
||||
* Destroy a vici_control_t.
|
||||
*/
|
||||
void (*destroy)(vici_control_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a vici_control instance.
|
||||
*
|
||||
* @param dispatcher dispatcher to receive requests from
|
||||
* @return query handler
|
||||
*/
|
||||
vici_control_t *vici_control_create(vici_dispatcher_t *dispatcher);
|
||||
|
||||
#endif /** VICI_CONTROL_H_ @}*/
|
|
@ -16,6 +16,7 @@
|
|||
#include "vici_plugin.h"
|
||||
#include "vici_dispatcher.h"
|
||||
#include "vici_query.h"
|
||||
#include "vici_control.h"
|
||||
|
||||
#include <library.h>
|
||||
#include <daemon.h>
|
||||
|
@ -41,6 +42,11 @@ struct private_vici_plugin_t {
|
|||
* Query commands
|
||||
*/
|
||||
vici_query_t *query;
|
||||
|
||||
/**
|
||||
* Control commands
|
||||
*/
|
||||
vici_control_t *control;
|
||||
};
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
|
@ -65,12 +71,14 @@ static bool register_vici(private_vici_plugin_t *this,
|
|||
if (this->dispatcher)
|
||||
{
|
||||
this->query = vici_query_create(this->dispatcher);
|
||||
this->control = vici_control_create(this->dispatcher);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->control->destroy(this->control);
|
||||
this->query->destroy(this->query);
|
||||
this->dispatcher->destroy(this->dispatcher);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue