Merge commit '86cc97e55fe346502462284d2e636a2b3708163e' as 'Sources/OpenVPN3'

This commit is contained in:
Sergey Abramchuk
2020-02-24 14:43:11 +03:00
655 changed files with 146468 additions and 0 deletions
+54
View File
@@ -0,0 +1,54 @@
// 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 Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
#ifndef OPENVPN_LOG_LOGBASE_H
#define OPENVPN_LOG_LOGBASE_H
#include <string>
#include <openvpn/common/rc.hpp>
#define OPENVPN_LOG_CLASS openvpn::LogBase
#define OPENVPN_LOG_INFO(x) x
namespace openvpn {
#ifdef OPENVPN_LOGBASE_NO_RC
struct LogBase
{
virtual void log(const std::string& str) = 0;
};
#else
struct LogBase : public RC<thread_safe_refcount>
{
typedef RCPtr<LogBase> Ptr;
virtual void log(const std::string& str) = 0;
};
#endif
}
#include <openvpn/log/logthread.hpp>
#endif
@@ -0,0 +1,57 @@
// 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 Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
#ifndef OPENVPN_LOG_LOGBASESIMPLE_H
#define OPENVPN_LOG_LOGBASESIMPLE_H
#include <iostream>
#include <mutex>
#include <openvpn/log/logbase.hpp>
#include <openvpn/time/timestr.hpp>
namespace openvpn {
class LogBaseSimple : public LogBase
{
public:
typedef RCPtr<LogBaseSimple> Ptr;
LogBaseSimple()
: log_context(this)
{
}
virtual void log(const std::string& str) override
{
const std::string ts = date_time();
{
std::lock_guard<std::mutex> lock(mutex);
std::cout << ts << ' ' << str << std::flush;
}
}
private:
std::mutex mutex;
Log::Context log_context;
};
}
#endif
@@ -0,0 +1,59 @@
// 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 Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
#ifndef OPENVPN_LOG_LOGBASESIMPLEMAC_H
#define OPENVPN_LOG_LOGBASESIMPLEMAC_H
#include <iostream>
#include <mutex>
#include <openvpn/log/logbase.hpp>
#include <openvpn/time/timestr.hpp>
#include <os/log.h>
namespace openvpn {
class LogBaseSimpleMac : public LogBase
{
public:
typedef RCPtr<LogBaseSimpleMac> Ptr;
LogBaseSimpleMac()
: log_context(this)
{
os_log_with_type(OS_LOG_DEFAULT, OS_LOG_TYPE_DEFAULT,
"LogBaseSimple for macOS/iOS initialized");
}
virtual void log(const std::string& str) override
{
std::lock_guard<std::mutex> lock(mutex);
os_log_with_type(OS_LOG_DEFAULT, OS_LOG_TYPE_DEFAULT,
"OVPN-CORE: %{public}s", str.c_str());
}
private:
std::mutex mutex;
Log::Context log_context;
};
}
#endif
@@ -0,0 +1,49 @@
// 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 Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
// Simple logging with data/time prepend
#pragma once
#include <iostream>
#include <openvpn/time/timestr.hpp>
#ifndef OPENVPN_LOG_STREAM
#define OPENVPN_LOG_STREAM std::cout
#endif
#define OPENVPN_LOG(args) OPENVPN_LOG_STREAM << date_time() << ' ' << args << std::endl
// like OPENVPN_LOG but no trailing newline
#define OPENVPN_LOG_NTNL(args) OPENVPN_LOG_STREAM << date_time() << ' ' << args
#define OPENVPN_LOG_STRING(str) OPENVPN_LOG_STREAM << date_time() << ' ' << (str)
// no-op constructs normally used with logthread.hpp
namespace openvpn {
namespace Log {
struct Context
{
struct Wrapper {};
Context(const Wrapper&) {}
};
}
}
+34
View File
@@ -0,0 +1,34 @@
// 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 Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
// Define null logging macros
#ifndef OPENVPN_LOG_LOGNULL_H
#define OPENVPN_LOG_LOGNULL_H
#define OPENVPN_LOG(args)
// like OPENVPN_LOG but no trailing newline
#define OPENVPN_LOG_NTNL(args)
#define OPENVPN_LOG_STRING(str)
#endif
+174
View File
@@ -0,0 +1,174 @@
// 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 Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
#ifndef OPENVPN_LOG_LOGPERIOD_H
#define OPENVPN_LOG_LOGPERIOD_H
#include <sys/time.h> // for time_t
#include <string>
#include <sstream>
#include <iomanip> // for setfill and setw
#include <openvpn/common/olong.hpp>
#include <openvpn/common/exception.hpp>
#include <openvpn/time/time.hpp>
#include <openvpn/time/timestr.hpp>
namespace openvpn {
class LogPeriod
{
public:
OPENVPN_EXCEPTION(log_period_error);
enum Period {
UNDEF,
DAILY,
HOURLY,
BY_MINUTE,
};
LogPeriod()
: start_(0),
end_(0),
period_(UNDEF)
{
}
LogPeriod(const Period period, const time_t base)
{
period_ = period;
const olong p = period_sec(period_);
start_ = period_base(period_, base);
end_ = start_ + p;
}
LogPeriod(const LogPeriod& other, const int index)
{
period_ = other.period_;
const olong p = period_sec(period_);
start_ = other.start_ + p * olong(index);
end_ = start_ + p;
}
bool is_current(const time_t now) const
{
const olong onow = olong(now);
return onow >= start_ && onow < end_;
}
bool defined() const
{
return period_ != UNDEF;
}
unsigned int expires_in(const time_t now)
{
const olong onow = olong(now);
if (onow < end_)
return end_ - onow;
else
return 0;
}
std::string to_string_verbose() const
{
return date_time(start_) + " -> " + date_time(end_);
}
std::string to_string() const
{
std::ostringstream os;
struct tm lt;
const time_t time = time_t(start_);
if (!localtime_r(&time, &lt))
throw log_period_error("to_string localtime_r");
os << std::setfill('0');
os << std::setw(4) << (lt.tm_year + 1900) << '.' << std::setw(2) << (lt.tm_mon + 1) << '.' << std::setw(2) << lt.tm_mday;
if (period_ == HOURLY || period_ == BY_MINUTE)
os << '-' << std::setw(2) << lt.tm_hour << ':' << std::setw(2) << lt.tm_min;
return os.str();
}
static Period period_from_string(const std::string& str)
{
if (str == "daily")
return DAILY;
else if (str == "hourly")
return HOURLY;
else if (str == "by_minute")
return BY_MINUTE;
else
throw log_period_error("unknown period: " + str);
}
private:
static olong period_sec(const Period p)
{
switch (p)
{
case DAILY:
return 86400;
case HOURLY:
return 3600;
case BY_MINUTE:
return 60;
default:
throw log_period_error("undefined period");
}
}
static olong period_base(const Period p, const time_t time)
{
struct tm lt;
if (!localtime_r(&time, &lt))
throw log_period_error("period_base localtime_r");
switch (p)
{
case DAILY:
lt.tm_hour = 0;
lt.tm_min = 0;
lt.tm_sec = 0;
break;
case HOURLY:
lt.tm_min = 0;
lt.tm_sec = 0;
break;
case BY_MINUTE:
lt.tm_sec = 0;
break;
default:
throw log_period_error("unknown period");
}
const time_t ret = mktime(&lt);
if (ret == -1)
throw log_period_error("mktime");
return olong(ret);
}
private:
olong start_;
olong end_;
Period period_;
};
}
#endif
@@ -0,0 +1,51 @@
// 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 Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
// Define simple logging macros that simply output to stdout
#ifndef OPENVPN_LOG_LOGSIMPLE_H
#define OPENVPN_LOG_LOGSIMPLE_H
#include <iostream>
#ifndef OPENVPN_LOG_STREAM
#define OPENVPN_LOG_STREAM std::cout
#endif
#define OPENVPN_LOG(args) OPENVPN_LOG_STREAM << args << std::endl
// like OPENVPN_LOG but no trailing newline
#define OPENVPN_LOG_NTNL(args) OPENVPN_LOG_STREAM << args
#define OPENVPN_LOG_STRING(str) OPENVPN_LOG_STREAM << (str)
// no-op constructs normally used with logthread.hpp
namespace openvpn {
namespace Log {
struct Context
{
struct Wrapper {};
Context(const Wrapper&) {}
};
}
}
#endif // OPENVPN_LOG_LOGSIMPLE_H
+168
View File
@@ -0,0 +1,168 @@
// 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 Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
// This is a general-purpose logging framework that allows for OPENVPN_LOG and
// OPENVPN_LOG_NTNL macros to dispatch logging data to a thread-local handler.
// NOTE: define USE_ASIO_THREADLOCAL if your C++ doesn't support the
// "thread_local" attribute.
#ifndef OPENVPN_LOG_LOGTHREAD_H
#define OPENVPN_LOG_LOGTHREAD_H
#include <string>
#include <sstream>
#include <thread>
#if defined(USE_ASIO) && defined(USE_ASIO_THREADLOCAL)
#include <asio/detail/tss_ptr.hpp>
#endif
#include <openvpn/common/size.hpp>
#include <openvpn/common/extern.hpp>
// Define these parameters before including this header:
// OPENVPN_LOG_CLASS -- client class that exposes a log() method
// OPENVPN_LOG_INFO -- converts a log string to the form that should be passed to log()
#ifndef OPENVPN_LOG_CLASS
#error OPENVPN_LOG_CLASS must be defined
#endif
#ifndef OPENVPN_LOG_INFO
#error OPENVPN_LOG_INFO must be defined
#endif
# define OPENVPN_LOG(args) \
do { \
if (openvpn::Log::Context::defined()) { \
std::ostringstream _ovpn_log; \
_ovpn_log << args << '\n'; \
(openvpn::Log::Context::obj()->log(OPENVPN_LOG_INFO(_ovpn_log.str()))); \
} \
} while (0)
// like OPENVPN_LOG but no trailing newline
#define OPENVPN_LOG_NTNL(args) \
do { \
if (openvpn::Log::Context::defined()) { \
std::ostringstream _ovpn_log; \
_ovpn_log << args; \
(openvpn::Log::Context::obj()->log(OPENVPN_LOG_INFO(_ovpn_log.str()))); \
} \
} while (0)
# define OPENVPN_LOG_STRING(str) \
do { \
if (openvpn::Log::Context::defined()) { \
(openvpn::Log::Context::obj()->log(OPENVPN_LOG_INFO(str))); \
} \
} while (0)
namespace openvpn {
namespace Log {
#ifdef OPENVPN_LOG_GLOBAL
// OPENVPN_LOG uses global object pointer
OPENVPN_EXTERN OPENVPN_LOG_CLASS* global_log; // GLOBAL
struct Context
{
struct Wrapper
{
};
Context(const Wrapper& wrap)
{
}
Context(OPENVPN_LOG_CLASS *cli)
{
global_log = cli;
}
~Context()
{
global_log = nullptr;
}
static bool defined()
{
return global_log != nullptr;
}
static OPENVPN_LOG_CLASS* obj()
{
return global_log;
}
};
#else
// OPENVPN_LOG uses thread-local object pointer
#if defined(USE_ASIO) && defined(USE_ASIO_THREADLOCAL)
OPENVPN_EXTERN asio::detail::tss_ptr<OPENVPN_LOG_CLASS> global_log; // GLOBAL
#else
OPENVPN_EXTERN thread_local OPENVPN_LOG_CLASS* global_log; // GLOBAL
#endif
struct Context
{
// Mechanism for passing thread-local
// global_log to another thread.
class Wrapper
{
public:
Wrapper() : log(obj()) {}
private:
friend struct Context;
OPENVPN_LOG_CLASS *log;
};
// While in scope, turns on global_log
// for this thread.
Context(const Wrapper& wrap)
{
global_log = wrap.log;
}
Context(OPENVPN_LOG_CLASS *cli)
{
global_log = cli;
}
~Context()
{
global_log = nullptr;
}
static bool defined()
{
return global_log != nullptr;
}
static OPENVPN_LOG_CLASS* obj()
{
return global_log;
}
};
#endif
}
}
#endif
@@ -0,0 +1,176 @@
// 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 Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
// A class that handles statistics tracking in an OpenVPN session
#ifndef OPENVPN_LOG_SESSIONSTATS_H
#define OPENVPN_LOG_SESSIONSTATS_H
#include <cstring>
#include <openvpn/common/size.hpp>
#include <openvpn/common/count.hpp>
#include <openvpn/common/rc.hpp>
#include <openvpn/error/error.hpp>
#include <openvpn/time/time.hpp>
namespace openvpn {
class SessionStats : public RC<thread_safe_refcount>
{
public:
typedef RCPtr<SessionStats> Ptr;
enum Stats {
// operating stats
BYTES_IN = 0, // network bytes in
BYTES_OUT, // network bytes out
PACKETS_IN, // network packets in
PACKETS_OUT, // network packets out
TUN_BYTES_IN, // tun/tap bytes in
TUN_BYTES_OUT, // tun/tap bytes out
TUN_PACKETS_IN, // tun/tap packets in
TUN_PACKETS_OUT, // tun/tap packets out
N_STATS,
};
SessionStats()
: verbose_(false)
{
std::memset((void *)stats_, 0, sizeof(stats_));
}
virtual void error(const size_t type, const std::string* text=nullptr) {}
// if true, clients may provide additional detail to error() method above
// via text argument.
bool verbose() const { return verbose_; }
#ifdef OPENVPN_STATS_VIRTUAL
virtual
#endif
void inc_stat(const size_t type, const count_t value)
{
if (type < N_STATS)
stats_[type] += value;
}
count_t get_stat(const size_t type) const
{
if (type < N_STATS)
return stats_[type];
else
return 0;
}
count_t get_stat_fast(const size_t type) const
{
return stats_[type];
}
static const char *stat_name(const size_t type)
{
static const char *names[] = {
"BYTES_IN",
"BYTES_OUT",
"PACKETS_IN",
"PACKETS_OUT",
"TUN_BYTES_IN",
"TUN_BYTES_OUT",
"TUN_PACKETS_IN",
"TUN_PACKETS_OUT",
};
if (type < N_STATS)
return names[type];
else
return "UNKNOWN_STAT_TYPE";
}
void update_last_packet_received(const Time& now)
{
last_packet_received_ = now;
}
const Time& last_packet_received() const { return last_packet_received_; }
struct DCOTransportSource : public virtual RC<thread_unsafe_refcount>
{
typedef RCPtr<DCOTransportSource> Ptr;
struct Data {
count_t bytes_in;
count_t bytes_out;
Data()
: bytes_in(0),
bytes_out(0)
{
}
Data(count_t bytes_in_arg, count_t bytes_out_arg)
: bytes_in(bytes_in_arg),
bytes_out(bytes_out_arg)
{
}
Data operator-(const Data& rhs) const
{
Data data;
if (bytes_in > rhs.bytes_in)
data.bytes_in = bytes_in - rhs.bytes_in;
if (bytes_out > rhs.bytes_out)
data.bytes_out = bytes_out - rhs.bytes_out;
return data;
}
};
virtual Data dco_transport_stats_delta() = 0;
};
void dco_configure(SessionStats::DCOTransportSource* source)
{
dco_.reset(source);
}
void dco_update()
{
if (dco_)
{
const DCOTransportSource::Data data = dco_->dco_transport_stats_delta();
stats_[BYTES_IN] += data.bytes_in;
stats_[BYTES_OUT] += data.bytes_out;
}
}
protected:
void session_stats_set_verbose(const bool v) { verbose_ = v; }
private:
bool verbose_;
Time last_packet_received_;
DCOTransportSource::Ptr dco_;
volatile count_t stats_[N_STATS];
};
} // namespace openvpn
#endif // OPENVPN_LOG_SESSIONSTATS_H