diff options
Diffstat (limited to 'src/charon/plugins/updown/updown_plugin.c')
-rw-r--r-- | src/charon/plugins/updown/updown_plugin.c | 206 |
1 files changed, 6 insertions, 200 deletions
diff --git a/src/charon/plugins/updown/updown_plugin.c b/src/charon/plugins/updown/updown_plugin.c index f358026f7..2e5884222 100644 --- a/src/charon/plugins/updown/updown_plugin.c +++ b/src/charon/plugins/updown/updown_plugin.c @@ -15,13 +15,10 @@ * $Id$ */ -#define _GNU_SOURCE -#include <stdio.h> - #include "updown_plugin.h" +#include "updown_listener.h" #include <daemon.h> -#include <config/child_cfg.h> typedef struct private_updown_plugin_t private_updown_plugin_t; @@ -38,205 +35,16 @@ struct private_updown_plugin_t { /** * Listener interface, listens to CHILD_SA state changes */ - listener_t listener; + updown_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 */ - if (asprintf(&my_client, "%R", my_ts) < 0) - { - my_client = NULL; - } - pos = strchr(my_client, '/'); - *pos = '\0'; - my_client_mask = pos + 1; - pos = strchr(my_client_mask, '['); - if (pos) - { - *pos = '\0'; - } - if (asprintf(&other_client, "%R", other_ts) < 0) - { - other_client = NULL; - } - pos = strchr(other_client, '/'); - *pos = '\0'; - other_client_mask = pos + 1; - pos = strchr(other_client_mask, '['); - if (pos) - { - *pos = '\0'; - } - - if (vip) - { - if (asprintf(&virtual_ip, "PLUTO_MY_SOURCEIP='%H' ", vip) < 0) - { - virtual_ip = NULL; - } - } - else - { - if (asprintf(&virtual_ip, "") < 0) - { - virtual_ip = NULL; - } - } - - 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; - - if (ike_sa) - { - 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); + charon->bus->remove_listener(charon->bus, &this->listener->listener); + this->listener->destroy(this->listener); free(this); } @@ -249,10 +57,8 @@ plugin_t *plugin_create() 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); + this->listener = updown_listener_create(); + charon->bus->add_listener(charon->bus, &this->listener->listener); return &this->public.plugin; } |