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