OpenVPN
win32.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2002-2023 OpenVPN Inc <sales@openvpn.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 /*
25  * Win32-specific OpenVPN code, targeted at the mingw
26  * development environment.
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include "syshead.h"
34 
35 #ifdef _WIN32
36 
37 #include "buffer.h"
38 #include "error.h"
39 #include "mtu.h"
40 #include "run_command.h"
41 #include "sig.h"
42 #include "win32-util.h"
43 #include "win32.h"
44 #include "openvpn-msg.h"
45 
46 #include "memdbg.h"
47 
48 #ifdef HAVE_VERSIONHELPERS_H
49 #include <versionhelpers.h>
50 #else
51 #include "compat-versionhelpers.h"
52 #endif
53 
54 #include "block_dns.h"
55 
56 /*
57  * WFP handle
58  */
59 static HANDLE m_hEngineHandle = NULL; /* GLOBAL */
60 
61 /*
62  * TAP adapter original metric value
63  */
64 static int tap_metric_v4 = -1; /* GLOBAL */
65 static int tap_metric_v6 = -1; /* GLOBAL */
66 
67 /*
68  * Windows internal socket API state (opaque).
69  */
70 static struct WSAData wsa_state; /* GLOBAL */
71 
72 /*
73  * Should we call win32_pause() on program exit?
74  */
75 static bool pause_exit_enabled = false; /* GLOBAL */
76 
77 /*
78  * win32_signal is used to get input from the keyboard
79  * if we are running in a console, or get input from an
80  * event object if we are running as a service.
81  */
82 
83 struct win32_signal win32_signal; /* GLOBAL */
84 
85 /*
86  * Save our old window title so we can restore
87  * it on exit.
88  */
89 struct window_title window_title; /* GLOBAL*/
90 
91 /*
92  * Special global semaphore used to protect network
93  * shell commands from simultaneous instantiation.
94  */
95 
96 struct semaphore netcmd_semaphore; /* GLOBAL */
97 
98 /*
99  * Windows system pathname such as c:\windows
100  */
101 static char *win_sys_path = NULL; /* GLOBAL */
102 
106 static void
108 
109 void
111 {
112  if (WSAStartup(0x0101, &wsa_state))
113  {
114  msg(M_ERR, "WSAStartup failed");
115  }
118 
120 }
121 
122 void
124 {
126  if (pause_exit_enabled)
127  {
129  {
130  struct win32_signal w;
131  win32_signal_open(&w, WSO_FORCE_CONSOLE, NULL, false);
132  win32_pause(&w);
133  win32_signal_close(&w);
134  }
135  else
136  {
138  }
139  }
142  WSACleanup();
143  free(win_sys_path);
144 }
145 
146 void
148 {
149  pause_exit_enabled = true;
150 }
151 
152 bool
154 {
155  CLEAR(*obj);
156 
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))
161  {
162  return false;
163  }
164  if (!SetSecurityDescriptorDacl(&obj->sd, TRUE, NULL, FALSE))
165  {
166  return false;
167  }
168  return true;
169 }
170 
171 void
173  const struct frame *frame,
174  BOOL event_state)
175 {
176  CLEAR(*o);
177 
178  /* manual reset event, initially set according to event_state */
179  o->overlapped.hEvent = CreateEvent(NULL, TRUE, event_state, NULL);
180  if (o->overlapped.hEvent == NULL)
181  {
182  msg(M_ERR, "Error: overlapped_io_init: CreateEvent failed");
183  }
184 
185  /* allocate buffer for overlapped I/O */
187 }
188 
189 void
191 {
192  if (o->overlapped.hEvent)
193  {
194  if (!CloseHandle(o->overlapped.hEvent))
195  {
196  msg(M_WARN | M_ERRNO, "Warning: CloseHandle failed on overlapped I/O event object");
197  }
198  }
199  free_buf(&o->buf_init);
200 }
201 
202 char *
204 {
205  switch (o->iostate)
206  {
207  case IOSTATE_INITIAL:
208  return "0";
209 
210  case IOSTATE_QUEUED:
211  return "Q";
212 
214  return "1";
215  }
216  return "?";
217 }
218 
219 /*
220  * Event-based notification of network events
221  */
222 
223 void
224 init_net_event_win32(struct rw_handle *event, long network_events, socket_descriptor_t sd, unsigned int flags)
225 {
226  /* manual reset events, initially set to unsignaled */
227 
228  /* initialize write event */
229  if (!(flags & NE32_PERSIST_EVENT) || !event->write)
230  {
231  if (flags & NE32_WRITE_EVENT)
232  {
233  event->write = CreateEvent(NULL, TRUE, FALSE, NULL);
234  if (event->write == NULL)
235  {
236  msg(M_ERR, "Error: init_net_event_win32: CreateEvent (write) failed");
237  }
238  }
239  else
240  {
241  event->write = NULL;
242  }
243  }
244 
245  /* initialize read event */
246  if (!(flags & NE32_PERSIST_EVENT) || !event->read)
247  {
248  event->read = CreateEvent(NULL, TRUE, FALSE, NULL);
249  if (event->read == NULL)
250  {
251  msg(M_ERR, "Error: init_net_event_win32: CreateEvent (read) failed");
252  }
253  }
254 
255  /* setup network events to change read event state */
256  if (WSAEventSelect(sd, event->read, network_events) != 0)
257  {
258  msg(M_FATAL | M_ERRNO, "Error: init_net_event_win32: WSAEventSelect call failed");
259  }
260 }
261 
262 long
264 {
265  WSANETWORKEVENTS wne;
266  if (WSAEnumNetworkEvents(sd, event->read, &wne) != 0)
267  {
268  msg(M_FATAL | M_ERRNO, "Error: reset_net_event_win32: WSAEnumNetworkEvents call failed");
269  return 0; /* NOTREACHED */
270  }
271  else
272  {
273  return wne.lNetworkEvents;
274  }
275 }
276 
277 void
278 close_net_event_win32(struct rw_handle *event, socket_descriptor_t sd, unsigned int flags)
279 {
280  if (event->read)
281  {
282  if (socket_defined(sd))
283  {
284  if (WSAEventSelect(sd, event->read, 0) != 0)
285  {
286  msg(M_WARN | M_ERRNO, "Warning: close_net_event_win32: WSAEventSelect call failed");
287  }
288  }
289  if (!ResetEvent(event->read))
290  {
291  msg(M_WARN | M_ERRNO, "Warning: ResetEvent (read) failed in close_net_event_win32");
292  }
293  if (!(flags & NE32_PERSIST_EVENT))
294  {
295  if (!CloseHandle(event->read))
296  {
297  msg(M_WARN | M_ERRNO, "Warning: CloseHandle (read) failed in close_net_event_win32");
298  }
299  event->read = NULL;
300  }
301  }
302 
303  if (event->write)
304  {
305  if (!ResetEvent(event->write))
306  {
307  msg(M_WARN | M_ERRNO, "Warning: ResetEvent (write) failed in close_net_event_win32");
308  }
309  if (!(flags & NE32_PERSIST_EVENT))
310  {
311  if (!CloseHandle(event->write))
312  {
313  msg(M_WARN | M_ERRNO, "Warning: CloseHandle (write) failed in close_net_event_win32");
314  }
315  event->write = NULL;
316  }
317  }
318 }
319 
320 /*
321  * struct net_event_win32
322  */
323 
324 void
326 {
327  CLEAR(*ne);
328  ne->sd = SOCKET_UNDEFINED;
329 }
330 
331 void
332 net_event_win32_start(struct net_event_win32 *ne, long network_events, socket_descriptor_t sd)
333 {
334  ASSERT(!socket_defined(ne->sd));
335  ne->sd = sd;
336  ne->event_mask = 0;
338 }
339 
340 void
342 {
343  BOOL status;
344  if (ne->event_mask & FD_WRITE)
345  {
346  status = SetEvent(ne->handle.write);
347  }
348  else
349  {
350  status = ResetEvent(ne->handle.write);
351  }
352  if (!status)
353  {
354  msg(M_WARN | M_ERRNO, "Warning: SetEvent/ResetEvent failed in net_event_win32_reset_write");
355  }
356 }
357 
358 void
360 {
361  ne->event_mask |= reset_net_event_win32(&ne->handle, ne->sd);
362 }
363 
364 void
366 {
367  if (net_event_win32_defined(ne))
368  {
370  }
371  ne->sd = SOCKET_UNDEFINED;
372  ne->event_mask = 0;
373 }
374 
375 void
377 {
378  if (net_event_win32_defined(ne))
379  {
380  close_net_event_win32(&ne->handle, ne->sd, 0);
381  }
383 }
384 
385 /*
386  * Simulate *nix signals on Windows.
387  *
388  * Two modes:
389  * (1) Console mode -- map keyboard function keys to signals
390  * (2) Service mode -- map Windows event object to SIGTERM
391  */
392 
393 static void
395 {
396  if (ws->mode == WSO_MODE_SERVICE && HANDLE_DEFINED(ws->in.read))
397  {
398  SetEvent(ws->in.read);
399  }
400  else /* generate a key-press event */
401  {
402  DWORD tmp;
403  INPUT_RECORD ir;
404  HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
405 
406  CLEAR(ir);
407  ir.EventType = KEY_EVENT;
408  ir.Event.KeyEvent.bKeyDown = true;
409  if (!stdin_handle || !WriteConsoleInput(stdin_handle, &ir, 1, &tmp))
410  {
411  msg(M_WARN|M_ERRNO, "WARN: win_trigger_event: WriteConsoleInput");
412  }
413  }
414 }
415 
416 /*
417  * Callback to handle console ctrl events
418  */
419 static bool WINAPI
420 win_ctrl_handler(DWORD signum)
421 {
422  msg(D_LOW, "win_ctrl_handler: signal received (code=%lu)", (unsigned long) signum);
423 
424  if (siginfo_static.signal_received == SIGTERM)
425  {
426  return true;
427  }
428 
429  switch (signum)
430  {
431  case CTRL_C_EVENT:
432  case CTRL_BREAK_EVENT:
433  throw_signal(SIGTERM);
434  /* trigget the win32_signal to interrupt the event loop */
436  return true;
437  break;
438 
439  default:
440  msg(D_LOW, "win_ctrl_handler: signal (code=%lu) not handled", (unsigned long) signum);
441  break;
442  }
443  /* pass all other signals to the next handler */
444  return false;
445 }
446 
447 void
449 {
450  CLEAR(*ws);
451 }
452 
453 void
455  int force,
456  const char *exit_event_name,
457  bool exit_event_initial_state)
458 {
459  CLEAR(*ws);
460 
461  ws->mode = WSO_MODE_UNDEF;
462  ws->in.read = INVALID_HANDLE_VALUE;
463  ws->in.write = INVALID_HANDLE_VALUE;
464  ws->console_mode_save = 0;
465  ws->console_mode_save_defined = false;
466 
467  if (force == WSO_NOFORCE || force == WSO_FORCE_CONSOLE)
468  {
469  /*
470  * Try to open console.
471  */
472  ws->in.read = GetStdHandle(STD_INPUT_HANDLE);
473  if (ws->in.read != INVALID_HANDLE_VALUE)
474  {
475  if (GetConsoleMode(ws->in.read, &ws->console_mode_save))
476  {
477  /* running on a console */
478  const DWORD new_console_mode = ws->console_mode_save
479  & ~(ENABLE_WINDOW_INPUT
480  | ENABLE_PROCESSED_INPUT
481  | ENABLE_LINE_INPUT
482  | ENABLE_ECHO_INPUT
483  | ENABLE_MOUSE_INPUT);
484 
485  if (new_console_mode != ws->console_mode_save)
486  {
487  if (!SetConsoleMode(ws->in.read, new_console_mode))
488  {
489  msg(M_ERR, "Error: win32_signal_open: SetConsoleMode failed");
490  }
491  ws->console_mode_save_defined = true;
492  }
493  ws->mode = WSO_MODE_CONSOLE;
494  }
495  else
496  {
497  ws->in.read = INVALID_HANDLE_VALUE; /* probably running as a service */
498  }
499  }
500  }
501 
502  /*
503  * If console open failed, assume we are running
504  * as a service.
505  */
506  if ((force == WSO_NOFORCE || force == WSO_FORCE_SERVICE)
507  && !HANDLE_DEFINED(ws->in.read) && exit_event_name)
508  {
509  struct security_attributes sa;
510  struct gc_arena gc = gc_new();
511  const wchar_t *exit_event_nameW = wide_string(exit_event_name, &gc);
512 
514  {
515  msg(M_ERR, "Error: win32_signal_open: init SA failed");
516  }
517 
518  ws->in.read = CreateEventW(&sa.sa, TRUE, exit_event_initial_state ? TRUE : FALSE,
519  exit_event_nameW);
520  if (ws->in.read == NULL)
521  {
522  msg(M_WARN|M_ERRNO, "NOTE: CreateEventW '%s' failed", exit_event_name);
523  }
524  else
525  {
526  if (WaitForSingleObject(ws->in.read, 0) != WAIT_TIMEOUT)
527  {
528  msg(M_FATAL, "ERROR: Exit Event ('%s') is signaled", exit_event_name);
529  }
530  else
531  {
532  ws->mode = WSO_MODE_SERVICE;
533  }
534  }
535  gc_free(&gc);
536  }
537  /* set the ctrl handler in both console and service modes */
538  if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE) win_ctrl_handler, true))
539  {
540  msg(M_WARN|M_ERRNO, "WARN: SetConsoleCtrlHandler failed");
541  }
542 }
543 
544 static bool
546 {
547  ASSERT(ws->mode == WSO_MODE_CONSOLE);
548  if (HANDLE_DEFINED(ws->in.read))
549  {
550  DWORD n;
551  if (GetNumberOfConsoleInputEvents(ws->in.read, &n))
552  {
553  return n > 0;
554  }
555  }
556  return false;
557 }
558 
559 static unsigned int
560 keyboard_ir_to_key(INPUT_RECORD *ir)
561 {
562  if (ir->Event.KeyEvent.uChar.AsciiChar == 0)
563  {
564  return ir->Event.KeyEvent.wVirtualScanCode;
565  }
566 
567  if ((ir->Event.KeyEvent.dwControlKeyState
568  & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
569  && (ir->Event.KeyEvent.wVirtualKeyCode != 18))
570  {
571  return ir->Event.KeyEvent.wVirtualScanCode * 256;
572  }
573 
574  return ir->Event.KeyEvent.uChar.AsciiChar;
575 }
576 
577 static unsigned int
579 {
580  ASSERT(ws->mode == WSO_MODE_CONSOLE);
581  if (HANDLE_DEFINED(ws->in.read))
582  {
583  INPUT_RECORD ir;
584  do
585  {
586  DWORD n;
587  if (!keyboard_input_available(ws))
588  {
589  return 0;
590  }
591  if (!ReadConsoleInput(ws->in.read, &ir, 1, &n))
592  {
593  return 0;
594  }
595  } while (ir.EventType != KEY_EVENT || ir.Event.KeyEvent.bKeyDown != TRUE);
596 
597  return keyboard_ir_to_key(&ir);
598  }
599  else
600  {
601  return 0;
602  }
603 }
604 
605 void
607 {
608  if (ws->mode == WSO_MODE_SERVICE && HANDLE_DEFINED(ws->in.read))
609  {
610  CloseHandle(ws->in.read);
611  }
613  {
614  if (!SetConsoleMode(ws->in.read, ws->console_mode_save))
615  {
616  msg(M_ERR, "Error: win32_signal_close: SetConsoleMode failed");
617  }
618  }
619  CLEAR(*ws);
620 }
621 
622 /*
623  * Return true if interrupt occurs in service mode.
624  */
625 bool
627 {
628  if (ws->mode == WSO_MODE_SERVICE)
629  {
630  if (HANDLE_DEFINED(ws->in.read)
631  && WaitForSingleObject(ws->in.read, 0) == WAIT_OBJECT_0)
632  {
633  return true;
634  }
635  }
636  return false;
637 }
638 
639 int
641 {
642  int ret = 0;
643 
644  if (ws->mode == WSO_MODE_SERVICE)
645  {
646  if (win32_service_interrupt(ws))
647  {
648  ret = SIGTERM;
649  }
650  }
651  else if (ws->mode == WSO_MODE_CONSOLE)
652  {
653  switch (win32_keyboard_get(ws))
654  {
655  case 0x3B: /* F1 -> USR1 */
656  ret = SIGUSR1;
657  break;
658 
659  case 0x3C: /* F2 -> USR2 */
660  ret = SIGUSR2;
661  break;
662 
663  case 0x3D: /* F3 -> HUP */
664  ret = SIGHUP;
665  break;
666 
667  case 0x3E: /* F4 -> TERM */
668  ret = SIGTERM;
669  break;
670 
671  case 0x03: /* CTRL-C -> TERM */
672  ret = SIGTERM;
673  break;
674  }
675  }
676  if (ret)
677  {
678  throw_signal(ret); /* this will update siginfo_static.signal received */
679  }
681 }
682 
683 void
685 {
686  if (ws->mode == WSO_MODE_CONSOLE && HANDLE_DEFINED(ws->in.read))
687  {
688  msg(M_INFO|M_NOPREFIX, "Press any key to continue...");
689  do
690  {
691  WaitForSingleObject(ws->in.read, INFINITE);
692  } while (!win32_keyboard_get(ws));
693  }
694 }
695 
696 /* window functions */
697 
698 void
700 {
701  CLEAR(*wt);
702 }
703 
704 void
706 {
707  if (!wt->saved)
708  {
709  if (!GetConsoleTitle(wt->old_window_title, sizeof(wt->old_window_title)))
710  {
711  wt->old_window_title[0] = 0;
712  wt->saved = false;
713  }
714  else
715  {
716  wt->saved = true;
717  }
718  }
719 }
720 
721 void
723 {
724  if (wt->saved)
725  {
726  SetConsoleTitle(wt->old_window_title);
727  }
728 }
729 
730 void
731 window_title_generate(const char *title)
732 {
733  struct gc_arena gc = gc_new();
734  struct buffer out = alloc_buf_gc(256, &gc);
735  if (!title)
736  {
737  title = "";
738  }
739  buf_printf(&out, "[%s] " PACKAGE_NAME " " PACKAGE_VERSION " F4:EXIT F1:USR1 F2:USR2 F3:HUP", title);
740  SetConsoleTitle(BSTR(&out));
741  gc_free(&gc);
742 }
743 
744 /* semaphore functions */
745 
746 void
748 {
749  CLEAR(*s);
750 }
751 
752 void
753 semaphore_open(struct semaphore *s, const char *name)
754 {
755  struct security_attributes sa;
756 
757  s->locked = false;
758  s->name = name;
759  s->hand = NULL;
760 
762  {
763  s->hand = CreateSemaphore(&sa.sa, 1, 1, name);
764  }
765 
766  if (s->hand == NULL)
767  {
768  msg(M_WARN|M_ERRNO, "WARNING: Cannot create Win32 semaphore '%s'", name);
769  }
770  else
771  {
772  dmsg(D_SEMAPHORE, "Created Win32 semaphore '%s'", s->name);
773  }
774 }
775 
776 bool
777 semaphore_lock(struct semaphore *s, int timeout_milliseconds)
778 {
779  bool ret = true;
780 
781  if (s->hand)
782  {
783  DWORD status;
784  ASSERT(!s->locked);
785 
786  dmsg(D_SEMAPHORE_LOW, "Attempting to lock Win32 semaphore '%s' prior to net shell command (timeout = %d sec)",
787  s->name,
788  timeout_milliseconds / 1000);
789  status = WaitForSingleObject(s->hand, timeout_milliseconds);
790  if (status == WAIT_FAILED)
791  {
792  msg(M_ERR, "Wait failed on Win32 semaphore '%s'", s->name);
793  }
794  ret = (status == WAIT_TIMEOUT) ? false : true;
795  if (ret)
796  {
797  dmsg(D_SEMAPHORE, "Locked Win32 semaphore '%s'", s->name);
798  s->locked = true;
799  }
800  else
801  {
802  dmsg(D_SEMAPHORE, "Wait on Win32 semaphore '%s' timed out after %d milliseconds",
803  s->name,
804  timeout_milliseconds);
805  }
806  }
807  return ret;
808 }
809 
810 void
812 {
813  if (s->hand)
814  {
815  ASSERT(s->locked);
816  dmsg(D_SEMAPHORE, "Releasing Win32 semaphore '%s'", s->name);
817  if (!ReleaseSemaphore(s->hand, 1, NULL))
818  {
819  msg(M_WARN | M_ERRNO, "ReleaseSemaphore failed on Win32 semaphore '%s'",
820  s->name);
821  }
822  s->locked = false;
823  }
824 }
825 
826 void
828 {
829  if (s->hand)
830  {
831  if (s->locked)
832  {
834  }
835  dmsg(D_SEMAPHORE, "Closing Win32 semaphore '%s'", s->name);
836  CloseHandle(s->hand);
837  s->hand = NULL;
838  }
839 }
840 
841 /*
842  * Special global semaphore used to protect network
843  * shell commands from simultaneous instantiation.
844  */
845 
846 void
848 {
850 }
851 
852 void
854 {
856 }
857 
858 void
860 {
861  const int timeout_seconds = 600;
862 
863  if (!netcmd_semaphore.hand)
864  {
866  }
867 
868  if (!semaphore_lock(&netcmd_semaphore, timeout_seconds * 1000))
869  {
870  msg(M_FATAL, "Cannot lock net command semaphore");
871  }
872 }
873 
874 void
876 {
878  /* netcmd_semaphore has max count of 1 - safe to close after release */
880 }
881 
882 /*
883  * Service functions for openvpn_execve
884  */
885 
886 static char *
887 env_block(const struct env_set *es)
888 {
889  char force_path[256];
890  char *sysroot = get_win_sys_path();
891 
892  if (!openvpn_snprintf(force_path, sizeof(force_path), "PATH=%s\\System32;%s;%s\\System32\\Wbem",
893  sysroot, sysroot, sysroot))
894  {
895  msg(M_WARN, "env_block: default path truncated to %s", force_path);
896  }
897 
898  if (es)
899  {
900  struct env_item *e;
901  char *ret;
902  char *p;
903  size_t nchars = 1;
904  bool path_seen = false;
905 
906  for (e = es->list; e != NULL; e = e->next)
907  {
908  nchars += strlen(e->string) + 1;
909  }
910 
911  nchars += strlen(force_path)+1;
912 
913  ret = (char *) malloc(nchars);
914  check_malloc_return(ret);
915 
916  p = ret;
917  for (e = es->list; e != NULL; e = e->next)
918  {
919  if (env_allowed(e->string))
920  {
921  strcpy(p, e->string);
922  p += strlen(e->string) + 1;
923  }
924  if (strncmp(e->string, "PATH=", 5 ) == 0)
925  {
926  path_seen = true;
927  }
928  }
929 
930  /* make sure PATH is set */
931  if (!path_seen)
932  {
933  msg( M_INFO, "env_block: add %s", force_path );
934  strcpy( p, force_path );
935  p += strlen(force_path) + 1;
936  }
937 
938  *p = '\0';
939  return ret;
940  }
941  else
942  {
943  return NULL;
944  }
945 }
946 
947 static WCHAR *
948 wide_cmd_line(const struct argv *a, struct gc_arena *gc)
949 {
950  size_t nchars = 1;
951  size_t maxlen = 0;
952  size_t i;
953  struct buffer buf;
954  char *work = NULL;
955 
956  if (!a)
957  {
958  return NULL;
959  }
960 
961  for (i = 0; i < a->argc; ++i)
962  {
963  const char *arg = a->argv[i];
964  const size_t len = strlen(arg);
965  nchars += len + 3;
966  if (len > maxlen)
967  {
968  maxlen = len;
969  }
970  }
971 
972  work = gc_malloc(maxlen + 1, false, gc);
973  check_malloc_return(work);
974  buf = alloc_buf_gc(nchars, gc);
975 
976  for (i = 0; i < a->argc; ++i)
977  {
978  const char *arg = a->argv[i];
979  strcpy(work, arg);
981  if (i)
982  {
983  buf_printf(&buf, " ");
984  }
985  if (string_class(work, CC_ANY, CC_SPACE))
986  {
987  buf_printf(&buf, "%s", work);
988  }
989  else
990  {
991  buf_printf(&buf, "\"%s\"", work);
992  }
993  }
994 
995  return wide_string(BSTR(&buf), gc);
996 }
997 
998 /*
999  * Attempt to simulate fork/execve on Windows
1000  */
1001 int
1002 openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags)
1003 {
1004  int ret = OPENVPN_EXECVE_ERROR;
1005  static bool exec_warn = false;
1006 
1007  if (a && a->argv[0])
1008  {
1009  if (openvpn_execve_allowed(flags))
1010  {
1011  struct gc_arena gc = gc_new();
1012  STARTUPINFOW start_info;
1013  PROCESS_INFORMATION proc_info;
1014 
1015  char *env = env_block(es);
1016  WCHAR *cl = wide_cmd_line(a, &gc);
1017  WCHAR *cmd = wide_string(a->argv[0], &gc);
1018 
1019  /* this allows console programs to run, and is ignored otherwise */
1020  DWORD proc_flags = CREATE_NO_WINDOW;
1021 
1022  CLEAR(start_info);
1023  CLEAR(proc_info);
1024 
1025  /* fill in STARTUPINFO struct */
1026  GetStartupInfoW(&start_info);
1027  start_info.cb = sizeof(start_info);
1028  start_info.dwFlags = STARTF_USESHOWWINDOW;
1029  start_info.wShowWindow = SW_HIDE;
1030 
1031  if (CreateProcessW(cmd, cl, NULL, NULL, FALSE, proc_flags, env, NULL, &start_info, &proc_info))
1032  {
1033  DWORD exit_status = 0;
1034  CloseHandle(proc_info.hThread);
1035  WaitForSingleObject(proc_info.hProcess, INFINITE);
1036  if (GetExitCodeProcess(proc_info.hProcess, &exit_status))
1037  {
1038  ret = (int)exit_status;
1039  }
1040  else
1041  {
1042  msg(M_WARN|M_ERRNO, "openvpn_execve: GetExitCodeProcess %ls failed", cmd);
1043  }
1044  CloseHandle(proc_info.hProcess);
1045  }
1046  else
1047  {
1048  msg(M_WARN|M_ERRNO, "openvpn_execve: CreateProcess %ls failed", cmd);
1049  }
1050  free(env);
1051  gc_free(&gc);
1052  }
1053  else
1054  {
1056  if (!exec_warn && (script_security() < SSEC_SCRIPTS))
1057  {
1059  exec_warn = true;
1060  }
1061  }
1062  }
1063  else
1064  {
1065  msg(M_WARN, "openvpn_execve: called with empty argv");
1066  }
1067  return ret;
1068 }
1069 
1070 /*
1071  * call ourself in another process
1072  */
1073 void
1074 fork_to_self(const char *cmdline)
1075 {
1076  STARTUPINFO start_info;
1077  PROCESS_INFORMATION proc_info;
1078  char self_exe[256];
1079  char *cl = string_alloc(cmdline, NULL);
1080  DWORD status;
1081 
1082  CLEAR(start_info);
1083  CLEAR(proc_info);
1084  CLEAR(self_exe);
1085 
1086  status = GetModuleFileName(NULL, self_exe, sizeof(self_exe));
1087  if (status == 0 || status == sizeof(self_exe))
1088  {
1089  msg(M_WARN|M_ERRNO, "fork_to_self: CreateProcess failed: cannot get module name via GetModuleFileName");
1090  goto done;
1091  }
1092 
1093  /* fill in STARTUPINFO struct */
1094  GetStartupInfo(&start_info);
1095  start_info.cb = sizeof(start_info);
1096  start_info.dwFlags = STARTF_USESHOWWINDOW;
1097  start_info.wShowWindow = SW_HIDE;
1098 
1099  if (CreateProcess(self_exe, cl, NULL, NULL, FALSE, 0, NULL, NULL, &start_info, &proc_info))
1100  {
1101  CloseHandle(proc_info.hThread);
1102  CloseHandle(proc_info.hProcess);
1103  }
1104  else
1105  {
1106  msg(M_WARN|M_ERRNO, "fork_to_self: CreateProcess failed: %s", cmdline);
1107  }
1108 
1109 done:
1110  free(cl);
1111 }
1112 
1113 char *
1115 {
1117  return win_sys_path;
1118 }
1119 
1120 void
1121 set_win_sys_path(const char *newpath, struct env_set *es)
1122 {
1123  free(win_sys_path);
1124  win_sys_path = string_alloc(newpath, NULL);
1125  setenv_str(es, SYS_PATH_ENV_VAR_NAME, win_sys_path); /* route.exe needs this */
1126 }
1127 
1128 void
1130 {
1131  char buf[256];
1132  DWORD status = GetEnvironmentVariable(SYS_PATH_ENV_VAR_NAME, buf, sizeof(buf));
1133  if (!status)
1134  {
1135  msg(M_ERR, "Cannot find environmental variable %s", SYS_PATH_ENV_VAR_NAME);
1136  }
1137  if (status > sizeof(buf) - 1)
1138  {
1139  msg(M_FATAL, "String overflow attempting to read environmental variable %s", SYS_PATH_ENV_VAR_NAME);
1140  }
1141  set_win_sys_path(buf, es);
1142 }
1143 
1144 
1145 const char *
1147 {
1148  static char tmpdir[MAX_PATH];
1149  WCHAR wtmpdir[MAX_PATH];
1150 
1151  if (!GetTempPathW(_countof(wtmpdir), wtmpdir))
1152  {
1153  /* Warn if we can't find a valid temporary directory, which should
1154  * be unlikely.
1155  */
1156  msg(M_WARN, "Could not find a suitable temporary directory."
1157  " (GetTempPath() failed). Consider using --tmp-dir");
1158  return NULL;
1159  }
1160 
1161  if (WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, NULL, 0, NULL, NULL) > sizeof(tmpdir))
1162  {
1163  msg(M_WARN, "Could not get temporary directory. Path is too long."
1164  " Consider using --tmp-dir");
1165  return NULL;
1166  }
1167 
1168  WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, tmpdir, sizeof(tmpdir), NULL, NULL);
1169  return tmpdir;
1170 }
1171 
1172 static bool
1173 win_block_dns_service(bool add, int index, const HANDLE pipe)
1174 {
1175  bool ret = false;
1176  ack_message_t ack;
1177  struct gc_arena gc = gc_new();
1178 
1179  block_dns_message_t data = {
1180  .header = {
1182  sizeof(block_dns_message_t),
1183  0
1184  },
1185  .iface = { .index = index, .name = "" }
1186  };
1187 
1188  if (!send_msg_iservice(pipe, &data, sizeof(data), &ack, "Block_DNS"))
1189  {
1190  goto out;
1191  }
1192 
1193  if (ack.error_number != NO_ERROR)
1194  {
1195  msg(M_WARN, "Block_DNS: %s block dns filters using service failed: %s [status=0x%x if_index=%d]",
1196  (add ? "adding" : "deleting"), strerror_win32(ack.error_number, &gc),
1197  ack.error_number, data.iface.index);
1198  goto out;
1199  }
1200 
1201  ret = true;
1202  msg(M_INFO, "%s outside dns using service succeeded.", (add ? "Blocking" : "Unblocking"));
1203 out:
1204  gc_free(&gc);
1205  return ret;
1206 }
1207 
1208 static void
1209 block_dns_msg_handler(DWORD err, const char *msg)
1210 {
1211  struct gc_arena gc = gc_new();
1212 
1213  if (err == 0)
1214  {
1215  msg(M_INFO, "%s", msg);
1216  }
1217  else
1218  {
1219  msg(M_WARN, "Error in add_block_dns_filters(): %s : %s [status=0x%lx]",
1220  msg, strerror_win32(err, &gc), err);
1221  }
1222 
1223  gc_free(&gc);
1224 }
1225 
1226 bool
1227 win_wfp_block_dns(const NET_IFINDEX index, const HANDLE msg_channel)
1228 {
1229  WCHAR openvpnpath[MAX_PATH];
1230  bool ret = false;
1231  DWORD status;
1232 
1233  if (msg_channel)
1234  {
1235  dmsg(D_LOW, "Using service to add block dns filters");
1236  ret = win_block_dns_service(true, index, msg_channel);
1237  goto out;
1238  }
1239 
1240  status = GetModuleFileNameW(NULL, openvpnpath, _countof(openvpnpath));
1241  if (status == 0 || status == _countof(openvpnpath))
1242  {
1243  msg(M_WARN|M_ERRNO, "block_dns: cannot get executable path");
1244  goto out;
1245  }
1246 
1247  status = add_block_dns_filters(&m_hEngineHandle, index, openvpnpath,
1249  if (status == 0)
1250  {
1251  int is_auto = 0;
1252  tap_metric_v4 = get_interface_metric(index, AF_INET, &is_auto);
1253  if (is_auto)
1254  {
1255  tap_metric_v4 = 0;
1256  }
1257  tap_metric_v6 = get_interface_metric(index, AF_INET6, &is_auto);
1258  if (is_auto)
1259  {
1260  tap_metric_v6 = 0;
1261  }
1263  if (!status)
1264  {
1265  set_interface_metric(index, AF_INET6, BLOCK_DNS_IFACE_METRIC);
1266  }
1267  }
1268 
1269  ret = (status == 0);
1270 
1271 out:
1272 
1273  return ret;
1274 }
1275 
1276 bool
1277 win_wfp_uninit(const NET_IFINDEX index, const HANDLE msg_channel)
1278 {
1279  dmsg(D_LOW, "Uninitializing WFP");
1280 
1281  if (msg_channel)
1282  {
1283  msg(D_LOW, "Using service to delete block dns filters");
1284  win_block_dns_service(false, index, msg_channel);
1285  }
1286  else
1287  {
1289  m_hEngineHandle = NULL;
1290  if (tap_metric_v4 >= 0)
1291  {
1292  set_interface_metric(index, AF_INET, tap_metric_v4);
1293  }
1294  if (tap_metric_v6 >= 0)
1295  {
1296  set_interface_metric(index, AF_INET6, tap_metric_v6);
1297  }
1298  }
1299 
1300  return true;
1301 }
1302 
1303 int
1305 {
1306  if (!IsWindowsXPOrGreater())
1307  {
1308  msg(M_FATAL, "Error: Windows version must be XP or greater.");
1309  }
1310 
1311  if (!IsWindowsVistaOrGreater())
1312  {
1313  return WIN_XP;
1314  }
1315 
1316  if (!IsWindows7OrGreater())
1317  {
1318  return WIN_VISTA;
1319  }
1320 
1321  if (!IsWindows8OrGreater())
1322  {
1323  return WIN_7;
1324  }
1325 
1326  if (!IsWindows8Point1OrGreater())
1327  {
1328  return WIN_8;
1329  }
1330 
1331  if (!IsWindows10OrGreater())
1332  {
1333  return WIN_8_1;
1334  }
1335 
1336  return WIN_10;
1337 }
1338 
1339 typedef enum {
1343  ARCH_NATIVE, /* means no emulation, makes sense for host arch */
1345 } arch_t;
1346 
1347 static void
1348 win32_get_arch(arch_t *process_arch, arch_t *host_arch)
1349 {
1350  *process_arch = ARCH_UNKNOWN;
1351  *host_arch = ARCH_NATIVE;
1352 
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");
1356 
1357  USHORT process_machine = 0;
1358  USHORT native_machine = 0;
1359 
1360 #ifdef _ARM64_
1361  *process_arch = ARCH_ARM64;
1362 #elif defined(_WIN64)
1363  *process_arch = ARCH_AMD64;
1364  if (is_wow64_process2)
1365  {
1366  /* this could be amd64 on arm64 */
1367  BOOL is_wow64 = is_wow64_process2(GetCurrentProcess(),
1368  &process_machine, &native_machine);
1369  if (is_wow64 && native_machine == IMAGE_FILE_MACHINE_ARM64)
1370  {
1371  *host_arch = ARCH_ARM64;
1372  }
1373  }
1374 #elif defined(_WIN32)
1375  *process_arch = ARCH_X86;
1376 
1377  if (is_wow64_process2)
1378  {
1379  /* check if we're running on arm64 or amd64 machine */
1380  BOOL is_wow64 = is_wow64_process2(GetCurrentProcess(),
1381  &process_machine, &native_machine);
1382  if (is_wow64)
1383  {
1384  switch (native_machine)
1385  {
1386  case IMAGE_FILE_MACHINE_ARM64:
1387  *host_arch = ARCH_ARM64;
1388  break;
1389 
1390  case IMAGE_FILE_MACHINE_AMD64:
1391  *host_arch = ARCH_AMD64;
1392  break;
1393 
1394  default:
1395  *host_arch = ARCH_UNKNOWN;
1396  break;
1397  }
1398  }
1399  }
1400  else
1401  {
1402  BOOL w64 = FALSE;
1403  BOOL is_wow64 = IsWow64Process(GetCurrentProcess(), &w64) && w64;
1404  if (is_wow64)
1405  {
1406  /* we are unable to differentiate between arm64 and amd64
1407  * machines here, so assume we are running on amd64 */
1408  *host_arch = ARCH_AMD64;
1409  }
1410  }
1411 #endif /* _ARM64_ */
1412 }
1413 
1414 static void
1415 win32_print_arch(arch_t arch, struct buffer *out)
1416 {
1417  switch (arch)
1418  {
1419  case ARCH_X86:
1420  buf_printf(out, "x86");
1421  break;
1422 
1423  case ARCH_AMD64:
1424  buf_printf(out, "amd64");
1425  break;
1426 
1427  case ARCH_ARM64:
1428  buf_printf(out, "arm64");
1429  break;
1430 
1431  case ARCH_UNKNOWN:
1432  buf_printf(out, "(unknown)");
1433  break;
1434 
1435  default:
1436  break;
1437  }
1438 }
1439 
1440 const char *
1441 win32_version_string(struct gc_arena *gc, bool add_name)
1442 {
1443  int version = win32_version_info();
1444  struct buffer out = alloc_buf_gc(256, gc);
1445 
1446  switch (version)
1447  {
1448  case WIN_XP:
1449  buf_printf(&out, "5.1%s", add_name ? " (Windows XP)" : "");
1450  break;
1451 
1452  case WIN_VISTA:
1453  buf_printf(&out, "6.0%s", add_name ? " (Windows Vista)" : "");
1454  break;
1455 
1456  case WIN_7:
1457  buf_printf(&out, "6.1%s", add_name ? " (Windows 7)" : "");
1458  break;
1459 
1460  case WIN_8:
1461  buf_printf(&out, "6.2%s", add_name ? " (Windows 8)" : "");
1462  break;
1463 
1464  case WIN_8_1:
1465  buf_printf(&out, "6.3%s", add_name ? " (Windows 8.1)" : "");
1466  break;
1467 
1468  case WIN_10:
1469  buf_printf(&out, "10.0%s", add_name ? " (Windows 10 or greater)" : "");
1470  break;
1471 
1472  default:
1473  msg(M_NONFATAL, "Unknown Windows version: %d", version);
1474  buf_printf(&out, "0.0%s", add_name ? " (unknown)" : "");
1475  break;
1476  }
1477 
1478  buf_printf(&out, ", ");
1479 
1480  arch_t process_arch, host_arch;
1481  win32_get_arch(&process_arch, &host_arch);
1482  win32_print_arch(process_arch, &out);
1483 
1484  buf_printf(&out, " executable");
1485 
1486  if (host_arch != ARCH_NATIVE)
1487  {
1488  buf_printf(&out, " running on ");
1489  win32_print_arch(host_arch, &out);
1490  buf_printf(&out, " host");
1491  }
1492 
1493  return (const char *)out.data;
1494 }
1495 
1496 bool
1497 send_msg_iservice(HANDLE pipe, const void *data, size_t size,
1498  ack_message_t *ack, const char *context)
1499 {
1500  struct gc_arena gc = gc_new();
1501  DWORD len;
1502  bool ret = true;
1503 
1504  if (!WriteFile(pipe, data, size, &len, NULL)
1505  || !ReadFile(pipe, ack, sizeof(*ack), &len, NULL))
1506  {
1507  msg(M_WARN, "%s: could not talk to service: %s [%lu]",
1508  context ? context : "Unknown",
1509  strerror_win32(GetLastError(), &gc), GetLastError());
1510  ret = false;
1511  }
1512 
1513  gc_free(&gc);
1514  return ret;
1515 }
1516 
1517 bool
1518 openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const format, ...)
1519 {
1520  va_list arglist;
1521  int len = -1;
1522  if (size > 0)
1523  {
1524  va_start(arglist, format);
1525  len = vswprintf(str, size, format, arglist);
1526  va_end(arglist);
1527  str[size - 1] = L'\0';
1528  }
1529  return (len >= 0 && len < size);
1530 }
1531 
1532 static BOOL
1533 get_install_path(WCHAR *path, DWORD size)
1534 {
1535  WCHAR reg_path[256];
1536  HKEY key;
1537  BOOL res = FALSE;
1538  openvpn_swprintf(reg_path, _countof(reg_path), L"SOFTWARE\\" PACKAGE_NAME);
1539 
1540  LONG status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, KEY_READ, &key);
1541  if (status != ERROR_SUCCESS)
1542  {
1543  return res;
1544  }
1545 
1546  /* The default value of REG_KEY is the install path */
1547  status = RegGetValueW(key, NULL, NULL, RRF_RT_REG_SZ, NULL, (LPBYTE)path, &size);
1548  res = status == ERROR_SUCCESS;
1549 
1550  RegCloseKey(key);
1551 
1552  return res;
1553 }
1554 
1555 static void
1557 {
1558  const WCHAR *ssl_fallback_dir = L"C:\\Windows\\System32";
1559 
1560  WCHAR install_path[MAX_PATH] = { 0 };
1561  if (!get_install_path(install_path, _countof(install_path)))
1562  {
1563  /* if we cannot find installation path from the registry,
1564  * use Windows directory as a fallback
1565  */
1566  openvpn_swprintf(install_path, _countof(install_path), L"%ls", ssl_fallback_dir);
1567  }
1568 
1569  if ((install_path[wcslen(install_path) - 1]) == L'\\')
1570  {
1571  install_path[wcslen(install_path) - 1] = L'\0';
1572  }
1573 
1574  static struct {
1575  WCHAR *name;
1576  WCHAR *value;
1577  } ossl_env[] = {
1578  {L"OPENSSL_CONF", L"openssl.cnf"},
1579  {L"OPENSSL_ENGINES", L"engines"},
1580  {L"OPENSSL_MODULES", L"modules"}
1581  };
1582 
1583  for (size_t i = 0; i < SIZE(ossl_env); ++i)
1584  {
1585  size_t size = 0;
1586 
1587  _wgetenv_s(&size, NULL, 0, ossl_env[i].name);
1588  if (size == 0)
1589  {
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);
1593  }
1594  }
1595 }
1596 
1597 void
1598 win32_sleep(const int n)
1599 {
1600  if (n < 0)
1601  {
1602  return;
1603  }
1604 
1605  /* Sleep() is not interruptible. Use a WAIT_OBJECT to catch signal */
1606 
1608  {
1609  if (n > 0)
1610  {
1611  Sleep(n*1000);
1612  }
1613  return;
1614  }
1615 
1616  update_time();
1617  time_t expire = now + n;
1618 
1619  while (expire >= now)
1620  {
1621  DWORD status = WaitForSingleObject(win32_signal.in.read, (expire-now)*1000);
1622  if ((status == WAIT_OBJECT_0 && win32_signal_get(&win32_signal))
1623  || status == WAIT_TIMEOUT)
1624  {
1625  return;
1626  }
1627 
1628  update_time();
1629 
1630  if (status != WAIT_OBJECT_0) /* wait failed or some unexpected error ? */
1631  {
1632  if (expire > now)
1633  {
1634  Sleep((expire-now)*1000);
1635  }
1636  return;
1637  }
1638  }
1639 }
1640 #endif /* ifdef _WIN32 */
overlapped_io_state_ascii
char * overlapped_io_state_ascii(const struct overlapped_io *o)
Definition: win32.c:203
set_win_sys_path
void set_win_sys_path(const char *newpath, struct env_set *es)
Definition: win32.c:1121
NE32_WRITE_EVENT
#define NE32_WRITE_EVENT
Definition: win32.h:87
signal_info::signal_received
volatile int signal_received
Definition: sig.h:43
WSO_MODE_CONSOLE
#define WSO_MODE_CONSOLE
Definition: win32.h:154
rw_handle::read
HANDLE read
Definition: win32.h:78
fork_to_self
void fork_to_self(const char *cmdline)
Definition: win32.c:1074
wsa_state
static struct WSAData wsa_state
Definition: win32.c:70
M_INFO
#define M_INFO
Definition: errlevel.h:55
security_attributes
Definition: win32.h:60
env_item::next
struct env_item * next
Definition: env_set.h:39
D_SEMAPHORE_LOW
#define D_SEMAPHORE_LOW
Definition: errlevel.h:135
WSO_MODE_UNDEF
#define WSO_MODE_UNDEF
Definition: win32.h:152
error.h
semaphore_close
void semaphore_close(struct semaphore *s)
Definition: win32.c:827
semaphore_lock
bool semaphore_lock(struct semaphore *s, int timeout_milliseconds)
Definition: win32.c:777
gc_new
static struct gc_arena gc_new(void)
Definition: buffer.h:1011
run_command.h
M_ERRNO
#define M_ERRNO
Definition: error.h:100
win32_signal::in
struct rw_handle in
Definition: win32.h:156
env_item::string
char * string
Definition: env_set.h:38
send_msg_iservice
bool send_msg_iservice(HANDLE pipe, const void *data, size_t size, ack_message_t *ack, const char *context)
Definition: win32.c:1497
PACKAGE_NAME
#define PACKAGE_NAME
Definition: config.h:492
strerror_win32
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition: error.c:812
block_dns_msg_handler
static void block_dns_msg_handler(DWORD err, const char *msg)
Definition: win32.c:1209
buffer::len
int len
Length in bytes of the actual content within the allocated memory.
Definition: buffer.h:66
net_event_win32::sd
socket_descriptor_t sd
Definition: win32.h:108
M_FATAL
#define M_FATAL
Definition: error.h:95
win32.h
block_dns_message_t::iface
interface_t iface
Definition: openvpn-msg.h:123
window_title::saved
bool saved
Definition: win32.h:73
argv
Definition: argv.h:35
netcmd_semaphore_lock
void netcmd_semaphore_lock(void)
Definition: win32.c:859
M_NONFATAL
#define M_NONFATAL
Definition: error.h:96
context
Contains all state information for one tunnel.
Definition: openvpn.h:476
es
struct env_set * es
Definition: test_pkcs11.c:131
OPENVPN_EXECVE_ERROR
#define OPENVPN_EXECVE_ERROR
Definition: run_command.h:36
SSEC_SCRIPTS
#define SSEC_SCRIPTS
Definition: run_command.h:33
BSTR
#define BSTR(buf)
Definition: buffer.h:129
alloc_buf_gc
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
BLOCK_DNS_IFACE_METRIC
#define BLOCK_DNS_IFACE_METRIC
Definition: block_dns.h:30
CC_CRLF
#define CC_CRLF
Definition: buffer.h:940
ack_message_t
Definition: openvpn-msg.h:116
HANDLE_DEFINED
#define HANDLE_DEFINED(h)
Definition: win32.h:66
net_event_win32_reset
void net_event_win32_reset(struct net_event_win32 *ne)
Definition: win32.c:359
semaphore
Definition: win32.h:239
PACKAGE_VERSION
#define PACKAGE_VERSION
Definition: config.h:504
win_get_tempdir
const char * win_get_tempdir(void)
Definition: win32.c:1146
dmsg
#define dmsg(flags,...)
Definition: error.h:154
net_event_win32_start
void net_event_win32_start(struct net_event_win32 *ne, long network_events, socket_descriptor_t sd)
Definition: win32.c:332
WIN_8_1
#define WIN_8_1
Definition: win32.h:300
D_LOW
#define D_LOW
Definition: errlevel.h:97
PACKAGE
#define PACKAGE
Definition: config.h:486
M_NOPREFIX
#define M_NOPREFIX
Definition: error.h:103
window_title_save
void window_title_save(struct window_title *wt)
Definition: win32.c:705
window_title
Definition: win32.h:71
NE32_PERSIST_EVENT
#define NE32_PERSIST_EVENT
Definition: win32.h:86
m_hEngineHandle
static HANDLE m_hEngineHandle
Definition: win32.c:59
ARCH_ARM64
@ ARCH_ARM64
Definition: win32.c:1342
frame
Packet geometry parameters.
Definition: mtu.h:98
netcmd_semaphore
struct semaphore netcmd_semaphore
Definition: win32.c:96
IOSTATE_IMMEDIATE_RETURN
#define IOSTATE_IMMEDIATE_RETURN
Definition: win32.h:203
net_event_win32
Definition: win32.h:105
net_event_win32_defined
static bool net_event_win32_defined(const struct net_event_win32 *ne)
Definition: win32.h:125
ARCH_UNKNOWN
@ ARCH_UNKNOWN
Definition: win32.c:1344
win_trigger_event
static void win_trigger_event(struct win32_signal *ws)
Definition: win32.c:394
WIN_10
#define WIN_10
Definition: win32.h:301
key
Container for unidirectional cipher and HMAC key material.
Definition: crypto.h:149
win32_get_arch
static void win32_get_arch(arch_t *process_arch, arch_t *host_arch)
Definition: win32.c:1348
CLEAR
#define CLEAR(x)
Definition: basic.h:33
net_event_win32_stop
void net_event_win32_stop(struct net_event_win32 *ne)
Definition: win32.c:365
win32_signal
Definition: win32.h:151
mtu.h
CC_DOUBLE_QUOTE
#define CC_DOUBLE_QUOTE
Definition: buffer.h:928
overlapped_io::overlapped
OVERLAPPED overlapped
Definition: win32.h:205
semaphore::locked
bool locked
Definition: win32.h:242
interface_t::index
int index
Definition: openvpn-msg.h:60
env_set::list
struct env_item * list
Definition: env_set.h:44
win32_signal_clear
void win32_signal_clear(struct win32_signal *ws)
Definition: win32.c:448
string_alloc
char * string_alloc(const char *str, struct gc_arena *gc)
Definition: buffer.c:693
window_title::old_window_title
char old_window_title[256]
Definition: win32.h:74
ASSERT
#define ASSERT(x)
Definition: error.h:201
overlapped_io_close
void overlapped_io_close(struct overlapped_io *o)
Definition: win32.c:190
compat-versionhelpers.h
semaphore::hand
HANDLE hand
Definition: win32.h:243
argv::argv
char ** argv
Definition: argv.h:39
win_ctrl_handler
static bool WINAPI win_ctrl_handler(DWORD signum)
Definition: win32.c:420
SYS_PATH_ENV_VAR_NAME
#define SYS_PATH_ENV_VAR_NAME
Definition: win32.h:36
win32_keyboard_get
static unsigned int win32_keyboard_get(struct win32_signal *ws)
Definition: win32.c:578
init_net_event_win32
void init_net_event_win32(struct rw_handle *event, long network_events, socket_descriptor_t sd, unsigned int flags)
Definition: win32.c:224
win_block_dns_service
static bool win_block_dns_service(bool add, int index, const HANDLE pipe)
Definition: win32.c:1173
OPENVPN_EXECVE_NOT_ALLOWED
#define OPENVPN_EXECVE_NOT_ALLOWED
Definition: run_command.h:37
CC_PRINT
#define CC_PRINT
Definition: buffer.h:911
block_dns_message_t::header
message_header_t header
Definition: openvpn-msg.h:122
update_time
static void update_time(void)
Definition: otime.h:77
win_wfp_block_dns
bool win_wfp_block_dns(const NET_IFINDEX index, const HANDLE msg_channel)
Definition: win32.c:1227
netcmd_semaphore_release
void netcmd_semaphore_release(void)
Definition: win32.c:875
ack_message_t::error_number
int error_number
Definition: openvpn-msg.h:118
string_mod
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Definition: buffer.c:1085
msg_add_block_dns
@ msg_add_block_dns
Definition: openvpn-msg.h:38
M_WARN
#define M_WARN
Definition: error.h:97
wide_string
WCHAR * wide_string(const char *utf8, struct gc_arena *gc)
Definition: win32-util.c:41
net_event_win32::event_mask
long event_mask
Definition: win32.h:109
window_title_clear
void window_title_clear(struct window_title *wt)
Definition: win32.c:699
security_attributes::sd
SECURITY_DESCRIPTOR sd
Definition: win32.h:63
WIN_VISTA
#define WIN_VISTA
Definition: win32.h:297
env_allowed
bool env_allowed(const char *str)
Definition: env_set.c:413
WSO_NOFORCE
#define WSO_NOFORCE
Definition: win32.h:167
netcmd_semaphore_init
void netcmd_semaphore_init(void)
Definition: win32.c:847
throw_signal
void throw_signal(const int signum)
Throw a hard signal.
Definition: sig.c:177
set_interface_metric
DWORD set_interface_metric(const NET_IFINDEX index, const ADDRESS_FAMILY family, const ULONG metric)
Sets interface metric value for specified interface index.
Definition: block_dns.c:389
set_win_sys_path_via_env
void set_win_sys_path_via_env(struct env_set *es)
Definition: win32.c:1129
M_ERR
#define M_ERR
Definition: error.h:111
semaphore_release
void semaphore_release(struct semaphore *s)
Definition: win32.c:811
win32_sleep
void win32_sleep(const int n)
Definition: win32.c:1598
set_pause_exit_win32
void set_pause_exit_win32(void)
Definition: win32.c:147
ARCH_X86
@ ARCH_X86
Definition: win32.c:1340
openvpn_swprintf
bool openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const format,...)
Definition: win32.c:1518
SIZE
#define SIZE(x)
Definition: basic.h:30
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
get_install_path
static BOOL get_install_path(WCHAR *path, DWORD size)
Definition: win32.c:1533
pause_exit_enabled
static bool pause_exit_enabled
Definition: win32.c:75
WSO_FORCE_CONSOLE
#define WSO_FORCE_CONSOLE
Definition: win32.h:169
socket_defined
static int socket_defined(const socket_descriptor_t sd)
Definition: syshead.h:437
window_title_generate
void window_title_generate(const char *title)
Definition: win32.c:731
CC_SPACE
#define CC_SPACE
Definition: buffer.h:913
D_SEMAPHORE
#define D_SEMAPHORE
Definition: errlevel.h:136
overlapped_io::iostate
int iostate
Definition: win32.h:204
WIN_7
#define WIN_7
Definition: win32.h:298
CC_ANY
#define CC_ANY
Definition: buffer.h:903
argv::argc
size_t argc
Definition: argv.h:38
buffer.h
syshead.h
block_dns_message_t
Definition: openvpn-msg.h:121
win32_print_arch
static void win32_print_arch(arch_t arch, struct buffer *out)
Definition: win32.c:1415
uninit_win32
void uninit_win32(void)
Definition: win32.c:123
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
alloc_buf_sock_tun
void alloc_buf_sock_tun(struct buffer *buf, const struct frame *frame)
Definition: mtu.c:42
close_net_event_win32
void close_net_event_win32(struct rw_handle *event, socket_descriptor_t sd, unsigned int flags)
Definition: win32.c:278
string_class
bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive)
Definition: buffer.c:1066
setenv_str
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition: env_set.c:283
SOCKET_UNDEFINED
#define SOCKET_UNDEFINED
Definition: syshead.h:427
get_interface_metric
int get_interface_metric(const NET_IFINDEX index, const ADDRESS_FAMILY family, int *is_auto)
Return interface metric value for the specified interface index.
Definition: block_dns.c:350
wide_cmd_line
static WCHAR * wide_cmd_line(const struct argv *a, struct gc_arena *gc)
Definition: win32.c:948
win32_version_string
const char * win32_version_string(struct gc_arena *gc, bool add_name)
Definition: win32.c:1441
env_set
Definition: env_set.h:42
ARCH_AMD64
@ ARCH_AMD64
Definition: win32.c:1341
keyboard_input_available
static bool keyboard_input_available(struct win32_signal *ws)
Definition: win32.c:545
openvpn_execve_allowed
bool openvpn_execve_allowed(const unsigned int flags)
Definition: run_command.c:110
reset_net_event_win32
long reset_net_event_win32(struct rw_handle *event, socket_descriptor_t sd)
Definition: win32.c:263
block_dns.h
win32_signal_get
int win32_signal_get(struct win32_signal *ws)
Definition: win32.c:640
add_block_dns_filters
DWORD add_block_dns_filters(HANDLE *engine_handle, int index, const WCHAR *exe_path, block_dns_msg_handler_t msg_handler)
Definition: block_dns.c:174
tap_metric_v6
static int tap_metric_v6
Definition: win32.c:65
free_buf
void free_buf(struct buffer *buf)
Definition: buffer.c:183
socket_descriptor_t
SOCKET socket_descriptor_t
Definition: syshead.h:429
net_event_win32_reset_write
void net_event_win32_reset_write(struct net_event_win32 *ne)
Definition: win32.c:341
keyboard_ir_to_key
static unsigned int keyboard_ir_to_key(INPUT_RECORD *ir)
Definition: win32.c:560
win_sys_path
static char * win_sys_path
Definition: win32.c:101
WIN_8
#define WIN_8
Definition: win32.h:299
overlapped_io::buf_init
struct buffer buf_init
Definition: win32.h:215
arch_t
arch_t
Definition: win32.c:1339
gc_malloc
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition: buffer.c:380
win32_signal_close
void win32_signal_close(struct win32_signal *ws)
Definition: win32.c:606
overlapped_io_init
void overlapped_io_init(struct overlapped_io *o, const struct frame *frame, BOOL event_state)
Definition: win32.c:172
openvpn_snprintf
bool openvpn_snprintf(char *str, size_t size, const char *format,...)
Definition: buffer.c:294
status
static SERVICE_STATUS status
Definition: interactive.c:56
rw_handle::write
HANDLE write
Definition: win32.h:79
gc_free
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1019
security_attributes::sa
SECURITY_ATTRIBUTES sa
Definition: win32.h:62
WSO_FORCE_SERVICE
#define WSO_FORCE_SERVICE
Definition: win32.h:168
init_security_attributes_allow_all
bool init_security_attributes_allow_all(struct security_attributes *obj)
Definition: win32.c:153
rw_handle
Definition: win32.h:77
init_win32
void init_win32(void)
Definition: win32.c:110
msg_del_block_dns
@ msg_del_block_dns
Definition: openvpn-msg.h:39
now
time_t now
Definition: otime.c:34
openvpn-msg.h
env_item
Definition: env_set.h:37
config.h
semaphore_open
void semaphore_open(struct semaphore *s, const char *name)
Definition: win32.c:753
win_wfp_uninit
bool win_wfp_uninit(const NET_IFINDEX index, const HANDLE msg_channel)
Definition: win32.c:1277
net_event_win32::handle
struct rw_handle handle
Definition: win32.h:107
set_openssl_env_vars
static void set_openssl_env_vars()
Set OpenSSL environment variables to a safe directory.
Definition: win32.c:1556
net_event_win32_close
void net_event_win32_close(struct net_event_win32 *ne)
Definition: win32.c:376
win32_signal::console_mode_save
DWORD console_mode_save
Definition: win32.h:157
check_malloc_return
static void check_malloc_return(void *p)
Definition: buffer.h:1089
semaphore::name
const char * name
Definition: win32.h:241
win32_signal::mode
int mode
Definition: win32.h:155
win32_service_interrupt
bool win32_service_interrupt(struct win32_signal *ws)
Definition: win32.c:626
sig.h
get_win_sys_path
char * get_win_sys_path(void)
Definition: win32.c:1114
net_event_win32_init
void net_event_win32_init(struct net_event_win32 *ne)
Definition: win32.c:325
win32_signal_open
void win32_signal_open(struct win32_signal *ws, int force, const char *exit_event_name, bool exit_event_initial_state)
Definition: win32.c:454
SCRIPT_SECURITY_WARNING
#define SCRIPT_SECURITY_WARNING
Definition: common.h:98
netcmd_semaphore_close
void netcmd_semaphore_close(void)
Definition: win32.c:853
win32_version_info
int win32_version_info(void)
Definition: win32.c:1304
tap_metric_v4
static int tap_metric_v4
Definition: win32.c:64
memdbg.h
window_title_restore
void window_title_restore(const struct window_title *wt)
Definition: win32.c:722
env_block
static char * env_block(const struct env_set *es)
Definition: win32.c:887
ARCH_NATIVE
@ ARCH_NATIVE
Definition: win32.c:1343
semaphore_clear
void semaphore_clear(struct semaphore *s)
Definition: win32.c:747
IOSTATE_INITIAL
#define IOSTATE_INITIAL
Definition: win32.h:201
msg
#define msg(flags,...)
Definition: error.h:150
siginfo_static
struct signal_info siginfo_static
Definition: sig.c:45
WSO_MODE_SERVICE
#define WSO_MODE_SERVICE
Definition: win32.h:153
buf_printf
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:240
win32-util.h
openvpn_execve
int openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags)
Definition: win32.c:1002
overlapped_io
Definition: win32.h:200
script_security
int script_security(void)
Definition: run_command.c:43
win32_signal::console_mode_save_defined
bool console_mode_save_defined
Definition: win32.h:158
win32_pause
void win32_pause(struct win32_signal *ws)
Definition: win32.c:684
IOSTATE_QUEUED
#define IOSTATE_QUEUED
Definition: win32.h:202
WIN_XP
#define WIN_XP
Definition: win32.h:296
delete_block_dns_filters
DWORD delete_block_dns_filters(HANDLE engine_handle)
Definition: block_dns.c:325
buffer::data
uint8_t * data
Pointer to the allocated memory.
Definition: buffer.h:68