mirror of
https://github.com/OpenVPN/openvpn3.git
synced 2024-09-20 20:13:05 +02:00
Merge branch 'master' into ios-tun-persist.20140816
This commit is contained in:
commit
5fc2aff9d7
@ -64,7 +64,7 @@
|
||||
#include <openvpn/common/rc.hpp>
|
||||
|
||||
#ifdef OPENVPN_BUFFER_ABORT
|
||||
#define OPENVPN_BUFFER_THROW(exc) { abort(); }
|
||||
#define OPENVPN_BUFFER_THROW(exc) { std::abort(); }
|
||||
#else
|
||||
#define OPENVPN_BUFFER_THROW(exc) { throw BufferException(BufferException::exc); }
|
||||
#endif
|
||||
|
@ -115,7 +115,8 @@ namespace openvpn {
|
||||
|
||||
ClientOptions(const OptionList& opt, // only needs to remain in scope for duration of constructor call
|
||||
const Config& config)
|
||||
: socket_protect(config.socket_protect),
|
||||
: server_addr_float(false),
|
||||
socket_protect(config.socket_protect),
|
||||
reconnect_notify(config.reconnect_notify),
|
||||
cli_stats(config.cli_stats),
|
||||
cli_events(config.cli_events),
|
||||
@ -200,6 +201,9 @@ namespace openvpn {
|
||||
if (opt.exists("remote-random"))
|
||||
remote_list->randomize(*prng);
|
||||
|
||||
// get "float" option
|
||||
server_addr_float = opt.exists("float");
|
||||
|
||||
// special remote cache handling for HTTP proxy
|
||||
if (http_proxy_options)
|
||||
{
|
||||
@ -445,6 +449,7 @@ namespace openvpn {
|
||||
udpconf->frame = frame;
|
||||
udpconf->stats = cli_stats;
|
||||
udpconf->socket_protect = socket_protect;
|
||||
udpconf->server_addr_float = server_addr_float;
|
||||
transport_factory = udpconf;
|
||||
}
|
||||
else if (transport_protocol.is_tcp())
|
||||
@ -470,6 +475,7 @@ namespace openvpn {
|
||||
SSLLib::SSLAPI::Config cc;
|
||||
Client::ProtoConfig::Ptr cp;
|
||||
RemoteList::Ptr remote_list;
|
||||
bool server_addr_float;
|
||||
TransportClientFactory::Ptr transport_factory;
|
||||
TunClientFactory::Ptr tun_factory;
|
||||
SocketProtect* socket_protect;
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm> // for std::min
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/cstdint.hpp> // for boost::uint...
|
||||
@ -572,7 +573,8 @@ namespace openvpn {
|
||||
}
|
||||
}
|
||||
|
||||
void send_push_request_callback(const boost::system::error_code& e)
|
||||
void send_push_request_callback(const Time::Duration& dur,
|
||||
const boost::system::error_code& e)
|
||||
{
|
||||
try {
|
||||
if (!e && !halt && !received_options.partial())
|
||||
@ -588,7 +590,12 @@ namespace openvpn {
|
||||
Base::write_control_string(std::string("PUSH_REQUEST"));
|
||||
Base::flush(true);
|
||||
set_housekeeping_timer();
|
||||
schedule_push_request_callback(false);
|
||||
|
||||
{
|
||||
const Time::Duration newdur = std::min(dur + Time::Duration::seconds(1),
|
||||
Time::Duration::seconds(3));
|
||||
schedule_push_request_callback(newdur);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
@ -597,12 +604,12 @@ namespace openvpn {
|
||||
}
|
||||
}
|
||||
|
||||
void schedule_push_request_callback(bool short_time)
|
||||
void schedule_push_request_callback(const Time::Duration& dur)
|
||||
{
|
||||
if (!received_options.partial())
|
||||
{
|
||||
push_request_timer.expires_at(now() + (short_time ? Time::Duration::seconds(1) : Time::Duration::seconds(3)));
|
||||
push_request_timer.async_wait(asio_dispatch_timer(&Session::send_push_request_callback, this));
|
||||
push_request_timer.expires_at(now() + dur);
|
||||
push_request_timer.async_wait(asio_dispatch_timer_arg(&Session::send_push_request_callback, this, dur));
|
||||
}
|
||||
}
|
||||
|
||||
@ -610,7 +617,7 @@ namespace openvpn {
|
||||
virtual void active()
|
||||
{
|
||||
OPENVPN_LOG("Session is ACTIVE");
|
||||
schedule_push_request_callback(true);
|
||||
schedule_push_request_callback(Time::Duration::seconds(0));
|
||||
}
|
||||
|
||||
void housekeeping_callback(const boost::system::error_code& e)
|
||||
|
@ -20,11 +20,11 @@
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// The file should include any platform-specific files necessary
|
||||
// to declare the abort() function.
|
||||
// to declare the std::abort() function.
|
||||
|
||||
#ifndef OPENVPN_COMMON_ABORT_H
|
||||
#define OPENVPN_COMMON_ABORT_H
|
||||
|
||||
#include <stdlib.h> // defines abort()
|
||||
#include <stdlib.h> // defines std::abort()
|
||||
|
||||
#endif // OPENVPN_COMMON_ABORT_H
|
||||
|
@ -1,68 +0,0 @@
|
||||
// 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) 2013-2014 OpenVPN Technologies, 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_COMMON_MEMCMP_H
|
||||
#define OPENVPN_COMMON_MEMCMP_H
|
||||
|
||||
#include <cstddef> // defines size_t and NULL
|
||||
|
||||
// Constant-time memory comparison method. Can be used in
|
||||
// security-sensitive contexts to inhibit timing attacks.
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
// Is value of type T aligned on A boundary?
|
||||
// NOTE: requires that sizeof(A) is a power of 2
|
||||
template <typename T, typename A>
|
||||
inline bool is_aligned(const T value)
|
||||
{
|
||||
return (size_t(value) & (sizeof(A)-1)) == 0;
|
||||
}
|
||||
|
||||
inline bool memcmp_secure(const unsigned char *p1, const unsigned char *p2, size_t size)
|
||||
{
|
||||
typedef unsigned int altword;
|
||||
if (is_aligned<const unsigned char *, altword>(p1) && is_aligned<const unsigned char *, altword>(p2) && is_aligned<size_t, altword>(size))
|
||||
{
|
||||
//OPENVPN_LOG("*** MEMCMP FAST");
|
||||
volatile altword *u1 = (volatile altword *)p1;
|
||||
volatile altword *u2 = (volatile altword *)p2;
|
||||
altword a = 0;
|
||||
size /= sizeof(altword);
|
||||
while (size--)
|
||||
a |= (*u1++ ^ *u2++);
|
||||
return bool(a);
|
||||
}
|
||||
else
|
||||
{
|
||||
//OPENVPN_LOG("*** MEMCMP CHAR " << (size_t(p1) & (sizeof(altword)-1)) << ' ' << (size_t(p2) & (sizeof(altword)-1)) << ' ' << size);
|
||||
volatile unsigned char *v1 = (volatile unsigned char *)p1;
|
||||
volatile unsigned char *v2 = (volatile unsigned char *)p2;
|
||||
unsigned char a = 0;
|
||||
while (size--)
|
||||
a |= (*v1++ ^ *v2++);
|
||||
return bool(a);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_COMMON_MEMCMP_H
|
116
openvpn/common/memneq.hpp
Normal file
116
openvpn/common/memneq.hpp
Normal file
@ -0,0 +1,116 @@
|
||||
// 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) 2013-2014 OpenVPN Technologies, 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_COMMON_MEMNEQ_H
|
||||
#define OPENVPN_COMMON_MEMNEQ_H
|
||||
|
||||
#include <openvpn/common/arch.hpp>
|
||||
#include <openvpn/common/types.hpp>
|
||||
|
||||
// Does this architecture allow efficient unaligned access?
|
||||
|
||||
#if defined(OPENVPN_ARCH_x86_64) || defined(OPENVPN_ARCH_i386)
|
||||
#define OPENVPN_HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||
#endif
|
||||
|
||||
// Define a portable compiler memory access fence (from Boost).
|
||||
|
||||
#if defined(__INTEL_COMPILER)
|
||||
|
||||
#define OPENVPN_COMPILER_FENCE __memory_barrier();
|
||||
|
||||
#elif defined( _MSC_VER ) && _MSC_VER >= 1310
|
||||
|
||||
extern "C" void _ReadWriteBarrier();
|
||||
#pragma intrinsic( _ReadWriteBarrier )
|
||||
|
||||
#define OPENVPN_COMPILER_FENCE _ReadWriteBarrier();
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
#define OPENVPN_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" );
|
||||
|
||||
#else
|
||||
|
||||
#error need memory fence definition for this compiler
|
||||
|
||||
#endif
|
||||
|
||||
// C++ doesn't allow increment of void *
|
||||
|
||||
#define OPENVPN_INCR_VOID_PTR(var, incr) (var) = static_cast<const unsigned char*>(var) + (incr)
|
||||
|
||||
namespace openvpn {
|
||||
namespace crypto {
|
||||
|
||||
#ifdef OPENVPN_HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||
enum { memneq_unaligned_ok = 1 };
|
||||
typedef size_t memneq_t;
|
||||
#else
|
||||
enum { memneq_unaligned_ok = 0 };
|
||||
typedef unsigned int memneq_t;
|
||||
#endif
|
||||
|
||||
// Is value of type T aligned on A boundary?
|
||||
// NOTE: requires that sizeof(A) is a power of 2
|
||||
template <typename T, typename A>
|
||||
inline bool is_aligned(const T value)
|
||||
{
|
||||
return (size_t(value) & (sizeof(A)-1)) == 0;
|
||||
}
|
||||
|
||||
// Returns true if we are allowed to dereference a and b that
|
||||
// point to objects of type memneq_t.
|
||||
inline bool memneq_deref_ok(const void *a, const void *b)
|
||||
{
|
||||
return memneq_unaligned_ok || (is_aligned<const void *, memneq_t>(a)|is_aligned<const void *, memneq_t>(b));
|
||||
}
|
||||
|
||||
// Constant-time memory equality method. Can be used in
|
||||
// security-sensitive contexts to inhibit timing attacks.
|
||||
inline bool memneq(const void *a, const void *b, size_t size)
|
||||
{
|
||||
memneq_t neq = 0;
|
||||
|
||||
if (memneq_deref_ok(a, b))
|
||||
{
|
||||
while (size >= sizeof(memneq_t))
|
||||
{
|
||||
neq |= *(memneq_t *)a ^ *(memneq_t *)b;
|
||||
OPENVPN_INCR_VOID_PTR(a, sizeof(memneq_t));
|
||||
OPENVPN_INCR_VOID_PTR(b, sizeof(memneq_t));
|
||||
size -= sizeof(memneq_t);
|
||||
}
|
||||
}
|
||||
while (size > 0)
|
||||
{
|
||||
neq |= *(unsigned char *)a ^ *(unsigned char *)b;
|
||||
OPENVPN_INCR_VOID_PTR(a, 1);
|
||||
OPENVPN_INCR_VOID_PTR(b, 1);
|
||||
size -= 1;
|
||||
}
|
||||
OPENVPN_COMPILER_FENCE
|
||||
return bool(neq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -98,6 +98,8 @@ namespace openvpn {
|
||||
RCImpl refcount_;
|
||||
};
|
||||
|
||||
#if !defined(OPENVPN_RC_USERDEF)
|
||||
|
||||
template <typename R>
|
||||
inline void intrusive_ptr_add_ref(R *p) BOOST_NOEXCEPT
|
||||
{
|
||||
@ -111,6 +113,8 @@ namespace openvpn {
|
||||
delete p;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_COMMON_RC_H
|
||||
|
@ -22,6 +22,8 @@
|
||||
#ifndef OPENVPN_COMMON_SIGNAL_H
|
||||
#define OPENVPN_COMMON_SIGNAL_H
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include <openvpn/common/platform.hpp>
|
||||
|
||||
#if !defined(OPENVPN_PLATFORM_WIN)
|
||||
@ -88,6 +90,43 @@ namespace openvpn {
|
||||
|
||||
unsigned int flags_;
|
||||
};
|
||||
|
||||
// Like Asio posix_signal_blocker, but only block certain signals
|
||||
class SignalBlocker : private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
SignalBlocker(const unsigned int flags) // use signal mask from class Signal
|
||||
: blocked_(false)
|
||||
{
|
||||
sigset_t new_mask;
|
||||
sigemptyset(&new_mask);
|
||||
if (flags & Signal::F_SIGINT)
|
||||
sigaddset(&new_mask, SIGINT);
|
||||
if (flags & Signal::F_SIGTERM)
|
||||
sigaddset(&new_mask, SIGTERM);
|
||||
if (flags & Signal::F_SIGHUP)
|
||||
sigaddset(&new_mask, SIGHUP);
|
||||
if (flags & Signal::F_SIGUSR1)
|
||||
sigaddset(&new_mask, SIGUSR1);
|
||||
if (flags & Signal::F_SIGUSR2)
|
||||
sigaddset(&new_mask, SIGUSR2);
|
||||
blocked_ = (pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask_) == 0);
|
||||
}
|
||||
|
||||
// Destructor restores the previous signal mask.
|
||||
~SignalBlocker()
|
||||
{
|
||||
if (blocked_)
|
||||
pthread_sigmask(SIG_SETMASK, &old_mask_, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
// Have signals been blocked.
|
||||
bool blocked_;
|
||||
|
||||
// The previous signal mask.
|
||||
sigset_t old_mask_;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include <openvpn/common/types.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/memcmp.hpp>
|
||||
#include <openvpn/common/memneq.hpp>
|
||||
#include <openvpn/buffer/buffer.hpp>
|
||||
#include <openvpn/random/prng.hpp>
|
||||
#include <openvpn/frame/frame.hpp>
|
||||
@ -58,7 +58,7 @@ namespace openvpn {
|
||||
const size_t hmac_size = hmac.output_size();
|
||||
const unsigned char *packet_hmac = buf.read_alloc(hmac_size);
|
||||
hmac.hmac(local_hmac, hmac_size, buf.c_data(), buf.size());
|
||||
if (memcmp_secure(local_hmac, packet_hmac, hmac_size))
|
||||
if (crypto::memneq(local_hmac, packet_hmac, hmac_size))
|
||||
{
|
||||
buf.reset_size();
|
||||
return Error::HMAC_ERROR;
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include <openvpn/common/types.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/memcmp.hpp>
|
||||
#include <openvpn/common/memneq.hpp>
|
||||
#include <openvpn/crypto/static_key.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
@ -92,7 +92,7 @@ namespace openvpn {
|
||||
if (hmac3_pre(data, data_size, l1, l2, l3))
|
||||
{
|
||||
ctx.final(local_hmac);
|
||||
return !memcmp_secure(data + l1, local_hmac, l2);
|
||||
return !crypto::memneq(data + l1, local_hmac, l2);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <openvpn/buffer/buffer.hpp>
|
||||
#include <openvpn/random/prng.hpp>
|
||||
#include <openvpn/common/hexstr.hpp>
|
||||
#include <openvpn/common/memcmp.hpp>
|
||||
#include <openvpn/common/memneq.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
@ -85,7 +85,7 @@ namespace openvpn {
|
||||
|
||||
bool match(const ProtoSessionID& other) const
|
||||
{
|
||||
return defined_ && other.defined_ && !memcmp_secure(id_, other.id_, SIZE);
|
||||
return defined_ && other.defined_ && !crypto::memneq(id_, other.id_, SIZE);
|
||||
}
|
||||
|
||||
std::string str() const
|
||||
|
Loading…
Reference in New Issue
Block a user