From 7f065a94bb2663d32da7424c777a580d470728a0 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Sat, 27 Mar 2021 20:33:44 +0100 Subject: [PATCH] openvpn: fix invoking user up & down commands from hotplug wrapper This commit adds a number of fixes to the OpenVPN up/down hotplug command wrapper which currently fails to actually invoke user defined up and down commands for uci configurations not using external native configurations. - Use the `--setenv` to pass the user configured `up` and `down` commands as `user_up` and `user_down` environment variables respectively - Instead of attempting to scrape the `up` and `down` settings from the (possibly generated) native OpenVPN configuration in `/etc/hotplug.d/openvpn/01-user`, read them from the respective environment variables instead - Fix parsing of native configuration values in `get_openvpn_option()`; first try to parse a given setting as single quoted value, then as double quoted and finally as non-quoted, potentially white-space escaped one. This ensures that `up '/bin/foo'` is interpreted as `/bin/foo` and not `'/bin/foo'` Ref: https://forum.openwrt.org/t/openvpn-up-down-configuration-ignored/91126 Supersedes: #15121, #15284 Signed-off-by: Jo-Philipp Wich --- net/openvpn/Makefile | 2 +- .../files/etc/hotplug.d/openvpn/01-user | 16 +++++++------- net/openvpn/files/lib/functions/openvpn.sh | 4 ++-- net/openvpn/files/openvpn.init | 21 ++++++++++++++----- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/net/openvpn/Makefile b/net/openvpn/Makefile index 36828b560..3b3adce42 100644 --- a/net/openvpn/Makefile +++ b/net/openvpn/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openvpn PKG_VERSION:=2.5.1 -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_SOURCE_URL:=\ https://build.openvpn.net/downloads/releases/ \ diff --git a/net/openvpn/files/etc/hotplug.d/openvpn/01-user b/net/openvpn/files/etc/hotplug.d/openvpn/01-user index f93823e5c..4c72f1c4b 100644 --- a/net/openvpn/files/etc/hotplug.d/openvpn/01-user +++ b/net/openvpn/files/etc/hotplug.d/openvpn/01-user @@ -1,7 +1,5 @@ #!/bin/sh -. /lib/functions/openvpn.sh - [ -e "/etc/openvpn.user" ] && { env -i ACTION="$ACTION" INSTANCE="$INSTANCE" \ /bin/sh \ @@ -11,12 +9,14 @@ # Wrap user defined scripts on up/down events case "$ACTION" in - up|down) - if get_openvpn_option "$config" command "$ACTION"; then - shift - exec /bin/sh -c "$command $*" - fi - ;; + up) command=$user_up ;; + down) command=$user_down ;; + *) command= ;; esac +if [ -n "$command" ]; then + shift + exec /bin/sh -c "$command $*" +fi + exit 0 diff --git a/net/openvpn/files/lib/functions/openvpn.sh b/net/openvpn/files/lib/functions/openvpn.sh index 83fb1bb45..2de6fb730 100644 --- a/net/openvpn/files/lib/functions/openvpn.sh +++ b/net/openvpn/files/lib/functions/openvpn.sh @@ -5,9 +5,9 @@ get_openvpn_option() { local variable="$2" local option="$3" - local value="$(sed -rne 's/^[ \t]*'"$option"'[ \t]+(([^ \t\\]|\\.)+)[ \t]*$/\1/p' "$config" | tail -n1 | sed -re 's/\\(.)/\1/g')" - [ -n "$value" ] || value="$(sed -rne 's/^[ \t]*'"$option"'[ \t]+'"'([^']+)'"'[ \t]*$/\1/p' "$config" | tail -n1)" + local value="$(sed -rne 's/^[ \t]*'"$option"'[ \t]+'"'([^']+)'"'[ \t]*$/\1/p' "$config" | tail -n1)" [ -n "$value" ] || value="$(sed -rne 's/^[ \t]*'"$option"'[ \t]+"(([^"\\]|\\.)+)"[ \t]*$/\1/p' "$config" | tail -n1 | sed -re 's/\\(.)/\1/g')" + [ -n "$value" ] || value="$(sed -rne 's/^[ \t]*'"$option"'[ \t]+(([^ \t\\]|\\.)+)[ \t]*$/\1/p' "$config" | tail -n1 | sed -re 's/\\(.)/\1/g')" [ -n "$value" ] || return 1 export -n "$variable=$value" diff --git a/net/openvpn/files/openvpn.init b/net/openvpn/files/openvpn.init index fba9b3c2c..f7dc006ce 100644 --- a/net/openvpn/files/openvpn.init +++ b/net/openvpn/files/openvpn.init @@ -141,6 +141,8 @@ openvpn_add_instance() { local dir="$2" local conf="$3" local security="$4" + local up="$5" + local down="$6" procd_open_instance "$name" procd_set_param command "$PROG" \ @@ -150,6 +152,8 @@ openvpn_add_instance() { --config "$conf" \ --up "/usr/libexec/openvpn-hotplug up $name" \ --down "/usr/libexec/openvpn-hotplug down $name" \ + ${up:+--setenv user_up "$up"} \ + ${down:+--setenv user_down "$down"} \ --script-security "${security:-2}" \ $(openvpn_get_dev "$name" "$conf") \ $(openvpn_get_credentials "$name" "$conf") @@ -173,14 +177,18 @@ start_instance() { return 1 } - local script_security + local up down script_security + config_get up "$s" up + config_get down "$s" down config_get script_security "$s" script_security [ ! -d "/var/run" ] && mkdir -p "/var/run" if [ ! -z "$config" ]; then append UCI_STARTED "$config" "$LIST_SEP" - openvpn_add_instance "$s" "${config%/*}" "$config" "$script_security" + [ -n "$up" ] || get_openvpn_option "$config" up up + [ -n "$down" ] || get_openvpn_option "$config" down down + openvpn_add_instance "$s" "${config%/*}" "$config" "$script_security" "$up" "$down" return fi @@ -190,7 +198,7 @@ start_instance() { append_params "$s" $OPENVPN_PARAMS append_list "$s" $OPENVPN_LIST - openvpn_add_instance "$s" "/var/etc" "openvpn-$s.conf" "$script_security" + openvpn_add_instance "$s" "/var/etc" "openvpn-$s.conf" "$script_security" "$up" "$down" } start_service() { @@ -207,6 +215,7 @@ start_service() { fi } + . /lib/functions/openvpn.sh . /usr/share/openvpn/openvpn.options config_load 'openvpn' @@ -216,7 +225,7 @@ start_service() { else config_foreach start_instance 'openvpn' - local path name + local path name up down for path in /etc/openvpn/*.conf; do if [ -f "$path" ]; then name="${path##*/}"; name="${name%.conf}" @@ -231,7 +240,9 @@ start_service() { continue fi - openvpn_add_instance "$name" "${path%/*}" "$path" + get_openvpn_option "$path" up up || up="" + get_openvpn_option "$path" down down || down="" + openvpn_add_instance "$name" "${path%/*}" "$path" "" "$up" "$down" fi done fi