OpenVPN 3 Core Library
Loading...
Searching...
No Matches
cliopt.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12// These classes encapsulate the basic setup of the various objects needed to
13// create an OpenVPN client session. The basic idea here is to look at both
14// compile time settings (i.e. crypto/SSL/random libraries), and run-time
15// (such as transport layer using UDP, TCP, or HTTP-proxy), and
16// build the actual objects that will be used to construct a client session.
17
18#ifndef OPENVPN_CLIENT_CLIOPT_H
19#define OPENVPN_CLIENT_CLIOPT_H
20
21#include <string>
22#include <tuple>
23#include <unordered_set>
24#include <map>
25#include <set>
26
28
41
53
55
56#ifdef OPENVPN_GREMLIN
58#endif
59
60#ifdef OPENVPN_PLATFORM_ANDROID
62#endif
63
64#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
67#endif
68
69#ifdef OPENVPN_EXTERNAL_TUN_FACTORY
70// requires that client implements ExternalTun::Factory::new_tun_factory
72#elif defined(USE_TUN_BUILDER)
74#elif defined(OPENVPN_PLATFORM_LINUX) && !defined(OPENVPN_FORCE_TUN_NULL)
76#ifdef OPENVPN_COMMAND_AGENT
78#endif
79#elif defined(OPENVPN_PLATFORM_MAC) && !defined(OPENVPN_FORCE_TUN_NULL)
82#ifdef OPENVPN_COMMAND_AGENT
84#endif
85#elif defined(OPENVPN_PLATFORM_WIN) && !defined(OPENVPN_FORCE_TUN_NULL)
87#ifdef OPENVPN_COMMAND_AGENT
89#endif
90#else
92#endif
93
94#ifdef PRIVATE_TUNNEL_PROXY
95#include <openvpn/pt/ptproxy.hpp>
96#endif
97
98#if defined(ENABLE_KOVPN) || defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)
100#endif
101
102#ifndef OPENVPN_UNUSED_OPTIONS
103#define OPENVPN_UNUSED_OPTIONS "UNKNOWN/UNSUPPORTED OPTIONS"
104#endif
105
106namespace openvpn {
107
109{
110
116 {
117 /* explicitly allow slicing to only copy the settings that
118 * are in the common base class \c ConfigCommon */
119 ClientAPI::ConfigCommon::operator=(config);
120
121 if (!config.protoOverride.empty())
123
124 if (config.protoVersionOverride == 4)
126 else if (config.protoVersionOverride == 6)
128
129 if (!config.allowUnusedAddrFamilies.empty())
130 allowUnusedAddrFamilies = TriStateSetting::parse(config.allowUnusedAddrFamilies);
131 }
132
134
136
138
139 /* from eval config */
141};
142
143
144class ClientOptions : public RC<thread_unsafe_refcount>
145{
146 public:
148
150
151 struct Config
152 {
153 /* Options set by the client application.
154 * This class only uses a subset. For simplicity
155 * we keep all client settings here instead of creating a new
156 * subset class of configuration options */
158
164 bool alt_proxy = false;
167
169#ifdef OPENVPN_PLATFORM_ANDROID
170 bool enable_route_emulation = true;
171#endif
172#ifdef OPENVPN_GREMLIN
173 Gremlin::Config::Ptr gremlin_config;
174#endif
175 Stop *stop = nullptr;
176
177 // callbacks -- must remain in scope for lifetime of ClientOptions object
182
183#ifdef USE_TUN_BUILDER
184 TunBuilderBase *builder = nullptr;
185#endif
186
187#ifdef OPENVPN_EXTERNAL_TUN_FACTORY
188 ExternalTun::Factory *extern_tun_factory = nullptr;
189#endif
190
191#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
192 ExternalTransport::Factory *extern_transport_factory = nullptr;
193#endif
194 };
195
196 ClientOptions(const OptionList &opt, // only needs to remain in scope for duration of constructor call
197 const Config &config)
199 server_addr_float(false),
205 tcp_queue_limit(64),
208 autologin(false),
209 autologin_sessions(false),
210 creds_locked(false),
213#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
214 ,
215 extern_transport_factory(config.extern_transport_factory)
216#endif
217 {
218 // parse general client options
219 const ParseClientConfig pcc(opt);
220
221 // creds
223 autologin = pcc.autologin();
225
226 // digest factory
228
229 // initialize RNG/PRNG
230 rng.reset(new SSLLib::RandomAPI());
231 prng.reset(new MTRand(time(nullptr)));
232
233 // frame
234 // get tun-mtu and tun-mtu-max parameter from config
235 const unsigned int tun_mtu = parse_tun_mtu(opt, 0);
236 const unsigned int tun_mtu_max = std::max(parse_tun_mtu_max(opt, TUN_MTU_DEFAULT + 100), tun_mtu);
237
238 const MSSCtrlParms mc(opt);
239 frame = frame_init(true, tun_mtu_max, mc.mssfix_ctrl, true);
240
241 // TCP queue limit
242 tcp_queue_limit = opt.get_num<decltype(tcp_queue_limit)>("tcp-queue-limit", 1, tcp_queue_limit, 1, 65536);
243
244 // route-nopull
246
247 // OpenVPN Protocol context (including SSL)
248 cp_main = proto_config(opt, config, pcc, false);
249 cp_relay = proto_config(opt, config, pcc, true); // may be null
250
251 CryptoAlgs::allow_default_dc_algs<SSLLib::CryptoAPI>(cp_main->ssl_factory->libctx(),
252 !config.clientconf.enableNonPreferredDCAlgorithms,
253 config.clientconf.enableLegacyAlgorithms);
254
255#if (defined(ENABLE_KOVPN) || defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)) && !defined(OPENVPN_FORCE_TUN_NULL) && !defined(OPENVPN_EXTERNAL_TUN_FACTORY)
256 if (config.clientconf.dco)
257#if defined(USE_TUN_BUILDER)
258 dco = DCOTransport::new_controller(config.builder);
259#else
260 dco = DCOTransport::new_controller(nullptr);
261#endif
262#endif
263
264 layer = cp_main->layer;
265
266#ifdef PRIVATE_TUNNEL_PROXY
267 if (config.alt_proxy && !dco)
268 alt_proxy = PTProxy::new_proxy(opt, rng);
269#endif
270
271 // If HTTP proxy parameters are not supplied by API, try to get them from config
274
275 // load remote list
276 if (config.remote_override)
277 {
278 remote_list.reset(new RemoteList(config.remote_override));
280 }
281 else
283 if (!remote_list->defined())
284 throw option_error(ERR_INVALID_CONFIG, "no remote option specified");
285
286 // If running in tun_persist mode, we need to do basic DNS caching so that
287 // we can avoid emitting DNS requests while the tunnel is blocked during
288 // reconnections.
289 remote_list->set_enable_cache(config.clientconf.tunPersist);
290
291 // process server/port/family overrides
292 remote_list->set_server_override(config.clientconf.serverOverride);
293 remote_list->set_port_override(config.clientconf.portOverride);
294 remote_list->set_proto_version_override(config.clientconf.proto_version_override);
295
296 // process protocol override, should be called after set_enable_cache
297 remote_list->handle_proto_override(config.clientconf.proto_override,
299
300 // process remote-random
301 if (opt.exists("remote-random"))
303
304 // get "float" option
305 server_addr_float = opt.exists("float");
306
307 // special remote cache handling for proxies
308 if (alt_proxy)
309 {
310 remote_list->set_enable_cache(false); // remote server addresses will be resolved by proxy
311 alt_proxy->set_enable_cache(config.clientconf.tunPersist);
312 }
313 else if (http_proxy_options)
314 {
315 remote_list->set_enable_cache(false); // remote server addresses will be resolved by proxy
316 http_proxy_options->proxy_server_set_enable_cache(config.clientconf.tunPersist);
317 }
318
320
321 // throw an exception if dco is requested but config/options are dco-incompatible
322 bool dco_compatible = false;
323 std::tie(dco_compatible, std::ignore) = check_dco_compatibility(clientconf, opt);
324 if (config.clientconf.dco && !dco_compatible)
325 {
326 throw option_error(ERR_INVALID_CONFIG, "dco_compatibility: config/options are not compatible with dco");
327 }
328
329#ifdef OPENVPN_PLATFORM_UWP
330 // workaround for OVPN3-62 Busy loop in win_event.hpp
332#endif
333
334 synchronous_dns_lookup = config.synchronous_dns_lookup;
335
336#ifdef OPENVPN_TLS_LINK
337 if (opt.exists("tls-ca"))
338 {
339 tls_ca = opt.cat("tls-ca");
340 }
341#endif
342
343 // init transport config
344 const std::string session_name = load_transport_config();
345
346 // initialize tun/tap
347 if (dco)
348 {
349 DCO::TunConfig tunconf;
350#if defined(OPENVPN_COMMAND_AGENT) && defined(OPENVPN_PLATFORM_WIN)
351 tunconf.setup_factory = WinCommandAgent::new_agent(opt);
352#endif
353 tunconf.tun_prop.layer = layer;
354 tunconf.tun_prop.session_name = session_name;
355 if (tun_mtu)
356 tunconf.tun_prop.mtu = tun_mtu;
357 tunconf.tun_prop.mtu_max = tun_mtu_max;
358 tunconf.tun_prop.google_dns_fallback = config.clientconf.googleDnsFallback;
359 tunconf.tun_prop.dhcp_search_domains_as_split_domains = config.clientconf.dhcpSearchDomainsAsSplitDomains;
361 tunconf.stop = config.stop;
362 tunconf.allow_local_dns_resolvers = config.clientconf.allowLocalDnsResolvers;
363#ifdef OPENVPN_PLATFORM_WIN
364 if (config.clientconf.tunPersist)
365 tunconf.tun_persist.reset(new TunWin::DcoTunPersist(true, TunWrapObjRetain::NO_RETAIN_NO_REPLACE, nullptr));
366#endif
367 tun_factory = dco->new_tun_factory(tunconf, opt);
368 }
369 else
370 {
371#ifdef OPENVPN_EXTERNAL_TUN_FACTORY
372 {
373 ExternalTun::Config tunconf;
374 tunconf.tun_prop.layer = layer;
375 tunconf.tun_prop.session_name = session_name;
376 tunconf.tun_prop.google_dns_fallback = config.clientconf.googleDnsFallback;
377 tunconf.tun_prop.dhcp_search_domains_as_split_domains = config.clientconf.dhcpSearchDomainsAsSplitDomains;
378 if (tun_mtu)
379 tunconf.tun_prop.mtu = tun_mtu;
380 tunconf.tun_prop.mtu_max = tun_mtu_max;
381 tunconf.frame = frame;
382 tunconf.stats = cli_stats;
384 tunconf.tun_persist = config.clientconf.tunPersist;
385 tunconf.stop = config.stop;
386 tun_factory.reset(config.extern_tun_factory->new_tun_factory(tunconf, opt));
387 if (!tun_factory)
388 throw option_error(ERR_INVALID_CONFIG, "OPENVPN_EXTERNAL_TUN_FACTORY: no tun factory");
389 }
390#elif defined(USE_TUN_BUILDER)
391 {
393 tunconf->builder = config.builder;
394 tunconf->tun_prop.session_name = session_name;
395 tunconf->tun_prop.google_dns_fallback = config.clientconf.googleDnsFallback;
396 tunconf->tun_prop.dhcp_search_domains_as_split_domains = config.clientconf.dhcpSearchDomainsAsSplitDomains;
397 tunconf->tun_prop.allow_local_lan_access = config.clientconf.allowLocalLanAccess;
398 if (tun_mtu)
399 tunconf->tun_prop.mtu = tun_mtu;
400 tunconf->tun_prop.mtu_max = tun_mtu_max;
401 tunconf->frame = frame;
402 tunconf->stats = cli_stats;
403 tunconf->tun_prop.remote_list = remote_list;
404 tun_factory = tunconf;
405#if defined(OPENVPN_PLATFORM_IPHONE)
406 tunconf->retain_sd = true;
407 tunconf->tun_prefix = true;
408 if (config.clientconf.tunPersist)
409 tunconf->tun_prop.remote_bypass = true;
410#endif
411#if defined(OPENVPN_PLATFORM_ANDROID)
412 // Android VPN API only supports excluded IP prefixes starting with Android 13/API 33,
413 // so we must emulate them for earlier platforms
414 if (config.enable_route_emulation)
415 {
416 tunconf->eer_factory.reset(new EmulateExcludeRouteFactoryImpl(false));
417 }
418 else
419 {
420 tunconf->eer_factory.reset(nullptr);
421 }
422#endif
423#if defined(OPENVPN_PLATFORM_MAC)
424 tunconf->tun_prefix = true;
425#endif
426 if (config.clientconf.tunPersist)
427 tunconf->tun_persist.reset(new TunBuilderClient::TunPersist(true, tunconf->retain_sd ? TunWrapObjRetain::RETAIN : TunWrapObjRetain::NO_RETAIN, config.builder));
428 tun_factory = tunconf;
429 }
430#elif defined(OPENVPN_PLATFORM_LINUX) && !defined(OPENVPN_FORCE_TUN_NULL)
431 {
433 tunconf->tun_prop.layer = layer;
434 tunconf->tun_prop.session_name = session_name;
435 if (tun_mtu)
436 tunconf->tun_prop.mtu = tun_mtu;
437 tunconf->tun_prop.mtu_max = tun_mtu_max;
438 tunconf->tun_prop.google_dns_fallback = config.clientconf.googleDnsFallback;
439 tunconf->tun_prop.dhcp_search_domains_as_split_domains = config.clientconf.dhcpSearchDomainsAsSplitDomains;
440 tunconf->generate_tun_builder_capture_event = config.clientconf.generateTunBuilderCaptureEvent;
441 tunconf->tun_prop.remote_list = remote_list;
442 tunconf->frame = frame;
443 tunconf->stats = cli_stats;
444 if (config.clientconf.tunPersist)
445 tunconf->tun_persist.reset(new TunLinux::TunPersist(true, TunWrapObjRetain::NO_RETAIN, nullptr));
446 tunconf->load(opt);
447 tun_factory = tunconf;
448 }
449#elif defined(OPENVPN_PLATFORM_MAC) && !defined(OPENVPN_FORCE_TUN_NULL)
450 {
452 tunconf->tun_prop.layer = layer;
453 tunconf->tun_prop.session_name = session_name;
454 tunconf->tun_prop.google_dns_fallback = config.clientconf.googleDnsFallback;
455 tunconf->tun_prop.dhcp_search_domains_as_split_domains = config.clientconf.dhcpSearchDomainsAsSplitDomains;
456 if (tun_mtu)
457 tunconf->tun_prop.mtu = tun_mtu;
458 tunconf->tun_prop.mtu_max = tun_mtu_max;
459 tunconf->frame = frame;
460 tunconf->stats = cli_stats;
461 tunconf->stop = config.stop;
462 if (config.clientconf.tunPersist)
463 {
464 tunconf->tun_persist.reset(new TunMac::TunPersist(true, TunWrapObjRetain::NO_RETAIN, nullptr));
465#ifndef OPENVPN_COMMAND_AGENT
466 /* remote_list is required by remote_bypass to work */
467 tunconf->tun_prop.remote_bypass = true;
468 tunconf->tun_prop.remote_list = remote_list;
469#endif
470 }
472#ifdef OPENVPN_COMMAND_AGENT
473 tunconf->tun_setup_factory = UnixCommandAgent::new_agent(opt);
474#endif
475 tun_factory = tunconf;
476 }
477#elif defined(OPENVPN_PLATFORM_WIN) && !defined(OPENVPN_FORCE_TUN_NULL)
478 {
480 tunconf->tun_prop.layer = layer;
481 tunconf->tun_prop.session_name = session_name;
482 tunconf->tun_prop.google_dns_fallback = config.clientconf.googleDnsFallback;
483 tunconf->tun_prop.dhcp_search_domains_as_split_domains = config.clientconf.dhcpSearchDomainsAsSplitDomains;
484 if (tun_mtu)
485 tunconf->tun_prop.mtu = tun_mtu;
486 tunconf->tun_prop.mtu_max = tun_mtu_max;
487 tunconf->frame = frame;
488 tunconf->stats = cli_stats;
489 tunconf->stop = config.stop;
490 tunconf->tun_type = config.clientconf.wintun ? TunWin::Wintun : TunWin::TapWindows6;
491 tunconf->allow_local_dns_resolvers = config.clientconf.allowLocalDnsResolvers;
492 if (config.clientconf.tunPersist)
493 {
494 tunconf->tun_persist.reset(new TunWin::TunPersist(true, TunWrapObjRetain::NO_RETAIN, nullptr));
495#ifndef OPENVPN_COMMAND_AGENT
496 /* remote_list is required by remote_bypass to work */
497 tunconf->tun_prop.remote_bypass = true;
498 tunconf->tun_prop.remote_list = remote_list;
499#endif
500 }
501#ifdef OPENVPN_COMMAND_AGENT
502 tunconf->tun_setup_factory = WinCommandAgent::new_agent(opt);
503#endif
504 tun_factory = tunconf;
505 }
506#else
507 {
509 tunconf->frame = frame;
510 tunconf->stats = cli_stats;
511 tun_factory = tunconf;
512 }
513#endif
514 }
515
516 // The Core Library itself does not handle TAP/OSI_LAYER_2 currently,
517 // so we bail out early whenever someone tries to use TAP configurations
519 throw ErrorCode(Error::TAP_NOT_SUPPORTED, true, "OSI layer 2 tunnels are not currently supported");
520
521 // server-poll-timeout
522 {
523 const Option *o = opt.get_ptr("server-poll-timeout");
524 if (o)
525 server_poll_timeout_ = parse_number_throw<unsigned int>(o->get(1, 16), "server-poll-timeout");
526 }
527
528 // create default creds object in case submit_creds is not called,
529 // and populate it with embedded creds, if available
530 {
531 ClientCreds::Ptr cc = new ClientCreds();
532 if (pcc.hasEmbeddedPassword())
533 {
536 submit_creds(cc);
537 creds_locked = true;
538 }
539 else if (autologin_sessions)
540 {
541 submit_creds(cc);
542 creds_locked = true;
543 }
544 else
545 {
546 submit_creds(cc);
547 }
548 }
549
550 // configure push_base, a set of base options that will be combined with
551 // options pushed by server.
552 {
554
555 // base options where multiple options of the same type can aggregate
556 push_base->multi.extend(opt, "route");
557 push_base->multi.extend(opt, "route-ipv6");
558 push_base->multi.extend(opt, "redirect-gateway");
559 push_base->multi.extend(opt, "redirect-private");
560 push_base->multi.extend(opt, "dhcp-option");
561
562 // base options which need to be merged, not just aggregated
563 push_base->merge.extend(opt, "dns");
564
565 // base options where only a single instance of each option makes sense
566 push_base->singleton.extend(opt, "redirect-dns");
567 push_base->singleton.extend(opt, "inactive");
568 push_base->singleton.extend(opt, "route-metric");
569
570 // IPv6
571 {
572 const unsigned int n6 = push_base->singleton.extend(opt, "block-ipv6");
573 const unsigned int n4 = push_base->singleton.extend(opt, "block-ipv4");
574
575 if (!n6 && config.clientconf.allowUnusedAddrFamilies() == TriStateSetting::No)
576 {
577 push_base->singleton.emplace_back("block-ipv6");
578 }
579 if (!n4 && config.clientconf.allowUnusedAddrFamilies() == TriStateSetting::No)
580 {
581 push_base->singleton.emplace_back("block-ipv4");
582 }
583 }
584 }
585
587 }
588
589 // If those options are present, dco cannot be used
590 inline static std::unordered_set<std::string> dco_incompatible_opts = {
591 "http-proxy",
592 "compress",
593 "comp-lzo"};
594
595
599 static std::tuple<bool, std::string> check_dco_compatibility(const ClientAPI::ConfigCommon &config, const OptionList &opt)
600 {
601#ifdef ENABLE_KOVPN
602 // only care about dco/dco-win
603 return std::make_tuple(true, "");
604#else
605
606 std::vector<std::string> reasons;
607
608 for (auto &optname : dco_incompatible_opts)
609 {
610 if (opt.exists(optname))
611 {
612 reasons.push_back("option " + optname + " is not compatible with dco");
613 }
614 }
615
616 if (config.enableLegacyAlgorithms)
617 {
618 reasons.emplace_back("legacy algorithms are not compatible with dco");
619 }
620
621 if (config.enableNonPreferredDCAlgorithms)
622 {
623 reasons.emplace_back("non-preferred data channel algorithms are not compatible with dco");
624 }
625
626 if (!config.proxyHost.empty())
627 {
628 reasons.emplace_back("proxyHost config setting is not compatible with dco");
629 }
630
631 if (reasons.empty())
632 {
633 return std::make_tuple(true, "");
634 }
635
636 return std::make_tuple(false, string::join(reasons, "\n"));
637
638#endif
639 }
640
642 {
643 // secret option not supported
644 if (opt.exists("secret"))
645 throw option_error(ERR_INVALID_OPTION_CRYPTO, "sorry, static key encryption mode (non-SSL/TLS) is not supported");
646
647 // fragment option not supported
648 if (opt.exists("fragment"))
649 throw option_error(ERR_INVALID_OPTION_VAL, "sorry, 'fragment' directive is not supported, nor is connecting to a server that uses 'fragment' directive");
650
651 if (!opt.exists("client"))
652 throw option_error(ERR_INVALID_CONFIG, "Neither 'client' nor both 'tls-client' and 'pull' options declared. OpenVPN3 client only supports --client mode.");
653
654 // Only p2p mode accept
655 if (opt.exists("mode"))
656 {
657 const auto &mode = opt.get("mode");
658 if (mode.size() != 2 || mode.get(1, 128) != "p2p")
659 {
660 throw option_error(ERR_INVALID_CONFIG, "Only 'mode p2p' supported");
661 }
662 }
663
664 // key-method 2 is the only thing that 2.5+ and 3.x support
665 if (opt.exists("key-method"))
666 {
667 auto keymethod = opt.get("key-method");
668 if (keymethod.size() != 2 || keymethod.get(1, 128) != "2")
669 {
670 throw option_error(ERR_INVALID_OPTION_VAL, "Only 'key-method 2' is supported: " + keymethod.get(1, 128));
671 }
672 }
673 }
674
675 std::unordered_set<std::string> settings_ignoreWithWarning = {
676 "allow-compression", /* TODO: maybe check against our client option compression setting? */
677 "allow-recursive-routing",
678 "auth-retry",
679 "compat-mode",
680 "connect-retry",
681 "connect-retry-max",
682 "connect-timeout", /* TODO: this should be really implemented */
683 "data-ciphers", /* TODO: maybe add more special warning that checks it against our supported ciphers */
684 "data-ciphers-fallback",
685 "disable-dco", /* TODO: maybe throw an error if DCO is active? */
686 "disable-occ",
687 "engine",
688 "explicit-exit-notify", /* ignoring it in config does not break connection or functionality */
689 "group",
690 "ifconfig-nowarn", /* v3 does not do OCC checks */
691 "ip-win32",
692 "keepalive", /* A push only feature (ping/ping-restart) in v3. Ignore with warning since often present in configs too */
693 "link-mtu",
694 "machine-readable-output", /* would be set by a CliOptions */
695 "mark", /* enables SO_MARK */
696 "mute",
697 "ncp-ciphers",
698 "nice",
699 "opt-verify",
700 "passtos",
701 "persist-key",
702 "persist-tun",
703 "preresolve",
704 "providers", /* Done via client options */
705 "remap-usr1",
706 "reneg-bytes",
707 "reneg-pkts",
708 "replay-window",
709 "resolv-retry",
710 "route-method", /* Windows specific fine tuning option */
711 "route-delay",
712 "show-net-up",
713 "socket-flags",
714 "suppress-timestamps", /* harmless to ignore */
715 "tcp-nodelay",
716 "tls-version-max", /* We don't allow restricting max version */
717 "tun-mtu-extra", /* (only really used in tap in OpenVPN 2.x)*/
718 "udp-mtu", /* Alias for link-mtu */
719 "user",
720 };
721
722 std::unordered_set<std::string> settings_serverOnlyOptions = {
723 "auth-gen-token",
724 "auth-gen-token-secret",
725 "auth-user-pass-optional",
726 "auth-user-pass-verify",
727 "bcast-buffers",
728 "ccd-exclusive",
729 "client-config-dir",
730 "client-connect",
731 "client-disconnect",
732 "client-to-client",
733 "connect-freq",
734 "dh",
735 "disable",
736 "duplicate-cn",
737 "hash-size",
738 "ifconfig-ipv6-pool",
739 "ifconfig-pool",
740 "ifconfig-pool-persist",
741 "ifconfig-push",
742 "ifconfig-push-constraint",
743 "iroute",
744 "iroute-ipv6",
745 "max-clients",
746 "max-routes-per-client",
747 "push",
748 "push-remove",
749 "push-reset",
750 "server",
751 "server-bridge",
752 "server-ipv6",
753 "stale-routes-check",
754 "tls-crypt-v2-verify",
755 "username-as-common-name",
756 "verify-client-cert",
757 "vlan-accept",
758 "vlan-pvid",
759 "vlan-tagging",
760 };
761
762 /* Features not implemented and not safe to ignore */
763 std::unordered_set<std::string> settings_feature_not_implemented_fatal = {
764 "askpass",
765 "capath",
766 "cd",
767 "chroot",
768 "client-nat",
769 "cryptoapicert",
770 "daemon",
771 "daemon",
772 "errors-to-stderr",
773 "gremlin",
774 "lladdr",
775 "log",
776 "log",
777 "log-append",
778 "management",
779 "memstats",
780 "msg-channel", /* (Windows service in v2) */
781 "ping-timer-rem",
782 "single-session", /* This option is quite obscure but changes behaviour enough to not ignore it */
783 "socks-proxy",
784 "status",
785 "status-version",
786 "syslog",
787 "tls-server", /* No p2p mode in v3 */
788 "verify-hash",
789 "win-sys",
790 "writepid",
791 "x509-username-field",
792 };
793
794 /* Features not implemented but safe enough to ignore */
795 std::unordered_set<std::string> settings_feature_not_implemented_warn = {
796 "allow-pull-fqdn",
797 "bind",
798 "local",
799 "lport",
800 "mlock",
801 "mtu-disc",
802 "mtu-test",
803 "persist-local-ip",
804 "persist-remote-ip",
805 "shaper",
806 "tls-exit",
807 };
808
809 /* Push only options (some are allowed in the config in OpenVPN 2
810 * but really push only options) */
811 std::unordered_set<std::string> settings_pushonlyoptions = {
812 "auth-token",
813 "auth-token-user",
814 "echo",
815 "parameter",
816 "ping",
817 "ping-exit",
818 "ping-restart", /* ping related options are pull only in v3, v2 needs them in the config for pure p2p */
819 "key-derivation",
820 "peer-id",
821 "protocol-flags",
822 "ifconfig",
823 "ifconfig-ipv6",
824 "topology",
825 "route-gateway"};
826
827 /* Features related to scripts/plugins */
828 std::unordered_set<std::string> settings_script_plugin_feature = {
829 "down",
830 "down-pre",
831 "ifconfig-noexec",
832 "ipchange",
833 "learn-address",
834 "plugin",
835 "route-noexec",
836 "route-pre-down",
837 "route-up",
838 "setenv-safe",
839 "tls-export-cert",
840 "tls-verify",
841 "up",
842 "up-delay",
843 "x509-track"};
844
845 /* Standalone OpenVPN v2 modes */
846 std::unordered_set<std::string> settings_standalone_options = {
847 "genkey",
848 "mktun",
849 "rmtun",
850 "show-ciphers",
851 "show-curves",
852 "show-digests",
853 "show-engines",
854 "show-groups",
855 "show-tls",
856 "test-crypto"};
857
858 /* Deprecated/throwing error in OpenVPN 2.x already: */
859 std::unordered_set<std::string> settings_removedOptions = {
860 "mtu-dynamic", "no-replay", "no-name-remapping", "compat-names", "ncp-disable", "no-iv"};
861
862 std::unordered_set<std::string> settings_ignoreSilently = {
863 "ecdh-curve", /* Deprecated in v2, not needed with modern OpenSSL */
864 "fast-io",
865 "max-routes",
866 "mute-replay-warnings",
867 "nobind", /* only behaviour in v3 client anyway */
868 "prng",
869 "rcvbuf", /* present in many configs */
870 "replay-persist", /* Makes little sense in TLS mode */
871 "script-security",
872 "sndbuf",
873 "tmp-dir",
874 "tun-ipv6", /* ignored in v2 as well */
875 "txqueuelen", /* so platforms evaluate that in tun, some do not, do not warn about that */
876 "verb"};
877
879 {
880 public:
881 void add_failed_opt(const Option &o, const std::string &message, bool fatal_arg)
882 {
883 if (!options_per_category.contains(message))
884 {
886 }
887
888 fatal |= fatal_arg;
889 options_per_category[message].push_back(o);
890 }
891
893 {
894 std::ostringstream os;
895
896 for (const auto &[category, options] : options_per_category)
897 {
898 if (!options.empty())
899 {
900 OPENVPN_LOG(category);
901
902 os << category << ": ";
903 std::vector<std::string> opts;
904 for (size_t i = 0; i < options.size(); ++i)
905 {
906 auto &o = options[i];
907 OPENVPN_LOG(std::to_string(i) << ' ' << o.render(Option::RENDER_BRACKET | Option::RENDER_TRUNC_64));
908 opts.push_back(o.get(0, 64));
909 }
910
911 os << string::join(opts, ",") << '\n';
912 }
913 }
914
915 if (fatal)
916 {
917 throw ErrorCode(Error::UNUSED_OPTIONS, true, os.str());
918 }
919 }
920
921 private:
922 std::map<std::string, std::vector<Option>> options_per_category;
923 bool fatal = false;
924 };
925
936 {
937 /* Meta options that AS profiles often have that we do not parse and
938 * can ignore without warning */
939 std::unordered_set<std::string> ignoreMetaOptions = {
940 "CLI_PREF_ALLOW_WEB_IMPORT",
941 "CLI_PREF_BASIC_CLIENT",
942 "CLI_PREF_ENABLE_CONNECT",
943 "CLI_PREF_ENABLE_XD_PROXY",
944 "WSHOST",
945 "WEB_CA_BUNDLE",
946 "IS_OPENVPN_WEB_CA",
947 "NO_WEB",
948 "ORGANIZATION"};
949
950 std::unordered_set<std::string> ignore_unknown_option_list;
951
952 if (opt.exists("ignore-unknown-option"))
953 {
954 auto igOptlist = opt.get_index("ignore-unknown-option");
955 for (auto igUnOptIdx : igOptlist)
956 {
957 const Option &o = opt[igUnOptIdx];
958 for (size_t i = 1; i < o.size(); i++)
959 {
960 const auto &optionToIgnore = o.get(i, 0);
961
962 ignore_unknown_option_list.insert(optionToIgnore);
963 }
964 o.touch();
965 }
966 }
967
968 for (const auto &o : opt)
969 {
970 if (!o.meta() && settings_ignoreSilently.contains(o.get(0, 0)))
971 {
972 o.touch();
973 }
974 if (o.meta() && ignoreMetaOptions.contains(o.get(0, 0)))
975 {
976 o.touch();
977 }
978 }
979
980 /* Mark all options that will not trigger any kind of message
981 * as touched to avoid an empty message with unused options */
982 if (opt.n_unused() == 0)
983 return;
984
985 OPENVPN_LOG_NTNL("NOTE: This configuration contains options that were not used:\n");
986
987 OptionErrors errors{};
988
989 /* Go through all options and check all options that have not been
990 * touched (parsed) yet */
991 showUnusedOptionsByList(opt, settings_removedOptions, "Removed deprecated option", true, errors);
992 showUnusedOptionsByList(opt, settings_serverOnlyOptions, "Server only option", true, errors);
993 showUnusedOptionsByList(opt, settings_standalone_options, "OpenVPN 2.x command line operation", true, errors);
994 showUnusedOptionsByList(opt, settings_feature_not_implemented_warn, "Feature not implemented (option ignored)", false, errors);
995 showUnusedOptionsByList(opt, settings_pushonlyoptions, "Option allowed only to be pushed by the server", true, errors);
996 showUnusedOptionsByList(opt, settings_script_plugin_feature, "Ignored (no script/plugin support)", false, errors);
997 showUnusedOptionsByList(opt, ignore_unknown_option_list, "Ignored by option 'ignore-unknown-option'", false, errors);
998 showUnusedOptionsByList(opt, settings_ignoreWithWarning, "Unsupported option (ignored)", false, errors);
999
1000 auto ignoredBySetenvOpt = [](const Option &option)
1001 { return !option.touched() && option.warnonlyunknown(); };
1002 showOptionsByFunction(opt, ignoredBySetenvOpt, "Ignored options prefixed with 'setenv opt'", false, errors);
1003
1004 auto unusedMetaOpt = [](const Option &option)
1005 { return !option.touched() && option.meta(); };
1006 showOptionsByFunction(opt, unusedMetaOpt, "Unused ignored meta options", false, errors);
1007
1008 auto managmentOpt = [](const Option &option)
1009 { return !option.touched() && option.get(0, 0).rfind("management", 0) == 0; };
1010 showOptionsByFunction(opt, managmentOpt, "OpenVPN management interface is not supported by this client", true, errors);
1011
1012 // If we still have options that are unaccounted for, we print them and throw an error or just warn about them
1013 auto onlyLightlyTouchedOptions = [](const Option &option)
1014 { return option.touched_lightly(); };
1015 showOptionsByFunction(opt, onlyLightlyTouchedOptions, "Unused options, probably specified multiple times in the configuration file", false, errors);
1016
1017 auto nonTouchedOptions = [](const Option &option)
1018 { return !option.touched() && !option.touched_lightly(); };
1019 showOptionsByFunction(opt, nonTouchedOptions, OPENVPN_UNUSED_OPTIONS, true, errors);
1020
1021 errors.print_option_errors();
1022 }
1023
1024 void showUnusedOptionsByList(const OptionList &optlist, std::unordered_set<std::string> option_set, const std::string &message, bool fatal, OptionErrors &errors)
1025 {
1026 auto func = [&option_set](const Option &opt)
1027 { return !opt.touched() && option_set.contains(opt.get(0, 0)); };
1028 showOptionsByFunction(optlist, func, message, fatal, errors);
1029 }
1030
1031 /* lambda expression that capture variables have complex signatures, avoid these by letting the compiler
1032 * itself figure it out with a template */
1033 template <typename T>
1034 void showOptionsByFunction(const OptionList &opt, T func, const std::string &message, bool fatal, OptionErrors &errors)
1035 {
1036 for (size_t i = 0; i < opt.size(); ++i)
1037 {
1038 auto &o = opt[i];
1039 if (func(o))
1040 {
1041 o.touch();
1042
1043 errors.add_failed_opt(o, message, fatal);
1044 }
1045 }
1046 }
1047
1049 {
1051
1052 // autologin sessions
1054 pi->emplace_back("IV_AUTO_SESS", "1");
1055
1056 if (pcc.pushPeerInfo())
1057 {
1058 /* If we override the HWADDR, we add it at this time statically. If we need to
1059 * dynamically discover it from the transport it will be added in
1060 * \c build_connect_time_peer_info_string instead */
1061 if (!config.clientconf.hwAddrOverride.empty())
1062 {
1063 pi->emplace_back("IV_HWADDR", config.clientconf.hwAddrOverride);
1064 }
1065
1066 pi->emplace_back("IV_SSL", get_ssl_library_version());
1067
1068 if (!config.clientconf.platformVersion.empty())
1069 pi->emplace_back("IV_PLAT_VER", config.clientconf.platformVersion);
1070
1071 /* ensure that we use only one variable with the same name */
1072 std::unordered_map<std::string, std::string> extra_values;
1073
1074 if (pcc.peerInfoUV())
1075 {
1076 for (const auto &kv : *pcc.peerInfoUV())
1077 {
1078 extra_values[kv.key] = kv.value;
1079 }
1080 }
1081
1082 /* Config::peerInfo takes precedence */
1083 if (config.extra_peer_info.get())
1084 {
1085 for (const auto &kv : *config.extra_peer_info.get())
1086 {
1087 extra_values[kv.key] = kv.value;
1088 }
1089 }
1090
1091 for (auto kv : extra_values)
1092 {
1093 pi->emplace_back(kv.first, kv.second);
1094 }
1095 }
1096
1097 // UI version
1098 if (!config.clientconf.guiVersion.empty())
1099 pi->emplace_back("IV_GUI_VER", config.clientconf.guiVersion);
1100
1101 // Supported SSO methods
1102 if (!config.clientconf.ssoMethods.empty())
1103 pi->emplace_back("IV_SSO", config.clientconf.ssoMethods);
1104
1105 if (!config.clientconf.appCustomProtocols.empty())
1106 pi->emplace_back("IV_ACC", "2048,6:A," + config.clientconf.appCustomProtocols);
1107
1108 return pi;
1109 }
1110
1112 {
1113 bool omit_next = false;
1114
1115 if (alt_proxy)
1116 omit_next = alt_proxy->next();
1117 if (!omit_next)
1118 remote_list->next(type);
1120 }
1121
1126
1128 {
1129 if (reconnect_notify)
1131 return false;
1132 }
1133
1135 {
1137 }
1138
1146 Client::Config::Ptr client_config(const bool relay_mode)
1147 {
1148 Client::Config::Ptr cli_config = new Client::Config;
1149
1150 // Copy ProtoConfig so that modifications due to server push will
1151 // not persist across client instantiations.
1152 cli_config->proto_context_config.reset(new ProtoContext::ProtoConfig(proto_config_cached(relay_mode)));
1153
1154 cli_config->proto_context_options = proto_context_options;
1155 cli_config->push_base = push_base;
1156 cli_config->transport_factory = transport_factory;
1157 cli_config->tun_factory = tun_factory;
1158 cli_config->cli_stats = cli_stats;
1159 cli_config->cli_events = cli_events;
1160 cli_config->creds = creds;
1161 cli_config->pushed_options_filter = pushed_options_filter;
1162 cli_config->tcp_queue_limit = tcp_queue_limit;
1163 cli_config->echo = clientconf.echo;
1164 cli_config->info = clientconf.info;
1165 cli_config->autologin_sessions = autologin_sessions;
1166
1167 // if the previous client instance had session-id, it must be used by the new instance too
1168 if (creds && creds->session_id_defined())
1169 {
1170 cli_config->proto_context_config->set_xmit_creds(true);
1171 }
1172
1173 return cli_config;
1174 }
1175
1176 bool need_creds() const
1177 {
1178 return !autologin;
1179 }
1180
1181 void submit_creds(const ClientCreds::Ptr &creds_arg)
1182 {
1183 if (!creds_arg)
1184 return;
1185
1186 // Override HTTP proxy credentials if provided dynamically
1188 http_proxy_options->username = creds_arg->get_http_proxy_username();
1190 http_proxy_options->password = creds_arg->get_http_proxy_password();
1191
1192 if (!creds_locked)
1193 {
1194 // if no username is defined in creds and userlocked_username is defined
1195 // in profile, set the creds username to be the userlocked_username
1196 if (!creds_arg->username_defined() && !userlocked_username.empty())
1197 {
1199 creds_arg->save_username_for_session_id();
1200 }
1201 creds = creds_arg;
1202 }
1203 }
1204
1206 {
1207 return !http_proxy_options;
1208 }
1209
1210 Time::Duration server_poll_timeout() const
1211 {
1212 return Time::Duration::seconds(server_poll_timeout_);
1213 }
1214
1216 {
1217 return *cli_stats;
1218 }
1220 {
1221 return cli_stats;
1222 }
1224 {
1225 return *cli_events;
1226 }
1228 {
1229 return client_lifecycle.get();
1230 }
1231
1232 int conn_timeout() const
1233 {
1234 return clientconf.connTimeout;
1235 }
1236
1238 {
1239 return asio_work_always_on_;
1240 }
1241
1243 {
1245 if (alt_proxy)
1246 {
1247 alt_proxy->precache(r);
1248 if (r)
1249 return r;
1250 }
1252 {
1253 http_proxy_options->proxy_server_precache(r);
1254 if (r)
1255 return r;
1256 }
1257 return remote_list;
1258 }
1259
1261 {
1262 now_.update();
1263 }
1264
1265 void finalize(const bool disconnected)
1266 {
1267 if (tun_factory)
1268 tun_factory->finalize(disconnected);
1269 }
1270
1271 private:
1273 {
1274 if (relay_mode && cp_relay)
1275 return *cp_relay;
1276 return *cp_main;
1277 }
1278
1280 const Config &config,
1281 const ParseClientConfig &pcc,
1282 const bool relay_mode)
1283 {
1284 // relay mode is null unless one of the below directives is defined
1285 if (relay_mode && !opt.exists("relay-mode"))
1287
1288 // load flags
1289 unsigned int lflags = SSLConfigAPI::LF_PARSE_MODE;
1290 if (relay_mode)
1292
1293 // client SSL config
1294 SSLLib::SSLAPI::Config::Ptr cc(new SSLLib::SSLAPI::Config());
1295 cc->set_external_pki_callback(config.external_pki, config.clientconf.external_pki_alias);
1296 cc->set_frame(frame);
1297 cc->set_flags(SSLConst::LOG_VERIFY_STATUS);
1298 cc->set_debug_level(config.clientconf.sslDebugLevel);
1299 cc->set_rng(rng);
1300 cc->set_local_cert_enabled(pcc.clientCertEnabled() && !config.clientconf.disableClientCert);
1301 /* load depends on private key password and legacy algorithms */
1302 cc->enable_legacy_algorithms(config.clientconf.enableLegacyAlgorithms);
1303 cc->set_private_key_password(config.clientconf.privateKeyPassword);
1304 cc->load(opt, lflags);
1305 cc->set_tls_version_min_override(config.clientconf.tlsVersionMinOverride);
1306 cc->set_tls_cert_profile_override(config.clientconf.tlsCertProfileOverride);
1307 cc->set_tls_cipher_list(config.clientconf.tlsCipherList);
1308 cc->set_tls_ciphersuite_list(config.clientconf.tlsCiphersuitesList);
1309
1310 // client ProtoContext config
1312 cp->ssl_factory = cc->new_factory();
1313 cp->relay_mode = relay_mode;
1314 cp->dc.set_factory(new CryptoDCSelect<SSLLib::CryptoAPI>(cp->ssl_factory->libctx(), frame, cli_stats, rng));
1315 cp->dc_deferred = true; // defer data channel setup until after options pull
1316 cp->tls_auth_factory.reset(new CryptoOvpnHMACFactory<SSLLib::CryptoAPI>());
1317 cp->tls_crypt_factory.reset(new CryptoTLSCryptFactory<SSLLib::CryptoAPI>());
1318 cp->tls_crypt_metadata_factory.reset(new CryptoTLSCryptMetadataFactory());
1319 cp->tlsprf_factory.reset(new CryptoTLSPRFFactory<SSLLib::CryptoAPI>());
1320 cp->load(opt, *proto_context_options, config.default_key_direction, false);
1321 cp->set_xmit_creds(!autologin || pcc.hasEmbeddedPassword() || autologin_sessions);
1322 cp->extra_peer_info = build_peer_info(config, pcc, autologin_sessions);
1323 cp->extra_peer_info_push_peerinfo = pcc.pushPeerInfo();
1324 cp->frame = frame;
1325 cp->now = &now_;
1326 cp->rng = rng;
1327 cp->prng = prng;
1328
1329 return cp;
1330 }
1331
1333 {
1334 // get current transport protocol
1335 const Protocol &transport_protocol = remote_list->current_transport_protocol();
1336
1337 // If we are connecting over a proxy, and TCP protocol is required, but current
1338 // transport protocol is NOT TCP, we will throw an internal error because this
1339 // should have been caught earlier in RemoteList::handle_proto_override.
1340
1341 // construct transport object
1342#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
1343 ExternalTransport::Config transconf;
1344 transconf.remote_list = remote_list;
1345 transconf.frame = frame;
1346 transconf.stats = cli_stats;
1347 transconf.socket_protect = socket_protect;
1350 transconf.protocol = transport_protocol;
1351 transport_factory = extern_transport_factory->new_transport_factory(transconf);
1352#ifdef OPENVPN_GREMLIN
1353 udpconf->gremlin_config = gremlin_config;
1354#endif
1355
1356#else
1357 if (dco)
1358 {
1359 DCO::TransportConfig transconf;
1360 transconf.protocol = transport_protocol;
1361 transconf.remote_list = remote_list;
1362 transconf.frame = frame;
1363 transconf.stats = cli_stats;
1365 transconf.socket_protect = socket_protect;
1367 }
1368 else if (alt_proxy)
1369 {
1370 if (alt_proxy->requires_tcp() && !transport_protocol.is_tcp())
1371 throw option_error(ERR_INVALID_CONFIG, "internal error: no TCP server entries for " + alt_proxy->name() + " transport");
1372 AltProxy::Config conf;
1373 conf.remote_list = remote_list;
1374 conf.frame = frame;
1375 conf.stats = cli_stats;
1378 conf.rng = rng;
1380 }
1381 else if (http_proxy_options)
1382 {
1383 if (!transport_protocol.is_tcp())
1384 throw option_error(ERR_INVALID_CONFIG, "internal error: no TCP server entries for HTTP proxy transport");
1385
1386 // HTTP Proxy transport
1388 httpconf->remote_list = remote_list;
1389 httpconf->frame = frame;
1390 httpconf->stats = cli_stats;
1391 httpconf->digest_factory.reset(new CryptoDigestFactory<SSLLib::CryptoAPI>(cp_main->ssl_factory->libctx()));
1392 httpconf->socket_protect = socket_protect;
1393 httpconf->http_proxy_options = http_proxy_options;
1394 httpconf->rng = rng;
1395#ifdef PRIVATE_TUNNEL_PROXY
1396 httpconf->skip_html = true;
1397#endif
1398 transport_factory = httpconf;
1399 }
1400 else
1401 {
1402 if (transport_protocol.is_udp())
1403 {
1404 // UDP transport
1406 udpconf->remote_list = remote_list;
1407 udpconf->frame = frame;
1408 udpconf->stats = cli_stats;
1409 udpconf->socket_protect = socket_protect;
1410 udpconf->server_addr_float = server_addr_float;
1411#ifdef OPENVPN_GREMLIN
1412 udpconf->gremlin_config = gremlin_config;
1413#endif
1414 transport_factory = udpconf;
1415 }
1416 else if (transport_protocol.is_tcp()
1417#ifdef OPENVPN_TLS_LINK
1418 || transport_protocol.is_tls()
1419#endif
1420 )
1421 {
1422 // TCP transport
1424 tcpconf->remote_list = remote_list;
1425 tcpconf->frame = frame;
1426 tcpconf->stats = cli_stats;
1427 tcpconf->socket_protect = socket_protect;
1428#ifdef OPENVPN_TLS_LINK
1429 if (transport_protocol.is_tls())
1430 tcpconf->use_tls = true;
1431 tcpconf->tls_ca = tls_ca;
1432#endif
1433#ifdef OPENVPN_GREMLIN
1434 tcpconf->gremlin_config = gremlin_config;
1435#endif
1436 transport_factory = tcpconf;
1437 }
1438 else
1439 throw option_error(ERR_INVALID_OPTION_VAL, "internal error: unknown transport protocol");
1440 }
1441#endif // OPENVPN_EXTERNAL_TRANSPORT_FACTORY
1443 }
1444 // General client options.
1446
1447 Time now_; // current time
1464 unsigned int tcp_queue_limit;
1467#ifdef OPENVPN_GREMLIN
1468 Gremlin::Config::Ptr gremlin_config;
1469#endif
1481#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
1482 ExternalTransport::Factory *extern_transport_factory;
1483#endif
1484#ifdef OPENVPN_TLS_LINK
1485 std::string tls_ca;
1486#endif
1487};
1488} // namespace openvpn
1489
1490#endif
bool username_defined() const
Definition clicreds.hpp:125
void set_username(const std::string &username_arg)
Definition clicreds.hpp:35
std::string get_http_proxy_username() const
Definition clicreds.hpp:115
bool http_proxy_password_defined() const
Definition clicreds.hpp:140
std::string get_http_proxy_password() const
Definition clicreds.hpp:120
bool session_id_defined() const
Definition clicreds.hpp:145
void set_password(const std::string &password_arg)
Definition clicreds.hpp:40
bool http_proxy_username_defined() const
Definition clicreds.hpp:135
void save_username_for_session_id()
Definition clicreds.hpp:164
std::map< std::string, std::vector< Option > > options_per_category
Definition cliopt.hpp:922
void add_failed_opt(const Option &o, const std::string &message, bool fatal_arg)
Definition cliopt.hpp:881
ClientCreds::Ptr creds
Definition cliopt.hpp:1462
void check_for_incompatible_options(const OptionList &opt)
Definition cliopt.hpp:641
std::unordered_set< std::string > settings_standalone_options
Definition cliopt.hpp:846
void showOptionsByFunction(const OptionList &opt, T func, const std::string &message, bool fatal, OptionErrors &errors)
Definition cliopt.hpp:1034
ReconnectNotify * reconnect_notify
Definition cliopt.hpp:1459
const SessionStats::Ptr & stats_ptr() const
Definition cliopt.hpp:1219
int conn_timeout() const
Definition cliopt.hpp:1232
ProtoContext::ProtoConfig & proto_config_cached(const bool relay_mode)
Definition cliopt.hpp:1272
void showUnusedOptionsByList(const OptionList &optlist, std::unordered_set< std::string > option_set, const std::string &message, bool fatal, OptionErrors &errors)
Definition cliopt.hpp:1024
std::unordered_set< std::string > settings_ignoreSilently
Definition cliopt.hpp:862
std::unordered_set< std::string > settings_feature_not_implemented_warn
Definition cliopt.hpp:795
void handle_unused_options(const OptionList &opt)
Definition cliopt.hpp:935
ProtoContext::ProtoConfig::Ptr cp_main
Definition cliopt.hpp:1452
PushOptionsBase::Ptr push_base
Definition cliopt.hpp:1476
static std::tuple< bool, std::string > check_dco_compatibility(const ClientAPI::ConfigCommon &config, const OptionList &opt)
Definition cliopt.hpp:599
std::unordered_set< std::string > settings_ignoreWithWarning
Definition cliopt.hpp:675
TransportClientFactory::Ptr transport_factory
Definition cliopt.hpp:1456
ClientEvent::Queue::Ptr cli_events
Definition cliopt.hpp:1461
HTTPProxyTransport::Options::Ptr http_proxy_options
Definition cliopt.hpp:1466
bool need_creds() const
Definition cliopt.hpp:1176
std::unordered_set< std::string > settings_removedOptions
Definition cliopt.hpp:859
unsigned int server_poll_timeout_
Definition cliopt.hpp:1463
ClientLifeCycle::Ptr client_lifecycle
Definition cliopt.hpp:1478
TunClientFactory::Ptr tun_factory
Definition cliopt.hpp:1457
void finalize(const bool disconnected)
Definition cliopt.hpp:1265
unsigned int tcp_queue_limit
Definition cliopt.hpp:1464
std::unordered_set< std::string > settings_script_plugin_feature
Definition cliopt.hpp:828
static PeerInfo::Set::Ptr build_peer_info(const Config &config, const ParseClientConfig &pcc, const bool autologin_sessions)
Definition cliopt.hpp:1048
std::unordered_set< std::string > settings_serverOnlyOptions
Definition cliopt.hpp:722
SocketProtect * socket_protect
Definition cliopt.hpp:1458
ProtoContext::ProtoConfig::Ptr cp_relay
Definition cliopt.hpp:1453
SessionStats::Ptr cli_stats
Definition cliopt.hpp:1460
bool server_poll_timeout_enabled() const
Definition cliopt.hpp:1205
RemoteList::Ptr remote_list
Definition cliopt.hpp:1454
bool asio_work_always_on() const
Definition cliopt.hpp:1237
ClientConfigParsed clientconf
Definition cliopt.hpp:1445
SessionStats & stats()
Definition cliopt.hpp:1215
bool pause_on_connection_timeout()
Definition cliopt.hpp:1127
void next(RemoteList::Advance type)
Definition cliopt.hpp:1111
static std::unordered_set< std::string > dco_incompatible_opts
Definition cliopt.hpp:590
ClientEvent::Queue & events()
Definition cliopt.hpp:1223
OptionList::FilterBase::Ptr pushed_options_filter
Definition cliopt.hpp:1477
ClientLifeCycle * lifecycle()
Definition cliopt.hpp:1227
std::unordered_set< std::string > settings_pushonlyoptions
Definition cliopt.hpp:811
Time::Duration server_poll_timeout() const
Definition cliopt.hpp:1210
bool retry_on_auth_failed() const
Definition cliopt.hpp:1134
ClientOptions(const OptionList &opt, const Config &config)
Definition cliopt.hpp:196
RandomAPI::Ptr prng
Definition cliopt.hpp:1449
std::string userlocked_username
Definition cliopt.hpp:1470
void submit_creds(const ClientCreds::Ptr &creds_arg)
Definition cliopt.hpp:1181
std::string load_transport_config()
Definition cliopt.hpp:1332
ProtoContext::ProtoConfig::Ptr proto_config(const OptionList &opt, const Config &config, const ParseClientConfig &pcc, const bool relay_mode)
Definition cliopt.hpp:1279
std::unordered_set< std::string > settings_feature_not_implemented_fatal
Definition cliopt.hpp:763
StrongRandomAPI::Ptr rng
Definition cliopt.hpp:1448
AltProxy::Ptr alt_proxy
Definition cliopt.hpp:1479
ProtoContextCompressionOptions::Ptr proto_context_options
Definition cliopt.hpp:1465
RemoteList::Ptr remote_list_precache() const
Definition cliopt.hpp:1242
Client::Config::Ptr client_config(const bool relay_mode)
Definition cliopt.hpp:1146
static Ptr parse(const OptionList &opt)
Definition httpcli.hpp:103
std::string cat(const std::string &name) const
Definition options.hpp:1269
void extend(const OptionList &other, FilterBase *filt=nullptr)
Definition options.hpp:1111
const IndexList & get_index(const std::string &name) const
Definition options.hpp:1250
T get_num(const std::string &name, const size_t idx, const T default_value) const
Definition options.hpp:1395
void touch(const std::string &name) const
Definition options.hpp:1435
const Option & get(const std::string &name) const
Definition options.hpp:1240
size_t n_unused(bool ignore_meta=false) const
Definition options.hpp:1491
const Option * get_ptr(const std::string &name) const
Definition options.hpp:1174
bool exists(const std::string &name) const
Definition options.hpp:1308
void touch(bool lightly=false) const
Definition options.hpp:378
const std::string & get(const size_t index, const size_t max_len) const
Definition options.hpp:184
size_t size() const
Definition options.hpp:320
const std::string & embeddedPassword() const
const PeerInfo::Set * peerInfoUV() const
const std::string & userlockedUsername() const
RCPtr< ProtoConfig > Ptr
Definition proto.hpp:339
bool is_udp() const
Definition protocol.hpp:75
bool is_tls() const
Definition protocol.hpp:83
static Protocol parse(const std::string &str, const AllowSuffix allow_suffix, const char *title=nullptr)
Definition protocol.hpp:157
bool is_tcp() const
Definition protocol.hpp:79
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
Definition rc.hpp:290
T * get() const noexcept
Returns the raw pointer to the object T, or nullptr.
Definition rc.hpp:321
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
Definition rc.hpp:908
virtual bool pause_on_connection_timeout()=0
void set_server_override(const std::string &server_override)
void next(Advance type=Advance::Addr)
void handle_proto_override(const Protocol &proto_override, const bool tcp_proxy_enabled)
bool defined() const
void set_enable_cache(const bool enable_cache_arg)
void set_random(const RandomAPI::Ptr &rng_arg)
void set_proto_version_override(const IP::Addr::Version v)
void set_port_override(const std::string &port_override)
const Protocol & current_transport_protocol() const
std::string current_server_host() const
void stop()
Definition stop.hpp:83
static TriStateSetting parse(const std::string &str)
TunBuilder methods, loosely based on the Android VpnService.Builder abstraction.
Definition base.hpp:42
static TunBuilderSetup::Factory::Ptr new_agent(const OptionList &opt)
Definition cmdagent.hpp:45
static TunWin::SetupFactory::Ptr new_agent(const OptionList &opt)
Definition cmdagent.hpp:42
#define OPENVPN_UNUSED_OPTIONS
Definition cliopt.hpp:103
#define OPENVPN_LOG_NTNL(args)
#define OPENVPN_LOG(args)
@ TAP_NOT_SUPPORTED
Definition error.hpp:45
auto join(const T &strings, const typename T::value_type &delim, const bool tail=false)
Definition string.hpp:481
unsigned int parse_tun_mtu_max(const OptionList &opt, unsigned int default_value)
Definition tunmtu.hpp:28
Frame::Ptr frame_init(const bool align_adjust_3_1, const size_t tun_mtu_max, const size_t control_channel_payload, const bool verbose)
@ TUN_MTU_DEFAULT
Definition tunmtu.hpp:20
unsigned int parse_tun_mtu(const OptionList &opt, unsigned int default_value)
Definition tunmtu.hpp:23
const std::string get_ssl_library_version()
Definition sslctx.hpp:1701
SocketProtect * socket_protect
Definition altproxy.hpp:42
StrongRandomAPI::Ptr rng
Definition altproxy.hpp:39
SessionStats::Ptr stats
Definition altproxy.hpp:37
DigestFactory::Ptr digest_factory
Definition altproxy.hpp:40
RemoteList::Ptr remote_list
Definition altproxy.hpp:34
virtual TransportClientFactory::Ptr new_transport_client_factory(const Config &)=0
virtual std::string name() const =0
virtual bool next()=0
virtual void precache(RemoteList::Ptr &r)=0
virtual bool requires_tcp() const =0
virtual void set_enable_cache(const bool enable_cache)=0
TriStateSetting allowUnusedAddrFamilies
Definition cliopt.hpp:137
std::string external_pki_alias
Definition cliopt.hpp:140
IP::Addr::Version proto_version_override
Definition cliopt.hpp:133
void import_client_settings(const ClientAPI::Config &config)
Definition cliopt.hpp:115
ReconnectNotify * reconnect_notify
Definition cliopt.hpp:180
ClientEvent::Queue::Ptr cli_events
Definition cliopt.hpp:161
ClientConfigParsed clientconf
Definition cliopt.hpp:157
PeerInfo::Set::Ptr extra_peer_info
Definition cliopt.hpp:168
RemoteList::RemoteOverride * remote_override
Definition cliopt.hpp:181
ExternalPKIBase * external_pki
Definition cliopt.hpp:178
SessionStats::Ptr cli_stats
Definition cliopt.hpp:160
ProtoContextCompressionOptions::Ptr proto_context_options
Definition cliopt.hpp:162
HTTPProxyTransport::Options::Ptr http_proxy_options
Definition cliopt.hpp:163
SocketProtect * socket_protect
Definition cliopt.hpp:179
RemoteList::Ptr remote_list
Definition dco.hpp:47
SessionStats::Ptr stats
Definition dco.hpp:50
SocketProtect * socket_protect
Definition dco.hpp:51
bool allow_local_dns_resolvers
Definition dco.hpp:73
TunProp::Config tun_prop
Definition dco.hpp:70
virtual TunClientFactory::Ptr new_tun_factory(const TunConfig &conf, const OptionList &opt)=0
virtual TransportClientFactory::Ptr new_transport_factory(const TransportConfig &conf)=0
TunProp::Config tun_prop
Definition config.hpp:26
SessionStats::Ptr stats
Definition config.hpp:28
unsigned int mssfix_ctrl
Definition mssparms.hpp:84
virtual void finalize(const bool disconnected)
Definition tunbase.hpp:126
RemoteList::Ptr remote_list
Definition tunprop.hpp:74
bool dhcp_search_domains_as_split_domains
Definition tunprop.hpp:60
std::string session_name
Definition tunprop.hpp:53
std::ostringstream os
static const char config[]
const char message[]
const std::string optname