0
0
mirror of https://github.com/OpenVPN/openvpn3.git synced 2024-09-19 19:52:15 +02:00

Move helper function from OpenVPNClient int OpenVPNClientHelper

This also makes most of them non-static to avoid the problem that these
functions depend on Initprocess::Init being instantiated before being
called.

Rename the local variables eval to eval_cfg to avoid shadowing the
class field of the same name.
This commit is contained in:
Arne Schwabe 2021-12-15 13:01:32 +01:00
parent f6d2c40b34
commit d7b316bd11
4 changed files with 105 additions and 63 deletions

View File

@ -619,7 +619,7 @@ namespace openvpn {
state->proto_context_options.reset(new ProtoContextOptions());
}
OPENVPN_CLIENT_EXPORT void OpenVPNClient::parse_config(const Config& config, EvalConfig& eval, OptionList& options)
OPENVPN_CLIENT_EXPORT void OpenVPNClientHelper::parse_config(const Config& config, EvalConfig& eval, OptionList& options)
{
try {
// validate proto_override
@ -740,27 +740,37 @@ namespace openvpn {
}
}
OPENVPN_CLIENT_EXPORT long OpenVPNClient::max_profile_size()
OpenVPNClientHelper::OpenVPNClientHelper() : init(new InitProcess::Init())
{
}
OpenVPNClientHelper::~OpenVPNClientHelper()
{
delete init;
}
OPENVPN_CLIENT_EXPORT long OpenVPNClientHelper::max_profile_size()
{
return ProfileParseLimits::MAX_PROFILE_SIZE;
}
OPENVPN_CLIENT_EXPORT MergeConfig OpenVPNClient::merge_config_static(const std::string& path,
bool follow_references)
OPENVPN_CLIENT_EXPORT MergeConfig OpenVPNClientHelper::merge_config(const std::string& path,
bool follow_references)
{
ProfileMerge pm(path, "ovpn", "", follow_references ? ProfileMerge::FOLLOW_PARTIAL : ProfileMerge::FOLLOW_NONE,
ProfileParseLimits::MAX_LINE_SIZE, ProfileParseLimits::MAX_PROFILE_SIZE);
return build_merge_config(pm);
}
OPENVPN_CLIENT_EXPORT MergeConfig OpenVPNClient::merge_config_string_static(const std::string& config_content)
OPENVPN_CLIENT_EXPORT MergeConfig OpenVPNClientHelper::merge_config_string(const std::string& config_content)
{
ProfileMergeFromString pm(config_content, "", ProfileMerge::FOLLOW_NONE,
ProfileParseLimits::MAX_LINE_SIZE, ProfileParseLimits::MAX_PROFILE_SIZE);
return build_merge_config(pm);
}
OPENVPN_CLIENT_EXPORT MergeConfig OpenVPNClient::build_merge_config(const ProfileMerge& pm)
OPENVPN_CLIENT_EXPORT MergeConfig OpenVPNClientHelper::build_merge_config(const ProfileMerge& pm)
{
MergeConfig ret;
ret.status = pm.status_string();
@ -777,7 +787,7 @@ namespace openvpn {
return ret;
}
OPENVPN_CLIENT_EXPORT EvalConfig OpenVPNClient::eval_config_static(const Config& config)
OPENVPN_CLIENT_EXPORT EvalConfig OpenVPNClientHelper::eval_config(const Config& config)
{
EvalConfig eval;
OptionList options;
@ -790,7 +800,7 @@ namespace openvpn {
{
// parse and validate configuration file
EvalConfig eval;
parse_config(config, eval, state->options);
OpenVPNClientHelper::parse_config(config, eval, state->options);
if (eval.error)
return eval;
@ -826,7 +836,7 @@ namespace openvpn {
return true;
}
OPENVPN_CLIENT_EXPORT bool OpenVPNClient::parse_dynamic_challenge(const std::string& cookie, DynamicChallenge& dc)
OPENVPN_CLIENT_EXPORT bool OpenVPNClientHelper::parse_dynamic_challenge(const std::string& cookie, DynamicChallenge& dc)
{
try {
ChallengeResponse cr(cookie);
@ -888,7 +898,7 @@ namespace openvpn {
Log::Context log_context(this);
#endif
OPENVPN_LOG(ClientAPI::OpenVPNClient::platform());
OPENVPN_LOG(ClientAPI::OpenVPNClientHelper::platform());
return do_connect();
}
@ -1372,18 +1382,17 @@ namespace openvpn {
state->on_disconnect();
}
OPENVPN_CLIENT_EXPORT std::string OpenVPNClient::crypto_self_test()
OPENVPN_CLIENT_EXPORT std::string OpenVPNClientHelper::crypto_self_test()
{
return SelfTest::crypto_self_test();
}
OPENVPN_CLIENT_EXPORT std::string OpenVPNClient::copyright()
OPENVPN_CLIENT_EXPORT std::string OpenVPNClientHelper::copyright()
{
return openvpn_copyright;
}
OPENVPN_CLIENT_EXPORT std::string OpenVPNClient::platform()
OPENVPN_CLIENT_EXPORT std::string OpenVPNClientHelper::platform()
{
std::string ret = platform_string();
#ifdef PRIVATE_TUNNEL_PROXY

View File

@ -38,6 +38,10 @@ namespace openvpn {
class ProfileMerge;
class Stop;
namespace InitProcess {
class Init;
};
namespace ClientAPI {
// Represents an OpenVPN server and its friendly name
// (client reads)
@ -461,6 +465,60 @@ namespace openvpn {
class ClientState;
};
/**
* Helper class for OpenVPN clients. Provider helper method to be used with
* the \sa OpenVPNClient class.
*/
class OpenVPNClientHelper {
/* To call parse_config */
friend class OpenVPNClient;
public:
OpenVPNClientHelper();
~OpenVPNClientHelper();
OpenVPNClientHelper(OpenVPNClientHelper &) = delete;
// Read an OpenVPN profile that might contain external
// file references, returning a unified profile.
MergeConfig merge_config(const std::string& path, bool follow_references);
// Read an OpenVPN profile that might contain external
// file references, returning a unified profile.
MergeConfig merge_config_string(const std::string& config_content);
// Parse profile and determine needed credentials statically.
EvalConfig eval_config(const Config& config);
// Maximum size of profile that should be allowed
static long max_profile_size();
// Parse a dynamic challenge cookie, placing the result in dc.
// Return true on success or false if parse error.
static bool parse_dynamic_challenge(const std::string& cookie, DynamicChallenge& dc);
// Do a crypto library self test
std::string crypto_self_test();
// Returns platform description string
static std::string platform();
// Returns core copyright
static std::string copyright();
private:
static MergeConfig build_merge_config(const ProfileMerge&);
static void parse_config(const Config&, EvalConfig&, OptionList&);
/* including initprocess.hpp here break since it pulls in logging
* (OPENVPN_LOG) which not setup when including this header, so break that
* cycle here with a pointer instead a normal member, std::unique_ptr
* and std::unique_ptr because they still need to have the initprocess.hpp
* included in the same compilation unit which breaks in the swig wrapped
* class, so we use a plain pointer and new/delete in constructor/destructor */
InitProcess::Init* init;
};
// Top-level OpenVPN client class.
class OpenVPNClient : public TunBuilderBase, // expose tun builder virtual methods
public LogReceiver, // log message notification
@ -472,24 +530,6 @@ namespace openvpn {
OpenVPNClient();
virtual ~OpenVPNClient();
// Read an OpenVPN profile that might contain external
// file references, returning a unified profile.
static MergeConfig merge_config_static(const std::string& path, bool follow_references);
// Read an OpenVPN profile that might contain external
// file references, returning a unified profile.
static MergeConfig merge_config_string_static(const std::string& config_content);
// Parse profile and determine needed credentials statically.
static EvalConfig eval_config_static(const Config& config);
// Maximum size of profile that should be allowed
static long max_profile_size();
// Parse a dynamic challenge cookie, placing the result in dc.
// Return true on success or false if parse error.
static bool parse_dynamic_challenge(const std::string& cookie, DynamicChallenge& dc);
// Parse OpenVPN configuration file.
EvalConfig eval_config(const Config&);
@ -584,15 +624,6 @@ namespace openvpn {
// Periodic convenience clock tick, controlled by Config::clockTickMS
virtual void clock_tick();
// Do a crypto library self test
static std::string crypto_self_test();
// Returns platform description string
static std::string platform();
// Returns core copyright
static std::string copyright();
// Hide protected methods/data from SWIG
#ifdef SWIGJAVA
private:
@ -615,11 +646,9 @@ namespace openvpn {
void connect_setup(Status&, bool&);
void do_connect_async();
static Status status_from_exception(const std::exception&);
static void parse_config(const Config&, EvalConfig&, OptionList&);
void parse_extras(const Config&, EvalConfig&);
void external_pki_error(const ExternalPKIRequestBase&, const size_t);
void process_epki_cert_chain(const ExternalPKICertRequest&);
static MergeConfig build_merge_config(const ProfileMerge&);
friend class MyClientEvents;
void on_disconnect();

View File

@ -19,6 +19,7 @@
// modify exported C++ class names to incorporate their enclosing namespace
%rename(ClientAPI_OpenVPNClient) OpenVPNClient;
%rename(ClientAPI_OpenVPNClientHelper) OpenVPNClientHelper;
%rename(ClientAPI_TunBuilderBase) TunBuilderBase;
%rename(ClientAPI_ExternalPKIBase) ExternalPKIBase;
%rename(ClientAPI_ServerEntry) ServerEntry;

View File

@ -280,7 +280,7 @@ private:
dc_cookie = ev.info;
ClientAPI::DynamicChallenge dc;
if (ClientAPI::OpenVPNClient::parse_dynamic_challenge(ev.info, dc)) {
if (ClientAPI::OpenVPNClientHelper::parse_dynamic_challenge(ev.info, dc)) {
std::cout << "DYNAMIC CHALLENGE" << std::endl;
std::cout << "challenge: " << dc.challenge << std::endl;
std::cout << "echo: " << dc.echo << std::endl;
@ -947,12 +947,13 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
if (version)
{
std::cout << "OpenVPN cli 1.0" << std::endl;
std::cout << ClientAPI::OpenVPNClient::platform() << std::endl;
std::cout << ClientAPI::OpenVPNClient::copyright() << std::endl;
std::cout << ClientAPI::OpenVPNClientHelper::platform() << std::endl;
std::cout << ClientAPI::OpenVPNClientHelper::copyright() << std::endl;
}
else if (self_test)
{
std::cout << ClientAPI::OpenVPNClient::crypto_self_test();
ClientAPI::OpenVPNClientHelper clihelper;
std::cout << clihelper.crypto_self_test();
}
else if (merge)
{
@ -1027,8 +1028,9 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
// setenv SERVER <HOST>/<FRIENDLY_NAME>
if (!config.serverOverride.empty())
{
const ClientAPI::EvalConfig eval = ClientAPI::OpenVPNClient::eval_config_static(config);
for (auto &se : eval.serverList)
ClientAPI::OpenVPNClientHelper clihelper;
const ClientAPI::EvalConfig cfg_eval = clihelper.eval_config(config);
for (auto &se : cfg_eval.serverList)
{
if (config.serverOverride == se.friendlyName)
{
@ -1040,26 +1042,27 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
if (eval)
{
const ClientAPI::EvalConfig eval = ClientAPI::OpenVPNClient::eval_config_static(config);
ClientAPI::OpenVPNClientHelper clihelper;
const ClientAPI::EvalConfig cfg_eval = clihelper.eval_config(config);
std::cout << "EVAL PROFILE" << std::endl;
std::cout << "error=" << eval.error << std::endl;
std::cout << "message=" << eval.message << std::endl;
std::cout << "userlockedUsername=" << eval.userlockedUsername << std::endl;
std::cout << "profileName=" << eval.profileName << std::endl;
std::cout << "friendlyName=" << eval.friendlyName << std::endl;
std::cout << "autologin=" << eval.autologin << std::endl;
std::cout << "externalPki=" << eval.externalPki << std::endl;
std::cout << "staticChallenge=" << eval.staticChallenge << std::endl;
std::cout << "staticChallengeEcho=" << eval.staticChallengeEcho << std::endl;
std::cout << "privateKeyPasswordRequired=" << eval.privateKeyPasswordRequired << std::endl;
std::cout << "allowPasswordSave=" << eval.allowPasswordSave << std::endl;
std::cout << "error=" << cfg_eval.error << std::endl;
std::cout << "message=" << cfg_eval.message << std::endl;
std::cout << "userlockedUsername=" << cfg_eval.userlockedUsername << std::endl;
std::cout << "profileName=" << cfg_eval.profileName << std::endl;
std::cout << "friendlyName=" << cfg_eval.friendlyName << std::endl;
std::cout << "autologin=" << cfg_eval.autologin << std::endl;
std::cout << "externalPki=" << cfg_eval.externalPki << std::endl;
std::cout << "staticChallenge=" << cfg_eval.staticChallenge << std::endl;
std::cout << "staticChallengeEcho=" << cfg_eval.staticChallengeEcho << std::endl;
std::cout << "privateKeyPasswordRequired=" << cfg_eval.privateKeyPasswordRequired << std::endl;
std::cout << "allowPasswordSave=" << cfg_eval.allowPasswordSave << std::endl;
if (!config.serverOverride.empty())
std::cout << "server=" << config.serverOverride << std::endl;
for (size_t i = 0; i < eval.serverList.size(); ++i)
for (size_t i = 0; i < cfg_eval.serverList.size(); ++i)
{
const ClientAPI::ServerEntry& se = eval.serverList[i];
const ClientAPI::ServerEntry& se = cfg_eval.serverList[i];
std::cout << '[' << i << "] " << se.server << '/' << se.friendlyName << std::endl;
}
}