1 /*
2  *  OpenVPN -- An application to securely tunnel IP networks
3  *             over a single UDP port, with support for SSL/TLS-based
4  *             session authentication and key exchange,
5  *             packet encryption, packet authentication, and
6  *             packet compression.
7  *
8  *  Copyright (C) 2002-2022 OpenVPN Inc <sales@openvpn.net>
9  *  Copyright (C) 2008-2022 David Sommerseth <dazo@eurephia.org>
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License version 2
13  *  as published by the Free Software Foundation.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License along
21  *  with this program; if not, write to the Free Software Foundation, Inc.,
22  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
25 /*
26  * 2004-01-28: Added Socks5 proxy support
27  *   (Christof Meerwald, http://cmeerw.org)
28  */
29 
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #elif defined(_MSC_VER)
33 #include "config-msvc.h"
34 #endif
35 #ifdef HAVE_CONFIG_VERSION_H
36 #include "config-version.h"
37 #endif
38 
39 #include "syshead.h"
40 
41 #include "buffer.h"
42 #include "error.h"
43 #include "common.h"
44 #include "run_command.h"
45 #include "shaper.h"
46 #include "crypto.h"
47 #include "ssl.h"
48 #include "ssl_ncp.h"
49 #include "options.h"
50 #include "misc.h"
51 #include "socket.h"
52 #include "packet_id.h"
53 #include "pkcs11.h"
54 #include "win32.h"
55 #include "push.h"
56 #include "pool.h"
57 #include "proto.h"
58 #include "helper.h"
59 #include "manage.h"
60 #include "forward.h"
61 #include "ssl_verify.h"
62 #include "platform.h"
63 #include <ctype.h>
64 
65 #include "memdbg.h"
66 
67 const char title_string[] =
68     PACKAGE_STRING
69 #ifdef CONFIGURE_GIT_REVISION
70     " [git:" CONFIGURE_GIT_REVISION CONFIGURE_GIT_FLAGS "]"
71 #endif
72     " " TARGET_ALIAS
73 #if defined(ENABLE_CRYPTO_MBEDTLS)
74     " [SSL (mbed TLS)]"
75 #elif defined(ENABLE_CRYPTO_OPENSSL)
76     " [SSL (OpenSSL)]"
77 #else
78     " [SSL]"
79 #endif /* defined(ENABLE_CRYPTO_MBEDTLS) */
80 #ifdef USE_COMP
81 #ifdef ENABLE_LZO
82     " [LZO]"
83 #endif
84 #ifdef ENABLE_LZ4
85     " [LZ4]"
86 #endif
87 #ifdef ENABLE_COMP_STUB
88     " [COMP_STUB]"
89 #endif
90 #endif /* USE_COMP */
91 #if EPOLL
92     " [EPOLL]"
93 #endif
94 #ifdef PRODUCT_TAP_DEBUG
95     " [TAPDBG]"
96 #endif
97 #ifdef ENABLE_PKCS11
98     " [PKCS11]"
99 #endif
100 #if ENABLE_IP_PKTINFO
101 #if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
102     " [MH/PKTINFO]"
103 #elif defined(IP_RECVDSTADDR)
104     " [MH/RECVDA]"
105 #endif
106 #endif
107     " [AEAD]"
108     " built on " __DATE__
109 ;
110 
111 #ifndef ENABLE_SMALL
112 
113 static const char usage_message[] =
114     "%s\n"
115     "\n"
116     "General Options:\n"
117     "--config file   : Read configuration options from file.\n"
118     "--help          : Show options.\n"
119     "--version       : Show copyright and version information.\n"
120     "\n"
121     "Tunnel Options:\n"
122     "--local host    : Local host name or ip address. Implies --bind.\n"
123     "--remote host [port] : Remote host name or ip address.\n"
124     "--remote-random : If multiple --remote options specified, choose one randomly.\n"
125     "--remote-random-hostname : Add a random string to remote DNS name.\n"
126     "--mode m        : Major mode, m = 'p2p' (default, point-to-point) or 'server'.\n"
127     "--proto p       : Use protocol p for communicating with peer.\n"
128     "                  p = udp (default), tcp-server, tcp-client\n"
129     "                      udp4, tcp4-server, tcp4-client\n"
130     "                      udp6, tcp6-server, tcp6-client\n"
131     "--proto-force p : only consider protocol p in list of connection profiles.\n"
132     "                  p = udp or tcp\n"
133     "--connect-retry n [m] : For client, number of seconds to wait between\n"
134     "                  connection retries (default=%d). On repeated retries\n"
135     "                  the wait time is exponentially increased to a maximum of m\n"
136     "                  (default=%d).\n"
137     "--connect-retry-max n : Maximum connection attempt retries, default infinite.\n"
138     "--http-proxy s p [up] [auth] : Connect to remote host\n"
139     "                  through an HTTP proxy at address s and port p.\n"
140     "                  If proxy authentication is required,\n"
141     "                  up is a file containing username/password on 2 lines, or\n"
142     "                  'stdin' to prompt from console.  Add auth='ntlm' if\n"
143     "                  the proxy requires NTLM authentication.\n"
144     "--http-proxy s p 'auto[-nct]' : Like the above directive, but automatically\n"
145     "                  determine auth method and query for username/password\n"
146     "                  if needed.  auto-nct disables weak proxy auth methods.\n"
147     "--http-proxy-option type [parm] : Set extended HTTP proxy options.\n"
148     "                                  Repeat to set multiple options.\n"
149     "                  VERSION version (default=1.0)\n"
150     "                  AGENT user-agent\n"
151     "--socks-proxy s [p] [up] : Connect to remote host through a Socks5 proxy at\n"
152     "                  address s and port p (default port = 1080).\n"
153     "                  If proxy authentication is required,\n"
154     "                  up is a file containing username/password on 2 lines, or\n"
155     "                  'stdin' to prompt for console.\n"
156     "--socks-proxy-retry : Retry indefinitely on Socks proxy errors.\n"
157     "--resolv-retry n: If hostname resolve fails for --remote, retry\n"
158     "                  resolve for n seconds before failing (disabled by default).\n"
159     "                  Set n=\"infinite\" to retry indefinitely.\n"
160     "--float         : Allow remote to change its IP address/port, such as through\n"
161     "                  DHCP (this is the default if --remote is not used).\n"
162     "--ipchange cmd  : Run command cmd on remote ip address initial\n"
163     "                  setting or change -- execute as: cmd ip-address port#\n"
164     "--port port     : TCP/UDP port # for both local and remote.\n"
165     "--lport port    : TCP/UDP port # for local (default=%s). Implies --bind.\n"
166     "--rport port    : TCP/UDP port # for remote (default=%s).\n"
167     "--bind          : Bind to local address and port. (This is the default unless\n"
168     "                  --proto tcp-client"
169     " or --http-proxy"
170     " or --socks-proxy"
171     " is used).\n"
172     "--nobind        : Do not bind to local address and port.\n"
173     "--dev tunX|tapX : tun/tap device (X can be omitted for dynamic device.\n"
174     "--dev-type dt   : Which device type are we using? (dt = tun or tap) Use\n"
175     "                  this option only if the tun/tap device used with --dev\n"
176     "                  does not begin with \"tun\" or \"tap\".\n"
177     "--dev-node node : Explicitly set the device node rather than using\n"
178     "                  /dev/net/tun, /dev/tun, /dev/tap, etc.\n"
179     "--lladdr hw     : Set the link layer address of the tap device.\n"
180     "--topology t    : Set --dev tun topology: 'net30', 'p2p', or 'subnet'.\n"
181 #ifdef ENABLE_IPROUTE
182     "--iproute cmd   : Use this command instead of default " IPROUTE_PATH ".\n"
183 #endif
184     "--ifconfig l rn : TUN: configure device to use IP address l as a local\n"
185     "                  endpoint and rn as a remote endpoint.  l & rn should be\n"
186     "                  swapped on the other peer.  l & rn must be private\n"
187     "                  addresses outside of the subnets used by either peer.\n"
188     "                  TAP: configure device to use IP address l as a local\n"
189     "                  endpoint and rn as a subnet mask.\n"
190     "--ifconfig-ipv6 l r : configure device to use IPv6 address l as local\n"
191     "                      endpoint (as a /64) and r as remote endpoint\n"
192     "--ifconfig-noexec : Don't actually execute ifconfig/netsh command, instead\n"
193     "                    pass --ifconfig parms by environment to scripts.\n"
194     "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n"
195     "                    connection doesn't match the remote side.\n"
196     "--route network [netmask] [gateway] [metric] :\n"
197     "                  Add route to routing table after connection\n"
198     "                  is established.  Multiple routes can be specified.\n"
199     "                  netmask default: 255.255.255.255\n"
200     "                  gateway default: taken from --route-gateway or --ifconfig\n"
201     "                  Specify default by leaving blank or setting to \"nil\".\n"
202     "--route-ipv6 network/bits [gateway] [metric] :\n"
203     "                  Add IPv6 route to routing table after connection\n"
204     "                  is established.  Multiple routes can be specified.\n"
205     "                  gateway default: taken from --route-ipv6-gateway or 'remote'\n"
206     "                  in --ifconfig-ipv6\n"
207     "--route-gateway gw|'dhcp' : Specify a default gateway for use with --route.\n"
208     "--route-ipv6-gateway gw : Specify a default gateway for use with --route-ipv6.\n"
209     "--route-metric m : Specify a default metric for use with --route.\n"
210     "--route-delay n [w] : Delay n seconds after connection initiation before\n"
211     "                  adding routes (may be 0).  If not specified, routes will\n"
212     "                  be added immediately after tun/tap open.  On Windows, wait\n"
213     "                  up to w seconds for TUN/TAP adapter to come up.\n"
214     "--route-up cmd  : Run command cmd after routes are added.\n"
215     "--route-pre-down cmd : Run command cmd before routes are removed.\n"
216     "--route-noexec  : Don't add routes automatically.  Instead pass routes to\n"
217     "                  --route-up script using environmental variables.\n"
218     "--route-nopull  : When used with --client or --pull, accept options pushed\n"
219     "                  by server EXCEPT for routes and dhcp options.\n"
220     "--allow-pull-fqdn : Allow client to pull DNS names from server for\n"
221     "                    --ifconfig, --route, and --route-gateway.\n"
222     "--redirect-gateway [flags]: Automatically execute routing\n"
223     "                  commands to redirect all outgoing IP traffic through the\n"
224     "                  VPN.  Add 'local' flag if both " PACKAGE_NAME " servers are directly\n"
225     "                  connected via a common subnet, such as with WiFi.\n"
226     "                  Add 'def1' flag to set default route using using 0.0.0.0/1\n"
227     "                  and 128.0.0.0/1 rather than 0.0.0.0/0.  Add 'bypass-dhcp'\n"
228     "                  flag to add a direct route to DHCP server, bypassing tunnel.\n"
229     "                  Add 'bypass-dns' flag to similarly bypass tunnel for DNS.\n"
230     "--redirect-private [flags]: Like --redirect-gateway, but omit actually changing\n"
231     "                  the default gateway.  Useful when pushing private subnets.\n"
232     "--block-ipv6     : (Client) Instead sending IPv6 to the server generate\n"
233     "                   ICMPv6 host unreachable messages on the client.\n"
234     "                   (Server) Instead of forwarding IPv6 packets send\n"
235     "                   ICMPv6 host unreachable packets to the client.\n"
236     "--client-nat snat|dnat network netmask alias : on client add 1-to-1 NAT rule.\n"
237     "--push-peer-info : (client only) push client info to server.\n"
238     "--setenv name value : Set a custom environmental variable to pass to script.\n"
239     "--setenv FORWARD_COMPATIBLE 1 : Relax config file syntax checking to allow\n"
240     "                  directives for future OpenVPN versions to be ignored.\n"
241     "--ignore-unkown-option opt1 opt2 ...: Relax config file syntax. Allow\n"
242     "                  these options to be ignored when unknown\n"
243     "--script-security level: Where level can be:\n"
244     "                  0 -- strictly no calling of external programs\n"
245     "                  1 -- (default) only call built-ins such as ifconfig\n"
246     "                  2 -- allow calling of built-ins and scripts\n"
247     "                  3 -- allow password to be passed to scripts via env\n"
248     "--shaper n      : Restrict output to peer to n bytes per second.\n"
249     "--keepalive n m : Helper option for setting timeouts in server mode.  Send\n"
250     "                  ping once every n seconds, restart if ping not received\n"
251     "                  for m seconds.\n"
252     "--inactive n [bytes] : Exit after n seconds of activity on tun/tap device\n"
253     "                  produces a combined in/out byte count < bytes.\n"
254     "--ping-exit n   : Exit if n seconds pass without reception of remote ping.\n"
255     "--ping-restart n: Restart if n seconds pass without reception of remote ping.\n"
256     "--ping-timer-rem: Run the --ping-exit/--ping-restart timer only if we have a\n"
257     "                  remote address.\n"
258     "--ping n        : Ping remote once every n seconds over TCP/UDP port.\n"
259 #if ENABLE_IP_PKTINFO
260     "--multihome     : Configure a multi-homed UDP server.\n"
261 #endif
262     "--fast-io       : (experimental) Optimize TUN/TAP/UDP writes.\n"
263     "--remap-usr1 s  : On SIGUSR1 signals, remap signal (s='SIGHUP' or 'SIGTERM').\n"
264     "--persist-tun   : Keep tun/tap device open across SIGUSR1 or --ping-restart.\n"
265     "--persist-remote-ip : Keep remote IP address across SIGUSR1 or --ping-restart.\n"
266     "--persist-local-ip  : Keep local IP address across SIGUSR1 or --ping-restart.\n"
267     "--persist-key   : Don't re-read key files across SIGUSR1 or --ping-restart.\n"
268 #if PASSTOS_CAPABILITY
269     "--passtos       : TOS passthrough (applies to IPv4 only).\n"
270 #endif
271     "--tun-mtu n     : Take the tun/tap device MTU to be n and derive the\n"
272     "                  TCP/UDP MTU from it (default=%d).\n"
273     "--tun-mtu-extra n : Assume that tun/tap device might return as many\n"
274     "                  as n bytes more than the tun-mtu size on read\n"
275     "                  (default TUN=0 TAP=%d).\n"
276     "--link-mtu n    : Take the TCP/UDP device MTU to be n and derive the tun MTU\n"
277     "                  from it.\n"
278     "--mtu-disc type : Should we do Path MTU discovery on TCP/UDP channel?\n"
279     "                  'no'    -- Never send DF (Don't Fragment) frames\n"
280     "                  'maybe' -- Use per-route hints\n"
281     "                  'yes'   -- Always DF (Don't Fragment)\n"
282     "--mtu-test      : Empirically measure and report MTU.\n"
283 #ifdef ENABLE_FRAGMENT
284     "--fragment max  : Enable internal datagram fragmentation so that no UDP\n"
285     "                  datagrams are sent which are larger than max bytes.\n"
286     "                  Adds 4 bytes of overhead per datagram.\n"
287 #endif
288     "--mssfix [n]    : Set upper bound on TCP MSS, default = tun-mtu size\n"
289     "                  or --fragment max value, whichever is lower.\n"
290     "--sndbuf size   : Set the TCP/UDP send buffer size.\n"
291     "--rcvbuf size   : Set the TCP/UDP receive buffer size.\n"
292 #if defined(TARGET_LINUX) && HAVE_DECL_SO_MARK
293     "--mark value    : Mark encrypted packets being sent with value. The mark value\n"
294     "                  can be matched in policy routing and packetfilter rules.\n"
295     "--bind-dev dev  : Bind to the given device when making connection to a peer or\n"
296     "                  listening for connections. This allows sending encrypted packets\n"
297     "                  via a VRF present on the system.\n"
298 #endif
299     "--txqueuelen n  : Set the tun/tap TX queue length to n (Linux only).\n"
300 #ifdef ENABLE_MEMSTATS
301     "--memstats file : Write live usage stats to memory mapped binary file.\n"
302 #endif
303     "--mlock         : Disable Paging -- ensures key material and tunnel\n"
304     "                  data will never be written to disk.\n"
305     "--up cmd        : Run command cmd after successful tun device open.\n"
306     "                  Execute as: cmd tun/tap-dev tun-mtu link-mtu \\\n"
307     "                              ifconfig-local-ip ifconfig-remote-ip\n"
308     "                  (pre --user or --group UID/GID change)\n"
309     "--up-delay      : Delay tun/tap open and possible --up script execution\n"
310     "                  until after TCP/UDP connection establishment with peer.\n"
311     "--down cmd      : Run command cmd after tun device close.\n"
312     "                  (post --user/--group UID/GID change and/or --chroot)\n"
313     "                  (command parameters are same as --up option)\n"
314     "--down-pre      : Run --down command before TUN/TAP close.\n"
315     "--up-restart    : Run up/down commands for all restarts including those\n"
316     "                  caused by --ping-restart or SIGUSR1\n"
317     "--user user     : Set UID to user after initialization.\n"
318     "--group group   : Set GID to group after initialization.\n"
319     "--chroot dir    : Chroot to this directory after initialization.\n"
320 #ifdef ENABLE_SELINUX
321     "--setcon context: Apply this SELinux context after initialization.\n"
322 #endif
323     "--cd dir        : Change to this directory before initialization.\n"
324     "--daemon [name] : Become a daemon after initialization.\n"
325     "                  The optional 'name' parameter will be passed\n"
326     "                  as the program name to the system logger.\n"
327     "--syslog [name] : Output to syslog, but do not become a daemon.\n"
328     "                  See --daemon above for a description of the 'name' parm.\n"
329     "--inetd [name] ['wait'|'nowait'] : Run as an inetd or xinetd server.\n"
330     "                  See --daemon above for a description of the 'name' parm.\n"
331     "--log file      : Output log to file which is created/truncated on open.\n"
332     "--log-append file : Append log to file, or create file if nonexistent.\n"
333     "--suppress-timestamps : Don't log timestamps to stdout/stderr.\n"
334     "--machine-readable-output : Always log timestamp, message flags to stdout/stderr.\n"
335     "--writepid file : Write main process ID to file.\n"
336     "--nice n        : Change process priority (>0 = lower, <0 = higher).\n"
337     "--echo [parms ...] : Echo parameters to log output.\n"
338     "--verb n        : Set output verbosity to n (default=%d):\n"
339     "                  (Level 3 is recommended if you want a good summary\n"
340     "                  of what's happening without being swamped by output).\n"
341     "                : 0 -- no output except fatal errors\n"
342     "                : 1 -- startup info + connection initiated messages +\n"
343     "                       non-fatal encryption & net errors\n"
344     "                : 2,3 -- show TLS negotiations & route info\n"
345     "                : 4 -- show parameters\n"
346     "                : 5 -- show 'RrWw' chars on console for each packet sent\n"
347     "                       and received from TCP/UDP (caps) or tun/tap (lc)\n"
348     "                : 6 to 11 -- debug messages of increasing verbosity\n"
349     "--mute n        : Log at most n consecutive messages in the same category.\n"
350     "--status file n : Write operational status to file every n seconds.\n"
351     "--status-version [n] : Choose the status file format version number.\n"
352     "                  Currently, n can be 1, 2, or 3 (default=1).\n"
353     "--disable-occ   : Disable options consistency check between peers.\n"
354 #ifdef ENABLE_DEBUG
355     "--gremlin mask  : Special stress testing mode (for debugging only).\n"
356 #endif
357 #if defined(USE_COMP)
358     "--compress alg  : Use compression algorithm alg\n"
359     "--allow-compression: Specify whether compression should be allowed\n"
360 #if defined(ENABLE_LZO)
361     "--comp-lzo      : Use LZO compression -- may add up to 1 byte per\n"
362     "                  packet for incompressible data.\n"
363     "--comp-noadapt  : Don't use adaptive compression when --comp-lzo\n"
364     "                  is specified.\n"
365 #endif
366 #endif
367 #ifdef ENABLE_MANAGEMENT
368     "--management ip port [pass] : Enable a TCP server on ip:port to handle\n"
369     "                  management functions.  pass is a password file\n"
370     "                  or 'stdin' to prompt from console.\n"
371 #if UNIX_SOCK_SUPPORT
372     "                  To listen on a unix domain socket, specific the pathname\n"
373     "                  in place of ip and use 'unix' as the port number.\n"
374 #endif
375     "--management-client : Management interface will connect as a TCP client to\n"
376     "                      ip/port rather than listen as a TCP server.\n"
377     "--management-query-passwords : Query management channel for private key\n"
378     "                  and auth-user-pass passwords.\n"
379     "--management-query-proxy : Query management channel for proxy information.\n"
380     "--management-query-remote : Query management channel for --remote directive.\n"
381     "--management-hold : Start " PACKAGE_NAME " in a hibernating state, until a client\n"
382     "                    of the management interface explicitly starts it.\n"
383     "--management-signal : Issue SIGUSR1 when management disconnect event occurs.\n"
384     "--management-forget-disconnect : Forget passwords when management disconnect\n"
385     "                                 event occurs.\n"
386     "--management-up-down : Report tunnel up/down events to management interface.\n"
387     "--management-log-cache n : Cache n lines of log file history for usage\n"
388     "                  by the management channel.\n"
389 #if UNIX_SOCK_SUPPORT
390     "--management-client-user u  : When management interface is a unix socket, only\n"
391     "                              allow connections from user u.\n"
392     "--management-client-group g : When management interface is a unix socket, only\n"
393     "                              allow connections from group g.\n"
394 #endif
395 #ifdef MANAGEMENT_DEF_AUTH
396     "--management-client-auth : gives management interface client the responsibility\n"
397     "                           to authenticate clients after their client certificate\n"
398     "			      has been verified.\n"
399 #endif
400 #ifdef MANAGEMENT_PF
401     "--management-client-pf : management interface clients must specify a packet\n"
402     "                         filter file for each connecting client.\n"
403 #endif
404 #endif /* ifdef ENABLE_MANAGEMENT */
405 #ifdef ENABLE_PLUGIN
406     "--plugin m [str]: Load plug-in module m passing str as an argument\n"
407     "                  to its initialization function.\n"
408 #endif
409     "--vlan-tagging  : Enable 802.1Q-based VLAN tagging.\n"
410     "--vlan-accept tagged|untagged|all : Set VLAN tagging mode. Default is 'all'.\n"
411     "--vlan-pvid v   : Sets the Port VLAN Identifier. Defaults to 1.\n"
412 #if P2MP
413     "\n"
414     "Multi-Client Server options (when --mode server is used):\n"
415     "--server network netmask : Helper option to easily configure server mode.\n"
416     "--server-ipv6 network/bits : Configure IPv6 server mode.\n"
417     "--server-bridge [IP netmask pool-start-IP pool-end-IP] : Helper option to\n"
418     "                    easily configure ethernet bridging server mode.\n"
419     "--push \"option\" : Push a config file option back to the peer for remote\n"
420     "                  execution.  Peer must specify --pull in its config file.\n"
421     "--push-reset    : Don't inherit global push list for specific\n"
422     "                  client instance.\n"
423     "--push-remove opt : Remove options matching 'opt' from the push list for\n"
424     "                  a specific client instance.\n"
425     "--ifconfig-pool start-IP end-IP [netmask] : Set aside a pool of subnets\n"
426     "                  to be dynamically allocated to connecting clients.\n"
427     "--ifconfig-pool-persist file [seconds] : Persist/unpersist ifconfig-pool\n"
428     "                  data to file, at seconds intervals (default=600).\n"
429     "                  If seconds=0, file will be treated as read-only.\n"
430     "--ifconfig-ipv6-pool base-IP/bits : set aside an IPv6 network block\n"
431     "                  to be dynamically allocated to connecting clients.\n"
432     "--ifconfig-push local remote-netmask : Push an ifconfig option to remote,\n"
433     "                  overrides --ifconfig-pool dynamic allocation.\n"
434     "                  Only valid in a client-specific config file.\n"
435     "--ifconfig-ipv6-push local/bits remote : Push an ifconfig-ipv6 option to\n"
436     "                  remote, overrides --ifconfig-ipv6-pool allocation.\n"
437     "                  Only valid in a client-specific config file.\n"
438     "--iroute network [netmask] : Route subnet to client.\n"
439     "--iroute-ipv6 network/bits : Route IPv6 subnet to client.\n"
440     "                  Sets up internal routes only.\n"
441     "                  Only valid in a client-specific config file.\n"
442     "--disable       : Client is disabled.\n"
443     "                  Only valid in a client-specific config file.\n"
444     "--verify-client-cert [none|optional|require] : perform no, optional or\n"
445     "                  mandatory client certificate verification.\n"
446     "                  Default is to require the client to supply a certificate.\n"
447     "--username-as-common-name  : For auth-user-pass authentication, use\n"
448     "                  the authenticated username as the common name,\n"
449     "                  rather than the common name from the client cert.\n"
450     "--auth-user-pass-verify cmd method: Query client for username/password and\n"
451     "                  run command cmd to verify.  If method='via-env', pass\n"
452     "                  user/pass via environment, if method='via-file', pass\n"
453     "                  user/pass via temporary file.\n"
454     "--auth-gen-token  [lifetime] Generate a random authentication token which is pushed\n"
455     "                  to each client, replacing the password.  Useful when\n"
456     "                  OTP based two-factor auth mechanisms are in use and\n"
457     "                  --reneg-* options are enabled. Optionally a lifetime in seconds\n"
458     "                  for generated tokens can be set.\n"
459     "--opt-verify    : Clients that connect with options that are incompatible\n"
460     "                  with those of the server will be disconnected.\n"
461     "--auth-user-pass-optional : Allow connections by clients that don't\n"
462     "                  specify a username/password.\n"
463     "--no-name-remapping : (DEPRECATED) Allow Common Name and X509 Subject to include\n"
464     "                      any printable character.\n"
465     "--client-to-client : Internally route client-to-client traffic.\n"
466     "--duplicate-cn  : Allow multiple clients with the same common name to\n"
467     "                  concurrently connect.\n"
468     "--client-connect cmd : Run command cmd on client connection.\n"
469     "--client-disconnect cmd : Run command cmd on client disconnection.\n"
470     "--client-config-dir dir : Directory for custom client config files.\n"
471     "--ccd-exclusive : Refuse connection unless custom client config is found.\n"
472     "--tmp-dir dir   : Temporary directory, used for --client-connect return file and plugin communication.\n"
473     "--hash-size r v : Set the size of the real address hash table to r and the\n"
474     "                  virtual address table to v.\n"
475     "--bcast-buffers n : Allocate n broadcast buffers.\n"
476     "--tcp-queue-limit n : Maximum number of queued TCP output packets.\n"
477     "--tcp-nodelay   : Macro that sets TCP_NODELAY socket flag on the server\n"
478     "                  as well as pushes it to connecting clients.\n"
479     "--learn-address cmd : Run command cmd to validate client virtual addresses.\n"
480     "--connect-freq n s : Allow a maximum of n new connections per s seconds.\n"
481     "--max-clients n : Allow a maximum of n simultaneously connected clients.\n"
482     "--max-routes-per-client n : Allow a maximum of n internal routes per client.\n"
483     "--stale-routes-check n [t] : Remove routes with a last activity timestamp\n"
484     "                             older than n seconds. Run this check every t\n"
485     "                             seconds (defaults to n).\n"
486     "--explicit-exit-notify [n] : In UDP server mode send [RESTART] command on exit/restart to connected\n"
487     "                             clients. n = 1 - reconnect to same server,\n"
488     "                             2 - advance to next server, default=1.\n"
489 #if PORT_SHARE
490     "--port-share host port [dir] : When run in TCP mode, proxy incoming HTTPS\n"
491     "                  sessions to a web server at host:port.  dir specifies an\n"
492     "                  optional directory to write origin IP:port data.\n"
493 #endif
494     "\n"
495     "Client options (when connecting to a multi-client server):\n"
496     "--client         : Helper option to easily configure client mode.\n"
497     "--auth-user-pass [up] : Authenticate with server using username/password.\n"
498     "                  up is a file containing the username on the first line,\n"
499     "                  and a password on the second. If either the password or both\n"
500     "                  the username and the password are omitted OpenVPN will prompt\n"
501     "                  for them from console.\n"
502     "--pull           : Accept certain config file options from the peer as if they\n"
503     "                  were part of the local config file.  Must be specified\n"
504     "                  when connecting to a '--mode server' remote host.\n"
505     "--pull-filter accept|ignore|reject t : Filter each option received from the\n"
506     "                  server if it starts with the text t. The action flag accept,\n"
507     "                  ignore or reject causes the option to be allowed, removed or\n"
508     "                  rejected with error. May be specified multiple times, and\n"
509     "                  each filter is applied in the order of appearance.\n"
510     "--auth-retry t  : How to handle auth failures.  Set t to\n"
511     "                  none (default), interact, or nointeract.\n"
512     "--static-challenge t e : Enable static challenge/response protocol using\n"
513     "                  challenge text t, with e indicating echo flag (0|1)\n"
514     "--connect-timeout n : when polling possible remote servers to connect to\n"
515     "                  in a round-robin fashion, spend no more than n seconds\n"
516     "                  waiting for a response before trying the next server.\n"
517     "--allow-recursive-routing : When this option is set, OpenVPN will not drop\n"
518     "                  incoming tun packets with same destination as host.\n"
519 #endif /* if P2MP */
520     "--explicit-exit-notify [n] : On exit/restart, send exit signal to\n"
521     "                  server/remote. n = # of retries, default=1.\n"
522     "\n"
523     "Data Channel Encryption Options (must be compatible between peers):\n"
524     "(These options are meaningful for both Static Key & TLS-mode)\n"
525     "--secret f [d]  : Enable Static Key encryption mode (non-TLS).\n"
526     "                  Use shared secret file f, generate with --genkey.\n"
527     "                  The optional d parameter controls key directionality.\n"
528     "                  If d is specified, use separate keys for each\n"
529     "                  direction, set d=0 on one side of the connection,\n"
530     "                  and d=1 on the other side.\n"
531     "--auth alg      : Authenticate packets with HMAC using message\n"
532     "                  digest algorithm alg (default=%s).\n"
533     "                  (usually adds 16 or 20 bytes per packet)\n"
534     "                  Set alg=none to disable authentication.\n"
535     "--cipher alg    : Encrypt packets with cipher algorithm alg\n"
536     "                  (default=%s).\n"
537     "                  Set alg=none to disable encryption.\n"
538     "--data-ciphers list : List of ciphers that are allowed to be negotiated.\n"
539     "--ncp-disable   : (DEPRECATED) Disable cipher negotiation.\n"
540     "--prng alg [nsl] : For PRNG, use digest algorithm alg, and\n"
541     "                   nonce_secret_len=nsl.  Set alg=none to disable PRNG.\n"
542 #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH
543     "--keysize n     : (DEPRECATED) Size of cipher key in bits (optional).\n"
544     "                  If unspecified, defaults to cipher-specific default.\n"
545 #endif
546 #ifndef ENABLE_CRYPTO_MBEDTLS
547     "--engine [name] : Enable OpenSSL hardware crypto engine functionality.\n"
548 #endif
549     "--no-replay     : (DEPRECATED) Disable replay protection.\n"
550     "--mute-replay-warnings : Silence the output of replay warnings to log file.\n"
551     "--replay-window n [t]  : Use a replay protection sliding window of size n\n"
552     "                         and a time window of t seconds.\n"
553     "                         Default n=%d t=%d\n"
554     "--replay-persist file : Persist replay-protection state across sessions\n"
555     "                  using file.\n"
556     "--test-crypto   : Run a self-test of crypto features enabled.\n"
557     "                  For debugging only.\n"
558 #ifdef ENABLE_PREDICTION_RESISTANCE
559     "--use-prediction-resistance: Enable prediction resistance on the random\n"
560     "                             number generator.\n"
561 #endif
562     "\n"
563     "TLS Key Negotiation Options:\n"
564     "(These options are meaningful only for TLS-mode)\n"
565     "--tls-server    : Enable TLS and assume server role during TLS handshake.\n"
566     "--tls-client    : Enable TLS and assume client role during TLS handshake.\n"
567     "--key-method m  : (DEPRECATED) Data channel key exchange method.  m should be a method\n"
568     "                  number, such as 1 (default), 2, etc.\n"
569     "--ca file       : Certificate authority file in .pem format containing\n"
570     "                  root certificate.\n"
571 #ifndef ENABLE_CRYPTO_MBEDTLS
572     "--capath dir    : A directory of trusted certificates (CAs"
573     " and CRLs).\n"
574 #endif /* ENABLE_CRYPTO_MBEDTLS */
575     "--dh file       : File containing Diffie Hellman parameters\n"
576     "                  in .pem format (for --tls-server only).\n"
577     "                  Use \"openssl dhparam -out dh1024.pem 1024\" to generate.\n"
578     "--cert file     : Local certificate in .pem format -- must be signed\n"
579     "                  by a Certificate Authority in --ca file.\n"
580     "--extra-certs file : one or more PEM certs that complete the cert chain.\n"
581     "--key file      : Local private key in .pem format.\n"
582     "--tls-version-min <version> ['or-highest'] : sets the minimum TLS version we\n"
583     "    will accept from the peer.  If version is unrecognized and 'or-highest'\n"
584     "    is specified, require max TLS version supported by SSL implementation.\n"
585     "--tls-version-max <version> : sets the maximum TLS version we will use.\n"
586 #ifndef ENABLE_CRYPTO_MBEDTLS
587     "--pkcs12 file   : PKCS#12 file containing local private key, local certificate\n"
588     "                  and optionally the root CA certificate.\n"
589 #endif
590 #ifdef ENABLE_X509ALTUSERNAME
591     "--x509-username-field : Field in x509 certificate containing the username.\n"
592     "                        Default is CN in the Subject field.\n"
593 #endif
594     "--verify-hash hash [algo] : Specify fingerprint for level-1 certificate.\n"
595     "                            Valid algo flags are SHA1 and SHA256. \n"
596 #ifdef _WIN32
597     "--cryptoapicert select-string : Load the certificate and private key from the\n"
598     "                  Windows Certificate System Store.\n"
599 #endif
600     "--tls-cipher l  : A list l of allowable TLS ciphers separated by : (optional).\n"
601     "--tls-ciphersuites l: A list of allowed TLS 1.3 cipher suites seperated by : (optional)\n"
602     "                : Use --show-tls to see a list of supported TLS ciphers (suites).\n"
603     "--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n"
604     "                  (default=legacy).\n"
605     "--tls-timeout n : Packet retransmit timeout on TLS control channel\n"
606     "                  if no ACK from remote within n seconds (default=%d).\n"
607     "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n"
608     "--reneg-pkts n  : Renegotiate data chan. key after n packets sent and recvd.\n"
609     "--reneg-sec max [min] : Renegotiate data chan. key after at most max (default=%d)\n"
610     "                  and at least min (defaults to 90%% of max on servers and equal\n"
611     "                  to max on clients).\n"
612     "--hand-window n : Data channel key exchange must finalize within n seconds\n"
613     "                  of handshake initiation by any peer (default=%d).\n"
614     "--tran-window n : Transition window -- old key can live this many seconds\n"
615     "                  after new key renegotiation begins (default=%d).\n"
616     "--single-session: Allow only one session (reset state on restart).\n"
617     "--tls-exit      : Exit on TLS negotiation failure.\n"
618     "--tls-auth f [d]: Add an additional layer of authentication on top of the TLS\n"
619     "                  control channel to protect against attacks on the TLS stack\n"
620     "                  and DoS attacks.\n"
621     "                  f (required) is a shared-secret key file.\n"
622     "                  The optional d parameter controls key directionality,\n"
623     "                  see --secret option for more info.\n"
624     "--tls-crypt key : Add an additional layer of authenticated encryption on top\n"
625     "                  of the TLS control channel to hide the TLS certificate,\n"
626     "                  provide basic post-quantum security and protect against\n"
627     "                  attacks on the TLS stack and DoS attacks.\n"
628     "                  key (required) provides the pre-shared key file.\n"
629     "                  see --secret option for more info.\n"
630     "--tls-crypt-v2 key : For clients: use key as a client-specific tls-crypt key.\n"
631     "                  For servers: use key to decrypt client-specific keys.  For\n"
632     "                  key generation (--genkey tls-crypt-v2-client): use key to\n"
633     "                  encrypt generated client-specific key.  (See --tls-crypt.)\n"
634     "--genkey tls-crypt-v2-client [keyfile] [base64 metadata]: Generate a\n"
635     "                  fresh tls-crypt-v2 client key, and store to\n"
636     "                  keyfile.  If supplied, include metadata in wrapped key.\n"
637     "--genkey tls-crypt-v2-server [keyfile] [base64 metadata]: Generate a\n"
638     "                  fresh tls-crypt-v2 server key, and store to keyfile\n"
639     "--tls-crypt-v2-verify cmd : Run command cmd to verify the metadata of the\n"
640     "                  client-supplied tls-crypt-v2 client key\n"
641     "--askpass [file]: Get PEM password from controlling tty before we daemonize.\n"
642     "--auth-nocache  : Don't cache --askpass or --auth-user-pass passwords.\n"
643     "--crl-verify crl ['dir']: Check peer certificate against a CRL.\n"
644     "--tls-verify cmd: Run command cmd to verify the X509 name of a\n"
645     "                  pending TLS connection that has otherwise passed all other\n"
646     "                  tests of certification.  cmd should return 0 to allow\n"
647     "                  TLS handshake to proceed, or 1 to fail.  (cmd is\n"
648     "                  executed as 'cmd certificate_depth subject')\n"
649     "--tls-export-cert [directory] : Get peer cert in PEM format and store it \n"
650     "                  in an openvpn temporary file in [directory]. Peer cert is \n"
651     "                  stored before tls-verify script execution and deleted after.\n"
652     "--verify-x509-name name: Accept connections only from a host with X509 subject\n"
653     "                  DN name. The remote host must also pass all other tests\n"
654     "                  of verification.\n"
655     "--ns-cert-type t: (DEPRECATED) Require that peer certificate was signed with \n"
656     "                  an explicit nsCertType designation t = 'client' | 'server'.\n"
657     "--x509-track x  : Save peer X509 attribute x in environment for use by\n"
658     "                  plugins and management interface.\n"
659 #ifdef HAVE_EXPORT_KEYING_MATERIAL
660     "--keying-material-exporter label len : Save Exported Keying Material (RFC5705)\n"
661     "                  of len bytes (min. 16 bytes) using label in environment for use by plugins.\n"
662 #endif
663     "--remote-cert-ku v ... : Require that the peer certificate was signed with\n"
664     "                  explicit key usage, you can specify more than one value.\n"
665     "                  value should be given in hex format.\n"
666     "--remote-cert-eku oid : Require that the peer certificate was signed with\n"
667     "                  explicit extended key usage. Extended key usage can be encoded\n"
668     "                  as an object identifier or OpenSSL string representation.\n"
669     "--remote-cert-tls t: Require that peer certificate was signed with explicit\n"
670     "                  key usage and extended key usage based on RFC3280 TLS rules.\n"
671     "                  t = 'client' | 'server'.\n"
672 #ifdef ENABLE_PKCS11
673     "\n"
674     "PKCS#11 Options:\n"
675     "--pkcs11-providers provider ... : PKCS#11 provider to load.\n"
676     "--pkcs11-protected-authentication [0|1] ... : Use PKCS#11 protected authentication\n"
677     "                              path. Set for each provider.\n"
678     "--pkcs11-private-mode hex ...   : PKCS#11 private key mode mask.\n"
679     "                              0       : Try  to determine automatically (default).\n"
680     "                              1       : Use Sign.\n"
681     "                              2       : Use SignRecover.\n"
682     "                              4       : Use Decrypt.\n"
683     "                              8       : Use Unwrap.\n"
684     "--pkcs11-cert-private [0|1] ... : Set if login should be performed before\n"
685     "                                  certificate can be accessed. Set for each provider.\n"
686     "--pkcs11-pin-cache seconds      : Number of seconds to cache PIN. The default is -1\n"
687     "                                  cache until token is removed.\n"
688     "--pkcs11-id-management          : Acquire identity from management interface.\n"
689     "--pkcs11-id serialized-id 'id'  : Identity to use, get using standalone --show-pkcs11-ids\n"
690 #endif                  /* ENABLE_PKCS11 */
691     "\n"
692     "SSL Library information:\n"
693     "--show-ciphers  : Show cipher algorithms to use with --cipher option.\n"
694     "--show-digests  : Show message digest algorithms to use with --auth option.\n"
695     "--show-engines  : Show hardware crypto accelerator engines (if available).\n"
696     "--show-tls      : Show all TLS ciphers (TLS used only as a control channel).\n"
697 #ifdef _WIN32
698     "\n"
699     "Windows Specific:\n"
700     "--win-sys path    : Pathname of Windows system directory. Default is the pathname\n"
701     "                    from SystemRoot environment variable.\n"
702     "--ip-win32 method : When using --ifconfig on Windows, set TAP-Windows adapter\n"
703     "                    IP address using method = manual, netsh, ipapi,\n"
704     "                    dynamic, or adaptive (default = adaptive).\n"
705     "                    Dynamic method allows two optional parameters:\n"
706     "                    offset: DHCP server address offset (> -256 and < 256).\n"
707     "                            If 0, use network address, if >0, take nth\n"
708     "                            address forward from network address, if <0,\n"
709     "                            take nth address backward from broadcast\n"
710     "                            address.\n"
711     "                            Default is 0.\n"
712     "                    lease-time: Lease time in seconds.\n"
713     "                                Default is one year.\n"
714     "--route-method    : Which method to use for adding routes on Windows?\n"
715     "                    adaptive (default) -- Try ipapi then fall back to exe.\n"
716     "                    ipapi -- Use IP helper API.\n"
717     "                    exe -- Call the route.exe shell command.\n"
718     "--dhcp-option type [parm] : Set extended TAP-Windows properties, must\n"
719     "                    be used with --ip-win32 dynamic.  For options\n"
720     "                    which allow multiple addresses,\n"
721     "                    --dhcp-option must be repeated.\n"
722     "                    DOMAIN name : Set DNS suffix\n"
723     "                    DOMAIN-SEARCH entry : Add entry to DNS domain search list\n"
724     "                    DNS addr    : Set domain name server address(es) (IPv4 and IPv6)\n"
725     "                    NTP         : Set NTP server address(es)\n"
726     "                    NBDD        : Set NBDD server address(es)\n"
727     "                    WINS addr   : Set WINS server address(es)\n"
728     "                    NBT type    : Set NetBIOS over TCP/IP Node type\n"
729     "                                  1: B, 2: P, 4: M, 8: H\n"
730     "                    NBS id      : Set NetBIOS scope ID\n"
731     "                    DISABLE-NBT : Disable Netbios-over-TCP/IP.\n"
732     "--dhcp-renew       : Ask Windows to renew the TAP adapter lease on startup.\n"
733     "--dhcp-pre-release : Ask Windows to release the previous TAP adapter lease on\n"
734     "                       startup.\n"
735     "--register-dns  : Run ipconfig /flushdns and ipconfig /registerdns\n"
736     "                  on connection initiation.\n"
737     "--tap-sleep n   : Sleep for n seconds after TAP adapter open before\n"
738     "                  attempting to set adapter properties.\n"
739     "--pause-exit         : When run from a console window, pause before exiting.\n"
740     "--service ex [0|1]   : For use when " PACKAGE_NAME " is being instantiated by a\n"
741     "                       service, and should not be used directly by end-users.\n"
742     "                       ex is the name of an event object which, when\n"
743     "                       signaled, will cause " PACKAGE_NAME " to exit.  A second\n"
744     "                       optional parameter controls the initial state of ex.\n"
745     "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
746     "                  after TAP adapter is up and routes have been added.\n"
747     "--windows-driver   : Which tun driver to use?\n"
748     "                     tap-windows6 (default)\n"
749     "                     wintun\n"
750     "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
751     "Windows Standalone Options:\n"
752     "\n"
753     "--show-adapters : Show all TAP-Windows adapters.\n"
754     "--show-net      : Show " PACKAGE_NAME "'s view of routing table and net adapter list.\n"
755     "--show-valid-subnets : Show valid subnets for --dev tun emulation.\n"
756     "--allow-nonadmin [TAP-adapter] : Allow " PACKAGE_NAME " running without admin privileges\n"
757     "                                 to access TAP adapter.\n"
758 #endif /* ifdef _WIN32 */
759     "\n"
760     "Generate a new key :\n"
761     "--genkey secret file   : Generate a new random key of type and write to file\n"
762     "                         (for use with --secret, --tls-auth or --tls-crypt)."
763 #ifdef ENABLE_FEATURE_TUN_PERSIST
764     "\n"
765     "Tun/tap config mode (available with linux 2.4+):\n"
766     "--mktun         : Create a persistent tunnel.\n"
767     "--rmtun         : Remove a persistent tunnel.\n"
768     "--dev tunX|tapX : tun/tap device\n"
769     "--dev-type dt   : Device type.  See tunnel options above for details.\n"
770     "--user user     : User to set privilege to.\n"
771     "--group group   : Group to set privilege to.\n"
772 #endif
773 #ifdef ENABLE_PKCS11
774     "\n"
775     "PKCS#11 standalone options:\n"
776 #ifdef DEFAULT_PKCS11_MODULE
777     "--show-pkcs11-ids [provider] [cert_private] : Show PKCS#11 available ids.\n"
778 #else
779     "--show-pkcs11-ids provider [cert_private] : Show PKCS#11 available ids.\n"
780 #endif
781     "                                            --verb option can be added *BEFORE* this.\n"
782 #endif                          /* ENABLE_PKCS11 */
783     "\n"
784     "General Standalone Options:\n"
785 #ifdef ENABLE_DEBUG
786     "--show-gateway : Show info about default gateway.\n"
787 #endif
788 ;
789 
790 #endif /* !ENABLE_SMALL */
791 
792 /*
793  * This is where the options defaults go.
794  * Any option not explicitly set here
795  * will be set to 0.
796  */
797 void
init_options(struct options * o,const bool init_gc)798 init_options(struct options *o, const bool init_gc)
799 {
800     CLEAR(*o);
801     if (init_gc)
802     {
803         gc_init(&o->gc);
804         o->gc_owned = true;
805     }
806     o->mode = MODE_POINT_TO_POINT;
807     o->topology = TOP_NET30;
808     o->ce.proto = PROTO_UDP;
809     o->ce.af = AF_UNSPEC;
810     o->ce.bind_ipv6_only = false;
811     o->ce.connect_retry_seconds = 5;
812     o->ce.connect_retry_seconds_max = 300;
813     o->ce.connect_timeout = 120;
814     o->connect_retry_max = 0;
815     o->ce.local_port = o->ce.remote_port = OPENVPN_PORT;
816     o->verbosity = 1;
817     o->status_file_update_freq = 60;
818     o->status_file_version = 1;
819     o->ce.bind_local = true;
820     o->ce.tun_mtu = TUN_MTU_DEFAULT;
821     o->ce.link_mtu = LINK_MTU_DEFAULT;
822     o->ce.mtu_discover_type = -1;
823     o->ce.mssfix = MSSFIX_DEFAULT;
824     o->route_delay_window = 30;
825     o->resolve_retry_seconds = RESOLV_RETRY_INFINITE;
826     o->resolve_in_advance = false;
827     o->proto_force = -1;
828     o->occ = true;
829 #ifdef ENABLE_MANAGEMENT
830     o->management_log_history_cache = 250;
831     o->management_echo_buffer_size = 100;
832     o->management_state_buffer_size = 100;
833 #endif
834 #ifdef ENABLE_FEATURE_TUN_PERSIST
835     o->persist_mode = 1;
836 #endif
837 #ifdef _WIN32
838 #if 0
839     o->tuntap_options.ip_win32_type = IPW32_SET_ADAPTIVE;
840 #else
841     o->tuntap_options.ip_win32_type = IPW32_SET_DHCP_MASQ;
842 #endif
843     o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
844     o->tuntap_options.dhcp_masq_offset = 0;     /* use network address as internal DHCP server address */
845     o->route_method = ROUTE_METHOD_ADAPTIVE;
846     o->block_outside_dns = false;
847     o->windows_driver = WINDOWS_DRIVER_TAP_WINDOWS6;
848 #endif
849     o->vlan_accept = VLAN_ALL;
850     o->vlan_pvid = 1;
851     o->real_hash_size = 256;
852     o->virtual_hash_size = 256;
853     o->n_bcast_buf = 256;
854     o->tcp_queue_limit = 64;
855     o->max_clients = 1024;
856     o->max_routes_per_client = 256;
857     o->stale_routes_check_interval = 0;
858     o->ifconfig_pool_persist_refresh_freq = 600;
859 #if P2MP
860     o->scheduled_exit_interval = 5;
861 #endif
862     o->ncp_enabled = true;
863     o->ncp_ciphers = "AES-256-GCM:AES-128-GCM";
864     o->authname = "SHA1";
865     o->prng_hash = "SHA1";
866     o->prng_nonce_secret_len = 16;
867     o->replay = true;
868     o->replay_window = DEFAULT_SEQ_BACKTRACK;
869     o->replay_time = DEFAULT_TIME_BACKTRACK;
870     o->key_direction = KEY_DIRECTION_BIDIRECTIONAL;
871 #ifdef ENABLE_PREDICTION_RESISTANCE
872     o->use_prediction_resistance = false;
873 #endif
874     o->tls_timeout = 2;
875     o->renegotiate_bytes = -1;
876     o->renegotiate_seconds = 3600;
877     o->renegotiate_seconds_min = -1;
878     o->handshake_window = 60;
879     o->transition_window = 3600;
880     o->tls_cert_profile = NULL;
881     o->ecdh_curve = NULL;
882 #ifdef ENABLE_X509ALTUSERNAME
883     o->x509_username_field = X509_USERNAME_FIELD_DEFAULT;
884 #endif
885 #ifdef ENABLE_PKCS11
886     o->pkcs11_pin_cache_period = -1;
887 #endif                  /* ENABLE_PKCS11 */
888 
889 /* P2MP server context features */
890     o->auth_token_generate = false;
891 
892     /* Set default --tmp-dir */
893 #ifdef _WIN32
894     /* On Windows, find temp dir via environment variables */
895     o->tmp_dir = win_get_tempdir();
896 #else
897     /* Non-windows platforms use $TMPDIR, and if not set, default to '/tmp' */
898     o->tmp_dir = getenv("TMPDIR");
899     if (!o->tmp_dir)
900     {
901         o->tmp_dir = "/tmp";
902     }
903 #endif /* _WIN32 */
904     o->allow_recursive_routing = false;
905 }
906 
907 void
uninit_options(struct options * o)908 uninit_options(struct options *o)
909 {
910     if (o->gc_owned)
911     {
912         gc_free(&o->gc);
913     }
914 }
915 
916 struct pull_filter
917 {
918 #define PUF_TYPE_UNDEF  0    /** undefined filter type */
919 #define PUF_TYPE_ACCEPT 1    /** filter type to accept a matching option */
920 #define PUF_TYPE_IGNORE 2    /** filter type to ignore a matching option */
921 #define PUF_TYPE_REJECT 3    /** filter type to reject and trigger SIGUSR1 */
922     int type;
923     int size;
924     char *pattern;
925     struct pull_filter *next;
926 };
927 
928 struct pull_filter_list
929 {
930     struct pull_filter *head;
931     struct pull_filter *tail;
932 };
933 
934 static const char *
pull_filter_type_name(int type)935 pull_filter_type_name(int type)
936 {
937     if (type == PUF_TYPE_ACCEPT)
938     {
939         return "accept";
940     }
941     if (type == PUF_TYPE_IGNORE)
942     {
943         return "ignore";
944     }
945     if (type == PUF_TYPE_REJECT)
946     {
947         return "reject";
948     }
949     else
950     {
951         return "???";
952     }
953 }
954 
955 #ifndef ENABLE_SMALL
956 
957 #define SHOW_PARM(name, value, format) msg(D_SHOW_PARMS, "  " #name " = " format, (value))
958 #define SHOW_STR(var)       SHOW_PARM(var, (o->var ? o->var : "[UNDEF]"), "'%s'")
959 #define SHOW_STR_INLINE(var)    SHOW_PARM(var, \
960                                           o->var ## _inline ? "[INLINE]" : \
961                                           (o->var ? o->var : "[UNDEF]"), \
962                                           "'%s'")
963 #define SHOW_INT(var)       SHOW_PARM(var, o->var, "%d")
964 #define SHOW_UINT(var)      SHOW_PARM(var, o->var, "%u")
965 #define SHOW_INT64(var)     SHOW_PARM(var, o->var, "%" PRIi64)
966 #define SHOW_UNSIGNED(var)  SHOW_PARM(var, o->var, "0x%08x")
967 #define SHOW_BOOL(var)      SHOW_PARM(var, (o->var ? "ENABLED" : "DISABLED"), "%s");
968 
969 #endif
970 
971 static void
setenv_connection_entry(struct env_set * es,const struct connection_entry * e,const int i)972 setenv_connection_entry(struct env_set *es,
973                         const struct connection_entry *e,
974                         const int i)
975 {
976     setenv_str_i(es, "proto", proto2ascii(e->proto, e->af, false), i);
977     setenv_str_i(es, "local", e->local, i);
978     setenv_str_i(es, "local_port", e->local_port, i);
979     setenv_str_i(es, "remote", e->remote, i);
980     setenv_str_i(es, "remote_port", e->remote_port, i);
981 
982     if (e->http_proxy_options)
983     {
984         setenv_str_i(es, "http_proxy_server", e->http_proxy_options->server, i);
985         setenv_str_i(es, "http_proxy_port", e->http_proxy_options->port, i);
986     }
987     if (e->socks_proxy_server)
988     {
989         setenv_str_i(es, "socks_proxy_server", e->socks_proxy_server, i);
990         setenv_str_i(es, "socks_proxy_port", e->socks_proxy_port, i);
991     }
992 }
993 
994 void
setenv_settings(struct env_set * es,const struct options * o)995 setenv_settings(struct env_set *es, const struct options *o)
996 {
997     setenv_str(es, "config", o->config);
998     setenv_int(es, "verb", o->verbosity);
999     setenv_int(es, "daemon", o->daemon);
1000     setenv_int(es, "daemon_log_redirect", o->log);
1001     setenv_long_long(es, "daemon_start_time", time(NULL));
1002     setenv_int(es, "daemon_pid", platform_getpid());
1003 
1004     if (o->connection_list)
1005     {
1006         int i;
1007         for (i = 0; i < o->connection_list->len; ++i)
1008         {
1009             setenv_connection_entry(es, o->connection_list->array[i], i+1);
1010         }
1011     }
1012     else
1013     {
1014         setenv_connection_entry(es, &o->ce, 1);
1015     }
1016 }
1017 
1018 static in_addr_t
get_ip_addr(const char * ip_string,int msglevel,bool * error)1019 get_ip_addr(const char *ip_string, int msglevel, bool *error)
1020 {
1021     unsigned int flags = GETADDR_HOST_ORDER;
1022     bool succeeded = false;
1023     in_addr_t ret;
1024 
1025     if (msglevel & M_FATAL)
1026     {
1027         flags |= GETADDR_FATAL;
1028     }
1029 
1030     ret = getaddr(flags, ip_string, 0, &succeeded, NULL);
1031     if (!succeeded && error)
1032     {
1033         *error = true;
1034     }
1035     return ret;
1036 }
1037 
1038 /**
1039  * Returns newly allocated string containing address part without "/nn".
1040  *
1041  * If gc != NULL, the allocated memory is registered in the supplied gc.
1042  */
1043 static char *
get_ipv6_addr_no_netbits(const char * addr,struct gc_arena * gc)1044 get_ipv6_addr_no_netbits(const char *addr, struct gc_arena *gc)
1045 {
1046     const char *end = strchr(addr, '/');
1047     char *ret = NULL;
1048     if (NULL == end)
1049     {
1050         ret = string_alloc(addr, gc);
1051     }
1052     else
1053     {
1054         size_t len = end - addr;
1055         ret = gc_malloc(len + 1, true, gc);
1056         memcpy(ret, addr, len);
1057     }
1058     return ret;
1059 }
1060 
1061 static bool
ipv6_addr_safe_hexplusbits(const char * ipv6_prefix_spec)1062 ipv6_addr_safe_hexplusbits( const char *ipv6_prefix_spec )
1063 {
1064     struct in6_addr t_addr;
1065     unsigned int t_bits;
1066 
1067     return get_ipv6_addr( ipv6_prefix_spec, &t_addr, &t_bits, M_WARN );
1068 }
1069 
1070 static char *
string_substitute(const char * src,int from,int to,struct gc_arena * gc)1071 string_substitute(const char *src, int from, int to, struct gc_arena *gc)
1072 {
1073     char *ret = (char *) gc_malloc(strlen(src) + 1, true, gc);
1074     char *dest = ret;
1075     char c;
1076 
1077     do
1078     {
1079         c = *src++;
1080         if (c == from)
1081         {
1082             c = to;
1083         }
1084         *dest++ = c;
1085     }
1086     while (c);
1087     return ret;
1088 }
1089 
1090 static uint8_t *
parse_hash_fingerprint(const char * str,int nbytes,int msglevel,struct gc_arena * gc)1091 parse_hash_fingerprint(const char *str, int nbytes, int msglevel, struct gc_arena *gc)
1092 {
1093     int i;
1094     const char *cp = str;
1095     uint8_t *ret = (uint8_t *) gc_malloc(nbytes, true, gc);
1096     char term = 1;
1097     int byte;
1098     char bs[3];
1099 
1100     for (i = 0; i < nbytes; ++i)
1101     {
1102         if (strlen(cp) < 2)
1103         {
1104             msg(msglevel, "format error in hash fingerprint: %s", str);
1105         }
1106         bs[0] = *cp++;
1107         bs[1] = *cp++;
1108         bs[2] = 0;
1109         byte = 0;
1110         if (sscanf(bs, "%x", &byte) != 1)
1111         {
1112             msg(msglevel, "format error in hash fingerprint hex byte: %s", str);
1113         }
1114         ret[i] = (uint8_t)byte;
1115         term = *cp++;
1116         if (term != ':' && term != 0)
1117         {
1118             msg(msglevel, "format error in hash fingerprint delimiter: %s", str);
1119         }
1120         if (term == 0)
1121         {
1122             break;
1123         }
1124     }
1125     if (term != 0 || i != nbytes-1)
1126     {
1127         msg(msglevel, "hash fingerprint is different length than expected (%d bytes): %s", nbytes, str);
1128     }
1129     return ret;
1130 }
1131 
1132 #ifdef _WIN32
1133 
1134 #ifndef ENABLE_SMALL
1135 
1136 static void
show_dhcp_option_list(const char * name,const char * const * array,int len)1137 show_dhcp_option_list(const char *name, const char * const*array, int len)
1138 {
1139     int i;
1140     for (i = 0; i < len; ++i)
1141     {
1142         msg(D_SHOW_PARMS, "  %s[%d] = %s", name, i, array[i] );
1143     }
1144 }
1145 
1146 static void
show_dhcp_option_addrs(const char * name,const in_addr_t * array,int len)1147 show_dhcp_option_addrs(const char *name, const in_addr_t *array, int len)
1148 {
1149     struct gc_arena gc = gc_new();
1150     int i;
1151     for (i = 0; i < len; ++i)
1152     {
1153         msg(D_SHOW_PARMS, "  %s[%d] = %s",
1154             name,
1155             i,
1156             print_in_addr_t(array[i], 0, &gc));
1157     }
1158     gc_free(&gc);
1159 }
1160 
1161 static void
show_tuntap_options(const struct tuntap_options * o)1162 show_tuntap_options(const struct tuntap_options *o)
1163 {
1164     SHOW_BOOL(ip_win32_defined);
1165     SHOW_INT(ip_win32_type);
1166     SHOW_INT(dhcp_masq_offset);
1167     SHOW_INT(dhcp_lease_time);
1168     SHOW_INT(tap_sleep);
1169     SHOW_BOOL(dhcp_options);
1170     SHOW_BOOL(dhcp_renew);
1171     SHOW_BOOL(dhcp_pre_release);
1172     SHOW_STR(domain);
1173     SHOW_STR(netbios_scope);
1174     SHOW_INT(netbios_node_type);
1175     SHOW_BOOL(disable_nbt);
1176 
1177     show_dhcp_option_addrs("DNS", o->dns, o->dns_len);
1178     show_dhcp_option_addrs("WINS", o->wins, o->wins_len);
1179     show_dhcp_option_addrs("NTP", o->ntp, o->ntp_len);
1180     show_dhcp_option_addrs("NBDD", o->nbdd, o->nbdd_len);
1181     show_dhcp_option_list("DOMAIN-SEARCH", o->domain_search_list, o->domain_search_list_len);
1182 }
1183 
1184 #endif /* ifndef ENABLE_SMALL */
1185 #endif /* ifdef _WIN32 */
1186 
1187 #if defined(_WIN32) || defined(TARGET_ANDROID)
1188 static void
dhcp_option_dns6_parse(const char * parm,struct in6_addr * dns6_list,int * len,int msglevel)1189 dhcp_option_dns6_parse(const char *parm, struct in6_addr *dns6_list, int *len, int msglevel)
1190 {
1191     struct in6_addr addr;
1192     if (*len >= N_DHCP_ADDR)
1193     {
1194         msg(msglevel, "--dhcp-option DNS: maximum of %d IPv6 dns servers can be specified",
1195             N_DHCP_ADDR);
1196     }
1197     else if (get_ipv6_addr(parm, &addr, NULL, msglevel))
1198     {
1199         dns6_list[(*len)++] = addr;
1200     }
1201 }
1202 static void
dhcp_option_address_parse(const char * name,const char * parm,in_addr_t * array,int * len,int msglevel)1203 dhcp_option_address_parse(const char *name, const char *parm, in_addr_t *array, int *len, int msglevel)
1204 {
1205     if (*len >= N_DHCP_ADDR)
1206     {
1207         msg(msglevel, "--dhcp-option %s: maximum of %d %s servers can be specified",
1208             name,
1209             N_DHCP_ADDR,
1210             name);
1211     }
1212     else
1213     {
1214         if (ip_addr_dotted_quad_safe(parm)) /* FQDN -- IP address only */
1215         {
1216             bool error = false;
1217             const in_addr_t addr = get_ip_addr(parm, msglevel, &error);
1218             if (!error)
1219             {
1220                 array[(*len)++] = addr;
1221             }
1222         }
1223         else
1224         {
1225             msg(msglevel, "dhcp-option parameter %s '%s' must be an IP address", name, parm);
1226         }
1227     }
1228 }
1229 
1230 #endif /* if defined(_WIN32) || defined(TARGET_ANDROID) */
1231 
1232 static const char *
print_vlan_accept(enum vlan_acceptable_frames mode)1233 print_vlan_accept(enum vlan_acceptable_frames mode)
1234 {
1235     switch (mode)
1236     {
1237         case VLAN_ONLY_TAGGED:
1238             return "tagged";
1239 
1240         case VLAN_ONLY_UNTAGGED_OR_PRIORITY:
1241             return "untagged";
1242 
1243         case VLAN_ALL:
1244             return "all";
1245     }
1246     return NULL;
1247 }
1248 
1249 #if P2MP
1250 
1251 #ifndef ENABLE_SMALL
1252 
1253 static void
show_p2mp_parms(const struct options * o)1254 show_p2mp_parms(const struct options *o)
1255 {
1256     struct gc_arena gc = gc_new();
1257 
1258     msg(D_SHOW_PARMS, "  server_network = %s", print_in_addr_t(o->server_network, 0, &gc));
1259     msg(D_SHOW_PARMS, "  server_netmask = %s", print_in_addr_t(o->server_netmask, 0, &gc));
1260     msg(D_SHOW_PARMS, "  server_network_ipv6 = %s", print_in6_addr(o->server_network_ipv6, 0, &gc) );
1261     SHOW_INT(server_netbits_ipv6);
1262     msg(D_SHOW_PARMS, "  server_bridge_ip = %s", print_in_addr_t(o->server_bridge_ip, 0, &gc));
1263     msg(D_SHOW_PARMS, "  server_bridge_netmask = %s", print_in_addr_t(o->server_bridge_netmask, 0, &gc));
1264     msg(D_SHOW_PARMS, "  server_bridge_pool_start = %s", print_in_addr_t(o->server_bridge_pool_start, 0, &gc));
1265     msg(D_SHOW_PARMS, "  server_bridge_pool_end = %s", print_in_addr_t(o->server_bridge_pool_end, 0, &gc));
1266     if (o->push_list.head)
1267     {
1268         const struct push_entry *e = o->push_list.head;
1269         while (e)
1270         {
1271             if (e->enable)
1272             {
1273                 msg(D_SHOW_PARMS, "  push_entry = '%s'", e->option);
1274             }
1275             e = e->next;
1276         }
1277     }
1278     SHOW_BOOL(ifconfig_pool_defined);
1279     msg(D_SHOW_PARMS, "  ifconfig_pool_start = %s", print_in_addr_t(o->ifconfig_pool_start, 0, &gc));
1280     msg(D_SHOW_PARMS, "  ifconfig_pool_end = %s", print_in_addr_t(o->ifconfig_pool_end, 0, &gc));
1281     msg(D_SHOW_PARMS, "  ifconfig_pool_netmask = %s", print_in_addr_t(o->ifconfig_pool_netmask, 0, &gc));
1282     SHOW_STR(ifconfig_pool_persist_filename);
1283     SHOW_INT(ifconfig_pool_persist_refresh_freq);
1284     SHOW_BOOL(ifconfig_ipv6_pool_defined);
1285     msg(D_SHOW_PARMS, "  ifconfig_ipv6_pool_base = %s", print_in6_addr(o->ifconfig_ipv6_pool_base, 0, &gc));
1286     SHOW_INT(ifconfig_ipv6_pool_netbits);
1287     SHOW_INT(n_bcast_buf);
1288     SHOW_INT(tcp_queue_limit);
1289     SHOW_INT(real_hash_size);
1290     SHOW_INT(virtual_hash_size);
1291     SHOW_STR(client_connect_script);
1292     SHOW_STR(learn_address_script);
1293     SHOW_STR(client_disconnect_script);
1294     SHOW_STR(client_config_dir);
1295     SHOW_BOOL(ccd_exclusive);
1296     SHOW_STR(tmp_dir);
1297     SHOW_BOOL(push_ifconfig_defined);
1298     msg(D_SHOW_PARMS, "  push_ifconfig_local = %s", print_in_addr_t(o->push_ifconfig_local, 0, &gc));
1299     msg(D_SHOW_PARMS, "  push_ifconfig_remote_netmask = %s", print_in_addr_t(o->push_ifconfig_remote_netmask, 0, &gc));
1300     SHOW_BOOL(push_ifconfig_ipv6_defined);
1301     msg(D_SHOW_PARMS, "  push_ifconfig_ipv6_local = %s/%d", print_in6_addr(o->push_ifconfig_ipv6_local, 0, &gc), o->push_ifconfig_ipv6_netbits );
1302     msg(D_SHOW_PARMS, "  push_ifconfig_ipv6_remote = %s", print_in6_addr(o->push_ifconfig_ipv6_remote, 0, &gc));
1303     SHOW_BOOL(enable_c2c);
1304     SHOW_BOOL(duplicate_cn);
1305     SHOW_INT(cf_max);
1306     SHOW_INT(cf_per);
1307     SHOW_INT(max_clients);
1308     SHOW_INT(max_routes_per_client);
1309     SHOW_STR(auth_user_pass_verify_script);
1310     SHOW_BOOL(auth_user_pass_verify_script_via_file);
1311     SHOW_BOOL(auth_token_generate);
1312     SHOW_INT(auth_token_lifetime);
1313     SHOW_STR_INLINE(auth_token_secret_file);
1314 #if PORT_SHARE
1315     SHOW_STR(port_share_host);
1316     SHOW_STR(port_share_port);
1317 #endif
1318     SHOW_BOOL(vlan_tagging);
1319     msg(D_SHOW_PARMS, "  vlan_accept = %s", print_vlan_accept(o->vlan_accept));
1320     SHOW_INT(vlan_pvid);
1321 
1322     SHOW_BOOL(client);
1323     SHOW_BOOL(pull);
1324     SHOW_STR(auth_user_pass_file);
1325 
1326     gc_free(&gc);
1327 }
1328 
1329 #endif /* ! ENABLE_SMALL */
1330 
1331 static void
option_iroute(struct options * o,const char * network_str,const char * netmask_str,int msglevel)1332 option_iroute(struct options *o,
1333               const char *network_str,
1334               const char *netmask_str,
1335               int msglevel)
1336 {
1337     struct iroute *ir;
1338 
1339     ALLOC_OBJ_GC(ir, struct iroute, &o->gc);
1340     ir->network = getaddr(GETADDR_HOST_ORDER, network_str, 0, NULL, NULL);
1341     ir->netbits = -1;
1342 
1343     if (netmask_str)
1344     {
1345         const in_addr_t netmask = getaddr(GETADDR_HOST_ORDER, netmask_str, 0, NULL, NULL);
1346         if (!netmask_to_netbits(ir->network, netmask, &ir->netbits))
1347         {
1348             msg(msglevel, "in --iroute %s %s : Bad network/subnet specification",
1349                 network_str,
1350                 netmask_str);
1351             return;
1352         }
1353     }
1354 
1355     ir->next = o->iroutes;
1356     o->iroutes = ir;
1357 }
1358 
1359 static void
option_iroute_ipv6(struct options * o,const char * prefix_str,int msglevel)1360 option_iroute_ipv6(struct options *o,
1361                    const char *prefix_str,
1362                    int msglevel)
1363 {
1364     struct iroute_ipv6 *ir;
1365 
1366     ALLOC_OBJ_GC(ir, struct iroute_ipv6, &o->gc);
1367 
1368     if (!get_ipv6_addr(prefix_str, &ir->network, &ir->netbits, msglevel ))
1369     {
1370         msg(msglevel, "in --iroute-ipv6 %s: Bad IPv6 prefix specification",
1371             prefix_str);
1372         return;
1373     }
1374 
1375     ir->next = o->iroutes_ipv6;
1376     o->iroutes_ipv6 = ir;
1377 }
1378 #endif /* P2MP */
1379 
1380 #ifndef ENABLE_SMALL
1381 static void
show_http_proxy_options(const struct http_proxy_options * o)1382 show_http_proxy_options(const struct http_proxy_options *o)
1383 {
1384     int i;
1385     msg(D_SHOW_PARMS, "BEGIN http_proxy");
1386     SHOW_STR(server);
1387     SHOW_STR(port);
1388     SHOW_STR(auth_method_string);
1389     SHOW_STR(auth_file);
1390     SHOW_STR(http_version);
1391     SHOW_STR(user_agent);
1392     for  (i = 0; i < MAX_CUSTOM_HTTP_HEADER && o->custom_headers[i].name; i++)
1393     {
1394         if (o->custom_headers[i].content)
1395         {
1396             msg(D_SHOW_PARMS, "  custom_header[%d] = %s: %s", i,
1397                 o->custom_headers[i].name, o->custom_headers[i].content);
1398         }
1399         else
1400         {
1401             msg(D_SHOW_PARMS, "  custom_header[%d] = %s", i,
1402                 o->custom_headers[i].name);
1403         }
1404     }
1405     msg(D_SHOW_PARMS, "END http_proxy");
1406 }
1407 #endif /* ifndef ENABLE_SMALL */
1408 
1409 void
options_detach(struct options * o)1410 options_detach(struct options *o)
1411 {
1412     gc_detach(&o->gc);
1413     o->routes = NULL;
1414     o->client_nat = NULL;
1415     clone_push_list(o);
1416 }
1417 
1418 void
rol_check_alloc(struct options * options)1419 rol_check_alloc(struct options *options)
1420 {
1421     if (!options->routes)
1422     {
1423         options->routes = new_route_option_list(&options->gc);
1424     }
1425 }
1426 
1427 static void
rol6_check_alloc(struct options * options)1428 rol6_check_alloc(struct options *options)
1429 {
1430     if (!options->routes_ipv6)
1431     {
1432         options->routes_ipv6 = new_route_ipv6_option_list(&options->gc);
1433     }
1434 }
1435 
1436 static void
cnol_check_alloc(struct options * options)1437 cnol_check_alloc(struct options *options)
1438 {
1439     if (!options->client_nat)
1440     {
1441         options->client_nat = new_client_nat_list(&options->gc);
1442     }
1443 }
1444 
1445 #ifndef ENABLE_SMALL
1446 static void
show_connection_entry(const struct connection_entry * o)1447 show_connection_entry(const struct connection_entry *o)
1448 {
1449     msg(D_SHOW_PARMS, "  proto = %s", proto2ascii(o->proto, o->af, false));
1450     SHOW_STR(local);
1451     SHOW_STR(local_port);
1452     SHOW_STR(remote);
1453     SHOW_STR(remote_port);
1454     SHOW_BOOL(remote_float);
1455     SHOW_BOOL(bind_defined);
1456     SHOW_BOOL(bind_local);
1457     SHOW_BOOL(bind_ipv6_only);
1458     SHOW_INT(connect_retry_seconds);
1459     SHOW_INT(connect_timeout);
1460 
1461     if (o->http_proxy_options)
1462     {
1463         show_http_proxy_options(o->http_proxy_options);
1464     }
1465     SHOW_STR(socks_proxy_server);
1466     SHOW_STR(socks_proxy_port);
1467     SHOW_INT(tun_mtu);
1468     SHOW_BOOL(tun_mtu_defined);
1469     SHOW_INT(link_mtu);
1470     SHOW_BOOL(link_mtu_defined);
1471     SHOW_INT(tun_mtu_extra);
1472     SHOW_BOOL(tun_mtu_extra_defined);
1473 
1474     SHOW_INT(mtu_discover_type);
1475 
1476 #ifdef ENABLE_FRAGMENT
1477     SHOW_INT(fragment);
1478 #endif
1479     SHOW_INT(mssfix);
1480 
1481     SHOW_INT(explicit_exit_notification);
1482 
1483     SHOW_STR_INLINE(tls_auth_file);
1484     SHOW_PARM(key_direction, keydirection2ascii(o->key_direction, false, true),
1485               "%s");
1486     SHOW_STR_INLINE(tls_crypt_file);
1487     SHOW_STR_INLINE(tls_crypt_v2_file);
1488 }
1489 
1490 
1491 static void
show_connection_entries(const struct options * o)1492 show_connection_entries(const struct options *o)
1493 {
1494     if (o->connection_list)
1495     {
1496         const struct connection_list *l = o->connection_list;
1497         int i;
1498         for (i = 0; i < l->len; ++i)
1499         {
1500             msg(D_SHOW_PARMS, "Connection profiles [%d]:", i);
1501             show_connection_entry(l->array[i]);
1502         }
1503     }
1504     else
1505     {
1506         msg(D_SHOW_PARMS, "Connection profiles [default]:");
1507         show_connection_entry(&o->ce);
1508     }
1509     msg(D_SHOW_PARMS, "Connection profiles END");
1510 }
1511 
1512 static void
show_pull_filter_list(const struct pull_filter_list * l)1513 show_pull_filter_list(const struct pull_filter_list *l)
1514 {
1515     struct pull_filter *f;
1516     if (!l)
1517     {
1518         return;
1519     }
1520 
1521     msg(D_SHOW_PARMS, "  Pull filters:");
1522     for (f = l->head; f; f = f->next)
1523     {
1524         msg(D_SHOW_PARMS, "    %s \"%s\"", pull_filter_type_name(f->type), f->pattern);
1525     }
1526 }
1527 
1528 #endif /* ifndef ENABLE_SMALL */
1529 
1530 void
show_settings(const struct options * o)1531 show_settings(const struct options *o)
1532 {
1533 #ifndef ENABLE_SMALL
1534     msg(D_SHOW_PARMS, "Current Parameter Settings:");
1535 
1536     SHOW_STR(config);
1537 
1538     SHOW_INT(mode);
1539 
1540 #ifdef ENABLE_FEATURE_TUN_PERSIST
1541     SHOW_BOOL(persist_config);
1542     SHOW_INT(persist_mode);
1543 #endif
1544 
1545     SHOW_BOOL(show_ciphers);
1546     SHOW_BOOL(show_digests);
1547     SHOW_BOOL(show_engines);
1548     SHOW_BOOL(genkey);
1549     SHOW_STR(genkey_filename);
1550     SHOW_STR(key_pass_file);
1551     SHOW_BOOL(show_tls_ciphers);
1552 
1553     SHOW_INT(connect_retry_max);
1554     show_connection_entries(o);
1555 
1556     SHOW_BOOL(remote_random);
1557 
1558     SHOW_STR(ipchange);
1559     SHOW_STR(dev);
1560     SHOW_STR(dev_type);
1561     SHOW_STR(dev_node);
1562     SHOW_STR(lladdr);
1563     SHOW_INT(topology);
1564     SHOW_STR(ifconfig_local);
1565     SHOW_STR(ifconfig_remote_netmask);
1566     SHOW_BOOL(ifconfig_noexec);
1567     SHOW_BOOL(ifconfig_nowarn);
1568     SHOW_STR(ifconfig_ipv6_local);
1569     SHOW_INT(ifconfig_ipv6_netbits);
1570     SHOW_STR(ifconfig_ipv6_remote);
1571 
1572 #ifdef ENABLE_FEATURE_SHAPER
1573     SHOW_INT(shaper);
1574 #endif
1575     SHOW_INT(mtu_test);
1576 
1577     SHOW_BOOL(mlock);
1578 
1579     SHOW_INT(keepalive_ping);
1580     SHOW_INT(keepalive_timeout);
1581     SHOW_INT(inactivity_timeout);
1582     SHOW_INT64(inactivity_minimum_bytes);
1583     SHOW_INT(ping_send_timeout);
1584     SHOW_INT(ping_rec_timeout);
1585     SHOW_INT(ping_rec_timeout_action);
1586     SHOW_BOOL(ping_timer_remote);
1587     SHOW_INT(remap_sigusr1);
1588     SHOW_BOOL(persist_tun);
1589     SHOW_BOOL(persist_local_ip);
1590     SHOW_BOOL(persist_remote_ip);
1591     SHOW_BOOL(persist_key);
1592 
1593 #if PASSTOS_CAPABILITY
1594     SHOW_BOOL(passtos);
1595 #endif
1596 
1597     SHOW_INT(resolve_retry_seconds);
1598     SHOW_BOOL(resolve_in_advance);
1599 
1600     SHOW_STR(username);
1601     SHOW_STR(groupname);
1602     SHOW_STR(chroot_dir);
1603     SHOW_STR(cd_dir);
1604 #ifdef ENABLE_SELINUX
1605     SHOW_STR(selinux_context);
1606 #endif
1607     SHOW_STR(writepid);
1608     SHOW_STR(up_script);
1609     SHOW_STR(down_script);
1610     SHOW_BOOL(down_pre);
1611     SHOW_BOOL(up_restart);
1612     SHOW_BOOL(up_delay);
1613     SHOW_BOOL(daemon);
1614     SHOW_INT(inetd);
1615     SHOW_BOOL(log);
1616     SHOW_BOOL(suppress_timestamps);
1617     SHOW_BOOL(machine_readable_output);
1618     SHOW_INT(nice);
1619     SHOW_INT(verbosity);
1620     SHOW_INT(mute);
1621 #ifdef ENABLE_DEBUG
1622     SHOW_INT(gremlin);
1623 #endif
1624     SHOW_STR(status_file);
1625     SHOW_INT(status_file_version);
1626     SHOW_INT(status_file_update_freq);
1627 
1628     SHOW_BOOL(occ);
1629     SHOW_INT(rcvbuf);
1630     SHOW_INT(sndbuf);
1631 #if defined(TARGET_LINUX) && HAVE_DECL_SO_MARK
1632     SHOW_INT(mark);
1633 #endif
1634     SHOW_INT(sockflags);
1635 
1636     SHOW_BOOL(fast_io);
1637 
1638 #ifdef USE_COMP
1639     SHOW_INT(comp.alg);
1640     SHOW_INT(comp.flags);
1641 #endif
1642 
1643     SHOW_STR(route_script);
1644     SHOW_STR(route_default_gateway);
1645     SHOW_INT(route_default_metric);
1646     SHOW_BOOL(route_noexec);
1647     SHOW_INT(route_delay);
1648     SHOW_INT(route_delay_window);
1649     SHOW_BOOL(route_delay_defined);
1650     SHOW_BOOL(route_nopull);
1651     SHOW_BOOL(route_gateway_via_dhcp);
1652     SHOW_BOOL(allow_pull_fqdn);
1653     show_pull_filter_list(o->pull_filter_list);
1654 
1655     if (o->routes)
1656     {
1657         print_route_options(o->routes, D_SHOW_PARMS);
1658     }
1659 
1660     if (o->client_nat)
1661     {
1662         print_client_nat_list(o->client_nat, D_SHOW_PARMS);
1663     }
1664 
1665 #ifdef ENABLE_MANAGEMENT
1666     SHOW_STR(management_addr);
1667     SHOW_STR(management_port);
1668     SHOW_STR(management_user_pass);
1669     SHOW_INT(management_log_history_cache);
1670     SHOW_INT(management_echo_buffer_size);
1671     SHOW_STR(management_write_peer_info_file);
1672     SHOW_STR(management_client_user);
1673     SHOW_STR(management_client_group);
1674     SHOW_INT(management_flags);
1675 #endif
1676 #ifdef ENABLE_PLUGIN
1677     if (o->plugin_list)
1678     {
1679         plugin_option_list_print(o->plugin_list, D_SHOW_PARMS);
1680     }
1681 #endif
1682 
1683     SHOW_STR_INLINE(shared_secret_file);
1684     SHOW_PARM(key_direction, keydirection2ascii(o->key_direction, false, true), "%s");
1685     SHOW_STR(ciphername);
1686     SHOW_BOOL(ncp_enabled);
1687     SHOW_STR(ncp_ciphers);
1688     SHOW_STR(authname);
1689     SHOW_STR(prng_hash);
1690     SHOW_INT(prng_nonce_secret_len);
1691     SHOW_INT(keysize);
1692 #ifndef ENABLE_CRYPTO_MBEDTLS
1693     SHOW_BOOL(engine);
1694 #endif /* ENABLE_CRYPTO_MBEDTLS */
1695     SHOW_BOOL(replay);
1696     SHOW_BOOL(mute_replay_warnings);
1697     SHOW_INT(replay_window);
1698     SHOW_INT(replay_time);
1699     SHOW_STR(packet_id_file);
1700     SHOW_BOOL(test_crypto);
1701 #ifdef ENABLE_PREDICTION_RESISTANCE
1702     SHOW_BOOL(use_prediction_resistance);
1703 #endif
1704 
1705     SHOW_BOOL(tls_server);
1706     SHOW_BOOL(tls_client);
1707     SHOW_STR_INLINE(ca_file);
1708     SHOW_STR(ca_path);
1709     SHOW_STR_INLINE(dh_file);
1710 #ifdef ENABLE_MANAGEMENT
1711     if ((o->management_flags & MF_EXTERNAL_CERT))
1712     {
1713         SHOW_PARM("cert_file","EXTERNAL_CERT","%s");
1714     }
1715     else
1716 #endif
1717     SHOW_STR_INLINE(cert_file);
1718     SHOW_STR_INLINE(extra_certs_file);
1719 
1720 #ifdef ENABLE_MANAGEMENT
1721     if ((o->management_flags & MF_EXTERNAL_KEY))
1722     {
1723         SHOW_PARM("priv_key_file","EXTERNAL_PRIVATE_KEY","%s");
1724     }
1725     else
1726 #endif
1727     SHOW_STR_INLINE(priv_key_file);
1728 #ifndef ENABLE_CRYPTO_MBEDTLS
1729     SHOW_STR_INLINE(pkcs12_file);
1730 #endif
1731 #ifdef ENABLE_CRYPTOAPI
1732     SHOW_STR(cryptoapi_cert);
1733 #endif
1734     SHOW_STR(cipher_list);
1735     SHOW_STR(cipher_list_tls13);
1736     SHOW_STR(tls_cert_profile);
1737     SHOW_STR(tls_verify);
1738     SHOW_STR(tls_export_cert);
1739     SHOW_INT(verify_x509_type);
1740     SHOW_STR(verify_x509_name);
1741     SHOW_STR_INLINE(crl_file);
1742     SHOW_INT(ns_cert_type);
1743     {
1744         int i;
1745         for (i = 0; i<MAX_PARMS; i++)
1746         {
1747             SHOW_INT(remote_cert_ku[i]);
1748         }
1749     }
1750     SHOW_STR(remote_cert_eku);
1751     SHOW_INT(ssl_flags);
1752 
1753     SHOW_INT(tls_timeout);
1754 
1755     SHOW_INT(renegotiate_bytes);
1756     SHOW_INT(renegotiate_packets);
1757     SHOW_INT(renegotiate_seconds);
1758 
1759     SHOW_INT(handshake_window);
1760     SHOW_INT(transition_window);
1761 
1762     SHOW_BOOL(single_session);
1763     SHOW_BOOL(push_peer_info);
1764     SHOW_BOOL(tls_exit);
1765 
1766     SHOW_STR(tls_crypt_v2_metadata);
1767 
1768 #ifdef ENABLE_PKCS11
1769     {
1770         int i;
1771         for (i = 0; i<MAX_PARMS && o->pkcs11_providers[i] != NULL; i++)
1772         {
1773             SHOW_PARM(pkcs11_providers, o->pkcs11_providers[i], "%s");
1774         }
1775     }
1776     {
1777         int i;
1778         for (i = 0; i<MAX_PARMS; i++)
1779         {
1780             SHOW_PARM(pkcs11_protected_authentication, o->pkcs11_protected_authentication[i] ? "ENABLED" : "DISABLED", "%s");
1781         }
1782     }
1783     {
1784         int i;
1785         for (i = 0; i<MAX_PARMS; i++)
1786         {
1787             SHOW_PARM(pkcs11_private_mode, o->pkcs11_private_mode[i], "%08x");
1788         }
1789     }
1790     {
1791         int i;
1792         for (i = 0; i<MAX_PARMS; i++)
1793         {
1794             SHOW_PARM(pkcs11_cert_private, o->pkcs11_cert_private[i] ? "ENABLED" : "DISABLED", "%s");
1795         }
1796     }
1797     SHOW_INT(pkcs11_pin_cache_period);
1798     SHOW_STR(pkcs11_id);
1799     SHOW_BOOL(pkcs11_id_management);
1800 #endif                  /* ENABLE_PKCS11 */
1801 
1802 #if P2MP
1803     show_p2mp_parms(o);
1804 #endif
1805 
1806 #ifdef _WIN32
1807     SHOW_BOOL(show_net_up);
1808     SHOW_INT(route_method);
1809     SHOW_BOOL(block_outside_dns);
1810     show_tuntap_options(&o->tuntap_options);
1811 #endif
1812 #endif /* ifndef ENABLE_SMALL */
1813 }
1814 
1815 #undef SHOW_PARM
1816 #undef SHOW_STR
1817 #undef SHOW_INT
1818 #undef SHOW_BOOL
1819 
1820 #ifdef ENABLE_MANAGEMENT
1821 
1822 static struct http_proxy_options *
parse_http_proxy_override(const char * server,const char * port,const char * flags,const int msglevel,struct gc_arena * gc)1823 parse_http_proxy_override(const char *server,
1824                           const char *port,
1825                           const char *flags,
1826                           const int msglevel,
1827                           struct gc_arena *gc)
1828 {
1829     if (server && port)
1830     {
1831         struct http_proxy_options *ho;
1832         ALLOC_OBJ_CLEAR_GC(ho, struct http_proxy_options, gc);
1833         ho->server = string_alloc(server, gc);
1834         ho->port = port;
1835         if (flags && !strcmp(flags, "nct"))
1836         {
1837             ho->auth_retry = PAR_NCT;
1838         }
1839         else
1840         {
1841             ho->auth_retry = PAR_ALL;
1842         }
1843         ho->http_version = "1.0";
1844         ho->user_agent = "OpenVPN-Autoproxy/1.0";
1845         return ho;
1846     }
1847     else
1848     {
1849         return NULL;
1850     }
1851 }
1852 
1853 static void
options_postprocess_http_proxy_override(struct options * o)1854 options_postprocess_http_proxy_override(struct options *o)
1855 {
1856     const struct connection_list *l = o->connection_list;
1857     int i;
1858     bool succeed = false;
1859     for (i = 0; i < l->len; ++i)
1860     {
1861         struct connection_entry *ce = l->array[i];
1862         if (ce->proto == PROTO_TCP_CLIENT || ce->proto == PROTO_TCP)
1863         {
1864             ce->http_proxy_options = o->http_proxy_override;
1865             succeed = true;
1866         }
1867     }
1868     if (succeed)
1869     {
1870         for (i = 0; i < l->len; ++i)
1871         {
1872             struct connection_entry *ce = l->array[i];
1873             if (ce->proto == PROTO_UDP)
1874             {
1875                 ce->flags |= CE_DISABLED;
1876             }
1877         }
1878     }
1879     else
1880     {
1881         msg(M_WARN, "Note: option http-proxy-override ignored because no TCP-based connection profiles are defined");
1882     }
1883 }
1884 
1885 #endif /* ifdef ENABLE_MANAGEMENT */
1886 
1887 static struct connection_list *
alloc_connection_list_if_undef(struct options * options)1888 alloc_connection_list_if_undef(struct options *options)
1889 {
1890     if (!options->connection_list)
1891     {
1892         ALLOC_OBJ_CLEAR_GC(options->connection_list, struct connection_list, &options->gc);
1893     }
1894     return options->connection_list;
1895 }
1896 
1897 static struct connection_entry *
alloc_connection_entry(struct options * options,const int msglevel)1898 alloc_connection_entry(struct options *options, const int msglevel)
1899 {
1900     struct connection_list *l = alloc_connection_list_if_undef(options);
1901     struct connection_entry *e;
1902 
1903     if (l->len >= CONNECTION_LIST_SIZE)
1904     {
1905         msg(msglevel, "Maximum number of 'connection' options (%d) exceeded", CONNECTION_LIST_SIZE);
1906         return NULL;
1907     }
1908     ALLOC_OBJ_GC(e, struct connection_entry, &options->gc);
1909     l->array[l->len++] = e;
1910     return e;
1911 }
1912 
1913 static struct remote_list *
alloc_remote_list_if_undef(struct options * options)1914 alloc_remote_list_if_undef(struct options *options)
1915 {
1916     if (!options->remote_list)
1917     {
1918         ALLOC_OBJ_CLEAR_GC(options->remote_list, struct remote_list, &options->gc);
1919     }
1920     return options->remote_list;
1921 }
1922 
1923 static struct remote_entry *
alloc_remote_entry(struct options * options,const int msglevel)1924 alloc_remote_entry(struct options *options, const int msglevel)
1925 {
1926     struct remote_list *l = alloc_remote_list_if_undef(options);
1927     struct remote_entry *e;
1928 
1929     if (l->len >= CONNECTION_LIST_SIZE)
1930     {
1931         msg(msglevel, "Maximum number of 'remote' options (%d) exceeded", CONNECTION_LIST_SIZE);
1932         return NULL;
1933     }
1934     ALLOC_OBJ_GC(e, struct remote_entry, &options->gc);
1935     l->array[l->len++] = e;
1936     return e;
1937 }
1938 
1939 static struct pull_filter_list *
alloc_pull_filter_list(struct options * o)1940 alloc_pull_filter_list(struct options *o)
1941 {
1942     if (!o->pull_filter_list)
1943     {
1944         ALLOC_OBJ_CLEAR_GC(o->pull_filter_list, struct pull_filter_list, &o->gc);
1945     }
1946     return o->pull_filter_list;
1947 }
1948 
1949 static struct pull_filter *
alloc_pull_filter(struct options * o,const int msglevel)1950 alloc_pull_filter(struct options *o, const int msglevel)
1951 {
1952     struct pull_filter_list *l = alloc_pull_filter_list(o);
1953     struct pull_filter *f;
1954 
1955     ALLOC_OBJ_CLEAR_GC(f, struct pull_filter, &o->gc);
1956     if (l->head)
1957     {
1958         ASSERT(l->tail);
1959         l->tail->next = f;
1960     }
1961     else
1962     {
1963         ASSERT(!l->tail);
1964         l->head = f;
1965     }
1966     l->tail = f;
1967     return f;
1968 }
1969 
1970 static void
connection_entry_load_re(struct connection_entry * ce,const struct remote_entry * re)1971 connection_entry_load_re(struct connection_entry *ce, const struct remote_entry *re)
1972 {
1973     if (re->remote)
1974     {
1975         ce->remote = re->remote;
1976     }
1977     if (re->remote_port)
1978     {
1979         ce->remote_port = re->remote_port;
1980     }
1981     if (re->proto >= 0)
1982     {
1983         ce->proto = re->proto;
1984     }
1985     if (re->af > 0)
1986     {
1987         ce->af = re->af;
1988     }
1989 }
1990 
1991 static void
connection_entry_preload_key(const char ** key_file,bool * key_inline,struct gc_arena * gc)1992 connection_entry_preload_key(const char **key_file, bool *key_inline,
1993                              struct gc_arena *gc)
1994 {
1995     if (key_file && *key_file && !(*key_inline))
1996     {
1997         struct buffer in = buffer_read_from_file(*key_file, gc);
1998         if (!buf_valid(&in))
1999         {
2000             msg(M_FATAL, "Cannot pre-load keyfile (%s)", *key_file);
2001         }
2002 
2003         *key_file = (const char *) in.data;
2004         *key_inline = true;
2005     }
2006 }
2007 
2008 static void
options_postprocess_verify_ce(const struct options * options,const struct connection_entry * ce)2009 options_postprocess_verify_ce(const struct options *options,
2010                               const struct connection_entry *ce)
2011 {
2012     struct options defaults;
2013     int dev = DEV_TYPE_UNDEF;
2014     bool pull = false;
2015 
2016     init_options(&defaults, true);
2017 
2018     if (options->test_crypto)
2019     {
2020         notnull(options->shared_secret_file, "key file (--secret)");
2021     }
2022     else
2023     {
2024         notnull(options->dev, "TUN/TAP device (--dev)");
2025     }
2026 
2027     /*
2028      * Get tun/tap/null device type
2029      */
2030     dev = dev_type_enum(options->dev, options->dev_type);
2031 
2032     /*
2033      * If "proto tcp" is specified, make sure we know whether it is
2034      * tcp-client or tcp-server.
2035      */
2036     if (ce->proto == PROTO_TCP)
2037     {
2038         msg(M_USAGE,
2039             "--proto tcp is ambiguous in this context. Please specify "
2040             "--proto tcp-server or --proto tcp-client");
2041     }
2042 
2043     /*
2044      * Sanity check on daemon/inetd modes
2045      */
2046 
2047     if (options->daemon && options->inetd)
2048     {
2049         msg(M_USAGE, "only one of --daemon or --inetd may be specified");
2050     }
2051 
2052     if (options->inetd && (ce->local || ce->remote))
2053     {
2054         msg(M_USAGE, "--local or --remote cannot be used with --inetd");
2055     }
2056 
2057     if (options->inetd && ce->proto == PROTO_TCP_CLIENT)
2058     {
2059         msg(M_USAGE, "--proto tcp-client cannot be used with --inetd");
2060     }
2061 
2062     if (options->inetd == INETD_NOWAIT && ce->proto != PROTO_TCP_SERVER)
2063     {
2064         msg(M_USAGE, "--inetd nowait can only be used with --proto tcp-server");
2065     }
2066 
2067     if (options->inetd == INETD_NOWAIT
2068         && !(options->tls_server || options->tls_client))
2069     {
2070         msg(M_USAGE, "--inetd nowait can only be used in TLS mode");
2071     }
2072 
2073     if (options->inetd == INETD_NOWAIT && dev != DEV_TYPE_TAP)
2074     {
2075         msg(M_USAGE, "--inetd nowait only makes sense in --dev tap mode");
2076     }
2077 
2078     if (options->inetd)
2079     {
2080         msg(M_WARN,
2081             "DEPRECATED OPTION: --inetd mode is deprecated and will be removed "
2082             "in OpenVPN 2.6");
2083     }
2084 
2085     if (options->lladdr && dev != DEV_TYPE_TAP)
2086     {
2087         msg(M_USAGE, "--lladdr can only be used in --dev tap mode");
2088     }
2089 
2090     /*
2091      * Sanity check on MTU parameters
2092      */
2093     if (options->ce.tun_mtu_defined && options->ce.link_mtu_defined)
2094     {
2095         msg(M_USAGE,
2096             "only one of --tun-mtu or --link-mtu may be defined (note that "
2097             "--ifconfig implies --link-mtu %d)", LINK_MTU_DEFAULT);
2098     }
2099 
2100     if (!proto_is_udp(ce->proto) && options->mtu_test)
2101     {
2102         msg(M_USAGE, "--mtu-test only makes sense with --proto udp");
2103     }
2104 
2105     /* will we be pulling options from server? */
2106 #if P2MP
2107     pull = options->pull;
2108 #endif
2109 
2110     /*
2111      * Sanity check on --local, --remote, and --ifconfig
2112      */
2113 
2114     if (proto_is_net(ce->proto)
2115         && string_defined_equal(ce->local, ce->remote)
2116         && string_defined_equal(ce->local_port, ce->remote_port))
2117     {
2118         msg(M_USAGE, "--remote and --local addresses are the same");
2119     }
2120 
2121     if (string_defined_equal(ce->remote, options->ifconfig_local)
2122         || string_defined_equal(ce->remote, options->ifconfig_remote_netmask))
2123     {
2124         msg(M_USAGE,
2125             "--local and --remote addresses must be distinct from --ifconfig "
2126             "addresses");
2127     }
2128 
2129     if (string_defined_equal(ce->local, options->ifconfig_local)
2130         || string_defined_equal(ce->local, options->ifconfig_remote_netmask))
2131     {
2132         msg(M_USAGE,
2133             "--local addresses must be distinct from --ifconfig addresses");
2134     }
2135 
2136     if (string_defined_equal(options->ifconfig_local,
2137                              options->ifconfig_remote_netmask))
2138     {
2139         msg(M_USAGE,
2140             "local and remote/netmask --ifconfig addresses must be different");
2141     }
2142 
2143     if (ce->bind_defined && !ce->bind_local)
2144     {
2145         msg(M_USAGE, "--bind and --nobind can't be used together");
2146     }
2147 
2148     if (ce->local && !ce->bind_local)
2149     {
2150         msg(M_USAGE,
2151             "--local and --nobind don't make sense when used together");
2152     }
2153 
2154     if (ce->local_port_defined && !ce->bind_local)
2155     {
2156         msg(M_USAGE,
2157             "--lport and --nobind don't make sense when used together");
2158     }
2159 
2160     if (!ce->remote && !ce->bind_local)
2161     {
2162         msg(M_USAGE, "--nobind doesn't make sense unless used with --remote");
2163     }
2164 
2165     /*
2166      * Check for consistency of management options
2167      */
2168 #ifdef ENABLE_MANAGEMENT
2169     if (!options->management_addr
2170         && (options->management_flags
2171             || options->management_write_peer_info_file
2172             || options->management_log_history_cache != defaults.management_log_history_cache))
2173     {
2174         msg(M_USAGE, "--management is not specified, however one or more options which modify the behavior of --management were specified");
2175     }
2176 
2177     if ((options->management_client_user || options->management_client_group)
2178         && !(options->management_flags & MF_UNIX_SOCK))
2179     {
2180         msg(M_USAGE, "--management-client-(user|group) can only be used on unix domain sockets");
2181     }
2182 
2183     if (options->management_addr
2184         && !(options->management_flags & MF_UNIX_SOCK)
2185         && (!options->management_user_pass))
2186     {
2187         msg(M_WARN, "WARNING: Using --management on a TCP port WITHOUT "
2188             "passwords is STRONGLY discouraged and considered insecure");
2189     }
2190 
2191 #endif /* ifdef ENABLE_MANAGEMENT */
2192 
2193 #if  defined(ENABLE_MANAGEMENT)
2194     if ((tls_version_max() >= TLS_VER_1_3)
2195         && (options->management_flags & MF_EXTERNAL_KEY)
2196         && !(options->management_flags & (MF_EXTERNAL_KEY_NOPADDING))
2197         )
2198     {
2199         msg(M_ERR, "management-external-key with OpenSSL 1.1.1 requires "
2200             "the nopadding argument/support");
2201     }
2202 #endif
2203     /*
2204      * Windows-specific options.
2205      */
2206 
2207 #ifdef _WIN32
2208     if (dev == DEV_TYPE_TUN && !(pull || (options->ifconfig_local && options->ifconfig_remote_netmask)))
2209     {
2210         msg(M_USAGE, "On Windows, --ifconfig is required when --dev tun is used");
2211     }
2212 
2213     if ((options->tuntap_options.ip_win32_defined)
2214         && !(pull || (options->ifconfig_local && options->ifconfig_remote_netmask)))
2215     {
2216         msg(M_USAGE, "On Windows, --ip-win32 doesn't make sense unless --ifconfig is also used");
2217     }
2218 
2219     if (options->tuntap_options.dhcp_options
2220         && options->windows_driver != WINDOWS_DRIVER_WINTUN
2221         && options->tuntap_options.ip_win32_type != IPW32_SET_DHCP_MASQ
2222         && options->tuntap_options.ip_win32_type != IPW32_SET_ADAPTIVE)
2223     {
2224         msg(M_USAGE, "--dhcp-option requires --ip-win32 dynamic or adaptive");
2225     }
2226 
2227     if (options->windows_driver == WINDOWS_DRIVER_WINTUN && dev != DEV_TYPE_TUN)
2228     {
2229         msg(M_USAGE, "--windows-driver wintun requires --dev tun");
2230     }
2231 #endif /* ifdef _WIN32 */
2232 
2233     /*
2234      * Check that protocol options make sense.
2235      */
2236 
2237 #ifdef ENABLE_FRAGMENT
2238     if (!proto_is_udp(ce->proto) && ce->fragment)
2239     {
2240         msg(M_USAGE, "--fragment can only be used with --proto udp");
2241     }
2242 #endif
2243 
2244     if (!proto_is_udp(ce->proto) && ce->explicit_exit_notification)
2245     {
2246         msg(M_USAGE,
2247             "--explicit-exit-notify can only be used with --proto udp");
2248     }
2249 
2250     if (!ce->remote && ce->proto == PROTO_TCP_CLIENT)
2251     {
2252         msg(M_USAGE, "--remote MUST be used in TCP Client mode");
2253     }
2254 
2255     if ((ce->http_proxy_options) && ce->proto != PROTO_TCP_CLIENT)
2256     {
2257         msg(M_USAGE,
2258             "--http-proxy MUST be used in TCP Client mode (i.e. --proto "
2259             "tcp-client)");
2260     }
2261 
2262     if ((ce->http_proxy_options) && !ce->http_proxy_options->server)
2263     {
2264         msg(M_USAGE,
2265             "--http-proxy not specified but other http proxy options present");
2266     }
2267 
2268     if (ce->http_proxy_options && ce->socks_proxy_server)
2269     {
2270         msg(M_USAGE,
2271             "--http-proxy can not be used together with --socks-proxy");
2272     }
2273 
2274     if (ce->socks_proxy_server && ce->proto == PROTO_TCP_SERVER)
2275     {
2276         msg(M_USAGE, "--socks-proxy can not be used in TCP Server mode");
2277     }
2278 
2279     if (ce->proto == PROTO_TCP_SERVER && (options->connection_list->len > 1))
2280     {
2281         msg(M_USAGE, "TCP server mode allows at most one --remote address");
2282     }
2283 
2284     /*
2285      * Check consistency of --mode server options.
2286      */
2287     if (options->mode == MODE_SERVER)
2288     {
2289 #define USAGE_VALID_SERVER_PROTOS "--mode server currently only supports " \
2290       "--proto values of udp, tcp-server, tcp4-server, or tcp6-server"
2291 #ifdef TARGET_ANDROID
2292         msg(M_FATAL, "--mode server not supported on Android");
2293 #endif
2294         if (!(dev == DEV_TYPE_TUN || dev == DEV_TYPE_TAP))
2295         {
2296             msg(M_USAGE, "--mode server only works with --dev tun or --dev tap");
2297         }
2298         if (options->pull)
2299         {
2300             msg(M_USAGE, "--pull cannot be used with --mode server");
2301         }
2302         if (options->pull_filter_list)
2303         {
2304             msg(M_WARN, "--pull-filter ignored for --mode server");
2305         }
2306         if (!(proto_is_udp(ce->proto) || ce->proto == PROTO_TCP_SERVER))
2307         {
2308             msg(M_USAGE, USAGE_VALID_SERVER_PROTOS);
2309         }
2310 #if PORT_SHARE
2311         if ((options->port_share_host || options->port_share_port)
2312             && (ce->proto != PROTO_TCP_SERVER))
2313         {
2314             msg(M_USAGE, "--port-share only works in TCP server mode "
2315                 "(--proto values of tcp-server, tcp4-server, or tcp6-server)");
2316         }
2317 #endif
2318         if (!options->tls_server)
2319         {
2320             msg(M_USAGE, "--mode server requires --tls-server");
2321         }
2322         if (ce->remote)
2323         {
2324             msg(M_USAGE, "--remote cannot be used with --mode server");
2325         }
2326         if (!ce->bind_local)
2327         {
2328             msg(M_USAGE, "--nobind cannot be used with --mode server");
2329         }
2330         if (ce->http_proxy_options)
2331         {
2332             msg(M_USAGE, "--http-proxy cannot be used with --mode server");
2333         }
2334         if (ce->socks_proxy_server)
2335         {
2336             msg(M_USAGE, "--socks-proxy cannot be used with --mode server");
2337         }
2338         /* <connection> blocks force to have a remote embedded, so we check
2339          * for the --remote and bail out if it is present
2340          */
2341         if (options->connection_list->len >1
2342             || options->connection_list->array[0]->remote)
2343         {
2344             msg(M_USAGE, "<connection> cannot be used with --mode server");
2345         }
2346 
2347         if (options->shaper)
2348         {
2349             msg(M_USAGE, "--shaper cannot be used with --mode server");
2350         }
2351         if (options->inetd)
2352         {
2353             msg(M_USAGE, "--inetd cannot be used with --mode server");
2354         }
2355         if (options->ipchange)
2356         {
2357             msg(M_USAGE,
2358                 "--ipchange cannot be used with --mode server (use "
2359                 "--client-connect instead)");
2360         }
2361         if (!(proto_is_dgram(ce->proto) || ce->proto == PROTO_TCP_SERVER))
2362         {
2363             msg(M_USAGE, USAGE_VALID_SERVER_PROTOS);
2364         }
2365         if (!proto_is_udp(ce->proto) && (options->cf_max || options->cf_per))
2366         {
2367             msg(M_USAGE, "--connect-freq only works with --mode server --proto udp.  Try --max-clients instead.");
2368         }
2369         if (!(dev == DEV_TYPE_TAP || (dev == DEV_TYPE_TUN && options->topology == TOP_SUBNET)) && options->ifconfig_pool_netmask)
2370         {
2371             msg(M_USAGE, "The third parameter to --ifconfig-pool (netmask) is only valid in --dev tap mode");
2372         }
2373         if (options->routes && (options->routes->flags & RG_ENABLE))
2374         {
2375             msg(M_USAGE, "--redirect-gateway cannot be used with --mode server (however --push \"redirect-gateway\" is fine)");
2376         }
2377         if (options->route_delay_defined)
2378         {
2379             msg(M_USAGE, "--route-delay cannot be used with --mode server");
2380         }
2381         if (options->up_delay)
2382         {
2383             msg(M_USAGE, "--up-delay cannot be used with --mode server");
2384         }
2385         if (!options->ifconfig_pool_defined
2386             && !options->ifconfig_ipv6_pool_defined
2387             && options->ifconfig_pool_persist_filename)
2388         {
2389             msg(M_USAGE,
2390                 "--ifconfig-pool-persist must be used with --ifconfig-pool or --ifconfig-ipv6-pool");
2391         }
2392         if (options->ifconfig_ipv6_pool_defined && !options->ifconfig_ipv6_local)
2393         {
2394             msg(M_USAGE, "--ifconfig-ipv6-pool needs --ifconfig-ipv6");
2395         }
2396         if (options->allow_recursive_routing)
2397         {
2398             msg(M_USAGE, "--allow-recursive-routing cannot be used with --mode server");
2399         }
2400         if (options->auth_user_pass_file)
2401         {
2402             msg(M_USAGE, "--auth-user-pass cannot be used with --mode server (it should be used on the client side only)");
2403         }
2404         if (options->ccd_exclusive && !options->client_config_dir)
2405         {
2406             msg(M_USAGE, "--ccd-exclusive must be used with --client-config-dir");
2407         }
2408         if (options->auth_token_generate && !options->renegotiate_seconds)
2409         {
2410             msg(M_USAGE, "--auth-gen-token needs a non-infinite "
2411                 "--renegotiate_seconds setting");
2412         }
2413         {
2414             const bool ccnr = (options->auth_user_pass_verify_script
2415                                || PLUGIN_OPTION_LIST(options)
2416                                || MAN_CLIENT_AUTH_ENABLED(options));
2417             const char *postfix = "must be used with --management-client-auth, an --auth-user-pass-verify script, or plugin";
2418             if ((options->ssl_flags & (SSLF_CLIENT_CERT_NOT_REQUIRED|SSLF_CLIENT_CERT_OPTIONAL)) && !ccnr)
2419             {
2420                 msg(M_USAGE, "--verify-client-cert none|optional %s", postfix);
2421             }
2422             if ((options->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) && !ccnr)
2423             {
2424                 msg(M_USAGE, "--username-as-common-name %s", postfix);
2425             }
2426             if ((options->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) && !ccnr)
2427             {
2428                 msg(M_USAGE, "--auth-user-pass-optional %s", postfix);
2429             }
2430         }
2431 
2432         if (options->vlan_tagging && dev != DEV_TYPE_TAP)
2433         {
2434             msg(M_USAGE, "--vlan-tagging must be used with --dev tap");
2435         }
2436         if (!options->vlan_tagging)
2437         {
2438             if (options->vlan_accept != defaults.vlan_accept)
2439             {
2440                 msg(M_USAGE, "--vlan-accept requires --vlan-tagging");
2441             }
2442             if (options->vlan_pvid != defaults.vlan_pvid)
2443             {
2444                 msg(M_USAGE, "--vlan-pvid requires --vlan-tagging");
2445             }
2446         }
2447     }
2448     else
2449     {
2450         /*
2451          * When not in server mode, err if parameters are
2452          * specified which require --mode server.
2453          */
2454         if (options->ifconfig_pool_defined || options->ifconfig_pool_persist_filename)
2455         {
2456             msg(M_USAGE, "--ifconfig-pool/--ifconfig-pool-persist requires --mode server");
2457         }
2458         if (options->ifconfig_ipv6_pool_defined)
2459         {
2460             msg(M_USAGE, "--ifconfig-ipv6-pool requires --mode server");
2461         }
2462         if (options->real_hash_size != defaults.real_hash_size
2463             || options->virtual_hash_size != defaults.virtual_hash_size)
2464         {
2465             msg(M_USAGE, "--hash-size requires --mode server");
2466         }
2467         if (options->learn_address_script)
2468         {
2469             msg(M_USAGE, "--learn-address requires --mode server");
2470         }
2471         if (options->client_connect_script)
2472         {
2473             msg(M_USAGE, "--client-connect requires --mode server");
2474         }
2475         if (options->client_disconnect_script)
2476         {
2477             msg(M_USAGE, "--client-disconnect requires --mode server");
2478         }
2479         if (options->client_config_dir || options->ccd_exclusive)
2480         {
2481             msg(M_USAGE, "--client-config-dir/--ccd-exclusive requires --mode server");
2482         }
2483         if (options->enable_c2c)
2484         {
2485             msg(M_USAGE, "--client-to-client requires --mode server");
2486         }
2487         if (options->duplicate_cn)
2488         {
2489             msg(M_USAGE, "--duplicate-cn requires --mode server");
2490         }
2491         if (options->cf_max || options->cf_per)
2492         {
2493             msg(M_USAGE, "--connect-freq requires --mode server");
2494         }
2495         if (options->ssl_flags & (SSLF_CLIENT_CERT_NOT_REQUIRED|SSLF_CLIENT_CERT_OPTIONAL))
2496         {
2497             msg(M_USAGE, "--verify-client-cert requires --mode server");
2498         }
2499         if (options->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME)
2500         {
2501             msg(M_USAGE, "--username-as-common-name requires --mode server");
2502         }
2503         if (options->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL)
2504         {
2505             msg(M_USAGE, "--auth-user-pass-optional requires --mode server");
2506         }
2507         if (options->ssl_flags & SSLF_OPT_VERIFY)
2508         {
2509             msg(M_USAGE, "--opt-verify requires --mode server");
2510         }
2511         if (options->server_flags & SF_TCP_NODELAY_HELPER)
2512         {
2513             msg(M_WARN, "WARNING: setting tcp-nodelay on the client side will not "
2514                 "affect the server. To have TCP_NODELAY in both direction use "
2515                 "tcp-nodelay in the server configuration instead.");
2516         }
2517         if (options->auth_user_pass_verify_script)
2518         {
2519             msg(M_USAGE, "--auth-user-pass-verify requires --mode server");
2520         }
2521         if (options->auth_token_generate)
2522         {
2523             msg(M_USAGE, "--auth-gen-token requires --mode server");
2524         }
2525 #if PORT_SHARE
2526         if (options->port_share_host || options->port_share_port)
2527         {
2528             msg(M_USAGE, "--port-share requires TCP server mode (--mode server --proto tcp-server)");
2529         }
2530 #endif
2531 
2532         if (options->stale_routes_check_interval)
2533         {
2534             msg(M_USAGE, "--stale-routes-check requires --mode server");
2535         }
2536 
2537         if (options->vlan_tagging)
2538         {
2539             msg(M_USAGE, "--vlan-tagging requires --mode server");
2540         }
2541     }
2542 
2543     if (options->keysize)
2544     {
2545         msg(M_WARN, "WARNING: --keysize is DEPRECATED and will be removed in OpenVPN 2.6");
2546     }
2547 
2548     /*
2549      * Check consistency of replay options
2550      */
2551     if (!options->replay
2552         && (options->replay_window != defaults.replay_window
2553             || options->replay_time != defaults.replay_time))
2554     {
2555         msg(M_USAGE, "--replay-window doesn't make sense when replay protection is disabled with --no-replay");
2556     }
2557 
2558     /*
2559      * SSL/TLS mode sanity checks.
2560      */
2561     if (options->tls_server + options->tls_client
2562         +(options->shared_secret_file != NULL) > 1)
2563     {
2564         msg(M_USAGE, "specify only one of --tls-server, --tls-client, or --secret");
2565     }
2566 
2567     if (options->ssl_flags & (SSLF_CLIENT_CERT_NOT_REQUIRED|SSLF_CLIENT_CERT_OPTIONAL))
2568     {
2569         msg(M_WARN, "WARNING: POTENTIALLY DANGEROUS OPTION "
2570             "--verify-client-cert none|optional "
2571             "may accept clients which do not present a certificate");
2572     }
2573 
2574     const int tls_version_max =
2575         (options->ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT)
2576         & SSLF_TLS_VERSION_MAX_MASK;
2577     const int tls_version_min =
2578         (options->ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT)
2579         & SSLF_TLS_VERSION_MIN_MASK;
2580 
2581     if (tls_version_max > 0 && tls_version_max < tls_version_min)
2582     {
2583         msg(M_USAGE, "--tls-version-min bigger than --tls-version-max");
2584     }
2585 
2586     if (options->tls_server || options->tls_client)
2587     {
2588 #ifdef ENABLE_PKCS11
2589         if (options->pkcs11_providers[0])
2590         {
2591             notnull(options->ca_file, "CA file (--ca)");
2592 
2593             if (options->pkcs11_id_management && options->pkcs11_id != NULL)
2594             {
2595                 msg(M_USAGE, "Parameter --pkcs11-id cannot be used when --pkcs11-id-management is also specified.");
2596             }
2597             if (!options->pkcs11_id_management && options->pkcs11_id == NULL)
2598             {
2599                 msg(M_USAGE, "Parameter --pkcs11-id or --pkcs11-id-management should be specified.");
2600             }
2601             if (options->cert_file)
2602             {
2603                 msg(M_USAGE, "Parameter --cert cannot be used when --pkcs11-provider is also specified.");
2604             }
2605             if (options->priv_key_file)
2606             {
2607                 msg(M_USAGE, "Parameter --key cannot be used when --pkcs11-provider is also specified.");
2608             }
2609 #ifdef ENABLE_MANAGEMENT
2610             if (options->management_flags & MF_EXTERNAL_KEY)
2611             {
2612                 msg(M_USAGE, "Parameter --management-external-key cannot be used when --pkcs11-provider is also specified.");
2613             }
2614             if (options->management_flags & MF_EXTERNAL_CERT)
2615             {
2616                 msg(M_USAGE, "Parameter --management-external-cert cannot be used when --pkcs11-provider is also specified.");
2617             }
2618 #endif
2619             if (options->pkcs12_file)
2620             {
2621                 msg(M_USAGE, "Parameter --pkcs12 cannot be used when --pkcs11-provider is also specified.");
2622             }
2623 #ifdef ENABLE_CRYPTOAPI
2624             if (options->cryptoapi_cert)
2625             {
2626                 msg(M_USAGE, "Parameter --cryptoapicert cannot be used when --pkcs11-provider is also specified.");
2627             }
2628 #endif
2629         }
2630         else
2631 #endif /* ifdef ENABLE_PKCS11 */
2632 #ifdef ENABLE_MANAGEMENT
2633         if ((options->management_flags & MF_EXTERNAL_KEY) && options->priv_key_file)
2634         {
2635             msg(M_USAGE, "--key and --management-external-key are mutually exclusive");
2636         }
2637         else if ((options->management_flags & MF_EXTERNAL_CERT))
2638         {
2639             if (options->cert_file)
2640             {
2641                 msg(M_USAGE, "--cert and --management-external-cert are mutually exclusive");
2642             }
2643             else if (!(options->management_flags & MF_EXTERNAL_KEY))
2644             {
2645                 msg(M_USAGE, "--management-external-cert must be used with --management-external-key");
2646             }
2647         }
2648         else
2649 #endif
2650 #ifdef ENABLE_CRYPTOAPI
2651         if (options->cryptoapi_cert)
2652         {
2653             if ((!(options->ca_file)) && (!(options->ca_path)))
2654             {
2655                 msg(M_USAGE, "You must define CA file (--ca) or CA path (--capath)");
2656             }
2657             if (options->cert_file)
2658             {
2659                 msg(M_USAGE, "Parameter --cert cannot be used when --cryptoapicert is also specified.");
2660             }
2661             if (options->priv_key_file)
2662             {
2663                 msg(M_USAGE, "Parameter --key cannot be used when --cryptoapicert is also specified.");
2664             }
2665             if (options->pkcs12_file)
2666             {
2667                 msg(M_USAGE, "Parameter --pkcs12 cannot be used when --cryptoapicert is also specified.");
2668             }
2669 #ifdef ENABLE_MANAGEMENT
2670             if (options->management_flags & MF_EXTERNAL_KEY)
2671             {
2672                 msg(M_USAGE, "Parameter --management-external-key cannot be used when --cryptoapicert is also specified.");
2673             }
2674             if (options->management_flags & MF_EXTERNAL_CERT)
2675             {
2676                 msg(M_USAGE, "Parameter --management-external-cert cannot be used when --cryptoapicert is also specified.");
2677             }
2678 #endif
2679         }
2680         else
2681 #endif /* ifdef ENABLE_CRYPTOAPI */
2682         if (options->pkcs12_file)
2683         {
2684 #ifdef ENABLE_CRYPTO_MBEDTLS
2685             msg(M_USAGE, "Parameter --pkcs12 cannot be used with the mbed TLS version version of OpenVPN.");
2686 #else
2687             if (options->ca_path)
2688             {
2689                 msg(M_USAGE, "Parameter --capath cannot be used when --pkcs12 is also specified.");
2690             }
2691             if (options->cert_file)
2692             {
2693                 msg(M_USAGE, "Parameter --cert cannot be used when --pkcs12 is also specified.");
2694             }
2695             if (options->priv_key_file)
2696             {
2697                 msg(M_USAGE, "Parameter --key cannot be used when --pkcs12 is also specified.");
2698             }
2699 #ifdef ENABLE_MANAGEMENT
2700             if (options->management_flags & MF_EXTERNAL_KEY)
2701             {
2702                 msg(M_USAGE, "Parameter --management-external-key cannot be used when --pkcs12 is also specified.");
2703             }
2704             if (options->management_flags & MF_EXTERNAL_CERT)
2705             {
2706                 msg(M_USAGE, "Parameter --management-external-cert cannot be used when --pkcs12 is also specified.");
2707             }
2708 #endif
2709 #endif /* ifdef ENABLE_CRYPTO_MBEDTLS */
2710         }
2711         else
2712         {
2713 #ifdef ENABLE_CRYPTO_MBEDTLS
2714             if (!(options->ca_file))
2715             {
2716                 msg(M_USAGE, "You must define CA file (--ca)");
2717             }
2718             if (options->ca_path)
2719             {
2720                 msg(M_USAGE, "Parameter --capath cannot be used with the mbed TLS version version of OpenVPN.");
2721             }
2722 #else  /* ifdef ENABLE_CRYPTO_MBEDTLS */
2723             if ((!(options->ca_file)) && (!(options->ca_path)))
2724             {
2725                 msg(M_USAGE, "You must define CA file (--ca) or CA path (--capath)");
2726             }
2727 #endif
2728             if (pull)
2729             {
2730 
2731                 const int sum =
2732 #ifdef ENABLE_MANAGEMENT
2733                     ((options->cert_file != NULL) || (options->management_flags & MF_EXTERNAL_CERT))
2734                     +((options->priv_key_file != NULL) || (options->management_flags & MF_EXTERNAL_KEY));
2735 #else
2736                     (options->cert_file != NULL) + (options->priv_key_file != NULL);
2737 #endif
2738 
2739                 if (sum == 0)
2740                 {
2741 #if P2MP
2742                     if (!options->auth_user_pass_file)
2743 #endif
2744                     msg(M_USAGE, "No client-side authentication method is specified.  You must use either --cert/--key, --pkcs12, or --auth-user-pass");
2745                 }
2746                 else if (sum == 2)
2747                 {
2748                 }
2749                 else
2750                 {
2751                     msg(M_USAGE, "If you use one of --cert or --key, you must use them both");
2752                 }
2753             }
2754             else
2755             {
2756 #ifdef ENABLE_MANAGEMENT
2757                 if (!(options->management_flags & MF_EXTERNAL_CERT))
2758 #endif
2759                 notnull(options->cert_file, "certificate file (--cert) or PKCS#12 file (--pkcs12)");
2760 #ifdef ENABLE_MANAGEMENT
2761                 if (!(options->management_flags & MF_EXTERNAL_KEY))
2762 #endif
2763                 notnull(options->priv_key_file, "private key file (--key) or PKCS#12 file (--pkcs12)");
2764             }
2765         }
2766         if (ce->tls_auth_file && ce->tls_crypt_file)
2767         {
2768             msg(M_USAGE, "--tls-auth and --tls-crypt are mutually exclusive");
2769         }
2770         if (options->tls_client && ce->tls_crypt_v2_file
2771             && (ce->tls_auth_file || ce->tls_crypt_file))
2772         {
2773             msg(M_USAGE, "--tls-crypt-v2, --tls-auth and --tls-crypt are mutually exclusive in client mode");
2774         }
2775     }
2776     else
2777     {
2778         /*
2779          * Make sure user doesn't specify any TLS options
2780          * when in non-TLS mode.
2781          */
2782 
2783 #define MUST_BE_UNDEF(parm) if (options->parm != defaults.parm) {msg(M_USAGE, err, #parm); \
2784 }
2785 
2786         const char err[] = "Parameter %s can only be specified in TLS-mode, i.e. where --tls-server or --tls-client is also specified.";
2787 
2788         MUST_BE_UNDEF(ca_file);
2789         MUST_BE_UNDEF(ca_path);
2790         MUST_BE_UNDEF(dh_file);
2791         MUST_BE_UNDEF(cert_file);
2792         MUST_BE_UNDEF(priv_key_file);
2793 #ifndef ENABLE_CRYPTO_MBEDTLS
2794         MUST_BE_UNDEF(pkcs12_file);
2795 #endif
2796         MUST_BE_UNDEF(cipher_list);
2797         MUST_BE_UNDEF(cipher_list_tls13);
2798         MUST_BE_UNDEF(tls_cert_profile);
2799         MUST_BE_UNDEF(tls_verify);
2800         MUST_BE_UNDEF(tls_export_cert);
2801         MUST_BE_UNDEF(verify_x509_name);
2802         MUST_BE_UNDEF(tls_timeout);
2803         MUST_BE_UNDEF(renegotiate_bytes);
2804         MUST_BE_UNDEF(renegotiate_packets);
2805         MUST_BE_UNDEF(renegotiate_seconds);
2806         MUST_BE_UNDEF(handshake_window);
2807         MUST_BE_UNDEF(transition_window);
2808         MUST_BE_UNDEF(tls_auth_file);
2809         MUST_BE_UNDEF(tls_crypt_file);
2810         MUST_BE_UNDEF(tls_crypt_v2_file);
2811         MUST_BE_UNDEF(single_session);
2812         MUST_BE_UNDEF(push_peer_info);
2813         MUST_BE_UNDEF(tls_exit);
2814         MUST_BE_UNDEF(crl_file);
2815         MUST_BE_UNDEF(ns_cert_type);
2816         MUST_BE_UNDEF(remote_cert_ku[0]);
2817         MUST_BE_UNDEF(remote_cert_eku);
2818 #ifdef ENABLE_PKCS11
2819         MUST_BE_UNDEF(pkcs11_providers[0]);
2820         MUST_BE_UNDEF(pkcs11_private_mode[0]);
2821         MUST_BE_UNDEF(pkcs11_id);
2822         MUST_BE_UNDEF(pkcs11_id_management);
2823 #endif
2824 
2825         if (pull)
2826         {
2827             msg(M_USAGE, err, "--pull");
2828         }
2829     }
2830 #undef MUST_BE_UNDEF
2831 
2832 #if P2MP
2833     if (options->auth_user_pass_file && !options->pull)
2834     {
2835         msg(M_USAGE, "--auth-user-pass requires --pull");
2836     }
2837 #endif
2838 
2839     uninit_options(&defaults);
2840 }
2841 
2842 static void
options_postprocess_mutate_ce(struct options * o,struct connection_entry * ce)2843 options_postprocess_mutate_ce(struct options *o, struct connection_entry *ce)
2844 {
2845     const int dev = dev_type_enum(o->dev, o->dev_type);
2846 
2847     if (o->server_defined || o->server_bridge_defined || o->server_bridge_proxy_dhcp)
2848     {
2849         if (ce->proto == PROTO_TCP)
2850         {
2851             ce->proto = PROTO_TCP_SERVER;
2852         }
2853     }
2854 
2855 #if P2MP
2856     if (o->client)
2857     {
2858         if (ce->proto == PROTO_TCP)
2859         {
2860             ce->proto = PROTO_TCP_CLIENT;
2861         }
2862     }
2863 #endif
2864 
2865     if (ce->proto == PROTO_TCP_CLIENT && !ce->local
2866         && !ce->local_port_defined && !ce->bind_defined)
2867     {
2868         ce->bind_local = false;
2869     }
2870 
2871     if (ce->proto == PROTO_UDP && ce->socks_proxy_server && !ce->local
2872         && !ce->local_port_defined && !ce->bind_defined)
2873     {
2874         ce->bind_local = false;
2875     }
2876 
2877     if (!ce->bind_local)
2878     {
2879         ce->local_port = NULL;
2880     }
2881 
2882     /* if protocol forcing is enabled, disable all protocols
2883      * except for the forced one
2884      */
2885     if (o->proto_force >= 0 && o->proto_force != ce->proto)
2886     {
2887         ce->flags |= CE_DISABLED;
2888     }
2889 
2890     /*
2891      * If --mssfix is supplied without a parameter, default
2892      * it to --fragment value, if --fragment is specified.
2893      */
2894     if (o->ce.mssfix_default)
2895     {
2896 #ifdef ENABLE_FRAGMENT
2897         if (ce->fragment)
2898         {
2899             ce->mssfix = ce->fragment;
2900         }
2901 #else
2902         msg(M_USAGE, "--mssfix must specify a parameter");
2903 #endif
2904     }
2905 
2906     /* our socks code is not fully IPv6 enabled yet (TCP works, UDP not)
2907      * so fall back to IPv4-only (trac #1221)
2908      */
2909     if (ce->socks_proxy_server && proto_is_udp(ce->proto) && ce->af != AF_INET)
2910     {
2911         if (ce->af == AF_INET6)
2912         {
2913             msg(M_INFO, "WARNING: '--proto udp6' is not compatible with "
2914                 "'--socks-proxy' today.  Forcing IPv4 mode." );
2915         }
2916         else
2917         {
2918             msg(M_INFO, "NOTICE: dual-stack mode for '--proto udp' does not "
2919                 "work correctly with '--socks-proxy' today.  Forcing IPv4." );
2920         }
2921         ce->af = AF_INET;
2922     }
2923 
2924     /*
2925      * Set MTU defaults
2926      */
2927     {
2928         if (!ce->tun_mtu_defined && !ce->link_mtu_defined)
2929         {
2930             ce->tun_mtu_defined = true;
2931         }
2932         if ((dev == DEV_TYPE_TAP) && !ce->tun_mtu_extra_defined)
2933         {
2934             ce->tun_mtu_extra_defined = true;
2935             ce->tun_mtu_extra = TAP_MTU_EXTRA_DEFAULT;
2936         }
2937     }
2938 
2939     /*
2940      * Set per-connection block tls-auth/crypt/crypto-v2 fields if undefined.
2941      *
2942      * At the end only one of these will be really set because the parser
2943      * logic prevents configurations where more are set.
2944      */
2945     if (!ce->tls_auth_file && !ce->tls_crypt_file && !ce->tls_crypt_v2_file)
2946     {
2947         ce->tls_auth_file = o->tls_auth_file;
2948         ce->tls_auth_file_inline = o->tls_auth_file_inline;
2949         ce->key_direction = o->key_direction;
2950 
2951         ce->tls_crypt_file = o->tls_crypt_file;
2952         ce->tls_crypt_file_inline = o->tls_crypt_file_inline;
2953 
2954         ce->tls_crypt_v2_file = o->tls_crypt_v2_file;
2955         ce->tls_crypt_v2_file_inline = o->tls_crypt_v2_file_inline;
2956     }
2957 
2958     /* Pre-cache tls-auth/crypt(-v2) key file if persist-key was specified and
2959      * keys were not already embedded in the config file.
2960      */
2961     if (o->persist_key)
2962     {
2963         connection_entry_preload_key(&ce->tls_auth_file,
2964                                      &ce->tls_auth_file_inline, &o->gc);
2965         connection_entry_preload_key(&ce->tls_crypt_file,
2966                                      &ce->tls_crypt_file_inline, &o->gc);
2967         connection_entry_preload_key(&ce->tls_crypt_v2_file,
2968                                      &ce->tls_crypt_v2_file_inline, &o->gc);
2969     }
2970 }
2971 
2972 #ifdef _WIN32
2973 /* If iservice is in use, we need def1 method for redirect-gateway */
2974 static void
remap_redirect_gateway_flags(struct options * opt)2975 remap_redirect_gateway_flags(struct options *opt)
2976 {
2977     if (opt->routes
2978         && opt->route_method == ROUTE_METHOD_SERVICE
2979         && opt->routes->flags & RG_REROUTE_GW
2980         && !(opt->routes->flags & RG_DEF1))
2981     {
2982         msg(M_INFO, "Flag 'def1' added to --redirect-gateway (iservice is in use)");
2983         opt->routes->flags |= RG_DEF1;
2984     }
2985 }
2986 #endif
2987 
2988 static void
options_postprocess_mutate_invariant(struct options * options)2989 options_postprocess_mutate_invariant(struct options *options)
2990 {
2991 #ifdef _WIN32
2992     const int dev = dev_type_enum(options->dev, options->dev_type);
2993 #endif
2994 
2995     /*
2996      * In forking TCP server mode, you don't need to ifconfig
2997      * the tap device (the assumption is that it will be bridged).
2998      */
2999     if (options->inetd == INETD_NOWAIT)
3000     {
3001         options->ifconfig_noexec = true;
3002     }
3003 
3004 #ifdef _WIN32
3005     /* when using wintun, kernel doesn't send DHCP requests, so don't use it */
3006     if (options->windows_driver == WINDOWS_DRIVER_WINTUN
3007         && (options->tuntap_options.ip_win32_type == IPW32_SET_DHCP_MASQ || options->tuntap_options.ip_win32_type == IPW32_SET_ADAPTIVE))
3008     {
3009         options->tuntap_options.ip_win32_type = IPW32_SET_NETSH;
3010     }
3011 
3012     if ((dev == DEV_TYPE_TUN || dev == DEV_TYPE_TAP) && !options->route_delay_defined)
3013     {
3014         /* delay may only be necessary when we perform DHCP handshake */
3015         const bool dhcp = (options->tuntap_options.ip_win32_type == IPW32_SET_DHCP_MASQ)
3016                           || (options->tuntap_options.ip_win32_type == IPW32_SET_ADAPTIVE);
3017         if ((options->mode == MODE_POINT_TO_POINT) && dhcp)
3018         {
3019             options->route_delay_defined = true;
3020             options->route_delay = 5; /* Vista sometimes has a race without this */
3021         }
3022     }
3023 
3024     if (options->ifconfig_noexec)
3025     {
3026         options->tuntap_options.ip_win32_type = IPW32_SET_MANUAL;
3027         options->ifconfig_noexec = false;
3028     }
3029 
3030     remap_redirect_gateway_flags(options);
3031 
3032     /*
3033      * Check consistency of --mode server options.
3034      */
3035     if (options->mode == MODE_SERVER)
3036     {
3037         /*
3038          * We need to explicitly set --tap-sleep because
3039          * we do not schedule event timers in the top-level context.
3040          */
3041         options->tuntap_options.tap_sleep = 10;
3042         if (options->route_delay_defined && options->route_delay)
3043         {
3044             options->tuntap_options.tap_sleep = options->route_delay;
3045         }
3046         options->route_delay_defined = false;
3047     }
3048 #endif /* ifdef _WIN32 */
3049 
3050 #ifdef DEFAULT_PKCS11_MODULE
3051     /* If p11-kit is present on the system then load its p11-kit-proxy.so
3052      * by default if the user asks for PKCS#11 without otherwise specifying
3053      * the module to use. */
3054     if (!options->pkcs11_providers[0]
3055         && (options->pkcs11_id || options->pkcs11_id_management))
3056     {
3057         options->pkcs11_providers[0] = DEFAULT_PKCS11_MODULE;
3058     }
3059 #endif
3060 }
3061 
3062 static void
options_postprocess_verify(const struct options * o)3063 options_postprocess_verify(const struct options *o)
3064 {
3065     if (o->connection_list)
3066     {
3067         int i;
3068         for (i = 0; i < o->connection_list->len; ++i)
3069         {
3070             options_postprocess_verify_ce(o, o->connection_list->array[i]);
3071         }
3072     }
3073     else
3074     {
3075         options_postprocess_verify_ce(o, &o->ce);
3076     }
3077 }
3078 
3079 static void
options_postprocess_cipher(struct options * o)3080 options_postprocess_cipher(struct options *o)
3081 {
3082     if (!o->pull && !(o->mode == MODE_SERVER))
3083     {
3084         /* we are in the classic P2P mode */
3085         o->ncp_enabled = false;
3086         msg( M_WARN, "Cipher negotiation is disabled since neither "
3087              "P2MP client nor server mode is enabled");
3088 
3089         /* If the cipher is not set, use the old default of BF-CBC. We will
3090          * warn that this is deprecated on cipher initialisation, no need
3091          * to warn here as well */
3092         if (!o->ciphername)
3093         {
3094             o->ciphername = "BF-CBC";
3095         }
3096         return;
3097     }
3098 
3099     /* pull or P2MP mode */
3100     if (!o->ciphername)
3101     {
3102         if (!o->ncp_enabled)
3103         {
3104             msg(M_USAGE, "--ncp-disable needs an explicit --cipher or "
3105                          "--data-ciphers-fallback config option");
3106         }
3107 
3108         msg(M_WARN, "--cipher is not set. Previous OpenVPN version defaulted to "
3109             "BF-CBC as fallback when cipher negotiation failed in this case. "
3110             "If you need this fallback please add '--data-ciphers-fallback "
3111             "BF-CBC' to your configuration and/or add BF-CBC to "
3112             "--data-ciphers.");
3113 
3114         /* We still need to set the ciphername to BF-CBC since various other
3115          * parts of OpenVPN assert that the ciphername is set */
3116         o->ciphername = "BF-CBC";
3117     }
3118     else if (!o->enable_ncp_fallback
3119              && !tls_item_in_cipher_list(o->ciphername, o->ncp_ciphers))
3120     {
3121         msg(M_WARN, "DEPRECATED OPTION: --cipher set to '%s' but missing in"
3122             " --data-ciphers (%s). Future OpenVPN version will "
3123             "ignore --cipher for cipher negotiations. "
3124             "Add '%s' to --data-ciphers or change --cipher '%s' to "
3125             "--data-ciphers-fallback '%s' to silence this warning.",
3126             o->ciphername, o->ncp_ciphers, o->ciphername,
3127             o->ciphername, o->ciphername);
3128         o->enable_ncp_fallback = true;
3129 
3130         /* Append the --cipher to ncp_ciphers to allow it in NCP */
3131         size_t newlen = strlen(o->ncp_ciphers) + 1 + strlen(o->ciphername) + 1;
3132         char *ncp_ciphers = gc_malloc(newlen, false, &o->gc);
3133 
3134         ASSERT(openvpn_snprintf(ncp_ciphers, newlen, "%s:%s", o->ncp_ciphers,
3135                                 o->ciphername));
3136         o->ncp_ciphers = ncp_ciphers;
3137     }
3138 }
3139 
3140 static void
options_postprocess_mutate(struct options * o)3141 options_postprocess_mutate(struct options *o)
3142 {
3143     int i;
3144     /*
3145      * Process helper-type options which map to other, more complex
3146      * sequences of options.
3147      */
3148     helper_client_server(o);
3149     helper_keepalive(o);
3150     helper_tcp_nodelay(o);
3151 
3152     options_postprocess_cipher(o);
3153     options_postprocess_mutate_invariant(o);
3154 
3155     if (o->ncp_enabled)
3156     {
3157         o->ncp_ciphers = mutate_ncp_cipher_list(o->ncp_ciphers, &o->gc);
3158         if (o->ncp_ciphers == NULL)
3159         {
3160             msg(M_USAGE, "NCP cipher list contains unsupported ciphers or is too long.");
3161         }
3162     }
3163 
3164     if (o->remote_list && !o->connection_list)
3165     {
3166         /*
3167          * Convert remotes into connection list
3168          */
3169         const struct remote_list *rl = o->remote_list;
3170         for (i = 0; i < rl->len; ++i)
3171         {
3172             const struct remote_entry *re = rl->array[i];
3173             struct connection_entry ce = o->ce;
3174             struct connection_entry *ace;
3175 
3176             ASSERT(re->remote);
3177             connection_entry_load_re(&ce, re);
3178             ace = alloc_connection_entry(o, M_USAGE);
3179             ASSERT(ace);
3180             *ace = ce;
3181         }
3182     }
3183     else if (!o->remote_list && !o->connection_list)
3184     {
3185         struct connection_entry *ace;
3186         ace = alloc_connection_entry(o, M_USAGE);
3187         ASSERT(ace);
3188         *ace = o->ce;
3189     }
3190 
3191     ASSERT(o->connection_list);
3192     for (i = 0; i < o->connection_list->len; ++i)
3193     {
3194         options_postprocess_mutate_ce(o, o->connection_list->array[i]);
3195     }
3196 
3197     if (o->tls_server)
3198     {
3199         /* Check that DH file is specified, or explicitly disabled */
3200         notnull(o->dh_file, "DH file (--dh)");
3201         if (streq(o->dh_file, "none"))
3202         {
3203             o->dh_file = NULL;
3204         }
3205     }
3206     else if (o->dh_file)
3207     {
3208         /* DH file is only meaningful in a tls-server context. */
3209         msg(M_WARN, "WARNING: Ignoring option 'dh' in tls-client mode, please only "
3210             "include this in your server configuration");
3211         o->dh_file = NULL;
3212     }
3213 #if ENABLE_MANAGEMENT
3214     if (o->http_proxy_override)
3215     {
3216         options_postprocess_http_proxy_override(o);
3217     }
3218 #endif
3219 
3220 #if P2MP
3221     /*
3222      * Save certain parms before modifying options via --pull
3223      */
3224     pre_pull_save(o);
3225 #endif
3226 }
3227 
3228 /*
3229  *  Check file/directory sanity
3230  *
3231  */
3232 #ifndef ENABLE_SMALL  /** Expect people using the stripped down version to know what they do */
3233 
3234 #define CHKACC_FILE (1<<0)       /** Check for a file/directory presence */
3235 #define CHKACC_DIRPATH (1<<1)    /** Check for directory presence where a file should reside */
3236 #define CHKACC_FILEXSTWR (1<<2)  /** If file exists, is it writable? */
3237 #define CHKACC_ACPTSTDIN (1<<3)  /** If filename is stdin, it's allowed and "exists" */
3238 #define CHKACC_PRIVATE (1<<4)    /** Warn if this (private) file is group/others accessible */
3239 
3240 static bool
check_file_access(const int type,const char * file,const int mode,const char * opt)3241 check_file_access(const int type, const char *file, const int mode, const char *opt)
3242 {
3243     int errcode = 0;
3244 
3245     /* If no file configured, no errors to look for */
3246     if (!file)
3247     {
3248         return false;
3249     }
3250 
3251     /* If stdin is allowed and the file name is 'stdin', then do no
3252      * further checks as stdin is always available
3253      */
3254     if ( (type & CHKACC_ACPTSTDIN) && streq(file, "stdin") )
3255     {
3256         return false;
3257     }
3258 
3259     /* Is the directory path leading to the given file accessible? */
3260     if (type & CHKACC_DIRPATH)
3261     {
3262         char *fullpath = string_alloc(file, NULL); /* POSIX dirname() implementation may modify its arguments */
3263         char *dirpath = dirname(fullpath);
3264 
3265         if (platform_access(dirpath, mode|X_OK) != 0)
3266         {
3267             errcode = errno;
3268         }
3269         free(fullpath);
3270     }
3271 
3272     /* Is the file itself accessible? */
3273     if (!errcode && (type & CHKACC_FILE) && (platform_access(file, mode) != 0) )
3274     {
3275         errcode = errno;
3276     }
3277 
3278     /* If the file exists and is accessible, is it writable? */
3279     if (!errcode && (type & CHKACC_FILEXSTWR) && (platform_access(file, F_OK) == 0) )
3280     {
3281         if (platform_access(file, W_OK) != 0)
3282         {
3283             errcode = errno;
3284         }
3285     }
3286 
3287     /* Warn if a given private file is group/others accessible. */
3288     if (type & CHKACC_PRIVATE)
3289     {
3290         platform_stat_t st;
3291         if (platform_stat(file, &st))
3292         {
3293             msg(M_WARN | M_ERRNO, "WARNING: cannot stat file '%s'", file);
3294         }
3295 #ifndef _WIN32
3296         else
3297         {
3298             if (st.st_mode & (S_IRWXG|S_IRWXO))
3299             {
3300                 msg(M_WARN, "WARNING: file '%s' is group or others accessible", file);
3301             }
3302         }
3303 #endif
3304     }
3305 
3306     /* Scream if an error is found */
3307     if (errcode > 0)
3308     {
3309         msg(M_NOPREFIX | M_OPTERR | M_ERRNO, "%s fails with '%s'", opt, file);
3310     }
3311 
3312     /* Return true if an error occurred */
3313     return (errcode != 0 ? true : false);
3314 }
3315 
3316 /* A wrapper for check_file_access() which also takes a chroot directory.
3317  * If chroot is NULL, behaviour is exactly the same as calling check_file_access() directly,
3318  * otherwise it will look for the file inside the given chroot directory instead.
3319  */
3320 static bool
check_file_access_chroot(const char * chroot,const int type,const char * file,const int mode,const char * opt)3321 check_file_access_chroot(const char *chroot, const int type, const char *file, const int mode, const char *opt)
3322 {
3323     bool ret = false;
3324 
3325     /* If no file configured, no errors to look for */
3326     if (!file)
3327     {
3328         return false;
3329     }
3330 
3331     /* If chroot is set, look for the file/directory inside the chroot */
3332     if (chroot)
3333     {
3334         struct gc_arena gc = gc_new();
3335         struct buffer chroot_file;
3336 
3337         chroot_file = prepend_dir(chroot, file, &gc);
3338         ret = check_file_access(type, BSTR(&chroot_file), mode, opt);
3339         gc_free(&gc);
3340     }
3341     else
3342     {
3343         /* No chroot in play, just call core file check function */
3344         ret = check_file_access(type, file, mode, opt);
3345     }
3346     return ret;
3347 }
3348 
3349 /**
3350  * A wrapper for check_file_access_chroot() that returns false immediately if
3351  * the file is inline (and therefore there is no access to check)
3352  */
3353 static bool
check_file_access_chroot_inline(bool is_inline,const char * chroot,const int type,const char * file,const int mode,const char * opt)3354 check_file_access_chroot_inline(bool is_inline, const char *chroot,
3355                                 const int type, const char *file,
3356                                 const int mode, const char *opt)
3357 {
3358     if (is_inline)
3359     {
3360         return false;
3361     }
3362 
3363     return check_file_access_chroot(chroot, type, file, mode, opt);
3364 }
3365 
3366 /**
3367  * A wrapper for check_file_access() that returns false immediately if the file
3368  * is inline (and therefore there is no access to check)
3369  */
3370 static bool
check_file_access_inline(bool is_inline,const int type,const char * file,const int mode,const char * opt)3371 check_file_access_inline(bool is_inline, const int type, const char *file,
3372                          const int mode, const char *opt)
3373 {
3374     if (is_inline)
3375     {
3376         return false;
3377     }
3378 
3379     return check_file_access(type, file, mode, opt);
3380 }
3381 
3382 /*
3383  * Verifies that the path in the "command" that comes after certain script options (e.g., --up) is a
3384  * valid file with appropriate permissions.
3385  *
3386  * "command" consists of a path, optionally followed by a space, which may be
3387  * followed by arbitrary arguments. It is NOT a full shell command line -- shell expansion is not
3388  * performed.
3389  *
3390  * The path and arguments in "command" may be single- or double-quoted or escaped.
3391  *
3392  * The path is extracted from "command", then check_file_access() is called to check it. The
3393  * arguments, if any, are ignored.
3394  *
3395  * Note that the type, mode, and opt arguments to this routine are the same as the corresponding
3396  * check_file_access() arguments.
3397  */
3398 static bool
check_cmd_access(const char * command,const char * opt,const char * chroot)3399 check_cmd_access(const char *command, const char *opt, const char *chroot)
3400 {
3401     struct argv argv;
3402     bool return_code;
3403 
3404     /* If no command was set, there are no errors to look for */
3405     if (!command)
3406     {
3407         return false;
3408     }
3409 
3410     /* Extract executable path and arguments */
3411     argv = argv_new();
3412     argv_parse_cmd(&argv, command);
3413 
3414     /* if an executable is specified then check it; otherwise, complain */
3415     if (argv.argv[0])
3416     {
3417         /* Scripts requires R_OK as well, but that might fail on binaries which
3418          * only requires X_OK to function on Unix - a scenario not unlikely to
3419          * be seen on suid binaries.
3420          */
3421         return_code = check_file_access_chroot(chroot, CHKACC_FILE, argv.argv[0], X_OK, opt);
3422     }
3423     else
3424     {
3425         msg(M_NOPREFIX|M_OPTERR, "%s fails with '%s': No path to executable.",
3426             opt, command);
3427         return_code = true;
3428     }
3429 
3430     argv_free(&argv);
3431 
3432     return return_code;
3433 }
3434 
3435 /*
3436  * Sanity check of all file/dir options.  Checks that file/dir
3437  * is accessible by OpenVPN
3438  */
3439 static void
options_postprocess_filechecks(struct options * options)3440 options_postprocess_filechecks(struct options *options)
3441 {
3442     bool errs = false;
3443 
3444     /* ** SSL/TLS/crypto related files ** */
3445     errs |= check_file_access_inline(options->dh_file_inline, CHKACC_FILE,
3446                                      options->dh_file, R_OK, "--dh");
3447 
3448     errs |= check_file_access_inline(options->ca_file_inline, CHKACC_FILE,
3449                                      options->ca_file, R_OK, "--ca");
3450 
3451     errs |= check_file_access_chroot(options->chroot_dir, CHKACC_FILE,
3452                                      options->ca_path, R_OK, "--capath");
3453 
3454     errs |= check_file_access_inline(options->cert_file_inline, CHKACC_FILE,
3455                                      options->cert_file, R_OK, "--cert");
3456 
3457     errs |= check_file_access_inline(options->extra_certs_file, CHKACC_FILE,
3458                                      options->extra_certs_file, R_OK,
3459                                      "--extra-certs");
3460 
3461 #ifdef ENABLE_MANAGMENT
3462     if (!(options->management_flags & MF_EXTERNAL_KEY))
3463 #endif
3464     {
3465         errs |= check_file_access_inline(options->priv_key_file_inline,
3466                                          CHKACC_FILE|CHKACC_PRIVATE,
3467                                          options->priv_key_file, R_OK, "--key");
3468     }
3469 
3470     errs |= check_file_access_inline(options->pkcs12_file_inline,
3471                                      CHKACC_FILE|CHKACC_PRIVATE,
3472                                      options->pkcs12_file, R_OK, "--pkcs12");
3473 
3474     if (options->ssl_flags & SSLF_CRL_VERIFY_DIR)
3475     {
3476         errs |= check_file_access_chroot(options->chroot_dir, CHKACC_FILE,
3477                                          options->crl_file, R_OK|X_OK,
3478                                          "--crl-verify directory");
3479     }
3480     else
3481     {
3482         errs |= check_file_access_chroot_inline(options->crl_file_inline,
3483                                                 options->chroot_dir,
3484                                                 CHKACC_FILE, options->crl_file,
3485                                                 R_OK, "--crl-verify");
3486     }
3487 
3488     ASSERT(options->connection_list);
3489     for (int i = 0; i < options->connection_list->len; ++i)
3490     {
3491         struct connection_entry *ce = options->connection_list->array[i];
3492 
3493         errs |= check_file_access_inline(ce->tls_auth_file_inline,
3494                                          CHKACC_FILE|CHKACC_PRIVATE,
3495                                          ce->tls_auth_file, R_OK,
3496                                          "--tls-auth");
3497         errs |= check_file_access_inline(ce->tls_crypt_file_inline,
3498                                          CHKACC_FILE|CHKACC_PRIVATE,
3499                                          ce->tls_crypt_file, R_OK,
3500                                          "--tls-crypt");
3501         errs |= check_file_access_inline(ce->tls_crypt_v2_file_inline,
3502                                          CHKACC_FILE|CHKACC_PRIVATE,
3503                                          ce->tls_crypt_v2_file, R_OK,
3504                                          "--tls-crypt-v2");
3505     }
3506 
3507     errs |= check_file_access_inline(options->shared_secret_file_inline,
3508                                      CHKACC_FILE|CHKACC_PRIVATE,
3509                                      options->shared_secret_file, R_OK,
3510                                      "--secret");
3511 
3512     errs |= check_file_access(CHKACC_DIRPATH|CHKACC_FILEXSTWR,
3513                               options->packet_id_file, R_OK|W_OK, "--replay-persist");
3514 
3515     /* ** Password files ** */
3516     errs |= check_file_access(CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE,
3517                               options->key_pass_file, R_OK, "--askpass");
3518 #ifdef ENABLE_MANAGEMENT
3519     errs |= check_file_access(CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE,
3520                               options->management_user_pass, R_OK,
3521                               "--management user/password file");
3522 #endif /* ENABLE_MANAGEMENT */
3523 #if P2MP
3524     errs |= check_file_access(CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE,
3525                               options->auth_user_pass_file, R_OK,
3526                               "--auth-user-pass");
3527 #endif /* P2MP */
3528 
3529     /* ** System related ** */
3530     errs |= check_file_access(CHKACC_FILE, options->chroot_dir,
3531                               R_OK|X_OK, "--chroot directory");
3532     errs |= check_file_access(CHKACC_DIRPATH|CHKACC_FILEXSTWR, options->writepid,
3533                               R_OK|W_OK, "--writepid");
3534 
3535     /* ** Log related ** */
3536     errs |= check_file_access(CHKACC_DIRPATH|CHKACC_FILEXSTWR, options->status_file,
3537                               R_OK|W_OK, "--status");
3538 
3539     /* ** Config related ** */
3540     errs |= check_file_access_chroot(options->chroot_dir, CHKACC_FILE, options->tls_export_cert,
3541                                      R_OK|W_OK|X_OK, "--tls-export-cert");
3542     errs |= check_file_access_chroot(options->chroot_dir, CHKACC_FILE, options->client_config_dir,
3543                                      R_OK|X_OK, "--client-config-dir");
3544     errs |= check_file_access_chroot(options->chroot_dir, CHKACC_FILE, options->tmp_dir,
3545                                      R_OK|W_OK|X_OK, "Temporary directory (--tmp-dir)");
3546 
3547     if (errs)
3548     {
3549         msg(M_USAGE, "Please correct these errors.");
3550     }
3551 }
3552 #endif /* !ENABLE_SMALL */
3553 
3554 /*
3555  * Sanity check on options.
3556  * Also set some options based on other
3557  * options.
3558  */
3559 void
options_postprocess(struct options * options)3560 options_postprocess(struct options *options)
3561 {
3562     options_postprocess_mutate(options);
3563     options_postprocess_verify(options);
3564 #ifndef ENABLE_SMALL
3565     options_postprocess_filechecks(options);
3566 #endif /* !ENABLE_SMALL */
3567 }
3568 
3569 #if P2MP
3570 
3571 /*
3572  * Save/Restore certain option defaults before --pull is applied.
3573  */
3574 
3575 void
pre_pull_save(struct options * o)3576 pre_pull_save(struct options *o)
3577 {
3578     if (o->pull)
3579     {
3580         ALLOC_OBJ_CLEAR_GC(o->pre_pull, struct options_pre_pull, &o->gc);
3581         o->pre_pull->tuntap_options = o->tuntap_options;
3582         o->pre_pull->tuntap_options_defined = true;
3583         o->pre_pull->foreign_option_index = o->foreign_option_index;
3584         if (o->routes)
3585         {
3586             o->pre_pull->routes = clone_route_option_list(o->routes, &o->gc);
3587             o->pre_pull->routes_defined = true;
3588         }
3589         if (o->routes_ipv6)
3590         {
3591             o->pre_pull->routes_ipv6 = clone_route_ipv6_option_list(o->routes_ipv6, &o->gc);
3592             o->pre_pull->routes_ipv6_defined = true;
3593         }
3594         if (o->client_nat)
3595         {
3596             o->pre_pull->client_nat = clone_client_nat_option_list(o->client_nat, &o->gc);
3597             o->pre_pull->client_nat_defined = true;
3598         }
3599 
3600         o->pre_pull->route_default_gateway = o->route_default_gateway;
3601         o->pre_pull->route_ipv6_default_gateway = o->route_ipv6_default_gateway;
3602 
3603         /* Ping related options should be reset to the config values on reconnect */
3604         o->pre_pull->ping_rec_timeout = o->ping_rec_timeout;
3605         o->pre_pull->ping_rec_timeout_action = o->ping_rec_timeout_action;
3606         o->pre_pull->ping_send_timeout = o->ping_send_timeout;
3607     }
3608 }
3609 
3610 void
pre_pull_restore(struct options * o,struct gc_arena * gc)3611 pre_pull_restore(struct options *o, struct gc_arena *gc)
3612 {
3613     const struct options_pre_pull *pp = o->pre_pull;
3614     if (pp)
3615     {
3616         CLEAR(o->tuntap_options);
3617         if (pp->tuntap_options_defined)
3618         {
3619             o->tuntap_options = pp->tuntap_options;
3620         }
3621 
3622         if (pp->routes_defined)
3623         {
3624             rol_check_alloc(o);
3625             copy_route_option_list(o->routes, pp->routes, gc);
3626         }
3627         else
3628         {
3629             o->routes = NULL;
3630         }
3631 
3632         if (pp->routes_ipv6_defined)
3633         {
3634             rol6_check_alloc(o);
3635             copy_route_ipv6_option_list(o->routes_ipv6, pp->routes_ipv6, gc);
3636         }
3637         else
3638         {
3639             o->routes_ipv6 = NULL;
3640         }
3641 
3642         o->route_default_gateway = pp->route_default_gateway;
3643         o->route_ipv6_default_gateway = pp->route_ipv6_default_gateway;
3644 
3645         if (pp->client_nat_defined)
3646         {
3647             cnol_check_alloc(o);
3648             copy_client_nat_option_list(o->client_nat, pp->client_nat);
3649         }
3650         else
3651         {
3652             o->client_nat = NULL;
3653         }
3654 
3655         o->foreign_option_index = pp->foreign_option_index;
3656 
3657         o->ping_rec_timeout = pp->ping_rec_timeout;
3658         o->ping_rec_timeout_action = pp->ping_rec_timeout_action;
3659         o->ping_send_timeout = pp->ping_send_timeout;
3660     }
3661 
3662     o->push_continuation = 0;
3663     o->push_option_types_found = 0;
3664 }
3665 
3666 #endif /* if P2MP */
3667 /**
3668  * Calculate the link-mtu to advertise to our peer.  The actual value is not
3669  * relevant, because we will possibly perform data channel cipher negotiation
3670  * after this, but older clients will log warnings if we do not supply them the
3671  * value they expect.  This assumes that the traditional cipher/auth directives
3672  * in the config match the config of the peer.
3673  */
3674 static size_t
calc_options_string_link_mtu(const struct options * o,const struct frame * frame)3675 calc_options_string_link_mtu(const struct options *o, const struct frame *frame)
3676 {
3677     size_t link_mtu = EXPANDED_SIZE(frame);
3678 
3679     if (o->pull || o->mode == MODE_SERVER)
3680     {
3681         struct frame fake_frame = *frame;
3682         struct key_type fake_kt;
3683         init_key_type(&fake_kt, o->ciphername, o->authname, o->keysize, true,
3684                       false);
3685         frame_remove_from_extra_frame(&fake_frame, crypto_max_overhead());
3686         crypto_adjust_frame_parameters(&fake_frame, &fake_kt, o->replay,
3687                                        cipher_kt_mode_ofb_cfb(fake_kt.cipher));
3688         frame_finalize(&fake_frame, o->ce.link_mtu_defined, o->ce.link_mtu,
3689                        o->ce.tun_mtu_defined, o->ce.tun_mtu);
3690         msg(D_MTU_DEBUG, "%s: link-mtu %u -> %d", __func__, (unsigned int) link_mtu,
3691             EXPANDED_SIZE(&fake_frame));
3692         link_mtu = EXPANDED_SIZE(&fake_frame);
3693     }
3694     return link_mtu;
3695 }
3696 /*
3697  * Build an options string to represent data channel encryption options.
3698  * This string must match exactly between peers.  The keysize is checked
3699  * separately by read_key().
3700  *
3701  * The following options must match on both peers:
3702  *
3703  * Tunnel options:
3704  *
3705  * --dev tun|tap [unit number need not match]
3706  * --dev-type tun|tap
3707  * --link-mtu
3708  * --udp-mtu
3709  * --tun-mtu
3710  * --proto udp
3711  * --proto tcp-client [matched with --proto tcp-server
3712  *                     on the other end of the connection]
3713  * --proto tcp-server [matched with --proto tcp-client on
3714  *                     the other end of the connection]
3715  * --tun-ipv6
3716  * --ifconfig x y [matched with --ifconfig y x on
3717  *                 the other end of the connection]
3718  *
3719  * --comp-lzo
3720  * --compress alg
3721  * --fragment
3722  *
3723  * Crypto Options:
3724  *
3725  * --cipher
3726  * --auth
3727  * --keysize
3728  * --secret
3729  * --no-replay
3730  *
3731  * SSL Options:
3732  *
3733  * --tls-auth
3734  * --tls-client [matched with --tls-server on
3735  *               the other end of the connection]
3736  * --tls-server [matched with --tls-client on
3737  *               the other end of the connection]
3738  */
3739 char *
options_string(const struct options * o,const struct frame * frame,struct tuntap * tt,openvpn_net_ctx_t * ctx,bool remote,struct gc_arena * gc)3740 options_string(const struct options *o,
3741                const struct frame *frame,
3742                struct tuntap *tt,
3743                openvpn_net_ctx_t *ctx,
3744                bool remote,
3745                struct gc_arena *gc)
3746 {
3747     struct buffer out = alloc_buf(OPTION_LINE_SIZE);
3748     bool tt_local = false;
3749 
3750     buf_printf(&out, "V4");
3751 
3752     /*
3753      * Tunnel Options
3754      */
3755 
3756     buf_printf(&out, ",dev-type %s", dev_type_string(o->dev, o->dev_type));
3757     /* the link-mtu that we send has only a meaning if have a fixed
3758      * cipher (p2p) or have a fallback cipher configured for older non
3759      * ncp clients. But not sending it will make even 2.4 complain
3760      * about it being missing. So still send it. */
3761     buf_printf(&out, ",link-mtu %u",
3762                (unsigned int) calc_options_string_link_mtu(o, frame));
3763 
3764     buf_printf(&out, ",tun-mtu %d", PAYLOAD_SIZE(frame));
3765     buf_printf(&out, ",proto %s",  proto_remote(o->ce.proto, remote));
3766 
3767     bool p2p_nopull = o->mode == MODE_POINT_TO_POINT && !PULL_DEFINED(o);
3768     /* send tun_ipv6 only in peer2peer mode - in client/server mode, it
3769      * is usually pushed by the server, triggering a non-helpful warning
3770      */
3771     if (o->ifconfig_ipv6_local && p2p_nopull)
3772     {
3773         buf_printf(&out, ",tun-ipv6");
3774     }
3775 
3776     /*
3777      * Try to get ifconfig parameters into the options string.
3778      * If tt is undefined, make a temporary instantiation.
3779      */
3780     if (!tt)
3781     {
3782         tt = init_tun(o->dev,
3783                       o->dev_type,
3784                       o->topology,
3785                       o->ifconfig_local,
3786                       o->ifconfig_remote_netmask,
3787                       o->ifconfig_ipv6_local,
3788                       o->ifconfig_ipv6_netbits,
3789                       o->ifconfig_ipv6_remote,
3790                       NULL,
3791                       NULL,
3792                       false,
3793                       NULL,
3794                       ctx);
3795         if (tt)
3796         {
3797             tt_local = true;
3798         }
3799     }
3800 
3801     if (tt && p2p_nopull)
3802     {
3803         const char *ios = ifconfig_options_string(tt, remote, o->ifconfig_nowarn, gc);
3804         if (ios && strlen(ios))
3805         {
3806             buf_printf(&out, ",ifconfig %s", ios);
3807         }
3808     }
3809     if (tt_local)
3810     {
3811         free(tt);
3812         tt = NULL;
3813     }
3814 
3815 #ifdef USE_COMP
3816     if (o->comp.alg != COMP_ALG_UNDEF)
3817     {
3818         buf_printf(&out, ",comp-lzo"); /* for compatibility, this simply indicates that compression context is active, not necessarily LZO per-se */
3819     }
3820 #endif
3821 
3822 #ifdef ENABLE_FRAGMENT
3823     if (o->ce.fragment)
3824     {
3825         buf_printf(&out, ",mtu-dynamic");
3826     }
3827 #endif
3828 
3829 #define TLS_CLIENT (o->tls_client)
3830 #define TLS_SERVER (o->tls_server)
3831 
3832     /*
3833      * Key direction
3834      */
3835     {
3836         const char *kd = keydirection2ascii(o->key_direction, remote, false);
3837         if (kd)
3838         {
3839             buf_printf(&out, ",keydir %s", kd);
3840         }
3841     }
3842 
3843     /*
3844      * Crypto Options
3845      */
3846     if (o->shared_secret_file || TLS_CLIENT || TLS_SERVER)
3847     {
3848         struct key_type kt;
3849 
3850         ASSERT((o->shared_secret_file != NULL)
3851                + (TLS_CLIENT == true)
3852                + (TLS_SERVER == true)
3853                <= 1);
3854 
3855         init_key_type(&kt, o->ciphername, o->authname, o->keysize, true,
3856                       false);
3857         /* Only announce the cipher to our peer if we are willing to
3858          * support it */
3859         const char *ciphername = cipher_kt_name(kt.cipher);
3860         if (p2p_nopull || !o->ncp_enabled
3861             || tls_item_in_cipher_list(ciphername, o->ncp_ciphers))
3862         {
3863             buf_printf(&out, ",cipher %s", ciphername);
3864         }
3865         buf_printf(&out, ",auth %s", md_kt_name(kt.digest));
3866         buf_printf(&out, ",keysize %d", kt.cipher_length * 8);
3867         if (o->shared_secret_file)
3868         {
3869             buf_printf(&out, ",secret");
3870         }
3871         if (!o->replay)
3872         {
3873             buf_printf(&out, ",no-replay");
3874         }
3875 
3876 #ifdef ENABLE_PREDICTION_RESISTANCE
3877         if (o->use_prediction_resistance)
3878         {
3879             buf_printf(&out, ",use-prediction-resistance");
3880         }
3881 #endif
3882     }
3883 
3884     /*
3885      * SSL Options
3886      */
3887     {
3888         if (TLS_CLIENT || TLS_SERVER)
3889         {
3890             if (o->ce.tls_auth_file)
3891             {
3892                 buf_printf(&out, ",tls-auth");
3893             }
3894             /* Not adding tls-crypt here, because we won't reach this code if
3895              * tls-auth/tls-crypt does not match.  Removing tls-auth here would
3896              * break stuff, so leaving that in place. */
3897 
3898             buf_printf(&out, ",key-method %d", KEY_METHOD_2);
3899         }
3900 
3901         if (remote)
3902         {
3903             if (TLS_CLIENT)
3904             {
3905                 buf_printf(&out, ",tls-server");
3906             }
3907             else if (TLS_SERVER)
3908             {
3909                 buf_printf(&out, ",tls-client");
3910             }
3911         }
3912         else
3913         {
3914             if (TLS_CLIENT)
3915             {
3916                 buf_printf(&out, ",tls-client");
3917             }
3918             else if (TLS_SERVER)
3919             {
3920                 buf_printf(&out, ",tls-server");
3921             }
3922         }
3923     }
3924 
3925 #undef TLS_CLIENT
3926 #undef TLS_SERVER
3927 
3928     return BSTR(&out);
3929 }
3930 
3931 /*
3932  * Compare option strings for equality.
3933  * If the first two chars of the strings differ, it means that
3934  * we are looking at different versions of the options string,
3935  * therefore don't compare them and return true.
3936  */
3937 
3938 bool
options_cmp_equal(char * actual,const char * expected)3939 options_cmp_equal(char *actual, const char *expected)
3940 {
3941     return options_cmp_equal_safe(actual, expected, strlen(actual) + 1);
3942 }
3943 
3944 void
options_warning(char * actual,const char * expected)3945 options_warning(char *actual, const char *expected)
3946 {
3947     options_warning_safe(actual, expected, strlen(actual) + 1);
3948 }
3949 
3950 static const char *
options_warning_extract_parm1(const char * option_string,struct gc_arena * gc_ret)3951 options_warning_extract_parm1(const char *option_string,
3952                               struct gc_arena *gc_ret)
3953 {
3954     struct gc_arena gc = gc_new();
3955     struct buffer b = string_alloc_buf(option_string, &gc);
3956     char *p = gc_malloc(OPTION_PARM_SIZE, false, &gc);
3957     const char *ret;
3958 
3959     buf_parse(&b, ' ', p, OPTION_PARM_SIZE);
3960     ret = string_alloc(p, gc_ret);
3961     gc_free(&gc);
3962     return ret;
3963 }
3964 
3965 static void
options_warning_safe_scan2(const int msglevel,const int delim,const bool report_inconsistent,const char * p1,const struct buffer * b2_src,const char * b1_name,const char * b2_name)3966 options_warning_safe_scan2(const int msglevel,
3967                            const int delim,
3968                            const bool report_inconsistent,
3969                            const char *p1,
3970                            const struct buffer *b2_src,
3971                            const char *b1_name,
3972                            const char *b2_name)
3973 {
3974     /* We will stop sending 'key-method', 'keydir', 'proto' and 'tls-auth' in
3975      * OCC in a future version (because it's not useful). To reduce questions
3976      * when interoperating, we no longer printing a warning about it.
3977      */
3978     if (strprefix(p1, "key-method ")
3979         || strprefix(p1, "keydir ")
3980         || strprefix(p1, "proto ")
3981         || streq(p1, "tls-auth")
3982         || strprefix(p1, "tun-ipv6")
3983         || strprefix(p1, "cipher "))
3984     {
3985         return;
3986     }
3987 
3988     if (strlen(p1) > 0)
3989     {
3990         struct gc_arena gc = gc_new();
3991         struct buffer b2 = *b2_src;
3992         const char *p1_prefix = options_warning_extract_parm1(p1, &gc);
3993         char *p2 = gc_malloc(OPTION_PARM_SIZE, false, &gc);
3994 
3995         while (buf_parse(&b2, delim, p2, OPTION_PARM_SIZE))
3996         {
3997             if (strlen(p2))
3998             {
3999                 const char *p2_prefix = options_warning_extract_parm1(p2, &gc);
4000 
4001                 if (!strcmp(p1, p2))
4002                 {
4003                     goto done;
4004                 }
4005                 if (!strcmp(p1_prefix, p2_prefix))
4006                 {
4007                     if (report_inconsistent)
4008                     {
4009                         msg(msglevel, "WARNING: '%s' is used inconsistently, %s='%s', %s='%s'",
4010                             safe_print(p1_prefix, &gc),
4011                             b1_name,
4012                             safe_print(p1, &gc),
4013                             b2_name,
4014                             safe_print(p2, &gc));
4015                     }
4016                     goto done;
4017                 }
4018             }
4019         }
4020 
4021         msg(msglevel, "WARNING: '%s' is present in %s config but missing in %s config, %s='%s'",
4022             safe_print(p1_prefix, &gc),
4023             b1_name,
4024             b2_name,
4025             b1_name,
4026             safe_print(p1, &gc));
4027 
4028 done:
4029         gc_free(&gc);
4030     }
4031 }
4032 
4033 static void
options_warning_safe_scan1(const int msglevel,const int delim,const bool report_inconsistent,const struct buffer * b1_src,const struct buffer * b2_src,const char * b1_name,const char * b2_name)4034 options_warning_safe_scan1(const int msglevel,
4035                            const int delim,
4036                            const bool report_inconsistent,
4037                            const struct buffer *b1_src,
4038                            const struct buffer *b2_src,
4039                            const char *b1_name,
4040                            const char *b2_name)
4041 {
4042     struct gc_arena gc = gc_new();
4043     struct buffer b = *b1_src;
4044     char *p = gc_malloc(OPTION_PARM_SIZE, true, &gc);
4045 
4046     while (buf_parse(&b, delim, p, OPTION_PARM_SIZE))
4047     {
4048         options_warning_safe_scan2(msglevel, delim, report_inconsistent, p, b2_src, b1_name, b2_name);
4049     }
4050 
4051     gc_free(&gc);
4052 }
4053 
4054 static void
options_warning_safe_ml(const int msglevel,char * actual,const char * expected,size_t actual_n)4055 options_warning_safe_ml(const int msglevel, char *actual, const char *expected, size_t actual_n)
4056 {
4057     struct gc_arena gc = gc_new();
4058 
4059     if (actual_n > 0)
4060     {
4061         struct buffer local = alloc_buf_gc(OPTION_PARM_SIZE + 16, &gc);
4062         struct buffer remote = alloc_buf_gc(OPTION_PARM_SIZE + 16, &gc);
4063         actual[actual_n - 1] = 0;
4064 
4065         buf_printf(&local, "version %s", expected);
4066         buf_printf(&remote, "version %s", actual);
4067 
4068         options_warning_safe_scan1(msglevel, ',', true,
4069                                    &local, &remote,
4070                                    "local", "remote");
4071 
4072         options_warning_safe_scan1(msglevel, ',', false,
4073                                    &remote, &local,
4074                                    "remote", "local");
4075     }
4076 
4077     gc_free(&gc);
4078 }
4079 
4080 bool
options_cmp_equal_safe(char * actual,const char * expected,size_t actual_n)4081 options_cmp_equal_safe(char *actual, const char *expected, size_t actual_n)
4082 {
4083     struct gc_arena gc = gc_new();
4084     bool ret = true;
4085 
4086     if (actual_n > 0)
4087     {
4088         actual[actual_n - 1] = 0;
4089 #ifndef ENABLE_STRICT_OPTIONS_CHECK
4090         if (strncmp(actual, expected, 2))
4091         {
4092             msg(D_SHOW_OCC, "NOTE: Options consistency check may be skewed by version differences");
4093             options_warning_safe_ml(D_SHOW_OCC, actual, expected, actual_n);
4094         }
4095         else
4096 #endif
4097         ret = !strcmp(actual, expected);
4098     }
4099     gc_free(&gc);
4100     return ret;
4101 }
4102 
4103 void
options_warning_safe(char * actual,const char * expected,size_t actual_n)4104 options_warning_safe(char *actual, const char *expected, size_t actual_n)
4105 {
4106     options_warning_safe_ml(M_WARN, actual, expected, actual_n);
4107 }
4108 
4109 const char *
options_string_version(const char * s,struct gc_arena * gc)4110 options_string_version(const char *s, struct gc_arena *gc)
4111 {
4112     struct buffer out = alloc_buf_gc(4, gc);
4113     strncpynt((char *) BPTR(&out), s, 3);
4114     return BSTR(&out);
4115 }
4116 
4117 char *
options_string_extract_option(const char * options_string,const char * opt_name,struct gc_arena * gc)4118 options_string_extract_option(const char *options_string,const char *opt_name,
4119                               struct gc_arena *gc)
4120 {
4121     char *ret = NULL;
4122     const size_t opt_name_len = strlen(opt_name);
4123 
4124     const char *p = options_string;
4125     while (p)
4126     {
4127         if (0 == strncmp(p, opt_name, opt_name_len)
4128             && strlen(p) > (opt_name_len+1) && p[opt_name_len] == ' ')
4129         {
4130             /* option found, extract value */
4131             const char *start = &p[opt_name_len+1];
4132             const char *end = strchr(p, ',');
4133             size_t val_len = end ? end - start : strlen(start);
4134             ret = gc_malloc(val_len+1, true, gc);
4135             memcpy(ret, start, val_len);
4136             break;
4137         }
4138         p = strchr(p, ',');
4139         if (p)
4140         {
4141             p++; /* skip delimiter */
4142         }
4143     }
4144     return ret;
4145 }
4146 
4147 static void
foreign_option(struct options * o,char * argv[],int len,struct env_set * es)4148 foreign_option(struct options *o, char *argv[], int len, struct env_set *es)
4149 {
4150     if (len > 0)
4151     {
4152         struct gc_arena gc = gc_new();
4153         struct buffer name = alloc_buf_gc(OPTION_PARM_SIZE, &gc);
4154         struct buffer value = alloc_buf_gc(OPTION_PARM_SIZE, &gc);
4155         int i;
4156         bool first = true;
4157         bool good = true;
4158 
4159         good &= buf_printf(&name, "foreign_option_%d", o->foreign_option_index + 1);
4160         ++o->foreign_option_index;
4161         for (i = 0; i < len; ++i)
4162         {
4163             if (argv[i])
4164             {
4165                 if (!first)
4166                 {
4167                     good &= buf_printf(&value, " ");
4168                 }
4169                 good &= buf_printf(&value, "%s", argv[i]);
4170                 first = false;
4171             }
4172         }
4173         if (good)
4174         {
4175             setenv_str(es, BSTR(&name), BSTR(&value));
4176         }
4177         else
4178         {
4179             msg(M_WARN, "foreign_option: name/value overflow");
4180         }
4181         gc_free(&gc);
4182     }
4183 }
4184 
4185 #ifdef _WIN32
4186 /**
4187  * Parses --windows-driver config option
4188  *
4189  * @param str       value of --windows-driver option
4190  * @param msglevel  msglevel to report parsing error
4191  * @return enum windows_driver_type  driver type, WINDOWS_DRIVER_UNSPECIFIED on unknown --windows-driver value
4192  */
4193 static enum windows_driver_type
parse_windows_driver(const char * str,const int msglevel)4194 parse_windows_driver(const char *str, const int msglevel)
4195 {
4196     if (streq(str, "tap-windows6"))
4197     {
4198         return WINDOWS_DRIVER_TAP_WINDOWS6;
4199     }
4200     else if (streq(str, "wintun"))
4201     {
4202         return WINDOWS_DRIVER_WINTUN;
4203     }
4204     else
4205     {
4206         msg(msglevel, "--windows-driver must be tap-windows6 or wintun");
4207         return WINDOWS_DRIVER_UNSPECIFIED;
4208     }
4209 }
4210 #endif
4211 
4212 /*
4213  * parse/print topology coding
4214  */
4215 
4216 int
parse_topology(const char * str,const int msglevel)4217 parse_topology(const char *str, const int msglevel)
4218 {
4219     if (streq(str, "net30"))
4220     {
4221         return TOP_NET30;
4222     }
4223     else if (streq(str, "p2p"))
4224     {
4225         return TOP_P2P;
4226     }
4227     else if (streq(str, "subnet"))
4228     {
4229         return TOP_SUBNET;
4230     }
4231     else
4232     {
4233         msg(msglevel, "--topology must be net30, p2p, or subnet");
4234         return TOP_UNDEF;
4235     }
4236 }
4237 
4238 const char *
print_topology(const int topology)4239 print_topology(const int topology)
4240 {
4241     switch (topology)
4242     {
4243         case TOP_UNDEF:
4244             return "undef";
4245 
4246         case TOP_NET30:
4247             return "net30";
4248 
4249         case TOP_P2P:
4250             return "p2p";
4251 
4252         case TOP_SUBNET:
4253             return "subnet";
4254 
4255         default:
4256             return "unknown";
4257     }
4258 }
4259 
4260 #if P2MP
4261 
4262 /*
4263  * Manage auth-retry variable
4264  */
4265 
4266 static int global_auth_retry; /* GLOBAL */
4267 
4268 int
auth_retry_get(void)4269 auth_retry_get(void)
4270 {
4271     return global_auth_retry;
4272 }
4273 
4274 bool
auth_retry_set(const int msglevel,const char * option)4275 auth_retry_set(const int msglevel, const char *option)
4276 {
4277     if (streq(option, "interact"))
4278     {
4279         global_auth_retry = AR_INTERACT;
4280     }
4281     else if (streq(option, "nointeract"))
4282     {
4283         global_auth_retry = AR_NOINTERACT;
4284     }
4285     else if (streq(option, "none"))
4286     {
4287         global_auth_retry = AR_NONE;
4288     }
4289     else
4290     {
4291         msg(msglevel, "--auth-retry method must be 'interact', 'nointeract', or 'none'");
4292         return false;
4293     }
4294     return true;
4295 }
4296 
4297 const char *
auth_retry_print(void)4298 auth_retry_print(void)
4299 {
4300     switch (global_auth_retry)
4301     {
4302         case AR_NONE:
4303             return "none";
4304 
4305         case AR_NOINTERACT:
4306             return "nointeract";
4307 
4308         case AR_INTERACT:
4309             return "interact";
4310 
4311         default:
4312             return "???";
4313     }
4314 }
4315 
4316 #endif /* if P2MP */
4317 
4318 /*
4319  * Print the help message.
4320  */
4321 static void
usage(void)4322 usage(void)
4323 {
4324     FILE *fp = msg_fp(0);
4325 
4326 #ifdef ENABLE_SMALL
4327 
4328     fprintf(fp, "Usage message not available\n");
4329 
4330 #else
4331 
4332     struct options o;
4333     init_options(&o, true);
4334 
4335     fprintf(fp, usage_message,
4336             title_string,
4337             o.ce.connect_retry_seconds,
4338             o.ce.connect_retry_seconds_max,
4339             o.ce.local_port, o.ce.remote_port,
4340             TUN_MTU_DEFAULT, TAP_MTU_EXTRA_DEFAULT,
4341             o.verbosity,
4342             o.authname, o.ciphername,
4343             o.replay_window, o.replay_time,
4344             o.tls_timeout, o.renegotiate_seconds,
4345             o.handshake_window, o.transition_window);
4346     fflush(fp);
4347 
4348 #endif /* ENABLE_SMALL */
4349 
4350     openvpn_exit(OPENVPN_EXIT_STATUS_USAGE); /* exit point */
4351 }
4352 
4353 void
usage_small(void)4354 usage_small(void)
4355 {
4356     msg(M_WARN|M_NOPREFIX, "Use --help for more information.");
4357     openvpn_exit(OPENVPN_EXIT_STATUS_USAGE); /* exit point */
4358 }
4359 
4360 #ifdef _WIN32
4361 void
show_windows_version(const unsigned int flags)4362 show_windows_version(const unsigned int flags)
4363 {
4364     struct gc_arena gc = gc_new();
4365     msg(flags, "Windows version %s", win32_version_string(&gc, true));
4366     gc_free(&gc);
4367 }
4368 #endif
4369 
4370 void
show_library_versions(const unsigned int flags)4371 show_library_versions(const unsigned int flags)
4372 {
4373 #ifdef ENABLE_LZO
4374 #define LZO_LIB_VER_STR ", LZO ", lzo_version_string()
4375 #else
4376 #define LZO_LIB_VER_STR "", ""
4377 #endif
4378 
4379     msg(flags, "library versions: %s%s%s", get_ssl_library_version(),
4380         LZO_LIB_VER_STR);
4381 
4382 #undef LZO_LIB_VER_STR
4383 }
4384 
4385 static void
usage_version(void)4386 usage_version(void)
4387 {
4388     msg(M_INFO|M_NOPREFIX, "%s", title_string);
4389     show_library_versions( M_INFO|M_NOPREFIX );
4390 #ifdef _WIN32
4391     show_windows_version( M_INFO|M_NOPREFIX );
4392 #endif
4393     msg(M_INFO|M_NOPREFIX, "Originally developed by James Yonan");
4394     msg(M_INFO|M_NOPREFIX, "Copyright (C) 2002-2022 OpenVPN Inc <sales@openvpn.net>");
4395 #ifndef ENABLE_SMALL
4396 #ifdef CONFIGURE_DEFINES
4397     msg(M_INFO|M_NOPREFIX, "Compile time defines: %s", CONFIGURE_DEFINES);
4398 #endif
4399 #ifdef CONFIGURE_SPECIAL_BUILD
4400     msg(M_INFO|M_NOPREFIX, "special build: %s", CONFIGURE_SPECIAL_BUILD);
4401 #endif
4402 #endif
4403     openvpn_exit(OPENVPN_EXIT_STATUS_GOOD);
4404 }
4405 
4406 void
notnull(const char * arg,const char * description)4407 notnull(const char *arg, const char *description)
4408 {
4409     if (!arg)
4410     {
4411         msg(M_USAGE, "You must define %s", description);
4412     }
4413 }
4414 
4415 bool
string_defined_equal(const char * s1,const char * s2)4416 string_defined_equal(const char *s1, const char *s2)
4417 {
4418     if (s1 && s2)
4419     {
4420         return !strcmp(s1, s2);
4421     }
4422     else
4423     {
4424         return false;
4425     }
4426 }
4427 
4428 #if 0
4429 static void
4430 ping_rec_err(int msglevel)
4431 {
4432     msg(msglevel, "only one of --ping-exit or --ping-restart options may be specified");
4433 }
4434 #endif
4435 
4436 static int
positive_atoi(const char * str)4437 positive_atoi(const char *str)
4438 {
4439     const int i = atoi(str);
4440     return i < 0 ? 0 : i;
4441 }
4442 
4443 #ifdef _WIN32  /* This function is only used when compiling on Windows */
4444 static unsigned int
atou(const char * str)4445 atou(const char *str)
4446 {
4447     unsigned int val = 0;
4448     sscanf(str, "%u", &val);
4449     return val;
4450 }
4451 #endif
4452 
4453 static inline bool
space(unsigned char c)4454 space(unsigned char c)
4455 {
4456     return c == '\0' || isspace(c);
4457 }
4458 
4459 int
parse_line(const char * line,char * p[],const int n,const char * file,const int line_num,int msglevel,struct gc_arena * gc)4460 parse_line(const char *line,
4461            char *p[],
4462            const int n,
4463            const char *file,
4464            const int line_num,
4465            int msglevel,
4466            struct gc_arena *gc)
4467 {
4468     const int STATE_INITIAL = 0;
4469     const int STATE_READING_QUOTED_PARM = 1;
4470     const int STATE_READING_UNQUOTED_PARM = 2;
4471     const int STATE_DONE = 3;
4472     const int STATE_READING_SQUOTED_PARM = 4;
4473 
4474     const char *error_prefix = "";
4475 
4476     int ret = 0;
4477     const char *c = line;
4478     int state = STATE_INITIAL;
4479     bool backslash = false;
4480     char in, out;
4481 
4482     char parm[OPTION_PARM_SIZE];
4483     unsigned int parm_len = 0;
4484 
4485     msglevel &= ~M_OPTERR;
4486 
4487     if (msglevel & M_MSG_VIRT_OUT)
4488     {
4489         error_prefix = "ERROR: ";
4490     }
4491 
4492     do
4493     {
4494         in = *c;
4495         out = 0;
4496 
4497         if (!backslash && in == '\\' && state != STATE_READING_SQUOTED_PARM)
4498         {
4499             backslash = true;
4500         }
4501         else
4502         {
4503             if (state == STATE_INITIAL)
4504             {
4505                 if (!space(in))
4506                 {
4507                     if (in == ';' || in == '#') /* comment */
4508                     {
4509                         break;
4510                     }
4511                     if (!backslash && in == '\"')
4512                     {
4513                         state = STATE_READING_QUOTED_PARM;
4514                     }
4515                     else if (!backslash && in == '\'')
4516                     {
4517                         state = STATE_READING_SQUOTED_PARM;
4518                     }
4519                     else
4520                     {
4521                         out = in;
4522                         state = STATE_READING_UNQUOTED_PARM;
4523                     }
4524                 }
4525             }
4526             else if (state == STATE_READING_UNQUOTED_PARM)
4527             {
4528                 if (!backslash && space(in))
4529                 {
4530                     state = STATE_DONE;
4531                 }
4532                 else
4533                 {
4534                     out = in;
4535                 }
4536             }
4537             else if (state == STATE_READING_QUOTED_PARM)
4538             {
4539                 if (!backslash && in == '\"')
4540                 {
4541                     state = STATE_DONE;
4542                 }
4543                 else
4544                 {
4545                     out = in;
4546                 }
4547             }
4548             else if (state == STATE_READING_SQUOTED_PARM)
4549             {
4550                 if (in == '\'')
4551                 {
4552                     state = STATE_DONE;
4553                 }
4554                 else
4555                 {
4556                     out = in;
4557                 }
4558             }
4559             if (state == STATE_DONE)
4560             {
4561                 /* ASSERT (parm_len > 0); */
4562                 p[ret] = gc_malloc(parm_len + 1, true, gc);
4563                 memcpy(p[ret], parm, parm_len);
4564                 p[ret][parm_len] = '\0';
4565                 state = STATE_INITIAL;
4566                 parm_len = 0;
4567                 ++ret;
4568             }
4569 
4570             if (backslash && out)
4571             {
4572                 if (!(out == '\\' || out == '\"' || space(out)))
4573                 {
4574 #ifdef ENABLE_SMALL
4575                     msg(msglevel, "%sOptions warning: Bad backslash ('\\') usage in %s:%d", error_prefix, file, line_num);
4576 #else
4577                     msg(msglevel, "%sOptions warning: Bad backslash ('\\') usage in %s:%d: remember that backslashes are treated as shell-escapes and if you need to pass backslash characters as part of a Windows filename, you should use double backslashes such as \"c:\\\\" PACKAGE "\\\\static.key\"", error_prefix, file, line_num);
4578 #endif
4579                     return 0;
4580                 }
4581             }
4582             backslash = false;
4583         }
4584 
4585         /* store parameter character */
4586         if (out)
4587         {
4588             if (parm_len >= SIZE(parm))
4589             {
4590                 parm[SIZE(parm) - 1] = 0;
4591                 msg(msglevel, "%sOptions error: Parameter at %s:%d is too long (%d chars max): %s",
4592                     error_prefix, file, line_num, (int) SIZE(parm), parm);
4593                 return 0;
4594             }
4595             parm[parm_len++] = out;
4596         }
4597 
4598         /* avoid overflow if too many parms in one config file line */
4599         if (ret >= n)
4600         {
4601             break;
4602         }
4603 
4604     } while (*c++ != '\0');
4605 
4606     if (state == STATE_READING_QUOTED_PARM)
4607     {
4608         msg(msglevel, "%sOptions error: No closing quotation (\") in %s:%d", error_prefix, file, line_num);
4609         return 0;
4610     }
4611     if (state == STATE_READING_SQUOTED_PARM)
4612     {
4613         msg(msglevel, "%sOptions error: No closing single quotation (\') in %s:%d", error_prefix, file, line_num);
4614         return 0;
4615     }
4616     if (state != STATE_INITIAL)
4617     {
4618         msg(msglevel, "%sOptions error: Residual parse state (%d) in %s:%d", error_prefix, state, file, line_num);
4619         return 0;
4620     }
4621 #if 0
4622     {
4623         int i;
4624         for (i = 0; i < ret; ++i)
4625         {
4626             msg(M_INFO|M_NOPREFIX, "%s:%d ARG[%d] '%s'", file, line_num, i, p[i]);
4627         }
4628     }
4629 #endif
4630     return ret;
4631 }
4632 
4633 static void
bypass_doubledash(char ** p)4634 bypass_doubledash(char **p)
4635 {
4636     if (strlen(*p) >= 3 && !strncmp(*p, "--", 2))
4637     {
4638         *p += 2;
4639     }
4640 }
4641 
4642 struct in_src {
4643 #define IS_TYPE_FP 1
4644 #define IS_TYPE_BUF 2
4645     int type;
4646     union {
4647         FILE *fp;
4648         struct buffer *multiline;
4649     } u;
4650 };
4651 
4652 static bool
in_src_get(const struct in_src * is,char * line,const int size)4653 in_src_get(const struct in_src *is, char *line, const int size)
4654 {
4655     if (is->type == IS_TYPE_FP)
4656     {
4657         return BOOL_CAST(fgets(line, size, is->u.fp));
4658     }
4659     else if (is->type == IS_TYPE_BUF)
4660     {
4661         bool status = buf_parse(is->u.multiline, '\n', line, size);
4662         if ((int) strlen(line) + 1 < size)
4663         {
4664             strcat(line, "\n");
4665         }
4666         return status;
4667     }
4668     else
4669     {
4670         ASSERT(0);
4671         return false;
4672     }
4673 }
4674 
4675 static char *
read_inline_file(struct in_src * is,const char * close_tag,int * num_lines,struct gc_arena * gc)4676 read_inline_file(struct in_src *is, const char *close_tag,
4677                  int *num_lines, struct gc_arena *gc)
4678 {
4679     char line[OPTION_LINE_SIZE];
4680     struct buffer buf = alloc_buf(8*OPTION_LINE_SIZE);
4681     char *ret;
4682     bool endtagfound = false;
4683 
4684     while (in_src_get(is, line, sizeof(line)))
4685     {
4686         (*num_lines)++;
4687         char *line_ptr = line;
4688         /* Remove leading spaces */
4689         while (isspace(*line_ptr))
4690         {
4691             line_ptr++;
4692         }
4693         if (!strncmp(line_ptr, close_tag, strlen(close_tag)))
4694         {
4695             endtagfound = true;
4696             break;
4697         }
4698         if (!buf_safe(&buf, strlen(line)+1))
4699         {
4700             /* Increase buffer size */
4701             struct buffer buf2 = alloc_buf(buf.capacity * 2);
4702             ASSERT(buf_copy(&buf2, &buf));
4703             buf_clear(&buf);
4704             free_buf(&buf);
4705             buf = buf2;
4706         }
4707         buf_printf(&buf, "%s", line);
4708     }
4709     if (!endtagfound)
4710     {
4711         msg(M_FATAL, "ERROR: Endtag %s missing", close_tag);
4712     }
4713     ret = string_alloc(BSTR(&buf), gc);
4714     buf_clear(&buf);
4715     free_buf(&buf);
4716     secure_memzero(line, sizeof(line));
4717     return ret;
4718 }
4719 
4720 static int
check_inline_file(struct in_src * is,char * p[],struct gc_arena * gc)4721 check_inline_file(struct in_src *is, char *p[], struct gc_arena *gc)
4722 {
4723     int num_inline_lines = 0;
4724 
4725     if (p[0] && !p[1])
4726     {
4727         char *arg = p[0];
4728         if (arg[0] == '<' && arg[strlen(arg)-1] == '>')
4729         {
4730             struct buffer close_tag;
4731 
4732             arg[strlen(arg) - 1] = '\0';
4733             p[0] = string_alloc(arg + 1, gc);
4734             close_tag = alloc_buf(strlen(p[0]) + 4);
4735             buf_printf(&close_tag, "</%s>", p[0]);
4736             p[1] = read_inline_file(is, BSTR(&close_tag), &num_inline_lines, gc);
4737             p[2] = NULL;
4738             free_buf(&close_tag);
4739         }
4740     }
4741     return num_inline_lines;
4742 }
4743 
4744 static int
check_inline_file_via_fp(FILE * fp,char * p[],struct gc_arena * gc)4745 check_inline_file_via_fp(FILE *fp, char *p[], struct gc_arena *gc)
4746 {
4747     struct in_src is;
4748     is.type = IS_TYPE_FP;
4749     is.u.fp = fp;
4750     return check_inline_file(&is, p, gc);
4751 }
4752 
4753 static int
check_inline_file_via_buf(struct buffer * multiline,char * p[],struct gc_arena * gc)4754 check_inline_file_via_buf(struct buffer *multiline, char *p[],
4755                           struct gc_arena *gc)
4756 {
4757     struct in_src is;
4758     is.type = IS_TYPE_BUF;
4759     is.u.multiline = multiline;
4760     return check_inline_file(&is, p, gc);
4761 }
4762 
4763 static void
4764 add_option(struct options *options,
4765            char *p[],
4766            bool is_inline,
4767            const char *file,
4768            int line,
4769            const int level,
4770            const int msglevel,
4771            const unsigned int permission_mask,
4772            unsigned int *option_types_found,
4773            struct env_set *es);
4774 
4775 static void
read_config_file(struct options * options,const char * file,int level,const char * top_file,const int top_line,const int msglevel,const unsigned int permission_mask,unsigned int * option_types_found,struct env_set * es)4776 read_config_file(struct options *options,
4777                  const char *file,
4778                  int level,
4779                  const char *top_file,
4780                  const int top_line,
4781                  const int msglevel,
4782                  const unsigned int permission_mask,
4783                  unsigned int *option_types_found,
4784                  struct env_set *es)
4785 {
4786     const int max_recursive_levels = 10;
4787     FILE *fp;
4788     int line_num;
4789     char line[OPTION_LINE_SIZE+1];
4790     char *p[MAX_PARMS+1];
4791 
4792     ++level;
4793     if (level <= max_recursive_levels)
4794     {
4795         if (streq(file, "stdin"))
4796         {
4797             fp = stdin;
4798         }
4799         else
4800         {
4801             fp = platform_fopen(file, "r");
4802         }
4803         if (fp)
4804         {
4805             line_num = 0;
4806             while (fgets(line, sizeof(line), fp))
4807             {
4808                 int offset = 0;
4809                 CLEAR(p);
4810                 ++line_num;
4811                 if (strlen(line) == OPTION_LINE_SIZE)
4812                 {
4813                     msg(msglevel, "In %s:%d: Maximum option line length (%d) exceeded, line starts with %s",
4814                         file, line_num, OPTION_LINE_SIZE, line);
4815                 }
4816 
4817                 /* Ignore UTF-8 BOM at start of stream */
4818                 if (line_num == 1 && strncmp(line, "\xEF\xBB\xBF", 3) == 0)
4819                 {
4820                     offset = 3;
4821                 }
4822                 if (parse_line(line + offset, p, SIZE(p)-1, file, line_num, msglevel, &options->gc))
4823                 {
4824                     bypass_doubledash(&p[0]);
4825                     int lines_inline = check_inline_file_via_fp(fp, p, &options->gc);
4826                     add_option(options, p, lines_inline, file, line_num, level,
4827                                msglevel, permission_mask, option_types_found,
4828                                es);
4829                     line_num += lines_inline;
4830                 }
4831             }
4832             if (fp != stdin)
4833             {
4834                 fclose(fp);
4835             }
4836         }
4837         else
4838         {
4839             msg(msglevel, "In %s:%d: Error opening configuration file: %s", top_file, top_line, file);
4840         }
4841     }
4842     else
4843     {
4844         msg(msglevel, "In %s:%d: Maximum recursive include levels exceeded in include attempt of file %s -- probably you have a configuration file that tries to include itself.", top_file, top_line, file);
4845     }
4846     secure_memzero(line, sizeof(line));
4847     CLEAR(p);
4848 }
4849 
4850 static void
read_config_string(const char * prefix,struct options * options,const char * config,const int msglevel,const unsigned int permission_mask,unsigned int * option_types_found,struct env_set * es)4851 read_config_string(const char *prefix,
4852                    struct options *options,
4853                    const char *config,
4854                    const int msglevel,
4855                    const unsigned int permission_mask,
4856                    unsigned int *option_types_found,
4857                    struct env_set *es)
4858 {
4859     char line[OPTION_LINE_SIZE];
4860     struct buffer multiline;
4861     int line_num = 0;
4862 
4863     buf_set_read(&multiline, (uint8_t *)config, strlen(config));
4864 
4865     while (buf_parse(&multiline, '\n', line, sizeof(line)))
4866     {
4867         char *p[MAX_PARMS+1];
4868         CLEAR(p);
4869         ++line_num;
4870         if (parse_line(line, p, SIZE(p)-1, prefix, line_num, msglevel, &options->gc))
4871         {
4872             bypass_doubledash(&p[0]);
4873             int lines_inline = check_inline_file_via_buf(&multiline, p, &options->gc);
4874             add_option(options, p, lines_inline, prefix, line_num, 0, msglevel,
4875                        permission_mask, option_types_found, es);
4876             line_num += lines_inline;
4877         }
4878         CLEAR(p);
4879     }
4880     secure_memzero(line, sizeof(line));
4881 }
4882 
4883 void
parse_argv(struct options * options,const int argc,char * argv[],const int msglevel,const unsigned int permission_mask,unsigned int * option_types_found,struct env_set * es)4884 parse_argv(struct options *options,
4885            const int argc,
4886            char *argv[],
4887            const int msglevel,
4888            const unsigned int permission_mask,
4889            unsigned int *option_types_found,
4890            struct env_set *es)
4891 {
4892     int i, j;
4893 
4894     /* usage message */
4895     if (argc <= 1)
4896     {
4897         usage();
4898     }
4899 
4900     /* config filename specified only? */
4901     if (argc == 2 && strncmp(argv[1], "--", 2))
4902     {
4903         char *p[MAX_PARMS];
4904         CLEAR(p);
4905         p[0] = "config";
4906         p[1] = argv[1];
4907         add_option(options, p, false, NULL, 0, 0, msglevel, permission_mask,
4908                    option_types_found, es);
4909     }
4910     else
4911     {
4912         /* parse command line */
4913         for (i = 1; i < argc; ++i)
4914         {
4915             char *p[MAX_PARMS];
4916             CLEAR(p);
4917             p[0] = argv[i];
4918             if (strncmp(p[0], "--", 2))
4919             {
4920                 msg(msglevel, "I'm trying to parse \"%s\" as an --option parameter but I don't see a leading '--'", p[0]);
4921             }
4922             else
4923             {
4924                 p[0] += 2;
4925             }
4926 
4927             for (j = 1; j < MAX_PARMS; ++j)
4928             {
4929                 if (i + j < argc)
4930                 {
4931                     char *arg = argv[i + j];
4932                     if (strncmp(arg, "--", 2))
4933                     {
4934                         p[j] = arg;
4935                     }
4936                     else
4937                     {
4938                         break;
4939                     }
4940                 }
4941             }
4942             add_option(options, p, false, NULL, 0, 0, msglevel, permission_mask,
4943                        option_types_found, es);
4944             i += j - 1;
4945         }
4946     }
4947 }
4948 
4949 /**
4950  * Filter an option line by all pull filters.
4951  *
4952  * If a match is found, the line is modified depending on
4953  * the filter type, and returns true. If the filter type is
4954  * reject, SIGUSR1 is triggered and the return value is false.
4955  * In that case the caller must end the push processing.
4956  */
4957 static bool
apply_pull_filter(const struct options * o,char * line)4958 apply_pull_filter(const struct options *o, char *line)
4959 {
4960     struct pull_filter *f;
4961 
4962     if (!o->pull_filter_list)
4963     {
4964         return true;
4965     }
4966 
4967     for (f = o->pull_filter_list->head; f; f = f->next)
4968     {
4969         if (f->type == PUF_TYPE_ACCEPT && strncmp(line, f->pattern, f->size) == 0)
4970         {
4971             msg(D_LOW, "Pushed option accepted by filter: '%s'", line);
4972             return true;
4973         }
4974         else if (f->type == PUF_TYPE_IGNORE && strncmp(line, f->pattern, f->size) == 0)
4975         {
4976             msg(D_PUSH, "Pushed option removed by filter: '%s'", line);
4977             *line = '\0';
4978             return true;
4979         }
4980         else if (f->type == PUF_TYPE_REJECT && strncmp(line, f->pattern, f->size) == 0)
4981         {
4982             msg(M_WARN, "Pushed option rejected by filter: '%s'. Restarting.", line);
4983             *line = '\0';
4984             throw_signal_soft(SIGUSR1, "Offending option received from server");
4985             return false;
4986         }
4987     }
4988     return true;
4989 }
4990 
4991 bool
apply_push_options(struct options * options,struct buffer * buf,unsigned int permission_mask,unsigned int * option_types_found,struct env_set * es)4992 apply_push_options(struct options *options,
4993                    struct buffer *buf,
4994                    unsigned int permission_mask,
4995                    unsigned int *option_types_found,
4996                    struct env_set *es)
4997 {
4998     char line[OPTION_PARM_SIZE];
4999     int line_num = 0;
5000     const char *file = "[PUSH-OPTIONS]";
5001     const int msglevel = D_PUSH_ERRORS|M_OPTERR;
5002 
5003     while (buf_parse(buf, ',', line, sizeof(line)))
5004     {
5005         char *p[MAX_PARMS+1];
5006         CLEAR(p);
5007         ++line_num;
5008         if (!apply_pull_filter(options, line))
5009         {
5010             return false; /* Cause push/pull error and stop push processing */
5011         }
5012         if (parse_line(line, p, SIZE(p)-1, file, line_num, msglevel, &options->gc))
5013         {
5014             add_option(options, p, false, file, line_num, 0, msglevel,
5015                        permission_mask, option_types_found, es);
5016         }
5017     }
5018     return true;
5019 }
5020 
5021 void
options_server_import(struct options * o,const char * filename,int msglevel,unsigned int permission_mask,unsigned int * option_types_found,struct env_set * es)5022 options_server_import(struct options *o,
5023                       const char *filename,
5024                       int msglevel,
5025                       unsigned int permission_mask,
5026                       unsigned int *option_types_found,
5027                       struct env_set *es)
5028 {
5029     msg(D_PUSH, "OPTIONS IMPORT: reading client specific options from: %s", filename);
5030     read_config_file(o,
5031                      filename,
5032                      0,
5033                      filename,
5034                      0,
5035                      msglevel,
5036                      permission_mask,
5037                      option_types_found,
5038                      es);
5039 }
5040 
5041 void
options_string_import(struct options * options,const char * config,const int msglevel,const unsigned int permission_mask,unsigned int * option_types_found,struct env_set * es)5042 options_string_import(struct options *options,
5043                       const char *config,
5044                       const int msglevel,
5045                       const unsigned int permission_mask,
5046                       unsigned int *option_types_found,
5047                       struct env_set *es)
5048 {
5049     read_config_string("[CONFIG-STRING]", options, config, msglevel, permission_mask, option_types_found, es);
5050 }
5051 
5052 #if P2MP
5053 
5054 #define VERIFY_PERMISSION(mask) {                                            \
5055         if (!verify_permission(p[0], file, line, (mask), permission_mask,        \
5056                                option_types_found, msglevel, options, is_inline)) \
5057         {                                                                        \
5058             goto err;                                                            \
5059         }                                                                        \
5060 }
5061 
5062 static bool
verify_permission(const char * name,const char * file,int line,const unsigned int type,const unsigned int allowed,unsigned int * found,const int msglevel,struct options * options,bool is_inline)5063 verify_permission(const char *name,
5064                   const char *file,
5065                   int line,
5066                   const unsigned int type,
5067                   const unsigned int allowed,
5068                   unsigned int *found,
5069                   const int msglevel,
5070                   struct options *options,
5071                   bool is_inline)
5072 {
5073     if (!(type & allowed))
5074     {
5075         msg(msglevel, "option '%s' cannot be used in this context (%s)", name, file);
5076         return false;
5077     }
5078 
5079     if (is_inline && !(type & OPT_P_INLINE))
5080     {
5081         msg(msglevel, "option '%s' is not expected to be inline (%s:%d)", name,
5082             file, line);
5083         return false;
5084     }
5085 
5086     if (found)
5087     {
5088         *found |= type;
5089     }
5090 
5091 #ifndef ENABLE_SMALL
5092     /* Check if this options is allowed in connection block,
5093      * but we are currently not in a connection block
5094      * unless this is a pushed option.
5095      * Parsing a connection block uses a temporary options struct without
5096      * connection_list
5097      */
5098 
5099     if ((type & OPT_P_CONNECTION) && options->connection_list
5100         && !(allowed & OPT_P_PULL_MODE))
5101     {
5102         if (file)
5103         {
5104             msg(M_WARN, "Option '%s' in %s:%d is ignored by previous <connection> blocks ", name, file, line);
5105         }
5106         else
5107         {
5108             msg(M_WARN, "Option '%s' is ignored by previous <connection> blocks", name);
5109         }
5110     }
5111 #endif
5112     return true;
5113 }
5114 
5115 #else  /* if P2MP */
5116 
5117 #define VERIFY_PERMISSION(mask)
5118 
5119 #endif /* if P2MP */
5120 
5121 /*
5122  * Check that an option doesn't have too
5123  * many parameters.
5124  */
5125 
5126 #define NM_QUOTE_HINT (1<<0)
5127 
5128 static bool
no_more_than_n_args(const int msglevel,char * p[],const int max,const unsigned int flags)5129 no_more_than_n_args(const int msglevel,
5130                     char *p[],
5131                     const int max,
5132                     const unsigned int flags)
5133 {
5134     const int len = string_array_len((const char **)p);
5135 
5136     if (!len)
5137     {
5138         return false;
5139     }
5140 
5141     if (len > max)
5142     {
5143         msg(msglevel, "the --%s directive should have at most %d parameter%s.%s",
5144             p[0],
5145             max - 1,
5146             max >= 3 ? "s" : "",
5147             (flags & NM_QUOTE_HINT) ? "  To pass a list of arguments as one of the parameters, try enclosing them in double quotes (\"\")." : "");
5148         return false;
5149     }
5150     else
5151     {
5152         return true;
5153     }
5154 }
5155 
5156 static inline int
msglevel_forward_compatible(struct options * options,const int msglevel)5157 msglevel_forward_compatible(struct options *options, const int msglevel)
5158 {
5159     return options->forward_compatible ? M_WARN : msglevel;
5160 }
5161 
5162 static void
set_user_script(struct options * options,const char ** script,const char * new_script,const char * type,bool in_chroot)5163 set_user_script(struct options *options,
5164                 const char **script,
5165                 const char *new_script,
5166                 const char *type,
5167                 bool in_chroot)
5168 {
5169     if (*script)
5170     {
5171         msg(M_WARN, "Multiple --%s scripts defined.  "
5172             "The previously configured script is overridden.", type);
5173     }
5174     *script = new_script;
5175     options->user_script_used = true;
5176 
5177 #ifndef ENABLE_SMALL
5178     {
5179         char script_name[100];
5180         openvpn_snprintf(script_name, sizeof(script_name),
5181                          "--%s script", type);
5182 
5183         if (check_cmd_access(*script, script_name, (in_chroot ? options->chroot_dir : NULL)))
5184         {
5185             msg(M_USAGE, "Please correct this error.");
5186         }
5187 
5188     }
5189 #endif
5190 }
5191 
5192 #ifdef USE_COMP
5193 static void
show_compression_warning(struct compress_options * info)5194 show_compression_warning(struct compress_options *info)
5195 {
5196     if (comp_non_stub_enabled(info))
5197     {
5198         /*
5199          * Check if already displayed the strong warning and enabled full
5200          * compression
5201          */
5202         if (!(info->flags & COMP_F_ALLOW_COMPRESS))
5203         {
5204             msg(M_WARN, "WARNING: Compression for receiving enabled. "
5205                 "Compression has been used in the past to break encryption. "
5206                 "Sent packets are not compressed unless \"allow-compression yes\" "
5207                 "is also set.");
5208         }
5209     }
5210 }
5211 #endif
5212 
5213 static void
add_option(struct options * options,char * p[],bool is_inline,const char * file,int line,const int level,const int msglevel,const unsigned int permission_mask,unsigned int * option_types_found,struct env_set * es)5214 add_option(struct options *options,
5215            char *p[],
5216            bool is_inline,
5217            const char *file,
5218            int line,
5219            const int level,
5220            const int msglevel,
5221            const unsigned int permission_mask,
5222            unsigned int *option_types_found,
5223            struct env_set *es)
5224 {
5225     struct gc_arena gc = gc_new();
5226     const bool pull_mode = BOOL_CAST(permission_mask & OPT_P_PULL_MODE);
5227     int msglevel_fc = msglevel_forward_compatible(options, msglevel);
5228 
5229     ASSERT(MAX_PARMS >= 7);
5230 
5231     /*
5232      * If directive begins with "setenv opt" prefix, don't raise an error if
5233      * directive is unrecognized.
5234      */
5235     if (streq(p[0], "setenv") && p[1] && streq(p[1], "opt") && !(permission_mask & OPT_P_PULL_MODE))
5236     {
5237         if (!p[2])
5238         {
5239             p[2] = "setenv opt"; /* will trigger an error that includes setenv opt */
5240         }
5241         p += 2;
5242         msglevel_fc = M_WARN;
5243     }
5244 
5245     if (!file)
5246     {
5247         file = "[CMD-LINE]";
5248         line = 1;
5249     }
5250     if (streq(p[0], "help"))
5251     {
5252         VERIFY_PERMISSION(OPT_P_GENERAL);
5253         usage();
5254         if (p[1])
5255         {
5256             msg(msglevel, "--help does not accept any parameters");
5257             goto err;
5258         }
5259     }
5260     if (streq(p[0], "version") && !p[1])
5261     {
5262         VERIFY_PERMISSION(OPT_P_GENERAL);
5263         usage_version();
5264     }
5265     else if (streq(p[0], "config") && p[1] && !p[2])
5266     {
5267         VERIFY_PERMISSION(OPT_P_CONFIG);
5268 
5269         /* save first config file only in options */
5270         if (!options->config)
5271         {
5272             options->config = p[1];
5273         }
5274 
5275         read_config_file(options, p[1], level, file, line, msglevel, permission_mask, option_types_found, es);
5276     }
5277 #if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
5278     else if (streq(p[0], "show-gateway") && !p[2])
5279     {
5280         struct route_gateway_info rgi;
5281         struct route_ipv6_gateway_info rgi6;
5282         struct in6_addr remote = IN6ADDR_ANY_INIT;
5283         openvpn_net_ctx_t net_ctx;
5284         VERIFY_PERMISSION(OPT_P_GENERAL);
5285         if (p[1])
5286         {
5287             get_ipv6_addr(p[1], &remote, NULL, M_WARN);
5288         }
5289         net_ctx_init(NULL, &net_ctx);
5290         get_default_gateway(&rgi, &net_ctx);
5291         get_default_gateway_ipv6(&rgi6, &remote, &net_ctx);
5292         print_default_gateway(M_INFO, &rgi, &rgi6);
5293         openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
5294     }
5295 #endif
5296 #if 0
5297     else if (streq(p[0], "foreign-option") && p[1])
5298     {
5299         VERIFY_PERMISSION(OPT_P_IPWIN32);
5300         foreign_option(options, p, 3, es);
5301     }
5302 #endif
5303     else if (streq(p[0], "echo") || streq(p[0], "parameter"))
5304     {
5305         struct buffer string = alloc_buf_gc(OPTION_PARM_SIZE, &gc);
5306         int j;
5307         bool good = true;
5308 
5309         VERIFY_PERMISSION(OPT_P_ECHO);
5310 
5311         for (j = 1; j < MAX_PARMS; ++j)
5312         {
5313             if (!p[j])
5314             {
5315                 break;
5316             }
5317             if (j > 1)
5318             {
5319                 good &= buf_printf(&string, " ");
5320             }
5321             good &= buf_printf(&string, "%s", p[j]);
5322         }
5323         if (good)
5324         {
5325             /* only message-related ECHO are logged, since other ECHOs
5326              * can potentially include security-sensitive strings */
5327             if (p[1] && strncmp(p[1], "msg", 3) == 0)
5328             {
5329                 msg(M_INFO, "%s:%s",
5330                     pull_mode ? "ECHO-PULL" : "ECHO",
5331                     BSTR(&string));
5332             }
5333 #ifdef ENABLE_MANAGEMENT
5334             if (management)
5335             {
5336                 management_echo(management, BSTR(&string), pull_mode);
5337             }
5338 #endif
5339         }
5340         else
5341         {
5342             msg(M_WARN, "echo/parameter option overflow");
5343         }
5344     }
5345 #ifdef ENABLE_MANAGEMENT
5346     else if (streq(p[0], "management") && p[1] && p[2] && !p[4])
5347     {
5348         VERIFY_PERMISSION(OPT_P_GENERAL);
5349         if (streq(p[2], "unix"))
5350         {
5351 #if UNIX_SOCK_SUPPORT
5352             options->management_flags |= MF_UNIX_SOCK;
5353 #else
5354             msg(msglevel, "MANAGEMENT: this platform does not support unix domain sockets");
5355             goto err;
5356 #endif
5357         }
5358 
5359         options->management_addr = p[1];
5360         options->management_port = p[2];
5361         if (p[3])
5362         {
5363             options->management_user_pass = p[3];
5364         }
5365     }
5366     else if (streq(p[0], "management-client-user") && p[1] && !p[2])
5367     {
5368         VERIFY_PERMISSION(OPT_P_GENERAL);
5369         options->management_client_user = p[1];
5370     }
5371     else if (streq(p[0], "management-client-group") && p[1] && !p[2])
5372     {
5373         VERIFY_PERMISSION(OPT_P_GENERAL);
5374         options->management_client_group = p[1];
5375     }
5376     else if (streq(p[0], "management-query-passwords") && !p[1])
5377     {
5378         VERIFY_PERMISSION(OPT_P_GENERAL);
5379         options->management_flags |= MF_QUERY_PASSWORDS;
5380     }
5381     else if (streq(p[0], "management-query-remote") && !p[1])
5382     {
5383         VERIFY_PERMISSION(OPT_P_GENERAL);
5384         options->management_flags |= MF_QUERY_REMOTE;
5385     }
5386     else if (streq(p[0], "management-query-proxy") && !p[1])
5387     {
5388         VERIFY_PERMISSION(OPT_P_GENERAL);
5389         options->management_flags |= MF_QUERY_PROXY;
5390     }
5391     else if (streq(p[0], "management-hold") && !p[1])
5392     {
5393         VERIFY_PERMISSION(OPT_P_GENERAL);
5394         options->management_flags |= MF_HOLD;
5395     }
5396     else if (streq(p[0], "management-signal") && !p[1])
5397     {
5398         VERIFY_PERMISSION(OPT_P_GENERAL);
5399         options->management_flags |= MF_SIGNAL;
5400     }
5401     else if (streq(p[0], "management-forget-disconnect") && !p[1])
5402     {
5403         VERIFY_PERMISSION(OPT_P_GENERAL);
5404         options->management_flags |= MF_FORGET_DISCONNECT;
5405     }
5406     else if (streq(p[0], "management-up-down") && !p[1])
5407     {
5408         VERIFY_PERMISSION(OPT_P_GENERAL);
5409         options->management_flags |= MF_UP_DOWN;
5410     }
5411     else if (streq(p[0], "management-client") && !p[2])
5412     {
5413         VERIFY_PERMISSION(OPT_P_GENERAL);
5414         options->management_flags |= MF_CONNECT_AS_CLIENT;
5415         options->management_write_peer_info_file = p[1];
5416     }
5417 #ifdef ENABLE_MANAGEMENT
5418     else if (streq(p[0], "management-external-key"))
5419     {
5420         VERIFY_PERMISSION(OPT_P_GENERAL);
5421         for (int j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
5422         {
5423             if (streq(p[j], "nopadding"))
5424             {
5425                 options->management_flags |= MF_EXTERNAL_KEY_NOPADDING;
5426             }
5427             else if (streq(p[j], "pkcs1"))
5428             {
5429                 options->management_flags |= MF_EXTERNAL_KEY_PKCS1PAD;
5430             }
5431             else
5432             {
5433                 msg(msglevel, "Unknown management-external-key flag: %s", p[j]);
5434             }
5435         }
5436         /*
5437          * When no option is present, assume that only PKCS1
5438          * padding is supported
5439          */
5440         if (!(options->management_flags
5441               &(MF_EXTERNAL_KEY_NOPADDING | MF_EXTERNAL_KEY_PKCS1PAD)))
5442         {
5443             options->management_flags |= MF_EXTERNAL_KEY_PKCS1PAD;
5444         }
5445         options->management_flags |= MF_EXTERNAL_KEY;
5446     }
5447     else if (streq(p[0], "management-external-cert") && p[1] && !p[2])
5448     {
5449         VERIFY_PERMISSION(OPT_P_GENERAL);
5450         options->management_flags |= MF_EXTERNAL_CERT;
5451         options->management_certificate = p[1];
5452     }
5453 #endif /* ifdef ENABLE_MANAGEMENT */
5454 #ifdef MANAGEMENT_DEF_AUTH
5455     else if (streq(p[0], "management-client-auth") && !p[1])
5456     {
5457         VERIFY_PERMISSION(OPT_P_GENERAL);
5458         options->management_flags |= MF_CLIENT_AUTH;
5459     }
5460 #endif
5461 #ifdef MANAGEMENT_PF
5462     else if (streq(p[0], "management-client-pf") && !p[1])
5463     {
5464         VERIFY_PERMISSION(OPT_P_GENERAL);
5465         options->management_flags |= (MF_CLIENT_PF | MF_CLIENT_AUTH);
5466     }
5467 #endif
5468     else if (streq(p[0], "management-log-cache") && p[1] && !p[2])
5469     {
5470         int cache;
5471 
5472         VERIFY_PERMISSION(OPT_P_GENERAL);
5473         cache = atoi(p[1]);
5474         if (cache < 1)
5475         {
5476             msg(msglevel, "--management-log-cache parameter is out of range");
5477             goto err;
5478         }
5479         options->management_log_history_cache = cache;
5480     }
5481 #endif /* ifdef ENABLE_MANAGEMENT */
5482 #ifdef ENABLE_PLUGIN
5483     else if (streq(p[0], "plugin") && p[1])
5484     {
5485         VERIFY_PERMISSION(OPT_P_PLUGIN);
5486         if (!options->plugin_list)
5487         {
5488             options->plugin_list = plugin_option_list_new(&options->gc);
5489         }
5490         if (!plugin_option_list_add(options->plugin_list, &p[1], &options->gc))
5491         {
5492             msg(msglevel, "plugin add failed: %s", p[1]);
5493             goto err;
5494         }
5495     }
5496 #endif
5497     else if (streq(p[0], "mode") && p[1] && !p[2])
5498     {
5499         VERIFY_PERMISSION(OPT_P_GENERAL);
5500         if (streq(p[1], "p2p"))
5501         {
5502             options->mode = MODE_POINT_TO_POINT;
5503         }
5504         else if (streq(p[1], "server"))
5505         {
5506             options->mode = MODE_SERVER;
5507         }
5508         else
5509         {
5510             msg(msglevel, "Bad --mode parameter: %s", p[1]);
5511             goto err;
5512         }
5513     }
5514     else if (streq(p[0], "dev") && p[1] && !p[2])
5515     {
5516         VERIFY_PERMISSION(OPT_P_GENERAL);
5517         options->dev = p[1];
5518     }
5519     else if (streq(p[0], "dev-type") && p[1] && !p[2])
5520     {
5521         VERIFY_PERMISSION(OPT_P_GENERAL);
5522         options->dev_type = p[1];
5523     }
5524 #ifdef _WIN32
5525     else if (streq(p[0], "windows-driver") && p[1] && !p[2])
5526     {
5527         VERIFY_PERMISSION(OPT_P_GENERAL);
5528         options->windows_driver = parse_windows_driver(p[1], M_FATAL);
5529     }
5530 #endif
5531     else if (streq(p[0], "dev-node") && p[1] && !p[2])
5532     {
5533         VERIFY_PERMISSION(OPT_P_GENERAL);
5534         options->dev_node = p[1];
5535     }
5536     else if (streq(p[0], "lladdr") && p[1] && !p[2])
5537     {
5538         VERIFY_PERMISSION(OPT_P_UP);
5539         if (mac_addr_safe(p[1])) /* MAC address only */
5540         {
5541             options->lladdr = p[1];
5542         }
5543         else
5544         {
5545             msg(msglevel, "lladdr parm '%s' must be a MAC address", p[1]);
5546             goto err;
5547         }
5548     }
5549     else if (streq(p[0], "topology") && p[1] && !p[2])
5550     {
5551         VERIFY_PERMISSION(OPT_P_UP);
5552         options->topology = parse_topology(p[1], msglevel);
5553     }
5554     else if (streq(p[0], "tun-ipv6") && !p[1])
5555     {
5556         if (!pull_mode)
5557         {
5558             msg(M_WARN, "Note: option tun-ipv6 is ignored because modern operating systems do not need special IPv6 tun handling anymore.");
5559         }
5560     }
5561 #ifdef ENABLE_IPROUTE
5562     else if (streq(p[0], "iproute") && p[1] && !p[2])
5563     {
5564         VERIFY_PERMISSION(OPT_P_GENERAL);
5565         iproute_path = p[1];
5566     }
5567 #endif
5568     else if (streq(p[0], "ifconfig") && p[1] && p[2] && !p[3])
5569     {
5570         VERIFY_PERMISSION(OPT_P_UP);
5571         if (ip_or_dns_addr_safe(p[1], options->allow_pull_fqdn) && ip_or_dns_addr_safe(p[2], options->allow_pull_fqdn)) /* FQDN -- may be DNS name */
5572         {
5573             options->ifconfig_local = p[1];
5574             options->ifconfig_remote_netmask = p[2];
5575         }
5576         else
5577         {
5578             msg(msglevel, "ifconfig parms '%s' and '%s' must be valid addresses", p[1], p[2]);
5579             goto err;
5580         }
5581     }
5582     else if (streq(p[0], "ifconfig-ipv6") && p[1] && p[2] && !p[3])
5583     {
5584         unsigned int netbits;
5585 
5586         VERIFY_PERMISSION(OPT_P_UP);
5587         if (get_ipv6_addr( p[1], NULL, &netbits, msglevel )
5588             && ipv6_addr_safe( p[2] ) )
5589         {
5590             if (netbits < 64 || netbits > 124)
5591             {
5592                 msg( msglevel, "ifconfig-ipv6: /netbits must be between 64 and 124, not '/%d'", netbits );
5593                 goto err;
5594             }
5595 
5596             options->ifconfig_ipv6_local = get_ipv6_addr_no_netbits(p[1], &options->gc);
5597             options->ifconfig_ipv6_netbits = netbits;
5598             options->ifconfig_ipv6_remote = p[2];
5599         }
5600         else
5601         {
5602             msg(msglevel, "ifconfig-ipv6 parms '%s' and '%s' must be valid addresses", p[1], p[2]);
5603             goto err;
5604         }
5605     }
5606     else if (streq(p[0], "ifconfig-noexec") && !p[1])
5607     {
5608         VERIFY_PERMISSION(OPT_P_UP);
5609         options->ifconfig_noexec = true;
5610     }
5611     else if (streq(p[0], "ifconfig-nowarn") && !p[1])
5612     {
5613         VERIFY_PERMISSION(OPT_P_UP);
5614         options->ifconfig_nowarn = true;
5615     }
5616     else if (streq(p[0], "local") && p[1] && !p[2])
5617     {
5618         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
5619         options->ce.local = p[1];
5620     }
5621     else if (streq(p[0], "remote-random") && !p[1])
5622     {
5623         VERIFY_PERMISSION(OPT_P_GENERAL);
5624         options->remote_random = true;
5625     }
5626     else if (streq(p[0], "connection") && p[1] && !p[3])
5627     {
5628         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INLINE);
5629         if (is_inline)
5630         {
5631             struct options sub;
5632             struct connection_entry *e;
5633 
5634             init_options(&sub, true);
5635             sub.ce = options->ce;
5636             read_config_string("[CONNECTION-OPTIONS]", &sub, p[1], msglevel,
5637                                OPT_P_CONNECTION, option_types_found, es);
5638             if (!sub.ce.remote)
5639             {
5640                 msg(msglevel, "Each 'connection' block must contain exactly one 'remote' directive");
5641                 uninit_options(&sub);
5642                 goto err;
5643             }
5644 
5645             e = alloc_connection_entry(options, msglevel);
5646             if (!e)
5647             {
5648                 uninit_options(&sub);
5649                 goto err;
5650             }
5651             *e = sub.ce;
5652             gc_transfer(&options->gc, &sub.gc);
5653             uninit_options(&sub);
5654         }
5655     }
5656     else if (streq(p[0], "ignore-unknown-option") && p[1])
5657     {
5658         int i;
5659         int j;
5660         int numignored = 0;
5661         const char **ignore;
5662 
5663         VERIFY_PERMISSION(OPT_P_GENERAL);
5664         /* Find out how many options to be ignored */
5665         for (i = 1; p[i]; i++)
5666         {
5667             numignored++;
5668         }
5669 
5670         /* add number of options already ignored */
5671         for (i = 0; options->ignore_unknown_option
5672              && options->ignore_unknown_option[i]; i++)
5673         {
5674             numignored++;
5675         }
5676 
5677         /* Allocate array */
5678         ALLOC_ARRAY_GC(ignore, const char *, numignored+1, &options->gc);
5679         for (i = 0; options->ignore_unknown_option
5680              && options->ignore_unknown_option[i]; i++)
5681         {
5682             ignore[i] = options->ignore_unknown_option[i];
5683         }
5684 
5685         options->ignore_unknown_option = ignore;
5686 
5687         for (j = 1; p[j]; j++)
5688         {
5689             /* Allow the user to specify ignore-unknown-option --opt too */
5690             if (p[j][0]=='-' && p[j][1]=='-')
5691             {
5692                 options->ignore_unknown_option[i] = (p[j]+2);
5693             }
5694             else
5695             {
5696                 options->ignore_unknown_option[i] = p[j];
5697             }
5698             i++;
5699         }
5700 
5701         options->ignore_unknown_option[i] = NULL;
5702     }
5703 #if ENABLE_MANAGEMENT
5704     else if (streq(p[0], "http-proxy-override") && p[1] && p[2] && !p[4])
5705     {
5706         VERIFY_PERMISSION(OPT_P_GENERAL);
5707         options->http_proxy_override = parse_http_proxy_override(p[1], p[2], p[3], msglevel, &options->gc);
5708         if (!options->http_proxy_override)
5709         {
5710             goto err;
5711         }
5712     }
5713 #endif
5714     else if (streq(p[0], "remote") && p[1] && !p[4])
5715     {
5716         struct remote_entry re;
5717         re.remote = re.remote_port = NULL;
5718         re.proto = -1;
5719         re.af = 0;
5720 
5721         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
5722         re.remote = p[1];
5723         if (p[2])
5724         {
5725             re.remote_port = p[2];
5726             if (p[3])
5727             {
5728                 const int proto = ascii2proto(p[3]);
5729                 const sa_family_t af = ascii2af(p[3]);
5730                 if (proto < 0)
5731                 {
5732                     msg(msglevel,
5733                         "remote: bad protocol associated with host %s: '%s'",
5734                         p[1], p[3]);
5735                     goto err;
5736                 }
5737                 re.proto = proto;
5738                 re.af = af;
5739             }
5740         }
5741         if (permission_mask & OPT_P_GENERAL)
5742         {
5743             struct remote_entry *e = alloc_remote_entry(options, msglevel);
5744             if (!e)
5745             {
5746                 goto err;
5747             }
5748             *e = re;
5749         }
5750         else if (permission_mask & OPT_P_CONNECTION)
5751         {
5752             connection_entry_load_re(&options->ce, &re);
5753         }
5754     }
5755     else if (streq(p[0], "resolv-retry") && p[1] && !p[2])
5756     {
5757         VERIFY_PERMISSION(OPT_P_GENERAL);
5758         if (streq(p[1], "infinite"))
5759         {
5760             options->resolve_retry_seconds = RESOLV_RETRY_INFINITE;
5761         }
5762         else
5763         {
5764             options->resolve_retry_seconds = positive_atoi(p[1]);
5765         }
5766     }
5767     else if ((streq(p[0], "preresolve") || streq(p[0], "ip-remote-hint")) && !p[2])
5768     {
5769         VERIFY_PERMISSION(OPT_P_GENERAL);
5770         options->resolve_in_advance = true;
5771         /* Note the ip-remote-hint and the argument p[1] are for
5772          * backward compatibility */
5773         if (p[1])
5774         {
5775             options->ip_remote_hint = p[1];
5776         }
5777     }
5778     else if (streq(p[0], "connect-retry") && p[1] && !p[3])
5779     {
5780         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
5781         options->ce.connect_retry_seconds = positive_atoi(p[1]);
5782         /*
5783          * Limit the base value of retry wait interval to 16 bits to avoid
5784          * overflow when scaled up for exponential backoff
5785          */
5786         if (options->ce.connect_retry_seconds > 0xFFFF)
5787         {
5788             options->ce.connect_retry_seconds = 0xFFFF;
5789             msg(M_WARN, "connect retry wait interval truncated to %d",
5790                 options->ce.connect_retry_seconds);
5791         }
5792 
5793         if (p[2])
5794         {
5795             options->ce.connect_retry_seconds_max =
5796                 max_int(positive_atoi(p[2]), options->ce.connect_retry_seconds);
5797         }
5798     }
5799     else if ((streq(p[0], "connect-timeout") || streq(p[0], "server-poll-timeout"))
5800              && p[1] && !p[2])
5801     {
5802         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
5803         options->ce.connect_timeout = positive_atoi(p[1]);
5804     }
5805     else if (streq(p[0], "connect-retry-max") && p[1] && !p[2])
5806     {
5807         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
5808         options->connect_retry_max = positive_atoi(p[1]);
5809     }
5810     else if (streq(p[0], "ipchange") && p[1])
5811     {
5812         VERIFY_PERMISSION(OPT_P_SCRIPT);
5813         if (!no_more_than_n_args(msglevel, p, 2, NM_QUOTE_HINT))
5814         {
5815             goto err;
5816         }
5817         set_user_script(options,
5818                         &options->ipchange,
5819                         string_substitute(p[1], ',', ' ', &options->gc),
5820                         "ipchange", true);
5821     }
5822     else if (streq(p[0], "float") && !p[1])
5823     {
5824         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
5825         options->ce.remote_float = true;
5826     }
5827 #ifdef ENABLE_DEBUG
5828     else if (streq(p[0], "gremlin") && p[1] && !p[2])
5829     {
5830         VERIFY_PERMISSION(OPT_P_GENERAL);
5831         options->gremlin = positive_atoi(p[1]);
5832     }
5833 #endif
5834     else if (streq(p[0], "chroot") && p[1] && !p[2])
5835     {
5836         VERIFY_PERMISSION(OPT_P_GENERAL);
5837         options->chroot_dir = p[1];
5838     }
5839     else if (streq(p[0], "cd") && p[1] && !p[2])
5840     {
5841         VERIFY_PERMISSION(OPT_P_GENERAL);
5842         if (platform_chdir(p[1]))
5843         {
5844             msg(M_ERR, "cd to '%s' failed", p[1]);
5845             goto err;
5846         }
5847         options->cd_dir = p[1];
5848     }
5849 #ifdef ENABLE_SELINUX
5850     else if (streq(p[0], "setcon") && p[1] && !p[2])
5851     {
5852         VERIFY_PERMISSION(OPT_P_GENERAL);
5853         options->selinux_context = p[1];
5854     }
5855 #endif
5856     else if (streq(p[0], "writepid") && p[1] && !p[2])
5857     {
5858         VERIFY_PERMISSION(OPT_P_GENERAL);
5859         options->writepid = p[1];
5860     }
5861     else if (streq(p[0], "up") && p[1])
5862     {
5863         VERIFY_PERMISSION(OPT_P_SCRIPT);
5864         if (!no_more_than_n_args(msglevel, p, 2, NM_QUOTE_HINT))
5865         {
5866             goto err;
5867         }
5868         set_user_script(options, &options->up_script, p[1], "up", false);
5869     }
5870     else if (streq(p[0], "down") && p[1])
5871     {
5872         VERIFY_PERMISSION(OPT_P_SCRIPT);
5873         if (!no_more_than_n_args(msglevel, p, 2, NM_QUOTE_HINT))
5874         {
5875             goto err;
5876         }
5877         set_user_script(options, &options->down_script, p[1], "down", true);
5878     }
5879     else if (streq(p[0], "down-pre") && !p[1])
5880     {
5881         VERIFY_PERMISSION(OPT_P_GENERAL);
5882         options->down_pre = true;
5883     }
5884     else if (streq(p[0], "up-delay") && !p[1])
5885     {
5886         VERIFY_PERMISSION(OPT_P_GENERAL);
5887         options->up_delay = true;
5888     }
5889     else if (streq(p[0], "up-restart") && !p[1])
5890     {
5891         VERIFY_PERMISSION(OPT_P_GENERAL);
5892         options->up_restart = true;
5893     }
5894     else if (streq(p[0], "syslog") && !p[2])
5895     {
5896         VERIFY_PERMISSION(OPT_P_GENERAL);
5897         open_syslog(p[1], false);
5898     }
5899     else if (streq(p[0], "daemon") && !p[2])
5900     {
5901         bool didit = false;
5902         VERIFY_PERMISSION(OPT_P_GENERAL);
5903         if (!options->daemon)
5904         {
5905             options->daemon = didit = true;
5906             open_syslog(p[1], false);
5907         }
5908         if (p[1])
5909         {
5910             if (!didit)
5911             {
5912                 msg(M_WARN, "WARNING: Multiple --daemon directives specified, ignoring --daemon %s. (Note that initscripts sometimes add their own --daemon directive.)", p[1]);
5913                 goto err;
5914             }
5915         }
5916     }
5917     else if (streq(p[0], "inetd") && !p[3])
5918     {
5919         VERIFY_PERMISSION(OPT_P_GENERAL);
5920         if (!options->inetd)
5921         {
5922             int z;
5923             const char *name = NULL;
5924             const char *opterr = "when --inetd is used with two parameters, one of them must be 'wait' or 'nowait' and the other must be a daemon name to use for system logging";
5925 
5926             options->inetd = -1;
5927 
5928             for (z = 1; z <= 2; ++z)
5929             {
5930                 if (p[z])
5931                 {
5932                     if (streq(p[z], "wait"))
5933                     {
5934                         if (options->inetd != -1)
5935                         {
5936                             msg(msglevel, "%s", opterr);
5937                             goto err;
5938                         }
5939                         else
5940                         {
5941                             options->inetd = INETD_WAIT;
5942                         }
5943                     }
5944                     else if (streq(p[z], "nowait"))
5945                     {
5946                         if (options->inetd != -1)
5947                         {
5948                             msg(msglevel, "%s", opterr);
5949                             goto err;
5950                         }
5951                         else
5952                         {
5953                             options->inetd = INETD_NOWAIT;
5954                         }
5955                     }
5956                     else
5957                     {
5958                         if (name != NULL)
5959                         {
5960                             msg(msglevel, "%s", opterr);
5961                             goto err;
5962                         }
5963                         name = p[z];
5964                     }
5965                 }
5966             }
5967 
5968             /* default */
5969             if (options->inetd == -1)
5970             {
5971                 options->inetd = INETD_WAIT;
5972             }
5973 
5974             save_inetd_socket_descriptor();
5975             open_syslog(name, true);
5976         }
5977     }
5978     else if (streq(p[0], "log") && p[1] && !p[2])
5979     {
5980         VERIFY_PERMISSION(OPT_P_GENERAL);
5981         options->log = true;
5982         redirect_stdout_stderr(p[1], false);
5983     }
5984     else if (streq(p[0], "suppress-timestamps") && !p[1])
5985     {
5986         VERIFY_PERMISSION(OPT_P_GENERAL);
5987         options->suppress_timestamps = true;
5988         set_suppress_timestamps(true);
5989     }
5990     else if (streq(p[0], "machine-readable-output") && !p[1])
5991     {
5992         VERIFY_PERMISSION(OPT_P_GENERAL);
5993         options->machine_readable_output = true;
5994         set_machine_readable_output(true);
5995     }
5996     else if (streq(p[0], "log-append") && p[1] && !p[2])
5997     {
5998         VERIFY_PERMISSION(OPT_P_GENERAL);
5999         options->log = true;
6000         redirect_stdout_stderr(p[1], true);
6001     }
6002 #ifdef ENABLE_MEMSTATS
6003     else if (streq(p[0], "memstats") && p[1] && !p[2])
6004     {
6005         VERIFY_PERMISSION(OPT_P_GENERAL);
6006         options->memstats_fn = p[1];
6007     }
6008 #endif
6009     else if (streq(p[0], "mlock") && !p[1])
6010     {
6011         VERIFY_PERMISSION(OPT_P_GENERAL);
6012         options->mlock = true;
6013     }
6014 #if ENABLE_IP_PKTINFO
6015     else if (streq(p[0], "multihome") && !p[1])
6016     {
6017         VERIFY_PERMISSION(OPT_P_GENERAL);
6018         options->sockflags |= SF_USE_IP_PKTINFO;
6019     }
6020 #endif
6021     else if (streq(p[0], "verb") && p[1] && !p[2])
6022     {
6023         VERIFY_PERMISSION(OPT_P_MESSAGES);
6024         options->verbosity = positive_atoi(p[1]);
6025         if (options->verbosity >= (D_TLS_DEBUG_MED & M_DEBUG_LEVEL))
6026         {
6027             /* We pass this flag to the SSL library to avoid
6028              * mbed TLS always generating debug level logging */
6029             options->ssl_flags |= SSLF_TLS_DEBUG_ENABLED;
6030         }
6031 #if !defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
6032         /* Warn when a debug verbosity is supplied when built without debug support */
6033         if (options->verbosity >= 7)
6034         {
6035             msg(M_WARN, "NOTE: debug verbosity (--verb %d) is enabled but this build lacks debug support.",
6036                 options->verbosity);
6037         }
6038 #endif
6039     }
6040     else if (streq(p[0], "mute") && p[1] && !p[2])
6041     {
6042         VERIFY_PERMISSION(OPT_P_MESSAGES);
6043         options->mute = positive_atoi(p[1]);
6044     }
6045     else if (streq(p[0], "errors-to-stderr") && !p[1])
6046     {
6047         VERIFY_PERMISSION(OPT_P_MESSAGES);
6048         errors_to_stderr();
6049     }
6050     else if (streq(p[0], "status") && p[1] && !p[3])
6051     {
6052         VERIFY_PERMISSION(OPT_P_GENERAL);
6053         options->status_file = p[1];
6054         if (p[2])
6055         {
6056             options->status_file_update_freq = positive_atoi(p[2]);
6057         }
6058     }
6059     else if (streq(p[0], "status-version") && p[1] && !p[2])
6060     {
6061         int version;
6062 
6063         VERIFY_PERMISSION(OPT_P_GENERAL);
6064         version = atoi(p[1]);
6065         if (version < 1 || version > 3)
6066         {
6067             msg(msglevel, "--status-version must be 1 to 3");
6068             goto err;
6069         }
6070         options->status_file_version = version;
6071     }
6072     else if (streq(p[0], "remap-usr1") && p[1] && !p[2])
6073     {
6074         VERIFY_PERMISSION(OPT_P_GENERAL);
6075         if (streq(p[1], "SIGHUP"))
6076         {
6077             options->remap_sigusr1 = SIGHUP;
6078         }
6079         else if (streq(p[1], "SIGTERM"))
6080         {
6081             options->remap_sigusr1 = SIGTERM;
6082         }
6083         else
6084         {
6085             msg(msglevel, "--remap-usr1 parm must be 'SIGHUP' or 'SIGTERM'");
6086             goto err;
6087         }
6088     }
6089     else if ((streq(p[0], "link-mtu") || streq(p[0], "udp-mtu")) && p[1] && !p[2])
6090     {
6091         VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION);
6092         options->ce.link_mtu = positive_atoi(p[1]);
6093         options->ce.link_mtu_defined = true;
6094     }
6095     else if (streq(p[0], "tun-mtu") && p[1] && !p[2])
6096     {
6097         VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION);
6098         options->ce.tun_mtu = positive_atoi(p[1]);
6099         options->ce.tun_mtu_defined = true;
6100     }
6101     else if (streq(p[0], "tun-mtu-extra") && p[1] && !p[2])
6102     {
6103         VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION);
6104         options->ce.tun_mtu_extra = positive_atoi(p[1]);
6105         options->ce.tun_mtu_extra_defined = true;
6106     }
6107 #ifdef ENABLE_FRAGMENT
6108     else if (streq(p[0], "mtu-dynamic"))
6109     {
6110         VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION);
6111         msg(msglevel, "--mtu-dynamic has been replaced by --fragment");
6112         goto err;
6113     }
6114     else if (streq(p[0], "fragment") && p[1] && !p[2])
6115     {
6116 /*      VERIFY_PERMISSION (OPT_P_MTU); */
6117         VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION);
6118         options->ce.fragment = positive_atoi(p[1]);
6119     }
6120 #endif
6121     else if (streq(p[0], "mtu-disc") && p[1] && !p[2])
6122     {
6123         VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION);
6124         options->ce.mtu_discover_type = translate_mtu_discover_type_name(p[1]);
6125     }
6126     else if (streq(p[0], "mtu-test") && !p[1])
6127     {
6128         VERIFY_PERMISSION(OPT_P_GENERAL);
6129         options->mtu_test = true;
6130     }
6131     else if (streq(p[0], "nice") && p[1] && !p[2])
6132     {
6133         VERIFY_PERMISSION(OPT_P_NICE);
6134         options->nice = atoi(p[1]);
6135     }
6136     else if (streq(p[0], "rcvbuf") && p[1] && !p[2])
6137     {
6138         VERIFY_PERMISSION(OPT_P_SOCKBUF);
6139         options->rcvbuf = positive_atoi(p[1]);
6140     }
6141     else if (streq(p[0], "sndbuf") && p[1] && !p[2])
6142     {
6143         VERIFY_PERMISSION(OPT_P_SOCKBUF);
6144         options->sndbuf = positive_atoi(p[1]);
6145     }
6146     else if (streq(p[0], "mark") && p[1] && !p[2])
6147     {
6148 #if defined(TARGET_LINUX) && HAVE_DECL_SO_MARK
6149         VERIFY_PERMISSION(OPT_P_GENERAL);
6150         options->mark = atoi(p[1]);
6151 #endif
6152     }
6153     else if (streq(p[0], "socket-flags"))
6154     {
6155         int j;
6156         VERIFY_PERMISSION(OPT_P_SOCKFLAGS);
6157         for (j = 1; j < MAX_PARMS && p[j]; ++j)
6158         {
6159             if (streq(p[j], "TCP_NODELAY"))
6160             {
6161                 options->sockflags |= SF_TCP_NODELAY;
6162             }
6163             else
6164             {
6165                 msg(msglevel, "unknown socket flag: %s", p[j]);
6166             }
6167         }
6168     }
6169 #ifdef TARGET_LINUX
6170     else if (streq (p[0], "bind-dev") && p[1])
6171     {
6172         VERIFY_PERMISSION (OPT_P_SOCKFLAGS);
6173         options->bind_dev = p[1];
6174     }
6175 #endif
6176     else if (streq(p[0], "txqueuelen") && p[1] && !p[2])
6177     {
6178         VERIFY_PERMISSION(OPT_P_GENERAL);
6179 #ifdef TARGET_LINUX
6180         options->tuntap_options.txqueuelen = positive_atoi(p[1]);
6181 #else
6182         msg(msglevel, "--txqueuelen not supported on this OS");
6183         goto err;
6184 #endif
6185     }
6186     else if (streq(p[0], "shaper") && p[1] && !p[2])
6187     {
6188 #ifdef ENABLE_FEATURE_SHAPER
6189         int shaper;
6190 
6191         VERIFY_PERMISSION(OPT_P_SHAPER);
6192         shaper = atoi(p[1]);
6193         if (shaper < SHAPER_MIN || shaper > SHAPER_MAX)
6194         {
6195             msg(msglevel, "Bad shaper value, must be between %d and %d",
6196                 SHAPER_MIN, SHAPER_MAX);
6197             goto err;
6198         }
6199         options->shaper = shaper;
6200 #else /* ENABLE_FEATURE_SHAPER */
6201         VERIFY_PERMISSION(OPT_P_GENERAL);
6202         msg(msglevel, "--shaper requires the gettimeofday() function which is missing");
6203         goto err;
6204 #endif /* ENABLE_FEATURE_SHAPER */
6205     }
6206     else if (streq(p[0], "port") && p[1] && !p[2])
6207     {
6208         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
6209         options->ce.local_port = options->ce.remote_port = p[1];
6210     }
6211     else if (streq(p[0], "lport") && p[1] && !p[2])
6212     {
6213         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
6214         options->ce.local_port_defined = true;
6215         options->ce.local_port = p[1];
6216     }
6217     else if (streq(p[0], "rport") && p[1] && !p[2])
6218     {
6219         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
6220         options->ce.remote_port = p[1];
6221     }
6222     else if (streq(p[0], "bind") && !p[2])
6223     {
6224         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
6225         options->ce.bind_defined = true;
6226         if (p[1] && streq(p[1], "ipv6only"))
6227         {
6228             options->ce.bind_ipv6_only = true;
6229         }
6230 
6231     }
6232     else if (streq(p[0], "nobind") && !p[1])
6233     {
6234         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
6235         options->ce.bind_local = false;
6236     }
6237     else if (streq(p[0], "fast-io") && !p[1])
6238     {
6239         VERIFY_PERMISSION(OPT_P_GENERAL);
6240         options->fast_io = true;
6241     }
6242     else if (streq(p[0], "inactive") && p[1] && !p[3])
6243     {
6244         VERIFY_PERMISSION(OPT_P_TIMER);
6245         options->inactivity_timeout = positive_atoi(p[1]);
6246         if (p[2])
6247         {
6248             int64_t val = atoll(p[2]);
6249             options->inactivity_minimum_bytes = (val < 0) ? 0 : val;
6250             if ( options->inactivity_minimum_bytes > INT_MAX )
6251             {
6252                 msg(M_WARN, "WARNING: '--inactive' with a 'bytes' value"
6253                     " >2 Gbyte was silently ignored in older versions.  If "
6254                     " your VPN exits unexpectedly with 'Inactivity timeout'"
6255                     " in %d seconds, revisit this value.",
6256                     options->inactivity_timeout );
6257             }
6258         }
6259     }
6260     else if (streq(p[0], "proto") && p[1] && !p[2])
6261     {
6262         int proto;
6263         sa_family_t af;
6264         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
6265         proto = ascii2proto(p[1]);
6266         af = ascii2af(p[1]);
6267         if (proto < 0)
6268         {
6269             msg(msglevel,
6270                 "Bad protocol: '%s'. Allowed protocols with --proto option: %s",
6271                 p[1],
6272                 proto2ascii_all(&gc));
6273             goto err;
6274         }
6275         options->ce.proto = proto;
6276         options->ce.af = af;
6277     }
6278     else if (streq(p[0], "proto-force") && p[1] && !p[2])
6279     {
6280         int proto_force;
6281         VERIFY_PERMISSION(OPT_P_GENERAL);
6282         proto_force = ascii2proto(p[1]);
6283         if (proto_force < 0)
6284         {
6285             msg(msglevel, "Bad --proto-force protocol: '%s'", p[1]);
6286             goto err;
6287         }
6288         options->proto_force = proto_force;
6289     }
6290     else if (streq(p[0], "http-proxy") && p[1] && !p[5])
6291     {
6292         struct http_proxy_options *ho;
6293 
6294         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
6295 
6296         {
6297             if (!p[2])
6298             {
6299                 msg(msglevel, "http-proxy port number not defined");
6300                 goto err;
6301             }
6302 
6303             ho = init_http_proxy_options_once(&options->ce.http_proxy_options, &options->gc);
6304 
6305             ho->server = p[1];
6306             ho->port = p[2];
6307         }
6308 
6309         if (p[3])
6310         {
6311             /* auto -- try to figure out proxy addr, port, and type automatically */
6312             /* semiauto -- given proxy addr:port, try to figure out type automatically */
6313             /* (auto|semiauto)-nct -- disable proxy auth cleartext protocols (i.e. basic auth) */
6314             if (streq(p[3], "auto"))
6315             {
6316                 ho->auth_retry = PAR_ALL;
6317             }
6318             else if (streq(p[3], "auto-nct"))
6319             {
6320                 ho->auth_retry = PAR_NCT;
6321             }
6322             else
6323             {
6324                 ho->auth_method_string = "basic";
6325                 ho->auth_file = p[3];
6326 
6327                 if (p[4])
6328                 {
6329                     ho->auth_method_string = p[4];
6330                 }
6331             }
6332         }
6333         else
6334         {
6335             ho->auth_method_string = "none";
6336         }
6337     }
6338     else if (streq(p[0], "http-proxy-user-pass") && p[1])
6339     {
6340         struct http_proxy_options *ho;
6341         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INLINE);
6342         ho = init_http_proxy_options_once(&options->ce.http_proxy_options, &options->gc);
6343         ho->auth_file = p[1];
6344         ho->inline_creds = is_inline;
6345     }
6346     else if (streq(p[0], "http-proxy-retry") || streq(p[0], "socks-proxy-retry"))
6347     {
6348         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
6349         msg(M_WARN, "DEPRECATED OPTION: http-proxy-retry and socks-proxy-retry: "
6350             "In OpenVPN 2.4 proxy connection retries are handled like regular connections. "
6351             "Use connect-retry-max 1 to get a similar behavior as before.");
6352     }
6353     else if (streq(p[0], "http-proxy-timeout") && p[1] && !p[2])
6354     {
6355         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
6356         msg(M_WARN, "DEPRECATED OPTION: http-proxy-timeout: In OpenVPN 2.4 the timeout until a connection to a "
6357             "server is established is managed with a single timeout set by connect-timeout");
6358     }
6359     else if (streq(p[0], "http-proxy-option") && p[1] && !p[4])
6360     {
6361         struct http_proxy_options *ho;
6362 
6363         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
6364         ho = init_http_proxy_options_once(&options->ce.http_proxy_options, &options->gc);
6365 
6366         if (streq(p[1], "VERSION") && p[2] && !p[3])
6367         {
6368             ho->http_version = p[2];
6369         }
6370         else if (streq(p[1], "AGENT") && p[2] && !p[3])
6371         {
6372             ho->user_agent = p[2];
6373         }
6374         else if ((streq(p[1], "EXT1") || streq(p[1], "EXT2") || streq(p[1], "CUSTOM-HEADER"))
6375                  && p[2])
6376         {
6377             /* In the wild patched versions use both EXT1/2 and CUSTOM-HEADER
6378              * with either two argument or one */
6379 
6380             struct http_custom_header *custom_header = NULL;
6381             int i;
6382             /* Find the first free header */
6383             for (i = 0; i < MAX_CUSTOM_HTTP_HEADER; i++)
6384             {
6385                 if (!ho->custom_headers[i].name)
6386                 {
6387                     custom_header = &ho->custom_headers[i];
6388                     break;
6389                 }
6390             }
6391             if (!custom_header)
6392             {
6393                 msg(msglevel, "Cannot use more than %d http-proxy-option CUSTOM-HEADER : '%s'", MAX_CUSTOM_HTTP_HEADER, p[1]);
6394             }
6395             else
6396             {
6397                 /* We will save p[2] and p[3], the proxy code will detect if
6398                  * p[3] is NULL */
6399                 custom_header->name = p[2];
6400                 custom_header->content = p[3];
6401             }
6402         }
6403         else
6404         {
6405             msg(msglevel, "Bad http-proxy-option or missing or extra parameter: '%s'", p[1]);
6406         }
6407     }
6408     else if (streq(p[0], "socks-proxy") && p[1] && !p[4])
6409     {
6410         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
6411 
6412         if (p[2])
6413         {
6414             options->ce.socks_proxy_port = p[2];
6415         }
6416         else
6417         {
6418             options->ce.socks_proxy_port = "1080";
6419         }
6420         options->ce.socks_proxy_server = p[1];
6421         options->ce.socks_proxy_authfile = p[3]; /* might be NULL */
6422     }
6423     else if (streq(p[0], "keepalive") && p[1] && p[2] && !p[3])
6424     {
6425         VERIFY_PERMISSION(OPT_P_GENERAL);
6426         options->keepalive_ping = atoi(p[1]);
6427         options->keepalive_timeout = atoi(p[2]);
6428     }
6429     else if (streq(p[0], "ping") && p[1] && !p[2])
6430     {
6431         VERIFY_PERMISSION(OPT_P_TIMER);
6432         options->ping_send_timeout = positive_atoi(p[1]);
6433     }
6434     else if (streq(p[0], "ping-exit") && p[1] && !p[2])
6435     {
6436         VERIFY_PERMISSION(OPT_P_TIMER);
6437         options->ping_rec_timeout = positive_atoi(p[1]);
6438         options->ping_rec_timeout_action = PING_EXIT;
6439     }
6440     else if (streq(p[0], "ping-restart") && p[1] && !p[2])
6441     {
6442         VERIFY_PERMISSION(OPT_P_TIMER);
6443         options->ping_rec_timeout = positive_atoi(p[1]);
6444         options->ping_rec_timeout_action = PING_RESTART;
6445     }
6446     else if (streq(p[0], "ping-timer-rem") && !p[1])
6447     {
6448         VERIFY_PERMISSION(OPT_P_TIMER);
6449         options->ping_timer_remote = true;
6450     }
6451     else if (streq(p[0], "explicit-exit-notify") && !p[2])
6452     {
6453         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION|OPT_P_EXPLICIT_NOTIFY);
6454         if (p[1])
6455         {
6456             options->ce.explicit_exit_notification = positive_atoi(p[1]);
6457         }
6458         else
6459         {
6460             options->ce.explicit_exit_notification = 1;
6461         }
6462     }
6463     else if (streq(p[0], "persist-tun") && !p[1])
6464     {
6465         VERIFY_PERMISSION(OPT_P_PERSIST);
6466         options->persist_tun = true;
6467     }
6468     else if (streq(p[0], "persist-key") && !p[1])
6469     {
6470         VERIFY_PERMISSION(OPT_P_PERSIST);
6471         options->persist_key = true;
6472     }
6473     else if (streq(p[0], "persist-local-ip") && !p[1])
6474     {
6475         VERIFY_PERMISSION(OPT_P_PERSIST_IP);
6476         options->persist_local_ip = true;
6477     }
6478     else if (streq(p[0], "persist-remote-ip") && !p[1])
6479     {
6480         VERIFY_PERMISSION(OPT_P_PERSIST_IP);
6481         options->persist_remote_ip = true;
6482     }
6483     else if (streq(p[0], "client-nat") && p[1] && p[2] && p[3] && p[4] && !p[5])
6484     {
6485         VERIFY_PERMISSION(OPT_P_ROUTE);
6486         cnol_check_alloc(options);
6487         add_client_nat_to_option_list(options->client_nat, p[1], p[2], p[3], p[4], msglevel);
6488     }
6489     else if (streq(p[0], "route") && p[1] && !p[5])
6490     {
6491         VERIFY_PERMISSION(OPT_P_ROUTE);
6492         rol_check_alloc(options);
6493         if (pull_mode)
6494         {
6495             if (!ip_or_dns_addr_safe(p[1], options->allow_pull_fqdn) && !is_special_addr(p[1])) /* FQDN -- may be DNS name */
6496             {
6497                 msg(msglevel, "route parameter network/IP '%s' must be a valid address", p[1]);
6498                 goto err;
6499             }
6500             if (p[2] && !ip_addr_dotted_quad_safe(p[2])) /* FQDN -- must be IP address */
6501             {
6502                 msg(msglevel, "route parameter netmask '%s' must be an IP address", p[2]);
6503                 goto err;
6504             }
6505             if (p[3] && !ip_or_dns_addr_safe(p[3], options->allow_pull_fqdn) && !is_special_addr(p[3])) /* FQDN -- may be DNS name */
6506             {
6507                 msg(msglevel, "route parameter gateway '%s' must be a valid address", p[3]);
6508                 goto err;
6509             }
6510         }
6511         add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4]);
6512     }
6513     else if (streq(p[0], "route-ipv6") && p[1] && !p[4])
6514     {
6515         VERIFY_PERMISSION(OPT_P_ROUTE);
6516         rol6_check_alloc(options);
6517         if (pull_mode)
6518         {
6519             if (!ipv6_addr_safe_hexplusbits(p[1]))
6520             {
6521                 msg(msglevel, "route-ipv6 parameter network/IP '%s' must be a valid address", p[1]);
6522                 goto err;
6523             }
6524             if (p[2] && !ipv6_addr_safe(p[2]))
6525             {
6526                 msg(msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]);
6527                 goto err;
6528             }
6529             /* p[3] is metric, if present */
6530         }
6531         add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3]);
6532     }
6533     else if (streq(p[0], "max-routes") && !p[2])
6534     {
6535         msg(M_WARN, "DEPRECATED OPTION: --max-routes option ignored."
6536             "The number of routes is unlimited as of OpenVPN 2.4. "
6537             "This option will be removed in a future version, "
6538             "please remove it from your configuration.");
6539     }
6540     else if (streq(p[0], "route-gateway") && p[1] && !p[2])
6541     {
6542         VERIFY_PERMISSION(OPT_P_ROUTE_EXTRAS);
6543         if (streq(p[1], "dhcp"))
6544         {
6545             options->route_gateway_via_dhcp = true;
6546         }
6547         else
6548         {
6549             if (ip_or_dns_addr_safe(p[1], options->allow_pull_fqdn) || is_special_addr(p[1])) /* FQDN -- may be DNS name */
6550             {
6551                 options->route_default_gateway = p[1];
6552             }
6553             else
6554             {
6555                 msg(msglevel, "route-gateway parm '%s' must be a valid address", p[1]);
6556                 goto err;
6557             }
6558         }
6559     }
6560     else if (streq(p[0], "route-ipv6-gateway") && p[1] && !p[2])
6561     {
6562         if (ipv6_addr_safe(p[1]))
6563         {
6564             options->route_ipv6_default_gateway = p[1];
6565         }
6566         else
6567         {
6568             msg(msglevel, "route-ipv6-gateway parm '%s' must be a valid address", p[1]);
6569             goto err;
6570         }
6571     }
6572     else if (streq(p[0], "route-metric") && p[1] && !p[2])
6573     {
6574         VERIFY_PERMISSION(OPT_P_ROUTE);
6575         options->route_default_metric = positive_atoi(p[1]);
6576     }
6577     else if (streq(p[0], "route-delay") && !p[3])
6578     {
6579         VERIFY_PERMISSION(OPT_P_ROUTE_EXTRAS);
6580         options->route_delay_defined = true;
6581         if (p[1])
6582         {
6583             options->route_delay = positive_atoi(p[1]);
6584             if (p[2])
6585             {
6586                 options->route_delay_window = positive_atoi(p[2]);
6587             }
6588         }
6589         else
6590         {
6591             options->route_delay = 0;
6592         }
6593     }
6594     else if (streq(p[0], "route-up") && p[1])
6595     {
6596         VERIFY_PERMISSION(OPT_P_SCRIPT);
6597         if (!no_more_than_n_args(msglevel, p, 2, NM_QUOTE_HINT))
6598         {
6599             goto err;
6600         }
6601         set_user_script(options, &options->route_script, p[1], "route-up", false);
6602     }
6603     else if (streq(p[0], "route-pre-down") && p[1])
6604     {
6605         VERIFY_PERMISSION(OPT_P_SCRIPT);
6606         if (!no_more_than_n_args(msglevel, p, 2, NM_QUOTE_HINT))
6607         {
6608             goto err;
6609         }
6610         set_user_script(options,
6611                         &options->route_predown_script,
6612                         p[1],
6613                         "route-pre-down", true);
6614     }
6615     else if (streq(p[0], "route-noexec") && !p[1])
6616     {
6617         VERIFY_PERMISSION(OPT_P_SCRIPT);
6618         options->route_noexec = true;
6619     }
6620     else if (streq(p[0], "route-nopull") && !p[1])
6621     {
6622         VERIFY_PERMISSION(OPT_P_GENERAL);
6623         options->route_nopull = true;
6624     }
6625     else if (streq(p[0], "pull-filter") && p[1] && p[2] && !p[3])
6626     {
6627         struct pull_filter *f;
6628         VERIFY_PERMISSION(OPT_P_GENERAL)
6629         f = alloc_pull_filter(options, msglevel);
6630 
6631         if (strcmp("accept", p[1]) == 0)
6632         {
6633             f->type = PUF_TYPE_ACCEPT;
6634         }
6635         else if (strcmp("ignore", p[1]) == 0)
6636         {
6637             f->type = PUF_TYPE_IGNORE;
6638         }
6639         else if (strcmp("reject", p[1]) == 0)
6640         {
6641             f->type = PUF_TYPE_REJECT;
6642         }
6643         else
6644         {
6645             msg(msglevel, "Unknown --pull-filter type: %s", p[1]);
6646             goto err;
6647         }
6648         f->pattern = p[2];
6649         f->size = strlen(p[2]);
6650     }
6651     else if (streq(p[0], "allow-pull-fqdn") && !p[1])
6652     {
6653         VERIFY_PERMISSION(OPT_P_GENERAL);
6654         options->allow_pull_fqdn = true;
6655     }
6656     else if (streq(p[0], "redirect-gateway") || streq(p[0], "redirect-private"))
6657     {
6658         int j;
6659         VERIFY_PERMISSION(OPT_P_ROUTE);
6660         rol_check_alloc(options);
6661 
6662         if (options->routes->flags & RG_ENABLE)
6663         {
6664             msg(M_WARN,
6665                 "WARNING: You have specified redirect-gateway and "
6666                 "redirect-private at the same time (or the same option "
6667                 "multiple times). This is not well supported and may lead to "
6668                 "unexpected results");
6669         }
6670 
6671         options->routes->flags |= RG_ENABLE;
6672 
6673         if (streq(p[0], "redirect-gateway"))
6674         {
6675             options->routes->flags |= RG_REROUTE_GW;
6676         }
6677         for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
6678         {
6679             if (streq(p[j], "local"))
6680             {
6681                 options->routes->flags |= RG_LOCAL;
6682             }
6683             else if (streq(p[j], "autolocal"))
6684             {
6685                 options->routes->flags |= RG_AUTO_LOCAL;
6686             }
6687             else if (streq(p[j], "def1"))
6688             {
6689                 options->routes->flags |= RG_DEF1;
6690             }
6691             else if (streq(p[j], "bypass-dhcp"))
6692             {
6693                 options->routes->flags |= RG_BYPASS_DHCP;
6694             }
6695             else if (streq(p[j], "bypass-dns"))
6696             {
6697                 options->routes->flags |= RG_BYPASS_DNS;
6698             }
6699             else if (streq(p[j], "block-local"))
6700             {
6701                 options->routes->flags |= RG_BLOCK_LOCAL;
6702             }
6703             else if (streq(p[j], "ipv6"))
6704             {
6705                 rol6_check_alloc(options);
6706                 options->routes_ipv6->flags |= RG_REROUTE_GW;
6707             }
6708             else if (streq(p[j], "!ipv4"))
6709             {
6710                 options->routes->flags &= ~(RG_REROUTE_GW | RG_ENABLE);
6711             }
6712             else
6713             {
6714                 msg(msglevel, "unknown --%s flag: %s", p[0], p[j]);
6715                 goto err;
6716             }
6717         }
6718 #ifdef _WIN32
6719         /* we need this here to handle pushed --redirect-gateway */
6720         remap_redirect_gateway_flags(options);
6721 #endif
6722     }
6723     else if (streq(p[0], "block-ipv6") && !p[1])
6724     {
6725         VERIFY_PERMISSION(OPT_P_ROUTE);
6726         options->block_ipv6 = true;
6727     }
6728     else if (streq(p[0], "remote-random-hostname") && !p[1])
6729     {
6730         VERIFY_PERMISSION(OPT_P_GENERAL);
6731         options->sockflags |= SF_HOST_RANDOMIZE;
6732     }
6733     else if (streq(p[0], "setenv") && p[1] && !p[3])
6734     {
6735         VERIFY_PERMISSION(OPT_P_GENERAL);
6736         if (streq(p[1], "REMOTE_RANDOM_HOSTNAME") && !p[2])
6737         {
6738             options->sockflags |= SF_HOST_RANDOMIZE;
6739         }
6740         else if (streq(p[1], "GENERIC_CONFIG"))
6741         {
6742             msg(msglevel, "this is a generic configuration and cannot directly be used");
6743             goto err;
6744         }
6745         else if (streq(p[1], "PUSH_PEER_INFO") && !p[2])
6746         {
6747             options->push_peer_info = true;
6748         }
6749         else if (streq(p[1], "SERVER_POLL_TIMEOUT") && p[2])
6750         {
6751             options->ce.connect_timeout = positive_atoi(p[2]);
6752         }
6753         else
6754         {
6755             if (streq(p[1], "FORWARD_COMPATIBLE") && p[2] && streq(p[2], "1"))
6756             {
6757                 options->forward_compatible = true;
6758                 msglevel_fc = msglevel_forward_compatible(options, msglevel);
6759             }
6760             setenv_str(es, p[1], p[2] ? p[2] : "");
6761         }
6762     }
6763     else if (streq(p[0], "setenv-safe") && p[1] && !p[3])
6764     {
6765         VERIFY_PERMISSION(OPT_P_SETENV);
6766         setenv_str_safe(es, p[1], p[2] ? p[2] : "");
6767     }
6768     else if (streq(p[0], "script-security") && p[1] && !p[2])
6769     {
6770         VERIFY_PERMISSION(OPT_P_GENERAL);
6771         script_security_set(atoi(p[1]));
6772     }
6773     else if (streq(p[0], "mssfix") && !p[2])
6774     {
6775         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
6776         if (p[1])
6777         {
6778             options->ce.mssfix = positive_atoi(p[1]);
6779         }
6780         else
6781         {
6782             options->ce.mssfix_default = true;
6783         }
6784 
6785     }
6786     else if (streq(p[0], "disable-occ") && !p[1])
6787     {
6788         VERIFY_PERMISSION(OPT_P_GENERAL);
6789         options->occ = false;
6790     }
6791 #if P2MP
6792     else if (streq(p[0], "server") && p[1] && p[2] && !p[4])
6793     {
6794         const int lev = M_WARN;
6795         bool error = false;
6796         in_addr_t network, netmask;
6797 
6798         VERIFY_PERMISSION(OPT_P_GENERAL);
6799         network = get_ip_addr(p[1], lev, &error);
6800         netmask = get_ip_addr(p[2], lev, &error);
6801         if (error || !network || !netmask)
6802         {
6803             msg(msglevel, "error parsing --server parameters");
6804             goto err;
6805         }
6806         options->server_defined = true;
6807         options->server_network = network;
6808         options->server_netmask = netmask;
6809 
6810         if (p[3])
6811         {
6812             if (streq(p[3], "nopool"))
6813             {
6814                 options->server_flags |= SF_NOPOOL;
6815             }
6816             else
6817             {
6818                 msg(msglevel, "error parsing --server: %s is not a recognized flag", p[3]);
6819                 goto err;
6820             }
6821         }
6822     }
6823     else if (streq(p[0], "server-ipv6") && p[1] && !p[3])
6824     {
6825         const int lev = M_WARN;
6826         struct in6_addr network;
6827         unsigned int netbits = 0;
6828 
6829         VERIFY_PERMISSION(OPT_P_GENERAL);
6830         if (!get_ipv6_addr(p[1], &network, &netbits, lev) )
6831         {
6832             msg(msglevel, "error parsing --server-ipv6 parameter");
6833             goto err;
6834         }
6835         if (netbits < 64 || netbits > 124)
6836         {
6837             msg(msglevel,
6838                 "--server-ipv6 settings: network must be between /64 and /124 (not /%d)",
6839                 netbits);
6840 
6841             goto err;
6842         }
6843         options->server_ipv6_defined = true;
6844         options->server_network_ipv6 = network;
6845         options->server_netbits_ipv6 = netbits;
6846 
6847         if (p[2])       /* no "nopool" options or similar for IPv6 */
6848         {
6849             msg(msglevel, "error parsing --server-ipv6: %s is not a recognized flag", p[3]);
6850             goto err;
6851         }
6852     }
6853     else if (streq(p[0], "server-bridge") && p[1] && p[2] && p[3] && p[4] && !p[5])
6854     {
6855         const int lev = M_WARN;
6856         bool error = false;
6857         in_addr_t ip, netmask, pool_start, pool_end;
6858 
6859         VERIFY_PERMISSION(OPT_P_GENERAL);
6860         ip = get_ip_addr(p[1], lev, &error);
6861         netmask = get_ip_addr(p[2], lev, &error);
6862         pool_start = get_ip_addr(p[3], lev, &error);
6863         pool_end = get_ip_addr(p[4], lev, &error);
6864         if (error || !ip || !netmask || !pool_start || !pool_end)
6865         {
6866             msg(msglevel, "error parsing --server-bridge parameters");
6867             goto err;
6868         }
6869         options->server_bridge_defined = true;
6870         options->server_bridge_ip = ip;
6871         options->server_bridge_netmask = netmask;
6872         options->server_bridge_pool_start = pool_start;
6873         options->server_bridge_pool_end = pool_end;
6874     }
6875     else if (streq(p[0], "server-bridge") && p[1] && streq(p[1], "nogw") && !p[2])
6876     {
6877         VERIFY_PERMISSION(OPT_P_GENERAL);
6878         options->server_bridge_proxy_dhcp = true;
6879         options->server_flags |= SF_NO_PUSH_ROUTE_GATEWAY;
6880     }
6881     else if (streq(p[0], "server-bridge") && !p[1])
6882     {
6883         VERIFY_PERMISSION(OPT_P_GENERAL);
6884         options->server_bridge_proxy_dhcp = true;
6885     }
6886     else if (streq(p[0], "push") && p[1] && !p[2])
6887     {
6888         VERIFY_PERMISSION(OPT_P_PUSH);
6889         push_options(options, &p[1], msglevel, &options->gc);
6890     }
6891     else if (streq(p[0], "push-reset") && !p[1])
6892     {
6893         VERIFY_PERMISSION(OPT_P_INSTANCE);
6894         push_reset(options);
6895     }
6896     else if (streq(p[0], "push-remove") && p[1] && !p[2])
6897     {
6898         VERIFY_PERMISSION(OPT_P_INSTANCE);
6899         msg(D_PUSH, "PUSH_REMOVE '%s'", p[1]);
6900         push_remove_option(options,p[1]);
6901     }
6902     else if (streq(p[0], "ifconfig-pool") && p[1] && p[2] && !p[4])
6903     {
6904         const int lev = M_WARN;
6905         bool error = false;
6906         in_addr_t start, end, netmask = 0;
6907 
6908         VERIFY_PERMISSION(OPT_P_GENERAL);
6909         start = get_ip_addr(p[1], lev, &error);
6910         end = get_ip_addr(p[2], lev, &error);
6911         if (p[3])
6912         {
6913             netmask = get_ip_addr(p[3], lev, &error);
6914         }
6915         if (error)
6916         {
6917             msg(msglevel, "error parsing --ifconfig-pool parameters");
6918             goto err;
6919         }
6920         if (!ifconfig_pool_verify_range(msglevel, start, end))
6921         {
6922             goto err;
6923         }
6924 
6925         options->ifconfig_pool_defined = true;
6926         options->ifconfig_pool_start = start;
6927         options->ifconfig_pool_end = end;
6928         if (netmask)
6929         {
6930             options->ifconfig_pool_netmask = netmask;
6931         }
6932     }
6933     else if (streq(p[0], "ifconfig-pool-persist") && p[1] && !p[3])
6934     {
6935         VERIFY_PERMISSION(OPT_P_GENERAL);
6936         options->ifconfig_pool_persist_filename = p[1];
6937         if (p[2])
6938         {
6939             options->ifconfig_pool_persist_refresh_freq = positive_atoi(p[2]);
6940         }
6941     }
6942     else if (streq(p[0], "ifconfig-ipv6-pool") && p[1] && !p[2])
6943     {
6944         const int lev = M_WARN;
6945         struct in6_addr network;
6946         unsigned int netbits = 0;
6947 
6948         VERIFY_PERMISSION(OPT_P_GENERAL);
6949         if (!get_ipv6_addr(p[1], &network, &netbits, lev ) )
6950         {
6951             msg(msglevel, "error parsing --ifconfig-ipv6-pool parameters");
6952             goto err;
6953         }
6954         if (netbits < 64 || netbits > 124)
6955         {
6956             msg(msglevel,
6957                 "--ifconfig-ipv6-pool settings: network must be between /64 and /124 (not /%d)",
6958                 netbits);
6959             goto err;
6960         }
6961 
6962         options->ifconfig_ipv6_pool_defined = true;
6963         options->ifconfig_ipv6_pool_base = network;
6964         options->ifconfig_ipv6_pool_netbits = netbits;
6965     }
6966     else if (streq(p[0], "hash-size") && p[1] && p[2] && !p[3])
6967     {
6968         int real, virtual;
6969 
6970         VERIFY_PERMISSION(OPT_P_GENERAL);
6971         real = atoi(p[1]);
6972         virtual = atoi(p[2]);
6973         if (real < 1 || virtual < 1)
6974         {
6975             msg(msglevel, "--hash-size sizes must be >= 1 (preferably a power of 2)");
6976             goto err;
6977         }
6978         options->real_hash_size = real;
6979         options->virtual_hash_size = real;
6980     }
6981     else if (streq(p[0], "connect-freq") && p[1] && p[2] && !p[3])
6982     {
6983         int cf_max, cf_per;
6984 
6985         VERIFY_PERMISSION(OPT_P_GENERAL);
6986         cf_max = atoi(p[1]);
6987         cf_per = atoi(p[2]);
6988         if (cf_max < 0 || cf_per < 0)
6989         {
6990             msg(msglevel, "--connect-freq parms must be > 0");
6991             goto err;
6992         }
6993         options->cf_max = cf_max;
6994         options->cf_per = cf_per;
6995     }
6996     else if (streq(p[0], "max-clients") && p[1] && !p[2])
6997     {
6998         int max_clients;
6999 
7000         VERIFY_PERMISSION(OPT_P_GENERAL);
7001         max_clients = atoi(p[1]);
7002         if (max_clients < 0)
7003         {
7004             msg(msglevel, "--max-clients must be at least 1");
7005             goto err;
7006         }
7007         if (max_clients >= MAX_PEER_ID) /* max peer-id value */
7008         {
7009             msg(msglevel, "--max-clients must be less than %d", MAX_PEER_ID);
7010             goto err;
7011         }
7012         options->max_clients = max_clients;
7013     }
7014     else if (streq(p[0], "max-routes-per-client") && p[1] && !p[2])
7015     {
7016         VERIFY_PERMISSION(OPT_P_INHERIT);
7017         options->max_routes_per_client = max_int(atoi(p[1]), 1);
7018     }
7019     else if (streq(p[0], "client-cert-not-required") && !p[1])
7020     {
7021         VERIFY_PERMISSION(OPT_P_GENERAL);
7022         msg(M_FATAL, "REMOVED OPTION: --client-cert-not-required, use '--verify-client-cert none' instead");
7023     }
7024     else if (streq(p[0], "verify-client-cert") && !p[2])
7025     {
7026         VERIFY_PERMISSION(OPT_P_GENERAL);
7027 
7028         /* Reset any existing flags */
7029         options->ssl_flags &= ~SSLF_CLIENT_CERT_OPTIONAL;
7030         options->ssl_flags &= ~SSLF_CLIENT_CERT_NOT_REQUIRED;
7031         if (p[1])
7032         {
7033             if (streq(p[1], "none"))
7034             {
7035                 options->ssl_flags |= SSLF_CLIENT_CERT_NOT_REQUIRED;
7036             }
7037             else if (streq(p[1], "optional"))
7038             {
7039                 options->ssl_flags |= SSLF_CLIENT_CERT_OPTIONAL;
7040             }
7041             else if (!streq(p[1], "require"))
7042             {
7043                 msg(msglevel, "parameter to --verify-client-cert must be 'none', 'optional' or 'require'");
7044                 goto err;
7045             }
7046         }
7047     }
7048     else if (streq(p[0], "username-as-common-name") && !p[1])
7049     {
7050         VERIFY_PERMISSION(OPT_P_GENERAL);
7051         options->ssl_flags |= SSLF_USERNAME_AS_COMMON_NAME;
7052     }
7053     else if (streq(p[0], "auth-user-pass-optional") && !p[1])
7054     {
7055         VERIFY_PERMISSION(OPT_P_GENERAL);
7056         options->ssl_flags |= SSLF_AUTH_USER_PASS_OPTIONAL;
7057     }
7058     else if (streq(p[0], "opt-verify") && !p[1])
7059     {
7060         VERIFY_PERMISSION(OPT_P_GENERAL);
7061         options->ssl_flags |= SSLF_OPT_VERIFY;
7062     }
7063     else if (streq(p[0], "auth-user-pass-verify") && p[1])
7064     {
7065         VERIFY_PERMISSION(OPT_P_SCRIPT);
7066         if (!no_more_than_n_args(msglevel, p, 3, NM_QUOTE_HINT))
7067         {
7068             goto err;
7069         }
7070         if (p[2])
7071         {
7072             if (streq(p[2], "via-env"))
7073             {
7074                 options->auth_user_pass_verify_script_via_file = false;
7075             }
7076             else if (streq(p[2], "via-file"))
7077             {
7078                 options->auth_user_pass_verify_script_via_file = true;
7079             }
7080             else
7081             {
7082                 msg(msglevel, "second parm to --auth-user-pass-verify must be 'via-env' or 'via-file'");
7083                 goto err;
7084             }
7085         }
7086         else
7087         {
7088             msg(msglevel, "--auth-user-pass-verify requires a second parameter ('via-env' or 'via-file')");
7089             goto err;
7090         }
7091         set_user_script(options,
7092                         &options->auth_user_pass_verify_script,
7093                         p[1], "auth-user-pass-verify", true);
7094     }
7095     else if (streq(p[0], "auth-gen-token") && !p[3])
7096     {
7097         VERIFY_PERMISSION(OPT_P_GENERAL);
7098         options->auth_token_generate = true;
7099         options->auth_token_lifetime = p[1] ? positive_atoi(p[1]) : 0;
7100         if (p[2])
7101         {
7102             if (streq(p[2], "external-auth"))
7103             {
7104                 options->auth_token_call_auth = true;
7105             }
7106             else
7107             {
7108                 msg(msglevel, "Invalid argument to auth-gen-token: %s", p[2]);
7109             }
7110         }
7111 
7112     }
7113     else if (streq(p[0], "auth-gen-token-secret") && p[1] && !p[2])
7114     {
7115         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INLINE);
7116         options->auth_token_secret_file = p[1];
7117         options->auth_token_secret_file_inline = is_inline;
7118 
7119     }
7120     else if (streq(p[0], "client-connect") && p[1])
7121     {
7122         VERIFY_PERMISSION(OPT_P_SCRIPT);
7123         if (!no_more_than_n_args(msglevel, p, 2, NM_QUOTE_HINT))
7124         {
7125             goto err;
7126         }
7127         set_user_script(options, &options->client_connect_script,
7128                         p[1], "client-connect", true);
7129     }
7130     else if (streq(p[0], "client-disconnect") && p[1])
7131     {
7132         VERIFY_PERMISSION(OPT_P_SCRIPT);
7133         if (!no_more_than_n_args(msglevel, p, 2, NM_QUOTE_HINT))
7134         {
7135             goto err;
7136         }
7137         set_user_script(options, &options->client_disconnect_script,
7138                         p[1], "client-disconnect", true);
7139     }
7140     else if (streq(p[0], "learn-address") && p[1])
7141     {
7142         VERIFY_PERMISSION(OPT_P_SCRIPT);
7143         if (!no_more_than_n_args(msglevel, p, 2, NM_QUOTE_HINT))
7144         {
7145             goto err;
7146         }
7147         set_user_script(options, &options->learn_address_script,
7148                         p[1], "learn-address", true);
7149     }
7150     else if (streq(p[0], "tmp-dir") && p[1] && !p[2])
7151     {
7152         VERIFY_PERMISSION(OPT_P_GENERAL);
7153         options->tmp_dir = p[1];
7154     }
7155     else if (streq(p[0], "client-config-dir") && p[1] && !p[2])
7156     {
7157         VERIFY_PERMISSION(OPT_P_GENERAL);
7158         options->client_config_dir = p[1];
7159     }
7160     else if (streq(p[0], "ccd-exclusive") && !p[1])
7161     {
7162         VERIFY_PERMISSION(OPT_P_GENERAL);
7163         options->ccd_exclusive = true;
7164     }
7165     else if (streq(p[0], "bcast-buffers") && p[1] && !p[2])
7166     {
7167         int n_bcast_buf;
7168 
7169         VERIFY_PERMISSION(OPT_P_GENERAL);
7170         n_bcast_buf = atoi(p[1]);
7171         if (n_bcast_buf < 1)
7172         {
7173             msg(msglevel, "--bcast-buffers parameter must be > 0");
7174         }
7175         options->n_bcast_buf = n_bcast_buf;
7176     }
7177     else if (streq(p[0], "tcp-queue-limit") && p[1] && !p[2])
7178     {
7179         int tcp_queue_limit;
7180 
7181         VERIFY_PERMISSION(OPT_P_GENERAL);
7182         tcp_queue_limit = atoi(p[1]);
7183         if (tcp_queue_limit < 1)
7184         {
7185             msg(msglevel, "--tcp-queue-limit parameter must be > 0");
7186         }
7187         options->tcp_queue_limit = tcp_queue_limit;
7188     }
7189 #if PORT_SHARE
7190     else if (streq(p[0], "port-share") && p[1] && p[2] && !p[4])
7191     {
7192         VERIFY_PERMISSION(OPT_P_GENERAL);
7193         options->port_share_host = p[1];
7194         options->port_share_port = p[2];
7195         options->port_share_journal_dir = p[3];
7196     }
7197 #endif
7198     else if (streq(p[0], "client-to-client") && !p[1])
7199     {
7200         VERIFY_PERMISSION(OPT_P_GENERAL);
7201         options->enable_c2c = true;
7202     }
7203     else if (streq(p[0], "duplicate-cn") && !p[1])
7204     {
7205         VERIFY_PERMISSION(OPT_P_GENERAL);
7206         options->duplicate_cn = true;
7207     }
7208     else if (streq(p[0], "iroute") && p[1] && !p[3])
7209     {
7210         const char *netmask = NULL;
7211 
7212         VERIFY_PERMISSION(OPT_P_INSTANCE);
7213         if (p[2])
7214         {
7215             netmask = p[2];
7216         }
7217         option_iroute(options, p[1], netmask, msglevel);
7218     }
7219     else if (streq(p[0], "iroute-ipv6") && p[1] && !p[2])
7220     {
7221         VERIFY_PERMISSION(OPT_P_INSTANCE);
7222         option_iroute_ipv6(options, p[1], msglevel);
7223     }
7224     else if (streq(p[0], "ifconfig-push") && p[1] && p[2] && !p[4])
7225     {
7226         in_addr_t local, remote_netmask;
7227 
7228         VERIFY_PERMISSION(OPT_P_INSTANCE);
7229         local = getaddr(GETADDR_HOST_ORDER|GETADDR_RESOLVE, p[1], 0, NULL, NULL);
7230         remote_netmask = getaddr(GETADDR_HOST_ORDER|GETADDR_RESOLVE, p[2], 0, NULL, NULL);
7231         if (local && remote_netmask)
7232         {
7233             options->push_ifconfig_defined = true;
7234             options->push_ifconfig_local = local;
7235             options->push_ifconfig_remote_netmask = remote_netmask;
7236             if (p[3])
7237             {
7238                 options->push_ifconfig_local_alias = getaddr(GETADDR_HOST_ORDER|GETADDR_RESOLVE, p[3], 0, NULL, NULL);
7239             }
7240         }
7241         else
7242         {
7243             msg(msglevel, "cannot parse --ifconfig-push addresses");
7244             goto err;
7245         }
7246     }
7247     else if (streq(p[0], "ifconfig-push-constraint") && p[1] && p[2] && !p[3])
7248     {
7249         in_addr_t network, netmask;
7250 
7251         VERIFY_PERMISSION(OPT_P_GENERAL);
7252         network = getaddr(GETADDR_HOST_ORDER|GETADDR_RESOLVE, p[1], 0, NULL, NULL);
7253         netmask = getaddr(GETADDR_HOST_ORDER, p[2], 0, NULL, NULL);
7254         if (network && netmask)
7255         {
7256             options->push_ifconfig_constraint_defined = true;
7257             options->push_ifconfig_constraint_network = network;
7258             options->push_ifconfig_constraint_netmask = netmask;
7259         }
7260         else
7261         {
7262             msg(msglevel, "cannot parse --ifconfig-push-constraint addresses");
7263             goto err;
7264         }
7265     }
7266     else if (streq(p[0], "ifconfig-ipv6-push") && p[1] && !p[3])
7267     {
7268         struct in6_addr local, remote;
7269         unsigned int netbits;
7270 
7271         VERIFY_PERMISSION(OPT_P_INSTANCE);
7272 
7273         if (!get_ipv6_addr( p[1], &local, &netbits, msglevel ) )
7274         {
7275             msg(msglevel, "cannot parse --ifconfig-ipv6-push addresses");
7276             goto err;
7277         }
7278 
7279         if (p[2])
7280         {
7281             if (!get_ipv6_addr( p[2], &remote, NULL, msglevel ) )
7282             {
7283                 msg( msglevel, "cannot parse --ifconfig-ipv6-push addresses");
7284                 goto err;
7285             }
7286         }
7287         else
7288         {
7289             if (!options->ifconfig_ipv6_local
7290                 || !get_ipv6_addr( options->ifconfig_ipv6_local, &remote,
7291                                    NULL, msglevel ) )
7292             {
7293                 msg( msglevel, "second argument to --ifconfig-ipv6-push missing and no global --ifconfig-ipv6 address set");
7294                 goto err;
7295             }
7296         }
7297 
7298         options->push_ifconfig_ipv6_defined = true;
7299         options->push_ifconfig_ipv6_local = local;
7300         options->push_ifconfig_ipv6_netbits = netbits;
7301         options->push_ifconfig_ipv6_remote = remote;
7302         options->push_ifconfig_ipv6_blocked = false;
7303     }
7304     else if (streq(p[0], "disable") && !p[1])
7305     {
7306         VERIFY_PERMISSION(OPT_P_INSTANCE);
7307         options->disable = true;
7308     }
7309     else if (streq(p[0], "tcp-nodelay") && !p[1])
7310     {
7311         VERIFY_PERMISSION(OPT_P_GENERAL);
7312         options->server_flags |= SF_TCP_NODELAY_HELPER;
7313     }
7314     else if (streq(p[0], "stale-routes-check") && p[1] && !p[3])
7315     {
7316         int ageing_time, check_interval;
7317 
7318         VERIFY_PERMISSION(OPT_P_GENERAL);
7319         ageing_time = atoi(p[1]);
7320         if (p[2])
7321         {
7322             check_interval = atoi(p[2]);
7323         }
7324         else
7325         {
7326             check_interval = ageing_time;
7327         }
7328 
7329         if (ageing_time < 1 || check_interval < 1)
7330         {
7331             msg(msglevel, "--stale-routes-check aging time and check interval must be >= 1");
7332             goto err;
7333         }
7334         options->stale_routes_ageing_time  = ageing_time;
7335         options->stale_routes_check_interval = check_interval;
7336     }
7337 
7338     else if (streq(p[0], "client") && !p[1])
7339     {
7340         VERIFY_PERMISSION(OPT_P_GENERAL);
7341         options->client = true;
7342     }
7343     else if (streq(p[0], "pull") && !p[1])
7344     {
7345         VERIFY_PERMISSION(OPT_P_GENERAL);
7346         options->pull = true;
7347     }
7348     else if (streq(p[0], "push-continuation") && p[1] && !p[2])
7349     {
7350         VERIFY_PERMISSION(OPT_P_PULL_MODE);
7351         options->push_continuation = atoi(p[1]);
7352     }
7353     else if (streq(p[0], "auth-user-pass") && !p[2])
7354     {
7355         VERIFY_PERMISSION(OPT_P_GENERAL);
7356         if (p[1])
7357         {
7358             options->auth_user_pass_file = p[1];
7359         }
7360         else
7361         {
7362             options->auth_user_pass_file = "stdin";
7363         }
7364     }
7365     else if (streq(p[0], "auth-retry") && p[1] && !p[2])
7366     {
7367         VERIFY_PERMISSION(OPT_P_GENERAL);
7368         auth_retry_set(msglevel, p[1]);
7369     }
7370 #ifdef ENABLE_MANAGEMENT
7371     else if (streq(p[0], "static-challenge") && p[1] && p[2] && !p[3])
7372     {
7373         VERIFY_PERMISSION(OPT_P_GENERAL);
7374         options->sc_info.challenge_text = p[1];
7375         if (atoi(p[2]))
7376         {
7377             options->sc_info.flags |= SC_ECHO;
7378         }
7379     }
7380 #endif
7381 #endif /* if P2MP */
7382     else if (streq(p[0], "msg-channel") && p[1])
7383     {
7384 #ifdef _WIN32
7385         VERIFY_PERMISSION(OPT_P_GENERAL);
7386         HANDLE process = GetCurrentProcess();
7387         HANDLE handle = (HANDLE) atoll(p[1]);
7388         if (!DuplicateHandle(process, handle, process, &options->msg_channel, 0,
7389                              FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
7390         {
7391             msg(msglevel, "could not duplicate service pipe handle");
7392             goto err;
7393         }
7394         options->route_method = ROUTE_METHOD_SERVICE;
7395 #else  /* ifdef _WIN32 */
7396         msg(msglevel, "--msg-channel is only supported on Windows");
7397         goto err;
7398 #endif
7399     }
7400 #ifdef _WIN32
7401     else if (streq(p[0], "win-sys") && p[1] && !p[2])
7402     {
7403         VERIFY_PERMISSION(OPT_P_GENERAL);
7404         if (streq(p[1], "env"))
7405         {
7406             msg(M_INFO, "NOTE: --win-sys env is default from OpenVPN 2.3.	 "
7407                 "This entry will now be ignored.  "
7408                 "Please remove this entry from your configuration file.");
7409         }
7410         else
7411         {
7412             set_win_sys_path(p[1], es);
7413         }
7414     }
7415     else if (streq(p[0], "route-method") && p[1] && !p[2])
7416     {
7417         VERIFY_PERMISSION(OPT_P_ROUTE_EXTRAS);
7418         if (streq(p[1], "adaptive"))
7419         {
7420             options->route_method = ROUTE_METHOD_ADAPTIVE;
7421         }
7422         else if (streq(p[1], "ipapi"))
7423         {
7424             options->route_method = ROUTE_METHOD_IPAPI;
7425         }
7426         else if (streq(p[1], "exe"))
7427         {
7428             options->route_method = ROUTE_METHOD_EXE;
7429         }
7430         else
7431         {
7432             msg(msglevel, "--route method must be 'adaptive', 'ipapi', or 'exe'");
7433             goto err;
7434         }
7435     }
7436     else if (streq(p[0], "ip-win32") && p[1] && !p[4])
7437     {
7438         const int index = ascii2ipset(p[1]);
7439         struct tuntap_options *to = &options->tuntap_options;
7440 
7441         VERIFY_PERMISSION(OPT_P_IPWIN32);
7442 
7443         if (index < 0)
7444         {
7445             msg(msglevel,
7446                 "Bad --ip-win32 method: '%s'.  Allowed methods: %s",
7447                 p[1],
7448                 ipset2ascii_all(&gc));
7449             goto err;
7450         }
7451 
7452         if (index == IPW32_SET_ADAPTIVE)
7453         {
7454             options->route_delay_window = IPW32_SET_ADAPTIVE_DELAY_WINDOW;
7455         }
7456 
7457         if (index == IPW32_SET_DHCP_MASQ)
7458         {
7459             if (p[2])
7460             {
7461                 if (!streq(p[2], "default"))
7462                 {
7463                     int offset = atoi(p[2]);
7464 
7465                     if (!(offset > -256 && offset < 256))
7466                     {
7467                         msg(msglevel, "--ip-win32 dynamic [offset] [lease-time]: offset (%d) must be > -256 and < 256", offset);
7468                         goto err;
7469                     }
7470 
7471                     to->dhcp_masq_custom_offset = true;
7472                     to->dhcp_masq_offset = offset;
7473                 }
7474 
7475                 if (p[3])
7476                 {
7477                     const int min_lease = 30;
7478                     int lease_time;
7479                     lease_time = atoi(p[3]);
7480                     if (lease_time < min_lease)
7481                     {
7482                         msg(msglevel, "--ip-win32 dynamic [offset] [lease-time]: lease time parameter (%d) must be at least %d seconds", lease_time, min_lease);
7483                         goto err;
7484                     }
7485                     to->dhcp_lease_time = lease_time;
7486                 }
7487             }
7488         }
7489         to->ip_win32_type = index;
7490         to->ip_win32_defined = true;
7491     }
7492 #endif /* ifdef _WIN32 */
7493 #if defined(_WIN32) || defined(TARGET_ANDROID)
7494     else if (streq(p[0], "dhcp-option") && p[1] && !p[3])
7495     {
7496         struct tuntap_options *o = &options->tuntap_options;
7497         VERIFY_PERMISSION(OPT_P_IPWIN32);
7498         bool ipv6dns = false;
7499 
7500         if ((streq(p[1], "DOMAIN") || streq(p[1], "ADAPTER_DOMAIN_SUFFIX"))
7501             && p[2])
7502         {
7503             o->domain = p[2];
7504         }
7505         else if (streq(p[1], "NBS") && p[2])
7506         {
7507             o->netbios_scope = p[2];
7508         }
7509         else if (streq(p[1], "NBT") && p[2])
7510         {
7511             int t;
7512             t = atoi(p[2]);
7513             if (!(t == 1 || t == 2 || t == 4 || t == 8))
7514             {
7515                 msg(msglevel, "--dhcp-option NBT: parameter (%d) must be 1, 2, 4, or 8", t);
7516                 goto err;
7517             }
7518             o->netbios_node_type = t;
7519         }
7520         else if ((streq(p[1], "DNS") || streq(p[1], "DNS6")) && p[2] && (!strstr(p[2], ":") || ipv6_addr_safe(p[2])))
7521         {
7522             if (strstr(p[2], ":"))
7523             {
7524                 ipv6dns = true;
7525                 foreign_option(options, p, 3, es);
7526                 dhcp_option_dns6_parse(p[2], o->dns6, &o->dns6_len, msglevel);
7527             }
7528             else
7529             {
7530                 dhcp_option_address_parse("DNS", p[2], o->dns, &o->dns_len, msglevel);
7531             }
7532         }
7533         else if (streq(p[1], "WINS") && p[2])
7534         {
7535             dhcp_option_address_parse("WINS", p[2], o->wins, &o->wins_len, msglevel);
7536         }
7537         else if (streq(p[1], "NTP") && p[2])
7538         {
7539             dhcp_option_address_parse("NTP", p[2], o->ntp, &o->ntp_len, msglevel);
7540         }
7541         else if (streq(p[1], "NBDD") && p[2])
7542         {
7543             dhcp_option_address_parse("NBDD", p[2], o->nbdd, &o->nbdd_len, msglevel);
7544         }
7545         else if (streq(p[1], "DOMAIN-SEARCH") && p[2])
7546         {
7547             if (o->domain_search_list_len < N_SEARCH_LIST_LEN)
7548             {
7549                 o->domain_search_list[o->domain_search_list_len++] = p[2];
7550             }
7551             else
7552             {
7553                 msg(msglevel, "--dhcp-option %s: maximum of %d search entries can be specified",
7554                     p[1], N_SEARCH_LIST_LEN);
7555             }
7556         }
7557         else if (streq(p[1], "DISABLE-NBT") && !p[2])
7558         {
7559             o->disable_nbt = 1;
7560         }
7561         else
7562         {
7563             msg(msglevel, "--dhcp-option: unknown option type '%s' or missing or unknown parameter", p[1]);
7564             goto err;
7565         }
7566 
7567         /* flag that we have options to give to the TAP driver's DHCPv4 server
7568          *  - skipped for "DNS6", as that's not a DHCPv4 option
7569          */
7570         if (!ipv6dns)
7571         {
7572             o->dhcp_options = true;
7573         }
7574     }
7575 #endif /* if defined(_WIN32) || defined(TARGET_ANDROID) */
7576 #ifdef _WIN32
7577     else if (streq(p[0], "show-adapters") && !p[1])
7578     {
7579         VERIFY_PERMISSION(OPT_P_GENERAL);
7580         show_tap_win_adapters(M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX);
7581         openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
7582     }
7583     else if (streq(p[0], "show-net") && !p[1])
7584     {
7585         VERIFY_PERMISSION(OPT_P_GENERAL);
7586         show_routes(M_INFO|M_NOPREFIX);
7587         show_adapters(M_INFO|M_NOPREFIX);
7588         openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
7589     }
7590     else if (streq(p[0], "show-net-up") && !p[1])
7591     {
7592         VERIFY_PERMISSION(OPT_P_UP);
7593         options->show_net_up = true;
7594     }
7595     else if (streq(p[0], "tap-sleep") && p[1] && !p[2])
7596     {
7597         int s;
7598         VERIFY_PERMISSION(OPT_P_IPWIN32);
7599         s = atoi(p[1]);
7600         if (s < 0 || s >= 256)
7601         {
7602             msg(msglevel, "--tap-sleep parameter must be between 0 and 255");
7603             goto err;
7604         }
7605         options->tuntap_options.tap_sleep = s;
7606     }
7607     else if (streq(p[0], "dhcp-renew") && !p[1])
7608     {
7609         VERIFY_PERMISSION(OPT_P_IPWIN32);
7610         options->tuntap_options.dhcp_renew = true;
7611     }
7612     else if (streq(p[0], "dhcp-pre-release") && !p[1])
7613     {
7614         VERIFY_PERMISSION(OPT_P_IPWIN32);
7615         options->tuntap_options.dhcp_pre_release = true;
7616         options->tuntap_options.dhcp_renew = true;
7617     }
7618     else if (streq(p[0], "dhcp-release") && !p[1])
7619     {
7620         msg(M_WARN, "Obsolete option --dhcp-release detected. This is now on by default");
7621     }
7622     else if (streq(p[0], "dhcp-internal") && p[1] && !p[2]) /* standalone method for internal use */
7623     {
7624         unsigned int adapter_index;
7625         VERIFY_PERMISSION(OPT_P_GENERAL);
7626         set_debug_level(options->verbosity, SDL_CONSTRAIN);
7627         adapter_index = atou(p[1]);
7628         sleep(options->tuntap_options.tap_sleep);
7629         if (options->tuntap_options.dhcp_pre_release)
7630         {
7631             dhcp_release_by_adapter_index(adapter_index);
7632         }
7633         if (options->tuntap_options.dhcp_renew)
7634         {
7635             dhcp_renew_by_adapter_index(adapter_index);
7636         }
7637         openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
7638     }
7639     else if (streq(p[0], "register-dns") && !p[1])
7640     {
7641         VERIFY_PERMISSION(OPT_P_IPWIN32);
7642         options->tuntap_options.register_dns = true;
7643     }
7644     else if (streq(p[0], "block-outside-dns") && !p[1])
7645     {
7646         VERIFY_PERMISSION(OPT_P_IPWIN32);
7647         options->block_outside_dns = true;
7648     }
7649     else if (streq(p[0], "rdns-internal") && !p[1])
7650     /* standalone method for internal use
7651      *
7652      * (if --register-dns is set, openvpn needs to call itself in a
7653      *  sub-process to execute the required functions in a non-blocking
7654      *  way, and uses --rdns-internal to signal that to itself)
7655      */
7656     {
7657         VERIFY_PERMISSION(OPT_P_GENERAL);
7658         set_debug_level(options->verbosity, SDL_CONSTRAIN);
7659         if (options->tuntap_options.register_dns)
7660         {
7661             ipconfig_register_dns(NULL);
7662         }
7663         openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
7664     }
7665     else if (streq(p[0], "show-valid-subnets") && !p[1])
7666     {
7667         VERIFY_PERMISSION(OPT_P_GENERAL);
7668         show_valid_win32_tun_subnets();
7669         openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
7670     }
7671     else if (streq(p[0], "pause-exit") && !p[1])
7672     {
7673         VERIFY_PERMISSION(OPT_P_GENERAL);
7674         set_pause_exit_win32();
7675     }
7676     else if (streq(p[0], "service") && p[1] && !p[3])
7677     {
7678         VERIFY_PERMISSION(OPT_P_GENERAL);
7679         options->exit_event_name = p[1];
7680         if (p[2])
7681         {
7682             options->exit_event_initial_state = (atoi(p[2]) != 0);
7683         }
7684     }
7685     else if (streq(p[0], "allow-nonadmin") && !p[2])
7686     {
7687         VERIFY_PERMISSION(OPT_P_GENERAL);
7688         tap_allow_nonadmin_access(p[1]);
7689         openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
7690     }
7691     else if (streq(p[0], "user") && p[1] && !p[2])
7692     {
7693         VERIFY_PERMISSION(OPT_P_GENERAL);
7694         msg(M_WARN, "NOTE: --user option is not implemented on Windows");
7695     }
7696     else if (streq(p[0], "group") && p[1] && !p[2])
7697     {
7698         VERIFY_PERMISSION(OPT_P_GENERAL);
7699         msg(M_WARN, "NOTE: --group option is not implemented on Windows");
7700     }
7701 #else  /* ifdef _WIN32 */
7702     else if (streq(p[0], "user") && p[1] && !p[2])
7703     {
7704         VERIFY_PERMISSION(OPT_P_GENERAL);
7705         options->username = p[1];
7706     }
7707     else if (streq(p[0], "group") && p[1] && !p[2])
7708     {
7709         VERIFY_PERMISSION(OPT_P_GENERAL);
7710         options->groupname = p[1];
7711     }
7712     else if (streq(p[0], "dhcp-option") && p[1] && !p[3])
7713     {
7714         VERIFY_PERMISSION(OPT_P_IPWIN32);
7715         foreign_option(options, p, 3, es);
7716     }
7717     else if (streq(p[0], "route-method") && p[1] && !p[2]) /* ignore when pushed to non-Windows OS */
7718     {
7719         VERIFY_PERMISSION(OPT_P_ROUTE_EXTRAS);
7720     }
7721 #endif /* ifdef _WIN32 */
7722 #if PASSTOS_CAPABILITY
7723     else if (streq(p[0], "passtos") && !p[1])
7724     {
7725         VERIFY_PERMISSION(OPT_P_GENERAL);
7726         options->passtos = true;
7727     }
7728 #endif
7729 #if defined(USE_COMP)
7730     else if (streq(p[0], "allow-compression") && p[1] && !p[2])
7731     {
7732         VERIFY_PERMISSION(OPT_P_GENERAL);
7733 
7734         if (streq(p[1], "no"))
7735         {
7736             options->comp.flags =
7737                 COMP_F_ALLOW_STUB_ONLY|COMP_F_ADVERTISE_STUBS_ONLY;
7738             if (comp_non_stub_enabled(&options->comp))
7739             {
7740                 msg(msglevel, "'--allow-compression no' conflicts with "
7741                     " enabling compression");
7742             }
7743         }
7744         else if (options->comp.flags & COMP_F_ALLOW_STUB_ONLY)
7745         {
7746             /* Also printed on a push to hint at configuration problems */
7747             msg(msglevel, "Cannot set allow-compression to '%s' "
7748                 "after set to 'no'", p[1]);
7749             goto err;
7750         }
7751         else if (streq(p[1], "asym"))
7752         {
7753             options->comp.flags &= ~COMP_F_ALLOW_COMPRESS;
7754         }
7755         else if (streq(p[1], "yes"))
7756         {
7757             msg(M_WARN, "WARNING: Compression for sending and receiving enabled. Compression has "
7758                 "been used in the past to break encryption. Allowing compression allows "
7759                 "attacks that break encryption. Using \"--allow-compression yes\" is "
7760                 "strongly discouraged for common usage. See --compress in the manual "
7761                 "page for more information ");
7762 
7763             options->comp.flags |= COMP_F_ALLOW_COMPRESS;
7764         }
7765         else
7766         {
7767             msg(msglevel, "bad allow-compression option: %s -- "
7768                 "must be 'yes', 'no', or 'asym'", p[1]);
7769             goto err;
7770         }
7771     }
7772     else if (streq(p[0], "comp-lzo") && !p[2])
7773     {
7774         VERIFY_PERMISSION(OPT_P_COMP);
7775 
7776         /* All lzo variants do not use swap */
7777         options->comp.flags &= ~COMP_F_SWAP;
7778 #if defined(ENABLE_LZO)
7779         if (p[1] && streq(p[1], "no"))
7780 #endif
7781         {
7782             options->comp.alg = COMP_ALG_STUB;
7783             options->comp.flags &= ~COMP_F_ADAPTIVE;
7784         }
7785 #if defined(ENABLE_LZO)
7786         else if (options->comp.flags & COMP_F_ALLOW_STUB_ONLY)
7787         {
7788             /* Also printed on a push to hint at configuration problems */
7789             msg(msglevel, "Cannot set comp-lzo to '%s', "
7790                 "allow-compression is set to 'no'", p[1]);
7791             goto err;
7792         }
7793         else if (p[1])
7794         {
7795             if (streq(p[1], "yes"))
7796             {
7797                 options->comp.alg = COMP_ALG_LZO;
7798                 options->comp.flags &= ~COMP_F_ADAPTIVE;
7799             }
7800             else if (streq(p[1], "adaptive"))
7801             {
7802                 options->comp.alg = COMP_ALG_LZO;
7803                 options->comp.flags |= COMP_F_ADAPTIVE;
7804             }
7805             else
7806             {
7807                 msg(msglevel, "bad comp-lzo option: %s -- must be 'yes', 'no', or 'adaptive'", p[1]);
7808                 goto err;
7809             }
7810         }
7811         else
7812         {
7813             options->comp.alg = COMP_ALG_LZO;
7814             options->comp.flags |= COMP_F_ADAPTIVE;
7815         }
7816         show_compression_warning(&options->comp);
7817 #endif /* if defined(ENABLE_LZO) */
7818     }
7819     else if (streq(p[0], "comp-noadapt") && !p[1])
7820     {
7821         /*
7822          * We do not need to check here if we allow compression since
7823          * it only modifies a flag if compression is enabled
7824          */
7825         VERIFY_PERMISSION(OPT_P_COMP);
7826         options->comp.flags &= ~COMP_F_ADAPTIVE;
7827     }
7828     else if (streq(p[0], "compress") && !p[2])
7829     {
7830         VERIFY_PERMISSION(OPT_P_COMP);
7831         if (p[1])
7832         {
7833             if (streq(p[1], "stub"))
7834             {
7835                 options->comp.alg = COMP_ALG_STUB;
7836                 options->comp.flags |= (COMP_F_SWAP|COMP_F_ADVERTISE_STUBS_ONLY);
7837             }
7838             else if (streq(p[1], "stub-v2"))
7839             {
7840                 options->comp.alg = COMP_ALGV2_UNCOMPRESSED;
7841                 options->comp.flags |= COMP_F_ADVERTISE_STUBS_ONLY;
7842             }
7843             else if (options->comp.flags & COMP_F_ALLOW_STUB_ONLY)
7844             {
7845                 /* Also printed on a push to hint at configuration problems */
7846                 msg(msglevel, "Cannot set compress to '%s', "
7847                     "allow-compression is set to 'no'", p[1]);
7848                 goto err;
7849             }
7850 #if defined(ENABLE_LZO)
7851             else if (streq(p[1], "lzo"))
7852             {
7853                 options->comp.alg = COMP_ALG_LZO;
7854                 options->comp.flags &= ~(COMP_F_ADAPTIVE | COMP_F_SWAP);
7855             }
7856 #endif
7857 #if defined(ENABLE_LZ4)
7858             else if (streq(p[1], "lz4"))
7859             {
7860                 options->comp.alg = COMP_ALG_LZ4;
7861                 options->comp.flags |= COMP_F_SWAP;
7862             }
7863             else if (streq(p[1], "lz4-v2"))
7864             {
7865                 options->comp.alg = COMP_ALGV2_LZ4;
7866             }
7867 #endif
7868             else
7869             {
7870                 msg(msglevel, "bad comp option: %s", p[1]);
7871                 goto err;
7872             }
7873         }
7874         else
7875         {
7876             options->comp.alg = COMP_ALG_STUB;
7877             options->comp.flags |= COMP_F_SWAP;
7878         }
7879         show_compression_warning(&options->comp);
7880     }
7881 #endif /* USE_COMP */
7882     else if (streq(p[0], "show-ciphers") && !p[1])
7883     {
7884         VERIFY_PERMISSION(OPT_P_GENERAL);
7885         options->show_ciphers = true;
7886     }
7887     else if (streq(p[0], "show-digests") && !p[1])
7888     {
7889         VERIFY_PERMISSION(OPT_P_GENERAL);
7890         options->show_digests = true;
7891     }
7892     else if (streq(p[0], "show-engines") && !p[1])
7893     {
7894         VERIFY_PERMISSION(OPT_P_GENERAL);
7895         options->show_engines = true;
7896     }
7897     else if (streq(p[0], "key-direction") && p[1] && !p[2])
7898     {
7899         int key_direction;
7900 
7901         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION);
7902 
7903         key_direction = ascii2keydirection(msglevel, p[1]);
7904         if (key_direction >= 0)
7905         {
7906             if (permission_mask & OPT_P_GENERAL)
7907             {
7908                 options->key_direction = key_direction;
7909             }
7910             else if (permission_mask & OPT_P_CONNECTION)
7911             {
7912                 options->ce.key_direction = key_direction;
7913             }
7914         }
7915         else
7916         {
7917             goto err;
7918         }
7919     }
7920     else if (streq(p[0], "secret") && p[1] && !p[3])
7921     {
7922         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INLINE);
7923         options->shared_secret_file = p[1];
7924         options->shared_secret_file_inline = is_inline;
7925         if (!is_inline && p[2])
7926         {
7927             int key_direction;
7928 
7929             key_direction = ascii2keydirection(msglevel, p[2]);
7930             if (key_direction >= 0)
7931             {
7932                 options->key_direction = key_direction;
7933             }
7934             else
7935             {
7936                 goto err;
7937             }
7938         }
7939     }
7940     else if (streq(p[0], "genkey") && !p[4])
7941     {
7942         VERIFY_PERMISSION(OPT_P_GENERAL);
7943         options->genkey = true;
7944         if (!p[1])
7945         {
7946             options->genkey_type = GENKEY_SECRET;
7947         }
7948         else
7949         {
7950             if (streq(p[1], "secret") || streq(p[1], "tls-auth")
7951                 || streq(p[1], "tls-crypt"))
7952             {
7953                 options->genkey_type = GENKEY_SECRET;
7954             }
7955             else if (streq(p[1], "tls-crypt-v2-server"))
7956             {
7957                 options->genkey_type = GENKEY_TLS_CRYPTV2_SERVER;
7958             }
7959             else if (streq(p[1], "tls-crypt-v2-client"))
7960             {
7961                 options->genkey_type = GENKEY_TLS_CRYPTV2_CLIENT;
7962                 if (p[3])
7963                 {
7964                     options->genkey_extra_data = p[3];
7965                 }
7966             }
7967             else if (streq(p[1], "auth-token"))
7968             {
7969                 options->genkey_type = GENKEY_AUTH_TOKEN;
7970             }
7971             else
7972             {
7973                 msg(msglevel, "unknown --genkey type: %s", p[1]);
7974             }
7975 
7976         }
7977         if (p[2])
7978         {
7979             options->genkey_filename = p[2];
7980         }
7981     }
7982     else if (streq(p[0], "auth") && p[1] && !p[2])
7983     {
7984         VERIFY_PERMISSION(OPT_P_GENERAL);
7985         options->authname = p[1];
7986     }
7987     else if (streq(p[0], "cipher") && p[1] && !p[2])
7988     {
7989         VERIFY_PERMISSION(OPT_P_NCP|OPT_P_INSTANCE);
7990         options->ciphername = p[1];
7991     }
7992     else if (streq(p[0], "data-ciphers-fallback") && p[1] && !p[2])
7993     {
7994         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INSTANCE);
7995         options->ciphername = p[1];
7996         options->enable_ncp_fallback = true;
7997     }
7998     else if ((streq(p[0], "data-ciphers") || streq(p[0], "ncp-ciphers"))
7999              && p[1] && !p[2])
8000     {
8001         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INSTANCE);
8002         if (streq(p[0], "ncp-ciphers"))
8003         {
8004             msg(M_INFO, "Note: Treating option '--ncp-ciphers' as "
8005                 " '--data-ciphers' (renamed in OpenVPN 2.5).");
8006         }
8007         options->ncp_ciphers = p[1];
8008     }
8009     else if (streq(p[0], "ncp-disable") && !p[1])
8010     {
8011         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INSTANCE);
8012         options->ncp_enabled = false;
8013         msg(M_WARN, "DEPRECATED OPTION: ncp-disable. Disabling "
8014             "cipher negotiation is a deprecated debug feature that "
8015             "will be removed in OpenVPN 2.6");
8016     }
8017     else if (streq(p[0], "prng") && p[1] && !p[3])
8018     {
8019         VERIFY_PERMISSION(OPT_P_GENERAL);
8020         if (streq(p[1], "none"))
8021         {
8022             options->prng_hash = NULL;
8023         }
8024         else
8025         {
8026             options->prng_hash = p[1];
8027         }
8028         if (p[2])
8029         {
8030             const int sl = atoi(p[2]);
8031             if (sl >= NONCE_SECRET_LEN_MIN && sl <= NONCE_SECRET_LEN_MAX)
8032             {
8033                 options->prng_nonce_secret_len = sl;
8034             }
8035             else
8036             {
8037                 msg(msglevel, "prng parameter nonce_secret_len must be between %d and %d",
8038                     NONCE_SECRET_LEN_MIN, NONCE_SECRET_LEN_MAX);
8039                 goto err;
8040             }
8041         }
8042     }
8043     else if (streq(p[0], "no-replay") && !p[1])
8044     {
8045         VERIFY_PERMISSION(OPT_P_GENERAL);
8046         options->replay = false;
8047     }
8048     else if (streq(p[0], "replay-window") && !p[3])
8049     {
8050         VERIFY_PERMISSION(OPT_P_GENERAL);
8051         if (p[1])
8052         {
8053             int replay_window;
8054 
8055             replay_window = atoi(p[1]);
8056             if (!(MIN_SEQ_BACKTRACK <= replay_window && replay_window <= MAX_SEQ_BACKTRACK))
8057             {
8058                 msg(msglevel, "replay-window window size parameter (%d) must be between %d and %d",
8059                     replay_window,
8060                     MIN_SEQ_BACKTRACK,
8061                     MAX_SEQ_BACKTRACK);
8062                 goto err;
8063             }
8064             options->replay_window = replay_window;
8065 
8066             if (p[2])
8067             {
8068                 int replay_time;
8069 
8070                 replay_time = atoi(p[2]);
8071                 if (!(MIN_TIME_BACKTRACK <= replay_time && replay_time <= MAX_TIME_BACKTRACK))
8072                 {
8073                     msg(msglevel, "replay-window time window parameter (%d) must be between %d and %d",
8074                         replay_time,
8075                         MIN_TIME_BACKTRACK,
8076                         MAX_TIME_BACKTRACK);
8077                     goto err;
8078                 }
8079                 options->replay_time = replay_time;
8080             }
8081         }
8082         else
8083         {
8084             msg(msglevel, "replay-window option is missing window size parameter");
8085             goto err;
8086         }
8087     }
8088     else if (streq(p[0], "mute-replay-warnings") && !p[1])
8089     {
8090         VERIFY_PERMISSION(OPT_P_GENERAL);
8091         options->mute_replay_warnings = true;
8092     }
8093     else if (streq(p[0], "replay-persist") && p[1] && !p[2])
8094     {
8095         VERIFY_PERMISSION(OPT_P_GENERAL);
8096         options->packet_id_file = p[1];
8097     }
8098     else if (streq(p[0], "test-crypto") && !p[1])
8099     {
8100         VERIFY_PERMISSION(OPT_P_GENERAL);
8101         options->test_crypto = true;
8102     }
8103 #ifndef ENABLE_CRYPTO_MBEDTLS
8104     else if (streq(p[0], "engine") && !p[2])
8105     {
8106         VERIFY_PERMISSION(OPT_P_GENERAL);
8107         if (p[1])
8108         {
8109             options->engine = p[1];
8110         }
8111         else
8112         {
8113             options->engine = "auto";
8114         }
8115     }
8116 #endif /* ENABLE_CRYPTO_MBEDTLS */
8117 #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH
8118     else if (streq(p[0], "keysize") && p[1] && !p[2])
8119     {
8120         int keysize;
8121 
8122         VERIFY_PERMISSION(OPT_P_NCP);
8123         keysize = atoi(p[1]) / 8;
8124         if (keysize < 0 || keysize > MAX_CIPHER_KEY_LENGTH)
8125         {
8126             msg(msglevel, "Bad keysize: %s", p[1]);
8127             goto err;
8128         }
8129         options->keysize = keysize;
8130     }
8131 #endif
8132 #ifdef ENABLE_PREDICTION_RESISTANCE
8133     else if (streq(p[0], "use-prediction-resistance") && !p[1])
8134     {
8135         VERIFY_PERMISSION(OPT_P_GENERAL);
8136         options->use_prediction_resistance = true;
8137     }
8138 #endif
8139     else if (streq(p[0], "show-tls") && !p[1])
8140     {
8141         VERIFY_PERMISSION(OPT_P_GENERAL);
8142         options->show_tls_ciphers = true;
8143     }
8144     else if ((streq(p[0], "show-curves") || streq(p[0], "show-groups")) && !p[1])
8145     {
8146         VERIFY_PERMISSION(OPT_P_GENERAL);
8147         options->show_curves = true;
8148     }
8149     else if (streq(p[0], "ecdh-curve") && p[1] && !p[2])
8150     {
8151         VERIFY_PERMISSION(OPT_P_GENERAL);
8152         msg(M_WARN, "Consider setting groups/curves preference with "
8153             "tls-groups instead of forcing a specific curve with "
8154             "ecdh-curve.");
8155         options->ecdh_curve = p[1];
8156     }
8157     else if (streq(p[0], "tls-server") && !p[1])
8158     {
8159         VERIFY_PERMISSION(OPT_P_GENERAL);
8160         options->tls_server = true;
8161     }
8162     else if (streq(p[0], "tls-client") && !p[1])
8163     {
8164         VERIFY_PERMISSION(OPT_P_GENERAL);
8165         options->tls_client = true;
8166     }
8167     else if (streq(p[0], "ca") && p[1] && !p[2])
8168     {
8169         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INLINE);
8170         options->ca_file = p[1];
8171         options->ca_file_inline = is_inline;
8172     }
8173 #ifndef ENABLE_CRYPTO_MBEDTLS
8174     else if (streq(p[0], "capath") && p[1] && !p[2])
8175     {
8176         VERIFY_PERMISSION(OPT_P_GENERAL);
8177         options->ca_path = p[1];
8178     }
8179 #endif /* ENABLE_CRYPTO_MBEDTLS */
8180     else if (streq(p[0], "dh") && p[1] && !p[2])
8181     {
8182         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INLINE);
8183         options->dh_file = p[1];
8184         options->dh_file_inline = is_inline;
8185     }
8186     else if (streq(p[0], "cert") && p[1] && !p[2])
8187     {
8188         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INLINE);
8189         options->cert_file = p[1];
8190         options->cert_file_inline = is_inline;
8191     }
8192     else if (streq(p[0], "extra-certs") && p[1] && !p[2])
8193     {
8194         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INLINE);
8195         options->extra_certs_file = p[1];
8196         options->extra_certs_file_inline = is_inline;
8197     }
8198     else if (streq(p[0], "verify-hash") && p[1] && !p[3])
8199     {
8200         VERIFY_PERMISSION(OPT_P_GENERAL);
8201 
8202         if (!p[2] || (p[2] && streq(p[2], "SHA1")))
8203         {
8204             options->verify_hash = parse_hash_fingerprint(p[1], SHA_DIGEST_LENGTH, msglevel, &options->gc);
8205             options->verify_hash_algo = MD_SHA1;
8206         }
8207         else if (p[2] && streq(p[2], "SHA256"))
8208         {
8209             options->verify_hash = parse_hash_fingerprint(p[1], SHA256_DIGEST_LENGTH, msglevel, &options->gc);
8210             options->verify_hash_algo = MD_SHA256;
8211         }
8212         else
8213         {
8214             msg(msglevel, "invalid or unsupported hashing algorithm: %s  (only SHA1 and SHA256 are valid)", p[2]);
8215             goto err;
8216         }
8217     }
8218 #ifdef ENABLE_CRYPTOAPI
8219     else if (streq(p[0], "cryptoapicert") && p[1] && !p[2])
8220     {
8221         VERIFY_PERMISSION(OPT_P_GENERAL);
8222         options->cryptoapi_cert = p[1];
8223     }
8224 #endif
8225     else if (streq(p[0], "key") && p[1] && !p[2])
8226     {
8227         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INLINE);
8228         options->priv_key_file = p[1];
8229         options->priv_key_file_inline = is_inline;
8230     }
8231     else if (streq(p[0], "tls-version-min") && p[1] && !p[3])
8232     {
8233         int ver;
8234         VERIFY_PERMISSION(OPT_P_GENERAL);
8235         ver = tls_version_parse(p[1], p[2]);
8236         if (ver == TLS_VER_BAD)
8237         {
8238             msg(msglevel, "unknown tls-version-min parameter: %s", p[1]);
8239             goto err;
8240         }
8241         options->ssl_flags &=
8242             ~(SSLF_TLS_VERSION_MIN_MASK << SSLF_TLS_VERSION_MIN_SHIFT);
8243         options->ssl_flags |= (ver << SSLF_TLS_VERSION_MIN_SHIFT);
8244     }
8245     else if (streq(p[0], "tls-version-max") && p[1] && !p[2])
8246     {
8247         int ver;
8248         VERIFY_PERMISSION(OPT_P_GENERAL);
8249         ver = tls_version_parse(p[1], NULL);
8250         if (ver == TLS_VER_BAD)
8251         {
8252             msg(msglevel, "unknown tls-version-max parameter: %s", p[1]);
8253             goto err;
8254         }
8255         options->ssl_flags &=
8256             ~(SSLF_TLS_VERSION_MAX_MASK << SSLF_TLS_VERSION_MAX_SHIFT);
8257         options->ssl_flags |= (ver << SSLF_TLS_VERSION_MAX_SHIFT);
8258     }
8259 #ifndef ENABLE_CRYPTO_MBEDTLS
8260     else if (streq(p[0], "pkcs12") && p[1] && !p[2])
8261     {
8262         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INLINE);
8263         options->pkcs12_file = p[1];
8264         options->pkcs12_file_inline = is_inline;
8265     }
8266 #endif /* ENABLE_CRYPTO_MBEDTLS */
8267     else if (streq(p[0], "askpass") && !p[2])
8268     {
8269         VERIFY_PERMISSION(OPT_P_GENERAL);
8270         if (p[1])
8271         {
8272             options->key_pass_file = p[1];
8273         }
8274         else
8275         {
8276             options->key_pass_file = "stdin";
8277         }
8278     }
8279     else if (streq(p[0], "auth-nocache") && !p[1])
8280     {
8281         VERIFY_PERMISSION(OPT_P_GENERAL);
8282         ssl_set_auth_nocache();
8283     }
8284     else if (streq(p[0], "auth-token") && p[1] && !p[2])
8285     {
8286         VERIFY_PERMISSION(OPT_P_ECHO);
8287         ssl_set_auth_token(p[1]);
8288 #ifdef ENABLE_MANAGEMENT
8289         if (management)
8290         {
8291             management_auth_token(management, p[1]);
8292         }
8293 #endif
8294     }
8295     else if (streq(p[0], "auth-token-user") && p[1] && !p[2])
8296     {
8297         VERIFY_PERMISSION(OPT_P_ECHO);
8298         ssl_set_auth_token_user(p[1]);
8299     }
8300     else if (streq(p[0], "single-session") && !p[1])
8301     {
8302         VERIFY_PERMISSION(OPT_P_GENERAL);
8303         options->single_session = true;
8304     }
8305     else if (streq(p[0], "push-peer-info") && !p[1])
8306     {
8307         VERIFY_PERMISSION(OPT_P_GENERAL);
8308         options->push_peer_info = true;
8309     }
8310     else if (streq(p[0], "tls-exit") && !p[1])
8311     {
8312         VERIFY_PERMISSION(OPT_P_GENERAL);
8313         options->tls_exit = true;
8314     }
8315     else if (streq(p[0], "tls-cipher") && p[1] && !p[2])
8316     {
8317         VERIFY_PERMISSION(OPT_P_GENERAL);
8318         options->cipher_list = p[1];
8319     }
8320     else if (streq(p[0], "tls-cert-profile") && p[1] && !p[2])
8321     {
8322         VERIFY_PERMISSION(OPT_P_GENERAL);
8323         options->tls_cert_profile = p[1];
8324     }
8325     else if (streq(p[0], "tls-ciphersuites") && p[1] && !p[2])
8326     {
8327         VERIFY_PERMISSION(OPT_P_GENERAL);
8328         options->cipher_list_tls13 = p[1];
8329     }
8330     else if (streq(p[0], "tls-groups") && p[1] && !p[2])
8331     {
8332         VERIFY_PERMISSION(OPT_P_GENERAL);
8333         options->tls_groups = p[1];
8334     }
8335     else if (streq(p[0], "crl-verify") && p[1] && ((p[2] && streq(p[2], "dir"))
8336                                                    || !p[2]))
8337     {
8338         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INLINE);
8339         if (p[2] && streq(p[2], "dir"))
8340         {
8341             options->ssl_flags |= SSLF_CRL_VERIFY_DIR;
8342         }
8343         options->crl_file = p[1];
8344         options->crl_file_inline = is_inline;
8345     }
8346     else if (streq(p[0], "tls-verify") && p[1])
8347     {
8348         VERIFY_PERMISSION(OPT_P_SCRIPT);
8349         if (!no_more_than_n_args(msglevel, p, 2, NM_QUOTE_HINT))
8350         {
8351             goto err;
8352         }
8353         set_user_script(options, &options->tls_verify,
8354                         string_substitute(p[1], ',', ' ', &options->gc),
8355                         "tls-verify", true);
8356     }
8357 #ifndef ENABLE_CRYPTO_MBEDTLS
8358     else if (streq(p[0], "tls-export-cert") && p[1] && !p[2])
8359     {
8360         VERIFY_PERMISSION(OPT_P_GENERAL);
8361         options->tls_export_cert = p[1];
8362     }
8363 #endif
8364     else if (streq(p[0], "compat-names"))
8365     {
8366         VERIFY_PERMISSION(OPT_P_GENERAL);
8367         msg(msglevel, "--compat-names was removed in OpenVPN 2.5. "
8368             "Update your configuration.");
8369         goto err;
8370     }
8371     else if (streq(p[0], "no-name-remapping") && !p[1])
8372     {
8373         VERIFY_PERMISSION(OPT_P_GENERAL);
8374         msg(msglevel, "--no-name-remapping was removed in OpenVPN 2.5. "
8375             "Update your configuration.");
8376         goto err;
8377     }
8378     else if (streq(p[0], "verify-x509-name") && p[1] && strlen(p[1]) && !p[3])
8379     {
8380         int type = VERIFY_X509_SUBJECT_DN;
8381         VERIFY_PERMISSION(OPT_P_GENERAL);
8382         if (p[2])
8383         {
8384             if (streq(p[2], "subject"))
8385             {
8386                 type = VERIFY_X509_SUBJECT_DN;
8387             }
8388             else if (streq(p[2], "name"))
8389             {
8390                 type = VERIFY_X509_SUBJECT_RDN;
8391             }
8392             else if (streq(p[2], "name-prefix"))
8393             {
8394                 type = VERIFY_X509_SUBJECT_RDN_PREFIX;
8395             }
8396             else
8397             {
8398                 msg(msglevel, "unknown X.509 name type: %s", p[2]);
8399                 goto err;
8400             }
8401         }
8402         options->verify_x509_type = type;
8403         options->verify_x509_name = p[1];
8404     }
8405     else if (streq(p[0], "ns-cert-type") && p[1] && !p[2])
8406     {
8407         VERIFY_PERMISSION(OPT_P_GENERAL);
8408         if (streq(p[1], "server"))
8409         {
8410             options->ns_cert_type = NS_CERT_CHECK_SERVER;
8411         }
8412         else if (streq(p[1], "client"))
8413         {
8414             options->ns_cert_type = NS_CERT_CHECK_CLIENT;
8415         }
8416         else
8417         {
8418             msg(msglevel, "--ns-cert-type must be 'client' or 'server'");
8419             goto err;
8420         }
8421     }
8422     else if (streq(p[0], "remote-cert-ku"))
8423     {
8424         VERIFY_PERMISSION(OPT_P_GENERAL);
8425 
8426         size_t j;
8427         for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
8428         {
8429             sscanf(p[j], "%x", &(options->remote_cert_ku[j-1]));
8430         }
8431         if (j == 1)
8432         {
8433             /* No specific KU required, but require KU to be present */
8434             options->remote_cert_ku[0] = OPENVPN_KU_REQUIRED;
8435         }
8436     }
8437     else if (streq(p[0], "remote-cert-eku") && p[1] && !p[2])
8438     {
8439         VERIFY_PERMISSION(OPT_P_GENERAL);
8440         options->remote_cert_eku = p[1];
8441     }
8442     else if (streq(p[0], "remote-cert-tls") && p[1] && !p[2])
8443     {
8444         VERIFY_PERMISSION(OPT_P_GENERAL);
8445 
8446         if (streq(p[1], "server"))
8447         {
8448             options->remote_cert_ku[0] = OPENVPN_KU_REQUIRED;
8449             options->remote_cert_eku = "TLS Web Server Authentication";
8450         }
8451         else if (streq(p[1], "client"))
8452         {
8453             options->remote_cert_ku[0] = OPENVPN_KU_REQUIRED;
8454             options->remote_cert_eku = "TLS Web Client Authentication";
8455         }
8456         else
8457         {
8458             msg(msglevel, "--remote-cert-tls must be 'client' or 'server'");
8459             goto err;
8460         }
8461     }
8462     else if (streq(p[0], "tls-timeout") && p[1] && !p[2])
8463     {
8464         VERIFY_PERMISSION(OPT_P_TLS_PARMS);
8465         options->tls_timeout = positive_atoi(p[1]);
8466     }
8467     else if (streq(p[0], "reneg-bytes") && p[1] && !p[2])
8468     {
8469         VERIFY_PERMISSION(OPT_P_TLS_PARMS);
8470         options->renegotiate_bytes = positive_atoi(p[1]);
8471     }
8472     else if (streq(p[0], "reneg-pkts") && p[1] && !p[2])
8473     {
8474         VERIFY_PERMISSION(OPT_P_TLS_PARMS);
8475         options->renegotiate_packets = positive_atoi(p[1]);
8476     }
8477     else if (streq(p[0], "reneg-sec") && p[1] && !p[3])
8478     {
8479         VERIFY_PERMISSION(OPT_P_TLS_PARMS);
8480         options->renegotiate_seconds = positive_atoi(p[1]);
8481         if (p[2])
8482         {
8483             options->renegotiate_seconds_min = positive_atoi(p[2]);
8484         }
8485     }
8486     else if (streq(p[0], "hand-window") && p[1] && !p[2])
8487     {
8488         VERIFY_PERMISSION(OPT_P_TLS_PARMS);
8489         options->handshake_window = positive_atoi(p[1]);
8490     }
8491     else if (streq(p[0], "tran-window") && p[1] && !p[2])
8492     {
8493         VERIFY_PERMISSION(OPT_P_TLS_PARMS);
8494         options->transition_window = positive_atoi(p[1]);
8495     }
8496     else if (streq(p[0], "tls-auth") && p[1] && !p[3])
8497     {
8498         int key_direction = -1;
8499 
8500         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION|OPT_P_INLINE);
8501 
8502         if (permission_mask & OPT_P_GENERAL)
8503         {
8504             options->tls_auth_file = p[1];
8505             options->tls_auth_file_inline = is_inline;
8506 
8507             if (!is_inline && p[2])
8508             {
8509                 key_direction = ascii2keydirection(msglevel, p[2]);
8510                 if (key_direction < 0)
8511                 {
8512                     goto err;
8513                 }
8514                 options->key_direction = key_direction;
8515             }
8516 
8517         }
8518         else if (permission_mask & OPT_P_CONNECTION)
8519         {
8520             options->ce.tls_auth_file = p[1];
8521             options->ce.tls_auth_file_inline = is_inline;
8522             options->ce.key_direction = KEY_DIRECTION_BIDIRECTIONAL;
8523 
8524             if (!is_inline && p[2])
8525             {
8526                 key_direction = ascii2keydirection(msglevel, p[2]);
8527                 if (key_direction < 0)
8528                 {
8529                     goto err;
8530                 }
8531                 options->ce.key_direction = key_direction;
8532             }
8533         }
8534     }
8535     else if (streq(p[0], "tls-crypt") && p[1] && !p[3])
8536     {
8537         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION|OPT_P_INLINE);
8538         if (permission_mask & OPT_P_GENERAL)
8539         {
8540             options->tls_crypt_file = p[1];
8541             options->tls_crypt_file_inline = is_inline;
8542         }
8543         else if (permission_mask & OPT_P_CONNECTION)
8544         {
8545             options->ce.tls_crypt_file = p[1];
8546             options->ce.tls_crypt_file_inline = is_inline;
8547         }
8548     }
8549     else if (streq(p[0], "tls-crypt-v2") && p[1] && !p[3])
8550     {
8551         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION|OPT_P_INLINE);
8552         if (permission_mask & OPT_P_GENERAL)
8553         {
8554             options->tls_crypt_v2_file = p[1];
8555             options->tls_crypt_v2_file_inline = is_inline;
8556         }
8557         else if (permission_mask & OPT_P_CONNECTION)
8558         {
8559             options->ce.tls_crypt_v2_file = p[1];
8560             options->ce.tls_crypt_v2_file_inline = is_inline;
8561         }
8562     }
8563     else if (streq(p[0], "tls-crypt-v2-verify") && p[1] && !p[2])
8564     {
8565         VERIFY_PERMISSION(OPT_P_GENERAL);
8566         options->tls_crypt_v2_verify_script = p[1];
8567     }
8568     else if (streq(p[0], "x509-track") && p[1] && !p[2])
8569     {
8570         VERIFY_PERMISSION(OPT_P_GENERAL);
8571         x509_track_add(&options->x509_track, p[1], msglevel, &options->gc);
8572     }
8573 #ifdef ENABLE_X509ALTUSERNAME
8574     else if (streq(p[0], "x509-username-field") && p[1] && !p[2])
8575     {
8576         /* This option used to automatically upcase the fieldname passed as the
8577          * option argument, e.g., "ou" became "OU". Now, this "helpfulness" is
8578          * fine-tuned by only upcasing Subject field attribute names which consist
8579          * of all lower-case characters. Mixed-case attributes such as
8580          * "emailAddress" are left as-is. An option parameter having the "ext:"
8581          * prefix for matching X.509v3 extended fields will also remain unchanged.
8582          */
8583         char *s = p[1];
8584 
8585         VERIFY_PERMISSION(OPT_P_GENERAL);
8586         if (strncmp("ext:", s, 4) != 0)
8587         {
8588             size_t i = 0;
8589             while (s[i] && !isupper(s[i]))
8590             {
8591                 i++;
8592             }
8593             if (strlen(s) == i)
8594             {
8595                 while ((*s = toupper(*s)) != '\0')
8596                 {
8597                     s++;
8598                 }
8599                 msg(M_WARN, "DEPRECATED FEATURE: automatically upcased the "
8600                     "--x509-username-field parameter to '%s'; please update your"
8601                     "configuration", p[1]);
8602             }
8603         }
8604         else if (!x509_username_field_ext_supported(s+4))
8605         {
8606             msg(msglevel, "Unsupported x509-username-field extension: %s", s);
8607         }
8608         options->x509_username_field = p[1];
8609     }
8610 #endif /* ENABLE_X509ALTUSERNAME */
8611 #ifdef ENABLE_PKCS11
8612     else if (streq(p[0], "show-pkcs11-ids") && !p[3])
8613     {
8614         char *provider =  p[1];
8615         bool cert_private = (p[2] == NULL ? false : ( atoi(p[2]) != 0 ));
8616 
8617 #ifdef DEFAULT_PKCS11_MODULE
8618         if (!provider)
8619         {
8620             provider = DEFAULT_PKCS11_MODULE;
8621         }
8622         else if (!p[2])
8623         {
8624             char *endp = NULL;
8625             int i = strtol(provider, &endp, 10);
8626 
8627             if (*endp == 0)
8628             {
8629                 /* There was one argument, and it was purely numeric.
8630                  * Interpret it as the cert_private argument */
8631                 provider = DEFAULT_PKCS11_MODULE;
8632                 cert_private = i;
8633             }
8634         }
8635 #else  /* ifdef DEFAULT_PKCS11_MODULE */
8636         if (!provider)
8637         {
8638             msg(msglevel, "--show-pkcs11-ids requires a provider parameter");
8639             goto err;
8640         }
8641 #endif /* ifdef DEFAULT_PKCS11_MODULE */
8642         VERIFY_PERMISSION(OPT_P_GENERAL);
8643 
8644         set_debug_level(options->verbosity, SDL_CONSTRAIN);
8645         show_pkcs11_ids(provider, cert_private);
8646         openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
8647     }
8648     else if (streq(p[0], "pkcs11-providers") && p[1])
8649     {
8650         int j;
8651 
8652         VERIFY_PERMISSION(OPT_P_GENERAL);
8653 
8654         for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
8655         {
8656             options->pkcs11_providers[j-1] = p[j];
8657         }
8658     }
8659     else if (streq(p[0], "pkcs11-protected-authentication"))
8660     {
8661         int j;
8662 
8663         VERIFY_PERMISSION(OPT_P_GENERAL);
8664 
8665         for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
8666         {
8667             options->pkcs11_protected_authentication[j-1] = atoi(p[j]) != 0 ? 1 : 0;
8668         }
8669     }
8670     else if (streq(p[0], "pkcs11-private-mode") && p[1])
8671     {
8672         int j;
8673 
8674         VERIFY_PERMISSION(OPT_P_GENERAL);
8675 
8676         for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
8677         {
8678             sscanf(p[j], "%x", &(options->pkcs11_private_mode[j-1]));
8679         }
8680     }
8681     else if (streq(p[0], "pkcs11-cert-private"))
8682     {
8683         int j;
8684 
8685         VERIFY_PERMISSION(OPT_P_GENERAL);
8686 
8687         for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
8688         {
8689             options->pkcs11_cert_private[j-1] = atoi(p[j]) != 0 ? 1 : 0;
8690         }
8691     }
8692     else if (streq(p[0], "pkcs11-pin-cache") && p[1] && !p[2])
8693     {
8694         VERIFY_PERMISSION(OPT_P_GENERAL);
8695         options->pkcs11_pin_cache_period = atoi(p[1]);
8696     }
8697     else if (streq(p[0], "pkcs11-id") && p[1] && !p[2])
8698     {
8699         VERIFY_PERMISSION(OPT_P_GENERAL);
8700         options->pkcs11_id = p[1];
8701     }
8702     else if (streq(p[0], "pkcs11-id-management") && !p[1])
8703     {
8704         VERIFY_PERMISSION(OPT_P_GENERAL);
8705         options->pkcs11_id_management = true;
8706     }
8707 #endif /* ifdef ENABLE_PKCS11 */
8708     else if (streq(p[0], "rmtun") && !p[1])
8709     {
8710         VERIFY_PERMISSION(OPT_P_GENERAL);
8711         options->persist_config = true;
8712         options->persist_mode = 0;
8713     }
8714     else if (streq(p[0], "mktun") && !p[1])
8715     {
8716         VERIFY_PERMISSION(OPT_P_GENERAL);
8717         options->persist_config = true;
8718         options->persist_mode = 1;
8719     }
8720     else if (streq(p[0], "peer-id") && p[1] && !p[2])
8721     {
8722         VERIFY_PERMISSION(OPT_P_PEER_ID);
8723         options->use_peer_id = true;
8724         options->peer_id = atoi(p[1]);
8725     }
8726 #ifdef HAVE_EXPORT_KEYING_MATERIAL
8727     else if (streq(p[0], "keying-material-exporter") && p[1] && p[2])
8728     {
8729         int ekm_length = positive_atoi(p[2]);
8730 
8731         VERIFY_PERMISSION(OPT_P_GENERAL);
8732 
8733         if (strncmp(p[1], "EXPORTER", 8))
8734         {
8735             msg(msglevel, "Keying material exporter label must begin with "
8736                 "\"EXPORTER\"");
8737             goto err;
8738         }
8739         if (ekm_length < 16 || ekm_length > 4095)
8740         {
8741             msg(msglevel, "Invalid keying material exporter length");
8742             goto err;
8743         }
8744 
8745         options->keying_material_exporter_label = p[1];
8746         options->keying_material_exporter_length = ekm_length;
8747     }
8748 #endif /* HAVE_EXPORT_KEYING_MATERIAL */
8749     else if (streq(p[0], "allow-recursive-routing") && !p[1])
8750     {
8751         VERIFY_PERMISSION(OPT_P_GENERAL);
8752         options->allow_recursive_routing = true;
8753     }
8754     else if (streq(p[0], "vlan-tagging") && !p[1])
8755     {
8756         VERIFY_PERMISSION(OPT_P_GENERAL);
8757         options->vlan_tagging = true;
8758     }
8759     else if (streq(p[0], "vlan-accept") && p[1] && !p[2])
8760     {
8761         VERIFY_PERMISSION(OPT_P_GENERAL);
8762         if (streq(p[1], "tagged"))
8763         {
8764             options->vlan_accept = VLAN_ONLY_TAGGED;
8765         }
8766         else if (streq(p[1], "untagged"))
8767         {
8768             options->vlan_accept = VLAN_ONLY_UNTAGGED_OR_PRIORITY;
8769         }
8770         else if (streq(p[1], "all"))
8771         {
8772             options->vlan_accept = VLAN_ALL;
8773         }
8774         else
8775         {
8776             msg(msglevel, "--vlan-accept must be 'tagged', 'untagged' or 'all'");
8777             goto err;
8778         }
8779     }
8780     else if (streq(p[0], "vlan-pvid") && p[1] && !p[2])
8781     {
8782         VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INSTANCE);
8783         options->vlan_pvid = positive_atoi(p[1]);
8784         if (options->vlan_pvid < OPENVPN_8021Q_MIN_VID
8785             || options->vlan_pvid > OPENVPN_8021Q_MAX_VID)
8786         {
8787             msg(msglevel,
8788                 "the parameter of --vlan-pvid parameters must be >= %u and <= %u",
8789                 OPENVPN_8021Q_MIN_VID, OPENVPN_8021Q_MAX_VID);
8790             goto err;
8791         }
8792     }
8793     else
8794     {
8795         int i;
8796         int msglevel = msglevel_fc;
8797         /* Check if an option is in --ignore-unknown-option and
8798          * set warning level to non fatal */
8799         for (i = 0; options->ignore_unknown_option && options->ignore_unknown_option[i]; i++)
8800         {
8801             if (streq(p[0], options->ignore_unknown_option[i]))
8802             {
8803                 msglevel = M_WARN;
8804                 break;
8805             }
8806         }
8807         if (file)
8808         {
8809             msg(msglevel, "Unrecognized option or missing or extra parameter(s) in %s:%d: %s (%s)", file, line, p[0], PACKAGE_VERSION);
8810         }
8811         else
8812         {
8813             msg(msglevel, "Unrecognized option or missing or extra parameter(s): --%s (%s)", p[0], PACKAGE_VERSION);
8814         }
8815     }
8816 err:
8817     gc_free(&gc);
8818 }
8819