From d134b7ffbb9ddf194b12ca5c9c92b98d91c4c7e6 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Mon, 20 Jul 2020 10:42:13 -0400 Subject: [PATCH 01/10] openfortivpn: Only start autostart interfaces on hotplug event Signed-off-by: Aaron Goodman --- net/openfortivpn/files/14-openforticlient | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/openfortivpn/files/14-openforticlient b/net/openfortivpn/files/14-openforticlient index 336e05a9c..9cff9bd21 100644 --- a/net/openfortivpn/files/14-openforticlient +++ b/net/openfortivpn/files/14-openforticlient @@ -8,6 +8,8 @@ for i in $networks; do iface_success=$? [ $? -eq 0 ] && [ $INTERFACE == "$iface" ] && { logger -t "openfortivpnhotplug" "$ACTION on $INTERFACE to bring up $i" + load_on_boot=$(uci get network.${i}.auto 2>/dev/null) + [ -n "$load_on_boot" ] && [ "$load_on_boot" -eq 0 ] && continue json_load "$(ifstatus $i)" json_get_var autostart autostart [ "$autostart" -eq 0 ] && { From 2f9cfb036f219df589c20ad9271e15c92722390b Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Mon, 20 Jul 2020 10:43:32 -0400 Subject: [PATCH 02/10] openfortivpn: block restart after authentication failure Block restart of the interface if the openfortivpn fails to authenticate. Without this check, with a bad password, netifd will continually hit the VPN endpoint with connection attempts Signed-off-by: Aaron Goodman --- net/openfortivpn/files/openfortivpn-wrapper | 38 ++++++++++++++++++--- net/openfortivpn/files/openfortivpn.sh | 2 +- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/net/openfortivpn/files/openfortivpn-wrapper b/net/openfortivpn/files/openfortivpn-wrapper index a64d94d83..cbfe64557 100755 --- a/net/openfortivpn/files/openfortivpn-wrapper +++ b/net/openfortivpn/files/openfortivpn-wrapper @@ -4,10 +4,40 @@ # file from cmd and to daemonize # $1 password file -# $2... are passed to openconnect +# $2 is the config name +# $3... are passed to openconnect test -z "$1" && exit 1 -pwfile=$1 -shift -exec /usr/sbin/openfortivpn "$@" < $pwfile \ No newline at end of file +pwfile=$1; shift +config=$1; shift +killed=0 + +trap_with_arg() { + func="$1" ; shift + for sig ; do + trap "$func $sig" "$sig" + done +} + +func_trap() { + logger "openfortivpn-wrapper[$$]" "sending signal ${1}" + killed=1 + kill -${1} $child 2>/dev/null +} + +trap_with_arg func_trap INT TERM KILL + + +start_time=$(date '+%s') +/usr/sbin/openfortivpn "$@" < $pwfile 2>/dev/null & +child=$! +wait $child || { + [ "$killed" = 1 ] && exit 0 + current_time=$(date '+%s') + elapsed=$(($current_time-$start_time)) + . /lib/netifd/netifd-proto.sh + proto_notify_error "$config" "Failed to connect after $elapsed seconds." + proto_block_restart "$config" + exit 1 +} diff --git a/net/openfortivpn/files/openfortivpn.sh b/net/openfortivpn/files/openfortivpn.sh index 7ddbc7b75..3e6d4cd91 100755 --- a/net/openfortivpn/files/openfortivpn.sh +++ b/net/openfortivpn/files/openfortivpn.sh @@ -137,7 +137,7 @@ mru 1354" > $callfile proto_export INTERFACE="$ifname" logger -p 6 -t openfortivpn "$config: executing 'openfortivpn $cmdline'" - eval "proto_run_command '$config' /usr/sbin/openfortivpn-wrapper '$pwfile' $cmdline" + eval "proto_run_command '$config' /usr/sbin/openfortivpn-wrapper '$pwfile' '$config' $cmdline" } From 7f109ec59f304b7a73bf3ea5ff54f7ae54aed5b7 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Mon, 20 Jul 2020 10:46:17 -0400 Subject: [PATCH 03/10] openfortivpn: minor formatting changes Signed-off-by: Aaron Goodman --- net/openfortivpn/files/openfortivpn.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/openfortivpn/files/openfortivpn.sh b/net/openfortivpn/files/openfortivpn.sh index 3e6d4cd91..b50ba016a 100755 --- a/net/openfortivpn/files/openfortivpn.sh +++ b/net/openfortivpn/files/openfortivpn.sh @@ -18,7 +18,7 @@ proto_openfortivpn_init_config() { proto_config_add_string "username" proto_config_add_string "password" proto_config_add_string "trusted_cert" - proto_config_add_string "remote_status_check" + proto_config_add_string "remote_status_check" proto_config_add_int "peerdns" proto_config_add_int "metric" no_device=1 @@ -30,7 +30,7 @@ proto_openfortivpn_setup() { local msg json_get_vars host server port iface_name local_ip username password trusted_cert \ - remote_status_check peerdns metric + remote_status_check peerdns metric ifname="vpn-$config" @@ -89,7 +89,7 @@ proto_openfortivpn_setup() { [ -n "$port" ] && port=":$port" - [ -z "$peerdns" ] && peerdns=1 + [ -z "$peerdns" ] && peerdns=1 append_args "$server$port" --pppd-ifname="$ifname" --use-syslog -c /dev/null append_args "--set-dns=0" From d8b71f45a8da8226ce1b801c37e88fefa9d93f36 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Mon, 20 Jul 2020 10:46:48 -0400 Subject: [PATCH 04/10] openfortivpn: don't report error if symlink already exists If two openfortivpn scripts are started at the same time, a race condition can occur where the conditional evaluates to true, but the symlink exists by the time the other script tries to create it Signed-off-by: Aaron Goodman --- net/openfortivpn/files/openfortivpn.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/openfortivpn/files/openfortivpn.sh b/net/openfortivpn/files/openfortivpn.sh index b50ba016a..5599f3150 100755 --- a/net/openfortivpn/files/openfortivpn.sh +++ b/net/openfortivpn/files/openfortivpn.sh @@ -104,7 +104,7 @@ proto_openfortivpn_setup() { [ -n "$username" ] && append_args -u "$username" [ -n "$password" ] && { umask 077 - mkdir -p /var/etc + mkdir -p '/var/etc/openfortivpn' pwfile="/var/etc/openfortivpn/$config.passwd" echo "$password" > "$pwfile" } @@ -112,7 +112,7 @@ proto_openfortivpn_setup() { [ -n "$local_ip" ] || local_ip=192.0.2.1 [ -e '/etc/ppp/peers' ] || mkdir -p '/etc/ppp/peers' [ -e '/etc/ppp/peers/openfortivpn' ] || { - ln -s -T '/var/etc/openfortivpn/peers' '/etc/ppp/peers/openfortivpn' + ln -s -T '/var/etc/openfortivpn/peers' '/etc/ppp/peers/openfortivpn' 2> /dev/null mkdir -p '/var/etc/openfortivpn/peers' } From c8a8afe8c0ee7eccb5466e2096021aeb7284d42e Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Mon, 20 Jul 2020 10:50:34 -0400 Subject: [PATCH 05/10] openfortivpn: version bump to 1.14.1-6 Signed-off-by: Aaron Goodman --- net/openfortivpn/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/openfortivpn/Makefile b/net/openfortivpn/Makefile index b07672cca..6b180c6b5 100644 --- a/net/openfortivpn/Makefile +++ b/net/openfortivpn/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openfortivpn PKG_VERSION:=1.14.1 -PKG_RELEASE:=5 +PKG_RELEASE:=6 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/adrienverge/openfortivpn/tar.gz/v$(PKG_VERSION)? From a541f0be8a8f28b8bb66c2fb433fa89e25704555 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Tue, 21 Jul 2020 02:12:37 -0400 Subject: [PATCH 06/10] openfortivpn: use proper method to access configuration in hotplug Use functions.sh to get configuration variables rather than calling uci Signed-off-by: Aaron Goodman --- net/openfortivpn/files/14-openforticlient | 33 ++++++++++++++--------- net/openfortivpn/files/openfortivpn.sh | 1 - 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/net/openfortivpn/files/14-openforticlient b/net/openfortivpn/files/14-openforticlient index 9cff9bd21..a9a24b18b 100644 --- a/net/openfortivpn/files/14-openforticlient +++ b/net/openfortivpn/files/14-openforticlient @@ -1,20 +1,27 @@ #!/bin/sh +. /lib/functions.sh . /usr/share/libubox/jshn.sh [ "$ACTION" != ifup ] && exit -networks=$(uci show network | sed "s/network.\([^.]*\).proto='openfortivpn'/\1/;t;d") -for i in $networks; do - iface=$(uci get "network.${i}.iface_name") - iface_success=$? - [ $? -eq 0 ] && [ $INTERFACE == "$iface" ] && { - logger -t "openfortivpnhotplug" "$ACTION on $INTERFACE to bring up $i" - load_on_boot=$(uci get network.${i}.auto 2>/dev/null) - [ -n "$load_on_boot" ] && [ "$load_on_boot" -eq 0 ] && continue - json_load "$(ifstatus $i)" +handle_network() +{ + config_get iface $1 iface_name + [ $INTERFACE != "$iface" ] && return + [ $(config_get $1 proto) != "openfortivpn" ] && return + + config_get_bool load_on_boot $1 auto + [ -n "$load_on_boot" ] && [ "$load_on_boot" -eq 0 ] && return + status="$(ifstatus $1)" || continue + json_load "$status" json_get_var autostart autostart + logger -t "openfortivpnhotplug" "$ACTION on $INTERFACE to bring up $1. Autostart is $autostart" [ "$autostart" -eq 0 ] && { - logger -t "openfortivpnhotplug" "auto-start was false. bringing $i up" - ubus call network.interface up "{ \"interface\" : \"$i\" }" + logger -t "openfortivpnhotplug" "auto-start was false. bringing $1 up" + ubus call network.interface up "{ \"interface\" : \"$1\" }" } - } -done +} + + +config_load network +config_foreach handle_network interface +exit 0 diff --git a/net/openfortivpn/files/openfortivpn.sh b/net/openfortivpn/files/openfortivpn.sh index 5599f3150..893510ce8 100755 --- a/net/openfortivpn/files/openfortivpn.sh +++ b/net/openfortivpn/files/openfortivpn.sh @@ -134,7 +134,6 @@ ip-down-script /lib/netifd/ppp-down mru 1354" > $callfile append_args "--pppd-call=openfortivpn/$config" - proto_export INTERFACE="$ifname" logger -p 6 -t openfortivpn "$config: executing 'openfortivpn $cmdline'" eval "proto_run_command '$config' /usr/sbin/openfortivpn-wrapper '$pwfile' '$config' $cmdline" From 7ec4881762b0eabb5fae881237760c999f3ce3f3 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Tue, 21 Jul 2020 02:13:56 -0400 Subject: [PATCH 07/10] openfortivpn: use functions/network.sh to access interface params Signed-off-by: Aaron Goodman --- net/openfortivpn/files/openfortivpn.sh | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/net/openfortivpn/files/openfortivpn.sh b/net/openfortivpn/files/openfortivpn.sh index 893510ce8..8f3f4b235 100755 --- a/net/openfortivpn/files/openfortivpn.sh +++ b/net/openfortivpn/files/openfortivpn.sh @@ -1,5 +1,6 @@ #!/bin/sh . /lib/functions.sh +. /lib/functions/network.sh . ../netifd-proto.sh init_proto "$@" @@ -36,17 +37,14 @@ proto_openfortivpn_setup() { [ -n "$iface_name" ] && { - json_load "$(ifstatus $iface_name)" - json_get_var iface_device_name l3_device - json_get_var iface_device_up up - } - - [ "$iface_device_up" -eq 1 ] || { - msg="$iface_name is not up $iface_device_up" - logger -t "openfortivpn" "$config: $msg" - proto_notify_error "$config" "$msg" - proto_block_restart "$config" - exit 1 + network_get_device iface_device_name "$iface_name" + network_is_up "$iface_name" ] || { + msg="$iface_name is not up $iface_device_up" + logger -t "openfortivpn" "$config: $msg" + proto_notify_error "$config" "$msg" + proto_block_restart "$config" + exit 1 + } } server_ip=$(resolveip -t 10 "$server") From 93af5a19bb21d8d72e6fd97b229657387137d8a0 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Tue, 28 Jul 2020 23:05:13 -0400 Subject: [PATCH 08/10] openfortivpn: add defaultroute option Signed-off-by: Aaron Goodman --- net/openfortivpn/files/openfortivpn.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/net/openfortivpn/files/openfortivpn.sh b/net/openfortivpn/files/openfortivpn.sh index 8f3f4b235..12306d7cf 100755 --- a/net/openfortivpn/files/openfortivpn.sh +++ b/net/openfortivpn/files/openfortivpn.sh @@ -20,18 +20,19 @@ proto_openfortivpn_init_config() { proto_config_add_string "password" proto_config_add_string "trusted_cert" proto_config_add_string "remote_status_check" - proto_config_add_int "peerdns" - proto_config_add_int "metric" + proto_config_add_defaults no_device=1 available=1 } proto_openfortivpn_setup() { - local config="$1" - local msg + local config="$1" + local msg ifname serverip pwfile callfile default_route_arg + local host server port iface_name local_ip username password trusted_cert \ + remote_status_check defaultroute peerdns metric json_get_vars host server port iface_name local_ip username password trusted_cert \ - remote_status_check peerdns metric + remote_status_check defaultroute peerdns metric ifname="vpn-$config" @@ -87,8 +88,8 @@ proto_openfortivpn_setup() { [ -n "$port" ] && port=":$port" - [ -z "$peerdns" ] && peerdns=1 - + [ -z "$peerdns" ] && peerdns=1 + [ "$defaultroute" = 1 ] && defaultroute_arg="defaultroute" || defaultroute_arg=nodefaultroute append_args "$server$port" --pppd-ifname="$ifname" --use-syslog -c /dev/null append_args "--set-dns=0" append_args "--no-routes" @@ -123,7 +124,7 @@ noauth default-asyncmap nopcomp receive-all -defaultroute +$defaultroute_arg nodetach ipparam $config lcp-max-configure 40 From 991147ff430f56f4018c1d62953fc8da56978672 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Thu, 30 Jul 2020 20:45:53 -0400 Subject: [PATCH 09/10] openfortivpn: improve logging Signed-off-by: Aaron Goodman --- net/openfortivpn/files/openfortivpn-wrapper | 2 +- net/openfortivpn/files/openfortivpn.sh | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/net/openfortivpn/files/openfortivpn-wrapper b/net/openfortivpn/files/openfortivpn-wrapper index cbfe64557..1535d3af3 100755 --- a/net/openfortivpn/files/openfortivpn-wrapper +++ b/net/openfortivpn/files/openfortivpn-wrapper @@ -21,7 +21,7 @@ trap_with_arg() { } func_trap() { - logger "openfortivpn-wrapper[$$]" "sending signal ${1}" + logger "openfortivpn-wrapper[$$]" "$config: sending signal ${1}" killed=1 kill -${1} $child 2>/dev/null } diff --git a/net/openfortivpn/files/openfortivpn.sh b/net/openfortivpn/files/openfortivpn.sh index 12306d7cf..fd1267a0b 100755 --- a/net/openfortivpn/files/openfortivpn.sh +++ b/net/openfortivpn/files/openfortivpn.sh @@ -28,7 +28,8 @@ proto_openfortivpn_init_config() { proto_openfortivpn_setup() { local config="$1" - local msg ifname serverip pwfile callfile default_route_arg + local msg ifname ip server_ip pwfile callfile default_route_arg + local host server port iface_name local_ip username password trusted_cert \ remote_status_check defaultroute peerdns metric json_get_vars host server port iface_name local_ip username password trusted_cert \ @@ -38,17 +39,17 @@ proto_openfortivpn_setup() { [ -n "$iface_name" ] && { - network_get_device iface_device_name "$iface_name" - network_is_up "$iface_name" ] || { + network_get_device iface_device_name "$iface_name" + network_is_up "$iface_name" || { msg="$iface_name is not up $iface_device_up" logger -t "openfortivpn" "$config: $msg" proto_notify_error "$config" "$msg" proto_block_restart "$config" exit 1 - } - } + } + } - server_ip=$(resolveip -t 10 "$server") + server_ip=$(resolveip -4 -t 10 "$server") [ $? -eq 0 ] || { msg="$config: failed to resolve server ip for $server" @@ -80,7 +81,7 @@ proto_openfortivpn_setup() { } } - for ip in $(resolveip -t 10 "$server"); do + for ip in $(resolveip -4 -t 10 "$server"); do logger -p 6 -t "openfortivpn" "$config: adding host dependency for $ip on $iface_name at $config" proto_add_host_dependency "$config" "$ip" "$iface_name" done @@ -108,7 +109,7 @@ proto_openfortivpn_setup() { echo "$password" > "$pwfile" } - [ -n "$local_ip" ] || local_ip=192.0.2.1 + [ -n "$local_ip" ] || local_ip=$server_ip [ -e '/etc/ppp/peers' ] || mkdir -p '/etc/ppp/peers' [ -e '/etc/ppp/peers/openfortivpn' ] || { ln -s -T '/var/etc/openfortivpn/peers' '/etc/ppp/peers/openfortivpn' 2> /dev/null @@ -134,7 +135,6 @@ mru 1354" > $callfile append_args "--pppd-call=openfortivpn/$config" logger -p 6 -t openfortivpn "$config: executing 'openfortivpn $cmdline'" - eval "proto_run_command '$config' /usr/sbin/openfortivpn-wrapper '$pwfile' '$config' $cmdline" } From 176f363b5f25b361284714dc9df7af23f7d9d4fb Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Fri, 31 Jul 2020 21:37:06 -0400 Subject: [PATCH 10/10] openfortivpn: remove explicit handling of peerdns and defaultroute netifd is clever enough to handle the peerdns and default route arguments, so we can just let them get passed along, and when ppp-up invokes proto_send_update, netifd will only apply what is needed Signed-off-by: Aaron Goodman --- net/openfortivpn/files/openfortivpn.sh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/net/openfortivpn/files/openfortivpn.sh b/net/openfortivpn/files/openfortivpn.sh index fd1267a0b..30e7b7810 100755 --- a/net/openfortivpn/files/openfortivpn.sh +++ b/net/openfortivpn/files/openfortivpn.sh @@ -20,7 +20,6 @@ proto_openfortivpn_init_config() { proto_config_add_string "password" proto_config_add_string "trusted_cert" proto_config_add_string "remote_status_check" - proto_config_add_defaults no_device=1 available=1 } @@ -28,12 +27,12 @@ proto_openfortivpn_init_config() { proto_openfortivpn_setup() { local config="$1" - local msg ifname ip server_ip pwfile callfile default_route_arg + local msg ifname ip server_ip pwfile callfile local host server port iface_name local_ip username password trusted_cert \ - remote_status_check defaultroute peerdns metric + remote_status_check json_get_vars host server port iface_name local_ip username password trusted_cert \ - remote_status_check defaultroute peerdns metric + remote_status_check ifname="vpn-$config" @@ -89,12 +88,10 @@ proto_openfortivpn_setup() { [ -n "$port" ] && port=":$port" - [ -z "$peerdns" ] && peerdns=1 - [ "$defaultroute" = 1 ] && defaultroute_arg="defaultroute" || defaultroute_arg=nodefaultroute append_args "$server$port" --pppd-ifname="$ifname" --use-syslog -c /dev/null append_args "--set-dns=0" append_args "--no-routes" - append_args "--pppd-use-peerdns=$peerdns" + append_args "--pppd-use-peerdns=1" [ -n "$iface_name" ] && { append_args "--ifname=$iface_device_name" @@ -125,7 +122,6 @@ noauth default-asyncmap nopcomp receive-all -$defaultroute_arg nodetach ipparam $config lcp-max-configure 40