#!/bin/sh
# Armando Peluso <armando@domotz.com>

if [ -f /etc/domotz.env ]; then
. /etc/domotz.env
fi

env_file="$DOMOTZ_REMOTE_PAWN_DIR"/openvpn/domotzvpn.env

openvpn_version () {
	if ! echo DOMOTZ_VPN_SERVER=$(domotz_openvpn --version | head -1 | cut -d " " -f1,2)
	then
		exit 127;
	else
		exit 0;
	fi
}

if [ "$1" = 'version' ] || [ -z "$1" ]; then
openvpn_version
fi

if [ -f "$env_file" ]; then
	. "$env_file"
else
	echo "File missing $env_file"
	exit 2;
fi

if [ ! -d "$DOMOTZVPN_CONFDIR"/conf ]; then
	mkdir -p "$DOMOTZVPN_CONFDIR"/conf
fi

domotzvpn_stop () {
	if ! kill $(cat "$DOMOTZVPN_CONFDIR"/conf/pid 2> /dev/null) 2> /dev/null
	then
		echo 'DomotzVpn not running'
	else
		echo 'DomotzVpn Stopping...'
		echo > "$DOMOTZVPN_CONFDIR"/conf/pid
	fi
}

domotzvpn_start () {
    if [ ! -e /dev/net/tun ]; then
    	mkdir -p /dev/net
    	mknod /dev/net/tun c 10 200
	fi

	domotz_openvpn --config "$DOMOTZVPN_CONFDIR"/conf/server.conf --daemon --writepid "$DOMOTZVPN_CONFDIR"/conf/pid
}

redirect_gw () {

# Writing the rules in the client file configuration, if the gateway redirect is set to no
sed -i '/^push/d' "$DOMOTZVPN_CONFDIR"/conf/server.conf

if [ "$REDIRECT_GW" = 'yes' ]; then
	route -n | grep 'U ' | awk '{print $1 " " $3}' | while read -r line; do
		echo 'push "route '${line}'"' >> "$DOMOTZVPN_CONFDIR"/conf/server.conf
	done

elif [ "$REDIRECT_GW" = 'no' ]; then
	echo 'push "redirect-gateway def1 bypass-dhcp"' >> "$DOMOTZVPN_CONFDIR"/conf/server.conf

	# DNS
	# Locate the proper resolv.conf
	# Needed for systems running systemd-resolved
	if grep -q "127.0.0.53" "/etc/resolv.conf"; then
		RESOLVCONF='/run/systemd/resolve/resolv.conf'
	elif grep -q "127.0.1.1" "/etc/resolv.conf" && dnsmasq --test && [ -f /etc/resolv.dnsmasq ]; then
		RESOLVCONF='/etc/resolv.dnsmasq'
	else
		RESOLVCONF='/etc/resolv.conf'
	fi
	# Obtain the resolvers from resolv.conf and use them for OpenVPN
    grep -v '#' "$RESOLVCONF" | grep 'nameserver' | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort -u | while read -r line; do
		if [ "$line" != '127.0.0.1' ]; then
			echo "push \"dhcp-option DNS $line\"" >> "$DOMOTZVPN_CONFDIR"/conf/server.conf
		fi
	done
fi

}

iptables_rules () {
if [ $DPLATFORM = 'netgear_router' ] && [ $DARCHITECTURE = 'ipq95xx' ]; then
	cp $DOMOTZ_REMOTE_PAWN_DIR/openvpn/iptables/netgear_router.rules $DOMOTZVPN_CONFDIR/conf/iptables.rules
else
        cp $DOMOTZ_REMOTE_PAWN_DIR/openvpn/iptables/iptables.rules $DOMOTZVPN_CONFDIR/conf/iptables.rules
fi
}

newclient () {
	domotzvpn_stop

	revoke  "$CLIENT"
	cd "$DOMOTZVPN_CONFDIR" || exit 2

	# Create the client certificates
	if [ $DPLATFORM == "netgear_router" ] && [ $DARCHITECTURE == "ipq95xx" ]; then
			echo yes | domotz_easyrsa --days=1 build-client-full "$CLIENT" nopass
	else
			domotz_easyrsa --days=1 build-client-full "$CLIENT" nopass
	fi


	# Generates the custom newclient.ovpn
	cp "$DOMOTZVPN_CONFDIR"/conf/client-common.txt "$DOMOTZVPN_CONFDIR"/"$1".ovpn

    redirect_gw

	{
		echo "remote $DOMOTZVPN_PUBLIC_DOMAIN $DOMOTZVPN_PUBLIC_PORT"
		echo "<ca>"
		cat "$EASYRSA_PKI"/ca.crt
		echo "</ca>"
		echo "<cert>"
		sed -ne '/BEGIN CERTIFICATE/,$ p' "$EASYRSA_PKI"/issued/"$1".crt
		echo "</cert>"
		echo "<key>"
		cat "$EASYRSA_PKI"/private/"$1".key
		echo "</key>"
		echo "<tls-auth>"
		sed -ne '/BEGIN OpenVPN Static key/,$ p' "$DOMOTZVPN_CONFDIR"/pki/ta.key
		echo "</tls-auth>"
	} >> "$DOMOTZVPN_CONFDIR"/"$1".ovpn
	# Enable net.ipv4.ip_forward for the system
	echo 1 > /proc/sys/net/ipv4/ip_forward

	modprobe tun 2> /dev/null

	if ! grep 'version 0.5' "$DOMOTZVPN_CONFDIR"/conf/iptables.rules > /dev/null
	then
		iptables_rules
	fi

	. "$DOMOTZVPN_CONFDIR"/conf/iptables.rules

    domotzvpn_start
}

revoke () {
	NUMBEROFCLIENTS=$(tail -n +2 "$EASYRSA_PKI"/index.txt | grep -c "^V")
	if [ "$NUMBEROFCLIENTS" = '0' ]; then
		echo
		echo "You have no existing clients!"
		fi
		cd "$DOMOTZVPN_CONFDIR" || exit 2
		domotz_easyrsa --batch revoke "$1"
		EASYRSA_CRL_DAYS=3650 domotz_easyrsa gen-crl
		rm -f pki/reqs/"$1".req
		rm -f pki/private/"$1".key
		rm -f pki/issued/"$1".crt
		touch pki/crl.pem
		# CRL is read with each client connection, when OpenVPN is dropped to "$DOMOTZVPN_SYSTEM_USERNAME"
		chown "$DOMOTZVPN_SYSTEM_USERNAME":"$DOMOTZVPN_SYSTEM_GROUPNAME" "$EASYRSA_PKI"/crl.pem
	}


reconf () {
	cd "$DOMOTZVPN_CONFDIR" || exit 2

	# Create the PKI, set up the CA and the server certificates
	rm -rf "$EASYRSA_PKI"
	domotz_easyrsa init-pki
	domotz_easyrsa --batch build-ca nopass
	if [ $DPLATFORM == "netgear_router" ] && [ $DARCHITECTURE == "ipq95xx" ]; then
			echo yes | EASYRSA_CERT_EXPIRE=3650 domotz_easyrsa build-server-full server nopass
	else
			EASYRSA_CERT_EXPIRE=3650 domotz_easyrsa build-server-full server nopass
	fi
	#EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full $CLIENT nopass
	EASYRSA_CRL_DAYS=3650 domotz_easyrsa gen-crl

	# CRL is read with each client connection, when OpenVPN is dropped to "$DOMOTZVPN_USERNAME"
	chown "$DOMOTZVPN_SYSTEM_USERNAME":"$DOMOTZVPN_SYSTEM_GROUPNAME" "$EASYRSA_PKI"/crl.pem

	# Generate key for tls-auth
	domotz_openvpn --genkey --secret "$DOMOTZVPN_CONFDIR"/pki/ta.key

	# Create the DH parameters file using the 2ton.com.au
	domotz_curl --connect-timeout 3 -k -s https://2ton.com.au/getprimes/random/dhparam/2048 > "$DOMOTZVPN_CONFDIR"/pki/dh.pem
	if ! domotz_openssl dhparam -inform PEM -in "$DOMOTZVPN_CONFDIR"/pki/dh.pem -check -text
		then
		# Create the DH parameters file using the predefined dh2048 key
		echo "So create the DH parameters file using the predefined dh2048 key"
		echo '-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEAwVJJW0cxiItYVKfh/ParQJhD7ucW3KV+XVuUtcX+p/4C25mjg8hM
KbfXLcMzT2cVW6ZtSftSRxQB45OVY5K67IK1VR/z6nntbYvLA4Fr3nC82ZXidO/S
/o73egcdgEvvRqJ2jiBTDPx/bnZ0ySAuLNRmNyXcZKnwOyL3MLuJtP9i640DV7SK
HCjGQGI5hTBLIsq6BoLZJ8jwIdnWTrhRuuivqKD0tBC0WnY+tt1w7jr+zn3OoktH
02JZHOfvlTNlnekZ7ax++xLT9cSKy4VKgVWsLR9MnAXLH1BLcLyYOAF0qXMNk9h1
IEXKFt+PGulcB3fwk69VgZv7+gw9sQ1ZuwIBAg==
-----END DH PARAMETERS-----' > "$DOMOTZVPN_CONFDIR"/pki/dh.pem
	fi

	# Generate server.conf
	echo "local 127.0.0.1
port $PORT
proto $PROTOCOL
dev tun
sndbuf 0
rcvbuf 0
ca $DOMOTZVPN_CONFDIR/pki/ca.crt
cert $DOMOTZVPN_CONFDIR/pki/issued/server.crt
key $DOMOTZVPN_CONFDIR/pki/private/server.key
dh $DOMOTZVPN_CONFDIR/pki/dh.pem
auth SHA512
tls-auth $DOMOTZVPN_CONFDIR/pki/ta.key 0
topology subnet
max-clients 1
server $DOMOTZVPN_NETWORK 255.255.255.0
ifconfig-pool-persist $DOMOTZVPN_CONFDIR/conf/ipp.txt 300" > "$DOMOTZVPN_CONFDIR"/conf/server.conf


	echo "keepalive 10 60
cipher AES-256-CBC
persist-key
persist-tun
;status openvpn-status.log
verb 3
mute 1
crl-verify $EASYRSA_PKI/crl.pem" >> "$DOMOTZVPN_CONFDIR"/conf/server.conf

	if [ -n "$DOMOTZVPN_SYSTEM_GROUPNAME" ]; then
		echo "group $DOMOTZVPN_SYSTEM_GROUPNAME" >> "$DOMOTZVPN_CONFDIR"/conf/server.conf
	fi
	echo "user $DOMOTZVPN_SYSTEM_USERNAME" >> "$DOMOTZVPN_CONFDIR"/conf/server.conf

	if [ -n "$DOMOTZVPN_ROUTE_RULES" ]; then
		echo "$DOMOTZVPN_ROUTE_RULES" >> "$DOMOTZVPN_CONFDIR"/conf/server.conf
	fi

    iptables_rules

	# client-common.txt is created so we have a template to add further users later
	echo "client
dev tun
proto $PROTOCOL
sndbuf 0
rcvbuf 0
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA512
cipher AES-256-CBC
setenv opt block-outside-dns
key-direction 1
keepalive 10 60
verb 3" > "$DOMOTZVPN_CONFDIR"/conf/client-common.txt
}

if [ -e "$DOMOTZVPN_CONFDIR"/conf/server.conf ]; then
	while :
	do
		option="$1:$2"
		case $option in
			newclient:'')
			newclient "$CLIENT"
			exit 0;
			;;
			newclient:no-redirect-gw)
			REDIRECT_GW='yes'
			newclient "$CLIENT"
			exit 0;
			;;
			revoke:'')
			revoke "$CLIENT"
			exit 0;
			;;
			force-reconf:'')
			reconf
			exit 0;
			;;
			stop:'')
			domotzvpn_stop
			exit 0;
			;;
			start:'')
			if ! ps axo pid= | grep -v grep | grep -w $(cat "$DOMOTZVPN_CONFDIR"/conf/pid) 2> /dev/null 1>&2; then
				echo "DomotzVpn starting..."
				domotzvpn_start
				sleep .5
				if ps axo pid= | grep -v grep | grep -w $(cat "$DOMOTZVPN_CONFDIR"/conf/pid) > /dev/null; then
					echo "DomotzVpn has been started! ($(cat "$DOMOTZVPN_CONFDIR"/conf/pid))"
				else
					echo "Oops... Unable to start DomotzVPN!"
				fi
			else
				echo "DomotzVpn is already started! ($(cat "$DOMOTZVPN_CONFDIR"/conf/pid))"
			fi
			exit
			;;
			*)
			exit 0;
			;;
		esac
	done
else
# Generate server.conf
reconf
# Generates the custom newclient.ovpn
if [ "$1" != 'reconf' ]; then
	newclient "$CLIENT"
else
	exit;
fi
fi