diff options
Diffstat (limited to 'pkg/helper/args.go')
-rw-r--r-- | pkg/helper/args.go | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/pkg/helper/args.go b/pkg/helper/args.go new file mode 100644 index 0000000..d6b3bb4 --- /dev/null +++ b/pkg/helper/args.go @@ -0,0 +1,103 @@ +package helper + +import ( + "log" + "net" + "os" + "regexp" + "strconv" +) + +const ( + // TODO: this is the nameserver for tcp, but for udp is 10.42.0.1 + // the nameserver pick up should be dependent on the proto being used + nameserver = "10.41.0.1" +) + +var ( + fixedArgs = []string{ + "--nobind", + "--client", + "--dev", "tun", + "--tls-client", + "--remote-cert-tls", "server", + "--dhcp-option", "DNS", nameserver, + "--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 + newArgs = append(newArgs, platformOpenvpnFlags...) + 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() +} |