OpenVPN 3 Core Library
Loading...
Searching...
No Matches
cliopthelper.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// A preliminary parser for OpenVPN client configuration files.
13
14#ifndef OPENVPN_CLIENT_CLIOPTHELPER_H
15#define OPENVPN_CLIENT_CLIOPTHELPER_H
16
17#include <vector>
18#include <string>
19#include <sstream>
20#include <utility>
21
22#ifdef HAVE_CONFIG_JSONCPP
23#include "json/json.h"
24#endif /* HAVE_CONFIG_JSONCPP */
25
36#include <openvpn/ssl/proto.hpp>
39
40namespace openvpn {
42{
43 public:
45 {
46 std::string server;
47 std::string friendlyName;
48 };
49
50 struct ServerList : public std::vector<ServerEntry>
51 {
52 };
53
55 {
56 std::string host;
57 std::string port;
58 std::string proto;
59 };
60
62 {
63 reset_pod();
64 }
65
67 {
68 try
69 {
70 // reset POD types
71 reset_pod();
72
73 // limits
74 const size_t max_server_list_size = ProfileParseLimits::MAX_SERVER_LIST_SIZE;
75
76 // setenv UV_x
77 PeerInfo::Set::Ptr peer_info_uv(new PeerInfo::Set);
78
79 // process setenv directives
80 {
81 const OptionList::IndexList *se = options.get_index_ptr("setenv");
82 if (se)
83 {
84 for (OptionList::IndexList::const_iterator i = se->begin(); i != se->end(); ++i)
85 {
86 const Option &o = options[*i];
87 o.touch();
88 const std::string arg1 = o.get_optional(1, 256);
89
90 // server-locked profiles not supported
91 if (arg1 == "GENERIC_CONFIG")
92 {
93 error_ = true;
94 message_ = "ERR_PROFILE_SERVER_LOCKED_UNSUPPORTED: server locked profiles are currently unsupported";
95 return;
96 }
97 else if (arg1 == "ALLOW_PASSWORD_SAVE")
98 allowPasswordSave_ = parse_bool(o, "setenv ALLOW_PASSWORD_SAVE", 2);
99 else if (arg1 == "CLIENT_CERT")
100 clientCertEnabled_ = parse_bool(o, "setenv CLIENT_CERT", 2);
101 else if (arg1 == "USERNAME")
102 userlockedUsername_ = o.get(2, 256);
103 else if (arg1 == "FRIENDLY_NAME")
104 friendlyName_ = o.get(2, 256);
105 else if (arg1 == "SERVER")
106 {
107 const std::string &serv = o.get(2, 256);
108 std::vector<std::string> slist = Split::by_char<std::vector<std::string>, NullLex, Split::NullLimit>(serv, '/', 0, 1);
109 ServerEntry se;
110 if (slist.size() == 1)
111 {
112 se.server = slist[0];
113 se.friendlyName = slist[0];
114 }
115 else if (slist.size() == 2)
116 {
117 se.server = slist[0];
118 se.friendlyName = slist[1];
119 }
120 if (!se.server.empty() && !se.friendlyName.empty() && serverList_.size() < max_server_list_size)
121 serverList_.push_back(std::move(se));
122 }
123 else if (arg1 == "PUSH_PEER_INFO")
124 pushPeerInfo_ = true;
125 else if (string::starts_with(arg1, "UV_") && arg1.length() >= 4 && string::is_word(arg1))
126 {
127 const std::string value = o.get_optional(2, 256);
128 if (string::is_printable(value))
129 peer_info_uv->emplace_back(arg1, value);
130 }
131 }
132 }
133 }
134
135 // Alternative to "setenv CLIENT_CERT 0". Note that as of OpenVPN 2.3, this option
136 // is only supported server-side, so this extends its meaning into the client realm.
137 if (options.exists("client-cert-not-required"))
138 clientCertEnabled_ = false;
139
140 // userlocked username
141 {
142 const Option *o = options.get_ptr("USERNAME");
143 if (o)
144 userlockedUsername_ = o->get(1, 256);
145 }
146
147 // userlocked username/password via <auth-user-pass>
148 std::vector<std::string> user_pass;
149 const bool auth_user_pass = parse_auth_user_pass(options, &user_pass);
150 if (auth_user_pass && user_pass.size() >= 1)
151 {
153 if (user_pass.size() >= 2)
154 {
157 }
158 }
159
160 // External PKI
162
163 // allow password save
164 {
165 const Option *o = options.get_ptr("allow-password-save");
166 if (o)
167 allowPasswordSave_ = parse_bool(*o, "allow-password-save", 1);
168 }
169
170 // autologin
171 {
172 autologin_ = is_autologin(options, auth_user_pass, user_pass);
173 if (autologin_)
174 allowPasswordSave_ = false; // saving passwords is incompatible with autologin
175 }
176
177 // static challenge
178 {
179 const Option *o = options.get_ptr("static-challenge");
180 if (o)
181 {
182 staticChallenge_ = o->get(1, 256);
183 if (o->get_optional(2, 16) == "1")
185 }
186 }
187
188 // validate remote list - don't randomize it at this point
189 RandomAPI::Ptr no_rng;
190 remoteList.reset(new RemoteList(options, "", 0, nullptr, no_rng));
191 {
192 if (remoteList->defined())
193 {
195 firstRemoteListItem_.host = ri->server_host;
196 firstRemoteListItem_.port = ri->server_port;
197 if (ri->transport_protocol.is_udp())
199 else if (ri->transport_protocol.is_tcp())
200 firstRemoteListItem_.proto = "tcp-client";
201 }
202 }
203
204 // determine if private key is encrypted
205 if (!externalPki_)
206 {
207 const Option *o = options.get_ptr("key");
208 if (o)
209 {
210 const std::string &key_txt = o->get(1, Option::MULTILINE);
211 privateKeyPasswordRequired_ = (key_txt.find("-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\n") != std::string::npos
212 || key_txt.find("-----BEGIN EC PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\n") != std::string::npos
213 || key_txt.find("-----BEGIN ENCRYPTED PRIVATE KEY-----") != std::string::npos);
214 }
215 }
216
217 {
218 const Option *o = options.get_ptr("ca");
219 if (o)
221 }
222
223 // profile name
224 {
225 const Option *o = options.get_ptr("PROFILE");
226 if (o)
227 {
228 // take PROFILE substring up to '/'
229 const std::string &pn = o->get(1, 256);
230 const size_t slashpos = pn.find('/');
231 if (slashpos != std::string::npos)
232 profileName_ = pn.substr(0, slashpos);
233 else
234 profileName_ = pn;
235 }
236 else
237 {
238 if (remoteList)
239 profileName_ = remoteList->get_item(0)->server_host;
240 }
241
242 // windows-driver
243 {
244 const Option *o = options.get_ptr("windows-driver");
245 if (o)
246 {
247 windowsDriver_ = o->get(1, 256);
248 }
249 }
250 }
251
252 // friendly name
253 {
254 const Option *o = options.get_ptr("FRIENDLY_NAME");
255 if (o)
256 friendlyName_ = o->get(1, 256);
257 }
258
259 // server list
260 {
261 const Option *o = options.get_ptr("HOST_LIST");
262 if (o)
263 {
264 SplitLines in(o->get(1, 4096 | Option::MULTILINE), 0);
265 while (in(true))
266 {
267 ServerEntry se;
268 se.server = in.line_ref();
269 se.friendlyName = se.server;
270 Option::validate_string("HOST_LIST server", se.server, 256);
271 Option::validate_string("HOST_LIST friendly name", se.friendlyName, 256);
272 if (!se.server.empty() && !se.friendlyName.empty() && serverList_.size() < max_server_list_size)
273 serverList_.push_back(std::move(se));
274 }
275 }
276 }
277
278 // push-peer-info
279 {
280 if (options.exists("push-peer-info"))
281 pushPeerInfo_ = true;
282 if (pushPeerInfo_)
283 peerInfoUV_ = std::move(peer_info_uv);
284 }
285
286 // dev name
287 {
288 const Option *o = options.get_ptr("dev");
289 if (o)
290 {
291 dev = o->get(1, 256);
292 }
293 }
294
295 // protocol configuration
296 {
300 protoConfig->load(options, ProtoContextCompressionOptions(), -1, false);
301 }
302
303 unsigned int lflags = SSLConfigAPI::LF_PARSE_MODE;
304
305 // ssl lib configuration
306 try
307 {
308 sslConfig.reset(new SSLLib::SSLAPI::Config());
309 sslConfig->set_rng(new SSLLib::RandomAPI());
310 sslConfig->load(options, lflags);
311 }
312 catch (...)
313 {
314 sslConfig.reset();
315 }
316 }
317 catch (const option_error &e)
318 {
319 error_ = true;
320 message_ = Unicode::utf8_printable<std::string>(e.what(), 256);
321 }
322 catch (const std::exception &e)
323 {
324 error_ = true;
325 message_ = Unicode::utf8_printable<std::string>(std::string("ERR_PROFILE_GENERIC: ") + e.what(), 256);
326 }
327 }
328
329 static ParseClientConfig parse(const std::string &content)
330 {
331 return parse(content, nullptr);
332 }
333
334 static ParseClientConfig parse(const std::string &content, OptionList::KeyValueList *content_list)
335 {
336 OptionList options;
337 return parse(content, content_list, options);
338 }
339
340 static ParseClientConfig parse(const std::string &content,
341 OptionList::KeyValueList *content_list,
342 OptionList &options)
343 {
344 try
345 {
346 OptionList::Limits limits("profile is too large",
352 options.clear();
353 options.parse_from_config(content, &limits);
354 options.parse_meta_from_config(content, "OVPN_ACCESS_SERVER", &limits);
355 if (content_list)
356 {
357 content_list->preprocess();
358 options.parse_from_key_value_list(*content_list, "OVPN_ACCESS_SERVER", &limits);
359 }
360 process_setenv_opt(options);
361 options.update_map();
362
363 // add in missing options
364 bool added = false;
365
366 /* client
367 Ensure that we always look at both options, so they register as touched */
368 const bool tls_client_exists = options.exists("tls-client");
369 const bool pull_exists = options.exists("pull");
370
371 if (tls_client_exists && pull_exists)
372 {
373 Option opt;
374 opt.push_back("client");
375 options.push_back(std::move(opt));
376 added = true;
377 }
378
379 // dev
380 if (!options.exists("dev"))
381 {
382 Option opt;
383 opt.push_back("dev");
384 opt.push_back("tun");
385 options.push_back(std::move(opt));
386 added = true;
387 }
388 if (added)
389 options.update_map();
390
391 return ParseClientConfig(options);
392 }
393 catch (const std::exception &e)
394 {
396 ret.error_ = true;
397 ret.message_ = Unicode::utf8_printable<std::string>(std::string("ERR_PROFILE_GENERIC: ") + e.what(), 256);
398 return ret;
399 }
400 }
401
402 // true if error
403 bool error() const
404 {
405 return error_;
406 }
407
408 // if error, message given here
409 const std::string &message() const
410 {
411 return message_;
412 }
413
414 // this username must be used with profile
415 const std::string &userlockedUsername() const
416 {
417 return userlockedUsername_;
418 }
419
420 // profile name of config
421 const std::string &profileName() const
422 {
423 return profileName_;
424 }
425
426 // "friendly" name of config
427 const std::string &friendlyName() const
428 {
429 return friendlyName_;
430 }
431
432 // true: no creds required, false: username/password required
433 bool autologin() const
434 {
435 return autologin_;
436 }
437
438 // profile embedded password via <auth-user-pass>
440 {
442 }
443 const std::string &embeddedPassword() const
444 {
445 return embeddedPassword_;
446 }
447
448 // true: no client cert/key required, false: client cert/key required
449 bool clientCertEnabled() const
450 {
451 return clientCertEnabled_;
452 }
453
454 // if true, this is an External PKI profile (no cert or key directives)
455 bool externalPki() const
456 {
457 return externalPki_;
458 }
459
460 std::string vpnCa() const
461 {
462 return vpnCa_;
463 }
464
465 // static challenge, may be empty, ignored if autologin
466 const std::string &staticChallenge() const
467 {
468 return staticChallenge_;
469 }
470
471 // true if static challenge response should be echoed to UI, ignored if autologin
473 {
475 }
476
477 // true if this profile requires a private key password
479 {
481 }
482
483 // true if user is allowed to save authentication password in UI
484 bool allowPasswordSave() const
485 {
486 return allowPasswordSave_;
487 }
488
489 // true if "setenv PUSH_PEER_INFO" or "push-peer-info" are defined
490 bool pushPeerInfo() const
491 {
492 return pushPeerInfo_;
493 }
494
495 // "setenv UV_x" directives if pushPeerInfo() is true
497 {
498 return peerInfoUV_.get();
499 }
500
501 // optional list of user-selectable VPN servers
502 const ServerList &serverList() const
503 {
504 return serverList_;
505 }
506
507 // return first remote directive in config
509 {
511 }
512
513 const std::string &windowsDriver() const
514 {
515 return windowsDriver_;
516 }
517
518 std::string to_string() const
519 {
520 std::ostringstream os;
521 os << "user=" << userlockedUsername_
522 << " pn=" << profileName_
523 << " fn=" << friendlyName_
524 << " auto=" << autologin_
525 << " embed_pw=" << hasEmbeddedPassword_
526 << " epki=" << externalPki_
527 << " schal=" << staticChallenge_
528 << " scecho=" << staticChallengeEcho_;
529 return os.str();
530 }
531
532 std::string to_string_config() const
533 {
534 std::ostringstream os;
535
536 os << "client" << std::endl;
537 os << "dev " << dev << std::endl;
538 os << "dev-type " << protoConfig->layer.dev_type() << std::endl;
539 for (size_t i = 0; i < remoteList->size(); i++)
540 {
542
543 os << "remote " << item->server_host << " " << item->server_port;
544 const char *proto = item->transport_protocol.protocol_to_string();
545 if (proto)
546 os << " " << proto;
547 os << std::endl;
548 }
549 if (protoConfig->tls_crypt_context)
550 {
551 os << "<tls-crypt>" << std::endl
552 << protoConfig->tls_crypt_key.render() << "</tls-crypt>"
553 << std::endl;
554 }
555 else if (protoConfig->tls_auth_context)
556 {
557 os << "<tls-auth>" << std::endl
558 << protoConfig->tls_auth_key.render() << "</tls-auth>"
559 << std::endl;
560 os << "key_direction " << protoConfig->key_direction << std::endl;
561 }
562
563 // SSL parameters
564 if (sslConfig)
565 {
566 print_pem(os, "ca", sslConfig->extract_ca());
567 print_pem(os, "crl", sslConfig->extract_crl());
568 print_pem(os, "key", sslConfig->extract_private_key());
569 print_pem(os, "cert", sslConfig->extract_cert());
570
571 std::vector<std::string> extra_certs = sslConfig->extract_extra_certs();
572 if (extra_certs.size() > 0)
573 {
574 os << "<extra-certs>" << std::endl;
575 for (auto &cert : extra_certs)
576 {
577 os << cert;
578 }
579 os << "</extra-certs>" << std::endl;
580 }
581 }
582
583 os << "cipher " << CryptoAlgs::name(protoConfig->dc.cipher(), "none")
584 << std::endl;
585 os << "auth " << CryptoAlgs::name(protoConfig->dc.digest(), "none")
586 << std::endl;
587 const char *comp = protoConfig->comp_ctx.method_to_string();
588 if (comp)
589 os << "compress " << comp << std::endl;
590 os << "keepalive " << protoConfig->keepalive_ping.to_seconds() << " "
591 << protoConfig->keepalive_timeout.to_seconds() << std::endl;
592 os << "tun-mtu " << protoConfig->tun_mtu << std::endl;
593 os << "reneg-sec " << protoConfig->renegotiate.to_seconds() << std::endl;
594
595 return os.str();
596 }
597
598#ifdef HAVE_CONFIG_JSONCPP
599
600 std::string to_json_config() const
601 {
602 std::ostringstream os;
603
604 Json::Value root(Json::objectValue);
605
606 root["mode"] = Json::Value("client");
607 root["dev"] = Json::Value(dev);
608 root["dev-type"] = Json::Value(protoConfig->layer.dev_type());
609 root["remotes"] = Json::Value(Json::arrayValue);
610 for (size_t i = 0; i < remoteList->size(); i++)
611 {
613
614 Json::Value el = Json::Value(Json::objectValue);
615 el["address"] = Json::Value(item->server_host);
616 el["port"] = Json::Value((Json::UInt)std::stoi(item->server_port));
617 if (item->transport_protocol() == Protocol::NONE)
618 el["proto"] = Json::Value("adaptive");
619 else
620 el["proto"] = Json::Value(item->transport_protocol.str());
621
622 root["remotes"].append(el);
623 }
624 if (protoConfig->tls_crypt_context)
625 {
626 root["tls_wrap"] = Json::Value(Json::objectValue);
627 root["tls_wrap"]["mode"] = Json::Value("tls_crypt");
628 root["tls_wrap"]["key"] = Json::Value(protoConfig->tls_key.render());
629 }
630 else if (protoConfig->tls_auth_context)
631 {
632 root["tls_wrap"] = Json::Value(Json::objectValue);
633 root["tls_wrap"]["mode"] = Json::Value("tls_auth");
634 root["tls_wrap"]["key_direction"] = Json::Value((Json::UInt)protoConfig->key_direction);
635 root["tls_wrap"]["key"] = Json::Value(protoConfig->tls_key.render());
636 }
637
638 // SSL parameters
639 if (sslConfig)
640 {
641 json_pem(root, "ca", sslConfig->extract_ca());
642 json_pem(root, "crl", sslConfig->extract_crl());
643 json_pem(root, "cert", sslConfig->extract_cert());
644
645 // JSON config is aimed to users, therefore we do not export the raw private
646 // key, but only some basic info
647 PKType::Type priv_key_type = sslConfig->private_key_type();
648 if (priv_key_type != PKType::PK_NONE)
649 {
650 root["key"] = Json::Value(Json::objectValue);
651 root["key"]["type"] = Json::Value(sslConfig->private_key_type_string());
652 root["key"]["length"] = Json::Value((Json::UInt)sslConfig->private_key_length());
653 }
654
655 std::vector<std::string> extra_certs = sslConfig->extract_extra_certs();
656 if (extra_certs.size() > 0)
657 {
658 root["extra_certs"] = Json::Value(Json::arrayValue);
659 for (auto cert = extra_certs.begin(); cert != extra_certs.end(); cert++)
660 {
661 if (!cert->empty())
662 root["extra_certs"].append(Json::Value(*cert));
663 }
664 }
665 }
666
667 root["cipher"] = Json::Value(CryptoAlgs::name(protoConfig->dc.cipher(), "none"));
668 root["auth"] = Json::Value(CryptoAlgs::name(protoConfig->dc.digest(), "none"));
669 if (protoConfig->comp_ctx.type() != CompressContext::NONE)
670 root["compression"] = Json::Value(protoConfig->comp_ctx.str());
671 root["keepalive"] = Json::Value(Json::objectValue);
672 root["keepalive"]["ping"] = Json::Value((Json::UInt)protoConfig->keepalive_ping.to_seconds());
673 root["keepalive"]["timeout"] = Json::Value((Json::UInt)protoConfig->keepalive_timeout.to_seconds());
674 root["tun_mtu"] = Json::Value((Json::UInt)protoConfig->tun_mtu);
675 root["reneg_sec"] = Json::Value((Json::UInt)protoConfig->renegotiate.to_seconds());
676
677 return root.toStyledString();
678 }
679
680#endif /* HAVE_CONFIG_JSONCPP */
681
682 private:
683 static void print_pem(std::ostream &os, std::string label, std::string pem)
684 {
685 if (pem.empty())
686 return;
687 os << "<" << label << ">" << std::endl
688 << pem << "</" << label << ">" << std::endl;
689 }
690
691#ifdef HAVE_CONFIG_JSONCPP
692
693 static void json_pem(Json::Value &obj, std::string key, std::string pem)
694 {
695 if (pem.empty())
696 return;
697 obj[key] = Json::Value(pem);
698 }
699
700#endif /* HAVE_CONFIG_JSONCPP */
701
702 static bool parse_auth_user_pass(const OptionList &options, std::vector<std::string> *user_pass)
703 {
704 return UserPass::parse(options, "auth-user-pass", 0, user_pass);
705 }
706
707 static void process_setenv_opt(OptionList &options)
708 {
709 for (OptionList::iterator i = options.begin(); i != options.end(); ++i)
710 {
711 Option &o = *i;
712 if (o.size() >= 3 && o.ref(0) == "setenv" && o.ref(1) == "opt")
713 {
714 o.remove_first(2);
715 o.enableWarnOnly();
716 }
717 }
718 }
719
720 static bool is_autologin(const OptionList &options,
721 const bool auth_user_pass,
722 const std::vector<std::string> &user_pass)
723 {
724 if (auth_user_pass && user_pass.size() >= 2) // embedded password?
725 return true;
726 else
727 {
728 const Option *autologin = options.get_ptr("AUTOLOGIN");
729 if (autologin)
730 return string::is_true(autologin->get_optional(1, 16));
731 else
732 {
733 bool ret = !auth_user_pass;
734 if (ret)
735 {
736 // External PKI profiles from AS don't declare auth-user-pass,
737 // and we have no way of knowing if they are autologin unless
738 // we examine their cert, which requires accessing the system-level
739 // cert store on the client. For now, we are going to assume
740 // that External PKI profiles from the AS are always userlogin,
741 // unless explicitly overriden by AUTOLOGIN above.
742 if (options.exists("EXTERNAL_PKI"))
743 return false;
744 }
745 return ret;
746 }
747 }
748 }
749
750 static bool is_external_pki(const OptionList &options)
751 {
752 const Option *epki = options.get_ptr("EXTERNAL_PKI");
753 if (epki)
754 return string::is_true(epki->get_optional(1, 16));
755 else
756 {
757 const Option *cert = options.get_ptr("cert");
758 const Option *key = options.get_ptr("key");
759 return !cert || !key;
760 }
761 }
762
770
771 bool parse_bool(const Option &o, const std::string &title, const size_t index)
772 {
773 const std::string parm = o.get(index, 16);
774 if (parm == "0")
775 return false;
776 else if (parm == "1")
777 return true;
778 else
779 throw option_error(ERR_INVALID_OPTION_VAL, title + ": parameter must be 0 or 1");
780 }
781
782 bool error_;
783 std::string message_;
785 std::string profileName_;
786 std::string friendlyName_;
790 std::string vpnCa_;
792 std::string staticChallenge_;
798 std::string embeddedPassword_;
803 SSLLib::SSLAPI::Config::Ptr sslConfig;
804 std::string dev;
805 std::string windowsDriver_;
806};
807} // namespace openvpn
808
809#endif
void parse_from_config(const std::string &str, Limits *lim)
Definition options.hpp:985
void parse_from_key_value_list(const KeyValueList &list, const std::string &meta_tag, Limits *lim)
Definition options.hpp:959
const IndexList * get_index_ptr(const std::string &name) const
Definition options.hpp:1276
const Option * get_ptr(const std::string &name) const
Definition options.hpp:1186
std::vector< unsigned int > IndexList
Definition options.hpp:520
void parse_meta_from_config(const std::string &str, const std::string &tag, Limits *lim)
Definition options.hpp:1052
bool exists(const std::string &name) const
Definition options.hpp:1325
std::string get_optional(const size_t index, const size_t max_len) const
Definition options.hpp:194
void push_back(const std::string &item)
Definition options.hpp:335
void touch(bool lightly=false) const
Definition options.hpp:385
const std::string & get(const size_t index, const size_t max_len) const
Definition options.hpp:187
static void validate_string(const std::string &name, const std::string &str, const size_t max_len)
Definition options.hpp:165
size_t size() const
Definition options.hpp:327
void enableWarnOnly()
Definition options.hpp:400
void remove_first(const size_t n_elements)
Definition options.hpp:373
const std::string & ref(const size_t i) const
Definition options.hpp:353
static ParseClientConfig parse(const std::string &content)
static bool is_autologin(const OptionList &options, const bool auth_user_pass, const std::vector< std::string > &user_pass)
const std::string & windowsDriver() const
ProtoContext::ProtoConfig::Ptr protoConfig
static bool parse_auth_user_pass(const OptionList &options, std::vector< std::string > *user_pass)
const std::string & profileName() const
const std::string & friendlyName() const
bool parse_bool(const Option &o, const std::string &title, const size_t index)
static bool is_external_pki(const OptionList &options)
SSLLib::SSLAPI::Config::Ptr sslConfig
static void process_setenv_opt(OptionList &options)
const std::string & embeddedPassword() const
const PeerInfo::Set * peerInfoUV() const
const RemoteItem & firstRemoteListItem() const
PeerInfo::Set::Ptr peerInfoUV_
std::string vpnCa() const
static ParseClientConfig parse(const std::string &content, OptionList::KeyValueList *content_list)
static void print_pem(std::ostream &os, std::string label, std::string pem)
const std::string & staticChallenge() const
const std::string & message() const
ParseClientConfig(const OptionList &options)
const std::string & userlockedUsername() const
const ServerList & serverList() const
std::string to_string_config() const
bool privateKeyPasswordRequired() const
static ParseClientConfig parse(const std::string &content, OptionList::KeyValueList *content_list, OptionList &options)
std::string to_string() const
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
bool defined() const
Item::Ptr get_item(const size_t index) const
size_t size() const
std::string & line_ref()
const char * name(const KeyDerivation kd)
bool parse(const OptionList &options, const std::string &opt_name, const unsigned int flags, std::vector< std::string > *user_pass)
interpret user-pass option
Definition userpass.hpp:74
std::string root(const std::string &basename)
Definition path.hpp:171
bool is_true(const std::string &str)
Definition string.hpp:73
bool starts_with(const STRING &str, const std::string &prefix)
Definition string.hpp:79
bool is_printable(const char c)
Definition string.hpp:299
bool is_word(const std::string &str)
Definition string.hpp:320
std::string ret
std::ostringstream os
const std::vector< std::string > user_pass