From 1e6f187eb4eb2990f26b2f54ddaaf993e9285718 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 27 Dec 2014 13:32:07 +0000 Subject: [PATCH] Fix hook settings writing and checking Formerly the check functions were not correctly called in some cases. Hence passing the check function is now explicitely required. The {port,zone}_settings_{read,write} functions do this transparent to the zone/port hooks. --- src/functions/functions.list | 13 +++++++ src/functions/functions.ports | 11 ++++-- src/functions/functions.settings | 58 ++++++++++++++++++++++++++------ src/functions/functions.util | 10 ++++++ src/functions/functions.zone | 25 ++++++++++---- src/header-zone | 6 ++-- src/hooks/ports/batman-adv | 2 +- src/hooks/ports/bonding | 2 +- src/hooks/ports/dummy | 2 +- src/hooks/ports/ethernet | 2 +- src/hooks/ports/vlan | 2 +- src/hooks/ports/wireless-adhoc | 2 +- src/hooks/ports/wireless-ap | 2 +- src/hooks/zones/6rd | 6 ++-- src/hooks/zones/6to4-tunnel | 6 ++-- src/hooks/zones/aiccu | 4 +-- src/hooks/zones/bridge | 4 +-- src/hooks/zones/modem | 10 +++--- src/hooks/zones/pppoe | 10 +++--- src/hooks/zones/pptp | 10 +++--- src/hooks/zones/wireless | 4 +-- 21 files changed, 134 insertions(+), 57 deletions(-) diff --git a/src/functions/functions.list b/src/functions/functions.list index 062df27e..0f11c32c 100644 --- a/src/functions/functions.list +++ b/src/functions/functions.list @@ -24,6 +24,19 @@ function list_append() { local list=${1} + assert isset list + shift + + local arg + for arg in $@; do + list_append_one "${list}" "${arg}" + done +} + +function list_append_one() { + assert [ $# -eq 2 ] + + local list="${1}" shift assert isset list diff --git a/src/functions/functions.ports b/src/functions/functions.ports index 5bed4d8b..58f60cd1 100644 --- a/src/functions/functions.ports +++ b/src/functions/functions.ports @@ -40,12 +40,11 @@ function port_config_dir() { function port_settings_read() { local port="${1}" assert isset port - shift # Save the HOOK variable. local hook="${HOOK}" - settings_read "$(port_file "${port}")" "$@" + settings_read "$(port_file "${port}")" ${HOOK_SETTINGS} # Restore hook. HOOK="${hook}" @@ -56,7 +55,13 @@ function port_settings_write() { assert isset port shift - settings_write "$(port_file "${port}")" "$@" + local args + if function_exists "hook_check_settings"; then + list_append args "--check=\"hook_check_settings\"" + fi + list_append args ${HOOK_SETTINGS} + + settings_write "$(port_file "${port}")" ${args} } function ports_get_all() { diff --git a/src/functions/functions.settings b/src/functions/functions.settings index 8b5ac98e..2f2821ff 100644 --- a/src/functions/functions.settings +++ b/src/functions/functions.settings @@ -132,13 +132,30 @@ function settings_strip() { } function settings_write() { - local settings_file=${1} + local settings_file="${1}" assert isset settings_file shift + local check_func + + local arg + while read arg; do + case "${arg}" in + --check=*) + check_func="$(cli_get_val "${arg}")" + ;; + + # Stop argument processing when reaching the first + # configuration parameter + *) + break + ;; + esac + shift + done <<< "$(args $@)" + # Check if all values to be written are sane - if ! settings_check; then - log CRITICAL "Configuration check failed. No settings have been written." + if isset check_func && ! settings_check "${check_func}"; then return ${EXIT_ERROR} fi @@ -174,13 +191,34 @@ function settings_print() { } function settings_check() { - # If there is a function defined that is called __check - # we call that function - if [ -n "$(type -t hook_check)" ]; then - hook_check || return $? - fi - - return ${EXIT_OK} + local check_func="${1}" + + # Execute the check function + "${check_func}" + local ret="${?}" + + case "${ret}" in + # OK + ${EXIT_OK}|${EXIT_TRUE}) + log DEBUG "Configuration check succeeded." + return ${EXIT_TRUE} + ;; + + # Error + ${EXIT_ERROR}|${EXIT_FALSE}) + log CRITICAL "Configuration check failed. No settings have been written." + return ${EXIT_FALSE} + ;; + + # Command not found + ${EXIT_COMMAND_NOT_FOUND}) + log CRITICAL "Configuration check function '${check_func}' was not found." + return ${EXIT_FALSE} + ;; + esac + + log CRITICAL "Unhandled exit code for '${check_func}': ${ret}" + return ${EXIT_ERROR} } function settings_set() { diff --git a/src/functions/functions.util b/src/functions/functions.util index f627d99d..18a8f184 100644 --- a/src/functions/functions.util +++ b/src/functions/functions.util @@ -436,6 +436,16 @@ function binary_exists() { return ${EXIT_ERROR} } +function function_exists() { + local function="${1}" + + if [ "$(type -t "${function}")" = "function" ]; then + return ${EXIT_TRUE} + fi + + return ${EXIT_FALSE} +} + function process_kill() { local process=${1} diff --git a/src/functions/functions.zone b/src/functions/functions.zone index 26fed661..22688a26 100644 --- a/src/functions/functions.zone +++ b/src/functions/functions.zone @@ -855,24 +855,28 @@ function zone_file() { function zone_settings_read() { local zone=${1} - assert isset zone # Save the HOOK variable. local hook="${HOOK}" - settings_read $(zone_file ${zone}) + settings_read "${zone}" ${HOOK_SETTINGS} # Restore hook. HOOK="${hook}" } function zone_settings_write() { - local zone=${1} - + local zone="${1}" assert isset zone - settings_write $(zone_file ${zone}) ${HOOK_SETTINGS} + local args + if function_exists "hook_check_settings"; then + list_append args "--check=\"hook_check_settings\"" + fi + list_append args ${HOOK_SETTINGS} + + settings_write "$(zone_file ${zone})" ${args} } function zone_settings_set() { @@ -901,7 +905,8 @@ function zone_settings_get() { assert isset key ( - zone_settings_read ${zone} + zone_settings_read "${zone}" "${key}" \ + --ignore-superfluous-settings echo "${!key}" ) @@ -947,8 +952,14 @@ function zone_port_settings_write() { local port="${2}" shift 2 + local args + if function_exists "hook_check_port_settings"; then + list_append args "--check=\"hook_check_port_settings\"" + fi + list_append args $@ + local path="$(zone_dir "${zone}")/ports/${port}" - settings_write "${path}" "$@" + settings_write "${path}" ${args} } function zone_port_settings_remove() { diff --git a/src/header-zone b/src/header-zone index a9e1ebef..1f3a6612 100644 --- a/src/header-zone +++ b/src/header-zone @@ -34,17 +34,17 @@ function hook_new() { assert isset zone shift - settings_read $(zone_dir ${zone})/settings + zone_settings_read "${zone}" hook_parse_cmdline $@ - settings_write $(zone_dir ${zone})/settings ${HOOK_SETTINGS} + zone_settings_write "${zone}" exit ${EXIT_OK} } function hook_edit() { - hook_create $@ + hook_new $@ } function hook_remove() { diff --git a/src/hooks/ports/batman-adv b/src/hooks/ports/batman-adv index 99080cf5..40b9735f 100644 --- a/src/hooks/ports/batman-adv +++ b/src/hooks/ports/batman-adv @@ -28,7 +28,7 @@ PORT_CHILDREN_VAR="SLAVES" ADDRESS=$(mac_generate) SLAVES= -function hook_check() { +function hook_check_settings() { assert isset ADDRESS assert ismac ADDRESS } diff --git a/src/hooks/ports/bonding b/src/hooks/ports/bonding index 33a3167c..b554c44b 100644 --- a/src/hooks/ports/bonding +++ b/src/hooks/ports/bonding @@ -28,7 +28,7 @@ SLAVES="" MIIMON=100 MODE="balance-rr" -function hook_check() { +function hook_check_settings() { assert isset ADDRESS assert ismac ADDRESS diff --git a/src/hooks/ports/dummy b/src/hooks/ports/dummy index df41ac9f..617084e4 100644 --- a/src/hooks/ports/dummy +++ b/src/hooks/ports/dummy @@ -23,7 +23,7 @@ HOOK_SETTINGS="HOOK ADDRESS" -function hook_check() { +function hook_check_settings() { assert ismac ADDRESS } diff --git a/src/hooks/ports/ethernet b/src/hooks/ports/ethernet index fca74ae7..783e0fc7 100644 --- a/src/hooks/ports/ethernet +++ b/src/hooks/ports/ethernet @@ -26,7 +26,7 @@ HOOK_SETTINGS="HOOK ADDRESS DEVICE" -function hook_check() { +function hook_check_settings() { assert ismac DEVICE if isset ADDRESS; then diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan index 6ab0aecf..b95f6a98 100644 --- a/src/hooks/ports/vlan +++ b/src/hooks/ports/vlan @@ -25,7 +25,7 @@ HOOK_SETTINGS="HOOK ADDRESS PARENT_DEVICE TAG" PORT_PARENTS_VAR="PARENT" -function hook_check() { +function hook_check_settings() { assert isset PARENT_DEVICE assert isinteger TAG diff --git a/src/hooks/ports/wireless-adhoc b/src/hooks/ports/wireless-adhoc index 1544473c..7c9ea365 100644 --- a/src/hooks/ports/wireless-adhoc +++ b/src/hooks/ports/wireless-adhoc @@ -30,7 +30,7 @@ MTU=1500 PHY= SSID= -function hook_check() { +function hook_check_settings() { assert isset ADDRESS assert ismac ADDRESS assert isset CHANNEL diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap index 8de0aba3..3ff80d06 100644 --- a/src/hooks/ports/wireless-ap +++ b/src/hooks/ports/wireless-ap @@ -32,7 +32,7 @@ KEY="" MODE="g" SSID= -function hook_check() { +function hook_check_settings() { assert isset ADDRESS assert ismac ADDRESS assert isset BROADCAST_SSID diff --git a/src/hooks/zones/6rd b/src/hooks/zones/6rd index 2777c907..a0a9bf95 100644 --- a/src/hooks/zones/6rd +++ b/src/hooks/zones/6rd @@ -36,7 +36,7 @@ SERVER_ADDRESS="" # The public IPv4 address of the tunnel client. PUBLIC_ADDRESS="" -function hook_check() { +function hook_check_settings() { assert isset SIX_RD_PREFIX assert isset PUBLIC_ADDRESS assert isset SERVER_ADDRESS @@ -101,7 +101,7 @@ function hook_up() { assert isset zone # Read configuration options. - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" # Configure the tunnel. if ! device_exists "${zone}"; then @@ -150,7 +150,7 @@ function hook_status() { cli_device_headline ${zone} - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" local server_line="${SERVER_ADDRESS}" local server_hostname=$(dns_get_hostname ${SERVER_ADDRESS}) diff --git a/src/hooks/zones/6to4-tunnel b/src/hooks/zones/6to4-tunnel index 898d8985..2fc91ad2 100644 --- a/src/hooks/zones/6to4-tunnel +++ b/src/hooks/zones/6to4-tunnel @@ -44,7 +44,7 @@ TUNNEL_ID= USERNAME= PASSWORD= -function hook_check() { +function hook_check_settings() { assert isset SERVER_ADDRESS assert isset LOCAL_ADDRESS assert isset LOCAL_ADDRESS6 @@ -102,7 +102,7 @@ function hook_up() { assert isset zone # Read configuration options. - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" if enabled AUTO_UPDATE_ENDPOINT; then log DEBUG "Updating tunnel endpoint" @@ -156,7 +156,7 @@ function hook_status() { cli_device_headline ${zone} - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" local server_line="${SERVER_ADDRESS}" local server_hostname=$(dns_get_hostname ${SERVER_ADDRESS}) diff --git a/src/hooks/zones/aiccu b/src/hooks/zones/aiccu index 86030a4b..d8852ebf 100644 --- a/src/hooks/zones/aiccu +++ b/src/hooks/zones/aiccu @@ -30,7 +30,7 @@ PROTOCOL="tic" TUNNEL_ID= REQUIRE_TLS="true" -function hook_check() { +function hook_check_settings() { assert isset USERNAME assert isset PASSWORD assert isset SERVER @@ -109,7 +109,7 @@ function hook_status() { cli_device_headline ${zone} - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" cli_headline 2 "Configuration" cli_print_fmt1 2 "User" "${USERNAME}" diff --git a/src/hooks/zones/bridge b/src/hooks/zones/bridge index 021e4402..b29c9680 100644 --- a/src/hooks/zones/bridge +++ b/src/hooks/zones/bridge @@ -38,7 +38,7 @@ STP_HELLO=2 STP_MAXAGE=20 STP_PRIORITY=512 -function hook_check() { +function hook_check_settings() { assert ismac MAC assert isbool STP assert isoneof STP_MODE stp rstp @@ -84,7 +84,7 @@ function hook_up() { local zone=${1} assert isset zone - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" # Create the bridge if it does not already exist. if ! device_exists "${zone}"; then diff --git a/src/hooks/zones/modem b/src/hooks/zones/modem index 7e2e6882..441e95e2 100644 --- a/src/hooks/zones/modem +++ b/src/hooks/zones/modem @@ -70,7 +70,7 @@ HOOK_SETTINGS="${HOOK_SETTINGS} PHONE_NUMBER" IMSI= HOOK_SETTINGS="${HOOK_SETTINGS} IMSI" -function hook_check() { +function hook_check_settings() { assert isset DEVICE assert isset PHONE_NUMBER @@ -140,14 +140,14 @@ function hook_up() { assert isset zone # Load configuration file. - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" # If we have got a PIN, we try to unlock the device first. if isset PIN; then if ! modem_sim_auto_unlock "${DEVICE}" "${PIN}"; then # Reset the PIN setting. PIN="" - zone_settings_write "${zone}" ${HOOK_SETTINGS} + zone_settings_write "${zone}" error "Could not unlock the SIM card. Removing PIN from settings." fi @@ -179,7 +179,7 @@ function hook_status() { cli_device_headline ${zone} - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" cli_headline 2 "Configuration" cli_print_fmt1 2 "Username" "${USERNAME}" @@ -272,7 +272,7 @@ function hook_ppp_write_config() { assert isset file # Read in the configuration files. - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" pppd_write_config ${file} \ --interface="${zone}" \ diff --git a/src/hooks/zones/pppoe b/src/hooks/zones/pppoe index b201ebe7..461d7a99 100644 --- a/src/hooks/zones/pppoe +++ b/src/hooks/zones/pppoe @@ -51,7 +51,7 @@ IPV6="true" # Use IPv6 prefix delegation. PREFIX_DELEGATION="false" -function hook_check() { +function hook_check_settings() { assert isset USERNAME assert isset PASSWORD @@ -105,7 +105,7 @@ function hook_up() { local zone=${1} assert isset zone - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" # Bring up the port. local port=$(__hook_get_port "${zone}") @@ -121,7 +121,7 @@ function hook_down() { local zone=${1} assert isset zone - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" # Stop the ppp daemon. pppd_stop ${zone} @@ -170,7 +170,7 @@ function hook_status() { cli_device_headline ${zone} - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" cli_headline 2 "Configuration" cli_print_fmt1 2 "Username" "${USERNAME}" @@ -228,7 +228,7 @@ function hook_ppp_write_config() { assert isset file # Read in the configuration files. - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" # A port has to be assigned for this action local port=$(__hook_get_port "${zone}") diff --git a/src/hooks/zones/pptp b/src/hooks/zones/pptp index 5902a5b5..2ce9e932 100644 --- a/src/hooks/zones/pptp +++ b/src/hooks/zones/pptp @@ -57,7 +57,7 @@ PREFIX_DELEGATION="false" # A list of refused authentification methods. REFUSED_AUTH_METHODS="" -function hook_check() { +function hook_check_settings() { assert isset USERNAME assert isset PASSWORD assert isset PEER_ADDRESS @@ -167,7 +167,7 @@ function hook_up() { local zone="${1}" assert isset zone - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" # Check if a port will be used. if isset PORT; then @@ -195,7 +195,7 @@ function hook_down() { local zone="${1}" assert isset zone - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" # Stop the ppp daemon. pppd_stop "${zone}" @@ -225,7 +225,7 @@ function hook_status() { cli_device_headline "${zone}" - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" # Display port configuration if a port is used. if isset PORT; then @@ -283,7 +283,7 @@ function hook_ppp_write_config() { assert isset file # Read in the configuration files. - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" # Prepare the command line options for the pptp plugin. local pptp_commandline="pptp ${PEER_ADDRESS} --nolaunchpppd" diff --git a/src/hooks/zones/wireless b/src/hooks/zones/wireless index e376ab0c..52a3da30 100644 --- a/src/hooks/zones/wireless +++ b/src/hooks/zones/wireless @@ -31,7 +31,7 @@ SSID= KEY= ENCRYPTION_MODE= -function hook_check() { +function hook_check_settings() { assert isset SSID if isset ADDRESS; then @@ -81,7 +81,7 @@ function hook_up() { assert isset zone # Read zone configuration. - zone_settings_read "${zone}" ${HOOK_SETTINGS} + zone_settings_read "${zone}" if ! device_exists ${zone}; then # Create the wireless interface. -- 2.39.2