656 lines
22 KiB
Plaintext
656 lines
22 KiB
Plaintext
|
(* OpenVPN module for Augeas
|
||
|
Author: Raphael Pinson <raphink@gmail.com>
|
||
|
Author: Justin Akers <dafugg@gmail.com>
|
||
|
|
||
|
Reference: http://openvpn.net/index.php/documentation/howto.html
|
||
|
Reference: https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
|
||
|
|
||
|
TODO: Inline file support
|
||
|
*)
|
||
|
|
||
|
|
||
|
module OpenVPN =
|
||
|
autoload xfm
|
||
|
|
||
|
(************************************************************************
|
||
|
* USEFUL PRIMITIVES
|
||
|
*************************************************************************)
|
||
|
|
||
|
let eol = Util.eol
|
||
|
let indent = Util.indent
|
||
|
|
||
|
(* Define separators *)
|
||
|
let sep = Util.del_ws_spc
|
||
|
|
||
|
(* Define value regexps.
|
||
|
Custom simplified ipv6 used instead of Rx.ipv6 as the augeas Travis instances
|
||
|
are limited to 2GB of memory. Using 'ipv6_re = Rx.ipv6' consumes an extra
|
||
|
2GB of memory and thus the test is OOM-killed.
|
||
|
*)
|
||
|
let ipv6_re = /[0-9A-Fa-f:]+/
|
||
|
let ipv4_re = Rx.ipv4
|
||
|
let ip_re = ipv4_re|ipv6_re
|
||
|
let num_re = Rx.integer
|
||
|
let fn_re = /[^#; \t\n][^#;\n]*[^#; \t\n]|[^#; \t\n]/
|
||
|
let fn_safe_re = /[^#; \t\r\n]+/
|
||
|
let an_re = /[a-z][a-z0-9_-]*/
|
||
|
let hn_re = Rx.hostname
|
||
|
let port_re = /[0-9]+/
|
||
|
let host_re = ip_re|hn_re
|
||
|
let proto_re = /(tcp|udp)/
|
||
|
let proto_ext_re = /(udp|tcp-client|tcp-server)/
|
||
|
let alg_re = /(none|[A-Za-z][A-Za-z0-9-]+)/
|
||
|
let ipv6_bits_re = ipv6_re . /\/[0-9]+/
|
||
|
|
||
|
(* Define store aliases *)
|
||
|
let ip = store ip_re
|
||
|
let num = store num_re
|
||
|
let filename = store fn_re
|
||
|
let filename_safe = store fn_safe_re
|
||
|
let hostname = store hn_re
|
||
|
let sto_to_dquote = store /[^"\n]+/ (* " Emacs, relax *)
|
||
|
let port = store port_re
|
||
|
let host = store host_re
|
||
|
let proto = store proto_re
|
||
|
let proto_ext = store proto_ext_re
|
||
|
|
||
|
(* define comments and empty lines *)
|
||
|
let comment = Util.comment_generic /[ \t]*[;#][ \t]*/ "# "
|
||
|
let comment_or_eol = eol | Util.comment_generic /[ \t]*[;#][ \t]*/ " # "
|
||
|
|
||
|
let empty = Util.empty
|
||
|
|
||
|
|
||
|
(************************************************************************
|
||
|
* SINGLE VALUES
|
||
|
*
|
||
|
* - local => IP|hostname
|
||
|
* - port => num
|
||
|
* - proto => udp|tcp-client|tcp-server
|
||
|
* - proto-force => udp|tcp
|
||
|
* - mode => p2p|server
|
||
|
* - dev => (tun|tap)\d*
|
||
|
* - dev-node => filename
|
||
|
* - ca => filename
|
||
|
* - config => filename
|
||
|
* - cert => filename
|
||
|
* - key => filename
|
||
|
* - dh => filename
|
||
|
* - ifconfig-pool-persist => filename
|
||
|
* - learn-address => filename
|
||
|
* - cipher => [A-Z0-9-]+
|
||
|
* - max-clients => num
|
||
|
* - user => alphanum
|
||
|
* - group => alphanum
|
||
|
* - status => filename
|
||
|
* - log => filename
|
||
|
* - log-append => filename
|
||
|
* - client-config-dir => filename
|
||
|
* - verb => num
|
||
|
* - mute => num
|
||
|
* - fragment => num
|
||
|
* - mssfix => num
|
||
|
* - connect-retry num
|
||
|
* - connect-retry-max num
|
||
|
* - connect-timeout num
|
||
|
* - http-proxy-timeout num
|
||
|
* - max-routes num
|
||
|
* - ns-cert-type => "server"
|
||
|
* - resolv-retry => "infinite"
|
||
|
* - script-security => [0-3] (execve|system)?
|
||
|
* - ipchange => command
|
||
|
* - topology => type
|
||
|
*************************************************************************)
|
||
|
|
||
|
let single_host = "local" | "tls-remote"
|
||
|
let single_ip = "lladdr"
|
||
|
let single_ipv6_bits = "iroute-ipv6"
|
||
|
| "server-ipv6"
|
||
|
| "ifconfig-ipv6-pool"
|
||
|
let single_num = "port"
|
||
|
| "max-clients"
|
||
|
| "verb"
|
||
|
| "mute"
|
||
|
| "fragment"
|
||
|
| "mssfix"
|
||
|
| "connect-retry"
|
||
|
| "connect-retry-max"
|
||
|
| "connect-timeout"
|
||
|
| "http-proxy-timeout"
|
||
|
| "resolv-retry"
|
||
|
| "lport"
|
||
|
| "rport"
|
||
|
| "max-routes"
|
||
|
| "max-routes-per-client"
|
||
|
| "route-metric"
|
||
|
| "tun-mtu"
|
||
|
| "tun-mtu-extra"
|
||
|
| "shaper"
|
||
|
| "ping"
|
||
|
| "ping-exit"
|
||
|
| "ping-restart"
|
||
|
| "sndbuf"
|
||
|
| "rcvbuf"
|
||
|
| "txqueuelen"
|
||
|
| "link-mtu"
|
||
|
| "nice"
|
||
|
| "management-log-cache"
|
||
|
| "bcast-buffers"
|
||
|
| "tcp-queue-limit"
|
||
|
| "server-poll-timeout"
|
||
|
| "keysize"
|
||
|
| "pkcs11-pin-cache"
|
||
|
| "tls-timeout"
|
||
|
| "reneg-bytes"
|
||
|
| "reneg-pkts"
|
||
|
| "reneg-sec"
|
||
|
| "hand-window"
|
||
|
| "tran-window"
|
||
|
let single_fn = "ca"
|
||
|
| "cert"
|
||
|
| "extra-certs"
|
||
|
| "config"
|
||
|
| "key"
|
||
|
| "dh"
|
||
|
| "log"
|
||
|
| "log-append"
|
||
|
| "client-config-dir"
|
||
|
| "dev-node"
|
||
|
| "cd"
|
||
|
| "chroot"
|
||
|
| "writepid"
|
||
|
| "client-config-dir"
|
||
|
| "tmp-dir"
|
||
|
| "replay-persist"
|
||
|
| "ca"
|
||
|
| "capath"
|
||
|
| "pkcs12"
|
||
|
| "pkcs11-id"
|
||
|
| "askpass"
|
||
|
| "tls-export-cert"
|
||
|
| "x509-track"
|
||
|
let single_an = "user"
|
||
|
| "group"
|
||
|
| "management-client-user"
|
||
|
| "management-client-group"
|
||
|
let single_cmd = "ipchange"
|
||
|
| "iproute"
|
||
|
| "route-up"
|
||
|
| "route-pre-down"
|
||
|
| "mark"
|
||
|
| "up"
|
||
|
| "down"
|
||
|
| "setcon"
|
||
|
| "echo"
|
||
|
| "client-connect"
|
||
|
| "client-disconnect"
|
||
|
| "learn-address"
|
||
|
| "tls-verify"
|
||
|
|
||
|
let single_entry (kw:regexp) (re:regexp)
|
||
|
= [ key kw . sep . store re . comment_or_eol ]
|
||
|
|
||
|
let single_opt_entry (kw:regexp) (re:regexp)
|
||
|
= [ key kw . (sep . store re)? .comment_or_eol ]
|
||
|
|
||
|
let single = single_entry single_num num_re
|
||
|
| single_entry single_fn fn_re
|
||
|
| single_entry single_an an_re
|
||
|
| single_entry single_host host_re
|
||
|
| single_entry single_ip ip_re
|
||
|
| single_entry single_ipv6_bits ipv6_bits_re
|
||
|
| single_entry single_cmd fn_re
|
||
|
| single_entry "proto" proto_ext_re
|
||
|
| single_entry "proto-force" proto_re
|
||
|
| single_entry "mode" /(p2p|server)/
|
||
|
| single_entry "dev" /(tun|tap)[0-9]*|null/
|
||
|
| single_entry "dev-type" /(tun|tap)/
|
||
|
| single_entry "topology" /(net30|p2p|subnet)/
|
||
|
| single_entry "cipher" alg_re
|
||
|
| single_entry "auth" alg_re
|
||
|
| single_entry "resolv-retry" "infinite"
|
||
|
| single_entry "script-security" /[0-3]( execve| system)?/
|
||
|
| single_entry "route-gateway" (host_re|/dhcp/)
|
||
|
| single_entry "mtu-disc" /(no|maybe|yes)/
|
||
|
| single_entry "remap-usr1" /SIG(HUP|TERM)/
|
||
|
| single_entry "socket-flags" /(TCP_NODELAY)/
|
||
|
| single_entry "auth-retry" /(none|nointeract|interact)/
|
||
|
| single_entry "tls-version-max" Rx.decimal
|
||
|
| single_entry "verify-hash" /([A-Za-z0-9]{2}:)+[A-Za-z0-9]{2}/
|
||
|
| single_entry "pkcs11-cert-private" /[01]/
|
||
|
| single_entry "pkcs11-protected-authentication" /[01]/
|
||
|
| single_entry "pkcs11-private-mode" /[A-Za-z0-9]+/
|
||
|
| single_entry "key-method" /[12]/
|
||
|
| single_entry "ns-cert-type" /(client|server)/
|
||
|
| single_entry "remote-cert-tls" /(client|server)/
|
||
|
|
||
|
let single_opt = single_opt_entry "comp-lzo" /(yes|no|adaptive)/
|
||
|
| single_opt_entry "syslog" fn_re
|
||
|
| single_opt_entry "daemon" fn_re
|
||
|
| single_opt_entry "auth-user-pass" fn_re
|
||
|
| single_opt_entry "explicit-exit-notify" num_re
|
||
|
| single_opt_entry "engine" fn_re
|
||
|
|
||
|
(************************************************************************
|
||
|
* DOUBLE VALUES
|
||
|
*************************************************************************)
|
||
|
|
||
|
let double_entry (kw:regexp) (a:string) (aval:regexp) (b:string) (bval:regexp)
|
||
|
= [ key kw
|
||
|
. sep . [ label a . store aval ]
|
||
|
. sep . [ label b . store bval ]
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let double_secopt_entry (kw:regexp) (a:string) (aval:regexp) (b:string) (bval:regexp)
|
||
|
= [ key kw
|
||
|
. sep . [ label a . store aval ]
|
||
|
. (sep . [ label b . store bval ])?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
|
||
|
let double = double_entry "keepalive" "ping" num_re "timeout" num_re
|
||
|
| double_entry "hash-size" "real" num_re "virtual" num_re
|
||
|
| double_entry "ifconfig" "local" ip_re "remote" ip_re
|
||
|
| double_entry "connect-freq" "num" num_re "sec" num_re
|
||
|
| double_entry "verify-x509-name" "name" hn_re "type"
|
||
|
/(subject|name|name-prefix)/
|
||
|
| double_entry "ifconfig-ipv6" "address" ipv6_bits_re "remote" ipv6_re
|
||
|
| double_entry "ifconfig-ipv6-push" "address" ipv6_bits_re "remote" ipv6_re
|
||
|
| double_secopt_entry "iroute" "local" ip_re "netmask" ip_re
|
||
|
| double_secopt_entry "stale-routes-check" "age" num_re "interval" num_re
|
||
|
| double_secopt_entry "ifconfig-pool-persist"
|
||
|
"file" fn_safe_re "seconds" num_re
|
||
|
| double_secopt_entry "secret" "file" fn_safe_re "direction" /[01]/
|
||
|
| double_secopt_entry "prng" "algorithm" alg_re "nsl" num_re
|
||
|
| double_secopt_entry "replay-window" "window-size" num_re "seconds" num_re
|
||
|
|
||
|
|
||
|
(************************************************************************
|
||
|
* FLAGS
|
||
|
*************************************************************************)
|
||
|
|
||
|
let flag_words = "client-to-client"
|
||
|
| "duplicate-cn"
|
||
|
| "persist-key"
|
||
|
| "persist-tun"
|
||
|
| "client"
|
||
|
| "remote-random"
|
||
|
| "nobind"
|
||
|
| "mute-replay-warnings"
|
||
|
| "http-proxy-retry"
|
||
|
| "socks-proxy-retry"
|
||
|
| "remote-random-hostname"
|
||
|
| "show-proxy-settings"
|
||
|
| "float"
|
||
|
| "bind"
|
||
|
| "nobind"
|
||
|
| "tun-ipv6"
|
||
|
| "ifconfig-noexec"
|
||
|
| "ifconfig-nowarn"
|
||
|
| "route-noexec"
|
||
|
| "route-nopull"
|
||
|
| "allow-pull-fqdn"
|
||
|
| "mtu-test"
|
||
|
| "ping-timer-rem"
|
||
|
| "persist-tun"
|
||
|
| "persist-local-ip"
|
||
|
| "persist-remote-ip"
|
||
|
| "mlock"
|
||
|
| "up-delay"
|
||
|
| "down-pre"
|
||
|
| "up-restart"
|
||
|
| "disable-occ"
|
||
|
| "errors-to-stderr"
|
||
|
| "passtos"
|
||
|
| "suppress-timestamps"
|
||
|
| "fast-io"
|
||
|
| "multihome"
|
||
|
| "comp-noadapt"
|
||
|
| "management-client"
|
||
|
| "management-query-passwords"
|
||
|
| "management-query-proxy"
|
||
|
| "management-query-remote"
|
||
|
| "management-forget-disconnect"
|
||
|
| "management-hold"
|
||
|
| "management-signal"
|
||
|
| "management-up-down"
|
||
|
| "management-client-auth"
|
||
|
| "management-client-pf"
|
||
|
| "push-reset"
|
||
|
| "push-peer-info"
|
||
|
| "disable"
|
||
|
| "ifconfig-pool-linear"
|
||
|
| "client-to-client"
|
||
|
| "duplicate-cn"
|
||
|
| "ccd-exclusive"
|
||
|
| "tcp-nodelay"
|
||
|
| "opt-verify"
|
||
|
| "auth-user-pass-optional"
|
||
|
| "client-cert-not-required"
|
||
|
| "username-as-common-name"
|
||
|
| "pull"
|
||
|
| "key-direction"
|
||
|
| "no-replay"
|
||
|
| "mute-replay-warnings"
|
||
|
| "no-iv"
|
||
|
| "use-prediction-resistance"
|
||
|
| "test-crypto"
|
||
|
| "tls-server"
|
||
|
| "tls-client"
|
||
|
| "pkcs11-id-management"
|
||
|
| "single-session"
|
||
|
| "tls-exit"
|
||
|
| "auth-nocache"
|
||
|
| "show-ciphers"
|
||
|
| "show-digests"
|
||
|
| "show-tls"
|
||
|
| "show-engines"
|
||
|
| "genkey"
|
||
|
| "mktun"
|
||
|
| "rmtun"
|
||
|
|
||
|
|
||
|
let flag_entry (kw:regexp)
|
||
|
= [ key kw . comment_or_eol ]
|
||
|
|
||
|
let flag = flag_entry flag_words
|
||
|
|
||
|
|
||
|
(************************************************************************
|
||
|
* OTHER FIELDS
|
||
|
*
|
||
|
* - server => IP IP [nopool]
|
||
|
* - server-bridge => IP IP IP IP
|
||
|
* - route => host host [host [num]]
|
||
|
* - push => "string"
|
||
|
* - tls-auth => filename [01]
|
||
|
* - remote => hostname/IP [num] [(tcp|udp)]
|
||
|
* - management => IP num filename
|
||
|
* - http-proxy => host port [filename|keyword] [method]
|
||
|
* - http-proxy-option => (VERSION decimal|AGENT string)
|
||
|
* ...
|
||
|
* and many others
|
||
|
*
|
||
|
*************************************************************************)
|
||
|
|
||
|
let server = [ key "server"
|
||
|
. sep . [ label "address" . ip ]
|
||
|
. sep . [ label "netmask" . ip ]
|
||
|
. (sep . [ key "nopool" ]) ?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let server_bridge =
|
||
|
let ip_params = [ label "address" . ip ] . sep
|
||
|
. [ label "netmask" . ip ] . sep
|
||
|
. [ label "start" . ip ] . sep
|
||
|
. [ label "end" . ip ] in
|
||
|
[ key "server-bridge"
|
||
|
. sep . (ip_params|store /(nogw)/)
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let route =
|
||
|
let route_net_kw = store (/(vpn_gateway|net_gateway|remote_host)/|host_re) in
|
||
|
[ key "route" . sep
|
||
|
. [ label "address" . route_net_kw ]
|
||
|
. (sep . [ label "netmask" . store (ip_re|/default/) ]
|
||
|
. (sep . [ label "gateway" . route_net_kw ]
|
||
|
. (sep . [ label "metric" . store (/default/|num_re)] )?
|
||
|
)?
|
||
|
)?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let route_ipv6 =
|
||
|
let route_net_re = /(vpn_gateway|net_gateway|remote_host)/ in
|
||
|
[ key "route-ipv6" . sep
|
||
|
. [ label "network" . store (route_net_re|ipv6_bits_re) ]
|
||
|
. (sep . [ label "gateway" . store (route_net_re|ipv6_re) ]
|
||
|
. (sep . [ label "metric" . store (/default/|num_re)] )?
|
||
|
)?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let push = [ key "push" . sep
|
||
|
. Quote.do_dquote sto_to_dquote
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let tls_auth = [ key "tls-auth" . sep
|
||
|
. [ label "key" . filename ] . sep
|
||
|
. [ label "is_client" . store /[01]/ ] . comment_or_eol
|
||
|
]
|
||
|
|
||
|
let remote = [ key "remote" . sep
|
||
|
. [ label "server" . host ]
|
||
|
. (sep . [label "port" . port]
|
||
|
. (sep . [label "proto" . proto]) ? ) ?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let http_proxy =
|
||
|
let auth_method_re = /(none|basic|ntlm)/ in
|
||
|
let auth_method = store auth_method_re in
|
||
|
[ key "http-proxy"
|
||
|
. sep . [ label "server" . host ]
|
||
|
. sep . [ label "port" . port ]
|
||
|
. (sep . [ label "auth" . filename_safe ]
|
||
|
. (sep . [ label "auth-method" . auth_method ]) ? )?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let http_proxy_option = [ key "http-proxy-option"
|
||
|
. sep . [ label "option" . store /(VERSION|AGENT)/ ]
|
||
|
. sep . [ label "value" . filename ]
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let socks_proxy = [ key "socks-proxy"
|
||
|
. sep . [ label "server" . host ]
|
||
|
. (sep . [ label "port" . port ]
|
||
|
. (sep . [ label "auth" . filename_safe ])? )?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let port_share = [ key "port-share"
|
||
|
. sep . [ label "host" . host ]
|
||
|
. sep . [ label "port" . port ]
|
||
|
. (sep . [ label "dir" . filename ])?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let route_delay = [ key "route-delay"
|
||
|
. (sep . [ label "seconds" . num ]
|
||
|
. (sep . [ label "win-seconds" . num ] ) ?
|
||
|
)?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let inetd = [ key "inetd"
|
||
|
. (sep . [label "mode" . store /(wait|nowait)/ ]
|
||
|
. (sep . [ label "progname" . filename ] ) ?
|
||
|
)?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let inactive = [ key "inactive"
|
||
|
. sep . [ label "seconds" . num ]
|
||
|
. (sep . [ label "bytes" . num ] ) ?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let client_nat = [ key "client-nat"
|
||
|
. sep . [ label "type" . store /(snat|dnat)/ ]
|
||
|
. sep . [ label "network" . ip ]
|
||
|
. sep . [ label "netmask" . ip ]
|
||
|
. sep . [ label "alias" . ip ]
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let status = [ key "status"
|
||
|
. sep . [ label "file" . filename_safe ]
|
||
|
. (sep . [ label "repeat-seconds" . num ]) ?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let plugin = [ key "plugin"
|
||
|
. sep . [ label "file" . filename_safe ]
|
||
|
. (sep . [ label "init-string" . filename ]) ?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let management = [ key "management" . sep
|
||
|
. [ label "server" . ip ]
|
||
|
. sep . [ label "port" . port ]
|
||
|
. (sep . [ label "pwfile" . filename ] ) ?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let auth_user_pass_verify = [ key "auth-user-pass-verify"
|
||
|
. sep . [ Quote.quote_spaces (label "command") ]
|
||
|
. sep . [ label "method" . store /via-(env|file)/ ]
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let static_challenge = [ key "static-challenge"
|
||
|
. sep . [ Quote.quote_spaces (label "text") ]
|
||
|
. sep . [ label "echo" . store /[01]/ ]
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let cryptoapicert = [ key "cryptoapicert" . sep . Quote.dquote
|
||
|
. [ key /[A-Z]+/ . Sep.colon . store /[A-Za-z _-]+/ ]
|
||
|
. Quote.dquote . comment_or_eol
|
||
|
]
|
||
|
|
||
|
let setenv =
|
||
|
let envvar = /[^#;\/ \t\n][A-Za-z0-9_-]+/ in
|
||
|
[ key ("setenv"|"setenv-safe")
|
||
|
. sep . [ key envvar . sep . store fn_re ]
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let redirect =
|
||
|
let redirect_flag = /(local|autolocal|def1|bypass-dhcp|bypass-dns|block-local)/ in
|
||
|
let redirect_key = "redirect-gateway" | "redirect-private" in
|
||
|
[ key redirect_key
|
||
|
. (sep . [ label "flag" . store redirect_flag ] ) +
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let tls_cipher =
|
||
|
let ciphername = /[A-Za-z0-9!_-]+/ in
|
||
|
[ key "tls-cipher" . sep
|
||
|
. [label "cipher" . store ciphername]
|
||
|
. (Sep.colon . [label "cipher" . store ciphername])*
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let remote_cert_ku =
|
||
|
let usage = [label "usage" . store /[A-Za-z0-9]{1,2}/] in
|
||
|
[ key "remote-cert-ku" . sep . usage . (sep . usage)* . comment_or_eol ]
|
||
|
|
||
|
(* FIXME: Surely there's a nicer way to do this *)
|
||
|
let remote_cert_eku =
|
||
|
let oid = [label "oid" . store /[0-9]+\.([0-9]+\.)*[0-9]+/] in
|
||
|
let symbolic = [Quote.do_quote_opt
|
||
|
(label "symbol" . store /[A-Za-z0-9][A-Za-z0-9 _-]*[A-Za-z0-9]/)] in
|
||
|
[ key "remote-cert-eku" . sep . (oid|symbolic) . comment_or_eol ]
|
||
|
|
||
|
let status_version = [ key "status-version"
|
||
|
. (sep . num) ?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let ifconfig_pool = [ key "ifconfig-pool"
|
||
|
. sep . [ label "start" . ip ]
|
||
|
. sep . [ label "end" . ip ]
|
||
|
. (sep . [ label "netmask" . ip ])?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let ifconfig_push = [ key "ifconfig-push"
|
||
|
. sep . [ label "local" . ip ]
|
||
|
. sep . [ label "remote-netmask" . ip ]
|
||
|
. (sep . [ label "alias" . store /[A-Za-z0-9_-]+/ ] )?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let ignore_unknown_option = [ key "ignore-unknown-option"
|
||
|
. (sep . [ label "opt" . store /[A-Za-z0-9_-]+/ ] ) +
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let tls_version_min = [ key "tls-version-min"
|
||
|
. sep . store Rx.decimal
|
||
|
. (sep . [ key "or-highest" ]) ?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let crl_verify = [ key "crl-verify"
|
||
|
. sep . filename_safe
|
||
|
. (sep . [ key "dir" ]) ?
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let x509_username_field =
|
||
|
let fieldname = /[A-Za-z0-9_-]+/ in
|
||
|
let extfield = ([key /ext/ . Sep.colon . store fieldname]) in
|
||
|
let subjfield = ([label "subj" . store fieldname]) in
|
||
|
[ key "x509-username-field"
|
||
|
. sep . (extfield|subjfield)
|
||
|
. comment_or_eol
|
||
|
]
|
||
|
|
||
|
let other = server
|
||
|
| server_bridge
|
||
|
| route
|
||
|
| push
|
||
|
| tls_auth
|
||
|
| remote
|
||
|
| http_proxy
|
||
|
| http_proxy_option
|
||
|
| socks_proxy
|
||
|
| management
|
||
|
| route_delay
|
||
|
| client_nat
|
||
|
| redirect
|
||
|
| inactive
|
||
|
| setenv
|
||
|
| inetd
|
||
|
| status
|
||
|
| status_version
|
||
|
| plugin
|
||
|
| ifconfig_pool
|
||
|
| ifconfig_push
|
||
|
| ignore_unknown_option
|
||
|
| auth_user_pass_verify
|
||
|
| port_share
|
||
|
| static_challenge
|
||
|
| tls_version_min
|
||
|
| tls_cipher
|
||
|
| cryptoapicert
|
||
|
| x509_username_field
|
||
|
| remote_cert_ku
|
||
|
| remote_cert_eku
|
||
|
| crl_verify
|
||
|
| route_ipv6
|
||
|
|
||
|
|
||
|
(************************************************************************
|
||
|
* LENS & FILTER
|
||
|
*************************************************************************)
|
||
|
|
||
|
let lns = ( comment | empty | single | single_opt | double | flag | other )*
|
||
|
|
||
|
let filter = (incl "/etc/openvpn/client.conf")
|
||
|
. (incl "/etc/openvpn/server.conf")
|
||
|
|
||
|
let xfm = transform lns filter
|
||
|
|
||
|
|
||
|
|