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