14#ifndef OPENVPN_CLIENT_CLIOPTHELPER_H
15#define OPENVPN_CLIENT_CLIOPTHELPER_H
22#ifdef HAVE_CONFIG_JSONCPP
84 for (OptionList::IndexList::const_iterator i = se->begin(); i != se->end(); ++i)
86 const Option &o = options[*i];
91 if (arg1 ==
"GENERIC_CONFIG")
94 message_ =
"ERR_PROFILE_SERVER_LOCKED_UNSUPPORTED: server locked profiles are currently unsupported";
97 else if (arg1 ==
"ALLOW_PASSWORD_SAVE")
99 else if (arg1 ==
"CLIENT_CERT")
101 else if (arg1 ==
"USERNAME")
103 else if (arg1 ==
"FRIENDLY_NAME")
105 else if (arg1 ==
"SERVER")
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);
110 if (slist.size() == 1)
113 se.friendlyName = slist[0];
115 else if (slist.size() == 2)
117 se.server = slist[0];
118 se.friendlyName = slist[1];
120 if (!se.server.empty() && !se.friendlyName.empty() &&
serverList_.size() < max_server_list_size)
123 else if (arg1 ==
"PUSH_PEER_INFO")
129 peer_info_uv->emplace_back(arg1, value);
137 if (options.
exists(
"client-cert-not-required"))
150 if (auth_user_pass &&
user_pass.size() >= 1)
197 if (ri->transport_protocol.is_udp())
199 else if (ri->transport_protocol.is_tcp())
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);
229 const std::string &pn = o->
get(1, 256);
230 const size_t slashpos = pn.find(
'/');
231 if (slashpos != std::string::npos)
280 if (options.
exists(
"push-peer-info"))
309 sslConfig->set_rng(
new SSLLib::RandomAPI());
317 catch (
const option_error &e)
320 message_ = Unicode::utf8_printable<std::string>(e.what(), 256);
322 catch (
const std::exception &e)
325 message_ = Unicode::utf8_printable<std::string>(std::string(
"ERR_PROFILE_GENERIC: ") + e.what(), 256);
331 return parse(content,
nullptr);
337 return parse(content, content_list, options);
368 const bool tls_client_exists = options.
exists(
"tls-client");
369 const bool pull_exists = options.
exists(
"pull");
371 if (tls_client_exists && pull_exists)
375 options.push_back(std::move(opt));
380 if (!options.
exists(
"dev"))
385 options.push_back(std::move(opt));
393 catch (
const std::exception &e)
397 ret.message_ = Unicode::utf8_printable<std::string>(std::string(
"ERR_PROFILE_GENERIC: ") + e.what(), 256);
520 std::ostringstream
os;
534 std::ostringstream
os;
536 os <<
"client" << std::endl;
537 os <<
"dev " <<
dev << std::endl;
538 os <<
"dev-type " <<
protoConfig->layer.dev_type() << std::endl;
543 os <<
"remote " << item->server_host <<
" " << item->server_port;
544 const char *proto = item->transport_protocol.protocol_to_string();
551 os <<
"<tls-crypt>" << std::endl
552 <<
protoConfig->tls_crypt_key.render() <<
"</tls-crypt>"
557 os <<
"<tls-auth>" << std::endl
558 <<
protoConfig->tls_auth_key.render() <<
"</tls-auth>"
560 os <<
"key_direction " <<
protoConfig->key_direction << std::endl;
571 std::vector<std::string> extra_certs =
sslConfig->extract_extra_certs();
572 if (extra_certs.size() > 0)
574 os <<
"<extra-certs>" << std::endl;
575 for (
auto &cert : extra_certs)
579 os <<
"</extra-certs>" << std::endl;
587 const char *comp =
protoConfig->comp_ctx.method_to_string();
589 os <<
"compress " << comp << std::endl;
590 os <<
"keepalive " <<
protoConfig->keepalive_ping.to_seconds() <<
" "
591 <<
protoConfig->keepalive_timeout.to_seconds() << std::endl;
593 os <<
"reneg-sec " <<
protoConfig->renegotiate.to_seconds() << std::endl;
598#ifdef HAVE_CONFIG_JSONCPP
600 std::string to_json_config()
const
602 std::ostringstream
os;
604 Json::Value root(Json::objectValue);
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);
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));
618 el[
"proto"] = Json::Value(
"adaptive");
620 el[
"proto"] = Json::Value(item->transport_protocol.str());
622 root[
"remotes"].append(el);
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());
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);
641 json_pem(root,
"ca",
sslConfig->extract_ca());
642 json_pem(root,
"crl",
sslConfig->extract_crl());
643 json_pem(root,
"cert",
sslConfig->extract_cert());
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());
655 std::vector<std::string> extra_certs =
sslConfig->extract_extra_certs();
656 if (extra_certs.size() > 0)
658 root[
"extra_certs"] = Json::Value(Json::arrayValue);
659 for (
auto cert = extra_certs.begin(); cert != extra_certs.end(); cert++)
662 root[
"extra_certs"].append(Json::Value(*cert));
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());
675 root[
"reneg_sec"] = Json::Value((Json::UInt)
protoConfig->renegotiate.to_seconds());
677 return root.toStyledString();
683 static void print_pem(std::ostream &
os, std::string label, std::string pem)
687 os <<
"<" << label <<
">" << std::endl
688 << pem <<
"</" << label <<
">" << std::endl;
691#ifdef HAVE_CONFIG_JSONCPP
693 static void json_pem(Json::Value &obj, std::string key, std::string pem)
697 obj[key] = Json::Value(pem);
709 for (OptionList::iterator i = options.begin(); i != options.end(); ++i)
712 if (o.
size() >= 3 && o.
ref(0) ==
"setenv" && o.
ref(1) ==
"opt")
721 const bool auth_user_pass,
722 const std::vector<std::string> &
user_pass)
724 if (auth_user_pass &&
user_pass.size() >= 2)
733 bool ret = !auth_user_pass;
742 if (options.
exists(
"EXTERNAL_PKI"))
759 return !cert || !key;
773 const std::string parm = o.
get(index, 16);
776 else if (parm ==
"1")
779 throw option_error(ERR_INVALID_OPTION_VAL, title +
": parameter must be 0 or 1");
void parse_from_config(const std::string &str, Limits *lim)
void parse_from_key_value_list(const KeyValueList &list, const std::string &meta_tag, Limits *lim)
const IndexList * get_index_ptr(const std::string &name) const
const Option * get_ptr(const std::string &name) const
std::vector< unsigned int > IndexList
void parse_meta_from_config(const std::string &str, const std::string &tag, Limits *lim)
bool exists(const std::string &name) const
std::string get_optional(const size_t index, const size_t max_len) const
void push_back(const std::string &item)
void touch(bool lightly=false) const
const std::string & get(const size_t index, const size_t max_len) const
static void validate_string(const std::string &name, const std::string &str, const size_t max_len)
void remove_first(const size_t n_elements)
const std::string & ref(const size_t i) const
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)
bool allowPasswordSave() const
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 privateKeyPasswordRequired_
std::string userlockedUsername_
bool parse_bool(const Option &o, const std::string &title, const size_t index)
static bool is_external_pki(const OptionList &options)
bool hasEmbeddedPassword() const
SSLLib::SSLAPI::Config::Ptr sslConfig
static void process_setenv_opt(OptionList &options)
bool hasEmbeddedPassword_
bool staticChallengeEcho() const
std::string windowsDriver_
const std::string & embeddedPassword() const
const PeerInfo::Set * peerInfoUV() const
std::string embeddedPassword_
const RemoteItem & firstRemoteListItem() const
PeerInfo::Set::Ptr peerInfoUV_
RemoteList::Ptr remoteList
RemoteItem firstRemoteListItem_
std::string vpnCa() const
bool staticChallengeEcho_
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
std::string friendlyName_
bool pushPeerInfo() 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 staticChallenge_
std::string to_string() const
bool clientCertEnabled() const
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
T * get() const noexcept
Returns the raw pointer to the object T, or nullptr.
Item::Ptr get_item(const size_t index) const
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
std::string root(const std::string &basename)
bool is_true(const std::string &str)
bool starts_with(const STRING &str, const std::string &prefix)
bool is_printable(const char c)
bool is_word(const std::string &str)
const std::vector< std::string > user_pass