From: Michael Tremer Date: Thu, 13 Aug 2015 09:02:58 +0000 (+0200) Subject: Introduce triggers X-Git-Tag: 007~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=de3ceceff6b02872a5c062091b2e470623558254;p=network.git Introduce triggers When the state of the network changes (i.e. a zone comes up, etc.) a set of triggers will be called so that external applications can adopt to these changes. Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 2bb27e2f..9d857748 100644 --- a/Makefile.am +++ b/Makefile.am @@ -46,6 +46,8 @@ hooks_configsdir = $(hooksdir)/configs hooks_portsdir = $(hooksdir)/ports hooks_zonesdir = $(hooksdir)/zones +triggersdir = $(networkdir)/triggers + CLEANFILES = DISTCLEANFILES = EXTRA_DIST = @@ -145,6 +147,7 @@ dist_network_SCRIPTS = \ src/functions/functions.settings \ src/functions/functions.stp \ src/functions/functions.sysctl \ + src/functions/functions.triggers \ src/functions/functions.usb \ src/functions/functions.util \ src/functions/functions.vlan \ @@ -309,6 +312,11 @@ dist_macros_DATA = \ # ------------------------------------------------------------------------------ +INSTALL_DIRS = \ + $(triggersdir) + +# ------------------------------------------------------------------------------ + MANPAGES = \ man/firewall-settings.8 \ man/network.8 \ diff --git a/src/functions/functions.constants b/src/functions/functions.constants index eb7fe7d4..abf7812e 100644 --- a/src/functions/functions.constants +++ b/src/functions/functions.constants @@ -33,6 +33,7 @@ NETWORK_CONFIG_DIR="/etc/network" NETWORK_DB_DIR="${RUN_DIR}/db" NETWORK_ZONE_DIR="${NETWORK_CONFIG_DIR}" NETWORK_HOOKS_DIR=/usr/lib/network/hooks +NETWORK_TRIGGERS_DIR=/usr/lib/network/triggers # Network file configuration. NETWORK_SETTINGS_FILE=${NETWORK_CONFIG_DIR}/config diff --git a/src/functions/functions.in b/src/functions/functions.in index 873b6bea..ba0f95e6 100644 --- a/src/functions/functions.in +++ b/src/functions/functions.in @@ -34,6 +34,9 @@ init_run() { for init in ${INIT_FUNCTIONS}; do ${init} done + + # Also execute all triggers + triggers_execute_all "init" } VERSION="@PACKAGE_VERSION@" diff --git a/src/functions/functions.routing b/src/functions/functions.routing index 5bfbea01..66346107 100644 --- a/src/functions/functions.routing +++ b/src/functions/functions.routing @@ -81,18 +81,15 @@ routing_default_update() { routes=$(echo ${routes}) # Remove all default routes. - while ${cmd} | grep -q "^default"; do - ${cmd} del default - done - if [ -z "${routes}" ]; then + cmd ${cmd} del default log INFO "Removed default route for ${proto}." return ${EXIT_OK} fi log INFO "Setting default route for ${proto}: ${routes}" - cmd ${cmd} add default ${routes} + cmd ${cmd} replace default ${routes} assert [ $? -eq 0 ] case "${proto}" in @@ -101,6 +98,8 @@ routing_default_update() { radvd_update ;; esac + + triggers_execute_all "online" done } diff --git a/src/functions/functions.triggers b/src/functions/functions.triggers new file mode 100644 index 00000000..28a1396b --- /dev/null +++ b/src/functions/functions.triggers @@ -0,0 +1,72 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2015 IPFire Network Development Team # +# # +# 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 3 of the License, or # +# (at your option) any later version. # +# # +# 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. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +TRIGGER_ACTIONS="init up down online" + +trigger_execute() { + local trigger="$1" + shift + + local environment=$@ + + if [ ! -x "${trigger}" ]; then + log WARNING "Trigger is not executable: ${trigger}" + return ${EXIT_ERROR} + fi + + log DEBUG "Executing trigger ${trigger}..." + cmd_clean_environment ${environment} "${trigger}" &>/dev/null + local ret=${?} + + if [ ${ret} -ne ${EXIT_OK} ]; then + log WARNING "Trigger ${trigger} exited with exit code: ${ret}" + log WARNING " Environment: ${environment}" + fi + + return ${ret} +} + +triggers_execute_all() { + local action="${1}" + shift + + # Check if the action is valid + assert list_match "${action}" ${TRIGGER_ACTIONS} + + local environment=$@ + + # Check if the directory exists + [ -d "${NETWORK_TRIGGERS_DIR}" ] || return ${EXIT_ERROR} + + local trigger + for trigger in ${NETWORK_TRIGGERS_DIR}/*; do + # Check if the trigger can be executed + if [ ! -x "${trigger}" ]; then + log DEBUG "Trigger is not executable: ${trigger}" + continue + fi + + # Execute the trigger + trigger_execute "${trigger}" ${environment} ACTION="${action}" + done + + return ${EXIT_OK} +} diff --git a/src/functions/functions.util b/src/functions/functions.util index d26f519f..fdb2ce47 100644 --- a/src/functions/functions.util +++ b/src/functions/functions.util @@ -363,6 +363,19 @@ cmd_not_implemented() { assert false "not implemented" } +# Runs a command in a clean environment so that no confidential information +# is leaked to any untrusted commands. +cmd_clean_environment() { + local cmd=$@ + + log DEBUG "Running command in a clean environment: ${cmd}" + env -i -- ${cmd} + local ret=${?} + + log DEBUG "Returned with code '${ret}'" + return ${ret} +} + # Increase security of the read command read() { builtin read -r $@ diff --git a/src/functions/functions.zone b/src/functions/functions.zone index a41585a9..c46cae94 100644 --- a/src/functions/functions.zone +++ b/src/functions/functions.zone @@ -351,6 +351,9 @@ zone_up() { hook_zone_exec ${hook} up ${zone} $@ zone_db ${zone} started + + # Execute all triggers after the zone got up + triggers_execute_all "up" ZONE="${zone}" } zone_down() { @@ -379,6 +382,9 @@ zone_down() { zone_db ${zone} stopped + # Execute all triggers after the zone went down + triggers_execute_all "down" ZONE="${zone}" + # Remove the zone, if it has got a remove tag. if zone_has_destroy_tag "${zone}"; then zone_destroy_now "${zone}"