From 52206cc7dda3d12d92dad3181e27b680c70e69e3 Mon Sep 17 00:00:00 2001
From: "kali kaneko (leap communications)" <kali@leap.se>
Date: Tue, 30 Nov 2021 18:49:00 +0100
Subject: [PATCH] [feat] udp nameservers

---
 pkg/helper/darwin.go  | 17 +++++++++++------
 pkg/helper/helper.go  |  8 +++++++-
 pkg/helper/linux.go   |  4 ++--
 pkg/helper/windows.go | 11 ++++-------
 pkg/vpn/launcher.go   |  7 ++++++-
 pkg/vpn/openvpn.go    |  7 +++++--
 6 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/pkg/helper/darwin.go b/pkg/helper/darwin.go
index 7269981c..a9f8e00a 100644
--- a/pkg/helper/darwin.go
+++ b/pkg/helper/darwin.go
@@ -29,11 +29,11 @@ package helper
 import (
 	"errors"
 	"fmt"
-	"path/filepath"
 	"log"
 	"os"
 	"os/exec"
 	"path"
+	"path/filepath"
 	"strconv"
 	"strings"
 
@@ -43,8 +43,8 @@ import (
 const (
 	bitmask_anchor = "com.apple/250.BitmaskFirewall"
 	gateways_table = "bitmask_gateways"
-	pfctl = "/sbin/pfctl"
-	LogFolder = "/var/log/"
+	pfctl          = "/sbin/pfctl"
+	LogFolder      = "/var/log/"
 )
 
 func _getExecPath() string {
@@ -119,9 +119,9 @@ func kill(cmd *exec.Cmd) error {
 	return nil
 }
 
-func firewallStart(gateways []string) error {
+func firewallStart(gateways []string, mode string) error {
 	enablePf()
-	err := resetGatewaysTable(gateways)
+	err := resetGatewaysTable(gateways, mode)
 	if err != nil {
 		return err
 	}
@@ -155,7 +155,7 @@ func enablePf() {
 	cmd.Run()
 }
 
-func resetGatewaysTable(gateways []string) error {
+func resetGatewaysTable(gateways []string, mode string) error {
 	log.Println("Resetting gateways")
 	cmd := exec.Command(pfctl, "-a", bitmask_anchor, "-t", gateways_table, "-T", "delete")
 	err := cmd.Run()
@@ -172,6 +172,11 @@ func resetGatewaysTable(gateways []string) error {
 		}
 	}
 
+	nameserver := nameserverTCP
+	if mode == "udp" {
+		nameserver = nameserverUDP
+	}
+
 	cmd = exec.Command(pfctl, "-a", bitmask_anchor, "-t", gateways_table, "-T", "add", nameserver)
 	return cmd.Run()
 
diff --git a/pkg/helper/helper.go b/pkg/helper/helper.go
index d23cefd6..7b6643be 100644
--- a/pkg/helper/helper.go
+++ b/pkg/helper/helper.go
@@ -122,6 +122,12 @@ func (openvpn *openvpnT) kill() error {
 }
 
 func firewallStartHandler(w http.ResponseWriter, r *http.Request) {
+	mode := "tcp"
+	query := r.URL.Query()
+	udp, udpParam := query["udp"]
+	if udpParam && len(udp) == 1 && udp[0] == "1" {
+		mode = "udp"
+	}
 	gateways, err := getArgs(r)
 	if err != nil {
 		log.Printf("An error has occurred processing gateways: %v", err)
@@ -135,7 +141,7 @@ func firewallStartHandler(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 
-	err = firewallStart(gateways)
+	err = firewallStart(gateways, mode)
 	if err != nil {
 		log.Printf("Error starting firewall: %v", err)
 		w.Write([]byte(err.Error()))
diff --git a/pkg/helper/linux.go b/pkg/helper/linux.go
index d6f30f2f..57fbdd98 100644
--- a/pkg/helper/linux.go
+++ b/pkg/helper/linux.go
@@ -33,7 +33,7 @@ const (
 )
 
 var (
-	snapOpenvpnPath      = "/snap/bin/" + config.BinaryName + ".openvpn"
+	snapOpenvpnPath = "/snap/bin/" + config.BinaryName + ".openvpn"
 )
 
 func getPlatformOpenvpnFlags() []string {
@@ -68,7 +68,7 @@ func kill(cmd *exec.Cmd) error {
 	return cmd.Process.Signal(os.Interrupt)
 }
 
-func firewallStart(gateways []string) error {
+func firewallStart(gateways []string, mode string) error {
 	log.Println("Start firewall: do nothing, not implemented")
 	return nil
 }
diff --git a/pkg/helper/windows.go b/pkg/helper/windows.go
index 43436ad3..ca1642e1 100644
--- a/pkg/helper/windows.go
+++ b/pkg/helper/windows.go
@@ -21,25 +21,23 @@ import (
 	"log"
 	"os"
 	"os/exec"
+	"path"
 	"strconv"
 	"strings"
-	"path"
 
 	"golang.org/x/sys/windows"
 	"golang.org/x/sys/windows/svc"
 )
 
-
-
 var (
-	svcName          = BinaryName + `-helper-v2`
+	svcName = BinaryName + `-helper-v2`
 
 	// XXX this is set to c:\WINDOWS\system32 on initialization. Do not use it, use a function call instead.
 	appPath          = getExecDir()
 	LogFolder        = getExecDir()
 	openvpnPath      = path.Join(appPath, "openvpn.exe")
 	chocoOpenvpnPath = `C:\Program Files\OpenVPN\bin\openvpn.exe`
-	httpServerConf = &httpConf{}
+	httpServerConf   = &httpConf{}
 )
 
 func getPlatformOpenvpnFlags() []string {
@@ -63,7 +61,6 @@ type httpConf struct {
 	BindAddr string
 }
 
-
 // parseCliArgs allows the helper binary to install/uninstall itself. It requires admin privileges.
 // However, be warned: if you intend to use it from the command line, you will have to compile it with the Go compiler yourself.
 // the version we're shipping (ie, cross-compiled with the mingw compiler) apparently is not able to output to stdout/stderr properly.
@@ -154,7 +151,7 @@ func kill(cmd *exec.Cmd) error {
 	return cmd.Process.Kill()
 }
 
-func firewallStart(gateways []string) error {
+func firewallStart(gateways []string, mode string) error {
 	log.Println("Start firewall: do nothing, not implemented")
 	return nil
 }
diff --git a/pkg/vpn/launcher.go b/pkg/vpn/launcher.go
index 1b2d6735..f6e08eb9 100644
--- a/pkg/vpn/launcher.go
+++ b/pkg/vpn/launcher.go
@@ -24,6 +24,7 @@ import (
 	"io/ioutil"
 	"log"
 	"net/http"
+	"os"
 	"strconv"
 	"strings"
 	"time"
@@ -115,7 +116,11 @@ func (l *launcher) firewallStart(gateways []bonafide.Gateway) error {
 	if err != nil {
 		return err
 	}
-	return l.send("/firewall/start", byteIPs)
+	uri := "/firewall/start"
+	if os.Getenv("UDP") == "1" {
+		uri = uri + "?udp=1"
+	}
+	return l.send(uri, byteIPs)
 }
 
 func (l *launcher) firewallStop() error {
diff --git a/pkg/vpn/openvpn.go b/pkg/vpn/openvpn.go
index d4e6330c..e110d453 100644
--- a/pkg/vpn/openvpn.go
+++ b/pkg/vpn/openvpn.go
@@ -155,6 +155,11 @@ func (b *Bitmask) startOpenVPN() error {
 		if err != nil {
 			return err
 		}
+		if b.udp {
+			os.Setenv("UDP", "1")
+		} else {
+			os.Setenv("UDP", "0")
+		}
 		err = b.launch.firewallStart(gateways)
 		if err != nil {
 			return err
@@ -164,10 +169,8 @@ func (b *Bitmask) startOpenVPN() error {
 			for _, port := range gw.Ports {
 				if port != "53" {
 					if b.udp {
-						os.Setenv("UDP", "1")
 						arg = append(arg, "--remote", gw.IPAddress, port, "udp4")
 					} else {
-						os.Setenv("UDP", "0")
 						arg = append(arg, "--remote", gw.IPAddress, port, "tcp4")
 					}
 				}
-- 
GitLab