Definitely an ack. We need this for Wintun and to drop that SYSTEM token hack.
Acked-by: Simon Rozman <si...@rozman.si> Best regards, Simon > -----Original Message----- > From: Lev Stipakov <lstipa...@gmail.com> > Sent: Tuesday, December 17, 2019 1:51 PM > To: openvpn-devel@lists.sourceforge.net > Cc: Lev Stipakov <l...@openvpn.net> > Subject: [Openvpn-devel] [PATCH v5 5/7] wintun: interactive service > support > > From: Lev Stipakov <l...@openvpn.net> > > Wintun requires ring buffers registration to be performed by privileged > process. In order to use openvpn with wintun by non-Administrator, we > need to use interactive service and shared memory to register buffers. > > Openvpn process creates memory mapping object and event for send and > receive ring and passes handles to interactive service. There handles > are duplicated and memory mapped object is mapped into the address space > of service process. > Then address of mapped view and event handle is passed to wintun kernel > driver. > > After interactive service preformed registration, openvpn process maps > memory mapped object into own address space. Thus mapped views in > openvpn and service process represent the same memory region. > > Signed-off-by: Lev Stipakov <l...@openvpn.net> > --- > > While v2 has been ACKed, it had to be rebased on top of previous patch > in series, which required some manual work. > > v5: > - rebased on top of [PATCH v8 4/7] wintun: ring buffers based I/O > (fixed struct tun_ring layout and made DeviceIoControl result check > more robust) > > v4: > - rebased on top of [PATCH v5 4/7] "wintun: ring buffers based I/O" > > v3: > - rebased on top of [PATCH v4 4/7] "wintun: ring buffers based I/O" > - added doxygen comments to ring_buffer.h > > v2: > - rebased on top of master > > include/openvpn-msg.h | 10 ++ > src/openvpn/Makefile.am | 2 +- > src/openvpn/openvpn.vcxproj | 2 + > src/openvpn/openvpn.vcxproj.filters | 8 +- > src/openvpn/ring_buffer.c | 56 ++++++++ > src/openvpn/ring_buffer.h | 104 +++++++++++++++ > src/openvpn/tun.c | 82 ++++++++++-- > src/openvpn/tun.h | 3 + > src/openvpn/win32.c | 27 ---- > src/openvpn/win32.h | 46 ------- > src/openvpnserv/Makefile.am | 3 +- > src/openvpnserv/interactive.c | 141 +++++++++++++++++++- > src/openvpnserv/openvpnserv.vcxproj | 2 + > src/openvpnserv/openvpnserv.vcxproj.filters | 6 + > 14 files changed, 399 insertions(+), 93 deletions(-) create mode > 100644 src/openvpn/ring_buffer.c create mode 100644 > src/openvpn/ring_buffer.h > > diff --git a/include/openvpn-msg.h b/include/openvpn-msg.h index > 66177a21..3ed62069 100644 > --- a/include/openvpn-msg.h > +++ b/include/openvpn-msg.h > @@ -39,6 +39,7 @@ typedef enum { > msg_del_block_dns, > msg_register_dns, > msg_enable_dhcp, > + msg_register_ring_buffers > } message_type_t; > > typedef struct { > @@ -117,4 +118,13 @@ typedef struct { > interface_t iface; > } enable_dhcp_message_t; > > +typedef struct { > + message_header_t header; > + HANDLE device; > + HANDLE send_ring_handle; > + HANDLE receive_ring_handle; > + HANDLE send_tail_moved; > + HANDLE receive_tail_moved; > +} register_ring_buffers_message_t; > + > #endif /* ifndef OPENVPN_MSG_H_ */ > diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index > a091ffc2..d1bb99c2 100644 > --- a/src/openvpn/Makefile.am > +++ b/src/openvpn/Makefile.am > @@ -138,6 +138,6 @@ openvpn_LDADD = \ > $(OPTIONAL_SYSTEMD_LIBS) \ > $(OPTIONAL_DL_LIBS) > if WIN32 > -openvpn_SOURCES += openvpn_win32_resources.rc block_dns.c block_dns.h > +openvpn_SOURCES += openvpn_win32_resources.rc block_dns.c block_dns.h > +ring_buffer.c ring_buffer.h > openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi - > lwinmm -lfwpuclnt -lrpcrt4 -lncrypt -lsetupapi endif diff --git > a/src/openvpn/openvpn.vcxproj b/src/openvpn/openvpn.vcxproj index > 7446d97d..614d720a 100644 > --- a/src/openvpn/openvpn.vcxproj > +++ b/src/openvpn/openvpn.vcxproj > @@ -181,6 +181,7 @@ > <ClCompile Include="ps.c" /> > <ClCompile Include="push.c" /> > <ClCompile Include="reliable.c" /> > + <ClCompile Include="ring_buffer.c" /> > <ClCompile Include="route.c" /> > <ClCompile Include="run_command.c" /> > <ClCompile Include="schedule.c" /> > @@ -265,6 +266,7 @@ > <ClInclude Include="push.h" /> > <ClInclude Include="pushlist.h" /> > <ClInclude Include="reliable.h" /> > + <ClInclude Include="ring_buffer.h" /> > <ClInclude Include="route.h" /> > <ClInclude Include="run_command.h" /> > <ClInclude Include="schedule.h" /> > diff --git a/src/openvpn/openvpn.vcxproj.filters > b/src/openvpn/openvpn.vcxproj.filters > index 653e892c..41e62d14 100644 > --- a/src/openvpn/openvpn.vcxproj.filters > +++ b/src/openvpn/openvpn.vcxproj.filters > @@ -240,6 +240,9 @@ > <ClCompile Include="vlan.c"> > <Filter>Source Files</Filter> > </ClCompile> > + <ClCompile Include="ring_buffer.c"> > + <Filter>Source Files</Filter> > + </ClCompile> > </ItemGroup> > <ItemGroup> > <ClInclude Include="base64.h"> > @@ -500,10 +503,13 @@ > <ClInclude Include="vlan.h"> > <Filter>Header Files</Filter> > </ClInclude> > + <ClInclude Include="ring_buffer.h"> > + <Filter>Header Files</Filter> > + </ClInclude> > </ItemGroup> > <ItemGroup> > <ResourceCompile Include="openvpn_win32_resources.rc"> > <Filter>Resource Files</Filter> > </ResourceCompile> > </ItemGroup> > -</Project> > \ No newline at end of file > +</Project> > diff --git a/src/openvpn/ring_buffer.c b/src/openvpn/ring_buffer.c new > file mode 100644 index 00000000..8c81dc46 > --- /dev/null > +++ b/src/openvpn/ring_buffer.c > @@ -0,0 +1,56 @@ > +/* > + * OpenVPN -- An application to securely tunnel IP networks > + * over a single UDP port, with support for SSL/TLS-based > + * session authentication and key exchange, > + * packet encryption, packet authentication, and > + * packet compression. > + * > + * Copyright (C) 2002-2019 OpenVPN Inc <sa...@openvpn.net> > + * 2019 Lev Stipakov <l...@openvpn.net> > + * > + * This program is free software; you can redistribute it and/or > +modify > + * it under the terms of the GNU General Public License version 2 > + * 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; if not, write to the Free Software Foundation, > +Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + */ > + > +#include "ring_buffer.h" > + > +#ifdef _WIN32 > + > +bool > +register_ring_buffers(HANDLE device, > + struct tun_ring *send_ring, > + struct tun_ring *receive_ring, > + HANDLE send_tail_moved, > + HANDLE receive_tail_moved) { > + struct tun_register_rings rr; > + BOOL res; > + DWORD bytes_returned; > + > + ZeroMemory(&rr, sizeof(rr)); > + > + rr.send.ring = send_ring; > + rr.send.ring_size = sizeof(struct tun_ring); > + rr.send.tail_moved = send_tail_moved; > + > + rr.receive.ring = receive_ring; > + rr.receive.ring_size = sizeof(struct tun_ring); > + rr.receive.tail_moved = receive_tail_moved; > + > + res = DeviceIoControl(device, TUN_IOCTL_REGISTER_RINGS, &rr, > sizeof(rr), > + NULL, 0, &bytes_returned, NULL); > + > + return res != FALSE; > +} > + > +#endif /* ifdef _WIN32 */ > \ No newline at end of file > diff --git a/src/openvpn/ring_buffer.h b/src/openvpn/ring_buffer.h new > file mode 100644 index 00000000..3522c984 > --- /dev/null > +++ b/src/openvpn/ring_buffer.h > @@ -0,0 +1,104 @@ > +/* > + * OpenVPN -- An application to securely tunnel IP networks > + * over a single UDP port, with support for SSL/TLS-based > + * session authentication and key exchange, > + * packet encryption, packet authentication, and > + * packet compression. > + * > + * Copyright (C) 2002-2019 OpenVPN Inc <sa...@openvpn.net> > + * 2019 Lev Stipakov <l...@openvpn.net> > + * > + * This program is free software; you can redistribute it and/or > +modify > + * it under the terms of the GNU General Public License version 2 > + * 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; if not, write to the Free Software Foundation, > +Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + */ > + > +#ifdef _WIN32 > +#ifndef OPENVPN_RING_BUFFER_H > +#define OPENVPN_RING_BUFFER_H > + > +#include <windows.h> > +#include <winioctl.h> > + > +#include <stdint.h> > +#include <stdbool.h> > + > +/* > + * Values below are taken from Wireguard Windows client > + * > +https://github.com/WireGuard/wireguard-go/blob/master/tun/wintun/ring_w > +indows.go#L14 > + */ > +#define WINTUN_RING_CAPACITY 0x800000 > +#define WINTUN_RING_TRAILING_BYTES 0x10000 > +#define WINTUN_MAX_PACKET_SIZE 0xffff > +#define WINTUN_PACKET_ALIGN 4 > + > +#define TUN_IOCTL_REGISTER_RINGS CTL_CODE(51820U, 0x970U, > +METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA) > + > +/** > + * Wintun ring buffer > + * See https://github.com/WireGuard/wintun#ring-layout > + */ > +struct tun_ring > +{ > + volatile ULONG head; > + volatile ULONG tail; > + volatile LONG alertable; > + UCHAR data[WINTUN_RING_CAPACITY + WINTUN_RING_TRAILING_BYTES]; }; > + > +/** > + * Struct for ring buffers registration > + * See https://github.com/WireGuard/wintun#registering-rings > + */ > +struct tun_register_rings > +{ > + struct > + { > + ULONG ring_size; > + struct tun_ring *ring; > + HANDLE tail_moved; > + } send, receive; > +}; > + > +struct TUN_PACKET_HEADER > +{ > + uint32_t size; > +}; > + > +struct TUN_PACKET > +{ > + uint32_t size; > + UCHAR data[WINTUN_MAX_PACKET_SIZE]; }; > + > +/** > + * Registers ring buffers used to exchange data between > + * userspace openvpn process and wintun kernel driver, > + * see https://github.com/WireGuard/wintun#registering-rings > + * > + * @param device handle to opened wintun device > + * @param send_ring pointer to send ring > + * @param receive_ring pointer to receive ring > + * @param send_tail_moved event set by wintun to signal openvpn > + * that data is available for reading in > send ring > + * @param receive_tail_moved event set by openvpn to signal wintun > + * that data has been written to receive > ring > + * @return true if registration is successful, false > otherwise > + */ > +bool register_ring_buffers(HANDLE device, > + struct tun_ring *send_ring, > + struct tun_ring *receive_ring, > + HANDLE send_tail_moved, > + HANDLE receive_tail_moved); > + > +#endif /* ifndef OPENVPN_RING_BUFFER_H */ #endif /* ifdef _WIN32 */ > diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index > 3f66b216..77d84fb2 100644 > --- a/src/openvpn/tun.c > +++ b/src/openvpn/tun.c > @@ -779,17 +779,29 @@ init_tun_post(struct tuntap *tt, > > if (tt->wintun) > { > - tt->wintun_send_ring = malloc(sizeof(struct tun_ring)); > - tt->wintun_receive_ring = malloc(sizeof(struct tun_ring)); > - if ((tt->wintun_send_ring == NULL) || (tt->wintun_receive_ring > == NULL)) > + tt->wintun_send_ring_handle = > CreateFileMapping(INVALID_HANDLE_VALUE, NULL, > + PAGE_READWRITE, > + 0, > + sizeof(struct > tun_ring), > + NULL); > + tt->wintun_receive_ring_handle = > CreateFileMapping(INVALID_HANDLE_VALUE, > + NULL, > + > PAGE_READWRITE, > + 0, > + > sizeof(struct tun_ring), > + NULL); > + if ((tt->wintun_send_ring_handle == NULL) || > + (tt->wintun_receive_ring_handle == NULL)) > { > msg(M_FATAL, "Cannot allocate memory for ring buffer"); > } > - ZeroMemory(tt->wintun_send_ring, sizeof(struct tun_ring)); > - ZeroMemory(tt->wintun_receive_ring, sizeof(struct tun_ring)); > > tt->rw_handle.read = CreateEvent(NULL, FALSE, FALSE, NULL); > tt->rw_handle.write = CreateEvent(NULL, FALSE, FALSE, NULL); > + > + if ((tt->rw_handle.read == NULL) || (tt->rw_handle.write == > NULL)) > + { > + msg(M_FATAL, "Cannot create events for ring buffer"); > + } > } > else > { > @@ -5604,6 +5616,44 @@ register_dns_service(const struct tuntap *tt) > gc_free(&gc); > } > > +static void > +service_register_ring_buffers(const struct tuntap *tt) { > + HANDLE msg_channel = tt->options.msg_channel; > + ack_message_t ack; > + struct gc_arena gc = gc_new(); > + > + register_ring_buffers_message_t msg = { > + .header = { > + msg_register_ring_buffers, > + sizeof(register_ring_buffers_message_t), > + 0 > + }, > + .device = tt->hand, > + .send_ring_handle = tt->wintun_send_ring_handle, > + .receive_ring_handle = tt->wintun_receive_ring_handle, > + .send_tail_moved = tt->rw_handle.read, > + .receive_tail_moved = tt->rw_handle.write > + }; > + > + if (!send_msg_iservice(msg_channel, &msg, sizeof(msg), &ack, > "Register ring buffers")) > + { > + gc_free(&gc); > + return; > + } > + else if (ack.error_number != NO_ERROR) > + { > + msg(M_FATAL, "Register ring buffers failed using service: %s > [status=0x%x]", > + strerror_win32(ack.error_number, &gc), ack.error_number); > + } > + else > + { > + msg(M_INFO, "Ring buffers registered via service"); > + } > + > + gc_free(&gc); > +} > + > void > fork_register_dns_action(struct tuntap *tt) { @@ -6198,9 +6248,20 @@ > open_tun(const char *dev, const char *dev_type, const char *dev_node, > struct tun > > if (tt->wintun) > { > + tt->wintun_send_ring = (struct tun_ring *)MapViewOfFile(tt- > >wintun_send_ring_handle, > + > FILE_MAP_ALL_ACCESS, > + 0, > + 0, > + > sizeof(struct tun_ring)); > + tt->wintun_receive_ring = (struct tun_ring *)MapViewOfFile(tt- > >wintun_receive_ring_handle, > + > FILE_MAP_ALL_ACCESS, > + 0, > + 0, > + > + sizeof(struct tun_ring)); > + > if (tt->options.msg_channel) > { > - /* TODO */ > + service_register_ring_buffers(tt); > } > else > { > @@ -6365,13 +6426,12 @@ close_tun(struct tuntap *tt, openvpn_net_ctx_t > *ctx) > { > CloseHandle(tt->rw_handle.read); > CloseHandle(tt->rw_handle.write); > + UnmapViewOfFile(tt->wintun_send_ring); > + UnmapViewOfFile(tt->wintun_receive_ring); > + CloseHandle(tt->wintun_send_ring_handle); > + CloseHandle(tt->wintun_receive_ring_handle); > } > > - free(tt->wintun_receive_ring); > - free(tt->wintun_send_ring); > - > - tt->wintun_receive_ring = NULL; > - tt->wintun_send_ring = NULL; > > clear_tuntap(tt); > free(tt); > diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h index > 10f687c5..b0b80d1a 100644 > --- a/src/openvpn/tun.h > +++ b/src/openvpn/tun.h > @@ -39,6 +39,7 @@ > #include "proto.h" > #include "misc.h" > #include "networking.h" > +#include "ring_buffer.h" > > #ifdef _WIN32 > #define WINTUN_COMPONENT_ID "wintun" > @@ -183,6 +184,8 @@ struct tuntap > bool wintun; /* true if wintun is used instead of tap-windows6 */ > int standby_iter; > > + HANDLE wintun_send_ring_handle; > + HANDLE wintun_receive_ring_handle; > struct tun_ring *wintun_send_ring; > struct tun_ring *wintun_receive_ring; #else /* ifdef _WIN32 */ > diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c index > 24dae7d6..b2f2a19f 100644 > --- a/src/openvpn/win32.c > +++ b/src/openvpn/win32.c > @@ -1588,31 +1588,4 @@ impersonate_as_system() > return true; > } > > -bool > -register_ring_buffers(HANDLE device, > - struct tun_ring* send_ring, > - struct tun_ring* receive_ring, > - HANDLE send_tail_moved, > - HANDLE receive_tail_moved) > -{ > - struct tun_register_rings rr; > - BOOL res; > - DWORD bytes_returned; > - > - ZeroMemory(&rr, sizeof(rr)); > - > - rr.send.ring = send_ring; > - rr.send.ring_size = sizeof(struct tun_ring); > - rr.send.tail_moved = send_tail_moved; > - > - rr.receive.ring = receive_ring; > - rr.receive.ring_size = sizeof(struct tun_ring); > - rr.receive.tail_moved = receive_tail_moved; > - > - res = DeviceIoControl(device, TUN_IOCTL_REGISTER_RINGS, &rr, > sizeof(rr), > - NULL, 0, &bytes_returned, NULL); > - > - return res != FALSE; > -} > - > #endif /* ifdef _WIN32 */ > diff --git a/src/openvpn/win32.h b/src/openvpn/win32.h index > 5fe95f47..4b508c56 100644 > --- a/src/openvpn/win32.h > +++ b/src/openvpn/win32.h > @@ -325,53 +325,7 @@ bool send_msg_iservice(HANDLE pipe, const void > *data, size_t size, int openvpn_execve(const struct argv *a, const > struct env_set *es, const unsigned int flags); > > -/* > - * Values below are taken from Wireguard Windows client > - * https://github.com/WireGuard/wireguard- > go/blob/master/tun/wintun/ring_windows.go#L14 > - */ > -#define WINTUN_RING_CAPACITY 0x800000 > -#define WINTUN_RING_TRAILING_BYTES 0x10000 -#define > WINTUN_MAX_PACKET_SIZE 0xffff -#define WINTUN_PACKET_ALIGN 4 > - > -struct tun_ring > -{ > - volatile ULONG head; > - volatile ULONG tail; > - volatile LONG alertable; > - UCHAR data[WINTUN_RING_CAPACITY + WINTUN_RING_TRAILING_BYTES]; > -}; > - > -struct tun_register_rings > -{ > - struct > - { > - ULONG ring_size; > - struct tun_ring *ring; > - HANDLE tail_moved; > - } send, receive; > -}; > - > -struct TUN_PACKET_HEADER > -{ > - uint32_t size; > -}; > - > -struct TUN_PACKET > -{ > - uint32_t size; > - UCHAR data[WINTUN_MAX_PACKET_SIZE]; > -}; > - > -#define TUN_IOCTL_REGISTER_RINGS CTL_CODE(51820U, 0x970U, > METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA) > - > bool impersonate_as_system(); > > -bool register_ring_buffers(HANDLE device, > - struct tun_ring *send_ring, > - struct tun_ring *receive_ring, > - HANDLE send_tail_moved, > - HANDLE receive_tail_moved); > - > #endif /* ifndef OPENVPN_WIN32_H */ > #endif /* ifdef _WIN32 */ > diff --git a/src/openvpnserv/Makefile.am b/src/openvpnserv/Makefile.am > index bc65070b..f8d3319c 100644 > --- a/src/openvpnserv/Makefile.am > +++ b/src/openvpnserv/Makefile.am > @@ -36,4 +36,5 @@ openvpnserv_SOURCES = \ > service.c service.h \ > validate.c validate.h \ > $(top_srcdir)/src/openvpn/block_dns.c > $(top_srcdir)/src/openvpn/block_dns.h \ > - openvpnserv_resources.rc > + openvpnserv_resources.rc \ > + $(top_srcdir)/src/openvpn/ring_buffer.c > +$(top_srcdir)/src/openvpn/ring_buffer.h > diff --git a/src/openvpnserv/interactive.c > b/src/openvpnserv/interactive.c index 623c3ff7..6e72a141 100644 > --- a/src/openvpnserv/interactive.c > +++ b/src/openvpnserv/interactive.c > @@ -43,13 +43,15 @@ > #include "openvpn-msg.h" > #include "validate.h" > #include "block_dns.h" > +#include "ring_buffer.h" > > #define IO_TIMEOUT 2000 /*ms*/ > > -#define ERROR_OPENVPN_STARTUP 0x20000000 > -#define ERROR_STARTUP_DATA 0x20000001 > -#define ERROR_MESSAGE_DATA 0x20000002 > -#define ERROR_MESSAGE_TYPE 0x20000003 > +#define ERROR_OPENVPN_STARTUP 0x20000000 > +#define ERROR_STARTUP_DATA 0x20000001 > +#define ERROR_MESSAGE_DATA 0x20000002 > +#define ERROR_MESSAGE_TYPE 0x20000003 > +#define ERROR_REGISTER_RING_BUFFERS 0x20000004 > > static SERVICE_STATUS_HANDLE service; > static SERVICE_STATUS status = { .dwServiceType = > SERVICE_WIN32_SHARE_PROCESS }; @@ -58,6 +60,7 @@ static settings_t > settings; static HANDLE rdns_semaphore = NULL; #define RDNS_TIMEOUT > 600 /* seconds to wait for the semaphore */ > > +#define TUN_IOCTL_REGISTER_RINGS CTL_CODE(51820U, 0x970U, > +METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA) > > openvpn_service_t interactive_service = { > interactive, > @@ -100,6 +103,14 @@ typedef struct { > int metric_v6; > } block_dns_data_t; > > +typedef struct { > + HANDLE send_ring_handle; > + HANDLE receive_ring_handle; > + HANDLE send_tail_moved; > + HANDLE receive_tail_moved; > + HANDLE device; > +} ring_buffer_handles_t; > + > > static DWORD > AddListItem(list_item_t **pfirst, LPVOID data) @@ -154,6 +165,26 @@ > CloseHandleEx(LPHANDLE handle) > return INVALID_HANDLE_VALUE; > } > > +static HANDLE > +OvpnUnmapViewOfFile(LPHANDLE handle) > +{ > + if (handle && *handle && *handle != INVALID_HANDLE_VALUE) > + { > + UnmapViewOfFile(*handle); > + *handle = INVALID_HANDLE_VALUE; > + } > + return INVALID_HANDLE_VALUE; > +} > + > +static void > +CloseRingBufferHandles(ring_buffer_handles_t *ring_buffer_handles) { > + CloseHandleEx(&ring_buffer_handles->device); > + CloseHandleEx(&ring_buffer_handles->receive_tail_moved); > + CloseHandleEx(&ring_buffer_handles->send_tail_moved); > + OvpnUnmapViewOfFile(&ring_buffer_handles->send_ring_handle); > + OvpnUnmapViewOfFile(&ring_buffer_handles->receive_ring_handle); > +} > > static HANDLE > InitOverlapped(LPOVERLAPPED overlapped) @@ -1198,8 +1229,95 @@ > HandleEnableDHCPMessage(const enable_dhcp_message_t *dhcp) > return err; > } > > +static DWORD > +OvpnDuplicateHandle(HANDLE ovpn_proc, HANDLE orig_handle, HANDLE* > +new_handle) { > + DWORD err = ERROR_SUCCESS; > + > + if (!DuplicateHandle(ovpn_proc, orig_handle, GetCurrentProcess(), > new_handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) > + { > + err = GetLastError(); > + MsgToEventLog(M_SYSERR, TEXT("Could not duplicate handle")); > + return err; > + } > + > + return err; > +} > + > +static DWORD > +DuplicateAndMapRing(HANDLE ovpn_proc, HANDLE orig_handle, HANDLE > +*new_handle, struct tun_ring **ring) { > + DWORD err = ERROR_SUCCESS; > + > + err = OvpnDuplicateHandle(ovpn_proc, orig_handle, new_handle); > + if (err != ERROR_SUCCESS) > + { > + return err; > + } > + *ring = (struct tun_ring *)MapViewOfFile(*new_handle, > FILE_MAP_ALL_ACCESS, 0, 0, sizeof(struct tun_ring)); > + if (*ring == NULL) > + { > + err = GetLastError(); > + MsgToEventLog(M_SYSERR, TEXT("Could not map shared memory")); > + return err; > + } > + > + return err; > +} > + > +static DWORD > +HandleRegisterRingBuffers(const register_ring_buffers_message_t *rrb, > HANDLE ovpn_proc, > + ring_buffer_handles_t *ring_buffer_handles) { > + DWORD err = 0; > + struct tun_ring *send_ring; > + struct tun_ring *receive_ring; > + > + CloseRingBufferHandles(ring_buffer_handles); > + > + err = OvpnDuplicateHandle(ovpn_proc, rrb->device, > &ring_buffer_handles->device); > + if (err != ERROR_SUCCESS) > + { > + return err; > + } > + > + err = DuplicateAndMapRing(ovpn_proc, rrb->send_ring_handle, > &ring_buffer_handles->send_ring_handle, &send_ring); > + if (err != ERROR_SUCCESS) > + { > + return err; > + } > + > + err = DuplicateAndMapRing(ovpn_proc, rrb->receive_ring_handle, > &ring_buffer_handles->receive_ring_handle, &receive_ring); > + if (err != ERROR_SUCCESS) > + { > + return err; > + } > + > + err = OvpnDuplicateHandle(ovpn_proc, rrb->send_tail_moved, > &ring_buffer_handles->send_tail_moved); > + if (err != ERROR_SUCCESS) > + { > + return err; > + } > + > + err = OvpnDuplicateHandle(ovpn_proc, rrb->receive_tail_moved, > &ring_buffer_handles->receive_tail_moved); > + if (err != ERROR_SUCCESS) > + { > + return err; > + } > + > + if (!register_ring_buffers(ring_buffer_handles->device, send_ring, > receive_ring, > + ring_buffer_handles->send_tail_moved, > ring_buffer_handles->receive_tail_moved)) > + { > + MsgToEventLog(M_SYSERR, TEXT("Could not register ring > buffers")); > + err = ERROR_REGISTER_RING_BUFFERS; > + } > + > + return err; > +} > + > static VOID > -HandleMessage(HANDLE pipe, DWORD bytes, DWORD count, LPHANDLE events, > undo_lists_t *lists) > +HandleMessage(HANDLE pipe, HANDLE ovpn_proc, ring_buffer_handles_t > *ring_buffer_handles, > + DWORD bytes, DWORD count, LPHANDLE events, undo_lists_t > +*lists) > { > DWORD read; > union { > @@ -1210,6 +1328,7 @@ HandleMessage(HANDLE pipe, DWORD bytes, DWORD > count, LPHANDLE events, undo_lists > block_dns_message_t block_dns; > dns_cfg_message_t dns; > enable_dhcp_message_t dhcp; > + register_ring_buffers_message_t rrb; > } msg; > ack_message_t ack = { > .header = { > @@ -1277,6 +1396,13 @@ HandleMessage(HANDLE pipe, DWORD bytes, DWORD > count, LPHANDLE events, undo_lists > } > break; > > + case msg_register_ring_buffers: > + if (msg.header.size == sizeof(msg.rrb)) > + { > + ack.error_number = HandleRegisterRingBuffers(&msg.rrb, > ovpn_proc, ring_buffer_handles); > + } > + break; > + > default: > ack.error_number = ERROR_MESSAGE_TYPE; > MsgToEventLog(MSG_FLAGS_ERROR, TEXT("Unknown message type > %d"), msg.header.type); @@ -1360,6 +1486,7 @@ RunOpenvpn(LPVOID p) > WCHAR *cmdline = NULL; > size_t cmdline_size; > undo_lists_t undo_lists; > + ring_buffer_handles_t ring_buffer_handles; > > SECURITY_ATTRIBUTES inheritable = { > .nLength = sizeof(inheritable), @@ -1380,6 +1507,7 @@ > RunOpenvpn(LPVOID p) > ZeroMemory(&startup_info, sizeof(startup_info)); > ZeroMemory(&undo_lists, sizeof(undo_lists)); > ZeroMemory(&proc_info, sizeof(proc_info)); > + ZeroMemory(&ring_buffer_handles, sizeof(ring_buffer_handles)); > > if (!GetStartupData(pipe, &sud)) > { > @@ -1611,7 +1739,7 @@ RunOpenvpn(LPVOID p) > break; > } > > - HandleMessage(ovpn_pipe, bytes, 1, &exit_event, &undo_lists); > + HandleMessage(ovpn_pipe, proc_info.hProcess, > + &ring_buffer_handles, bytes, 1, &exit_event, &undo_lists); > } > > WaitForSingleObject(proc_info.hProcess, IO_TIMEOUT); @@ -1638,6 > +1766,7 @@ out: > free(cmdline); > DestroyEnvironmentBlock(user_env); > FreeStartupData(&sud); > + CloseRingBufferHandles(&ring_buffer_handles); > CloseHandleEx(&proc_info.hProcess); > CloseHandleEx(&proc_info.hThread); > CloseHandleEx(&stdin_read); > diff --git a/src/openvpnserv/openvpnserv.vcxproj > b/src/openvpnserv/openvpnserv.vcxproj > index 7061b7b1..c5a34b87 100644 > --- a/src/openvpnserv/openvpnserv.vcxproj > +++ b/src/openvpnserv/openvpnserv.vcxproj > @@ -115,6 +115,7 @@ > </Link> > </ItemDefinitionGroup> > <ItemGroup> > + <ClCompile Include="..\openvpn\ring_buffer.c" /> > <ClCompile Include="automatic.c" /> > <ClCompile Include="common.c" /> > <ClCompile Include="interactive.c" /> @@ -123,6 +124,7 @@ > <ClCompile Include="..\openvpn\block_dns.c" /> > </ItemGroup> > <ItemGroup> > + <ClInclude Include="..\openvpn\ring_buffer.h" /> > <ClInclude Include="service.h" /> > <ClInclude Include="validate.h" /> > <ClInclude Include="..\openvpn\block_dns.h" /> diff --git > a/src/openvpnserv/openvpnserv.vcxproj.filters > b/src/openvpnserv/openvpnserv.vcxproj.filters > index 3ce9bb24..3cb14ef6 100644 > --- a/src/openvpnserv/openvpnserv.vcxproj.filters > +++ b/src/openvpnserv/openvpnserv.vcxproj.filters > @@ -33,6 +33,9 @@ > <ClCompile Include="..\openvpn\block_dns.c"> > <Filter>Source Files</Filter> > </ClCompile> > + <ClCompile Include="..\openvpn\ring_buffer.c"> > + <Filter>Source Files</Filter> > + </ClCompile> > </ItemGroup> > <ItemGroup> > <ClInclude Include="service.h"> > @@ -44,6 +47,9 @@ > <ClInclude Include="..\openvpn\block_dns.h"> > <Filter>Header Files</Filter> > </ClInclude> > + <ClInclude Include="..\openvpn\ring_buffer.h"> > + <Filter>Header Files</Filter> > + </ClInclude> > </ItemGroup> > <ItemGroup> > <ResourceCompile Include="openvpnserv_resources.rc"> > -- > 2.17.1 > > > > _______________________________________________ > Openvpn-devel mailing list > Openvpn-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/openvpn-devel
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel