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