moved updown script invocation to an optional plugin
This commit is contained in:
parent
e17353fc31
commit
ad3af574a4
|
@ -569,7 +569,7 @@ AC_ARG_ENABLE(
|
|||
|
||||
AC_ARG_ENABLE(
|
||||
[updown],
|
||||
AS_HELP_STRING([--disable-updown],[disable installation of firewall scripts. (default is NO).]),
|
||||
AS_HELP_STRING([--disable-updown],[disable updown firewall script plugin. (default is NO).]),
|
||||
[if test x$enableval = xyes; then
|
||||
updown=true
|
||||
else
|
||||
|
@ -874,6 +874,7 @@ AM_CONDITIONAL(USE_NM, test x$nm = xtrue)
|
|||
AM_CONDITIONAL(USE_UCI, test x$uci = xtrue)
|
||||
AM_CONDITIONAL(USE_SMP, test x$smp = xtrue)
|
||||
AM_CONDITIONAL(USE_SQL, test x$sql = xtrue)
|
||||
AM_CONDITIONAL(USE_UPDOWN, test x$updown = xtrue)
|
||||
AM_CONDITIONAL(USE_UNIT_TESTS, test x$unittest = xtrue)
|
||||
AM_CONDITIONAL(USE_EAP_SIM, test x$eap_sim = xtrue)
|
||||
AM_CONDITIONAL(USE_EAP_SIM_FILE, test x$eap_sim_file = xtrue)
|
||||
|
@ -902,7 +903,6 @@ AM_CONDITIONAL(USE_CAPABILITIES, test x$capabilities = xlibcap)
|
|||
AM_CONDITIONAL(USE_PLUTO, test x$pluto = xtrue)
|
||||
AM_CONDITIONAL(USE_CHARON, test x$charon = xtrue)
|
||||
AM_CONDITIONAL(USE_TOOLS, test x$tools = xtrue)
|
||||
AM_CONDITIONAL(USE_UPDOWN, test x$updown = xtrue)
|
||||
AM_CONDITIONAL(USE_LIBSTRONGSWAN, test x$charon = xtrue -o x$tools = xtrue)
|
||||
AM_CONDITIONAL(USE_FILE_CONFIG, test x$pluto = xtrue -o x$stroke = xtrue)
|
||||
|
||||
|
@ -966,6 +966,7 @@ AC_OUTPUT(
|
|||
src/charon/plugins/nm/Makefile
|
||||
src/charon/plugins/uci/Makefile
|
||||
src/charon/plugins/stroke/Makefile
|
||||
src/charon/plugins/updown/Makefile
|
||||
src/charon/plugins/unit_tester/Makefile
|
||||
src/stroke/Makefile
|
||||
src/ipsec/Makefile
|
||||
|
|
|
@ -169,6 +169,11 @@ if USE_SQL
|
|||
PLUGINS += sql
|
||||
endif
|
||||
|
||||
if USE_UPDOWN
|
||||
SUBDIRS += plugins/updown
|
||||
PLUGINS += updown
|
||||
endif
|
||||
|
||||
if USE_EAP_IDENTITY
|
||||
SUBDIRS += plugins/eap_identity
|
||||
PLUGINS += eapidentity
|
||||
|
|
|
@ -321,6 +321,9 @@ static void log_(private_bus_t *this, debug_t group, level_t level,
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* unregister a listener
|
||||
*/
|
||||
static void unregister_listener(private_bus_t *this, entry_t *entry,
|
||||
enumerator_t *enumerator)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
|
||||
|
||||
AM_CFLAGS = -rdynamic
|
||||
|
||||
plugin_LTLIBRARIES = libstrongswan-updown.la
|
||||
libstrongswan_updown_la_SOURCES = updown_plugin.h updown_plugin.c
|
||||
libstrongswan_updown_la_LDFLAGS = -module
|
||||
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "updown_plugin.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <config/child_cfg.h>
|
||||
|
||||
typedef struct private_updown_plugin_t private_updown_plugin_t;
|
||||
|
||||
/**
|
||||
* private data of updown plugin
|
||||
*/
|
||||
struct private_updown_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
updown_plugin_t public;
|
||||
|
||||
/**
|
||||
* Listener interface, listens to CHILD_SA state changes
|
||||
*/
|
||||
listener_t listener;
|
||||
};
|
||||
|
||||
/**
|
||||
* Run the up/down script
|
||||
*/
|
||||
static void updown(ike_sa_t *ike_sa, child_sa_t *child_sa, bool up)
|
||||
{
|
||||
traffic_selector_t *my_ts, *other_ts;
|
||||
enumerator_t *enumerator;
|
||||
child_cfg_t *config;
|
||||
host_t *vip, *me, *other;
|
||||
char *script;
|
||||
|
||||
config = child_sa->get_config(child_sa);
|
||||
vip = ike_sa->get_virtual_ip(ike_sa, TRUE);
|
||||
script = config->get_updown(config);
|
||||
me = ike_sa->get_my_host(ike_sa);
|
||||
other = ike_sa->get_other_host(ike_sa);
|
||||
|
||||
if (script == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
enumerator = child_sa->create_policy_enumerator(child_sa);
|
||||
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
|
||||
{
|
||||
char command[1024];
|
||||
char *my_client, *other_client, *my_client_mask, *other_client_mask;
|
||||
char *pos, *virtual_ip, *iface;
|
||||
FILE *shell;
|
||||
|
||||
/* get subnet/bits from string */
|
||||
asprintf(&my_client, "%R", my_ts);
|
||||
pos = strchr(my_client, '/');
|
||||
*pos = '\0';
|
||||
my_client_mask = pos + 1;
|
||||
pos = strchr(my_client_mask, '[');
|
||||
if (pos)
|
||||
{
|
||||
*pos = '\0';
|
||||
}
|
||||
asprintf(&other_client, "%R", other_ts);
|
||||
pos = strchr(other_client, '/');
|
||||
*pos = '\0';
|
||||
other_client_mask = pos + 1;
|
||||
pos = strchr(other_client_mask, '[');
|
||||
if (pos)
|
||||
{
|
||||
*pos = '\0';
|
||||
}
|
||||
|
||||
if (vip)
|
||||
{
|
||||
asprintf(&virtual_ip, "PLUTO_MY_SOURCEIP='%H' ", vip);
|
||||
}
|
||||
else
|
||||
{
|
||||
asprintf(&virtual_ip, "");
|
||||
}
|
||||
|
||||
iface = charon->kernel_interface->get_interface(
|
||||
charon->kernel_interface, me);
|
||||
|
||||
/* build the command with all env variables.
|
||||
* TODO: PLUTO_PEER_CA and PLUTO_NEXT_HOP are currently missing
|
||||
*/
|
||||
snprintf(command, sizeof(command),
|
||||
"2>&1 "
|
||||
"PLUTO_VERSION='1.1' "
|
||||
"PLUTO_VERB='%s%s%s' "
|
||||
"PLUTO_CONNECTION='%s' "
|
||||
"PLUTO_INTERFACE='%s' "
|
||||
"PLUTO_REQID='%u' "
|
||||
"PLUTO_ME='%H' "
|
||||
"PLUTO_MY_ID='%D' "
|
||||
"PLUTO_MY_CLIENT='%s/%s' "
|
||||
"PLUTO_MY_CLIENT_NET='%s' "
|
||||
"PLUTO_MY_CLIENT_MASK='%s' "
|
||||
"PLUTO_MY_PORT='%u' "
|
||||
"PLUTO_MY_PROTOCOL='%u' "
|
||||
"PLUTO_PEER='%H' "
|
||||
"PLUTO_PEER_ID='%D' "
|
||||
"PLUTO_PEER_CLIENT='%s/%s' "
|
||||
"PLUTO_PEER_CLIENT_NET='%s' "
|
||||
"PLUTO_PEER_CLIENT_MASK='%s' "
|
||||
"PLUTO_PEER_PORT='%u' "
|
||||
"PLUTO_PEER_PROTOCOL='%u' "
|
||||
"%s"
|
||||
"%s"
|
||||
"%s",
|
||||
up ? "up" : "down",
|
||||
my_ts->is_host(my_ts, me) ? "-host" : "-client",
|
||||
me->get_family(me) == AF_INET ? "" : "-v6",
|
||||
config->get_name(config),
|
||||
iface ? iface : "unknown",
|
||||
child_sa->get_reqid(child_sa),
|
||||
me, ike_sa->get_my_id(ike_sa),
|
||||
my_client, my_client_mask,
|
||||
my_client, my_client_mask,
|
||||
my_ts->get_from_port(my_ts),
|
||||
my_ts->get_protocol(my_ts),
|
||||
other, ike_sa->get_other_id(ike_sa),
|
||||
other_client, other_client_mask,
|
||||
other_client, other_client_mask,
|
||||
other_ts->get_from_port(other_ts),
|
||||
other_ts->get_protocol(other_ts),
|
||||
virtual_ip,
|
||||
config->get_hostaccess(config) ? "PLUTO_HOST_ACCESS='1' " : "",
|
||||
script);
|
||||
free(my_client);
|
||||
free(other_client);
|
||||
free(virtual_ip);
|
||||
free(iface);
|
||||
|
||||
DBG3(DBG_CHD, "running updown script: %s", command);
|
||||
shell = popen(command, "r");
|
||||
|
||||
if (shell == NULL)
|
||||
{
|
||||
DBG1(DBG_CHD, "could not execute updown script '%s'", script);
|
||||
return;
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
char resp[128];
|
||||
|
||||
if (fgets(resp, sizeof(resp), shell) == NULL)
|
||||
{
|
||||
if (ferror(shell))
|
||||
{
|
||||
DBG1(DBG_CHD, "error reading output from updown script");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *e = resp + strlen(resp);
|
||||
if (e > resp && e[-1] == '\n')
|
||||
{ /* trim trailing '\n' */
|
||||
e[-1] = '\0';
|
||||
}
|
||||
DBG1(DBG_CHD, "updown: %s", resp);
|
||||
}
|
||||
}
|
||||
pclose(shell);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener implementation
|
||||
*/
|
||||
static bool child_state_change(listener_t *this, ike_sa_t *ike_sa,
|
||||
child_sa_t *child_sa, child_sa_state_t state)
|
||||
{
|
||||
child_sa_state_t old;
|
||||
|
||||
old = child_sa->get_state(child_sa);
|
||||
|
||||
if ((old == CHILD_INSTALLED && state != CHILD_REKEYING ) ||
|
||||
(old == CHILD_DELETING && state == CHILD_DESTROYING))
|
||||
{
|
||||
updown(ike_sa, child_sa, FALSE);
|
||||
}
|
||||
else if (state == CHILD_INSTALLED)
|
||||
{
|
||||
updown(ike_sa, child_sa, TRUE);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of plugin_t.destroy
|
||||
*/
|
||||
static void destroy(private_updown_plugin_t *this)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *plugin_create()
|
||||
{
|
||||
private_updown_plugin_t *this = malloc_thing(private_updown_plugin_t);
|
||||
|
||||
this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
|
||||
|
||||
memset(&this->listener, 0, sizeof(listener_t));
|
||||
this->listener.child_state_change = child_state_change;
|
||||
|
||||
charon->bus->add_listener(charon->bus, &this->listener);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup updown updown
|
||||
* @ingroup cplugins
|
||||
*
|
||||
* @defgroup updown_plugin updown_plugin
|
||||
* @{ @ingroup updown
|
||||
*/
|
||||
|
||||
#ifndef UPDOWN_PLUGIN_H_
|
||||
#define UPDOWN_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct updown_plugin_t updown_plugin_t;
|
||||
|
||||
/**
|
||||
* Updown firewall script invocation plugin, compatible to pluto ones.
|
||||
*/
|
||||
struct updown_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a updown_plugin instance.
|
||||
*/
|
||||
plugin_t *plugin_create();
|
||||
|
||||
#endif /* UPDOWN_PLUGIN_H_ @}*/
|
|
@ -30,6 +30,7 @@ ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
|
|||
"CREATED",
|
||||
"ROUTED",
|
||||
"INSTALLED",
|
||||
"UPDATING",
|
||||
"REKEYING",
|
||||
"DELETING",
|
||||
"DESTROYING",
|
||||
|
@ -49,8 +50,6 @@ struct private_child_sa_t {
|
|||
struct {
|
||||
/** address of peer */
|
||||
host_t *addr;
|
||||
/** id of peer */
|
||||
identification_t *id;
|
||||
/** actual used SPI, 0 if unused */
|
||||
u_int32_t spi;
|
||||
/** Compression Parameter Index (CPI) used, 0 if unused */
|
||||
|
@ -142,20 +141,10 @@ struct private_child_sa_t {
|
|||
*/
|
||||
ipsec_mode_t mode;
|
||||
|
||||
/**
|
||||
* virtual IP assigned to local host
|
||||
*/
|
||||
host_t *virtual_ip;
|
||||
|
||||
/**
|
||||
* config used to create this child
|
||||
*/
|
||||
child_cfg_t *config;
|
||||
|
||||
/**
|
||||
* cached interface name for iptables
|
||||
*/
|
||||
char *iface;
|
||||
};
|
||||
|
||||
typedef struct keylen_entry_t keylen_entry_t;
|
||||
|
@ -403,171 +392,11 @@ static void get_stats(private_child_sa_t *this, ipsec_mode_t *mode,
|
|||
SET_PTR_IF(use_fwd, fwd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the up/down script
|
||||
*/
|
||||
static void updown(private_child_sa_t *this, bool up)
|
||||
{
|
||||
traffic_selector_t *my_ts, *other_ts;
|
||||
enumerator_t *enumerator;
|
||||
char *script;
|
||||
|
||||
script = this->config->get_updown(this->config);
|
||||
|
||||
if (script == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
enumerator = create_policy_enumerator(this);
|
||||
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
|
||||
{
|
||||
char command[1024];
|
||||
char *my_client, *other_client, *my_client_mask, *other_client_mask;
|
||||
char *pos, *virtual_ip;
|
||||
FILE *shell;
|
||||
|
||||
/* get subnet/bits from string */
|
||||
asprintf(&my_client, "%R", my_ts);
|
||||
pos = strchr(my_client, '/');
|
||||
*pos = '\0';
|
||||
my_client_mask = pos + 1;
|
||||
pos = strchr(my_client_mask, '[');
|
||||
if (pos)
|
||||
{
|
||||
*pos = '\0';
|
||||
}
|
||||
asprintf(&other_client, "%R", other_ts);
|
||||
pos = strchr(other_client, '/');
|
||||
*pos = '\0';
|
||||
other_client_mask = pos + 1;
|
||||
pos = strchr(other_client_mask, '[');
|
||||
if (pos)
|
||||
{
|
||||
*pos = '\0';
|
||||
}
|
||||
|
||||
if (this->virtual_ip)
|
||||
{
|
||||
asprintf(&virtual_ip, "PLUTO_MY_SOURCEIP='%H' ",
|
||||
this->virtual_ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
asprintf(&virtual_ip, "");
|
||||
}
|
||||
|
||||
/* we cache the iface name, as it may not be available when
|
||||
* the SA gets deleted */
|
||||
if (up)
|
||||
{
|
||||
free(this->iface);
|
||||
this->iface = charon->kernel_interface->get_interface(
|
||||
charon->kernel_interface, this->me.addr);
|
||||
}
|
||||
|
||||
/* build the command with all env variables.
|
||||
* TODO: PLUTO_PEER_CA and PLUTO_NEXT_HOP are currently missing
|
||||
*/
|
||||
snprintf(command, sizeof(command),
|
||||
"2>&1 "
|
||||
"PLUTO_VERSION='1.1' "
|
||||
"PLUTO_VERB='%s%s%s' "
|
||||
"PLUTO_CONNECTION='%s' "
|
||||
"PLUTO_INTERFACE='%s' "
|
||||
"PLUTO_REQID='%u' "
|
||||
"PLUTO_ME='%H' "
|
||||
"PLUTO_MY_ID='%D' "
|
||||
"PLUTO_MY_CLIENT='%s/%s' "
|
||||
"PLUTO_MY_CLIENT_NET='%s' "
|
||||
"PLUTO_MY_CLIENT_MASK='%s' "
|
||||
"PLUTO_MY_PORT='%u' "
|
||||
"PLUTO_MY_PROTOCOL='%u' "
|
||||
"PLUTO_PEER='%H' "
|
||||
"PLUTO_PEER_ID='%D' "
|
||||
"PLUTO_PEER_CLIENT='%s/%s' "
|
||||
"PLUTO_PEER_CLIENT_NET='%s' "
|
||||
"PLUTO_PEER_CLIENT_MASK='%s' "
|
||||
"PLUTO_PEER_PORT='%u' "
|
||||
"PLUTO_PEER_PROTOCOL='%u' "
|
||||
"%s"
|
||||
"%s"
|
||||
"%s",
|
||||
up ? "up" : "down",
|
||||
my_ts->is_host(my_ts, this->me.addr) ? "-host" : "-client",
|
||||
this->me.addr->get_family(this->me.addr) == AF_INET ? "" : "-v6",
|
||||
this->config->get_name(this->config),
|
||||
this->iface ? this->iface : "unknown",
|
||||
this->reqid,
|
||||
this->me.addr,
|
||||
this->me.id,
|
||||
my_client, my_client_mask,
|
||||
my_client, my_client_mask,
|
||||
my_ts->get_from_port(my_ts),
|
||||
my_ts->get_protocol(my_ts),
|
||||
this->other.addr,
|
||||
this->other.id,
|
||||
other_client, other_client_mask,
|
||||
other_client, other_client_mask,
|
||||
other_ts->get_from_port(other_ts),
|
||||
other_ts->get_protocol(other_ts),
|
||||
virtual_ip,
|
||||
this->config->get_hostaccess(this->config) ?
|
||||
"PLUTO_HOST_ACCESS='1' " : "",
|
||||
script);
|
||||
free(my_client);
|
||||
free(other_client);
|
||||
free(virtual_ip);
|
||||
|
||||
DBG3(DBG_CHD, "running updown script: %s", command);
|
||||
shell = popen(command, "r");
|
||||
|
||||
if (shell == NULL)
|
||||
{
|
||||
DBG1(DBG_CHD, "could not execute updown script '%s'", script);
|
||||
return;
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
char resp[128];
|
||||
|
||||
if (fgets(resp, sizeof(resp), shell) == NULL)
|
||||
{
|
||||
if (ferror(shell))
|
||||
{
|
||||
DBG1(DBG_CHD, "error reading output from updown script");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *e = resp + strlen(resp);
|
||||
if (e > resp && e[-1] == '\n')
|
||||
{ /* trim trailing '\n' */
|
||||
e[-1] = '\0';
|
||||
}
|
||||
DBG1(DBG_CHD, "updown: %s", resp);
|
||||
}
|
||||
}
|
||||
pclose(shell);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements child_sa_t.set_state
|
||||
*/
|
||||
static void set_state(private_child_sa_t *this, child_sa_state_t state)
|
||||
{
|
||||
if (state == CHILD_INSTALLED)
|
||||
{
|
||||
updown(this, TRUE);
|
||||
}
|
||||
charon->bus->child_state_change(charon->bus, &this->public, state);
|
||||
this->state = state;
|
||||
}
|
||||
|
@ -955,27 +784,32 @@ static status_t get_use_time(private_child_sa_t *this,
|
|||
* Implementation of child_sa_t.update_hosts.
|
||||
*/
|
||||
static status_t update_hosts(private_child_sa_t *this,
|
||||
host_t *me, host_t *other, bool encap)
|
||||
host_t *me, host_t *other, host_t *vip, bool encap)
|
||||
{
|
||||
child_sa_state_t old;
|
||||
|
||||
/* anything changed at all? */
|
||||
if (me->equals(me, this->me.addr) &&
|
||||
other->equals(other, this->other.addr) && this->encap == encap)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* run updown script to remove iptables rules */
|
||||
updown(this, FALSE);
|
||||
|
||||
old = this->state;
|
||||
set_state(this, CHILD_UPDATING);
|
||||
|
||||
this->encap = encap;
|
||||
|
||||
if (this->ipcomp != IPCOMP_NONE)
|
||||
{
|
||||
/* update our (initator) IPComp SA */
|
||||
charon->kernel_interface->update_sa(charon->kernel_interface, htonl(ntohs(this->me.cpi)),
|
||||
IPPROTO_COMP, this->other.addr, this->me.addr, other, me, FALSE);
|
||||
charon->kernel_interface->update_sa(charon->kernel_interface,
|
||||
htonl(ntohs(this->me.cpi)), IPPROTO_COMP,
|
||||
this->other.addr, this->me.addr, other, me, FALSE);
|
||||
/* update his (responder) IPComp SA */
|
||||
charon->kernel_interface->update_sa(charon->kernel_interface, htonl(ntohs(this->other.cpi)),
|
||||
IPPROTO_COMP, this->me.addr, this->other.addr, me, other, FALSE);
|
||||
charon->kernel_interface->update_sa(charon->kernel_interface,
|
||||
htonl(ntohs(this->other.cpi)), IPPROTO_COMP,
|
||||
this->me.addr, this->other.addr, me, other, FALSE);
|
||||
}
|
||||
|
||||
/* update our (initator) SA */
|
||||
|
@ -1018,12 +852,10 @@ static status_t update_hosts(private_child_sa_t *this,
|
|||
|
||||
/* we reinstall the virtual IP to handle interface roaming
|
||||
* correctly */
|
||||
if (this->virtual_ip)
|
||||
if (vip)
|
||||
{
|
||||
charon->kernel_interface->del_ip(charon->kernel_interface,
|
||||
this->virtual_ip);
|
||||
charon->kernel_interface->add_ip(charon->kernel_interface,
|
||||
this->virtual_ip, me);
|
||||
charon->kernel_interface->del_ip(charon->kernel_interface, vip);
|
||||
charon->kernel_interface->add_ip(charon->kernel_interface, vip, me);
|
||||
}
|
||||
|
||||
/* reinstall updated policies */
|
||||
|
@ -1052,20 +884,11 @@ static status_t update_hosts(private_child_sa_t *this,
|
|||
this->other.addr = other->clone(other);
|
||||
}
|
||||
|
||||
/* install new iptables rules */
|
||||
updown(this, TRUE);
|
||||
set_state(this, old);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.set_virtual_ip.
|
||||
*/
|
||||
static void set_virtual_ip(private_child_sa_t *this, host_t *ip)
|
||||
{
|
||||
this->virtual_ip = ip->clone(ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.activate_ipcomp.
|
||||
*/
|
||||
|
@ -1098,11 +921,6 @@ static void destroy(private_child_sa_t *this)
|
|||
enumerator_t *enumerator;
|
||||
traffic_selector_t *my_ts, *other_ts;
|
||||
|
||||
if (this->state == CHILD_DELETING || this->state == CHILD_INSTALLED)
|
||||
{
|
||||
updown(this, FALSE);
|
||||
}
|
||||
|
||||
set_state(this, CHILD_DESTROYING);
|
||||
|
||||
/* delete SAs in the kernel, if they are set up */
|
||||
|
@ -1158,11 +976,7 @@ static void destroy(private_child_sa_t *this)
|
|||
this->other_ts->destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy));
|
||||
this->me.addr->destroy(this->me.addr);
|
||||
this->other.addr->destroy(this->other.addr);
|
||||
this->me.id->destroy(this->me.id);
|
||||
this->other.id->destroy(this->other.id);
|
||||
this->config->destroy(this->config);
|
||||
free(this->iface);
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
free(this);
|
||||
}
|
||||
|
||||
|
@ -1170,7 +984,6 @@ static void destroy(private_child_sa_t *this)
|
|||
* Described in header.
|
||||
*/
|
||||
child_sa_t * child_sa_create(host_t *me, host_t* other,
|
||||
identification_t *my_id, identification_t *other_id,
|
||||
child_cfg_t *config, u_int32_t rekey, bool encap)
|
||||
{
|
||||
static u_int32_t reqid = 0;
|
||||
|
@ -1186,7 +999,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
|||
this->public.alloc = (status_t(*)(child_sa_t*,linked_list_t*))alloc;
|
||||
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,ipsec_mode_t,prf_plus_t*))add;
|
||||
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,ipsec_mode_t,prf_plus_t*))update;
|
||||
this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,bool))update_hosts;
|
||||
this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,host_t*,bool))update_hosts;
|
||||
this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*,ipsec_mode_t,protocol_id_t))add_policies;
|
||||
this->public.get_traffic_selectors = (linked_list_t*(*)(child_sa_t*,bool))get_traffic_selectors;
|
||||
this->public.create_policy_enumerator = (enumerator_t*(*)(child_sa_t*))create_policy_enumerator;
|
||||
|
@ -1196,14 +1009,11 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
|||
this->public.get_config = (child_cfg_t*(*)(child_sa_t*))get_config;
|
||||
this->public.activate_ipcomp = (void(*)(child_sa_t*,ipcomp_transform_t,u_int16_t))activate_ipcomp;
|
||||
this->public.allocate_cpi = (u_int16_t(*)(child_sa_t*))allocate_cpi;
|
||||
this->public.set_virtual_ip = (void(*)(child_sa_t*,host_t*))set_virtual_ip;
|
||||
this->public.destroy = (void(*)(child_sa_t*))destroy;
|
||||
|
||||
/* private data */
|
||||
this->me.addr = me->clone(me);
|
||||
this->other.addr = other->clone(other);
|
||||
this->me.id = my_id->clone(my_id);
|
||||
this->other.id = other_id->clone(other_id);
|
||||
this->me.spi = 0;
|
||||
this->me.cpi = 0;
|
||||
this->other.spi = 0;
|
||||
|
@ -1224,10 +1034,9 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
|||
this->other_ts = linked_list_create();
|
||||
this->protocol = PROTO_NONE;
|
||||
this->mode = MODE_TUNNEL;
|
||||
this->virtual_ip = NULL;
|
||||
this->iface = NULL;
|
||||
this->config = config;
|
||||
config->get_ref(config);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,11 @@ enum child_sa_state_t {
|
|||
*/
|
||||
CHILD_INSTALLED,
|
||||
|
||||
/**
|
||||
* While updating hosts, in update_hosts()
|
||||
*/
|
||||
CHILD_UPDATING,
|
||||
|
||||
/**
|
||||
* CHILD_SA which is rekeying
|
||||
*/
|
||||
|
@ -207,11 +212,12 @@ struct child_sa_t {
|
|||
*
|
||||
* @param me the new local host
|
||||
* @param other the new remote host
|
||||
* @param vip virtual IP, if any
|
||||
* @param TRUE to use UDP encapsulation for NAT traversal
|
||||
* @return SUCCESS or FAILED
|
||||
*/
|
||||
status_t (*update_hosts)(child_sa_t *this, host_t *me, host_t *other,
|
||||
bool encap);
|
||||
host_t *vip, bool encap);
|
||||
|
||||
/**
|
||||
* Install the policies using some traffic selectors.
|
||||
|
@ -272,16 +278,6 @@ struct child_sa_t {
|
|||
*/
|
||||
child_cfg_t* (*get_config) (child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Set the virtual IP used received from IRAS.
|
||||
*
|
||||
* To allow proper setup of firewall rules, the virtual IP is required
|
||||
* for filtering.
|
||||
*
|
||||
* @param ip own virtual IP
|
||||
*/
|
||||
void (*set_virtual_ip) (child_sa_t *this, host_t *ip);
|
||||
|
||||
/**
|
||||
* Activate IPComp by setting the transform ID and CPI values.
|
||||
*
|
||||
|
@ -316,8 +312,7 @@ struct child_sa_t {
|
|||
* @param encap TRUE to enable UDP encapsulation (NAT traversal)
|
||||
* @return child_sa_t object
|
||||
*/
|
||||
child_sa_t * child_sa_create(host_t *me, host_t *other,
|
||||
identification_t *my_id, identification_t* other_id,
|
||||
child_cfg_t *config, u_int32_t reqid, bool encap);
|
||||
child_sa_t * child_sa_create(host_t *me, host_t *other, child_cfg_t *config,
|
||||
u_int32_t reqid, bool encap);
|
||||
|
||||
#endif /*CHILD_SA_H_ @} */
|
||||
|
|
|
@ -927,7 +927,7 @@ static void update_hosts(private_ike_sa_t *this, host_t *me, host_t *other)
|
|||
while (iterator->iterate(iterator, (void**)&child_sa))
|
||||
{
|
||||
child_sa->update_hosts(child_sa, this->my_host, this->other_host,
|
||||
has_condition(this, COND_NAT_ANY));
|
||||
this->my_virtual_ip, has_condition(this, COND_NAT_ANY));
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
|
@ -1285,8 +1285,8 @@ static status_t route(private_ike_sa_t *this, child_cfg_t *child_cfg)
|
|||
resolve_hosts(this);
|
||||
|
||||
/* install kernel policies */
|
||||
child_sa = child_sa_create(this->my_host, this->other_host, this->my_id,
|
||||
this->other_id, child_cfg, 0, FALSE);
|
||||
child_sa = child_sa_create(this->my_host, this->other_host,
|
||||
child_cfg, 0, FALSE);
|
||||
me = this->my_host;
|
||||
if (this->my_virtual_ip)
|
||||
{
|
||||
|
@ -2481,6 +2481,9 @@ static void destroy(private_ike_sa_t *this)
|
|||
|
||||
this->child_sas->destroy_offset(this->child_sas, offsetof(child_sa_t, destroy));
|
||||
|
||||
/* unset SA after here to avoid usage by the listeners */
|
||||
charon->bus->set_sa(charon->bus, NULL);
|
||||
|
||||
this->task_manager->destroy(this->task_manager);
|
||||
|
||||
DESTROY_IF(this->crypter_in);
|
||||
|
|
|
@ -880,7 +880,6 @@ static status_t checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ik
|
|||
|
||||
ike_sa_id = ike_sa->get_id(ike_sa);
|
||||
DBG2(DBG_MGR, "checkin and destroy IKE_SA");
|
||||
charon->bus->set_sa(charon->bus, NULL);
|
||||
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
|
||||
|
@ -899,6 +898,7 @@ static status_t checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ik
|
|||
DBG2(DBG_MGR, "tried to check-in and delete nonexisting IKE_SA");
|
||||
retval = NOT_FOUND;
|
||||
}
|
||||
charon->bus->set_sa(charon->bus, NULL);
|
||||
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
return retval;
|
||||
|
@ -981,6 +981,7 @@ static void flush(private_ike_sa_manager_t *this)
|
|||
enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
charon->bus->set_sa(charon->bus, entry->ike_sa);
|
||||
entry->ike_sa->delete(entry->ike_sa);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
@ -990,8 +991,10 @@ static void flush(private_ike_sa_manager_t *this)
|
|||
while (this->ike_sa_list->remove_last(this->ike_sa_list,
|
||||
(void**)&entry) == SUCCESS)
|
||||
{
|
||||
charon->bus->set_sa(charon->bus, entry->ike_sa);
|
||||
entry_destroy(entry);
|
||||
}
|
||||
charon->bus->set_sa(charon->bus, NULL);
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
}
|
||||
|
||||
|
|
|
@ -260,11 +260,6 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
|
|||
{
|
||||
my_vip = me;
|
||||
}
|
||||
else if (this->initiator)
|
||||
{
|
||||
/* to setup firewall rules correctly, CHILD_SA needs the virtual IP */
|
||||
this->child_sa->set_virtual_ip(this->child_sa, my_vip);
|
||||
}
|
||||
if (other_vip == NULL)
|
||||
{
|
||||
other_vip = other;
|
||||
|
@ -639,11 +634,8 @@ static status_t build_i(private_child_create_t *this, message_t *message)
|
|||
this->dh_group == MODP_NONE);
|
||||
this->mode = this->config->get_mode(this->config);
|
||||
|
||||
this->child_sa = child_sa_create(
|
||||
this->ike_sa->get_my_host(this->ike_sa),
|
||||
this->ike_sa->get_other_host(this->ike_sa),
|
||||
this->ike_sa->get_my_id(this->ike_sa),
|
||||
this->ike_sa->get_other_id(this->ike_sa), this->config, this->reqid,
|
||||
this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
|
||||
this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
|
||||
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
|
||||
|
||||
if (this->child_sa->alloc(this->child_sa, this->proposals) != SUCCESS)
|
||||
|
@ -822,11 +814,8 @@ static status_t build_r(private_child_create_t *this, message_t *message)
|
|||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
this->child_sa = child_sa_create(
|
||||
this->ike_sa->get_my_host(this->ike_sa),
|
||||
this->ike_sa->get_other_host(this->ike_sa),
|
||||
this->ike_sa->get_my_id(this->ike_sa),
|
||||
this->ike_sa->get_other_id(this->ike_sa), this->config, this->reqid,
|
||||
this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
|
||||
this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
|
||||
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
|
||||
|
||||
if (this->config->use_ipcomp(this->config) &&
|
||||
|
|
|
@ -254,6 +254,7 @@ static void update_children(private_ike_mobike_t *this)
|
|||
child_sa->update_hosts(child_sa,
|
||||
this->ike_sa->get_my_host(this->ike_sa),
|
||||
this->ike_sa->get_other_host(this->ike_sa),
|
||||
this->ike_sa->get_virtual_ip(this->ike_sa, TRUE),
|
||||
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
|
Loading…
Reference in New Issue