0
0
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:
James Yonan 2014-08-19 17:02:49 -06:00
commit 5fc2aff9d7
11 changed files with 188 additions and 84 deletions

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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
View 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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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