As discussed a while ago on the mailing list and
community meetings, having SYSTEM elevation hack
inside openvpn code considered harmful.
Since interactive service is the recommended way
of using openvpn on Windows, limiting wintun usage to
interactive service should not be an issue.
Remove elevation hack code and provide an error message
telling user to use interactive service or do SYSTEM
elevation himself via psexec.
Move implementation of register_ring_buffers() to header
amd delete ring_buffer.c.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <
20200724104841.89-1-lstipakov@gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg20567.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
$(OPTIONAL_DL_LIBS) \
$(OPTIONAL_INOTIFY_LIBS)
if WIN32
-openvpn_SOURCES += openvpn_win32_resources.rc block_dns.c block_dns.h ring_buffer.c ring_buffer.h
+openvpn_SOURCES += openvpn_win32_resources.rc block_dns.c block_dns.h ring_buffer.h
openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4 -lncrypt -lsetupapi
endif
<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" />
<ClCompile Include="vlan.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="ring_buffer.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="ssl_ncp.c">
<Filter>Source Files</Filter>
</ClCompile>
+++ /dev/null
-/*
- * 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 <sales@openvpn.net>
- * 2019 Lev Stipakov <lev@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
* that data has been written to receive ring
* @return true if registration is successful, false otherwise - use GetLastError()
*/
-bool register_ring_buffers(HANDLE device,
- struct tun_ring *send_ring,
- struct tun_ring *receive_ring,
- HANDLE send_tail_moved,
- HANDLE receive_tail_moved);
+static 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 /* ifndef OPENVPN_RING_BUFFER_H */
#endif /* ifdef _WIN32 */
}
else
{
- if (!impersonate_as_system())
- {
- msg(M_FATAL, "ERROR: Failed to impersonate as SYSTEM, make sure process is running under privileged account");
- }
- if (!register_ring_buffers(tt->hand,
- tt->wintun_send_ring,
- tt->wintun_receive_ring,
- tt->rw_handle.read,
- tt->rw_handle.write))
- {
- switch (GetLastError())
- {
- case ERROR_ACCESS_DENIED:
- msg(M_FATAL, "Access denied registering ring buffers. Is this process run as SYSTEM?");
- break;
-
- case ERROR_ALREADY_INITIALIZED:
- msg(M_NONFATAL, "Adapter %s is already in use", device_guid);
- break;
-
- default:
- msg(M_NONFATAL | M_ERRNO, "Failed to register ring buffers");
- }
- ret = false;
- }
- if (!RevertToSelf())
- {
- msg(M_FATAL, "ERROR: RevertToSelf error: %lu", GetLastError());
- }
+ msg(M_FATAL, "ERROR: Wintun requires SYSTEM privileges and therefore "
+ "should be used with interactive service. If you want to "
+ "use openvpn from command line, you need to do SYSTEM "
+ "elevation yourself (for example with psexec).");
}
return ret;
return ret;
}
-bool
-impersonate_as_system()
-{
- HANDLE thread_token, process_snapshot, winlogon_process, winlogon_token, duplicated_token;
- PROCESSENTRY32 entry;
- BOOL ret;
- DWORD pid = 0;
- TOKEN_PRIVILEGES privileges;
-
- CLEAR(entry);
- CLEAR(privileges);
-
- entry.dwSize = sizeof(PROCESSENTRY32);
-
- privileges.PrivilegeCount = 1;
- privileges.Privileges->Attributes = SE_PRIVILEGE_ENABLED;
-
- if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privileges.Privileges[0].Luid))
- {
- return false;
- }
-
- if (!ImpersonateSelf(SecurityImpersonation))
- {
- return false;
- }
-
- if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &thread_token))
- {
- RevertToSelf();
- return false;
- }
- if (!AdjustTokenPrivileges(thread_token, FALSE, &privileges, sizeof(privileges), NULL, NULL))
- {
- CloseHandle(thread_token);
- RevertToSelf();
- return false;
- }
- CloseHandle(thread_token);
-
- process_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (process_snapshot == INVALID_HANDLE_VALUE)
- {
- RevertToSelf();
- return false;
- }
- for (ret = Process32First(process_snapshot, &entry); ret; ret = Process32Next(process_snapshot, &entry))
- {
- if (!_stricmp(entry.szExeFile, "winlogon.exe"))
- {
- pid = entry.th32ProcessID;
- break;
- }
- }
- CloseHandle(process_snapshot);
- if (!pid)
- {
- RevertToSelf();
- return false;
- }
-
- winlogon_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
- if (!winlogon_process)
- {
- RevertToSelf();
- return false;
- }
-
- if (!OpenProcessToken(winlogon_process, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &winlogon_token))
- {
- CloseHandle(winlogon_process);
- RevertToSelf();
- return false;
- }
- CloseHandle(winlogon_process);
-
- if (!DuplicateToken(winlogon_token, SecurityImpersonation, &duplicated_token))
- {
- CloseHandle(winlogon_token);
- RevertToSelf();
- return false;
- }
- CloseHandle(winlogon_token);
-
- if (!SetThreadToken(NULL, duplicated_token))
- {
- CloseHandle(duplicated_token);
- RevertToSelf();
- return false;
- }
- CloseHandle(duplicated_token);
-
- return true;
-}
-
#endif /* ifdef _WIN32 */
validate.c validate.h \
$(top_srcdir)/src/openvpn/block_dns.c $(top_srcdir)/src/openvpn/block_dns.h \
openvpnserv_resources.rc \
- $(top_srcdir)/src/openvpn/ring_buffer.c $(top_srcdir)/src/openvpn/ring_buffer.h
+ $(top_srcdir)/src/openvpn/ring_buffer.h
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="..\openvpn\ring_buffer.c" />
<ClCompile Include="automatic.c" />
<ClCompile Include="common.c" />
<ClCompile Include="interactive.c" />
<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">