mirror of
https://github.com/deneraraujo/OpenVPNAdapter.git
synced 2026-02-11 00:00:08 +08:00
Squashed 'OpenVPN Adapter/Vendors/openvpn/' content from commit da99df6
git-subtree-dir: OpenVPN Adapter/Vendors/openvpn git-subtree-split: da99df69492256d7a18bbea303ae98457782a4bf
This commit is contained in:
3
test/ovpncli/.gitignore
vendored
Normal file
3
test/ovpncli/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
cli
|
||||
cli.dSYM
|
||||
build.tmp
|
||||
24
test/ovpncli/README.txt
Normal file
24
test/ovpncli/README.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
Build on Mac:
|
||||
|
||||
With MbedTLS:
|
||||
GCC_EXTRA="-ferror-limit=4" STRIP=1 MTLS=1 SNAP=1 LZ4=1 build cli
|
||||
|
||||
With MbedTLS and Minicrypto:
|
||||
GCC_EXTRA="-ferror-limit=4" STRIP=1 MTLS=1 MINI=1 SNAP=1 LZ4=1 build cli
|
||||
|
||||
With MbedTLS, Minicrypto, and C++11 for optimized move constructors:
|
||||
GCC_EXTRA="-ferror-limit=4 -std=c++11" STRIP=1 MTLS=1 MINI=1 SNAP=1 LZ4=1 build cli
|
||||
|
||||
With OpenSSL:
|
||||
GCC_EXTRA="-ferror-limit=4" STRIP=1 OSSL=1 OPENSSL_SYS=1 SNAP=1 LZ4=1 build cli
|
||||
|
||||
With MbedTLS/AppleCrypto hybrid:
|
||||
GCC_EXTRA="-ferror-limit=4" STRIP=1 HYBRID=1 SNAP=1 LZ4=1 build cli
|
||||
|
||||
Build on Linux:
|
||||
|
||||
With MbedTLS:
|
||||
STRIP=1 SNAP=1 LZ4=1 MTLS=1 NOSSL=1 build cli
|
||||
|
||||
With OpenSSL:
|
||||
STRIP=1 SNAP=1 LZ4=1 build cli
|
||||
842
test/ovpncli/cli.cpp
Normal file
842
test/ovpncli/cli.cpp
Normal file
@@ -0,0 +1,842 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// OpenVPN 3 test client
|
||||
|
||||
#include <stdlib.h> // for atoi
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include <openvpn/common/platform.hpp>
|
||||
|
||||
#ifdef OPENVPN_PLATFORM_MAC
|
||||
#include <CoreFoundation/CFBundle.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
// If enabled, don't direct ovpn3 core logging to
|
||||
// ClientAPI::OpenVPNClient::log() virtual method.
|
||||
// Instead, logging will go to LogBaseSimple::log().
|
||||
// In this case, make sure to define:
|
||||
// LogBaseSimple log;
|
||||
// at the top of your main() function to receive
|
||||
// log messages from all threads.
|
||||
// Also, note that the OPENVPN_LOG_GLOBAL setting
|
||||
// MUST be consistent across all compilation units.
|
||||
#ifdef OPENVPN_USE_LOG_BASE_SIMPLE
|
||||
#define OPENVPN_LOG_GLOBAL // use global rather than thread-local log object pointer
|
||||
#include <openvpn/log/logbasesimple.hpp>
|
||||
#endif
|
||||
|
||||
// don't export core symbols
|
||||
#define OPENVPN_CORE_API_VISIBILITY_HIDDEN
|
||||
|
||||
// should be included before other openvpn includes,
|
||||
// with the exception of openvpn/log includes
|
||||
#include <client/ovpncli.cpp>
|
||||
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/string.hpp>
|
||||
#include <openvpn/common/signal.hpp>
|
||||
#include <openvpn/common/file.hpp>
|
||||
#include <openvpn/common/getopt.hpp>
|
||||
#include <openvpn/common/getpw.hpp>
|
||||
#include <openvpn/common/cleanup.hpp>
|
||||
#include <openvpn/time/timestr.hpp>
|
||||
#include <openvpn/ssl/peerinfo.hpp>
|
||||
#include <openvpn/ssl/sslchoose.hpp>
|
||||
|
||||
#if defined(USE_MBEDTLS)
|
||||
#include <openvpn/mbedtls/util/pkcs1.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(OPENVPN_PLATFORM_WIN)
|
||||
#include <openvpn/win/console.hpp>
|
||||
#endif
|
||||
|
||||
using namespace openvpn;
|
||||
|
||||
namespace {
|
||||
OPENVPN_SIMPLE_EXCEPTION(usage);
|
||||
}
|
||||
|
||||
class Client : public ClientAPI::OpenVPNClient
|
||||
{
|
||||
public:
|
||||
bool is_dynamic_challenge() const
|
||||
{
|
||||
return !dc_cookie.empty();
|
||||
}
|
||||
|
||||
std::string dynamic_challenge_cookie()
|
||||
{
|
||||
return dc_cookie;
|
||||
}
|
||||
|
||||
std::string epki_ca;
|
||||
std::string epki_cert;
|
||||
#if defined(USE_MBEDTLS)
|
||||
MbedTLSPKI::PKContext epki_ctx; // external PKI context
|
||||
#endif
|
||||
|
||||
private:
|
||||
virtual bool socket_protect(int socket)
|
||||
{
|
||||
std::cout << "*** socket_protect " << socket << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void event(const ClientAPI::Event& ev)
|
||||
{
|
||||
std::cout << date_time() << " EVENT: " << ev.name;
|
||||
if (!ev.info.empty())
|
||||
std::cout << ' ' << ev.info;
|
||||
if (ev.fatal)
|
||||
std::cout << " [FATAL-ERR]";
|
||||
else if (ev.error)
|
||||
std::cout << " [ERR]";
|
||||
std::cout << std::endl;
|
||||
if (ev.name == "DYNAMIC_CHALLENGE")
|
||||
{
|
||||
dc_cookie = ev.info;
|
||||
|
||||
ClientAPI::DynamicChallenge dc;
|
||||
if (ClientAPI::OpenVPNClient::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;
|
||||
std::cout << "responseRequired: " << dc.responseRequired << std::endl;
|
||||
std::cout << "stateID: " << dc.stateID << std::endl;
|
||||
}
|
||||
}
|
||||
else if (ev.name == "INFO" && (string::starts_with(ev.info, "OPEN_URL:http://")
|
||||
|| string::starts_with(ev.info, "OPEN_URL:https://")))
|
||||
{
|
||||
// launch URL
|
||||
const std::string url_str = ev.info.substr(9);
|
||||
#ifdef OPENVPN_PLATFORM_MAC
|
||||
std::thread thr([url_str]() {
|
||||
CFURLRef url = CFURLCreateWithBytes(
|
||||
NULL, // allocator
|
||||
(UInt8*)url_str.c_str(), // URLBytes
|
||||
url_str.length(), // length
|
||||
kCFStringEncodingUTF8, // encoding
|
||||
NULL // baseURL
|
||||
);
|
||||
LSOpenCFURLRef(url, 0);
|
||||
CFRelease(url);
|
||||
});
|
||||
thr.detach();
|
||||
#else
|
||||
std::cout << "No implementation to launch " << url_str << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
virtual void log(const ClientAPI::LogInfo& log)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(log_mutex);
|
||||
std::cout << date_time() << ' ' << log.text << std::flush;
|
||||
}
|
||||
|
||||
virtual void external_pki_cert_request(ClientAPI::ExternalPKICertRequest& certreq)
|
||||
{
|
||||
if (!epki_cert.empty())
|
||||
{
|
||||
certreq.cert = epki_cert;
|
||||
certreq.supportingChain = epki_ca;
|
||||
}
|
||||
else
|
||||
{
|
||||
certreq.error = true;
|
||||
certreq.errorText = "external_pki_cert_request not implemented";
|
||||
}
|
||||
}
|
||||
|
||||
virtual void external_pki_sign_request(ClientAPI::ExternalPKISignRequest& signreq)
|
||||
{
|
||||
#if defined(USE_MBEDTLS)
|
||||
if (epki_ctx.defined())
|
||||
{
|
||||
try {
|
||||
// decode base64 sign request
|
||||
BufferAllocated signdata(256, BufferAllocated::GROW);
|
||||
base64->decode(signdata, signreq.data);
|
||||
|
||||
// get MD alg
|
||||
const mbedtls_md_type_t md_alg = PKCS1::DigestPrefix::MbedTLSParse().alg_from_prefix(signdata);
|
||||
|
||||
// log info
|
||||
OPENVPN_LOG("SIGN[" << PKCS1::DigestPrefix::MbedTLSParse::to_string(md_alg) << ',' << signdata.size() << "]: " << render_hex_generic(signdata));
|
||||
|
||||
// allocate buffer for signature
|
||||
BufferAllocated sig(mbedtls_pk_get_len(epki_ctx.get()), BufferAllocated::ARRAY);
|
||||
|
||||
// sign it
|
||||
size_t sig_size = 0;
|
||||
const int status = mbedtls_pk_sign(epki_ctx.get(),
|
||||
md_alg,
|
||||
signdata.c_data(),
|
||||
signdata.size(),
|
||||
sig.data(),
|
||||
&sig_size,
|
||||
rng_callback,
|
||||
this);
|
||||
if (status != 0)
|
||||
throw Exception("mbedtls_pk_sign failed, err=" + openvpn::to_string(status));
|
||||
if (sig.size() != sig_size)
|
||||
throw Exception("unexpected signature size");
|
||||
|
||||
// encode base64 signature
|
||||
signreq.sig = base64->encode(sig);
|
||||
OPENVPN_LOG("SIGNATURE[" << sig_size << "]: " << signreq.sig);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
signreq.error = true;
|
||||
signreq.errorText = std::string("external_pki_sign_request: ") + e.what();
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
signreq.error = true;
|
||||
signreq.errorText = "external_pki_sign_request not implemented";
|
||||
}
|
||||
}
|
||||
|
||||
// RNG callback
|
||||
static int rng_callback(void *arg, unsigned char *data, size_t len)
|
||||
{
|
||||
Client *self = (Client *)arg;
|
||||
if (!self->rng)
|
||||
{
|
||||
self->rng.reset(new SSLLib::RandomAPI(false));
|
||||
self->rng->assert_crypto();
|
||||
}
|
||||
return self->rng->rand_bytes_noexcept(data, len) ? 0 : -1; // using -1 as a general-purpose mbed TLS error code
|
||||
}
|
||||
|
||||
virtual bool pause_on_connection_timeout()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::mutex log_mutex;
|
||||
std::string dc_cookie;
|
||||
RandomAPI::Ptr rng; // random data source for epki
|
||||
};
|
||||
|
||||
static Client *the_client = nullptr; // GLOBAL
|
||||
|
||||
static void worker_thread()
|
||||
{
|
||||
openvpn_io::detail::signal_blocker signal_blocker; // signals should be handled by parent thread
|
||||
try {
|
||||
std::cout << "Thread starting..." << std::endl;
|
||||
ClientAPI::Status connect_status = the_client->connect();
|
||||
if (connect_status.error)
|
||||
{
|
||||
std::cout << "connect error: ";
|
||||
if (!connect_status.status.empty())
|
||||
std::cout << connect_status.status << ": ";
|
||||
std::cout << connect_status.message << std::endl;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << "Connect thread exception: " << e.what() << std::endl;
|
||||
}
|
||||
std::cout << "Thread finished" << std::endl;
|
||||
}
|
||||
|
||||
static void print_stats(const Client& client)
|
||||
{
|
||||
const int n = client.stats_n();
|
||||
std::vector<long long> stats = client.stats_bundle();
|
||||
|
||||
std::cout << "STATS:" << std::endl;
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
const long long value = stats[i];
|
||||
if (value)
|
||||
std::cout << " " << client.stats_name(i) << " : " << value << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(OPENVPN_PLATFORM_WIN)
|
||||
static void handler(int signum)
|
||||
{
|
||||
switch (signum)
|
||||
{
|
||||
case SIGTERM:
|
||||
case SIGINT:
|
||||
std::cout << "received stop signal " << signum << std::endl;
|
||||
if (the_client)
|
||||
the_client->stop();
|
||||
break;
|
||||
case SIGHUP:
|
||||
std::cout << "received reconnect signal " << signum << std::endl;
|
||||
if (the_client)
|
||||
the_client->reconnect(0);
|
||||
break;
|
||||
case SIGUSR1:
|
||||
if (the_client)
|
||||
print_stats(*the_client);
|
||||
break;
|
||||
case SIGUSR2:
|
||||
{
|
||||
// toggle pause/resume
|
||||
static bool hup = false;
|
||||
std::cout << "received pause/resume toggle signal " << signum << std::endl;
|
||||
if (the_client)
|
||||
{
|
||||
if (hup)
|
||||
the_client->resume();
|
||||
else
|
||||
the_client->pause("pause-resume-signal");
|
||||
hup = !hup;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std::cout << "received unknown signal " << signum << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static std::string read_profile(const char *fn, const std::string* profile_content)
|
||||
{
|
||||
if (!string::strcasecmp(fn, "http") && profile_content && !profile_content->empty())
|
||||
return *profile_content;
|
||||
else
|
||||
{
|
||||
ProfileMerge pm(fn, "ovpn", "", ProfileMerge::FOLLOW_FULL,
|
||||
ProfileParseLimits::MAX_LINE_SIZE, ProfileParseLimits::MAX_PROFILE_SIZE);
|
||||
if (pm.status() != ProfileMerge::MERGE_SUCCESS)
|
||||
OPENVPN_THROW_EXCEPTION("merge config error: " << pm.status_string() << " : " << pm.error());
|
||||
return pm.profile_content();
|
||||
}
|
||||
}
|
||||
|
||||
int openvpn_client(int argc, char *argv[], const std::string* profile_content)
|
||||
{
|
||||
static const struct option longopts[] = {
|
||||
{ "username", required_argument, nullptr, 'u' },
|
||||
{ "password", required_argument, nullptr, 'p' },
|
||||
{ "response", required_argument, nullptr, 'r' },
|
||||
{ "dc", required_argument, nullptr, 'D' },
|
||||
{ "proto", required_argument, nullptr, 'P' },
|
||||
{ "ipv6", required_argument, nullptr, '6' },
|
||||
{ "server", required_argument, nullptr, 's' },
|
||||
{ "timeout", required_argument, nullptr, 't' },
|
||||
{ "compress", required_argument, nullptr, 'c' },
|
||||
{ "pk-password", required_argument, nullptr, 'z' },
|
||||
{ "tvm-override", required_argument, nullptr, 'M' },
|
||||
{ "proxy-host", required_argument, nullptr, 'h' },
|
||||
{ "proxy-port", required_argument, nullptr, 'q' },
|
||||
{ "proxy-username", required_argument, nullptr, 'U' },
|
||||
{ "proxy-password", required_argument, nullptr, 'W' },
|
||||
{ "peer-info", required_argument, nullptr, 'I' },
|
||||
{ "gremlin", required_argument, nullptr, 'G' },
|
||||
{ "proxy-basic", no_argument, nullptr, 'B' },
|
||||
{ "alt-proxy", no_argument, nullptr, 'A' },
|
||||
{ "dco", no_argument, nullptr, 'd' },
|
||||
{ "eval", no_argument, nullptr, 'e' },
|
||||
{ "self-test", no_argument, nullptr, 'T' },
|
||||
{ "cache-password", no_argument, nullptr, 'C' },
|
||||
{ "no-cert", no_argument, nullptr, 'x' },
|
||||
{ "force-aes-cbc", no_argument, nullptr, 'f' },
|
||||
{ "google-dns", no_argument, nullptr, 'g' },
|
||||
{ "persist-tun", no_argument, nullptr, 'j' },
|
||||
{ "def-keydir", required_argument, nullptr, 'k' },
|
||||
{ "merge", no_argument, nullptr, 'm' },
|
||||
{ "version", no_argument, nullptr, 'v' },
|
||||
{ "auto-sess", no_argument, nullptr, 'a' },
|
||||
{ "tcprof-override", required_argument, nullptr, 'X' },
|
||||
{ "ssl-debug", required_argument, nullptr, 1 },
|
||||
{ "epki-cert", required_argument, nullptr, 2 },
|
||||
{ "epki-ca", required_argument, nullptr, 3 },
|
||||
{ "epki-key", required_argument, nullptr, 4 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
int ret = 0;
|
||||
auto cleanup = Cleanup([]() {
|
||||
the_client = nullptr;
|
||||
});
|
||||
std::unique_ptr<std::thread> thread;
|
||||
|
||||
try {
|
||||
if (argc >= 2)
|
||||
{
|
||||
std::string username;
|
||||
std::string password;
|
||||
std::string response;
|
||||
std::string dynamicChallengeCookie;
|
||||
std::string proto;
|
||||
std::string ipv6;
|
||||
std::string server;
|
||||
int timeout = 0;
|
||||
std::string compress;
|
||||
std::string privateKeyPassword;
|
||||
std::string tlsVersionMinOverride;
|
||||
std::string tlsCertProfileOverride;
|
||||
std::string proxyHost;
|
||||
std::string proxyPort;
|
||||
std::string proxyUsername;
|
||||
std::string proxyPassword;
|
||||
std::string peer_info;
|
||||
std::string gremlin;
|
||||
bool eval = false;
|
||||
bool self_test = false;
|
||||
bool cachePassword = false;
|
||||
bool disableClientCert = false;
|
||||
bool proxyAllowCleartextAuth = false;
|
||||
int defaultKeyDirection = -1;
|
||||
bool forceAesCbcCiphersuites = false;
|
||||
int sslDebugLevel = 0;
|
||||
bool googleDnsFallback = false;
|
||||
bool autologinSessions = false;
|
||||
bool tunPersist = false;
|
||||
bool merge = false;
|
||||
bool version = false;
|
||||
bool altProxy = false;
|
||||
bool dco = false;
|
||||
std::string epki_cert_fn;
|
||||
std::string epki_ca_fn;
|
||||
std::string epki_key_fn;
|
||||
|
||||
int ch;
|
||||
optind = 1;
|
||||
while ((ch = getopt_long(argc, argv, "BAdeTCxfgjmvau:p:r:D:P:6:s:t:c:z:M:h:q:U:W:I:G:k:X:", longopts, nullptr)) != -1)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case 1: // ssl-debug
|
||||
sslDebugLevel = ::atoi(optarg);
|
||||
break;
|
||||
case 2: // --epki-cert
|
||||
epki_cert_fn = optarg;
|
||||
break;
|
||||
case 3: // --epki-ca
|
||||
epki_ca_fn = optarg;
|
||||
break;
|
||||
case 4: // --epki-key
|
||||
epki_key_fn = optarg;
|
||||
break;
|
||||
case 'e':
|
||||
eval = true;
|
||||
break;
|
||||
case 'T':
|
||||
self_test = true;
|
||||
break;
|
||||
case 'C':
|
||||
cachePassword = true;
|
||||
break;
|
||||
case 'x':
|
||||
disableClientCert = true;
|
||||
break;
|
||||
case 'u':
|
||||
username = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
password = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
response = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
proto = optarg;
|
||||
break;
|
||||
case '6':
|
||||
ipv6 = optarg;
|
||||
break;
|
||||
case 's':
|
||||
server = optarg;
|
||||
break;
|
||||
case 't':
|
||||
timeout = ::atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
compress = optarg;
|
||||
break;
|
||||
case 'z':
|
||||
privateKeyPassword = optarg;
|
||||
break;
|
||||
case 'M':
|
||||
tlsVersionMinOverride = optarg;
|
||||
break;
|
||||
case 'X':
|
||||
tlsCertProfileOverride = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
proxyHost = optarg;
|
||||
break;
|
||||
case 'q':
|
||||
proxyPort = optarg;
|
||||
break;
|
||||
case 'U':
|
||||
proxyUsername = optarg;
|
||||
break;
|
||||
case 'W':
|
||||
proxyPassword = optarg;
|
||||
break;
|
||||
case 'B':
|
||||
proxyAllowCleartextAuth = true;
|
||||
break;
|
||||
case 'A':
|
||||
altProxy = true;
|
||||
break;
|
||||
case 'd':
|
||||
dco = true;
|
||||
break;
|
||||
case 'f':
|
||||
forceAesCbcCiphersuites = true;
|
||||
break;
|
||||
case 'g':
|
||||
googleDnsFallback = true;
|
||||
break;
|
||||
case 'a':
|
||||
autologinSessions = true;
|
||||
break;
|
||||
case 'j':
|
||||
tunPersist = true;
|
||||
break;
|
||||
case 'm':
|
||||
merge = true;
|
||||
break;
|
||||
case 'v':
|
||||
version = true;
|
||||
break;
|
||||
case 'k':
|
||||
{
|
||||
const std::string arg = optarg;
|
||||
if (arg == "bi" || arg == "bidirectional")
|
||||
defaultKeyDirection = -1;
|
||||
else if (arg == "0")
|
||||
defaultKeyDirection = 0;
|
||||
else if (arg == "1")
|
||||
defaultKeyDirection = 1;
|
||||
else
|
||||
OPENVPN_THROW_EXCEPTION("bad default key-direction: " << arg);
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
dynamicChallengeCookie = optarg;
|
||||
break;
|
||||
case 'I':
|
||||
peer_info = optarg;
|
||||
break;
|
||||
case 'G':
|
||||
gremlin = optarg;
|
||||
break;
|
||||
default:
|
||||
throw usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (version)
|
||||
{
|
||||
std::cout << "OpenVPN cli 1.0" << std::endl;
|
||||
std::cout << ClientAPI::OpenVPNClient::platform() << std::endl;
|
||||
std::cout << ClientAPI::OpenVPNClient::copyright() << std::endl;
|
||||
}
|
||||
else if (self_test)
|
||||
{
|
||||
std::cout << ClientAPI::OpenVPNClient::crypto_self_test();
|
||||
}
|
||||
else if (merge)
|
||||
{
|
||||
if (argc != 1)
|
||||
throw usage();
|
||||
std::cout << read_profile(argv[0], profile_content);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (argc < 1)
|
||||
throw usage();
|
||||
|
||||
bool retry;
|
||||
do {
|
||||
retry = false;
|
||||
|
||||
ClientAPI::Config config;
|
||||
config.guiVersion = "cli 1.0";
|
||||
config.content = read_profile(argv[0], profile_content);
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
config.content += argv[i];
|
||||
config.content += '\n';
|
||||
}
|
||||
config.serverOverride = server;
|
||||
config.protoOverride = proto;
|
||||
config.connTimeout = timeout;
|
||||
config.compressionMode = compress;
|
||||
config.ipv6 = ipv6;
|
||||
config.privateKeyPassword = privateKeyPassword;
|
||||
config.tlsVersionMinOverride = tlsVersionMinOverride;
|
||||
config.tlsCertProfileOverride = tlsCertProfileOverride;
|
||||
config.disableClientCert = disableClientCert;
|
||||
config.proxyHost = proxyHost;
|
||||
config.proxyPort = proxyPort;
|
||||
config.proxyUsername = proxyUsername;
|
||||
config.proxyPassword = proxyPassword;
|
||||
config.proxyAllowCleartextAuth = proxyAllowCleartextAuth;
|
||||
config.altProxy = altProxy;
|
||||
config.dco = dco;
|
||||
config.defaultKeyDirection = defaultKeyDirection;
|
||||
config.forceAesCbcCiphersuites = forceAesCbcCiphersuites;
|
||||
config.sslDebugLevel = sslDebugLevel;
|
||||
config.googleDnsFallback = googleDnsFallback;
|
||||
config.autologinSessions = autologinSessions;
|
||||
config.tunPersist = tunPersist;
|
||||
config.gremlinConfig = gremlin;
|
||||
config.info = true;
|
||||
|
||||
if (!epki_cert_fn.empty())
|
||||
config.externalPkiAlias = "epki"; // dummy string
|
||||
|
||||
PeerInfo::Set::parse_csv(peer_info, config.peerInfo);
|
||||
|
||||
if (eval)
|
||||
{
|
||||
ClientAPI::EvalConfig eval = ClientAPI::OpenVPNClient::eval_config_static(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;
|
||||
|
||||
for (size_t i = 0; i < eval.serverList.size(); ++i)
|
||||
{
|
||||
const ClientAPI::ServerEntry& se = eval.serverList[i];
|
||||
std::cout << '[' << i << "] " << se.server << '/' << se.friendlyName << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Client client;
|
||||
ClientAPI::EvalConfig eval = client.eval_config(config);
|
||||
if (eval.error)
|
||||
OPENVPN_THROW_EXCEPTION("eval config error: " << eval.message);
|
||||
if (eval.autologin)
|
||||
{
|
||||
if (!username.empty() || !password.empty())
|
||||
std::cout << "NOTE: creds were not needed" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (username.empty())
|
||||
OPENVPN_THROW_EXCEPTION("need creds");
|
||||
ClientAPI::ProvideCreds creds;
|
||||
if (password.empty() && dynamicChallengeCookie.empty())
|
||||
password = get_password("Password:");
|
||||
creds.username = username;
|
||||
creds.password = password;
|
||||
creds.response = response;
|
||||
creds.dynamicChallengeCookie = dynamicChallengeCookie;
|
||||
creds.replacePasswordWithSessionID = true;
|
||||
creds.cachePassword = cachePassword;
|
||||
ClientAPI::Status creds_status = client.provide_creds(creds);
|
||||
if (creds_status.error)
|
||||
OPENVPN_THROW_EXCEPTION("creds error: " << creds_status.message);
|
||||
}
|
||||
|
||||
// external PKI
|
||||
if (!epki_cert_fn.empty())
|
||||
{
|
||||
client.epki_cert = read_text_utf8(epki_cert_fn);
|
||||
if (!epki_ca_fn.empty())
|
||||
client.epki_ca = read_text_utf8(epki_ca_fn);
|
||||
#if defined(USE_MBEDTLS)
|
||||
if (!epki_key_fn.empty())
|
||||
{
|
||||
const std::string epki_key_txt = read_text_utf8(epki_key_fn);
|
||||
client.epki_ctx.parse(epki_key_txt, "EPKI", privateKeyPassword);
|
||||
}
|
||||
else
|
||||
OPENVPN_THROW_EXCEPTION("--epki-key must be specified");
|
||||
#endif
|
||||
}
|
||||
|
||||
std::cout << "CONNECTING..." << std::endl;
|
||||
|
||||
#if !defined(OPENVPN_PLATFORM_WIN)
|
||||
// start connect thread
|
||||
the_client = &client;
|
||||
thread.reset(new std::thread([]() {
|
||||
worker_thread();
|
||||
}));
|
||||
|
||||
{
|
||||
// catch signals that might occur while we're in join()
|
||||
Signal signal(handler, Signal::F_SIGINT|Signal::F_SIGTERM|Signal::F_SIGHUP|Signal::F_SIGUSR1|Signal::F_SIGUSR2);
|
||||
|
||||
// wait for connect thread to exit
|
||||
thread->join();
|
||||
}
|
||||
the_client = nullptr;
|
||||
#else
|
||||
// Set Windows title bar
|
||||
const std::string title_text = "F2:Stats F3:Reconnect F4:Stop F5:Pause";
|
||||
Win::Console::Title title(ClientAPI::OpenVPNClient::platform() + " " + title_text);
|
||||
Win::Console::Input console;
|
||||
|
||||
// start connect thread
|
||||
volatile bool thread_exit = false;
|
||||
the_client = &client;
|
||||
thread.reset(new std::thread([&thread_exit]() {
|
||||
worker_thread();
|
||||
thread_exit = true;
|
||||
}));
|
||||
|
||||
// wait for connect thread to exit, also check for keypresses
|
||||
while (!thread_exit)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
const unsigned int c = console.get();
|
||||
if (!c)
|
||||
break;
|
||||
else if (c == 0x3C) // F2
|
||||
print_stats(*the_client);
|
||||
else if (c == 0x3D) // F3
|
||||
the_client->reconnect(0);
|
||||
else if (c == 0x3E) // F4
|
||||
the_client->stop();
|
||||
else if (c == 0x3F) // F5
|
||||
the_client->pause("user-pause");
|
||||
}
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
// wait for connect thread to exit
|
||||
thread->join();
|
||||
|
||||
the_client = nullptr;
|
||||
#endif
|
||||
|
||||
// Get dynamic challenge response
|
||||
if (client.is_dynamic_challenge())
|
||||
{
|
||||
std::cout << "ENTER RESPONSE" << std::endl;
|
||||
std::getline(std::cin, response);
|
||||
if (!response.empty())
|
||||
{
|
||||
dynamicChallengeCookie = client.dynamic_challenge_cookie();
|
||||
retry = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// print closing stats
|
||||
print_stats(client);
|
||||
}
|
||||
}
|
||||
} while (retry);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw usage();
|
||||
}
|
||||
catch (const usage&)
|
||||
{
|
||||
std::cout << "OpenVPN Client (ovpncli)" << std::endl;
|
||||
std::cout << "usage: cli [options] <config-file> [extra-config-directives...]" << std::endl;
|
||||
std::cout << "--version, -v : show version info" << std::endl;
|
||||
std::cout << "--eval, -e : evaluate profile only (standalone)" << std::endl;
|
||||
std::cout << "--merge, -m : merge profile into unified format (standalone)" << std::endl;
|
||||
std::cout << "--username, -u : username" << std::endl;
|
||||
std::cout << "--password, -p : password" << std::endl;
|
||||
std::cout << "--response, -r : static response" << std::endl;
|
||||
std::cout << "--dc, -D : dynamic challenge/response cookie" << std::endl;
|
||||
std::cout << "--proto, -P : protocol override (udp|tcp)" << std::endl;
|
||||
std::cout << "--server, -s : server override" << std::endl;
|
||||
std::cout << "--ipv6, -6 : IPv6 (yes|no|default)" << std::endl;
|
||||
std::cout << "--timeout, -t : timeout" << std::endl;
|
||||
std::cout << "--compress, -c : compression mode (yes|no|asym)" << std::endl;
|
||||
std::cout << "--pk-password, -z : private key password" << std::endl;
|
||||
std::cout << "--tvm-override, -M : tls-version-min override (disabled, default, tls_1_x)" << std::endl;
|
||||
std::cout << "--tcprof-override, -X : tls-cert-profile override (legacy, preferred, etc.)" << std::endl;
|
||||
std::cout << "--proxy-host, -h : HTTP proxy hostname/IP" << std::endl;
|
||||
std::cout << "--proxy-port, -q : HTTP proxy port" << std::endl;
|
||||
std::cout << "--proxy-username, -U : HTTP proxy username" << std::endl;
|
||||
std::cout << "--proxy-password, -W : HTTP proxy password" << std::endl;
|
||||
std::cout << "--proxy-basic, -B : allow HTTP basic auth" << std::endl;
|
||||
std::cout << "--alt-proxy, -A : enable alternative proxy module" << std::endl;
|
||||
std::cout << "--dco, -d : enable data channel offload" << std::endl;
|
||||
std::cout << "--cache-password, -C : cache password" << std::endl;
|
||||
std::cout << "--no-cert, -x : disable client certificate" << std::endl;
|
||||
std::cout << "--def-keydir, -k : default key direction ('bi', '0', or '1')" << std::endl;
|
||||
std::cout << "--force-aes-cbc, -f : force AES-CBC ciphersuites" << std::endl;
|
||||
std::cout << "--ssl-debug : SSL debug level" << std::endl;
|
||||
std::cout << "--google-dns, -g : enable Google DNS fallback" << std::endl;
|
||||
std::cout << "--auto-sess, -a : request autologin session" << std::endl;
|
||||
std::cout << "--persist-tun, -j : keep TUN interface open across reconnects" << std::endl;
|
||||
std::cout << "--peer-info, -I : peer info key/value list in the form K1=V1,K2=V2,..." << std::endl;
|
||||
std::cout << "--gremlin, -G : gremlin info (send_delay_ms, recv_delay_ms, send_drop_prob, recv_drop_prob)" << std::endl;
|
||||
std::cout << "--epki-ca : simulate external PKI cert supporting intermediate/root certs" << std::endl;
|
||||
std::cout << "--epki-cert : simulate external PKI cert" << std::endl;
|
||||
std::cout << "--epki-key : simulate external PKI private key" << std::endl;
|
||||
ret = 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENVPN_OVPNCLI_OMIT_MAIN
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#ifdef OPENVPN_LOG_LOGBASE_H
|
||||
LogBaseSimple log;
|
||||
#endif
|
||||
|
||||
try {
|
||||
Client::init_process();
|
||||
ret = openvpn_client(argc, argv, nullptr);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << "Main thread exception: " << e.what() << std::endl;
|
||||
ret = 1;
|
||||
}
|
||||
Client::uninit_process();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
34
test/ovpncli/go
Executable file
34
test/ovpncli/go
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
GCC_EXTRA="$GCC_EXTRA -DOPENVPN_SHOW_SESSION_TOKEN"
|
||||
[ "$EER" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DTEST_EER"
|
||||
[ "$NULL" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DOPENVPN_FORCE_TUN_NULL"
|
||||
[ "$EXIT" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DTUN_NULL_EXIT"
|
||||
[ "$GREMLIN" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DOPENVPN_GREMLIN"
|
||||
[ "$DEX" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DOPENVPN_DISABLE_EXPLICIT_EXIT"
|
||||
[ "$BS64" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DOPENVPN_BS64_DATA_LIMIT=2500000"
|
||||
if [ "$AGENT" = "1" ]; then
|
||||
GCC_EXTRA="$GCC_EXTRA -DOPENVPN_COMMAND_AGENT"
|
||||
export JSON=1
|
||||
fi
|
||||
export GCC_EXTRA
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
cd $O3/core
|
||||
if [ "$DEBUG" = "3" ]; then
|
||||
. vars/vars-osx64-dbg
|
||||
else
|
||||
. vars/vars-osx64
|
||||
fi
|
||||
. vars/setpath
|
||||
cd test/ovpncli
|
||||
ASIO=1 MTLS=1 LZ4=1 PTPROXY=1 build cli 2>&1
|
||||
else
|
||||
cd $O3/core
|
||||
if [ "$DEBUG" = "3" ]; then
|
||||
. vars/vars-linux-dbg
|
||||
else
|
||||
. vars/vars-linux
|
||||
fi
|
||||
. vars/setpath
|
||||
cd test/ovpncli
|
||||
ASIO=1 MTLS=1 LZ4=1 NOSSL=1 PTPROXY=1 build cli 2>&1
|
||||
fi
|
||||
5
test/ssl/.gitignore
vendored
Normal file
5
test/ssl/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
proto
|
||||
proto.gcda
|
||||
proto.dSYM
|
||||
proto.exe
|
||||
proto.obj
|
||||
80
test/ssl/README.txt
Normal file
80
test/ssl/README.txt
Normal file
@@ -0,0 +1,80 @@
|
||||
Building proto.cpp sample:
|
||||
|
||||
On Mac
|
||||
|
||||
Build with MbedTLS client and server (no minicrypto ASM algs for MbedTLS):
|
||||
|
||||
MTLS=1 build proto
|
||||
|
||||
Build with MbedTLS client and server using 4 concurrent threads (no minicrypto ASM algs for MbedTLS):
|
||||
|
||||
-DN_THREADS=4" MTLS=1 build proto
|
||||
|
||||
Build with MbedTLS client and OpenSSL server (no minicrypto ASM algs for MbedTLS):
|
||||
|
||||
MTLS=1 OSSL=1 OPENSSL_SYS=1 build proto
|
||||
|
||||
Build with OpenSSL client and server:
|
||||
|
||||
OSSL=1 OPENSSL_SYS=1 build proto
|
||||
|
||||
Build with AppleSSL client and OpenSSL server:
|
||||
|
||||
SSL_BOTH=1 OPENSSL_SYS=1 build proto
|
||||
|
||||
Build with MbedTLS client and server + minicrypto lib:
|
||||
|
||||
MTLS=1 MINI=1 build proto
|
||||
|
||||
Build with MbedTLS client and server (no minicrypto ASM algs for MbedTLS),
|
||||
except substitute AppleSSL crypto algs for the client side:
|
||||
|
||||
HYBRID=1 build proto
|
||||
|
||||
On Linux:
|
||||
|
||||
Build with MbedTLS client and server (no ASM crypto algs):
|
||||
|
||||
MTLS=1 NOSSL=1 build proto
|
||||
|
||||
Build with OpenSSL client and server:
|
||||
|
||||
OSSL=1 build proto
|
||||
|
||||
Build with MbedTLS client and OpenSSL server:
|
||||
|
||||
MTLS=1 OSSL=1 build proto
|
||||
|
||||
Build with MbedTLS client and server (no ASM crypto algs)
|
||||
using Profile-Guided Optimization:
|
||||
|
||||
PGEN=1 MTLS=1 NOSSL=1 build proto && ./proto && PUSE=1 MTLS=1 NOSSL=1 build proto
|
||||
|
||||
Variations:
|
||||
|
||||
To simulate less data-channel activity and more SSL renegotiations
|
||||
(RENEG default is 900):
|
||||
|
||||
GCC_EXTRA="-DRENEG=90" build proto
|
||||
|
||||
For verbose output, lower the number of xmit/recv iterations by defining
|
||||
ITER to be 10000 or less, e.g.
|
||||
|
||||
GCC_EXTRA="-DITER=1000" build proto
|
||||
|
||||
Crypto self-test (MbedTLS must be built with DEBUG_BUILD=1 or SELF_TEST=1):
|
||||
|
||||
./proto test
|
||||
|
||||
Caveats:
|
||||
|
||||
When using MbedTLS as both client and server, make sure to build
|
||||
MbedTLS on Mac OS X with OSX_SERVER=1.
|
||||
|
||||
Typical output:
|
||||
|
||||
$ time ./proto
|
||||
*** app bytes=73301015 net_bytes=146383320 data_bytes=36327640 prog=0000218807/0000218806 D=12600/600/12600/800 N=1982/1982 SH=17800/17800 HE=3/6
|
||||
real 0m11.003s
|
||||
user 0m10.981s
|
||||
sys 0m0.004s
|
||||
35
test/ssl/ca.crt
Normal file
35
test/ssl/ca.crt
Normal file
@@ -0,0 +1,35 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
103
test/ssl/client.crt
Normal file
103
test/ssl/client.crt
Normal file
@@ -0,0 +1,103 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 2 (0x2)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
|
||||
Validity
|
||||
Not Before: Oct 22 21:59:53 2014 GMT
|
||||
Not After : Oct 19 21:59:53 2024 GMT
|
||||
Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=Test-Client/emailAddress=me@myhost.mydomain
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:ec:65:8f:e9:12:c2:1a:5b:e6:56:2a:08:a9:82:
|
||||
3a:2d:44:78:a3:00:3b:b0:9f:e7:27:10:40:93:ef:
|
||||
f1:cc:3e:a0:aa:04:a2:80:1b:13:a9:e6:fe:81:d6:
|
||||
70:90:a8:d8:d4:de:30:d8:35:00:d2:be:62:f0:48:
|
||||
da:fc:15:8d:c4:c6:6d:0b:99:f1:2b:83:00:0a:d3:
|
||||
2a:23:0b:e5:cd:f9:35:df:43:61:15:72:ad:95:98:
|
||||
f6:73:21:41:5e:a0:dd:47:27:a0:d5:9a:d4:41:a8:
|
||||
1c:1d:57:20:71:17:8f:f7:28:9e:3e:07:ce:ec:d5:
|
||||
0e:42:4f:1e:74:47:8e:47:9d:d2:14:28:27:2c:14:
|
||||
10:f5:d1:96:b5:93:74:84:ef:f9:04:de:8d:4a:6f:
|
||||
df:77:ab:ea:d1:58:d3:44:fe:5a:04:01:ff:06:7a:
|
||||
97:f7:fd:e3:57:48:e1:f0:df:40:13:9f:66:23:5a:
|
||||
e3:55:54:3d:54:39:ee:00:f9:12:f1:d2:df:74:2e:
|
||||
ba:d7:f0:8d:c6:dd:18:58:1c:93:22:0b:75:fa:a8:
|
||||
d6:e0:b5:2f:2d:b9:d4:fe:b9:4f:86:e2:75:48:16:
|
||||
60:fb:3f:c9:b4:30:42:29:fb:3b:b3:2b:b9:59:81:
|
||||
6a:46:f3:45:83:bf:fd:d5:1a:ff:37:0c:6f:5b:fd:
|
||||
61:f1
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
X509v3 Subject Key Identifier:
|
||||
D2:B4:36:0F:B1:FC:DD:A5:EA:2A:F7:C7:23:89:FA:E3:FA:7A:44:1D
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:2B:40:E5:C9:7D:F5:F4:96:38:E9:2F:E3:2F:D9:40:64:C9:8E:05:9B
|
||||
DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
|
||||
serial:A1:4E:DE:FA:90:F2:AE:81
|
||||
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
7f:e0:fe:84:a7:ec:df:62:a5:cd:3c:c1:e6:42:b1:31:12:f0:
|
||||
b9:da:a7:9e:3f:bd:96:52:b6:fc:55:74:64:3e:e4:ff:7e:aa:
|
||||
f7:3e:06:18:5f:73:85:f8:c8:e0:67:1b:4d:97:ca:05:d0:37:
|
||||
07:33:64:9b:e6:78:77:14:9a:55:bb:2a:ac:c3:7f:c9:15:08:
|
||||
83:5c:c8:c2:61:d3:71:4c:05:0b:2b:cb:a3:87:6d:a0:32:ed:
|
||||
b0:b3:27:97:4a:55:8d:01:2a:30:56:68:ab:f2:da:5c:10:73:
|
||||
c9:aa:0a:9c:4b:4c:a0:5b:51:6e:0a:7e:6c:53:80:b0:00:e1:
|
||||
1e:9a:4c:0a:37:9e:20:89:bc:c5:e5:79:58:b7:45:ff:d3:c4:
|
||||
a1:fd:d9:78:3d:45:16:74:df:82:44:1d:1d:81:50:5a:b9:32:
|
||||
4c:e2:4f:3f:0e:3a:65:5a:64:83:3b:29:31:c4:99:88:bc:c5:
|
||||
84:39:f2:19:12:e1:66:d0:ea:fb:75:b1:d2:27:be:91:59:a3:
|
||||
2b:09:d5:5c:bf:46:8e:d6:67:d6:0b:ec:da:ab:f0:80:19:87:
|
||||
64:07:a9:77:b1:5e:0c:e2:c5:1d:6a:ac:5d:23:f3:30:75:36:
|
||||
4e:ca:c3:4e:b0:4d:8c:2c:ce:52:61:63:de:d5:f5:ef:ef:0a:
|
||||
6b:23:25:26:3c:3a:f2:c3:c2:16:19:3f:a9:32:ba:68:f9:c9:
|
||||
12:3c:3e:c6:1f:ff:9b:4e:f4:90:b0:63:f5:d1:33:00:30:5a:
|
||||
e8:24:fa:35:44:9b:6a:80:f3:a6:cc:7b:3c:73:5f:50:c4:30:
|
||||
71:d8:74:90:27:0a:01:4e:a5:5e:b1:f8:da:c2:61:81:11:ae:
|
||||
29:a3:8f:fa:7e:4c:4e:62:b1:00:de:92:e3:8f:6a:2e:da:d9:
|
||||
38:5d:6b:7c:0d:e4:01:aa:c8:c6:6d:8b:cd:c0:c8:6e:e4:57:
|
||||
21:8a:f6:46:30:d9:ad:51:a1:87:96:a6:53:c9:1e:c6:bb:c3:
|
||||
eb:55:fe:8c:d6:5c:d5:c6:f3:ca:b0:60:d2:d4:2a:1f:88:94:
|
||||
d3:4c:1a:da:0c:94:fe:c1:5d:0d:2a:db:99:29:5d:f6:dd:16:
|
||||
c4:c8:4d:74:9e:80:d9:d0:aa:ed:7b:e3:30:e4:47:d8:f5:15:
|
||||
c1:71:b8:c6:fd:ee:fc:9e:b2:5f:b5:b7:92:ed:ff:ca:37:f6:
|
||||
c7:82:b4:54:13:9b:83:cd:87:8b:7e:64:f6:2e:54:3a:22:b1:
|
||||
c5:c1:f4:a5:25:53:9a:4d:a8:0f:e7:35:4b:89:df:19:83:66:
|
||||
64:d9:db:d1:61:2b:24:1b:1d:44:44:fb:49:30:87:b7:49:23:
|
||||
08:02:8a:e0:25:f3:f4:43
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFFDCCAvygAwIBAgIBAjANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJLRzEL
|
||||
MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
|
||||
VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTE0MTAy
|
||||
MjIxNTk1M1oXDTI0MTAxOTIxNTk1M1owajELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
|
||||
Ak5BMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxFDASBgNVBAMTC1Rlc3QtQ2xpZW50
|
||||
MSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqGSIb3
|
||||
DQEBAQUAA4IBDwAwggEKAoIBAQDsZY/pEsIaW+ZWKgipgjotRHijADuwn+cnEECT
|
||||
7/HMPqCqBKKAGxOp5v6B1nCQqNjU3jDYNQDSvmLwSNr8FY3Exm0LmfErgwAK0yoj
|
||||
C+XN+TXfQ2EVcq2VmPZzIUFeoN1HJ6DVmtRBqBwdVyBxF4/3KJ4+B87s1Q5CTx50
|
||||
R45HndIUKCcsFBD10Za1k3SE7/kE3o1Kb993q+rRWNNE/loEAf8Gepf3/eNXSOHw
|
||||
30ATn2YjWuNVVD1UOe4A+RLx0t90LrrX8I3G3RhYHJMiC3X6qNbgtS8tudT+uU+G
|
||||
4nVIFmD7P8m0MEIp+zuzK7lZgWpG80WDv/3VGv83DG9b/WHxAgMBAAGjgcgwgcUw
|
||||
CQYDVR0TBAIwADAdBgNVHQ4EFgQU0rQ2D7H83aXqKvfHI4n64/p6RB0wgZgGA1Ud
|
||||
IwSBkDCBjYAUK0DlyX319JY46S/jL9lAZMmOBZuhaqRoMGYxCzAJBgNVBAYTAktH
|
||||
MQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMMT3BlblZQ
|
||||
Ti1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW6CCQChTt76
|
||||
kPKugTANBgkqhkiG9w0BAQsFAAOCAgEAf+D+hKfs32KlzTzB5kKxMRLwudqnnj+9
|
||||
llK2/FV0ZD7k/36q9z4GGF9zhfjI4GcbTZfKBdA3BzNkm+Z4dxSaVbsqrMN/yRUI
|
||||
g1zIwmHTcUwFCyvLo4dtoDLtsLMnl0pVjQEqMFZoq/LaXBBzyaoKnEtMoFtRbgp+
|
||||
bFOAsADhHppMCjeeIIm8xeV5WLdF/9PEof3ZeD1FFnTfgkQdHYFQWrkyTOJPPw46
|
||||
ZVpkgzspMcSZiLzFhDnyGRLhZtDq+3Wx0ie+kVmjKwnVXL9GjtZn1gvs2qvwgBmH
|
||||
ZAepd7FeDOLFHWqsXSPzMHU2TsrDTrBNjCzOUmFj3tX17+8KayMlJjw68sPCFhk/
|
||||
qTK6aPnJEjw+xh//m070kLBj9dEzADBa6CT6NUSbaoDzpsx7PHNfUMQwcdh0kCcK
|
||||
AU6lXrH42sJhgRGuKaOP+n5MTmKxAN6S449qLtrZOF1rfA3kAarIxm2LzcDIbuRX
|
||||
IYr2RjDZrVGhh5amU8kexrvD61X+jNZc1cbzyrBg0tQqH4iU00wa2gyU/sFdDSrb
|
||||
mSld9t0WxMhNdJ6A2dCq7XvjMORH2PUVwXG4xv3u/J6yX7W3ku3/yjf2x4K0VBOb
|
||||
g82Hi35k9i5UOiKxxcH0pSVTmk2oD+c1S4nfGYNmZNnb0WErJBsdRET7STCHt0kj
|
||||
CAKK4CXz9EM=
|
||||
-----END CERTIFICATE-----
|
||||
28
test/ssl/client.key
Normal file
28
test/ssl/client.key
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDsZY/pEsIaW+ZW
|
||||
KgipgjotRHijADuwn+cnEECT7/HMPqCqBKKAGxOp5v6B1nCQqNjU3jDYNQDSvmLw
|
||||
SNr8FY3Exm0LmfErgwAK0yojC+XN+TXfQ2EVcq2VmPZzIUFeoN1HJ6DVmtRBqBwd
|
||||
VyBxF4/3KJ4+B87s1Q5CTx50R45HndIUKCcsFBD10Za1k3SE7/kE3o1Kb993q+rR
|
||||
WNNE/loEAf8Gepf3/eNXSOHw30ATn2YjWuNVVD1UOe4A+RLx0t90LrrX8I3G3RhY
|
||||
HJMiC3X6qNbgtS8tudT+uU+G4nVIFmD7P8m0MEIp+zuzK7lZgWpG80WDv/3VGv83
|
||||
DG9b/WHxAgMBAAECggEBAIOdaCpUD02trOh8LqZxowJhBOl7z7/ex0uweMPk67LT
|
||||
i5AdVHwOlzwZJ8oSIknoOBEMRBWcLQEojt1JMuL2/R95emzjIKshHHzqZKNulFvB
|
||||
TIUpdnwChTKtH0mqUkLlPU3Ienty4IpNlpmfUKimfbkWHERdBJBHbtDsTABhdo3X
|
||||
9pCF/yRKqJS2Fy/Mkl3gv1y/NB1OL4Jhl7vQbf+kmgfQN2qdOVe2BOKQ8NlPUDmE
|
||||
/1XNIDaE3s6uvUaoFfwowzsCCwN2/8QrRMMKkjvV+lEVtNmQdYxj5Xj5IwS0vkK0
|
||||
6icsngW87cpZxxc1zsRWcSTloy5ohub4FgKhlolmigECgYEA+cBlxzLvaMzMlBQY
|
||||
kCac9KQMvVL+DIFHlZA5i5L/9pRVp4JJwj3GUoehFJoFhsxnKr8HZyLwBKlCmUVm
|
||||
VxnshRWiAU18emUmeAtSGawlAS3QXhikVZDdd/L20YusLT+DXV81wlKR97/r9+17
|
||||
klQOLkSdPm9wcMDOWMNHX8bUg8kCgYEA8k+hQv6+TR/+Beao2IIctFtw/EauaJiJ
|
||||
wW5ql1cpCLPMAOQUvjs0Km3zqctfBF8mUjdkcyJ4uhL9FZtfywY22EtRIXOJ/8VR
|
||||
we65mVo6RLR8YVM54sihanuFOnlyF9LIBWB+9pUfh1/Y7DSebh7W73uxhAxQhi3Y
|
||||
QwfIQIFd8OkCgYBalH4VXhLYhpaYCiXSej6ot6rrK2N6c5Tb2MAWMA1nh+r84tMP
|
||||
gMoh+pDgYPAqMI4mQbxUmqZEeoLuBe6VHpDav7rPECRaW781AJ4ZM4cEQ3Jz/inz
|
||||
4qOAMn10CF081/Ez9ykPPlU0bsYNWHNd4eB2xWnmUBKOwk7UgJatVPaUiQKBgQCI
|
||||
f18CVGpzG9CHFnaK8FCnMNOm6VIaTcNcGY0mD81nv5Dt943P054BQMsAHTY7SjZW
|
||||
HioRyZtkhonXAB2oSqnekh7zzxgv4sG5k3ct8evdBCcE1FNJc2eqikZ0uDETRoOy
|
||||
s7cRxNNr+QxDkyikM+80HOPU1PMPgwfOSrX90GJQ8QKBgEBKohGMV/sNa4t14Iau
|
||||
qO8aagoqh/68K9GFXljsl3/iCSa964HIEREtW09Qz1w3dotEgp2w8bsDa+OwWrLy
|
||||
0SY7T5jRViM3cDWRlUBLrGGiL0FiwsfqiRiji60y19erJgrgyGVIb1kIgIBRkgFM
|
||||
2MMweASzTmZcri4PA/5C0HYb
|
||||
-----END PRIVATE KEY-----
|
||||
8
test/ssl/dh.pem
Normal file
8
test/ssl/dh.pem
Normal file
@@ -0,0 +1,8 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBCAKCAQEArdnA32xujHPlPI+jPffHSoMUZ+b5gRz1H1Lw9//Gugm5TAsRiYrB
|
||||
t2BDSsMKvAjyqN+i5SJv4TOk98kRRKB27iPvyXmiL945VaDQl/UehCySjYlGFUjW
|
||||
9nuo+JwQxeSbw0TLiSYoYJZQ8X1CxPl9mgJl277O4cW1Gc8I/bWa+ipU/4K5wv3h
|
||||
GI8nt+6A0jN3M/KebotMP101G4k0l0qsY4oRMTmP+z3oAP0qU9NZ1jiuMFVzRlNp
|
||||
5FdYF7ctrH+tBF+QmyT4SRKSED4wE4oX6gp420NaBhIEQifIj75wlMDtxQlpkN+x
|
||||
QkjsEbPlaPKHGQ4uupssChVUi8IM2yq5EwIBAg==
|
||||
-----END DH PARAMETERS-----
|
||||
23
test/ssl/go
Executable file
23
test/ssl/go
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
cd $O3/core
|
||||
. vars/vars-osx64
|
||||
. vars/setpath
|
||||
cd test/ssl
|
||||
ASIO=1 MTLS=1 build proto
|
||||
else
|
||||
cd $O3/core
|
||||
. vars/vars-linux
|
||||
. vars/setpath
|
||||
cd test/ssl
|
||||
if [ "$MO_HYBRID" = "1" ]; then
|
||||
# mbedTLS client, OpenSSL server
|
||||
ASIO=1 OPENSSL_SYS=1 MTLS=1 build proto
|
||||
elif [ "$OSSL" = "1" ]; then
|
||||
# OpenSSL client/server
|
||||
ASIO=1 OPENSSL_SYS=1 build proto
|
||||
else
|
||||
# mbedTLS client/server
|
||||
ASIO=1 MTLS=1 NOSSL=1 build proto
|
||||
fi
|
||||
fi
|
||||
1102
test/ssl/proto.cpp
Normal file
1102
test/ssl/proto.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2
test/ssl/protowin.h
Normal file
2
test/ssl/protowin.h
Normal file
@@ -0,0 +1,2 @@
|
||||
//#define RENEG 900
|
||||
//#define ITER 1000
|
||||
113
test/ssl/server.crt
Normal file
113
test/ssl/server.crt
Normal file
@@ -0,0 +1,113 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 1 (0x1)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
|
||||
Validity
|
||||
Not Before: Oct 22 21:59:52 2014 GMT
|
||||
Not After : Oct 19 21:59:52 2024 GMT
|
||||
Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=Test-Server/emailAddress=me@myhost.mydomain
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:a5:b8:a2:ee:ce:b1:a6:0f:6a:b2:9f:d3:22:17:
|
||||
79:de:09:98:71:78:fa:a7:ce:36:51:54:57:c7:31:
|
||||
99:56:d1:8a:d6:c5:fd:52:e6:88:0e:7b:f9:ea:27:
|
||||
7a:bf:3f:14:ec:aa:d2:ff:8b:56:58:ac:ca:51:77:
|
||||
c5:3c:b6:e4:83:6f:22:06:2d:5b:eb:e7:59:d4:ab:
|
||||
42:c8:d5:a9:87:73:b3:73:36:51:2f:a5:d0:90:a2:
|
||||
87:64:54:6c:12:d3:b8:76:47:69:af:ae:8f:00:b3:
|
||||
70:b9:e7:67:3f:8c:6a:3d:79:5f:81:27:a3:0e:aa:
|
||||
a7:3d:81:48:10:b1:18:6c:38:2e:8f:7a:7b:c5:3d:
|
||||
21:c8:f9:a0:7f:17:2b:88:4f:ba:f2:ec:6d:24:8e:
|
||||
6c:f1:0a:5c:d9:5b:b1:b0:fc:49:cb:4a:d2:58:c6:
|
||||
2a:25:b0:97:84:c3:9e:ff:34:8c:10:46:7f:0f:fb:
|
||||
3c:59:7a:a6:29:0c:ae:8e:50:3a:f2:53:84:40:2d:
|
||||
d5:91:7b:0a:37:8e:82:77:ce:66:2f:34:77:5c:a5:
|
||||
45:3b:00:19:a7:07:d1:92:e6:66:b9:3b:4e:e9:63:
|
||||
fc:33:98:1a:ae:7b:08:7d:0a:df:7a:ba:aa:59:6d:
|
||||
86:82:0a:64:2b:da:59:a7:4c:4e:ef:3d:bd:04:a2:
|
||||
4b:31
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Cert Type:
|
||||
SSL Server
|
||||
Netscape Comment:
|
||||
OpenSSL Generated Server Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
B3:9D:81:E6:16:92:64:C4:86:87:F5:29:10:1B:5E:2F:74:F7:ED:B1
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:2B:40:E5:C9:7D:F5:F4:96:38:E9:2F:E3:2F:D9:40:64:C9:8E:05:9B
|
||||
DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
|
||||
serial:A1:4E:DE:FA:90:F2:AE:81
|
||||
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Server Authentication
|
||||
X509v3 Key Usage:
|
||||
Digital Signature, Key Encipherment
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
4e:25:80:1b:cb:b0:42:ff:bb:3f:e8:0d:58:c1:80:db:cf:d0:
|
||||
90:df:ca:c1:e6:41:e1:48:7f:a7:1e:c7:35:9f:9c:6d:7c:3e:
|
||||
82:e8:de:7e:ae:82:16:00:33:0f:02:23:f1:9d:fe:2b:06:16:
|
||||
05:55:16:89:dc:63:ac:5f:1a:31:13:79:21:a3:6e:60:28:e8:
|
||||
e7:6b:54:00:22:a1:b7:69:5a:17:31:ce:0f:c2:a6:dd:a3:6f:
|
||||
de:ea:19:6c:d2:d2:cb:35:9d:dd:87:51:33:68:cd:c3:9b:90:
|
||||
55:f1:80:3d:5c:b8:09:b6:e1:3c:13:a4:5d:4a:ce:a5:11:9e:
|
||||
f9:08:ee:be:e3:54:1d:06:4c:bb:1b:72:13:ee:7d:a0:45:cc:
|
||||
fe:d1:3b:02:03:c1:d4:ea:45:2d:a8:c9:97:e7:f3:8a:7a:a0:
|
||||
2f:dd:48:3a:75:c9:42:28:94:fc:af:44:52:16:68:98:d6:ad:
|
||||
a8:65:b1:cd:ac:60:41:70:e5:44:e8:5a:f2:e7:fc:3b:fe:45:
|
||||
89:17:1d:6d:85:c6:f0:fc:69:87:d1:1d:07:f3:cb:7b:54:8d:
|
||||
aa:a3:cc:e3:c6:fc:d6:05:76:35:d0:26:63:8e:d1:a8:b7:ff:
|
||||
61:42:8a:2c:63:1f:d4:ec:14:47:6b:1e:e3:81:61:12:3b:8c:
|
||||
16:b5:cf:87:6a:2d:42:21:83:9c:0e:3a:90:3a:1e:c1:36:61:
|
||||
41:f9:fb:4e:5d:ea:f4:df:23:92:33:2b:9b:14:9f:a0:f5:d3:
|
||||
c4:f8:1f:2f:9c:11:36:af:2a:22:61:95:32:0b:c4:1c:2d:b1:
|
||||
c1:0a:2a:97:c0:43:4a:6c:3e:db:00:cd:29:15:9e:7e:41:75:
|
||||
36:a8:56:86:8c:82:9e:46:20:e5:06:1e:60:d2:03:5f:9f:9e:
|
||||
69:bb:bf:c2:b4:43:e2:7d:85:17:83:18:41:b0:cb:a9:04:1b:
|
||||
18:52:9f:89:8b:76:9f:94:59:81:4f:60:5b:33:18:fc:c7:52:
|
||||
d0:d2:69:fc:0b:a2:63:32:75:43:99:e9:d7:f8:6d:c7:55:31:
|
||||
0c:f3:ef:1a:71:e1:0a:57:e1:9d:13:b2:1e:fe:1d:ef:e4:f1:
|
||||
51:d9:95:b3:fd:28:28:93:91:4a:29:c5:37:0e:ab:d8:85:6a:
|
||||
fe:a8:83:1f:7b:80:5d:1f:04:79:b7:a9:08:6e:0d:d6:2e:aa:
|
||||
7c:f6:63:7d:41:de:70:13:32:ce:dd:58:cc:a6:73:d4:72:7e:
|
||||
d7:ac:74:a8:35:ba:c3:1b:2a:64:d7:5a:37:97:56:94:34:2b:
|
||||
2a:71:60:bc:69:ab:00:85:b9:4f:67:32:17:51:c3:da:57:3a:
|
||||
37:89:66:c4:7a:51:da:5f
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
AIW5T2cyF1HD2lc6N4lmxHpR2l8=
|
||||
-----END CERTIFICATE-----
|
||||
28
test/ssl/server.key
Normal file
28
test/ssl/server.key
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCluKLuzrGmD2qy
|
||||
n9MiF3neCZhxePqnzjZRVFfHMZlW0YrWxf1S5ogOe/nqJ3q/PxTsqtL/i1ZYrMpR
|
||||
d8U8tuSDbyIGLVvr51nUq0LI1amHc7NzNlEvpdCQoodkVGwS07h2R2mvro8As3C5
|
||||
52c/jGo9eV+BJ6MOqqc9gUgQsRhsOC6PenvFPSHI+aB/FyuIT7ry7G0kjmzxClzZ
|
||||
W7Gw/EnLStJYxiolsJeEw57/NIwQRn8P+zxZeqYpDK6OUDryU4RALdWRewo3joJ3
|
||||
zmYvNHdcpUU7ABmnB9GS5ma5O07pY/wzmBquewh9Ct96uqpZbYaCCmQr2lmnTE7v
|
||||
Pb0EoksxAgMBAAECggEAPMOMin+jR75TYxeTNObiunVOPh0b2zeTVxLT9KfND7ZZ
|
||||
cBK8pg79SEJRCnhbW5BnvbeNEkIm8PC6ZlDCM1bkRwUStq0fDUqQ95esLzOYq5/S
|
||||
5qW98viblszhU/pYfja/Zi8dI1uf96PT63Zbt0NnGQ9N42+DLDeKhtTGdchZqiQA
|
||||
LeSR0bQanY4tUUtCNYvBT8E3pzhoIsUzVwzIK53oovRpcOX3pMXVYZsmNhXdFFRy
|
||||
YkjMXpj7fGyaAJK0QsC+PsgrKuhXDzDttsG2lI/mq9+7RXB3d/pzhmBVWynVH2lw
|
||||
iQ7ONkSz7akDz/4I4WmxJep+FfQJYgK6rnLAlQqauQKBgQDammSAprnvDvNhSEp8
|
||||
W+xt7jQnFqaENbGgP0/D/OZMXc4khgexqlKFmSnBCRDmQ6JvLTWqDXC4+aqAbFQz
|
||||
zAIjiKaT+so8xvFRob+rBMJY5JLYKNa+zUUanfORUNYLFJPvFqnrWGaJ9uufdaM7
|
||||
0a5bu95PN74NXee3DBbpBv8HLwKBgQDCEk+IjNbjMT+Neq0ywUeM5rFrUKi92abe
|
||||
AgsVpjbighRV+6jA2lZFJcize+xYJ9wiOR1/TEI9PZ2OtBkqpwVdvTEHTagRLcvd
|
||||
NfGcptREDnNLoNWA22buQpztiEduutACWQsrd+JQmqbUicUdW4zw86/oCMbYCW3V
|
||||
QmYOLns7nwKBgHHUX20WZE91S4pmqFKlUzHTDdkk1ESX6Qx2q0R01j8BwawHFs6O
|
||||
0DW9EZ7w55nfsh+OPRl1sjK/3ubMgfQO0TZLm+IGf3Sya0qEnVeiPMkpDMX+TgRA
|
||||
wzEe+ou6uho+9uFSvdxMxeglaYA5M2ycvNwLsbEyZ4ZyVYxdgTiKahYFAoGAcIfP
|
||||
iD0qKQiYcj/tB94cz+3AeJqHjbYT1O1YYhBECOkmQ4kuG80+cs/q5W/45lEOiuWV
|
||||
Xgfo7Lu6jVGOujWoneci87oqtvNYH4e09oGh2WiLoBG9Wv9dWtBTUERSLzmxfXsG
|
||||
SAk2uEhEbj8IhfJc8iZLHH9iVUh6YEslBBodqL8CgYEAlAhvcqAvw5SzsfBR5Mcu
|
||||
4Nql6mXEVhHCvS4hdFCGaNF0z9A6eBORKJpdLWnqhpquDQDsghWE+Ga4QKSNFIi1
|
||||
fnAaykmZuY3ToqNOIaVlYM6HpMEz0wHQbTWfDLGcTFcElLZgMAk7VlDyiYVOco+E
|
||||
QX9lXOO1PGpLzXhlDxSe63Y=
|
||||
-----END PRIVATE KEY-----
|
||||
21
test/ssl/tls-auth.key
Normal file
21
test/ssl/tls-auth.key
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# 2048 bit OpenVPN static key
|
||||
#
|
||||
-----BEGIN OpenVPN Static key V1-----
|
||||
02a83428cd0e690e4afe8e9f10b439cb
|
||||
8405bdea3f0cada559df5d8398018258
|
||||
9727346c21655d956611b40ebbbc5280
|
||||
56bb220ac635a3432817110b8ff074af
|
||||
bd3124c39fef2551c3dde7eeb6469c3a
|
||||
a29b38c499e200ebed75c0381684676e
|
||||
890e86da25be6473fb0e484aeed91896
|
||||
ffbc9e78457943a67803924cb6a32074
|
||||
0d314e5114c979ab3849c176d7738278
|
||||
d6d7db6c9a8d70cf1445f9aab193a701
|
||||
38f7af565a8fa368a656e0cec69d4a7b
|
||||
6515ae50d30b269e1750ba59e9e12629
|
||||
cfbfcceefabda3a793f5cb5bbdf18ab3
|
||||
8d69293d8923d427136dd9fcd2660e12
|
||||
dfaa32c0f865f72fffea123b3c12425b
|
||||
86f22ba328f5837ccfab21fc068925f3
|
||||
-----END OpenVPN Static key V1-----
|
||||
402
test/unused
Normal file
402
test/unused
Normal file
@@ -0,0 +1,402 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2015 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// These classes define function objects to be used as asynchronous callbacks
|
||||
// for Asio methods. Think of these as optimized special cases of function
|
||||
// objects that could be more generally (but perhaps less optimally) defined
|
||||
// with lambdas.
|
||||
|
||||
#ifndef OPENVPN_COMMON_ASIODISPATCH_H
|
||||
#define OPENVPN_COMMON_ASIODISPATCH_H
|
||||
|
||||
#include <asio.hpp>
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/rc.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
// Dispatcher for asio async_write
|
||||
|
||||
template <typename C, typename Handler>
|
||||
class AsioDispatchWrite
|
||||
{
|
||||
public:
|
||||
AsioDispatchWrite(Handler handle_write, C* obj)
|
||||
: handle_write_(handle_write), obj_(obj) {}
|
||||
|
||||
void operator()(const asio::error_code& error, const size_t bytes_sent)
|
||||
{
|
||||
(obj_.get()->*handle_write_)(error, bytes_sent);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handle_write_;
|
||||
RCPtr<C> obj_;
|
||||
};
|
||||
|
||||
template <typename C, typename Handler>
|
||||
AsioDispatchWrite<C, Handler> asio_dispatch_write(Handler handle_write, C* obj)
|
||||
{
|
||||
return AsioDispatchWrite<C, Handler>(handle_write, obj);
|
||||
}
|
||||
|
||||
// Dispatcher for asio async_read with argument
|
||||
|
||||
template <typename C, typename Handler, typename Data>
|
||||
class AsioDispatchRead
|
||||
{
|
||||
public:
|
||||
AsioDispatchRead(Handler handle_read, C* obj, Data data)
|
||||
: handle_read_(handle_read), obj_(obj), data_(data) {}
|
||||
|
||||
void operator()(const asio::error_code& error, const size_t bytes_recvd)
|
||||
{
|
||||
(obj_.get()->*handle_read_)(data_, error, bytes_recvd);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handle_read_;
|
||||
RCPtr<C> obj_;
|
||||
Data data_;
|
||||
};
|
||||
|
||||
template <typename C, typename Handler, typename Data>
|
||||
AsioDispatchRead<C, Handler, Data> asio_dispatch_read(Handler handle_read, C* obj, Data data)
|
||||
{
|
||||
return AsioDispatchRead<C, Handler, Data>(handle_read, obj, data);
|
||||
}
|
||||
|
||||
// Dispatcher for asio async_read without argument
|
||||
|
||||
template <typename C, typename Handler>
|
||||
class AsioDispatchReadNoArg
|
||||
{
|
||||
public:
|
||||
AsioDispatchReadNoArg(Handler handle_read, C* obj)
|
||||
: handle_read_(handle_read), obj_(obj) {}
|
||||
|
||||
void operator()(const asio::error_code& error, const size_t bytes_recvd)
|
||||
{
|
||||
(obj_.get()->*handle_read_)(error, bytes_recvd);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handle_read_;
|
||||
RCPtr<C> obj_;
|
||||
};
|
||||
|
||||
template <typename C, typename Handler>
|
||||
AsioDispatchReadNoArg<C, Handler> asio_dispatch_read_noarg(Handler handle_read, C* obj)
|
||||
{
|
||||
return AsioDispatchReadNoArg<C, Handler>(handle_read, obj);
|
||||
}
|
||||
|
||||
// Dispatcher for asio async_wait with argument
|
||||
|
||||
template <typename C, typename Handler, typename Data>
|
||||
class AsioDispatchTimerArg
|
||||
{
|
||||
public:
|
||||
AsioDispatchTimerArg(Handler handler, C* obj, Data data)
|
||||
: handler_(handler), obj_(obj), data_(data) {}
|
||||
|
||||
void operator()(const asio::error_code& error)
|
||||
{
|
||||
(obj_.get()->*handler_)(data_, error);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
RCPtr<C> obj_;
|
||||
Data data_;
|
||||
};
|
||||
|
||||
template <typename C, typename Handler, typename Data>
|
||||
AsioDispatchTimerArg<C, Handler, Data> asio_dispatch_timer_arg(Handler handler, C* obj, Data data)
|
||||
{
|
||||
return AsioDispatchTimerArg<C, Handler, Data>(handler, obj, data);
|
||||
}
|
||||
|
||||
// Dispatcher for asio async_wait without argument
|
||||
|
||||
template <typename C, typename Handler>
|
||||
class AsioDispatchTimer
|
||||
{
|
||||
public:
|
||||
AsioDispatchTimer(Handler handler, C* obj)
|
||||
: handler_(handler), obj_(obj) {}
|
||||
|
||||
void operator()(const asio::error_code& error)
|
||||
{
|
||||
(obj_.get()->*handler_)(error);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
RCPtr<C> obj_;
|
||||
};
|
||||
|
||||
template <typename C, typename Handler>
|
||||
AsioDispatchTimer<C, Handler> asio_dispatch_timer(Handler handler, C* obj)
|
||||
{
|
||||
return AsioDispatchTimer<C, Handler>(handler, obj);
|
||||
}
|
||||
|
||||
// Dispatcher for asio async_connect with argument
|
||||
|
||||
template <typename C, typename Handler, typename Data>
|
||||
class AsioDispatchConnectArg
|
||||
{
|
||||
public:
|
||||
AsioDispatchConnectArg(Handler handler, C* obj, Data data)
|
||||
: handler_(handler), obj_(obj), data_(data) {}
|
||||
|
||||
void operator()(const asio::error_code& error)
|
||||
{
|
||||
(obj_.get()->*handler_)(data_, error);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
RCPtr<C> obj_;
|
||||
Data data_;
|
||||
};
|
||||
|
||||
template <typename C, typename Handler, typename Data>
|
||||
AsioDispatchConnectArg<C, Handler, Data> asio_dispatch_connect_arg(Handler handler, C* obj, Data data)
|
||||
{
|
||||
return AsioDispatchConnectArg<C, Handler, Data>(handler, obj, data);
|
||||
}
|
||||
|
||||
// Dispatcher for asio async_connect without argument
|
||||
|
||||
template <typename C, typename Handler>
|
||||
class AsioDispatchConnect
|
||||
{
|
||||
public:
|
||||
AsioDispatchConnect(Handler handler, C* obj)
|
||||
: handler_(handler), obj_(obj) {}
|
||||
|
||||
void operator()(const asio::error_code& error)
|
||||
{
|
||||
(obj_.get()->*handler_)(error);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
RCPtr<C> obj_;
|
||||
};
|
||||
|
||||
template <typename C, typename Handler>
|
||||
AsioDispatchConnect<C, Handler> asio_dispatch_connect(Handler handler, C* obj)
|
||||
{
|
||||
return AsioDispatchConnect<C, Handler>(handler, obj);
|
||||
}
|
||||
|
||||
// Dispatcher for asio async_connect (ComposedConnectHandler) without argument
|
||||
|
||||
template <typename C, typename Handler>
|
||||
class AsioDispatchComposedConnect
|
||||
{
|
||||
public:
|
||||
AsioDispatchComposedConnect(Handler handler, C* obj)
|
||||
: handler_(handler), obj_(obj) {}
|
||||
|
||||
void operator()(const asio::error_code& error, asio::ip::tcp::resolver::iterator endpoint_iterator)
|
||||
{
|
||||
(obj_.get()->*handler_)(error, endpoint_iterator);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
RCPtr<C> obj_;
|
||||
};
|
||||
|
||||
template <typename C, typename Handler>
|
||||
AsioDispatchComposedConnect<C, Handler> asio_dispatch_composed_connect(Handler handler, C* obj)
|
||||
{
|
||||
return AsioDispatchComposedConnect<C, Handler>(handler, obj);
|
||||
}
|
||||
|
||||
// Dispatcher for asio async_accept with argument
|
||||
|
||||
template <typename C, typename Handler, typename Data>
|
||||
class AsioDispatchAcceptArg
|
||||
{
|
||||
public:
|
||||
AsioDispatchAcceptArg(Handler handler, C* obj, Data data)
|
||||
: handler_(handler), obj_(obj), data_(data) {}
|
||||
|
||||
void operator()(const asio::error_code& error)
|
||||
{
|
||||
(obj_.get()->*handler_)(data_, error);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
RCPtr<C> obj_;
|
||||
Data data_;
|
||||
};
|
||||
|
||||
template <typename C, typename Handler, typename Data>
|
||||
AsioDispatchAcceptArg<C, Handler, Data> asio_dispatch_accept_arg(Handler handler, C* obj, Data data)
|
||||
{
|
||||
return AsioDispatchAcceptArg<C, Handler, Data>(handler, obj, data);
|
||||
}
|
||||
|
||||
// Dispatcher for asio post with argument
|
||||
|
||||
template <typename C, typename Handler, typename Data>
|
||||
class AsioDispatchPostArg
|
||||
{
|
||||
public:
|
||||
AsioDispatchPostArg(Handler handler, C* obj, Data data)
|
||||
: handler_(handler), obj_(obj), data_(data) {}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
(obj_.get()->*handler_)(data_);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
RCPtr<C> obj_;
|
||||
Data data_;
|
||||
};
|
||||
|
||||
template <typename C, typename Handler, typename Data>
|
||||
AsioDispatchPostArg<C, Handler, Data> asio_dispatch_post_arg(Handler handler, C* obj, Data data)
|
||||
{
|
||||
return AsioDispatchPostArg<C, Handler, Data>(handler, obj, data);
|
||||
}
|
||||
|
||||
// Dispatcher for asio post without argument
|
||||
|
||||
template <typename C, typename Handler>
|
||||
class AsioDispatchPost
|
||||
{
|
||||
public:
|
||||
AsioDispatchPost(Handler handler, C* obj)
|
||||
: handler_(handler), obj_(obj) {}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
(obj_.get()->*handler_)();
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
RCPtr<C> obj_;
|
||||
};
|
||||
|
||||
template <typename C, typename Handler>
|
||||
AsioDispatchPost<C, Handler> asio_dispatch_post(Handler handler, C* obj)
|
||||
{
|
||||
return AsioDispatchPost<C, Handler>(handler, obj);
|
||||
}
|
||||
|
||||
// Dispatcher for asynchronous resolver without argument
|
||||
|
||||
template <typename C, typename Handler, typename EndpointIterator>
|
||||
class AsioDispatchResolve
|
||||
{
|
||||
public:
|
||||
AsioDispatchResolve(Handler handler, C* obj)
|
||||
: handler_(handler), obj_(obj) {}
|
||||
|
||||
void operator()(const asio::error_code& error, EndpointIterator iter)
|
||||
{
|
||||
(obj_.get()->*handler_)(error, iter);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
RCPtr<C> obj_;
|
||||
};
|
||||
|
||||
// Dispatcher for asynchronous resolver with argument
|
||||
|
||||
template <typename C, typename Handler, typename EndpointIterator, typename Data>
|
||||
class AsioDispatchResolveArg
|
||||
{
|
||||
public:
|
||||
AsioDispatchResolveArg(Handler handler, C* obj, Data data)
|
||||
: handler_(handler), obj_(obj), data_(data) {}
|
||||
|
||||
void operator()(const asio::error_code& error, EndpointIterator iter)
|
||||
{
|
||||
(obj_.get()->*handler_)(error, iter, data_);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
RCPtr<C> obj_;
|
||||
Data data_;
|
||||
};
|
||||
|
||||
|
||||
// Dispatcher for asio signal
|
||||
|
||||
template <typename C, typename Handler>
|
||||
class AsioDispatchSignal
|
||||
{
|
||||
public:
|
||||
AsioDispatchSignal(Handler handler, C* obj)
|
||||
: handler_(handler), obj_(obj) {}
|
||||
|
||||
void operator()(const asio::error_code& error, int signal_number)
|
||||
{
|
||||
(obj_.get()->*handler_)(error, signal_number);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
RCPtr<C> obj_;
|
||||
};
|
||||
|
||||
template <typename C, typename Handler>
|
||||
AsioDispatchSignal<C, Handler> asio_dispatch_signal(Handler handler, C* obj)
|
||||
{
|
||||
return AsioDispatchSignal<C, Handler>(handler, obj);
|
||||
}
|
||||
|
||||
// General purpose dispatcher with data
|
||||
|
||||
template <typename C, typename Handler, typename Data>
|
||||
class SimpleDispatch
|
||||
{
|
||||
public:
|
||||
SimpleDispatch(Handler handler, C* obj)
|
||||
: handler_(handler), obj_(obj) {}
|
||||
|
||||
void operator()(Data data)
|
||||
{
|
||||
(obj_->*handler_)(data);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
C* obj_;
|
||||
};
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_COMMON_ASIODISPATCH_H
|
||||
Reference in New Issue
Block a user