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

wintun: support for privilege separation

This allows to run openvpn under normal user account,
in which case ring buffers registration is performed
by a separate privileged process.

Signed-off-by: Lev Stipakov <lev@openvpn.net>
This commit is contained in:
Lev Stipakov 2019-08-08 16:45:07 +03:00
parent 6f266be3d8
commit 48f2b5100b
12 changed files with 445 additions and 129 deletions

108
openvpn/common/event.hpp Normal file
View File

@ -0,0 +1,108 @@
// 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_WIN_EVENT_H
#define OPENVPN_WIN_EVENT_H
#include <windows.h>
#include <string>
#include <openvpn/buffer/bufhex.hpp>
#include <openvpn/win/winerr.hpp>
#include <openvpn/win/scoped_handle.hpp>
namespace openvpn {
namespace Win {
// Wrap a standard Windows Event object
class Event
{
public:
Event()
{
event.reset(::CreateEvent(NULL, TRUE, FALSE, NULL));
if (!event.defined())
{
const Win::LastError err;
OPENVPN_THROW_EXCEPTION("Win::Event: cannot create Windows event: " << err.message());
}
}
std::string duplicate_local()
{
HANDLE new_handle;
if (!::DuplicateHandle(GetCurrentProcess(),
event(),
GetCurrentProcess(),
&new_handle,
0,
FALSE,
DUPLICATE_SAME_ACCESS))
{
const Win::LastError err;
OPENVPN_THROW_EXCEPTION("Win::Event: DuplicateHandle failed: " << err.message());
}
return BufHex::render(new_handle);
}
void signal_event()
{
if (event.defined())
{
::SetEvent(event());
event.close();
}
}
void release_event()
{
event.close();
}
HANDLE operator()() const
{
return event();
}
void reset(HANDLE h)
{
event.reset(h);
}
private:
ScopedHANDLE event;
};
// Windows event object that automatically signals in the destructor
struct DestroyEvent : public Event
{
~DestroyEvent()
{
signal_event();
}
};
}
}
#endif

View File

@ -31,7 +31,7 @@ namespace openvpn {
// TunPersistTemplate adds persistence capabilities onto TunWrapTemplate,
// in order to implement logic for the persist-tun directive.
template <typename SCOPED_OBJ>
template <typename SCOPED_OBJ, typename STATE=TunProp::State::Ptr>
class TunPersistTemplate : public TunWrapTemplate<SCOPED_OBJ>
{
public:
@ -47,7 +47,7 @@ namespace openvpn {
}
// Current persisted state
const TunProp::State::Ptr& state() const
const STATE& state() const
{
return state_;
}
@ -124,7 +124,7 @@ namespace openvpn {
// Possibly save tunnel fd/handle, state, and options.
bool persist_tun_state(const typename SCOPED_OBJ::base_type obj,
const TunProp::State::Ptr& state)
const STATE& state)
{
if (!enable_persistence_ || !use_persisted_tun_)
{
@ -151,7 +151,7 @@ namespace openvpn {
const bool enable_persistence_;
TunBuilderBase * const tb_;
TunProp::State::Ptr state_;
STATE state_;
std::string options_;
TunBuilderCapture::Ptr copt_;

View File

@ -34,7 +34,17 @@ namespace openvpn {
// These types manage the underlying TAP driver HANDLE
typedef openvpn_io::windows::stream_handle TAPStream;
typedef ScopedAsioStream<TAPStream> ScopedTAPStream;
typedef TunPersistTemplate<ScopedTAPStream> TunPersist;
struct TunPersistState {
TunProp::State::Ptr state;
RingBuffer::Ptr ring_buffer;
void reset()
{
state.reset();
ring_buffer.reset();
}
};
typedef TunPersistTemplate<ScopedTAPStream, TunPersistState> TunPersist;
class ClientConfig : public TunClientFactory
{

View File

@ -33,8 +33,11 @@
#include <openvpn/common/destruct.hpp>
#include <openvpn/common/stop.hpp>
#include <openvpn/common/event.hpp>
#include <openvpn/tun/builder/capture.hpp>
#include <openvpn/tun/win/ringbuffer.hpp>
namespace openvpn {
namespace TunWin {
struct SetupBase : public DestructorBase
@ -46,7 +49,8 @@ namespace openvpn {
virtual HANDLE establish(const TunBuilderCapture& pull,
const std::wstring& openvpn_app_path,
Stop* stop,
std::ostream& os) = 0;
std::ostream& os,
RingBuffer::Ptr rings) = 0;
virtual bool l2_ready(const TunBuilderCapture& pull) = 0;

View File

@ -104,7 +104,7 @@ namespace openvpn {
// Check if persisted tun session matches properties of to-be-created session
if (tun_persist->use_persisted_tun(server_addr, config->tun_prop, opt))
{
state = tun_persist->state();
state = tun_persist->state().state;
OPENVPN_LOG("TunPersist: reused tun context");
}
else
@ -135,14 +135,14 @@ namespace openvpn {
{
std::ostringstream os;
auto os_print = Cleanup([&os](){ OPENVPN_LOG_STRING(os.str()); });
th = tun_setup->establish(*po, Win::module_name(), config->stop, os);
th = tun_setup->establish(*po, Win::module_name(), config->stop, os, NULL);
}
// create ASIO wrapper for HANDLE
TAPStream* ts = new TAPStream(io_context, th);
// persist tun settings state
if (tun_persist->persist_tun_state(ts, state))
if (tun_persist->persist_tun_state(ts, { state, nullptr }))
OPENVPN_LOG("TunPersist: saving tun context:" << std::endl << tun_persist->options());
// setup handler for external tun close

View File

@ -68,7 +68,8 @@ namespace openvpn {
virtual HANDLE establish(const TunBuilderCapture& pull,
const std::wstring& openvpn_app_path,
Stop* stop,
std::ostream& os) override // defined by SetupBase
std::ostream& os,
RingBuffer::Ptr ring_buffer) override // defined by SetupBase
{
// close out old remove cmds, if they exist
destroy(os);
@ -123,6 +124,9 @@ namespace openvpn {
if (pull.layer() == Layer::OSI_LAYER_2)
l2_state.reset(new L2State(tap, openvpn_app_path));
if (ring_buffer)
register_rings(th(), ring_buffer);
return th.release();
}
@ -250,6 +254,31 @@ namespace openvpn {
int indices[2] = {0, 0};
};
void register_rings(HANDLE handle, RingBuffer::Ptr ring_buffer)
{
TUN_REGISTER_RINGS rings;
ZeroMemory(&rings, sizeof(rings));
rings.receive.ring = ring_buffer->receive_ring();
rings.receive.tail_moved = ring_buffer->receive_ring_tail_moved();
rings.receive.ring_size = sizeof(rings.receive.ring->data);
rings.send.ring = ring_buffer->send_ring();
rings.send.tail_moved = ring_buffer->send_ring_tail_moved();
rings.send.ring_size = sizeof(rings.send.ring->data);
{
Win::Impersonate imp(true);
if (!DeviceIoControl(handle, TUN_IOCTL_REGISTER_RINGS, &rings, sizeof(rings), NULL, NULL, NULL, NULL))
{
const Win::LastError err;
throw ErrorCode(Error::TUN_REGISTER_RINGS_ERROR, true, "Error registering ring buffers: " + err.message());
}
}
}
#if _WIN32_WINNT >= 0x0600
// Configure TAP adapter on Vista and higher
void adapter_config(HANDLE th,

View File

@ -6,15 +6,6 @@
#include <openvpn/tun/win/client/clientconfig.hpp>
#include <openvpn/win/modname.hpp>
#define TUN_IOCTL_REGISTER_RINGS CTL_CODE(51820U, 0x970U, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
#define TUN_IOCTL_FORCE_CLOSE_HANDLES CTL_CODE(51820U, 0x971U, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
#define WINTUN_RING_CAPACITY 0x800000
#define WINTUN_RING_TRAILING_BYTES 0x10000
#define WINTUN_RING_FRAMING_SIZE 12
#define WINTUN_MAX_PACKET_SIZE 0xffff
#define WINTUN_PACKET_ALIGN 4
namespace openvpn {
namespace TunWin {
@ -30,53 +21,78 @@ namespace openvpn {
config(config_arg),
parent(parent_arg),
state(new TunProp::State()),
ring_send_tail_moved_event(io_context_arg),
frame(config_arg->frame)
{
}
// Inherited via TunClient
void tun_start(const OptionList& opt, TransportClient& transcli, CryptoDCSettings&) override
{
halt = false;
if (config->tun_persist)
tun_persist = config->tun_persist; // long-term persistent
else
tun_persist.reset(new TunPersist(false, false, nullptr)); // short-term
try {
const IP::Addr server_addr = transcli.server_endpoint_addr();
// notify parent
parent.tun_pre_tun_config();
// Check if persisted tun session matches properties of to-be-created session
if (tun_persist->use_persisted_tun(server_addr, config->tun_prop, opt))
{
state = tun_persist->state().state;
ring_buffer = tun_persist->state().ring_buffer;
OPENVPN_LOG("TunPersist: reused tun context");
}
else
{
// notify parent
parent.tun_pre_tun_config();
// parse pushed options
TunBuilderCapture::Ptr po(new TunBuilderCapture());
TunProp::configure_builder(po.get(),
state.get(),
config->stats.get(),
server_addr,
config->tun_prop,
opt,
nullptr,
false);
OPENVPN_LOG("CAPTURED OPTIONS:" << std::endl << po->to_string());
// close old TAP handle if persisted
tun_persist->close();
// create new tun setup object
tun_setup = config->new_setup_obj(io_context);
// parse pushed options
TunBuilderCapture::Ptr po(new TunBuilderCapture());
TunProp::configure_builder(po.get(),
state.get(),
config->stats.get(),
server_addr,
config->tun_prop,
opt,
nullptr,
false);
OPENVPN_LOG("CAPTURED OPTIONS:" << std::endl << po->to_string());
// open/config TAP
{
std::ostringstream os;
auto os_print = Cleanup([&os]() { OPENVPN_LOG_STRING(os.str()); });
driver_handle = tun_setup->establish(*po, Win::module_name(), config->stop, os);
}
// create new tun setup object
tun_setup = config->new_setup_obj(io_context);
// assert ownership over TAP device handle
tun_setup->confirm();
ring_buffer.reset(new RingBuffer(io_context));
register_rings();
// open/config TAP
HANDLE th;
{
std::ostringstream os;
auto os_print = Cleanup([&os]() { OPENVPN_LOG_STRING(os.str()); });
th = tun_setup->establish(*po, Win::module_name(), config->stop, os, ring_buffer);
}
// create ASIO wrapper for HANDLE
TAPStream* ts = new TAPStream(io_context, th);
// persist tun settings state
if (tun_persist->persist_tun_state(ts, { state, ring_buffer }))
OPENVPN_LOG("TunPersist: saving tun context:" << std::endl << tun_persist->options());
openvpn_io::post([self=Ptr(this)](){
// enable tun_setup destructor
tun_persist->add_destructor(tun_setup);
// assert ownership over TAP device handle
tun_setup->confirm();
}
openvpn_io::post([self = Ptr(this)](){
self->read();
});
@ -98,11 +114,8 @@ namespace openvpn {
if (!halt)
{
halt = true;
unregister_rings();
std::ostringstream os;
auto os_print = Cleanup([&os]() { OPENVPN_LOG_STRING(os.str()); });
tun_setup->destroy(os);
tun_persist.reset();
}
}
@ -113,7 +126,9 @@ namespace openvpn {
bool tun_send(BufferAllocated& buf) override
{
ULONG head = rings.receive.ring->head;
TUN_RING* receive_ring = ring_buffer->receive_ring();
ULONG head = receive_ring->head;
if (head > WINTUN_RING_CAPACITY)
{
if (head == 0xFFFFFFFF)
@ -121,7 +136,7 @@ namespace openvpn {
return false;
}
ULONG tail = rings.receive.ring->tail;
ULONG tail = receive_ring->tail;
if (tail >= WINTUN_RING_CAPACITY)
return false;
@ -134,15 +149,15 @@ namespace openvpn {
}
// copy packet size and data into ring
TUN_PACKET* packet = (TUN_PACKET*)& rings.receive.ring->data[tail];
TUN_PACKET* packet = (TUN_PACKET*)& receive_ring->data[tail];
packet->size = buf.size();
std::memcpy(packet->data, buf.data(), buf.size());
// move ring tail
tail = wrap(tail + aligned_packet_size);
rings.receive.ring->tail = tail;
if (rings.receive.ring->alertable != 0)
SetEvent(rings.receive.tail_moved);
receive_ring->tail = tail;
if (receive_ring->alertable != 0)
SetEvent(ring_buffer->receive_ring_tail_moved());
return true;
}
@ -187,17 +202,19 @@ namespace openvpn {
private:
void read()
{
TUN_RING* send_ring = ring_buffer->send_ring();
if (halt)
return;
ULONG head = rings.send.ring->head;
ULONG head = send_ring->head;
if (head >= WINTUN_RING_CAPACITY)
{
parent.tun_error(Error::TUN_ERROR, "ring head exceeds ring capacity");
return;
}
ULONG tail = rings.send.ring->tail;
ULONG tail = send_ring->tail;
if (tail >= WINTUN_RING_CAPACITY)
{
parent.tun_error(Error::TUN_ERROR, "ring tail exceeds ring capacity");
@ -207,7 +224,7 @@ namespace openvpn {
// tail has moved?
if (head == tail)
{
ring_send_tail_moved_event.async_wait([self=Ptr(this)](const openvpn_io::error_code& error) {
ring_buffer->send_tail_moved_asio_event().async_wait([self=Ptr(this)](const openvpn_io::error_code& error) {
if (!error)
self->read();
else
@ -227,7 +244,7 @@ namespace openvpn {
return;
}
TUN_PACKET* packet = (TUN_PACKET*)& rings.send.ring->data[head];
TUN_PACKET* packet = (TUN_PACKET*)&send_ring->data[head];
if (packet->size > WINTUN_MAX_PACKET_SIZE)
{
parent.tun_error(Error::TUN_ERROR, "packet too big in send ring");
@ -246,7 +263,7 @@ namespace openvpn {
buf.write(packet->data, packet->size);
head = wrap(head + aligned_packet_size);
rings.send.ring->head = head;
send_ring->head = head;
parent.tun_recv(buf);
@ -258,65 +275,6 @@ namespace openvpn {
}
}
void register_rings()
{
ZeroMemory(&rings, sizeof(rings));
rings.receive.ring = new TUN_RING();
ZeroMemory(rings.receive.ring, sizeof(rings.receive.ring));
rings.receive.tail_moved = CreateEvent(NULL, FALSE, FALSE, NULL);
rings.receive.ring_size = sizeof(rings.receive.ring->data);
rings.send.ring = new TUN_RING();
ZeroMemory(rings.send.ring, sizeof(rings.send.ring));
rings.send.tail_moved = CreateEvent(NULL, FALSE, FALSE, NULL);
rings.send.ring_size = sizeof(rings.send.ring->data);
ring_send_tail_moved_event.assign(rings.send.tail_moved);
{
Win::Impersonate imp(true);
if (!DeviceIoControl(driver_handle, TUN_IOCTL_REGISTER_RINGS, &rings, sizeof(rings), NULL, NULL, NULL, NULL))
{
const Win::LastError err;
throw ErrorCode(Error::TUN_REGISTER_RINGS_ERROR, true, "Error registering ring buffers: " + err.message());
}
}
}
void unregister_rings()
{
// delete ring buffers
delete rings.send.ring;
rings.send.ring = nullptr;
delete rings.receive.ring;
rings.receive.ring = nullptr;
// close event handles
CloseHandle(rings.receive.tail_moved);
CloseHandle(driver_handle);
}
struct TUN_RING {
volatile ULONG head;
volatile ULONG tail;
volatile LONG alertable;
UCHAR data[WINTUN_RING_CAPACITY + WINTUN_RING_TRAILING_BYTES + WINTUN_RING_FRAMING_SIZE];
};
struct TUN_REGISTER_RINGS
{
struct
{
ULONG ring_size;
TUN_RING* ring;
HANDLE tail_moved;
} send, receive;
};
struct TUN_PACKET_HEADER
{
uint32_t size;
@ -328,7 +286,6 @@ namespace openvpn {
UCHAR data[WINTUN_MAX_PACKET_SIZE];
};
ULONG packet_align(ULONG size)
{
return (size + (WINTUN_PACKET_ALIGN - 1)) & ~(WINTUN_PACKET_ALIGN - 1);
@ -340,22 +297,24 @@ namespace openvpn {
}
openvpn_io::io_context& io_context;
TunPersist::Ptr tun_persist; // contains the TAP device HANDLE
ClientConfig::Ptr config;
TunClientParent& parent;
TunProp::State::Ptr state;
TunWin::SetupBase::Ptr tun_setup;
TUN_REGISTER_RINGS rings = {};
TUN_RING* receive_ring = nullptr;
TUN_RING* send_ring = nullptr;
BufferAllocated buf;
Frame::Ptr frame;
bool halt;
bool halt = false;
HANDLE driver_handle = NULL;
ScopedHANDLE driver_handle;
openvpn_io::windows::object_handle ring_send_tail_moved_event;
RingBuffer::Ptr ring_buffer;
};
}
}

View File

@ -0,0 +1,158 @@
// 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/>.
//
#pragma once
#include <Windows.h>
#include <string>
#include <openvpn/buffer/bufhex.hpp>
#include <openvpn/common/rc.hpp>
#include <openvpn/win/scoped_handle.hpp>
#define TUN_IOCTL_REGISTER_RINGS CTL_CODE(51820U, 0x970U, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
#define TUN_IOCTL_FORCE_CLOSE_HANDLES CTL_CODE(51820U, 0x971U, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
#define WINTUN_RING_CAPACITY 0x800000
#define WINTUN_RING_TRAILING_BYTES 0x10000
#define WINTUN_RING_FRAMING_SIZE 12
#define WINTUN_MAX_PACKET_SIZE 0xffff
#define WINTUN_PACKET_ALIGN 4
namespace openvpn
{
namespace TunWin
{
struct TUN_RING {
volatile ULONG head;
volatile ULONG tail;
volatile LONG alertable;
UCHAR data[WINTUN_RING_CAPACITY + WINTUN_RING_TRAILING_BYTES + WINTUN_RING_FRAMING_SIZE];
};
struct TUN_REGISTER_RINGS
{
struct
{
ULONG ring_size;
TUN_RING* ring;
HANDLE tail_moved;
} send, receive;
};
typedef openvpn_io::windows::object_handle AsioEvent;
class RingBuffer : public RC<thread_unsafe_refcount>
{
public:
typedef RCPtr<RingBuffer> Ptr;
RingBuffer(openvpn_io::io_context& io_context)
: send_ring_hmem(CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(TUN_RING), NULL)),
receive_ring_hmem(CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(TUN_RING), NULL)),
send_tail_moved_asio_event_(io_context)
{
send_ring_ = (TUN_RING*)MapViewOfFile(send_ring_hmem(), FILE_MAP_ALL_ACCESS, 0, 0, sizeof(TUN_RING));
receive_ring_ = (TUN_RING*)MapViewOfFile(receive_ring_hmem(), FILE_MAP_ALL_ACCESS, 0, 0, sizeof(TUN_RING));
send_tail_moved_asio_event_.assign(send_ring_tail_moved_());
}
RingBuffer(openvpn_io::io_context& io_context,
HANDLE client_process,
const std::string& send_ring_hmem_hex,
const std::string& receive_ring_hmem_hex,
const std::string& send_ring_tail_moved_hex,
const std::string& receive_ring_tail_moved_hex)
: send_tail_moved_asio_event_(io_context)
{
HANDLE remote_handle = BufHex::parse<HANDLE>(send_ring_hmem_hex, "send_ring_hmem");
HANDLE handle;
DuplicateHandle(client_process, remote_handle, GetCurrentProcess(), &handle, 0, FALSE, DUPLICATE_SAME_ACCESS);
send_ring_hmem.reset(handle);
remote_handle = BufHex::parse<HANDLE>(receive_ring_hmem_hex, "receive_ring_hmem");
DuplicateHandle(client_process, remote_handle, GetCurrentProcess(), &handle, 0, FALSE, DUPLICATE_SAME_ACCESS);
receive_ring_hmem.reset(handle);
remote_handle = BufHex::parse<HANDLE>(send_ring_tail_moved_hex, "send_ring_tail_moved");
DuplicateHandle(client_process, remote_handle, GetCurrentProcess(), &handle, 0, FALSE, DUPLICATE_SAME_ACCESS);
send_ring_tail_moved_.reset(handle);
remote_handle = BufHex::parse<HANDLE>(receive_ring_tail_moved_hex, "receive_ring_tail_moved");
DuplicateHandle(client_process, remote_handle, GetCurrentProcess(), &handle, 0, FALSE, DUPLICATE_SAME_ACCESS);
receive_ring_tail_moved_.reset(handle);
send_ring_ = (TUN_RING*)MapViewOfFile(send_ring_hmem(), FILE_MAP_ALL_ACCESS, 0, 0, sizeof(TUN_RING));
receive_ring_ = (TUN_RING*)MapViewOfFile(receive_ring_hmem(), FILE_MAP_ALL_ACCESS, 0, 0, sizeof(TUN_RING));
}
RingBuffer(RingBuffer const&) = delete;
RingBuffer& operator=(RingBuffer const&) = delete;
HANDLE send_ring_tail_moved()
{
return send_ring_tail_moved_();
}
HANDLE receive_ring_tail_moved()
{
return receive_ring_tail_moved_();
}
TUN_RING* send_ring()
{
return send_ring_;
}
TUN_RING* receive_ring()
{
return receive_ring_;
}
AsioEvent& send_tail_moved_asio_event()
{
return send_tail_moved_asio_event_;
}
#ifdef HAVE_JSON
void serialize(Json::Value& json)
{
json["send_ring_hmem"] = BufHex::render(send_ring_hmem());
json["receive_ring_hmem"] = BufHex::render(receive_ring_hmem());
json["send_ring_tail_moved"] = BufHex::render(send_ring_tail_moved());
json["receive_ring_tail_moved"] = BufHex::render(receive_ring_tail_moved());
}
#endif
protected:
Win::ScopedHANDLE send_ring_hmem;
Win::ScopedHANDLE receive_ring_hmem;
Win::Event send_ring_tail_moved_;
Win::Event receive_ring_tail_moved_;
AsioEvent send_tail_moved_asio_event_;
TUN_RING* send_ring_ = nullptr;
TUN_RING* receive_ring_ = nullptr;
};
}
}

View File

@ -87,10 +87,17 @@ namespace openvpn {
{
if (defined())
{
const BOOL ret = ::CloseHandle(handle);
//OPENVPN_LOG("**** SH CLOSE hand=" << handle << " ret=" << ret);
handle = nullptr;
return ret != 0;
__try
{
const BOOL ret = ::CloseHandle(handle);
//OPENVPN_LOG("**** SH CLOSE hand=" << handle << " ret=" << ret);
handle = nullptr;
return ret != 0;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return false;
}
}
else
return true;

View File

@ -10,6 +10,9 @@ Global
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
DebugAgent|ARM = DebugAgent|ARM
DebugAgent|x64 = DebugAgent|x64
DebugAgent|x86 = DebugAgent|x86
DebugOpenSSL|ARM = DebugOpenSSL|ARM
DebugOpenSSL|x64 = DebugOpenSSL|x64
DebugOpenSSL|x86 = DebugOpenSSL|x86
@ -25,6 +28,10 @@ Global
{1F891260-2039-494F-9777-EC5166AF31BC}.Debug|x64.ActiveCfg = Debug|x64
{1F891260-2039-494F-9777-EC5166AF31BC}.Debug|x64.Build.0 = Debug|x64
{1F891260-2039-494F-9777-EC5166AF31BC}.Debug|x86.ActiveCfg = Debug|x64
{1F891260-2039-494F-9777-EC5166AF31BC}.DebugAgent|ARM.ActiveCfg = DebugAgent|x64
{1F891260-2039-494F-9777-EC5166AF31BC}.DebugAgent|x64.ActiveCfg = DebugAgent|x64
{1F891260-2039-494F-9777-EC5166AF31BC}.DebugAgent|x64.Build.0 = DebugAgent|x64
{1F891260-2039-494F-9777-EC5166AF31BC}.DebugAgent|x86.ActiveCfg = DebugAgent|x64
{1F891260-2039-494F-9777-EC5166AF31BC}.DebugOpenSSL|ARM.ActiveCfg = DebugOpenSSL|x64
{1F891260-2039-494F-9777-EC5166AF31BC}.DebugOpenSSL|x64.ActiveCfg = DebugOpenSSL|x64
{1F891260-2039-494F-9777-EC5166AF31BC}.DebugOpenSSL|x64.Build.0 = DebugOpenSSL|x64

View File

@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="DebugAgent|x64">
<Configuration>DebugAgent</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="DebugOpenSSL|x64">
<Configuration>DebugOpenSSL</Configuration>
<Platform>x64</Platform>
@ -121,6 +125,7 @@
<ClInclude Include="..\openvpn\common\endian.hpp" />
<ClInclude Include="..\openvpn\common\enumdir.hpp" />
<ClInclude Include="..\openvpn\common\environ.hpp" />
<ClInclude Include="..\openvpn\common\event.hpp" />
<ClInclude Include="..\openvpn\common\exception.hpp" />
<ClInclude Include="..\openvpn\common\extern.hpp" />
<ClInclude Include="..\openvpn\common\ffs.hpp" />
@ -425,6 +430,7 @@
<ClInclude Include="..\openvpn\tun\win\client\tuncli.hpp" />
<ClInclude Include="..\openvpn\tun\win\client\tunsetup.hpp" />
<ClInclude Include="..\openvpn\tun\win\nrpt.hpp" />
<ClInclude Include="..\openvpn\tun\win\ringbuffer.hpp" />
<ClInclude Include="..\openvpn\tun\win\tunutil.hpp" />
<ClInclude Include="..\openvpn\tun\win\wfp.hpp" />
<ClInclude Include="..\openvpn\tun\win\winproxy.hpp" />
@ -456,6 +462,12 @@
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugAgent|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugOpenSSL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
@ -502,6 +514,26 @@
<ShowProgress>NotSet</ShowProgress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugAgent|x64'">
<ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;TAP_WIN_COMPONENT_ID=tap0901;OPENVPN_COMMAND_AGENT;HAVE_JSONCPP;OVPNAGENT_DISABLE_PATH_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(O3)\deps\amd64\mbedtls\include;$(O3)\deps\amd64\tap-windows\src;$(O3)\deps\amd64\asio\asio\include;$(O3)\deps\amd64\lz4\lib;$(O3)\common;$(O3)\core;$(O3)\deps\amd64\jsoncpp\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<SuppressStartupBanner>false</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(O3)\deps\amd64\mbedtls\library;$(O3)\deps\amd64\lz4\lib;$(O3)\deps\amd64\jsoncpp\dist;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>lz4.lib;mbedtls.lib;fwpuclnt.lib;ws2_32.lib;crypt32.lib;iphlpapi.lib;winmm.lib;advapi32.lib;wininet.lib;shell32.lib;ole32.lib;rpcrt4.lib;Wtsapi32.lib;setupapi.lib;jsoncpp.lib</AdditionalDependencies>
<ShowProgress>NotSet</ShowProgress>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugOpenSSL|x64'">
<ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel>

View File

@ -429,6 +429,8 @@
<ClInclude Include="..\openvpn\ip\ping6.hpp" />
<ClInclude Include="..\openvpn\ip\csum.hpp" />
<ClInclude Include="..\openvpn\tun\win\client\clientconfig.hpp" />
<ClInclude Include="..\openvpn\tun\win\ringbuffer.hpp" />
<ClInclude Include="..\openvpn\common\event.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\test\ovpncli\cli.cpp" />