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