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-2017 OpenVPN Technologies, 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, targetted 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 "sig.h"
43 #include "win32.h"
44 #include "misc.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();
136  free(win_sys_path);
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
272 close_net_event_win32(struct rw_handle *event, socket_descriptor_t sd, unsigned int flags)
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  int status;
689  msg(M_INFO|M_NOPREFIX, "Press any key to continue...");
690  do
691  {
692  status = WaitForSingleObject(ws->in.read, INFINITE);
693  } while (!win32_keyboard_get(ws));
694  }
695 }
696 
697 /* window functions */
698 
699 void
701 {
702  CLEAR(*wt);
703 }
704 
705 void
707 {
708  if (!wt->saved)
709  {
710  if (!GetConsoleTitle(wt->old_window_title, sizeof(wt->old_window_title)))
711  {
712  wt->old_window_title[0] = 0;
713  wt->saved = false;
714  }
715  else
716  {
717  wt->saved = true;
718  }
719  }
720 }
721 
722 void
724 {
725  if (wt->saved)
726  {
727  SetConsoleTitle(wt->old_window_title);
728  }
729 }
730 
731 void
732 window_title_generate(const char *title)
733 {
734  struct gc_arena gc = gc_new();
735  struct buffer out = alloc_buf_gc(256, &gc);
736  if (!title)
737  {
738  title = "";
739  }
740  buf_printf(&out, "[%s] " PACKAGE_NAME " " PACKAGE_VERSION " F4:EXIT F1:USR1 F2:USR2 F3:HUP", title);
741  SetConsoleTitle(BSTR(&out));
742  gc_free(&gc);
743 }
744 
745 /* semaphore functions */
746 
747 void
749 {
750  CLEAR(*s);
751 }
752 
753 void
754 semaphore_open(struct semaphore *s, const char *name)
755 {
756  struct security_attributes sa;
757 
758  s->locked = false;
759  s->name = name;
760  s->hand = NULL;
761 
763  {
764  s->hand = CreateSemaphore(&sa.sa, 1, 1, name);
765  }
766 
767  if (s->hand == NULL)
768  {
769  msg(M_WARN|M_ERRNO, "WARNING: Cannot create Win32 semaphore '%s'", name);
770  }
771  else
772  {
773  dmsg(D_SEMAPHORE, "Created Win32 semaphore '%s'", s->name);
774  }
775 }
776 
777 bool
778 semaphore_lock(struct semaphore *s, int timeout_milliseconds)
779 {
780  bool ret = true;
781 
782  if (s->hand)
783  {
784  DWORD status;
785  ASSERT(!s->locked);
786 
787  dmsg(D_SEMAPHORE_LOW, "Attempting to lock Win32 semaphore '%s' prior to net shell command (timeout = %d sec)",
788  s->name,
789  timeout_milliseconds / 1000);
790  status = WaitForSingleObject(s->hand, timeout_milliseconds);
791  if (status == WAIT_FAILED)
792  {
793  msg(M_ERR, "Wait failed on Win32 semaphore '%s'", s->name);
794  }
795  ret = (status == WAIT_TIMEOUT) ? false : true;
796  if (ret)
797  {
798  dmsg(D_SEMAPHORE, "Locked Win32 semaphore '%s'", s->name);
799  s->locked = true;
800  }
801  else
802  {
803  dmsg(D_SEMAPHORE, "Wait on Win32 semaphore '%s' timed out after %d milliseconds",
804  s->name,
805  timeout_milliseconds);
806  }
807  }
808  return ret;
809 }
810 
811 void
813 {
814  if (s->hand)
815  {
816  ASSERT(s->locked);
817  dmsg(D_SEMAPHORE, "Releasing Win32 semaphore '%s'", s->name);
818  if (!ReleaseSemaphore(s->hand, 1, NULL))
819  {
820  msg(M_WARN | M_ERRNO, "ReleaseSemaphore failed on Win32 semaphore '%s'",
821  s->name);
822  }
823  s->locked = false;
824  }
825 }
826 
827 void
829 {
830  if (s->hand)
831  {
832  if (s->locked)
833  {
835  }
836  dmsg(D_SEMAPHORE, "Closing Win32 semaphore '%s'", s->name);
837  CloseHandle(s->hand);
838  s->hand = NULL;
839  }
840 }
841 
842 /*
843  * Special global semaphore used to protect network
844  * shell commands from simultaneous instantiation.
845  */
846 
847 void
849 {
850  semaphore_open(&netcmd_semaphore, PACKAGE "_netcmd");
851 }
852 
853 void
855 {
857 }
858 
859 void
861 {
862  const int timeout_seconds = 600;
863 
864  if (!netcmd_semaphore.hand)
865  {
867  }
868 
869  if (!semaphore_lock(&netcmd_semaphore, timeout_seconds * 1000))
870  {
871  msg(M_FATAL, "Cannot lock net command semaphore");
872  }
873 }
874 
875 void
877 {
879  /* netcmd_semaphore has max count of 1 - safe to close after release */
881 }
882 
883 /*
884  * Return true if filename is safe to be used on Windows,
885  * by avoiding the following reserved names:
886  *
887  * CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9,
888  * LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, and CLOCK$
889  *
890  * See: http://msdn.microsoft.com/en-us/library/aa365247.aspx
891  * and http://msdn.microsoft.com/en-us/library/86k9f82k(VS.80).aspx
892  */
893 
894 static bool
895 cmp_prefix(const char *str, const bool n, const char *pre)
896 {
897  size_t i = 0;
898 
899  if (!str)
900  {
901  return false;
902  }
903 
904  while (true)
905  {
906  const int c1 = pre[i];
907  int c2 = str[i];
908  ++i;
909  if (c1 == '\0')
910  {
911  if (n)
912  {
913  if (isdigit(c2))
914  {
915  c2 = str[i];
916  }
917  else
918  {
919  return false;
920  }
921  }
922  return c2 == '\0' || c2 == '.';
923  }
924  else if (c2 == '\0')
925  {
926  return false;
927  }
928  if (c1 != tolower(c2))
929  {
930  return false;
931  }
932  }
933 }
934 
935 bool
936 win_safe_filename(const char *fn)
937 {
938  if (cmp_prefix(fn, false, "con"))
939  {
940  return false;
941  }
942  if (cmp_prefix(fn, false, "prn"))
943  {
944  return false;
945  }
946  if (cmp_prefix(fn, false, "aux"))
947  {
948  return false;
949  }
950  if (cmp_prefix(fn, false, "nul"))
951  {
952  return false;
953  }
954  if (cmp_prefix(fn, true, "com"))
955  {
956  return false;
957  }
958  if (cmp_prefix(fn, true, "lpt"))
959  {
960  return false;
961  }
962  if (cmp_prefix(fn, false, "clock$"))
963  {
964  return false;
965  }
966  return true;
967 }
968 
969 /*
970  * Service functions for openvpn_execve
971  */
972 
973 static char *
974 env_block(const struct env_set *es)
975 {
976  char force_path[256];
977  char *sysroot = get_win_sys_path();
978 
979  if (!openvpn_snprintf(force_path, sizeof(force_path), "PATH=%s\\System32;%s;%s\\System32\\Wbem",
980  sysroot, sysroot, sysroot))
981  {
982  msg(M_WARN, "env_block: default path truncated to %s", force_path);
983  }
984 
985  if (es)
986  {
987  struct env_item *e;
988  char *ret;
989  char *p;
990  size_t nchars = 1;
991  bool path_seen = false;
992 
993  for (e = es->list; e != NULL; e = e->next)
994  {
995  nchars += strlen(e->string) + 1;
996  }
997 
998  nchars += strlen(force_path)+1;
999 
1000  ret = (char *) malloc(nchars);
1001  check_malloc_return(ret);
1002 
1003  p = ret;
1004  for (e = es->list; e != NULL; e = e->next)
1005  {
1006  if (env_allowed(e->string))
1007  {
1008  strcpy(p, e->string);
1009  p += strlen(e->string) + 1;
1010  }
1011  if (strncmp(e->string, "PATH=", 5 ) == 0)
1012  {
1013  path_seen = true;
1014  }
1015  }
1016 
1017  /* make sure PATH is set */
1018  if (!path_seen)
1019  {
1020  msg( M_INFO, "env_block: add %s", force_path );
1021  strcpy( p, force_path );
1022  p += strlen(force_path) + 1;
1023  }
1024 
1025  *p = '\0';
1026  return ret;
1027  }
1028  else
1029  {
1030  return NULL;
1031  }
1032 }
1033 
1034 static WCHAR *
1035 wide_cmd_line(const struct argv *a, struct gc_arena *gc)
1036 {
1037  size_t nchars = 1;
1038  size_t maxlen = 0;
1039  size_t i;
1040  struct buffer buf;
1041  char *work = NULL;
1042 
1043  if (!a)
1044  {
1045  return NULL;
1046  }
1047 
1048  for (i = 0; i < a->argc; ++i)
1049  {
1050  const char *arg = a->argv[i];
1051  const size_t len = strlen(arg);
1052  nchars += len + 3;
1053  if (len > maxlen)
1054  {
1055  maxlen = len;
1056  }
1057  }
1058 
1059  work = gc_malloc(maxlen + 1, false, gc);
1060  check_malloc_return(work);
1061  buf = alloc_buf_gc(nchars, gc);
1062 
1063  for (i = 0; i < a->argc; ++i)
1064  {
1065  const char *arg = a->argv[i];
1066  strcpy(work, arg);
1068  if (i)
1069  {
1070  buf_printf(&buf, " ");
1071  }
1072  if (string_class(work, CC_ANY, CC_SPACE))
1073  {
1074  buf_printf(&buf, "%s", work);
1075  }
1076  else
1077  {
1078  buf_printf(&buf, "\"%s\"", work);
1079  }
1080  }
1081 
1082  return wide_string(BSTR(&buf), gc);
1083 }
1084 
1085 /*
1086  * Attempt to simulate fork/execve on Windows
1087  */
1088 int
1089 openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags)
1090 {
1091  int ret = -1;
1092  static bool exec_warn = false;
1093 
1094  if (a && a->argv[0])
1095  {
1096  if (openvpn_execve_allowed(flags))
1097  {
1098  struct gc_arena gc = gc_new();
1099  STARTUPINFOW start_info;
1100  PROCESS_INFORMATION proc_info;
1101 
1102  char *env = env_block(es);
1103  WCHAR *cl = wide_cmd_line(a, &gc);
1104  WCHAR *cmd = wide_string(a->argv[0], &gc);
1105 
1106  /* this allows console programs to run, and is ignored otherwise */
1107  DWORD proc_flags = CREATE_NO_WINDOW;
1108 
1109  CLEAR(start_info);
1110  CLEAR(proc_info);
1111 
1112  /* fill in STARTUPINFO struct */
1113  GetStartupInfoW(&start_info);
1114  start_info.cb = sizeof(start_info);
1115  start_info.dwFlags = STARTF_USESHOWWINDOW;
1116  start_info.wShowWindow = SW_HIDE;
1117 
1118  if (CreateProcessW(cmd, cl, NULL, NULL, FALSE, proc_flags, env, NULL, &start_info, &proc_info))
1119  {
1120  DWORD exit_status = 0;
1121  CloseHandle(proc_info.hThread);
1122  WaitForSingleObject(proc_info.hProcess, INFINITE);
1123  if (GetExitCodeProcess(proc_info.hProcess, &exit_status))
1124  {
1125  ret = (int)exit_status;
1126  }
1127  else
1128  {
1129  msg(M_WARN|M_ERRNO, "openvpn_execve: GetExitCodeProcess %S failed", cmd);
1130  }
1131  CloseHandle(proc_info.hProcess);
1132  }
1133  else
1134  {
1135  msg(M_WARN|M_ERRNO, "openvpn_execve: CreateProcess %S failed", cmd);
1136  }
1137  free(env);
1138  gc_free(&gc);
1139  }
1140  else if (!exec_warn && (script_security < SSEC_SCRIPTS))
1141  {
1143  exec_warn = true;
1144  }
1145  }
1146  else
1147  {
1148  msg(M_WARN, "openvpn_execve: called with empty argv");
1149  }
1150  return ret;
1151 }
1152 
1153 WCHAR *
1154 wide_string(const char *utf8, struct gc_arena *gc)
1155 {
1156  int n = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
1157  WCHAR *ucs16 = gc_malloc(n * sizeof(WCHAR), false, gc);
1158  MultiByteToWideChar(CP_UTF8, 0, utf8, -1, ucs16, n);
1159  return ucs16;
1160 }
1161 
1162 /*
1163  * call ourself in another process
1164  */
1165 void
1166 fork_to_self(const char *cmdline)
1167 {
1168  STARTUPINFO start_info;
1169  PROCESS_INFORMATION proc_info;
1170  char self_exe[256];
1171  char *cl = string_alloc(cmdline, NULL);
1172  DWORD status;
1173 
1174  CLEAR(start_info);
1175  CLEAR(proc_info);
1176  CLEAR(self_exe);
1177 
1178  status = GetModuleFileName(NULL, self_exe, sizeof(self_exe));
1179  if (status == 0 || status == sizeof(self_exe))
1180  {
1181  msg(M_WARN|M_ERRNO, "fork_to_self: CreateProcess failed: cannot get module name via GetModuleFileName");
1182  goto done;
1183  }
1184 
1185  /* fill in STARTUPINFO struct */
1186  GetStartupInfo(&start_info);
1187  start_info.cb = sizeof(start_info);
1188  start_info.dwFlags = STARTF_USESHOWWINDOW;
1189  start_info.wShowWindow = SW_HIDE;
1190 
1191  if (CreateProcess(self_exe, cl, NULL, NULL, FALSE, 0, NULL, NULL, &start_info, &proc_info))
1192  {
1193  CloseHandle(proc_info.hThread);
1194  CloseHandle(proc_info.hProcess);
1195  }
1196  else
1197  {
1198  msg(M_WARN|M_ERRNO, "fork_to_self: CreateProcess failed: %s", cmdline);
1199  }
1200 
1201 done:
1202  free(cl);
1203 }
1204 
1205 char *
1207 {
1209  return win_sys_path;
1210 }
1211 
1212 void
1213 set_win_sys_path(const char *newpath, struct env_set *es)
1214 {
1215  free(win_sys_path);
1216  win_sys_path = string_alloc(newpath, NULL);
1217  setenv_str(es, SYS_PATH_ENV_VAR_NAME, win_sys_path); /* route.exe needs this */
1218 }
1219 
1220 void
1222 {
1223  char buf[256];
1224  DWORD status = GetEnvironmentVariable(SYS_PATH_ENV_VAR_NAME, buf, sizeof(buf));
1225  if (!status)
1226  {
1227  msg(M_ERR, "Cannot find environmental variable %s", SYS_PATH_ENV_VAR_NAME);
1228  }
1229  if (status > sizeof(buf) - 1)
1230  {
1231  msg(M_FATAL, "String overflow attempting to read environmental variable %s", SYS_PATH_ENV_VAR_NAME);
1232  }
1233  set_win_sys_path(buf, es);
1234 }
1235 
1236 
1237 const char *
1239 {
1240  static char tmpdir[MAX_PATH];
1241  WCHAR wtmpdir[MAX_PATH];
1242 
1243  if (!GetTempPathW(_countof(wtmpdir), wtmpdir))
1244  {
1245  /* Warn if we can't find a valid temporary directory, which should
1246  * be unlikely.
1247  */
1248  msg(M_WARN, "Could not find a suitable temporary directory."
1249  " (GetTempPath() failed). Consider using --tmp-dir");
1250  return NULL;
1251  }
1252 
1253  if (WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, NULL, 0, NULL, NULL) > sizeof(tmpdir))
1254  {
1255  msg(M_WARN, "Could not get temporary directory. Path is too long."
1256  " Consider using --tmp-dir");
1257  return NULL;
1258  }
1259 
1260  WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, tmpdir, sizeof(tmpdir), NULL, NULL);
1261  return tmpdir;
1262 }
1263 
1264 static bool
1265 win_block_dns_service(bool add, int index, const HANDLE pipe)
1266 {
1267  DWORD len;
1268  bool ret = false;
1269  ack_message_t ack;
1270  struct gc_arena gc = gc_new();
1271 
1272  block_dns_message_t data = {
1273  .header = {
1275  sizeof(block_dns_message_t),
1276  0
1277  },
1278  .iface = { .index = index, .name = "" }
1279  };
1280 
1281  if (!WriteFile(pipe, &data, sizeof(data), &len, NULL)
1282  || !ReadFile(pipe, &ack, sizeof(ack), &len, NULL))
1283  {
1284  msg(M_WARN, "Block_DNS: could not talk to service: %s [%lu]",
1285  strerror_win32(GetLastError(), &gc), GetLastError());
1286  goto out;
1287  }
1288 
1289  if (ack.error_number != NO_ERROR)
1290  {
1291  msg(M_WARN, "Block_DNS: %s block dns filters using service failed: %s [status=0x%x if_index=%d]",
1292  (add ? "adding" : "deleting"), strerror_win32(ack.error_number, &gc),
1293  ack.error_number, data.iface.index);
1294  goto out;
1295  }
1296 
1297  ret = true;
1298  msg(M_INFO, "%s outside dns using service succeeded.", (add ? "Blocking" : "Unblocking"));
1299 out:
1300  gc_free(&gc);
1301  return ret;
1302 }
1303 
1304 static void
1305 block_dns_msg_handler(DWORD err, const char *msg)
1306 {
1307  struct gc_arena gc = gc_new();
1308 
1309  if (err == 0)
1310  {
1311  msg(M_INFO, "%s", msg);
1312  }
1313  else
1314  {
1315  msg(M_WARN, "Error in add_block_dns_filters(): %s : %s [status=0x%lx]",
1316  msg, strerror_win32(err, &gc), err);
1317  }
1318 
1319  gc_free(&gc);
1320 }
1321 
1322 bool
1323 win_wfp_block_dns(const NET_IFINDEX index, const HANDLE msg_channel)
1324 {
1325  WCHAR openvpnpath[MAX_PATH];
1326  bool ret = false;
1327  DWORD status;
1328 
1329  if (msg_channel)
1330  {
1331  dmsg(D_LOW, "Using service to add block dns filters");
1332  ret = win_block_dns_service(true, index, msg_channel);
1333  goto out;
1334  }
1335 
1336  status = GetModuleFileNameW(NULL, openvpnpath, _countof(openvpnpath));
1337  if (status == 0 || status == _countof(openvpnpath))
1338  {
1339  msg(M_WARN|M_ERRNO, "block_dns: cannot get executable path");
1340  goto out;
1341  }
1342 
1343  status = add_block_dns_filters(&m_hEngineHandle, index, openvpnpath,
1345  if (status == 0)
1346  {
1347  tap_metric_v4 = get_interface_metric(index, AF_INET);
1348  tap_metric_v6 = get_interface_metric(index, AF_INET6);
1349  if (tap_metric_v4 < 0)
1350  {
1351  /* error, should not restore metric */
1352  tap_metric_v4 = -1;
1353  }
1354  if (tap_metric_v6 < 0)
1355  {
1356  /* error, should not restore metric */
1357  tap_metric_v6 = -1;
1358  }
1359  status = set_interface_metric(index, AF_INET, BLOCK_DNS_IFACE_METRIC);
1360  if (!status)
1361  {
1362  set_interface_metric(index, AF_INET6, BLOCK_DNS_IFACE_METRIC);
1363  }
1364  }
1365 
1366  ret = (status == 0);
1367 
1368 out:
1369 
1370  return ret;
1371 }
1372 
1373 bool
1374 win_wfp_uninit(const NET_IFINDEX index, const HANDLE msg_channel)
1375 {
1376  dmsg(D_LOW, "Uninitializing WFP");
1377 
1378  if (msg_channel)
1379  {
1380  msg(D_LOW, "Using service to delete block dns filters");
1381  win_block_dns_service(false, index, msg_channel);
1382  }
1383  else
1384  {
1386  m_hEngineHandle = NULL;
1387  if (tap_metric_v4 >= 0)
1388  {
1389  set_interface_metric(index, AF_INET, tap_metric_v4);
1390  }
1391  if (tap_metric_v6 >= 0)
1392  {
1393  set_interface_metric(index, AF_INET6, tap_metric_v6);
1394  }
1395  }
1396 
1397  return true;
1398 }
1399 
1400 int
1402 {
1403  if (!IsWindowsXPOrGreater())
1404  {
1405  msg(M_FATAL, "Error: Windows version must be XP or greater.");
1406  }
1407 
1408  if (!IsWindowsVistaOrGreater())
1409  {
1410  return WIN_XP;
1411  }
1412 
1413  if (!IsWindows7OrGreater())
1414  {
1415  return WIN_VISTA;
1416  }
1417 
1418  if (!IsWindows8OrGreater())
1419  {
1420  return WIN_7;
1421  }
1422  else
1423  {
1424  return WIN_8;
1425  }
1426 }
1427 
1428 bool
1430 {
1431 #if defined(_WIN64)
1432  return true; /* 64-bit programs run only on Win64 */
1433 #elif defined(_WIN32)
1434  /* 32-bit programs run on both 32-bit and 64-bit Windows */
1435  BOOL f64 = FALSE;
1436  return IsWow64Process(GetCurrentProcess(), &f64) && f64;
1437 #else /* if defined(_WIN64) */
1438  return false; /* Win64 does not support Win16 */
1439 #endif
1440 }
1441 
1442 const char *
1443 win32_version_string(struct gc_arena *gc, bool add_name)
1444 {
1445  int version = win32_version_info();
1446  struct buffer out = alloc_buf_gc(256, gc);
1447 
1448  switch (version)
1449  {
1450  case WIN_XP:
1451  buf_printf(&out, "5.1%s", add_name ? " (Windows XP)" : "");
1452  break;
1453 
1454  case WIN_VISTA:
1455  buf_printf(&out, "6.0%s", add_name ? " (Windows Vista)" : "");
1456  break;
1457 
1458  case WIN_7:
1459  buf_printf(&out, "6.1%s", add_name ? " (Windows 7)" : "");
1460  break;
1461 
1462  case WIN_8:
1463  buf_printf(&out, "6.2%s", add_name ? " (Windows 8 or greater)" : "");
1464  break;
1465 
1466  default:
1467  msg(M_NONFATAL, "Unknown Windows version: %d", version);
1468  buf_printf(&out, "0.0%s", add_name ? " (unknown)" : "");
1469  break;
1470  }
1471 
1472  buf_printf(&out, win32_is_64bit() ? " 64bit" : " 32bit");
1473 
1474  return (const char *)out.data;
1475 }
1476 
1477 #endif /* ifdef _WIN32 */
struct signal_info siginfo_static
Definition: sig.c:46
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:1000
WCHAR * wide_string(const char *utf8, struct gc_arena *gc)
Definition: win32.c:1154
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:854
const char * win_get_tempdir(void)
Definition: win32.c:1238
static int tap_metric_v4
Definition: win32.c:65
struct buffer buf_init
Definition: win32.h:209
#define WSO_NOFORCE
Definition: win32.h:161
void free_buf(struct buffer *buf)
Definition: buffer.c:191
HANDLE read
Definition: win32.h:72
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:1265
char * string_alloc(const char *str, struct gc_arena *gc)
Definition: buffer.c:626
static void win_trigger_event(struct win32_signal *ws)
Definition: win32.c:388
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition: error.c:825
#define WSO_FORCE_SERVICE
Definition: win32.h:162
#define M_INFO
Definition: errlevel.h:55
Packet geometry parameters.
Definition: mtu.h:93
void window_title_clear(struct window_title *wt)
Definition: win32.c:700
void semaphore_open(struct semaphore *s, const char *name)
Definition: win32.c:754
#define D_SEMAPHORE_LOW
Definition: errlevel.h:131
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:990
OVERLAPPED overlapped
Definition: win32.h:199
DWORD delete_block_dns_filters(HANDLE engine_handle)
Definition: block_dns.c:333
#define CC_PRINT
Definition: buffer.h:882
int script_security
Definition: misc.c:55
#define ASSERT(x)
Definition: error.h:221
#define SIGUSR1
Definition: config-msvc.h:116
struct semaphore netcmd_semaphore
Definition: win32.c:97
void semaphore_close(struct semaphore *s)
Definition: win32.c:828
#define WIN_VISTA
Definition: win32.h:298
#define M_FATAL
Definition: error.h:94
bool win32_service_interrupt(struct win32_signal *ws)
Definition: win32.c:619
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:223
#define CLEAR(x)
Definition: basic.h:33
const char * win32_version_string(struct gc_arena *gc, bool add_name)
Definition: win32.c:1443
#define WIN_7
Definition: win32.h:299
void window_title_restore(const struct window_title *wt)
Definition: win32.c:723
#define SIGTERM
Definition: config-msvc.h:118
#define SIGHUP
Definition: config-msvc.h:114
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition: misc.c:564
#define WIN_XP
Definition: win32.h:297
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:895
void close_net_event_win32(struct rw_handle *event, socket_descriptor_t sd, unsigned int flags)
Definition: win32.c:272
static char * env_block(const struct env_set *es)
Definition: win32.c:974
#define SYS_PATH_ENV_VAR_NAME
Definition: win32.h:31
void netcmd_semaphore_lock(void)
Definition: win32.c:860
#define BLOCK_DNS_IFACE_METRIC
Definition: block_dns.h:30
Definition: misc.h:44
bool semaphore_lock(struct semaphore *s, int timeout_milliseconds)
Definition: win32.c:778
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:1213
static HANDLE m_hEngineHandle
Definition: win32.c:60
int iostate
Definition: win32.h:198
#define WSO_FORCE_CONSOLE
Definition: win32.h:163
#define WSO_MODE_CONSOLE
Definition: win32.h:148
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:277
static struct WSAData wsa_state
Definition: win32.c:71
bool console_mode_save_defined
Definition: win32.h:152
struct env_item * list
Definition: misc.h:51
#define NE32_WRITE_EVENT
Definition: win32.h:81
void set_win_sys_path_via_env(struct env_set *es)
Definition: win32.c:1221
void win32_signal_clear(struct win32_signal *ws)
Definition: win32.c:442
static struct gc_arena gc_new(void)
Definition: buffer.h:982
#define IOSTATE_IMMEDIATE_RETURN
Definition: win32.h:197
static unsigned int keyboard_ir_to_key(INPUT_RECORD *ir)
Definition: win32.c:553
int get_interface_metric(const NET_IFINDEX index, const ADDRESS_FAMILY family)
Returns interface metric value for specified interface index.
Definition: block_dns.c:357
char ** argv
Definition: argv.h:38
#define WSO_MODE_UNDEF
Definition: win32.h:146
void init_win32(void)
Definition: win32.c:105
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition: buffer.c:346
void semaphore_clear(struct semaphore *s)
Definition: win32.c:748
#define M_ERR
Definition: error.h:110
#define IOSTATE_QUEUED
Definition: win32.h:196
SECURITY_ATTRIBUTES sa
Definition: win32.h:56
static int socket_defined(const socket_descriptor_t sd)
Definition: syshead.h:494
void overlapped_io_close(struct overlapped_io *o)
Definition: win32.c:184
static SERVICE_STATUS status
Definition: automatic.c:47
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
void net_event_win32_close(struct net_event_win32 *ne)
Definition: win32.c:370
struct env_item * next
Definition: misc.h:46
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
char * string
Definition: misc.h:45
long event_mask
Definition: win32.h:103
bool env_allowed(const char *str)
Definition: misc.c:1301
char * get_win_sys_path(void)
Definition: win32.c:1206
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:1035
uint8_t * data
Pointer to the allocated memory.
Definition: buffer.h:68
#define dmsg
Definition: error.h:174
struct rw_handle in
Definition: win32.h:150
#define SOCKET_UNDEFINED
Definition: syshead.h:486
#define NE32_PERSIST_EVENT
Definition: win32.h:80
char * overlapped_io_state_ascii(const struct overlapped_io *o)
Definition: win32.c:197
struct rw_handle handle
Definition: win32.h:101
bool win_wfp_block_dns(const NET_IFINDEX index, const HANDLE msg_channel)
Definition: win32.c:1323
volatile int source
Definition: sig.h:46
void window_title_save(struct window_title *wt)
Definition: win32.c:706
size_t argc
Definition: argv.h:37
SECURITY_DESCRIPTOR sd
Definition: win32.h:57
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:237
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:1166
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Definition: buffer.c:1019
void set_pause_exit_win32(void)
Definition: win32.c:140
HANDLE write
Definition: win32.h:73
#define D_SEMAPHORE
Definition: errlevel.h:132
volatile int signal_received
Definition: sig.h:45
bool openvpn_execve_allowed(const unsigned int flags)
Definition: misc.c:171
#define SIGUSR2
Definition: config-msvc.h:117
static void check_malloc_return(const void *p)
Definition: buffer.h:1060
void semaphore_release(struct semaphore *s)
Definition: win32.c:812
int mode
Definition: win32.h:149
SOCKET socket_descriptor_t
Definition: syshead.h:487
int openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags)
Definition: win32.c:1089
#define M_NOPREFIX
Definition: error.h:102
long reset_net_event_win32(struct rw_handle *event, socket_descriptor_t sd)
Definition: win32.c:257
#define msg
Definition: error.h:173
static bool net_event_win32_defined(const struct net_event_win32 *ne)
Definition: win32.h:119
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:387
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
#define SCRIPT_SECURITY_WARNING
Definition: common.h:100
bool win_wfp_uninit(const NET_IFINDEX index, const HANDLE msg_channel)
Definition: win32.c:1374
DWORD console_mode_save
Definition: win32.h:151
int win32_version_info(void)
Definition: win32.c:1401
#define WSO_MODE_SERVICE
Definition: win32.h:147
void netcmd_semaphore_release(void)
Definition: win32.c:876
#define IOSTATE_INITIAL
Definition: win32.h:195
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
const char * name
Definition: win32.h:236
HANDLE hand
Definition: win32.h:238
Definition: misc.h:49
void win32_pause(struct win32_signal *ws)
Definition: win32.c:684
void throw_signal(const int signum)
Definition: sig.c:104
#define CC_SPACE
Definition: buffer.h:884
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
message_header_t header
Definition: openvpn-msg.h:110
#define M_ERRNO
Definition: error.h:99
int win32_signal_get(struct win32_signal *ws)
Definition: win32.c:633
#define WIN_8
Definition: win32.h:300
Definition: argv.h:35
bool win32_is_64bit(void)
Definition: win32.c:1429
char old_window_title[256]
Definition: win32.h:68
#define CC_CRLF
Definition: buffer.h:911
#define M_NONFATAL
Definition: error.h:95
void window_title_generate(const char *title)
Definition: win32.c:732
interface_t iface
Definition: openvpn-msg.h:111
#define CC_ANY
Definition: buffer.h:874
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:1305
#define M_WARN
Definition: error.h:96
socket_descriptor_t sd
Definition: win32.h:102
bool saved
Definition: win32.h:67
#define CC_DOUBLE_QUOTE
Definition: buffer.h:899
bool win_safe_filename(const char *fn)
Definition: win32.c:936
void netcmd_semaphore_init(void)
Definition: win32.c:848
#define HANDLE_DEFINED(h)
Definition: win32.h:60
#define SSEC_SCRIPTS
Definition: misc.h:292