mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-05 00:00:45 -04:00
updown: Use process abstraction to invoke updown script
This commit is contained in:
parent
7dd06d274d
commit
6890bdc7a0
@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "updown_listener.h"
|
#include "updown_listener.h"
|
||||||
|
|
||||||
|
#include <utils/process.h>
|
||||||
#include <hydra.h>
|
#include <hydra.h>
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
#include <config/child_cfg.h>
|
#include <config/child_cfg.h>
|
||||||
@ -97,53 +99,84 @@ static char* uncache_iface(private_updown_listener_t *this, u_int32_t reqid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create variables for handled DNS attributes
|
* Allocate and push a format string to the environment
|
||||||
*/
|
*/
|
||||||
static char *make_dns_vars(private_updown_listener_t *this, ike_sa_t *ike_sa)
|
static bool push_env(char *envp[], u_int count, char *fmt, ...)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
int i = 0;
|
||||||
host_t *host;
|
char *str;
|
||||||
int v4 = 0, v6 = 0;
|
va_list args;
|
||||||
char total[512] = "", current[64];
|
|
||||||
|
|
||||||
if (!this->handler)
|
while (envp[i])
|
||||||
{
|
{
|
||||||
return strdup("");
|
if (++i + 1 >= count)
|
||||||
}
|
|
||||||
|
|
||||||
enumerator = this->handler->create_dns_enumerator(this->handler,
|
|
||||||
ike_sa->get_unique_id(ike_sa));
|
|
||||||
while (enumerator->enumerate(enumerator, &host))
|
|
||||||
{
|
|
||||||
switch (host->get_family(host))
|
|
||||||
{
|
{
|
||||||
case AF_INET:
|
return FALSE;
|
||||||
snprintf(current, sizeof(current),
|
|
||||||
"PLUTO_DNS4_%d='%H' ", ++v4, host);
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
snprintf(current, sizeof(current),
|
|
||||||
"PLUTO_DNS6_%d='%H' ", ++v6, host);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
strncat(total, current, sizeof(total) - strlen(total) - 1);
|
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
va_start(args, fmt);
|
||||||
|
if (vasprintf(&str, fmt, args) >= 0)
|
||||||
return strdup(total);
|
{
|
||||||
|
envp[i] = str;
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
return envp[i] != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create variables for local virtual IPs
|
* Free all allocated environment strings
|
||||||
*/
|
*/
|
||||||
static char *make_vip_vars(private_updown_listener_t *this, ike_sa_t *ike_sa)
|
static void free_env(char *envp[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; envp[i]; i++)
|
||||||
|
{
|
||||||
|
free(envp[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push variables for handled DNS attributes
|
||||||
|
*/
|
||||||
|
static void push_dns_env(private_updown_listener_t *this, ike_sa_t *ike_sa,
|
||||||
|
char *envp[], u_int count)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
host_t *host;
|
||||||
|
int v4 = 0, v6 = 0;
|
||||||
|
|
||||||
|
if (this->handler)
|
||||||
|
{
|
||||||
|
enumerator = this->handler->create_dns_enumerator(this->handler,
|
||||||
|
ike_sa->get_unique_id(ike_sa));
|
||||||
|
while (enumerator->enumerate(enumerator, &host))
|
||||||
|
{
|
||||||
|
switch (host->get_family(host))
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
push_env(envp, count, "PLUTO_DNS4_%d=%H", ++v4, host);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
push_env(envp, count, "PLUTO_DNS6_%d=%H", ++v6, host);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push variables for local virtual IPs
|
||||||
|
*/
|
||||||
|
static void push_vip_env(private_updown_listener_t *this, ike_sa_t *ike_sa,
|
||||||
|
char *envp[], u_int count)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
host_t *host;
|
host_t *host;
|
||||||
int v4 = 0, v6 = 0;
|
int v4 = 0, v6 = 0;
|
||||||
char total[512] = "", current[64];
|
|
||||||
bool first = TRUE;
|
bool first = TRUE;
|
||||||
|
|
||||||
enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
|
enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
|
||||||
@ -151,28 +184,22 @@ static char *make_vip_vars(private_updown_listener_t *this, ike_sa_t *ike_sa)
|
|||||||
{
|
{
|
||||||
if (first)
|
if (first)
|
||||||
{ /* legacy variable for first VIP */
|
{ /* legacy variable for first VIP */
|
||||||
snprintf(current, sizeof(current),
|
first = FALSE;
|
||||||
"PLUTO_MY_SOURCEIP='%H' ", host);
|
push_env(envp, count, "PLUTO_MY_SOURCEIP=%H", host);
|
||||||
strncat(total, current, sizeof(total) - strlen(total) - 1);
|
|
||||||
}
|
}
|
||||||
switch (host->get_family(host))
|
switch (host->get_family(host))
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
snprintf(current, sizeof(current),
|
push_env(envp, count, "PLUTO_MY_SOURCEIP4_%d=%H", ++v4, host);
|
||||||
"PLUTO_MY_SOURCEIP4_%d='%H' ", ++v4, host);
|
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
snprintf(current, sizeof(current),
|
push_env(envp, count, "PLUTO_MY_SOURCEIP6_%d=%H", ++v6, host);
|
||||||
"PLUTO_MY_SOURCEIP6_%d='%H' ", ++v6, host);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
strncat(total, current, sizeof(total) - strlen(total) - 1);
|
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
return strdup(total);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -196,6 +223,164 @@ static u_int16_t get_port(traffic_selector_t *me,
|
|||||||
return local ? me->get_from_port(me) : other->get_from_port(other);
|
return local ? me->get_from_port(me) : other->get_from_port(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoke the updown script once for given traffic selectors
|
||||||
|
*/
|
||||||
|
static void invoke_once(private_updown_listener_t *this, ike_sa_t *ike_sa,
|
||||||
|
child_sa_t *child_sa, child_cfg_t *config, bool up,
|
||||||
|
traffic_selector_t *my_ts, traffic_selector_t *other_ts)
|
||||||
|
{
|
||||||
|
host_t *me, *other, *host;
|
||||||
|
char *iface;
|
||||||
|
u_int8_t mask;
|
||||||
|
mark_t mark;
|
||||||
|
bool is_host, is_ipv6;
|
||||||
|
int out;
|
||||||
|
FILE *shell;
|
||||||
|
process_t *process;
|
||||||
|
char *envp[128] = {};
|
||||||
|
|
||||||
|
me = ike_sa->get_my_host(ike_sa);
|
||||||
|
other = ike_sa->get_other_host(ike_sa);
|
||||||
|
|
||||||
|
push_env(envp, countof(envp), "PLUTO_VERSION=1.1");
|
||||||
|
is_host = my_ts->is_host(my_ts, me);
|
||||||
|
if (is_host)
|
||||||
|
{
|
||||||
|
is_ipv6 = me->get_family(me) == AF_INET6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_ipv6 = my_ts->get_type(my_ts) == TS_IPV6_ADDR_RANGE;
|
||||||
|
}
|
||||||
|
push_env(envp, countof(envp), "PLUTO_VERB=%s%s%s",
|
||||||
|
up ? "up" : "down",
|
||||||
|
is_host ? "-host" : "-client",
|
||||||
|
is_ipv6 ? "-v6" : "");
|
||||||
|
push_env(envp, countof(envp), "PLUTO_CONNECTION=%s",
|
||||||
|
config->get_name(config));
|
||||||
|
if (up)
|
||||||
|
{
|
||||||
|
if (hydra->kernel_interface->get_interface(hydra->kernel_interface,
|
||||||
|
me, &iface))
|
||||||
|
{
|
||||||
|
cache_iface(this, child_sa->get_reqid(child_sa), iface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iface = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iface = uncache_iface(this, child_sa->get_reqid(child_sa));
|
||||||
|
}
|
||||||
|
push_env(envp, countof(envp), "PLUTO_INTERFACE=%s",
|
||||||
|
iface ? iface : "unknown");
|
||||||
|
push_env(envp, countof(envp), "PLUTO_REQID=%u",
|
||||||
|
child_sa->get_reqid(child_sa));
|
||||||
|
push_env(envp, countof(envp), "PLUTO_PROTO=%s",
|
||||||
|
child_sa->get_protocol(child_sa) == PROTO_ESP ? "esp" : "ah");
|
||||||
|
push_env(envp, countof(envp), "PLUTO_UNIQUEID=%u",
|
||||||
|
ike_sa->get_unique_id(ike_sa));
|
||||||
|
push_env(envp, countof(envp), "PLUTO_ME=%H", me);
|
||||||
|
push_env(envp, countof(envp), "PLUTO_MY_ID=%Y", ike_sa->get_my_id(ike_sa));
|
||||||
|
if (my_ts->to_subnet(my_ts, &host, &mask))
|
||||||
|
{
|
||||||
|
push_env(envp, countof(envp), "PLUTO_MY_CLIENT=%+H/%u", host, mask);
|
||||||
|
host->destroy(host);
|
||||||
|
}
|
||||||
|
push_env(envp, countof(envp), "PLUTO_MY_PORT=%u",
|
||||||
|
get_port(my_ts, other_ts, TRUE));
|
||||||
|
push_env(envp, countof(envp), "PLUTO_MY_PROTOCOL=%u",
|
||||||
|
my_ts->get_protocol(my_ts));
|
||||||
|
push_env(envp, countof(envp), "PLUTO_PEER=%H", other);
|
||||||
|
push_env(envp, countof(envp), "PLUTO_PEER_ID=%Y",
|
||||||
|
ike_sa->get_other_id(ike_sa));
|
||||||
|
if (other_ts->to_subnet(other_ts, &host, &mask))
|
||||||
|
{
|
||||||
|
push_env(envp, countof(envp), "PLUTO_PEER_CLIENT=%+H/%u", host, mask);
|
||||||
|
host->destroy(host);
|
||||||
|
}
|
||||||
|
push_env(envp, countof(envp), "PLUTO_PEER_PORT=%u",
|
||||||
|
get_port(my_ts, other_ts, FALSE));
|
||||||
|
push_env(envp, countof(envp), "PLUTO_PEER_PROTOCOL=%u",
|
||||||
|
other_ts->get_protocol(other_ts));
|
||||||
|
if (ike_sa->has_condition(ike_sa, COND_EAP_AUTHENTICATED) ||
|
||||||
|
ike_sa->has_condition(ike_sa, COND_XAUTH_AUTHENTICATED))
|
||||||
|
{
|
||||||
|
push_env(envp, countof(envp), "PLUTO_XAUTH_ID=%Y",
|
||||||
|
ike_sa->get_other_eap_id(ike_sa));
|
||||||
|
}
|
||||||
|
push_vip_env(this, ike_sa, envp, countof(envp));
|
||||||
|
mark = config->get_mark(config, TRUE);
|
||||||
|
if (mark.value)
|
||||||
|
{
|
||||||
|
push_env(envp, countof(envp), "PLUTO_MARK_IN=%u/0x%08x",
|
||||||
|
mark.value, mark.mask);
|
||||||
|
}
|
||||||
|
mark = config->get_mark(config, FALSE);
|
||||||
|
if (mark.value)
|
||||||
|
{
|
||||||
|
push_env(envp, countof(envp), "PLUTO_MARK_OUT=%u/0x%08x",
|
||||||
|
mark.value, mark.mask);
|
||||||
|
}
|
||||||
|
if (ike_sa->has_condition(ike_sa, COND_NAT_ANY))
|
||||||
|
{
|
||||||
|
push_env(envp, countof(envp), "PLUTO_UDP_ENC=%u",
|
||||||
|
other->get_port(other));
|
||||||
|
}
|
||||||
|
if (child_sa->get_ipcomp(child_sa) != IPCOMP_NONE)
|
||||||
|
{
|
||||||
|
push_env(envp, countof(envp), "PLUTO_IPCOMP=1");
|
||||||
|
}
|
||||||
|
push_dns_env(this, ike_sa, envp, countof(envp));
|
||||||
|
if (config->get_hostaccess(config))
|
||||||
|
{
|
||||||
|
push_env(envp, countof(envp), "PLUTO_HOST_ACCESS=1");
|
||||||
|
}
|
||||||
|
|
||||||
|
process = process_start_shell(envp, NULL, &out, NULL, "2>&1 %s",
|
||||||
|
config->get_updown(config));
|
||||||
|
if (process)
|
||||||
|
{
|
||||||
|
shell = fdopen(out, "r");
|
||||||
|
if (shell)
|
||||||
|
{
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
char resp[128];
|
||||||
|
|
||||||
|
if (fgets(resp, sizeof(resp), shell) == NULL)
|
||||||
|
{
|
||||||
|
if (ferror(shell))
|
||||||
|
{
|
||||||
|
DBG1(DBG_CHD, "error reading from updown script");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *e = resp + strlen(resp);
|
||||||
|
if (e > resp && e[-1] == '\n')
|
||||||
|
{
|
||||||
|
e[-1] = '\0';
|
||||||
|
}
|
||||||
|
DBG1(DBG_CHD, "updown: %s", resp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(shell);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
close(out);
|
||||||
|
}
|
||||||
|
process->wait(process, NULL);
|
||||||
|
}
|
||||||
|
free(iface);
|
||||||
|
free_env(envp);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(listener_t, child_updown, bool,
|
METHOD(listener_t, child_updown, bool,
|
||||||
private_updown_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
private_updown_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
||||||
bool up)
|
bool up)
|
||||||
@ -203,233 +388,17 @@ METHOD(listener_t, child_updown, bool,
|
|||||||
traffic_selector_t *my_ts, *other_ts;
|
traffic_selector_t *my_ts, *other_ts;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
child_cfg_t *config;
|
child_cfg_t *config;
|
||||||
host_t *me, *other;
|
|
||||||
char *script;
|
|
||||||
|
|
||||||
config = child_sa->get_config(child_sa);
|
config = child_sa->get_config(child_sa);
|
||||||
script = config->get_updown(config);
|
if (config->get_updown(config))
|
||||||
me = ike_sa->get_my_host(ike_sa);
|
|
||||||
other = ike_sa->get_other_host(ike_sa);
|
|
||||||
|
|
||||||
if (script == NULL)
|
|
||||||
{
|
{
|
||||||
return TRUE;
|
enumerator = child_sa->create_policy_enumerator(child_sa);
|
||||||
|
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
|
||||||
|
{
|
||||||
|
invoke_once(this, ike_sa, child_sa, config, up, my_ts, other_ts);
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
enumerator = child_sa->create_policy_enumerator(child_sa);
|
|
||||||
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
|
|
||||||
{
|
|
||||||
char command[2048];
|
|
||||||
host_t *my_client, *other_client;
|
|
||||||
u_int8_t my_client_mask, other_client_mask;
|
|
||||||
char *virtual_ip, *iface, *mark_in, *mark_out, *udp_enc, *dns, *xauth;
|
|
||||||
mark_t mark;
|
|
||||||
bool is_host, is_ipv6, use_ipcomp;
|
|
||||||
FILE *shell;
|
|
||||||
|
|
||||||
my_ts->to_subnet(my_ts, &my_client, &my_client_mask);
|
|
||||||
other_ts->to_subnet(other_ts, &other_client, &other_client_mask);
|
|
||||||
|
|
||||||
virtual_ip = make_vip_vars(this, ike_sa);
|
|
||||||
|
|
||||||
/* check for the presence of an inbound mark */
|
|
||||||
mark = config->get_mark(config, TRUE);
|
|
||||||
if (mark.value)
|
|
||||||
{
|
|
||||||
if (asprintf(&mark_in, "PLUTO_MARK_IN='%u/0x%08x' ",
|
|
||||||
mark.value, mark.mask ) < 0)
|
|
||||||
{
|
|
||||||
mark_in = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (asprintf(&mark_in, "") < 0)
|
|
||||||
{
|
|
||||||
mark_in = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for the presence of an outbound mark */
|
|
||||||
mark = config->get_mark(config, FALSE);
|
|
||||||
if (mark.value)
|
|
||||||
{
|
|
||||||
if (asprintf(&mark_out, "PLUTO_MARK_OUT='%u/0x%08x' ",
|
|
||||||
mark.value, mark.mask ) < 0)
|
|
||||||
{
|
|
||||||
mark_out = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (asprintf(&mark_out, "") < 0)
|
|
||||||
{
|
|
||||||
mark_out = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for a NAT condition causing ESP_IN_UDP encapsulation */
|
|
||||||
if (ike_sa->has_condition(ike_sa, COND_NAT_ANY))
|
|
||||||
{
|
|
||||||
if (asprintf(&udp_enc, "PLUTO_UDP_ENC='%u' ",
|
|
||||||
other->get_port(other)) < 0)
|
|
||||||
{
|
|
||||||
udp_enc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (asprintf(&udp_enc, "") < 0)
|
|
||||||
{
|
|
||||||
udp_enc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ike_sa->has_condition(ike_sa, COND_EAP_AUTHENTICATED) ||
|
|
||||||
ike_sa->has_condition(ike_sa, COND_XAUTH_AUTHENTICATED))
|
|
||||||
{
|
|
||||||
if (asprintf(&xauth, "PLUTO_XAUTH_ID='%Y' ",
|
|
||||||
ike_sa->get_other_eap_id(ike_sa)) < 0)
|
|
||||||
{
|
|
||||||
xauth = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (asprintf(&xauth, "") < 0)
|
|
||||||
{
|
|
||||||
xauth = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (up)
|
|
||||||
{
|
|
||||||
if (hydra->kernel_interface->get_interface(hydra->kernel_interface,
|
|
||||||
me, &iface))
|
|
||||||
{
|
|
||||||
cache_iface(this, child_sa->get_reqid(child_sa), iface);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iface = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iface = uncache_iface(this, child_sa->get_reqid(child_sa));
|
|
||||||
}
|
|
||||||
|
|
||||||
dns = make_dns_vars(this, ike_sa);
|
|
||||||
|
|
||||||
/* check for IPComp */
|
|
||||||
use_ipcomp = child_sa->get_ipcomp(child_sa) != IPCOMP_NONE;
|
|
||||||
|
|
||||||
/* determine IPv4/IPv6 and client/host situation */
|
|
||||||
is_host = my_ts->is_host(my_ts, me);
|
|
||||||
is_ipv6 = is_host ? (me->get_family(me) == AF_INET6) :
|
|
||||||
(my_ts->get_type(my_ts) == TS_IPV6_ADDR_RANGE);
|
|
||||||
|
|
||||||
/* build the command with all env variables.
|
|
||||||
*/
|
|
||||||
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_PROTO='%s' "
|
|
||||||
"PLUTO_UNIQUEID='%u' "
|
|
||||||
"PLUTO_ME='%H' "
|
|
||||||
"PLUTO_MY_ID='%Y' "
|
|
||||||
"PLUTO_MY_CLIENT='%+H/%u' "
|
|
||||||
"PLUTO_MY_PORT='%u' "
|
|
||||||
"PLUTO_MY_PROTOCOL='%u' "
|
|
||||||
"PLUTO_PEER='%H' "
|
|
||||||
"PLUTO_PEER_ID='%Y' "
|
|
||||||
"PLUTO_PEER_CLIENT='%+H/%u' "
|
|
||||||
"PLUTO_PEER_PORT='%u' "
|
|
||||||
"PLUTO_PEER_PROTOCOL='%u' "
|
|
||||||
"%s"
|
|
||||||
"%s"
|
|
||||||
"%s"
|
|
||||||
"%s"
|
|
||||||
"%s"
|
|
||||||
"%s"
|
|
||||||
"%s"
|
|
||||||
"%s"
|
|
||||||
"%s",
|
|
||||||
up ? "up" : "down",
|
|
||||||
is_host ? "-host" : "-client",
|
|
||||||
is_ipv6 ? "-v6" : "",
|
|
||||||
config->get_name(config),
|
|
||||||
iface ? iface : "unknown",
|
|
||||||
child_sa->get_reqid(child_sa),
|
|
||||||
child_sa->get_protocol(child_sa) == PROTO_ESP ? "esp" : "ah",
|
|
||||||
ike_sa->get_unique_id(ike_sa),
|
|
||||||
me, ike_sa->get_my_id(ike_sa),
|
|
||||||
my_client, my_client_mask,
|
|
||||||
get_port(my_ts, other_ts, TRUE),
|
|
||||||
my_ts->get_protocol(my_ts),
|
|
||||||
other, ike_sa->get_other_id(ike_sa),
|
|
||||||
other_client, other_client_mask,
|
|
||||||
get_port(my_ts, other_ts, FALSE),
|
|
||||||
other_ts->get_protocol(other_ts),
|
|
||||||
xauth,
|
|
||||||
virtual_ip,
|
|
||||||
mark_in,
|
|
||||||
mark_out,
|
|
||||||
udp_enc,
|
|
||||||
use_ipcomp ? "PLUTO_IPCOMP='1' " : "",
|
|
||||||
config->get_hostaccess(config) ? "PLUTO_HOST_ACCESS='1' " : "",
|
|
||||||
dns,
|
|
||||||
script);
|
|
||||||
my_client->destroy(my_client);
|
|
||||||
other_client->destroy(other_client);
|
|
||||||
free(virtual_ip);
|
|
||||||
free(mark_in);
|
|
||||||
free(mark_out);
|
|
||||||
free(udp_enc);
|
|
||||||
free(dns);
|
|
||||||
free(iface);
|
|
||||||
free(xauth);
|
|
||||||
|
|
||||||
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 TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
char resp[128];
|
|
||||||
|
|
||||||
if (fgets(resp, sizeof(resp), shell) == NULL)
|
|
||||||
{
|
|
||||||
if (ferror(shell))
|
|
||||||
{
|
|
||||||
DBG1(DBG_CHD, "error reading output from updown script");
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user