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