#!/bin/sh /etc/rc.common

START=60

report_log() {
	[ "$#" -gt 0 ] && logger -s -t "webifopenvpn" "$@"
}

append_bool() {
	local section="$1"
	local option="$2"
	local value="$3"
	local _loctmp
	config_get_bool _loctmp "$section" "$option"
	[ "$_loctmp" -gt 0 ] && append args "$value"
}

append_parm() {
	local section="$1"
	local option="$2"
	local switch="$3"
	local default="$4"
	local _loctmp
	config_get _loctmp "$section" "$option"
	[ -z "$_loctmp" ] && _loctmp="$default"
	[ -n "$_loctmp" ] && append args "$switch $_loctmp"
}

file_check() {
	while [ -n "$1" ]; do
		if [ ! -s "$1" ]; then
			report_log "Missing $1. Please generate and try again."
			auth_incomplete=1
		fi
		shift
	done
}

webifopenvpn_config() {
	local cfg="$1"
	local enabled service_mode authentication dir_name
	local ifconfig_local ifconfig_remote ifconfig_ipaddr
	local auth_incomplete args pid

	config_get_bool enabled "$cfg" enabled 0
	[ "$enabled" -eq 1 ] && {
		config_get service_mode "$cfg" mode
		config_get authentication "$cfg" auth
		config_get dir_name "$cfg" dir
		config_get ifconfig_local "$cfg" local
		config_get ifconfig_remote "$cfg" remote
		config_get ifconfig_ipaddr "$cfg" ipaddr

		auth_incomplete=0
		args=""

		case "$authentication" in
			cert)
				file_check "$dir_name/certificate.p12"
				append args "--pkcs12 \"$dir_name/certificate.p12\""
			;;
			psk)
				file_check "$dir_name/shared.key"
				append args "--secret \"$dir_name/shared.key\""
			;;
			pem)
				file_check "$dir_name/ca.crt" "$dir_name/client.crt" "$dir_name/client.key"
				append args "--ca \"$dir_name/ca.crt\" --cert \"$dir_name/client.crt\" --key \"$dir_name/client.key\""
			;;
			*)
				report_log "unknown authentication type, aborting!"
				auth_incomplete=1
			;;
		esac
		[ "$auth_incomplete" != 0 ] && return

		append_parm "$cfg" "proto" "--proto" "udp"
		append_parm "$cfg" "port" "--port" "1194"

		append_parm "$cfg" "dev" "--dev" "tun"
		append_parm "$cfg" "user" "--user" "nobody"
		append_parm "$cfg" "group" "--group" "nogroup"
		append_parm "$cfg" "status" "--status" "/tmp/openvpn-status.log"
		append_parm "$cfg" "verb" "--verb" "1"

		append_bool "$cfg" "complzo" "--comp-lzo"
		append_bool "$cfg" "persisttun" "--persist-tun"
		append_bool "$cfg" "persistkey" "--persist-key"
		append_bool "$cfg" "client_to_client" "--client-to-client"

		append_parm "$cfg" "ping" "--ping"
		append_parm "$cfg" "ping_restart" "--ping-restart"
		pid=$(mktemp /var/run/webifopenvpn.pid.XXXXXX)
		append_parm "$cfg" "write_pid" "--writepid" "\"$pid\""
		append_parm "$cfg" "cmdline" ""
		if [ -n "$ifconfig_local" -a -n "$ifconfig_remote" ]; then
			append args "--ifconfig $ifconfig_local $ifconfig_remote"
		fi

		case "$service_mode" in
			client)
				if [ -z "$ifconfig_ipaddr" ]; then
					report_log "remote server not configured!"
					return
				fi
				append_bool "pull" "--pull"
				if [ "$authentication" = "cert" -o "$authentication" = "pem" ]; then
					append args "--tls-client"
					if [ -s "$dir_name/tlsauth.key" ]; then
						append args "--tls-auth \"$dir_name/tlsauth.key\""
					fi
				fi
				append args "--remote $ifconfig_ipaddr --nobind"
			;;
			server)
				if [ -z "$ifconfig_local" ]; then
					report_log "local VPN endpoint not configured!"
					return
				fi
				if [ -z "$ifconfig_remote" ]; then
					report_log "remote VPN endpoint not configured!"
					return
				fi
				if [ "$authentication" = "cert" -o "$authentication" = "pem" ]; then
					append args "--tls-server"
					if [ -s "$dir_name/dh.pem" ]; then
						append args "--dh \"$dir_name/dh.pem\""
					fi
					if [ -s "$dir_name/tlsauth.key" ]; then
						append args "--tls-auth \"$dir_name/tlsauth.key\""
					fi
				fi
			;;
			*)
				report_log "unknown mode, aborting!"
				return
			;;
		esac
		eval "openvpn --daemon $args"
	}
}

start() {
	config_load webifopenvpn
	config_foreach webifopenvpn_config webifopenvpn
}

stop() {
	for i in $(ls /var/run/webifopenvpn.pid.*); do
		webifopenvpn_pid=$(cat "$i" 2>/dev/null)
		[ -n "$webifopenvpn_pid" ] && [ -d /proc/$webifopenvpn_pid ] && kill -TERM $webifopenvpn_pid 2>/dev/null
		rm -f "$i" 2>/dev/null
	done
}

restart() {
	stop
	sleep 3
	start
}

reload() {
	restart
}
