37 #include <minwindef.h>
51 #include <versionhelpers.h>
156 obj->
sa.nLength =
sizeof(SECURITY_ATTRIBUTES);
157 obj->
sa.lpSecurityDescriptor = &obj->
sd;
158 obj->
sa.bInheritHandle = FALSE;
159 if (!InitializeSecurityDescriptor(&obj->
sd, SECURITY_DESCRIPTOR_REVISION))
163 if (!SetSecurityDescriptorDacl(&obj->
sd, TRUE, NULL, FALSE))
178 o->
overlapped.hEvent = CreateEvent(NULL, TRUE, event_state, NULL);
181 msg(
M_ERR,
"Error: overlapped_io_init: CreateEvent failed");
195 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle failed on overlapped I/O event object");
232 event->write = CreateEvent(NULL, TRUE, FALSE, NULL);
233 if (event->
write == NULL)
235 msg(
M_ERR,
"Error: init_net_event_win32: CreateEvent (write) failed");
247 event->read = CreateEvent(NULL, TRUE, FALSE, NULL);
248 if (event->
read == NULL)
250 msg(
M_ERR,
"Error: init_net_event_win32: CreateEvent (read) failed");
255 if (WSAEventSelect(sd, event->
read, network_events) != 0)
257 msg(
M_FATAL |
M_ERRNO,
"Error: init_net_event_win32: WSAEventSelect call failed");
264 WSANETWORKEVENTS wne;
265 if (WSAEnumNetworkEvents(sd, event->
read, &wne) != 0)
267 msg(
M_FATAL |
M_ERRNO,
"Error: reset_net_event_win32: WSAEnumNetworkEvents call failed");
272 return wne.lNetworkEvents;
283 if (WSAEventSelect(sd, event->
read, 0) != 0)
285 msg(
M_WARN |
M_ERRNO,
"Warning: close_net_event_win32: WSAEventSelect call failed");
288 if (!ResetEvent(event->
read))
290 msg(
M_WARN |
M_ERRNO,
"Warning: ResetEvent (read) failed in close_net_event_win32");
294 if (!CloseHandle(event->
read))
296 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle (read) failed in close_net_event_win32");
304 if (!ResetEvent(event->
write))
306 msg(
M_WARN |
M_ERRNO,
"Warning: ResetEvent (write) failed in close_net_event_win32");
310 if (!CloseHandle(event->
write))
312 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle (write) failed in close_net_event_win32");
353 msg(
M_WARN |
M_ERRNO,
"Warning: SetEvent/ResetEvent failed in net_event_win32_reset_write");
403 HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
406 ir.EventType = KEY_EVENT;
407 ir.Event.KeyEvent.bKeyDown =
true;
408 if (!stdin_handle || !WriteConsoleInput(stdin_handle, &ir, 1, &tmp))
421 msg(
D_LOW,
"win_ctrl_handler: signal received (code=%lu)", (
unsigned long) signum);
431 case CTRL_BREAK_EVENT:
439 msg(
D_LOW,
"win_ctrl_handler: signal (code=%lu) not handled", (
unsigned long) signum);
455 const char *exit_event_name,
456 bool exit_event_initial_state)
461 ws->
in.
read = INVALID_HANDLE_VALUE;
462 ws->
in.
write = INVALID_HANDLE_VALUE;
471 ws->
in.
read = GetStdHandle(STD_INPUT_HANDLE);
472 if (ws->
in.
read != INVALID_HANDLE_VALUE)
478 & ~(ENABLE_WINDOW_INPUT
479 | ENABLE_PROCESSED_INPUT
482 | ENABLE_MOUSE_INPUT);
486 if (!SetConsoleMode(ws->
in.
read, new_console_mode))
488 msg(
M_ERR,
"Error: win32_signal_open: SetConsoleMode failed");
496 ws->
in.
read = INVALID_HANDLE_VALUE;
510 const wchar_t *exit_event_nameW =
wide_string(exit_event_name, &gc);
514 msg(
M_ERR,
"Error: win32_signal_open: init SA failed");
517 ws->
in.
read = CreateEventW(&sa.
sa, TRUE, exit_event_initial_state ? TRUE : FALSE,
525 if (WaitForSingleObject(ws->
in.
read, 0) != WAIT_TIMEOUT)
527 msg(
M_FATAL,
"ERROR: Exit Event ('%s') is signaled", exit_event_name);
550 if (GetNumberOfConsoleInputEvents(ws->
in.
read, &n))
561 if (ir->Event.KeyEvent.uChar.AsciiChar == 0)
563 return ir->Event.KeyEvent.wVirtualScanCode;
566 if ((ir->Event.KeyEvent.dwControlKeyState
567 & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
568 && (ir->Event.KeyEvent.wVirtualKeyCode != 18))
570 return ir->Event.KeyEvent.wVirtualScanCode * 256;
573 return ir->Event.KeyEvent.uChar.AsciiChar;
590 if (!ReadConsoleInput(ws->
in.
read, &ir, 1, &n))
594 }
while (ir.EventType != KEY_EVENT || ir.Event.KeyEvent.bKeyDown != TRUE);
615 msg(
M_ERR,
"Error: win32_signal_close: SetConsoleMode failed");
630 && WaitForSingleObject(ws->
in.
read, 0) == WAIT_OBJECT_0)
690 WaitForSingleObject(ws->
in.
read, INFINITE);
739 SetConsoleTitle(
BSTR(&out));
762 s->
hand = CreateSemaphore(&
sa.sa, 1, 1, name);
785 dmsg(
D_SEMAPHORE_LOW,
"Attempting to lock Win32 semaphore '%s' prior to net shell command (timeout = %d sec)",
787 timeout_milliseconds / 1000);
788 status = WaitForSingleObject(s->
hand, timeout_milliseconds);
789 if (
status == WAIT_FAILED)
791 msg(
M_ERR,
"Wait failed on Win32 semaphore '%s'", s->
name);
793 ret = (
status == WAIT_TIMEOUT) ?
false :
true;
801 dmsg(
D_SEMAPHORE,
"Wait on Win32 semaphore '%s' timed out after %d milliseconds",
803 timeout_milliseconds);
816 if (!ReleaseSemaphore(s->
hand, 1, NULL))
835 CloseHandle(s->
hand);
860 const int timeout_seconds = 600;
869 msg(
M_FATAL,
"Cannot lock net command semaphore");
888 char force_path[256];
891 if (!snprintf(force_path,
sizeof(force_path),
"PATH=%s\\System32;%s;%s\\System32\\Wbem",
892 sysroot, sysroot, sysroot))
894 msg(
M_WARN,
"env_block: default path truncated to %s", force_path);
903 bool path_seen =
false;
907 nchars += strlen(e->
string) + 1;
910 nchars += strlen(force_path)+1;
912 ret = (
char *) malloc(nchars);
921 p += strlen(e->
string) + 1;
923 if (strncmp(e->
string,
"PATH=", 5 ) == 0)
932 msg(
M_INFO,
"env_block: add %s", force_path );
933 strcpy( p, force_path );
934 p += strlen(force_path) + 1;
960 for (i = 0; i < a->
argc; ++i)
962 const char *arg = a->
argv[i];
963 const size_t len = strlen(arg);
975 for (i = 0; i < a->
argc; ++i)
977 const char *arg = a->
argv[i];
1004 static bool exec_warn =
false;
1006 if (a && a->
argv[0])
1011 STARTUPINFOW start_info;
1012 PROCESS_INFORMATION proc_info;
1019 DWORD proc_flags = CREATE_NO_WINDOW;
1025 GetStartupInfoW(&start_info);
1026 start_info.cb =
sizeof(start_info);
1027 start_info.dwFlags = STARTF_USESHOWWINDOW;
1028 start_info.wShowWindow = SW_HIDE;
1030 if (CreateProcessW(cmd, cl, NULL, NULL, FALSE, proc_flags, env, NULL, &start_info, &proc_info))
1032 DWORD exit_status = 0;
1033 CloseHandle(proc_info.hThread);
1034 WaitForSingleObject(proc_info.hProcess, INFINITE);
1035 if (GetExitCodeProcess(proc_info.hProcess, &exit_status))
1037 ret = (int)exit_status;
1043 CloseHandle(proc_info.hProcess);
1064 msg(
M_WARN,
"openvpn_execve: called with empty argv");
1075 STARTUPINFO start_info;
1076 PROCESS_INFORMATION proc_info;
1085 status = GetModuleFileName(NULL, self_exe,
sizeof(self_exe));
1088 msg(
M_WARN|
M_ERRNO,
"fork_to_self: CreateProcess failed: cannot get module name via GetModuleFileName");
1093 GetStartupInfo(&start_info);
1094 start_info.cb =
sizeof(start_info);
1095 start_info.dwFlags = STARTF_USESHOWWINDOW;
1096 start_info.wShowWindow = SW_HIDE;
1098 if (CreateProcess(self_exe, cl, NULL, NULL, FALSE, 0, NULL, NULL, &start_info, &proc_info))
1100 CloseHandle(proc_info.hThread);
1101 CloseHandle(proc_info.hProcess);
1136 if (
status >
sizeof(buf) - 1)
1146 DWORD
status = GetModuleFileNameW(NULL, path, size);
1166 msg(
M_WARN,
"Error in WFP: %s : %s [status=0x%lx]",
1187 .iface = { .index = index, .name =
"" }
1197 msg(
M_WARN,
"WFP block: %s block filters using service failed: %s [status=0x%x if_index=%d]",
1204 msg(
M_INFO,
"%s WFP block filters using service succeeded.", (add ?
"Adding" :
"Deleting"));
1213 WCHAR openvpnpath[MAX_PATH];
1219 dmsg(
D_LOW,
"Using service to add WFP block filters");
1266 msg(
D_LOW,
"Using service to delete WFP block filters");
1289 if (!IsWindowsXPOrGreater())
1291 msg(
M_FATAL,
"Error: Windows version must be XP or greater.");
1294 if (!IsWindowsVistaOrGreater())
1299 if (!IsWindows7OrGreater())
1304 if (!IsWindows8OrGreater())
1309 if (!IsWindows8Point1OrGreater())
1314 if (!IsWindows10OrGreater())
1336 typedef BOOL (WINAPI *is_wow64_process2_t)(HANDLE, USHORT *, USHORT *);
1337 is_wow64_process2_t is_wow64_process2 = (is_wow64_process2_t)
1338 GetProcAddress(GetModuleHandle(
"Kernel32.dll"),
"IsWow64Process2");
1340 USHORT process_machine = 0;
1341 USHORT native_machine = 0;
1345 #elif defined(_WIN64)
1347 if (is_wow64_process2)
1350 BOOL is_wow64 = is_wow64_process2(GetCurrentProcess(),
1351 &process_machine, &native_machine);
1352 if (is_wow64 && native_machine == IMAGE_FILE_MACHINE_ARM64)
1357 #elif defined(_WIN32)
1360 if (is_wow64_process2)
1363 BOOL is_wow64 = is_wow64_process2(GetCurrentProcess(),
1364 &process_machine, &native_machine);
1367 switch (native_machine)
1369 case IMAGE_FILE_MACHINE_ARM64:
1373 case IMAGE_FILE_MACHINE_AMD64:
1386 BOOL is_wow64 = IsWow64Process(GetCurrentProcess(), &w64) && w64;
1432 buf_printf(&out,
"5.1%s", add_name ?
" (Windows XP)" :
"");
1436 buf_printf(&out,
"6.0%s", add_name ?
" (Windows Vista)" :
"");
1440 buf_printf(&out,
"6.1%s", add_name ?
" (Windows 7)" :
"");
1444 buf_printf(&out,
"6.2%s", add_name ?
" (Windows 8)" :
"");
1448 buf_printf(&out,
"6.3%s", add_name ?
" (Windows 8.1)" :
"");
1452 buf_printf(&out,
"10.0%s", add_name ?
" (Windows 10 or greater)" :
"");
1457 buf_printf(&out,
"0.0%s", add_name ?
" (unknown)" :
"");
1463 arch_t process_arch, host_arch;
1476 return (
const char *)out.
data;
1487 if (!WriteFile(pipe, data, size, &len, NULL)
1488 || !ReadFile(pipe, ack,
sizeof(*ack), &len, NULL))
1490 msg(
M_WARN,
"%s: could not talk to service: %s [%lu]",
1503 WCHAR reg_path[256];
1505 swprintf(reg_path, _countof(reg_path), L
"SOFTWARE\\" PACKAGE_NAME);
1507 LONG
status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, KEY_READ, &hkey);
1508 if (
status != ERROR_SUCCESS)
1513 status = RegGetValueW(hkey, NULL,
key, RRF_RT_REG_SZ, NULL, (LPBYTE)value, &size);
1517 return status == ERROR_SUCCESS;
1523 const WCHAR *ssl_fallback_dir = L
"C:\\Windows\\System32";
1525 WCHAR install_path[MAX_PATH] = { 0 };
1531 swprintf(install_path, _countof(install_path), L
"%ls", ssl_fallback_dir);
1534 if ((install_path[wcslen(install_path) - 1]) == L
'\\')
1536 install_path[wcslen(install_path) - 1] = L
'\0';
1543 {L
"OPENSSL_CONF", L
"openssl.cnf"},
1544 {L
"OPENSSL_ENGINES", L
"engines"},
1545 {L
"OPENSSL_MODULES", L
"modules"}
1548 for (
size_t i = 0; i <
SIZE(ossl_env); ++i)
1552 _wgetenv_s(&size, NULL, 0, ossl_env[i].name);
1555 WCHAR val[MAX_PATH] = {0};
1556 swprintf(val, _countof(val), L
"%ls\\ssl\\%ls", install_path, ossl_env[i].value);
1557 _wputenv_s(ossl_env[i].name, val);
1582 time_t expire =
now + n;
1584 while (expire >=
now)
1588 ||
status == WAIT_TIMEOUT)
1595 if (
status != WAIT_OBJECT_0)
1599 Sleep((expire-
now)*1000);
1610 if (wcsncmp(plugin_path, L
"\\\\", 2) == 0)
1612 msg(
M_WARN,
"UNC paths for plugins are not allowed.");
1616 WCHAR plugin_dir[MAX_PATH] = { 0 };
1623 msg(
M_WARN,
"Installation path could not be determined.");
1627 WCHAR system_dir[MAX_PATH] = { 0 };
1628 if (GetSystemDirectoryW(system_dir, _countof(system_dir)) == 0)
1633 if ((wcslen(plugin_dir) == 0) && (wcslen(system_dir) == 0))
1638 WCHAR normalized_plugin_dir[MAX_PATH] = { 0 };
1641 if (wcslen(plugin_dir) > 0)
1643 if (!GetFullPathNameW(plugin_dir, MAX_PATH, normalized_plugin_dir, NULL))
1651 if ((wcslen(normalized_plugin_dir) > 0) && (wcsnicmp(normalized_plugin_dir,
1652 plugin_path, wcslen(normalized_plugin_dir)) == 0))
1658 return wcsnicmp(system_dir, plugin_path, wcslen(system_dir)) == 0;