From: Florian Eckert <fe@dev.tdt.de>
Date: Fri, 30 Nov 2018 13:03:50 +0000 (+0100)
Subject: openvpn: add generic hotplug mechanism
X-Git-Tag: v21.02.0-rc1~2457
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=8fe9940db66517679f09fa1d2f6f79229b6a8361;p=openwrt%2Fopenwrt.git

openvpn: add generic hotplug mechanism

Pass a default --up and --down executable to each started OpenVPN instance
which triggers /etc/hotplug.d/openvpn/ scripts whenever an instance
goes up or down.

User-configured up and down scripts are invoked by the default shipped
01-user hotplug handler to ensure that existing setups continue to work
as before.

As a consequence of this change, the up, down and script_security OpenVPN
options are removed from the option file, since we're always passing them
via the command line, they do not need to get included into the generated
configuration.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
[reword commit message, move hotplug executable to /usr/libexec]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
---

diff --git a/package/network/services/openvpn/Makefile b/package/network/services/openvpn/Makefile
index 5f102d967d..f1170bbd37 100644
--- a/package/network/services/openvpn/Makefile
+++ b/package/network/services/openvpn/Makefile
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
 PKG_NAME:=openvpn
 
 PKG_VERSION:=2.4.9
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE_URL:=\
 	https://build.openvpn.net/downloads/releases/ \
@@ -102,6 +102,7 @@ endef
 
 define Package/openvpn-$(BUILD_VARIANT)/conffiles
 /etc/config/openvpn
+/etc/openvpn.user
 endef
 
 define Package/openvpn-$(BUILD_VARIANT)/install
@@ -111,7 +112,9 @@ define Package/openvpn-$(BUILD_VARIANT)/install
 		$(1)/etc/init.d \
 		$(1)/etc/config \
 		$(1)/etc/openvpn \
-		$(1)/lib/upgrade/keep.d
+		$(1)/lib/upgrade/keep.d \
+		$(1)/usr/libexec \
+		$(1)/etc/hotplug.d/openvpn
 
 	$(INSTALL_BIN) \
 		$(PKG_INSTALL_DIR)/usr/sbin/openvpn \
@@ -120,6 +123,19 @@ define Package/openvpn-$(BUILD_VARIANT)/install
 	$(INSTALL_BIN) \
 		files/openvpn.init \
 		$(1)/etc/init.d/openvpn
+
+	$(INSTALL_BIN) \
+		files/usr/libexec/openvpn-hotplug \
+		$(1)/usr/libexec/openvpn-hotplug
+
+	$(INSTALL_DATA) \
+		files/etc/hotplug.d/openvpn/01-user \
+		$(1)/etc/hotplug.d/openvpn/01-user
+
+	$(INSTALL_DATA) \
+		files/etc/openvpn.user \
+		$(1)/etc/openvpn.user
+
 	$(INSTALL_DATA) \
 		files/openvpn.options \
 		$(1)/usr/share/openvpn/openvpn.options
diff --git a/package/network/services/openvpn/files/etc/hotplug.d/openvpn/01-user b/package/network/services/openvpn/files/etc/hotplug.d/openvpn/01-user
new file mode 100644
index 0000000000..6d45f0b7c6
--- /dev/null
+++ b/package/network/services/openvpn/files/etc/hotplug.d/openvpn/01-user
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+get_option() {
+	local variable="$1"
+	local option="$2"
+
+	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)"
+	[ -n "$value" ] || value="$(sed -rne 's/^[ \t]*'"$option"'[ \t]+"(([^"\\]|\\.)+)"[ \t]*$/\1/p' "$config" | tail -n1 | sed -re 's/\\(.)/\1/g')"
+	[ -n "$value" ] || return 1
+
+	export -n "$variable=$value"
+	return 0
+}
+
+[ -e "/etc/openvpn.user" ] && {
+	env -i ACTION="$ACTION" INSTANCE="$INSTANCE" \
+		/bin/sh \
+		/etc/openvpn.user \
+		$*
+}
+
+# Wrap user defined scripts on up/down events
+case "$ACTION" in
+	up|down)
+		if get_option command "$ACTION"; then
+			exec /bin/sh -c "$command $ACTION $INSTANCE $*"
+		fi
+	;;
+esac
+
+exit 0
diff --git a/package/network/services/openvpn/files/etc/openvpn.user b/package/network/services/openvpn/files/etc/openvpn.user
new file mode 100644
index 0000000000..a77566556a
--- /dev/null
+++ b/package/network/services/openvpn/files/etc/openvpn.user
@@ -0,0 +1,11 @@
+#!/bin/sh
+#
+# This file is interpreted as shell script.
+# Put your custom openvpn action here, they will
+# be executed with each opevnp event.
+#
+# $ACTION
+#      <down>    down action is generated after the TUN/TAP device is closed
+#      <up>      up action is generated after the TUN/TAP device is opened
+# $INSTANCE  Name of the openvpn instance which went up or down
+
diff --git a/package/network/services/openvpn/files/openvpn.init b/package/network/services/openvpn/files/openvpn.init
index a7d35d1a98..a560b89ff2 100644
--- a/package/network/services/openvpn/files/openvpn.init
+++ b/package/network/services/openvpn/files/openvpn.init
@@ -73,13 +73,17 @@ openvpn_add_instance() {
 	local name="$1"
 	local dir="$2"
 	local conf="$3"
+	local security="$4"
 
 	procd_open_instance "$name"
 	procd_set_param command "$PROG"	\
 		--syslog "openvpn($name)" \
 		--status "/var/run/openvpn.$name.status" \
 		--cd "$dir" \
-		--config "$conf"
+		--config "$conf" \
+		--up "/usr/libexec/openvpn-hotplug up $name" \
+		--down "/usr/libexec/openvpn-hotplug down $name" \
+		--script-security "${security:-2}"
 	procd_set_param file "$dir/$conf"
 	procd_set_param term_timeout 15
 	procd_set_param respawn
@@ -100,11 +104,14 @@ start_instance() {
 		return 1
 	}
 
+	local script_security
+	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"
+		openvpn_add_instance "$s" "${config%/*}" "$config" "$script_security"
 		return
 	fi
 
@@ -115,7 +122,7 @@ start_instance() {
 	append_params "$s" $OPENVPN_PARAMS
 	append_list "$s" $OPENVPN_LIST
 
-	openvpn_add_instance "$s" "/var/etc" "openvpn-$s.conf"
+	openvpn_add_instance "$s" "/var/etc" "openvpn-$s.conf" "$script_security"
 }
 
 start_service() {
diff --git a/package/network/services/openvpn/files/openvpn.options b/package/network/services/openvpn/files/openvpn.options
index 2da563968c..5d7a387cd3 100644
--- a/package/network/services/openvpn/files/openvpn.options
+++ b/package/network/services/openvpn/files/openvpn.options
@@ -25,7 +25,6 @@ dev
 dev_node
 dev_type
 dh
-down
 ecdh_curve
 echo
 engine
@@ -103,7 +102,6 @@ route_metric
 route_pre_down
 route_up
 rport
-script_security
 secret
 server
 server_bridge
@@ -127,7 +125,6 @@ tran_window
 tun_mtu
 tun_mtu_extra
 txqueuelen
-up
 user
 verb
 verify_client_cert
diff --git a/package/network/services/openvpn/files/usr/libexec/openvpn-hotplug b/package/network/services/openvpn/files/usr/libexec/openvpn-hotplug
new file mode 100644
index 0000000000..9235fbacfe
--- /dev/null
+++ b/package/network/services/openvpn/files/usr/libexec/openvpn-hotplug
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+ACTION=$1
+shift
+INSTANCE=$1
+shift
+
+export ACTION=$ACTION
+export INSTANCE=$INSTANCE
+exec /sbin/hotplug-call openvpn "$@"