1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
package helper
import (
"log"
"net"
"os"
"regexp"
"strconv"
"path/filepath"
)
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,
"--tls-version-min", "1.0",
"--log", filepath.Join(LogFolder, "openvpn-leap.log"),
}
allowedArgs = 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, getPlatformOpenvpnFlags()...)
for i := 0; i < len(args); i++ {
params, ok := allowedArgs[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()
}
|