48 #ifdef HAVE_VERSIONHELPERS_H
49 #include <versionhelpers.h>
157 obj->
sa.nLength =
sizeof(SECURITY_ATTRIBUTES);
158 obj->
sa.lpSecurityDescriptor = &obj->
sd;
159 obj->
sa.bInheritHandle = FALSE;
160 if (!InitializeSecurityDescriptor(&obj->
sd, SECURITY_DESCRIPTOR_REVISION))
164 if (!SetSecurityDescriptorDacl(&obj->
sd, TRUE, NULL, FALSE))
179 o->
overlapped.hEvent = CreateEvent(NULL, TRUE, event_state, NULL);
182 msg(
M_ERR,
"Error: overlapped_io_init: CreateEvent failed");
196 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle failed on overlapped I/O event object");
233 event->write = CreateEvent(NULL, TRUE, FALSE, NULL);
234 if (event->
write == NULL)
236 msg(
M_ERR,
"Error: init_net_event_win32: CreateEvent (write) failed");
248 event->read = CreateEvent(NULL, TRUE, FALSE, NULL);
249 if (event->
read == NULL)
251 msg(
M_ERR,
"Error: init_net_event_win32: CreateEvent (read) failed");
256 if (WSAEventSelect(sd, event->
read, network_events) != 0)
258 msg(
M_FATAL |
M_ERRNO,
"Error: init_net_event_win32: WSAEventSelect call failed");
265 WSANETWORKEVENTS wne;
266 if (WSAEnumNetworkEvents(sd, event->
read, &wne) != 0)
268 msg(
M_FATAL |
M_ERRNO,
"Error: reset_net_event_win32: WSAEnumNetworkEvents call failed");
273 return wne.lNetworkEvents;
284 if (WSAEventSelect(sd, event->
read, 0) != 0)
286 msg(
M_WARN |
M_ERRNO,
"Warning: close_net_event_win32: WSAEventSelect call failed");
289 if (!ResetEvent(event->
read))
291 msg(
M_WARN |
M_ERRNO,
"Warning: ResetEvent (read) failed in close_net_event_win32");
295 if (!CloseHandle(event->
read))
297 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle (read) failed in close_net_event_win32");
305 if (!ResetEvent(event->
write))
307 msg(
M_WARN |
M_ERRNO,
"Warning: ResetEvent (write) failed in close_net_event_win32");
311 if (!CloseHandle(event->
write))
313 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle (write) failed in close_net_event_win32");
354 msg(
M_WARN |
M_ERRNO,
"Warning: SetEvent/ResetEvent failed in net_event_win32_reset_write");
404 HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
407 ir.EventType = KEY_EVENT;
408 ir.Event.KeyEvent.bKeyDown =
true;
409 if (!stdin_handle || !WriteConsoleInput(stdin_handle, &ir, 1, &tmp))
422 msg(
D_LOW,
"win_ctrl_handler: signal received (code=%lu)", (
unsigned long) signum);
432 case CTRL_BREAK_EVENT:
440 msg(
D_LOW,
"win_ctrl_handler: signal (code=%lu) not handled", (
unsigned long) signum);
456 const char *exit_event_name,
457 bool exit_event_initial_state)
462 ws->
in.
read = INVALID_HANDLE_VALUE;
463 ws->
in.
write = INVALID_HANDLE_VALUE;
472 ws->
in.
read = GetStdHandle(STD_INPUT_HANDLE);
473 if (ws->
in.
read != INVALID_HANDLE_VALUE)
479 & ~(ENABLE_WINDOW_INPUT
480 | ENABLE_PROCESSED_INPUT
483 | ENABLE_MOUSE_INPUT);
487 if (!SetConsoleMode(ws->
in.
read, new_console_mode))
489 msg(
M_ERR,
"Error: win32_signal_open: SetConsoleMode failed");
497 ws->
in.
read = INVALID_HANDLE_VALUE;
511 const wchar_t *exit_event_nameW =
wide_string(exit_event_name, &gc);
515 msg(
M_ERR,
"Error: win32_signal_open: init SA failed");
518 ws->
in.
read = CreateEventW(&sa.
sa, TRUE, exit_event_initial_state ? TRUE : FALSE,
526 if (WaitForSingleObject(ws->
in.
read, 0) != WAIT_TIMEOUT)
528 msg(
M_FATAL,
"ERROR: Exit Event ('%s') is signaled", exit_event_name);
551 if (GetNumberOfConsoleInputEvents(ws->
in.
read, &n))
562 if (ir->Event.KeyEvent.uChar.AsciiChar == 0)
564 return ir->Event.KeyEvent.wVirtualScanCode;
567 if ((ir->Event.KeyEvent.dwControlKeyState
568 & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
569 && (ir->Event.KeyEvent.wVirtualKeyCode != 18))
571 return ir->Event.KeyEvent.wVirtualScanCode * 256;
574 return ir->Event.KeyEvent.uChar.AsciiChar;
591 if (!ReadConsoleInput(ws->
in.
read, &ir, 1, &n))
595 }
while (ir.EventType != KEY_EVENT || ir.Event.KeyEvent.bKeyDown != TRUE);
616 msg(
M_ERR,
"Error: win32_signal_close: SetConsoleMode failed");
631 && WaitForSingleObject(ws->
in.
read, 0) == WAIT_OBJECT_0)
691 WaitForSingleObject(ws->
in.
read, INFINITE);
740 SetConsoleTitle(
BSTR(&out));
763 s->
hand = CreateSemaphore(&
sa.sa, 1, 1, name);
786 dmsg(
D_SEMAPHORE_LOW,
"Attempting to lock Win32 semaphore '%s' prior to net shell command (timeout = %d sec)",
788 timeout_milliseconds / 1000);
789 status = WaitForSingleObject(s->
hand, timeout_milliseconds);
790 if (
status == WAIT_FAILED)
792 msg(
M_ERR,
"Wait failed on Win32 semaphore '%s'", s->
name);
794 ret = (
status == WAIT_TIMEOUT) ?
false :
true;
802 dmsg(
D_SEMAPHORE,
"Wait on Win32 semaphore '%s' timed out after %d milliseconds",
804 timeout_milliseconds);
817 if (!ReleaseSemaphore(s->
hand, 1, NULL))
836 CloseHandle(s->
hand);
861 const int timeout_seconds = 600;
870 msg(
M_FATAL,
"Cannot lock net command semaphore");
889 char force_path[256];
892 if (!
openvpn_snprintf(force_path,
sizeof(force_path),
"PATH=%s\\System32;%s;%s\\System32\\Wbem",
893 sysroot, sysroot, sysroot))
895 msg(
M_WARN,
"env_block: default path truncated to %s", force_path);
904 bool path_seen =
false;
908 nchars += strlen(e->
string) + 1;
911 nchars += strlen(force_path)+1;
913 ret = (
char *) malloc(nchars);
922 p += strlen(e->
string) + 1;
924 if (strncmp(e->
string,
"PATH=", 5 ) == 0)
933 msg(
M_INFO,
"env_block: add %s", force_path );
934 strcpy( p, force_path );
935 p += strlen(force_path) + 1;
961 for (i = 0; i < a->
argc; ++i)
963 const char *arg = a->
argv[i];
964 const size_t len = strlen(arg);
976 for (i = 0; i < a->
argc; ++i)
978 const char *arg = a->
argv[i];
1005 static bool exec_warn =
false;
1007 if (a && a->
argv[0])
1012 STARTUPINFOW start_info;
1013 PROCESS_INFORMATION proc_info;
1020 DWORD proc_flags = CREATE_NO_WINDOW;
1026 GetStartupInfoW(&start_info);
1027 start_info.cb =
sizeof(start_info);
1028 start_info.dwFlags = STARTF_USESHOWWINDOW;
1029 start_info.wShowWindow = SW_HIDE;
1031 if (CreateProcessW(cmd, cl, NULL, NULL, FALSE, proc_flags, env, NULL, &start_info, &proc_info))
1033 DWORD exit_status = 0;
1034 CloseHandle(proc_info.hThread);
1035 WaitForSingleObject(proc_info.hProcess, INFINITE);
1036 if (GetExitCodeProcess(proc_info.hProcess, &exit_status))
1038 ret = (int)exit_status;
1044 CloseHandle(proc_info.hProcess);
1065 msg(
M_WARN,
"openvpn_execve: called with empty argv");
1076 STARTUPINFO start_info;
1077 PROCESS_INFORMATION proc_info;
1086 status = GetModuleFileName(NULL, self_exe,
sizeof(self_exe));
1089 msg(
M_WARN|
M_ERRNO,
"fork_to_self: CreateProcess failed: cannot get module name via GetModuleFileName");
1094 GetStartupInfo(&start_info);
1095 start_info.cb =
sizeof(start_info);
1096 start_info.dwFlags = STARTF_USESHOWWINDOW;
1097 start_info.wShowWindow = SW_HIDE;
1099 if (CreateProcess(self_exe, cl, NULL, NULL, FALSE, 0, NULL, NULL, &start_info, &proc_info))
1101 CloseHandle(proc_info.hThread);
1102 CloseHandle(proc_info.hProcess);
1137 if (
status >
sizeof(buf) - 1)
1148 static char tmpdir[MAX_PATH];
1149 WCHAR wtmpdir[MAX_PATH];
1151 if (!GetTempPathW(_countof(wtmpdir), wtmpdir))
1156 msg(
M_WARN,
"Could not find a suitable temporary directory."
1157 " (GetTempPath() failed). Consider using --tmp-dir");
1161 if (WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, NULL, 0, NULL, NULL) >
sizeof(tmpdir))
1163 msg(
M_WARN,
"Could not get temporary directory. Path is too long."
1164 " Consider using --tmp-dir");
1168 WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, tmpdir,
sizeof(tmpdir), NULL, NULL);
1185 .iface = { .index = index, .name =
"" }
1195 msg(
M_WARN,
"Block_DNS: %s block dns filters using service failed: %s [status=0x%x if_index=%d]",
1202 msg(
M_INFO,
"%s outside dns using service succeeded.", (add ?
"Blocking" :
"Unblocking"));
1219 msg(
M_WARN,
"Error in add_block_dns_filters(): %s : %s [status=0x%lx]",
1229 WCHAR openvpnpath[MAX_PATH];
1235 dmsg(
D_LOW,
"Using service to add block dns filters");
1240 status = GetModuleFileNameW(NULL, openvpnpath, _countof(openvpnpath));
1283 msg(
D_LOW,
"Using service to delete block dns filters");
1306 if (!IsWindowsXPOrGreater())
1308 msg(
M_FATAL,
"Error: Windows version must be XP or greater.");
1311 if (!IsWindowsVistaOrGreater())
1316 if (!IsWindows7OrGreater())
1321 if (!IsWindows8OrGreater())
1326 if (!IsWindows8Point1OrGreater())
1331 if (!IsWindows10OrGreater())
1353 typedef BOOL (WINAPI *is_wow64_process2_t)(HANDLE, USHORT *, USHORT *);
1354 is_wow64_process2_t is_wow64_process2 = (is_wow64_process2_t)
1355 GetProcAddress(GetModuleHandle(
"Kernel32.dll"),
"IsWow64Process2");
1357 USHORT process_machine = 0;
1358 USHORT native_machine = 0;
1362 #elif defined(_WIN64)
1364 if (is_wow64_process2)
1367 BOOL is_wow64 = is_wow64_process2(GetCurrentProcess(),
1368 &process_machine, &native_machine);
1369 if (is_wow64 && native_machine == IMAGE_FILE_MACHINE_ARM64)
1374 #elif defined(_WIN32)
1377 if (is_wow64_process2)
1380 BOOL is_wow64 = is_wow64_process2(GetCurrentProcess(),
1381 &process_machine, &native_machine);
1384 switch (native_machine)
1386 case IMAGE_FILE_MACHINE_ARM64:
1390 case IMAGE_FILE_MACHINE_AMD64:
1403 BOOL is_wow64 = IsWow64Process(GetCurrentProcess(), &w64) && w64;
1449 buf_printf(&out,
"5.1%s", add_name ?
" (Windows XP)" :
"");
1453 buf_printf(&out,
"6.0%s", add_name ?
" (Windows Vista)" :
"");
1457 buf_printf(&out,
"6.1%s", add_name ?
" (Windows 7)" :
"");
1461 buf_printf(&out,
"6.2%s", add_name ?
" (Windows 8)" :
"");
1465 buf_printf(&out,
"6.3%s", add_name ?
" (Windows 8.1)" :
"");
1469 buf_printf(&out,
"10.0%s", add_name ?
" (Windows 10 or greater)" :
"");
1474 buf_printf(&out,
"0.0%s", add_name ?
" (unknown)" :
"");
1480 arch_t process_arch, host_arch;
1493 return (
const char *)out.
data;
1504 if (!WriteFile(pipe, data, size, &len, NULL)
1505 || !ReadFile(pipe, ack,
sizeof(*ack), &len, NULL))
1507 msg(
M_WARN,
"%s: could not talk to service: %s [%lu]",
1524 va_start(arglist, format);
1525 len = vswprintf(str, size, format, arglist);
1527 str[size - 1] = L
'\0';
1529 return (len >= 0 && len < size);
1535 WCHAR reg_path[256];
1540 LONG
status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, KEY_READ, &
key);
1541 if (
status != ERROR_SUCCESS)
1547 status = RegGetValueW(
key, NULL, NULL, RRF_RT_REG_SZ, NULL, (LPBYTE)path, &size);
1548 res =
status == ERROR_SUCCESS;
1558 const WCHAR *ssl_fallback_dir = L
"C:\\Windows\\System32";
1560 WCHAR install_path[MAX_PATH] = { 0 };
1566 openvpn_swprintf(install_path, _countof(install_path), L
"%ls", ssl_fallback_dir);
1569 if ((install_path[wcslen(install_path) - 1]) == L
'\\')
1571 install_path[wcslen(install_path) - 1] = L
'\0';
1578 {L
"OPENSSL_CONF", L
"openssl.cnf"},
1579 {L
"OPENSSL_ENGINES", L
"engines"},
1580 {L
"OPENSSL_MODULES", L
"modules"}
1583 for (
size_t i = 0; i <
SIZE(ossl_env); ++i)
1587 _wgetenv_s(&size, NULL, 0, ossl_env[i].name);
1590 WCHAR val[MAX_PATH] = {0};
1591 openvpn_swprintf(val, _countof(val), L
"%ls\\ssl\\%ls", install_path, ossl_env[i].value);
1592 _wputenv_s(ossl_env[i].name, val);
1617 time_t expire =
now + n;
1619 while (expire >=
now)
1623 ||
status == WAIT_TIMEOUT)
1630 if (
status != WAIT_OBJECT_0)
1634 Sleep((expire-
now)*1000);