summaryrefslogtreecommitdiff
path: root/helper/args.go
diff options
context:
space:
mode:
Diffstat (limited to 'helper/args.go')
-rw-r--r--helper/args.go104
1 files changed, 104 insertions, 0 deletions
diff --git a/helper/args.go b/helper/args.go
new file mode 100644
index 0000000..5651cb4
--- /dev/null
+++ b/helper/args.go
@@ -0,0 +1,104 @@
+package main
+
+import (
+ "log"
+ "net"
+ "os"
+ "regexp"
+ "strconv"
+)
+
+const (
+ openvpnUser = "nobody"
+ openvpnGroup = "nobody"
+ nameserver = "10.42.0.1"
+)
+
+var (
+ fixedArgs = []string{
+ "--nobind",
+ "--client",
+ "--dev", "tun",
+ "--tls-client",
+ "--remote-cert-tls", "server",
+ "--dhcp-option", "DNS", nameserver,
+ "--user", openvpnUser,
+ "--group", openvpnGroup,
+ "--log", logFolder + "openvpn.log",
+ }
+
+ allowendArgs = map[string][]string{
+ "--remote": []string{"IP", "NUMBER", "PROTO"},
+ "--tls-cipher": []string{"CIPHER"},
+ "--cipher": []string{"CIPHER"},
+ "--auth": []string{"CIPHER"},
+ "--management-client": []string{},
+ "--management": []string{"IP", "NUMBER"},
+ "--cert": []string{"FILE"},
+ "--key": []string{"FILE"},
+ "--ca": []string{"FILE"},
+ "--fragment": []string{"NUMBER"},
+ "--keepalive": []string{"NUMBER", "NUMBER"},
+ "--verb": []string{"NUMBER"},
+ "--tun-ipv6": []string{},
+ }
+
+ cipher = regexp.MustCompile("^[A-Z0-9-]+$")
+ formats = map[string]func(s string) bool{
+ "NUMBER": isNumber,
+ "PROTO": isProto,
+ "IP": isIP,
+ "CIPHER": cipher.MatchString,
+ "FILE": isFile,
+ }
+)
+
+func parseOpenvpnArgs(args []string) []string {
+ newArgs := fixedArgs
+ for i := 0; i < len(args); i++ {
+ params, ok := allowendArgs[args[i]]
+ if !ok {
+ log.Printf("Invalid openvpn arg: %s", args[i])
+ continue
+ }
+ for j, arg := range args[i+1 : i+len(params)+1] {
+ if !formats[params[j]](arg) {
+ ok = false
+ break
+ }
+ }
+ if ok {
+ newArgs = append(newArgs, args[i:i+len(params)+1]...)
+ i = i + len(params)
+ } else {
+ log.Printf("Invalid openvpn arg params: %v", args[i:i+len(params)+1])
+ }
+ }
+ return newArgs
+}
+
+func isNumber(s string) bool {
+ _, err := strconv.Atoi(s)
+ return err == nil
+}
+
+func isProto(s string) bool {
+ for _, proto := range []string{"tcp", "udp", "tcp4", "udp4", "tcp6", "udp6"} {
+ if s == proto {
+ return true
+ }
+ }
+ return false
+}
+
+func isIP(s string) bool {
+ return net.ParseIP(s) != nil
+}
+
+func isFile(s string) bool {
+ info, err := os.Stat(s)
+ if err != nil {
+ return false
+ }
+ return !info.IsDir()
+}