summaryrefslogtreecommitdiff
path: root/src/openvpn/win32.c
diff options
context:
space:
mode:
authorAlberto Gonzalez Iniesta <agi@inittab.org>2016-12-27 18:25:47 +0100
committerAlberto Gonzalez Iniesta <agi@inittab.org>2016-12-27 18:25:47 +0100
commit3a2bbdb05ca6a6996e424c9fb225cb0d53804125 (patch)
treef29063da5bec4caf3853d49a22a09c8619eebd21 /src/openvpn/win32.c
parentd53dba59e78da865c4fe820386ff2f4f76925f3b (diff)
New upstream version 2.4.0upstream/2.4.0
Diffstat (limited to 'src/openvpn/win32.c')
-rw-r--r--src/openvpn/win32.c1622
1 files changed, 891 insertions, 731 deletions
diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c
index 00bc7ac..e26f54d 100644
--- a/src/openvpn/win32.c
+++ b/src/openvpn/win32.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -97,100 +97,112 @@ struct semaphore netcmd_semaphore; /* GLOBAL */
static char *win_sys_path = NULL; /* GLOBAL */
void
-init_win32 (void)
+init_win32(void)
{
- if (WSAStartup(0x0101, &wsa_state))
+ if (WSAStartup(0x0101, &wsa_state))
{
- msg (M_ERR, "WSAStartup failed");
+ msg(M_ERR, "WSAStartup failed");
}
- window_title_clear (&window_title);
- win32_signal_clear (&win32_signal);
+ window_title_clear(&window_title);
+ win32_signal_clear(&win32_signal);
}
void
-uninit_win32 (void)
+uninit_win32(void)
{
- netcmd_semaphore_close ();
- if (pause_exit_enabled)
- {
- if (win32_signal.mode == WSO_MODE_UNDEF)
- {
- struct win32_signal w;
- win32_signal_open (&w, WSO_FORCE_CONSOLE, NULL, false);
- win32_pause (&w);
- win32_signal_close (&w);
- }
- else
- win32_pause (&win32_signal);
- }
- window_title_restore (&window_title);
- win32_signal_close (&win32_signal);
- WSACleanup ();
- free (win_sys_path);
+ netcmd_semaphore_close();
+ if (pause_exit_enabled)
+ {
+ if (win32_signal.mode == WSO_MODE_UNDEF)
+ {
+ struct win32_signal w;
+ win32_signal_open(&w, WSO_FORCE_CONSOLE, NULL, false);
+ win32_pause(&w);
+ win32_signal_close(&w);
+ }
+ else
+ {
+ win32_pause(&win32_signal);
+ }
+ }
+ window_title_restore(&window_title);
+ win32_signal_close(&win32_signal);
+ WSACleanup();
+ free(win_sys_path);
}
void
-set_pause_exit_win32 (void)
+set_pause_exit_win32(void)
{
- pause_exit_enabled = true;
+ pause_exit_enabled = true;
}
bool
-init_security_attributes_allow_all (struct security_attributes *obj)
+init_security_attributes_allow_all(struct security_attributes *obj)
{
- CLEAR (*obj);
+ CLEAR(*obj);
- obj->sa.nLength = sizeof (SECURITY_ATTRIBUTES);
- obj->sa.lpSecurityDescriptor = &obj->sd;
- obj->sa.bInheritHandle = FALSE;
- if (!InitializeSecurityDescriptor (&obj->sd, SECURITY_DESCRIPTOR_REVISION))
- return false;
- if (!SetSecurityDescriptorDacl (&obj->sd, TRUE, NULL, FALSE))
- return false;
- return true;
+ obj->sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ obj->sa.lpSecurityDescriptor = &obj->sd;
+ obj->sa.bInheritHandle = FALSE;
+ if (!InitializeSecurityDescriptor(&obj->sd, SECURITY_DESCRIPTOR_REVISION))
+ {
+ return false;
+ }
+ if (!SetSecurityDescriptorDacl(&obj->sd, TRUE, NULL, FALSE))
+ {
+ return false;
+ }
+ return true;
}
void
-overlapped_io_init (struct overlapped_io *o,
- const struct frame *frame,
- BOOL event_state,
- bool tuntap_buffer) /* if true: tuntap buffer, if false: socket buffer */
+overlapped_io_init(struct overlapped_io *o,
+ const struct frame *frame,
+ BOOL event_state,
+ bool tuntap_buffer) /* if true: tuntap buffer, if false: socket buffer */
{
- CLEAR (*o);
+ CLEAR(*o);
- /* manual reset event, initially set according to event_state */
- o->overlapped.hEvent = CreateEvent (NULL, TRUE, event_state, NULL);
- if (o->overlapped.hEvent == NULL)
- msg (M_ERR, "Error: overlapped_io_init: CreateEvent failed");
+ /* manual reset event, initially set according to event_state */
+ o->overlapped.hEvent = CreateEvent(NULL, TRUE, event_state, NULL);
+ if (o->overlapped.hEvent == NULL)
+ {
+ msg(M_ERR, "Error: overlapped_io_init: CreateEvent failed");
+ }
- /* allocate buffer for overlapped I/O */
- alloc_buf_sock_tun (&o->buf_init, frame, tuntap_buffer, 0);
+ /* allocate buffer for overlapped I/O */
+ alloc_buf_sock_tun(&o->buf_init, frame, tuntap_buffer, 0);
}
void
-overlapped_io_close (struct overlapped_io *o)
+overlapped_io_close(struct overlapped_io *o)
{
- if (o->overlapped.hEvent)
+ if (o->overlapped.hEvent)
{
- if (!CloseHandle (o->overlapped.hEvent))
- msg (M_WARN | M_ERRNO, "Warning: CloseHandle failed on overlapped I/O event object");
+ if (!CloseHandle(o->overlapped.hEvent))
+ {
+ msg(M_WARN | M_ERRNO, "Warning: CloseHandle failed on overlapped I/O event object");
+ }
}
- free_buf (&o->buf_init);
+ free_buf(&o->buf_init);
}
char *
-overlapped_io_state_ascii (const struct overlapped_io *o)
+overlapped_io_state_ascii(const struct overlapped_io *o)
{
- switch (o->iostate)
+ switch (o->iostate)
{
- case IOSTATE_INITIAL:
- return "0";
- case IOSTATE_QUEUED:
- return "Q";
- case IOSTATE_IMMEDIATE_RETURN:
- return "1";
+ case IOSTATE_INITIAL:
+ return "0";
+
+ case IOSTATE_QUEUED:
+ return "Q";
+
+ case IOSTATE_IMMEDIATE_RETURN:
+ return "1";
}
- return "?";
+ return "?";
}
/*
@@ -198,79 +210,99 @@ overlapped_io_state_ascii (const struct overlapped_io *o)
*/
void
-init_net_event_win32 (struct rw_handle *event, long network_events, socket_descriptor_t sd, unsigned int flags)
+init_net_event_win32(struct rw_handle *event, long network_events, socket_descriptor_t sd, unsigned int flags)
{
- /* manual reset events, initially set to unsignaled */
+ /* manual reset events, initially set to unsignaled */
- /* initialize write event */
- if (!(flags & NE32_PERSIST_EVENT) || !event->write)
+ /* initialize write event */
+ if (!(flags & NE32_PERSIST_EVENT) || !event->write)
{
- if (flags & NE32_WRITE_EVENT)
- {
- event->write = CreateEvent (NULL, TRUE, FALSE, NULL);
- if (event->write == NULL)
- msg (M_ERR, "Error: init_net_event_win32: CreateEvent (write) failed");
- }
- else
- event->write = NULL;
+ if (flags & NE32_WRITE_EVENT)
+ {
+ event->write = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (event->write == NULL)
+ {
+ msg(M_ERR, "Error: init_net_event_win32: CreateEvent (write) failed");
+ }
+ }
+ else
+ {
+ event->write = NULL;
+ }
}
- /* initialize read event */
- if (!(flags & NE32_PERSIST_EVENT) || !event->read)
+ /* initialize read event */
+ if (!(flags & NE32_PERSIST_EVENT) || !event->read)
{
- event->read = CreateEvent (NULL, TRUE, FALSE, NULL);
- if (event->read == NULL)
- msg (M_ERR, "Error: init_net_event_win32: CreateEvent (read) failed");
+ event->read = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (event->read == NULL)
+ {
+ msg(M_ERR, "Error: init_net_event_win32: CreateEvent (read) failed");
+ }
+ }
+
+ /* setup network events to change read event state */
+ if (WSAEventSelect(sd, event->read, network_events) != 0)
+ {
+ msg(M_FATAL | M_ERRNO, "Error: init_net_event_win32: WSAEventSelect call failed");
}
-
- /* setup network events to change read event state */
- if (WSAEventSelect (sd, event->read, network_events) != 0)
- msg (M_FATAL | M_ERRNO, "Error: init_net_event_win32: WSAEventSelect call failed");
}
long
-reset_net_event_win32 (struct rw_handle *event, socket_descriptor_t sd)
+reset_net_event_win32(struct rw_handle *event, socket_descriptor_t sd)
{
- WSANETWORKEVENTS wne;
- if (WSAEnumNetworkEvents (sd, event->read, &wne) != 0)
+ WSANETWORKEVENTS wne;
+ if (WSAEnumNetworkEvents(sd, event->read, &wne) != 0)
+ {
+ msg(M_FATAL | M_ERRNO, "Error: reset_net_event_win32: WSAEnumNetworkEvents call failed");
+ return 0; /* NOTREACHED */
+ }
+ else
{
- msg (M_FATAL | M_ERRNO, "Error: reset_net_event_win32: WSAEnumNetworkEvents call failed");
- return 0; /* NOTREACHED */
+ return wne.lNetworkEvents;
}
- else
- return wne.lNetworkEvents;
}
void
-close_net_event_win32 (struct rw_handle *event, socket_descriptor_t sd, unsigned int flags)
+close_net_event_win32(struct rw_handle *event, socket_descriptor_t sd, unsigned int flags)
{
- if (event->read)
- {
- if (socket_defined (sd))
- {
- if (WSAEventSelect (sd, event->read, 0) != 0)
- msg (M_WARN | M_ERRNO, "Warning: close_net_event_win32: WSAEventSelect call failed");
- }
- if (!ResetEvent (event->read))
- msg (M_WARN | M_ERRNO, "Warning: ResetEvent (read) failed in close_net_event_win32");
- if (!(flags & NE32_PERSIST_EVENT))
- {
- if (!CloseHandle (event->read))
- msg (M_WARN | M_ERRNO, "Warning: CloseHandle (read) failed in close_net_event_win32");
- event->read = NULL;
- }
- }
-
- if (event->write)
- {
- if (!ResetEvent (event->write))
- msg (M_WARN | M_ERRNO, "Warning: ResetEvent (write) failed in close_net_event_win32");
- if (!(flags & NE32_PERSIST_EVENT))
- {
- if (!CloseHandle (event->write))
- msg (M_WARN | M_ERRNO, "Warning: CloseHandle (write) failed in close_net_event_win32");
- event->write = NULL;
- }
+ if (event->read)
+ {
+ if (socket_defined(sd))
+ {
+ if (WSAEventSelect(sd, event->read, 0) != 0)
+ {
+ msg(M_WARN | M_ERRNO, "Warning: close_net_event_win32: WSAEventSelect call failed");
+ }
+ }
+ if (!ResetEvent(event->read))
+ {
+ msg(M_WARN | M_ERRNO, "Warning: ResetEvent (read) failed in close_net_event_win32");
+ }
+ if (!(flags & NE32_PERSIST_EVENT))
+ {
+ if (!CloseHandle(event->read))
+ {
+ msg(M_WARN | M_ERRNO, "Warning: CloseHandle (read) failed in close_net_event_win32");
+ }
+ event->read = NULL;
+ }
+ }
+
+ if (event->write)
+ {
+ if (!ResetEvent(event->write))
+ {
+ msg(M_WARN | M_ERRNO, "Warning: ResetEvent (write) failed in close_net_event_win32");
+ }
+ if (!(flags & NE32_PERSIST_EVENT))
+ {
+ if (!CloseHandle(event->write))
+ {
+ msg(M_WARN | M_ERRNO, "Warning: CloseHandle (write) failed in close_net_event_win32");
+ }
+ event->write = NULL;
+ }
}
}
@@ -279,54 +311,64 @@ close_net_event_win32 (struct rw_handle *event, socket_descriptor_t sd, unsigned
*/
void
-net_event_win32_init (struct net_event_win32 *ne)
+net_event_win32_init(struct net_event_win32 *ne)
{
- CLEAR (*ne);
- ne->sd = SOCKET_UNDEFINED;
+ CLEAR(*ne);
+ ne->sd = SOCKET_UNDEFINED;
}
void
-net_event_win32_start (struct net_event_win32 *ne, long network_events, socket_descriptor_t sd)
+net_event_win32_start(struct net_event_win32 *ne, long network_events, socket_descriptor_t sd)
{
- ASSERT (!socket_defined (ne->sd));
- ne->sd = sd;
- ne->event_mask = 0;
- init_net_event_win32 (&ne->handle, network_events, sd, NE32_PERSIST_EVENT|NE32_WRITE_EVENT);
+ ASSERT(!socket_defined(ne->sd));
+ ne->sd = sd;
+ ne->event_mask = 0;
+ init_net_event_win32(&ne->handle, network_events, sd, NE32_PERSIST_EVENT|NE32_WRITE_EVENT);
}
void
-net_event_win32_reset_write (struct net_event_win32 *ne)
+net_event_win32_reset_write(struct net_event_win32 *ne)
{
- BOOL status;
- if (ne->event_mask & FD_WRITE)
- status = SetEvent (ne->handle.write);
- else
- status = ResetEvent (ne->handle.write);
- if (!status)
- msg (M_WARN | M_ERRNO, "Warning: SetEvent/ResetEvent failed in net_event_win32_reset_write");
+ BOOL status;
+ if (ne->event_mask & FD_WRITE)
+ {
+ status = SetEvent(ne->handle.write);
+ }
+ else
+ {
+ status = ResetEvent(ne->handle.write);
+ }
+ if (!status)
+ {
+ msg(M_WARN | M_ERRNO, "Warning: SetEvent/ResetEvent failed in net_event_win32_reset_write");
+ }
}
void
-net_event_win32_reset (struct net_event_win32 *ne)
+net_event_win32_reset(struct net_event_win32 *ne)
{
- ne->event_mask |= reset_net_event_win32 (&ne->handle, ne->sd);
+ ne->event_mask |= reset_net_event_win32(&ne->handle, ne->sd);
}
void
-net_event_win32_stop (struct net_event_win32 *ne)
+net_event_win32_stop(struct net_event_win32 *ne)
{
- if (net_event_win32_defined (ne))
- close_net_event_win32 (&ne->handle, ne->sd, NE32_PERSIST_EVENT);
- ne->sd = SOCKET_UNDEFINED;
- ne->event_mask = 0;
+ if (net_event_win32_defined(ne))
+ {
+ close_net_event_win32(&ne->handle, ne->sd, NE32_PERSIST_EVENT);
+ }
+ ne->sd = SOCKET_UNDEFINED;
+ ne->event_mask = 0;
}
void
-net_event_win32_close (struct net_event_win32 *ne)
+net_event_win32_close(struct net_event_win32 *ne)
{
- if (net_event_win32_defined (ne))
- close_net_event_win32 (&ne->handle, ne->sd, 0);
- net_event_win32_init (ne);
+ if (net_event_win32_defined(ne))
+ {
+ close_net_event_win32(&ne->handle, ne->sd, 0);
+ }
+ net_event_win32_init(ne);
}
/*
@@ -340,19 +382,23 @@ net_event_win32_close (struct net_event_win32 *ne)
static void
win_trigger_event(struct win32_signal *ws)
{
- if (ws->mode == WSO_MODE_SERVICE && HANDLE_DEFINED(ws->in.read))
- SetEvent (ws->in.read);
- else /* generate a key-press event */
+ if (ws->mode == WSO_MODE_SERVICE && HANDLE_DEFINED(ws->in.read))
{
- DWORD tmp;
- INPUT_RECORD ir;
- HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
-
- CLEAR(ir);
- ir.EventType = KEY_EVENT;
- ir.Event.KeyEvent.bKeyDown = true;
- if (!stdin_handle || !WriteConsoleInput(stdin_handle, &ir, 1, &tmp))
- msg(M_WARN|M_ERRNO, "WARN: win_trigger_event: WriteConsoleInput");
+ SetEvent(ws->in.read);
+ }
+ else /* generate a key-press event */
+ {
+ DWORD tmp;
+ INPUT_RECORD ir;
+ HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
+
+ CLEAR(ir);
+ ir.EventType = KEY_EVENT;
+ ir.Event.KeyEvent.bKeyDown = true;
+ if (!stdin_handle || !WriteConsoleInput(stdin_handle, &ir, 1, &tmp))
+ {
+ msg(M_WARN|M_ERRNO, "WARN: win_trigger_event: WriteConsoleInput");
+ }
}
}
@@ -360,372 +406,429 @@ win_trigger_event(struct win32_signal *ws)
* Callback to handle console ctrl events
*/
static bool WINAPI
-win_ctrl_handler (DWORD signum)
+win_ctrl_handler(DWORD signum)
{
- msg(D_LOW, "win_ctrl_handler: signal received (code=%lu)", (unsigned long) signum);
-
- if (siginfo_static.signal_received == SIGTERM)
- return true;
-
- switch (signum)
- {
- case CTRL_C_EVENT:
- case CTRL_BREAK_EVENT:
- throw_signal(SIGTERM);
- /* trigget the win32_signal to interrupt the event loop */
- win_trigger_event(&win32_signal);
- return true;
- break;
- default:
- msg(D_LOW, "win_ctrl_handler: signal (code=%lu) not handled", (unsigned long) signum);
- break;
- }
- /* pass all other signals to the next handler */
- return false;
+ msg(D_LOW, "win_ctrl_handler: signal received (code=%lu)", (unsigned long) signum);
+
+ if (siginfo_static.signal_received == SIGTERM)
+ {
+ return true;
+ }
+
+ switch (signum)
+ {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ throw_signal(SIGTERM);
+ /* trigget the win32_signal to interrupt the event loop */
+ win_trigger_event(&win32_signal);
+ return true;
+ break;
+
+ default:
+ msg(D_LOW, "win_ctrl_handler: signal (code=%lu) not handled", (unsigned long) signum);
+ break;
+ }
+ /* pass all other signals to the next handler */
+ return false;
}
void
-win32_signal_clear (struct win32_signal *ws)
+win32_signal_clear(struct win32_signal *ws)
{
- CLEAR (*ws);
+ CLEAR(*ws);
}
void
-win32_signal_open (struct win32_signal *ws,
- int force,
- const char *exit_event_name,
- bool exit_event_initial_state)
+win32_signal_open(struct win32_signal *ws,
+ int force,
+ const char *exit_event_name,
+ bool exit_event_initial_state)
{
- CLEAR (*ws);
-
- ws->mode = WSO_MODE_UNDEF;
- ws->in.read = INVALID_HANDLE_VALUE;
- ws->in.write = INVALID_HANDLE_VALUE;
- ws->console_mode_save = 0;
- ws->console_mode_save_defined = false;
-
- if (force == WSO_NOFORCE || force == WSO_FORCE_CONSOLE)
- {
- /*
- * Try to open console.
- */
- ws->in.read = GetStdHandle (STD_INPUT_HANDLE);
- if (ws->in.read != INVALID_HANDLE_VALUE)
- {
- if (GetConsoleMode (ws->in.read, &ws->console_mode_save))
- {
- /* running on a console */
- const DWORD new_console_mode = ws->console_mode_save
- & ~(ENABLE_WINDOW_INPUT
- | ENABLE_PROCESSED_INPUT
- | ENABLE_LINE_INPUT
- | ENABLE_ECHO_INPUT
- | ENABLE_MOUSE_INPUT);
-
- if (new_console_mode != ws->console_mode_save)
- {
- if (!SetConsoleMode (ws->in.read, new_console_mode))
- msg (M_ERR, "Error: win32_signal_open: SetConsoleMode failed");
- ws->console_mode_save_defined = true;
- }
- ws->mode = WSO_MODE_CONSOLE;
- }
- else
- ws->in.read = INVALID_HANDLE_VALUE; /* probably running as a service */
- }
- }
-
- /*
- * If console open failed, assume we are running
- * as a service.
- */
- if ((force == WSO_NOFORCE || force == WSO_FORCE_SERVICE)
- && !HANDLE_DEFINED (ws->in.read) && exit_event_name)
- {
- struct security_attributes sa;
-
- if (!init_security_attributes_allow_all (&sa))
- msg (M_ERR, "Error: win32_signal_open: init SA failed");
-
- ws->in.read = CreateEvent (&sa.sa,
- TRUE,
- exit_event_initial_state ? TRUE : FALSE,
- exit_event_name);
- if (ws->in.read == NULL)
- {
- msg (M_WARN|M_ERRNO, "NOTE: CreateEvent '%s' failed", exit_event_name);
- }
- else
- {
- if (WaitForSingleObject (ws->in.read, 0) != WAIT_TIMEOUT)
- msg (M_FATAL, "ERROR: Exit Event ('%s') is signaled", exit_event_name);
- else
- ws->mode = WSO_MODE_SERVICE;
- }
+ CLEAR(*ws);
+
+ ws->mode = WSO_MODE_UNDEF;
+ ws->in.read = INVALID_HANDLE_VALUE;
+ ws->in.write = INVALID_HANDLE_VALUE;
+ ws->console_mode_save = 0;
+ ws->console_mode_save_defined = false;
+
+ if (force == WSO_NOFORCE || force == WSO_FORCE_CONSOLE)
+ {
+ /*
+ * Try to open console.
+ */
+ ws->in.read = GetStdHandle(STD_INPUT_HANDLE);
+ if (ws->in.read != INVALID_HANDLE_VALUE)
+ {
+ if (GetConsoleMode(ws->in.read, &ws->console_mode_save))
+ {
+ /* running on a console */
+ const DWORD new_console_mode = ws->console_mode_save
+ & ~(ENABLE_WINDOW_INPUT
+ | ENABLE_PROCESSED_INPUT
+ | ENABLE_LINE_INPUT
+ | ENABLE_ECHO_INPUT
+ | ENABLE_MOUSE_INPUT);
+
+ if (new_console_mode != ws->console_mode_save)
+ {
+ if (!SetConsoleMode(ws->in.read, new_console_mode))
+ {
+ msg(M_ERR, "Error: win32_signal_open: SetConsoleMode failed");
+ }
+ ws->console_mode_save_defined = true;
+ }
+ ws->mode = WSO_MODE_CONSOLE;
+ }
+ else
+ {
+ ws->in.read = INVALID_HANDLE_VALUE; /* probably running as a service */
+ }
+ }
+ }
+
+ /*
+ * If console open failed, assume we are running
+ * as a service.
+ */
+ if ((force == WSO_NOFORCE || force == WSO_FORCE_SERVICE)
+ && !HANDLE_DEFINED(ws->in.read) && exit_event_name)
+ {
+ struct security_attributes sa;
+
+ if (!init_security_attributes_allow_all(&sa))
+ {
+ msg(M_ERR, "Error: win32_signal_open: init SA failed");
+ }
+
+ ws->in.read = CreateEvent(&sa.sa,
+ TRUE,
+ exit_event_initial_state ? TRUE : FALSE,
+ exit_event_name);
+ if (ws->in.read == NULL)
+ {
+ msg(M_WARN|M_ERRNO, "NOTE: CreateEvent '%s' failed", exit_event_name);
+ }
+ else
+ {
+ if (WaitForSingleObject(ws->in.read, 0) != WAIT_TIMEOUT)
+ {
+ msg(M_FATAL, "ERROR: Exit Event ('%s') is signaled", exit_event_name);
+ }
+ else
+ {
+ ws->mode = WSO_MODE_SERVICE;
+ }
+ }
}
/* set the ctrl handler in both console and service modes */
- if (!SetConsoleCtrlHandler ((PHANDLER_ROUTINE) win_ctrl_handler, true))
- msg (M_WARN|M_ERRNO, "WARN: SetConsoleCtrlHandler failed");
+ if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE) win_ctrl_handler, true))
+ {
+ msg(M_WARN|M_ERRNO, "WARN: SetConsoleCtrlHandler failed");
+ }
}
static bool
-keyboard_input_available (struct win32_signal *ws)
+keyboard_input_available(struct win32_signal *ws)
{
- ASSERT (ws->mode == WSO_MODE_CONSOLE);
- if (HANDLE_DEFINED (ws->in.read))
+ ASSERT(ws->mode == WSO_MODE_CONSOLE);
+ if (HANDLE_DEFINED(ws->in.read))
{
- DWORD n;
- if (GetNumberOfConsoleInputEvents (ws->in.read, &n))
- return n > 0;
+ DWORD n;
+ if (GetNumberOfConsoleInputEvents(ws->in.read, &n))
+ {
+ return n > 0;
+ }
}
- return false;
+ return false;
}
static unsigned int
-keyboard_ir_to_key (INPUT_RECORD *ir)
+keyboard_ir_to_key(INPUT_RECORD *ir)
{
- if (ir->Event.KeyEvent.uChar.AsciiChar == 0)
- return ir->Event.KeyEvent.wVirtualScanCode;
+ if (ir->Event.KeyEvent.uChar.AsciiChar == 0)
+ {
+ return ir->Event.KeyEvent.wVirtualScanCode;
+ }
- if ((ir->Event.KeyEvent.dwControlKeyState
- & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
- && (ir->Event.KeyEvent.wVirtualKeyCode != 18))
- return ir->Event.KeyEvent.wVirtualScanCode * 256;
+ if ((ir->Event.KeyEvent.dwControlKeyState
+ & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
+ && (ir->Event.KeyEvent.wVirtualKeyCode != 18))
+ {
+ return ir->Event.KeyEvent.wVirtualScanCode * 256;
+ }
- return ir->Event.KeyEvent.uChar.AsciiChar;
+ return ir->Event.KeyEvent.uChar.AsciiChar;
}
static unsigned int
-win32_keyboard_get (struct win32_signal *ws)
+win32_keyboard_get(struct win32_signal *ws)
{
- ASSERT (ws->mode == WSO_MODE_CONSOLE);
- if (HANDLE_DEFINED (ws->in.read))
- {
- INPUT_RECORD ir;
- do {
- DWORD n;
- if (!keyboard_input_available (ws))
- return 0;
- if (!ReadConsoleInput (ws->in.read, &ir, 1, &n))
- return 0;
- } while (ir.EventType != KEY_EVENT || ir.Event.KeyEvent.bKeyDown != TRUE);
-
- return keyboard_ir_to_key (&ir);
- }
- else
- return 0;
+ ASSERT(ws->mode == WSO_MODE_CONSOLE);
+ if (HANDLE_DEFINED(ws->in.read))
+ {
+ INPUT_RECORD ir;
+ do {
+ DWORD n;
+ if (!keyboard_input_available(ws))
+ {
+ return 0;
+ }
+ if (!ReadConsoleInput(ws->in.read, &ir, 1, &n))
+ {
+ return 0;
+ }
+ } while (ir.EventType != KEY_EVENT || ir.Event.KeyEvent.bKeyDown != TRUE);
+
+ return keyboard_ir_to_key(&ir);
+ }
+ else
+ {
+ return 0;
+ }
}
void
-win32_signal_close (struct win32_signal *ws)
+win32_signal_close(struct win32_signal *ws)
{
- if (ws->mode == WSO_MODE_SERVICE && HANDLE_DEFINED (ws->in.read))
- CloseHandle (ws->in.read);
- if (ws->console_mode_save_defined)
+ if (ws->mode == WSO_MODE_SERVICE && HANDLE_DEFINED(ws->in.read))
{
- if (!SetConsoleMode (ws->in.read, ws->console_mode_save))
- msg (M_ERR, "Error: win32_signal_close: SetConsoleMode failed");
+ CloseHandle(ws->in.read);
}
- CLEAR (*ws);
+ if (ws->console_mode_save_defined)
+ {
+ if (!SetConsoleMode(ws->in.read, ws->console_mode_save))
+ {
+ msg(M_ERR, "Error: win32_signal_close: SetConsoleMode failed");
+ }
+ }
+ CLEAR(*ws);
}
/*
* Return true if interrupt occurs in service mode.
*/
bool
-win32_service_interrupt (struct win32_signal *ws)
+win32_service_interrupt(struct win32_signal *ws)
{
- if (ws->mode == WSO_MODE_SERVICE)
+ if (ws->mode == WSO_MODE_SERVICE)
{
- if (HANDLE_DEFINED (ws->in.read)
- && WaitForSingleObject (ws->in.read, 0) == WAIT_OBJECT_0)
- return true;
+ if (HANDLE_DEFINED(ws->in.read)
+ && WaitForSingleObject(ws->in.read, 0) == WAIT_OBJECT_0)
+ {
+ return true;
+ }
}
- return false;
+ return false;
}
int
-win32_signal_get (struct win32_signal *ws)
+win32_signal_get(struct win32_signal *ws)
{
- int ret = 0;
- if (siginfo_static.signal_received)
- {
- ret = siginfo_static.signal_received;
- }
- else
- {
- if (ws->mode == WSO_MODE_SERVICE)
- {
- if (win32_service_interrupt (ws))
- ret = SIGTERM;
- }
- else if (ws->mode == WSO_MODE_CONSOLE)
- {
- switch (win32_keyboard_get (ws))
- {
- case 0x3B: /* F1 -> USR1 */
- ret = SIGUSR1;
- break;
- case 0x3C: /* F2 -> USR2 */
- ret = SIGUSR2;
- break;
- case 0x3D: /* F3 -> HUP */
- ret = SIGHUP;
- break;
- case 0x3E: /* F4 -> TERM */
- ret = SIGTERM;
- break;
- case 0x03: /* CTRL-C -> TERM */
- ret = SIGTERM;
- break;
- }
- }
- if (ret)
- {
- siginfo_static.signal_received = ret;
- siginfo_static.source = SIG_SOURCE_HARD;
- }
- }
- return ret;
+ int ret = 0;
+ if (siginfo_static.signal_received)
+ {
+ ret = siginfo_static.signal_received;
+ }
+ else
+ {
+ if (ws->mode == WSO_MODE_SERVICE)
+ {
+ if (win32_service_interrupt(ws))
+ {
+ ret = SIGTERM;
+ }
+ }
+ else if (ws->mode == WSO_MODE_CONSOLE)
+ {
+ switch (win32_keyboard_get(ws))
+ {
+ case 0x3B: /* F1 -> USR1 */
+ ret = SIGUSR1;
+ break;
+
+ case 0x3C: /* F2 -> USR2 */
+ ret = SIGUSR2;
+ break;
+
+ case 0x3D: /* F3 -> HUP */
+ ret = SIGHUP;
+ break;
+
+ case 0x3E: /* F4 -> TERM */
+ ret = SIGTERM;
+ break;
+
+ case 0x03: /* CTRL-C -> TERM */
+ ret = SIGTERM;
+ break;
+ }
+ }
+ if (ret)
+ {
+ siginfo_static.signal_received = ret;
+ siginfo_static.source = SIG_SOURCE_HARD;
+ }
+ }
+ return ret;
}
void
-win32_pause (struct win32_signal *ws)
+win32_pause(struct win32_signal *ws)
{
- if (ws->mode == WSO_MODE_CONSOLE && HANDLE_DEFINED (ws->in.read))
+ if (ws->mode == WSO_MODE_CONSOLE && HANDLE_DEFINED(ws->in.read))
{
- int status;
- msg (M_INFO|M_NOPREFIX, "Press any key to continue...");
- do {
- status = WaitForSingleObject (ws->in.read, INFINITE);
- } while (!win32_keyboard_get (ws));
+ int status;
+ msg(M_INFO|M_NOPREFIX, "Press any key to continue...");
+ do {
+ status = WaitForSingleObject(ws->in.read, INFINITE);
+ } while (!win32_keyboard_get(ws));
}
}
/* window functions */
void
-window_title_clear (struct window_title *wt)
+window_title_clear(struct window_title *wt)
{
- CLEAR (*wt);
+ CLEAR(*wt);
}
void
-window_title_save (struct window_title *wt)
+window_title_save(struct window_title *wt)
{
- if (!wt->saved)
+ if (!wt->saved)
{
- if (!GetConsoleTitle (wt->old_window_title, sizeof (wt->old_window_title)))
- {
- wt->old_window_title[0] = 0;
- wt->saved = false;
- }
- else
- wt->saved = true;
+ if (!GetConsoleTitle(wt->old_window_title, sizeof(wt->old_window_title)))
+ {
+ wt->old_window_title[0] = 0;
+ wt->saved = false;
+ }
+ else
+ {
+ wt->saved = true;
+ }
}
}
void
-window_title_restore (const struct window_title *wt)
+window_title_restore(const struct window_title *wt)
{
- if (wt->saved)
- SetConsoleTitle (wt->old_window_title);
+ if (wt->saved)
+ {
+ SetConsoleTitle(wt->old_window_title);
+ }
}
void
-window_title_generate (const char *title)
+window_title_generate(const char *title)
{
- struct gc_arena gc = gc_new ();
- struct buffer out = alloc_buf_gc (256, &gc);
- if (!title)
- title = "";
- buf_printf (&out, "[%s] " PACKAGE_NAME " " PACKAGE_VERSION " F4:EXIT F1:USR1 F2:USR2 F3:HUP", title);
- SetConsoleTitle (BSTR (&out));
- gc_free (&gc);
+ struct gc_arena gc = gc_new();
+ struct buffer out = alloc_buf_gc(256, &gc);
+ if (!title)
+ {
+ title = "";
+ }
+ buf_printf(&out, "[%s] " PACKAGE_NAME " " PACKAGE_VERSION " F4:EXIT F1:USR1 F2:USR2 F3:HUP", title);
+ SetConsoleTitle(BSTR(&out));
+ gc_free(&gc);
}
/* semaphore functions */
void
-semaphore_clear (struct semaphore *s)
+semaphore_clear(struct semaphore *s)
{
- CLEAR (*s);
+ CLEAR(*s);
}
void
-semaphore_open (struct semaphore *s, const char *name)
+semaphore_open(struct semaphore *s, const char *name)
{
- struct security_attributes sa;
+ struct security_attributes sa;
- s->locked = false;
- s->name = name;
- s->hand = NULL;
+ s->locked = false;
+ s->name = name;
+ s->hand = NULL;
- if (init_security_attributes_allow_all (&sa))
- s->hand = CreateSemaphore(&sa.sa, 1, 1, name);
+ if (init_security_attributes_allow_all(&sa))
+ {
+ s->hand = CreateSemaphore(&sa.sa, 1, 1, name);
+ }
- if (s->hand == NULL)
- msg (M_WARN|M_ERRNO, "WARNING: Cannot create Win32 semaphore '%s'", name);
- else
- dmsg (D_SEMAPHORE, "Created Win32 semaphore '%s'", s->name);
+ if (s->hand == NULL)
+ {
+ msg(M_WARN|M_ERRNO, "WARNING: Cannot create Win32 semaphore '%s'", name);
+ }
+ else
+ {
+ dmsg(D_SEMAPHORE, "Created Win32 semaphore '%s'", s->name);
+ }
}
bool
-semaphore_lock (struct semaphore *s, int timeout_milliseconds)
+semaphore_lock(struct semaphore *s, int timeout_milliseconds)
{
- bool ret = true;
-
- if (s->hand)
- {
- DWORD status;
- ASSERT (!s->locked);
-
- dmsg (D_SEMAPHORE_LOW, "Attempting to lock Win32 semaphore '%s' prior to net shell command (timeout = %d sec)",
- s->name,
- timeout_milliseconds / 1000);
- status = WaitForSingleObject (s->hand, timeout_milliseconds);
- if (status == WAIT_FAILED)
- msg (M_ERR, "Wait failed on Win32 semaphore '%s'", s->name);
- ret = (status == WAIT_TIMEOUT) ? false : true;
- if (ret)
- {
- dmsg (D_SEMAPHORE, "Locked Win32 semaphore '%s'", s->name);
- s->locked = true;
- }
- else
- {
- dmsg (D_SEMAPHORE, "Wait on Win32 semaphore '%s' timed out after %d milliseconds",
- s->name,
- timeout_milliseconds);
- }
- }
- return ret;
+ bool ret = true;
+
+ if (s->hand)
+ {
+ DWORD status;
+ ASSERT(!s->locked);
+
+ dmsg(D_SEMAPHORE_LOW, "Attempting to lock Win32 semaphore '%s' prior to net shell command (timeout = %d sec)",
+ s->name,
+ timeout_milliseconds / 1000);
+ status = WaitForSingleObject(s->hand, timeout_milliseconds);
+ if (status == WAIT_FAILED)
+ {
+ msg(M_ERR, "Wait failed on Win32 semaphore '%s'", s->name);
+ }
+ ret = (status == WAIT_TIMEOUT) ? false : true;
+ if (ret)
+ {
+ dmsg(D_SEMAPHORE, "Locked Win32 semaphore '%s'", s->name);
+ s->locked = true;
+ }
+ else
+ {
+ dmsg(D_SEMAPHORE, "Wait on Win32 semaphore '%s' timed out after %d milliseconds",
+ s->name,
+ timeout_milliseconds);
+ }
+ }
+ return ret;
}
void
-semaphore_release (struct semaphore *s)
+semaphore_release(struct semaphore *s)
{
- if (s->hand)
+ if (s->hand)
{
- ASSERT (s->locked);
- dmsg (D_SEMAPHORE, "Releasing Win32 semaphore '%s'", s->name);
- if (!ReleaseSemaphore(s->hand, 1, NULL))
- msg (M_WARN | M_ERRNO, "ReleaseSemaphore failed on Win32 semaphore '%s'",
- s->name);
- s->locked = false;
+ ASSERT(s->locked);
+ dmsg(D_SEMAPHORE, "Releasing Win32 semaphore '%s'", s->name);
+ if (!ReleaseSemaphore(s->hand, 1, NULL))
+ {
+ msg(M_WARN | M_ERRNO, "ReleaseSemaphore failed on Win32 semaphore '%s'",
+ s->name);
+ }
+ s->locked = false;
}
}
void
-semaphore_close (struct semaphore *s)
+semaphore_close(struct semaphore *s)
{
- if (s->hand)
+ if (s->hand)
{
- if (s->locked)
- semaphore_release (s);
- dmsg (D_SEMAPHORE, "Closing Win32 semaphore '%s'", s->name);
- CloseHandle (s->hand);
- s->hand = NULL;
+ if (s->locked)
+ {
+ semaphore_release(s);
+ }
+ dmsg(D_SEMAPHORE, "Closing Win32 semaphore '%s'", s->name);
+ CloseHandle(s->hand);
+ s->hand = NULL;
}
}
@@ -735,35 +838,39 @@ semaphore_close (struct semaphore *s)
*/
void
-netcmd_semaphore_init (void)
+netcmd_semaphore_init(void)
{
- semaphore_open (&netcmd_semaphore, PACKAGE "_netcmd");
+ semaphore_open(&netcmd_semaphore, PACKAGE "_netcmd");
}
void
-netcmd_semaphore_close (void)
+netcmd_semaphore_close(void)
{
- semaphore_close (&netcmd_semaphore);
+ semaphore_close(&netcmd_semaphore);
}
void
-netcmd_semaphore_lock (void)
+netcmd_semaphore_lock(void)
{
- const int timeout_seconds = 600;
+ const int timeout_seconds = 600;
- if (!netcmd_semaphore.hand)
- netcmd_semaphore_init ();
+ if (!netcmd_semaphore.hand)
+ {
+ netcmd_semaphore_init();
+ }
- if (!semaphore_lock (&netcmd_semaphore, timeout_seconds * 1000))
- msg (M_FATAL, "Cannot lock net command semaphore");
+ if (!semaphore_lock(&netcmd_semaphore, timeout_seconds * 1000))
+ {
+ msg(M_FATAL, "Cannot lock net command semaphore");
+ }
}
void
-netcmd_semaphore_release (void)
+netcmd_semaphore_release(void)
{
- semaphore_release (&netcmd_semaphore);
- /* netcmd_semaphore has max count of 1 - safe to close after release */
- semaphore_close (&netcmd_semaphore);
+ semaphore_release(&netcmd_semaphore);
+ /* netcmd_semaphore has max count of 1 - safe to close after release */
+ semaphore_close(&netcmd_semaphore);
}
/*
@@ -778,54 +885,78 @@ netcmd_semaphore_release (void)
*/
static bool
-cmp_prefix (const char *str, const bool n, const char *pre)
+cmp_prefix(const char *str, const bool n, const char *pre)
{
- size_t i = 0;
+ size_t i = 0;
- if (!str)
- return false;
+ if (!str)
+ {
+ return false;
+ }
- while (true)
- {
- const int c1 = pre[i];
- int c2 = str[i];
- ++i;
- if (c1 == '\0')
- {
- if (n)
- {
- if (isdigit (c2))
- c2 = str[i];
- else
- return false;
- }
- return c2 == '\0' || c2 == '.';
- }
- else if (c2 == '\0')
- return false;
- if (c1 != tolower(c2))
- return false;
+ while (true)
+ {
+ const int c1 = pre[i];
+ int c2 = str[i];
+ ++i;
+ if (c1 == '\0')
+ {
+ if (n)
+ {
+ if (isdigit(c2))
+ {
+ c2 = str[i];
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return c2 == '\0' || c2 == '.';
+ }
+ else if (c2 == '\0')
+ {
+ return false;
+ }
+ if (c1 != tolower(c2))
+ {
+ return false;
+ }
}
}
bool
-win_safe_filename (const char *fn)
+win_safe_filename(const char *fn)
{
- if (cmp_prefix (fn, false, "con"))
- return false;
- if (cmp_prefix (fn, false, "prn"))
- return false;
- if (cmp_prefix (fn, false, "aux"))
- return false;
- if (cmp_prefix (fn, false, "nul"))
- return false;
- if (cmp_prefix (fn, true, "com"))
- return false;
- if (cmp_prefix (fn, true, "lpt"))
- return false;
- if (cmp_prefix (fn, false, "clock$"))
- return false;
- return true;
+ if (cmp_prefix(fn, false, "con"))
+ {
+ return false;
+ }
+ if (cmp_prefix(fn, false, "prn"))
+ {
+ return false;
+ }
+ if (cmp_prefix(fn, false, "aux"))
+ {
+ return false;
+ }
+ if (cmp_prefix(fn, false, "nul"))
+ {
+ return false;
+ }
+ if (cmp_prefix(fn, true, "com"))
+ {
+ return false;
+ }
+ if (cmp_prefix(fn, true, "lpt"))
+ {
+ return false;
+ }
+ if (cmp_prefix(fn, false, "clock$"))
+ {
+ return false;
+ }
+ return true;
}
/*
@@ -833,372 +964,397 @@ win_safe_filename (const char *fn)
*/
static char *
-env_block (const struct env_set *es)
+env_block(const struct env_set *es)
{
- char force_path[256];
- char *sysroot = get_win_sys_path();
-
- if (!openvpn_snprintf(force_path, sizeof(force_path), "PATH=%s\\System32;%s;%s\\System32\\Wbem",
- sysroot, sysroot, sysroot))
- msg(M_WARN, "env_block: default path truncated to %s", force_path);
-
- if (es)
- {
- struct env_item *e;
- char *ret;
- char *p;
- size_t nchars = 1;
- bool path_seen = false;
-
- for (e = es->list; e != NULL; e = e->next)
- nchars += strlen (e->string) + 1;
-
- nchars += strlen(force_path)+1;
-
- ret = (char *) malloc (nchars);
- check_malloc_return (ret);
-
- p = ret;
- for (e = es->list; e != NULL; e = e->next)
- {
- if (env_allowed (e->string))
- {
- strcpy (p, e->string);
- p += strlen (e->string) + 1;
- }
- if ( strncmp(e->string, "PATH=", 5 ) == 0 )
- path_seen = true;
- }
-
- /* make sure PATH is set */
- if ( !path_seen )
- {
- msg( M_INFO, "env_block: add %s", force_path );
- strcpy( p, force_path );
- p += strlen(force_path) + 1;
- }
-
- *p = '\0';
- return ret;
- }
- else
- return NULL;
+ char force_path[256];
+ char *sysroot = get_win_sys_path();
+
+ if (!openvpn_snprintf(force_path, sizeof(force_path), "PATH=%s\\System32;%s;%s\\System32\\Wbem",
+ sysroot, sysroot, sysroot))
+ {
+ msg(M_WARN, "env_block: default path truncated to %s", force_path);
+ }
+
+ if (es)
+ {
+ struct env_item *e;
+ char *ret;
+ char *p;
+ size_t nchars = 1;
+ bool path_seen = false;
+
+ for (e = es->list; e != NULL; e = e->next)
+ nchars += strlen(e->string) + 1;
+
+ nchars += strlen(force_path)+1;
+
+ ret = (char *) malloc(nchars);
+ check_malloc_return(ret);
+
+ p = ret;
+ for (e = es->list; e != NULL; e = e->next)
+ {
+ if (env_allowed(e->string))
+ {
+ strcpy(p, e->string);
+ p += strlen(e->string) + 1;
+ }
+ if (strncmp(e->string, "PATH=", 5 ) == 0)
+ {
+ path_seen = true;
+ }
+ }
+
+ /* make sure PATH is set */
+ if (!path_seen)
+ {
+ msg( M_INFO, "env_block: add %s", force_path );
+ strcpy( p, force_path );
+ p += strlen(force_path) + 1;
+ }
+
+ *p = '\0';
+ return ret;
+ }
+ else
+ {
+ return NULL;
+ }
}
static WCHAR *
-wide_cmd_line (const struct argv *a, struct gc_arena *gc)
+wide_cmd_line(const struct argv *a, struct gc_arena *gc)
{
- size_t nchars = 1;
- size_t maxlen = 0;
- size_t i;
- struct buffer buf;
- char *work = NULL;
+ size_t nchars = 1;
+ size_t maxlen = 0;
+ size_t i;
+ struct buffer buf;
+ char *work = NULL;
- if (!a)
- return NULL;
+ if (!a)
+ {
+ return NULL;
+ }
- for (i = 0; i < a->argc; ++i)
+ for (i = 0; i < a->argc; ++i)
{
- const char *arg = a->argv[i];
- const size_t len = strlen (arg);
- nchars += len + 3;
- if (len > maxlen)
- maxlen = len;
+ const char *arg = a->argv[i];
+ const size_t len = strlen(arg);
+ nchars += len + 3;
+ if (len > maxlen)
+ {
+ maxlen = len;
+ }
}
- work = gc_malloc (maxlen + 1, false, gc);
- check_malloc_return (work);
- buf = alloc_buf_gc (nchars, gc);
+ work = gc_malloc(maxlen + 1, false, gc);
+ check_malloc_return(work);
+ buf = alloc_buf_gc(nchars, gc);
- for (i = 0; i < a->argc; ++i)
+ for (i = 0; i < a->argc; ++i)
{
- const char *arg = a->argv[i];
- strcpy (work, arg);
- string_mod (work, CC_PRINT, CC_DOUBLE_QUOTE|CC_CRLF, '_');
- if (i)
- buf_printf (&buf, " ");
- if (string_class (work, CC_ANY, CC_SPACE))
- buf_printf (&buf, "%s", work);
- else
- buf_printf (&buf, "\"%s\"", work);
+ const char *arg = a->argv[i];
+ strcpy(work, arg);
+ string_mod(work, CC_PRINT, CC_DOUBLE_QUOTE|CC_CRLF, '_');
+ if (i)
+ {
+ buf_printf(&buf, " ");
+ }
+ if (string_class(work, CC_ANY, CC_SPACE))
+ {
+ buf_printf(&buf, "%s", work);
+ }
+ else
+ {
+ buf_printf(&buf, "\"%s\"", work);
+ }
}
- return wide_string (BSTR (&buf), gc);
+ return wide_string(BSTR(&buf), gc);
}
/*
* Attempt to simulate fork/execve on Windows
*/
int
-openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned int flags)
+openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags)
{
- int ret = -1;
- static bool exec_warn = false;
+ int ret = -1;
+ static bool exec_warn = false;
- if (a && a->argv[0])
+ if (a && a->argv[0])
{
- if (openvpn_execve_allowed (flags))
- {
- struct gc_arena gc = gc_new ();
- STARTUPINFOW start_info;
- PROCESS_INFORMATION proc_info;
+ if (openvpn_execve_allowed(flags))
+ {
+ struct gc_arena gc = gc_new();
+ STARTUPINFOW start_info;
+ PROCESS_INFORMATION proc_info;
- char *env = env_block (es);
- WCHAR *cl = wide_cmd_line (a, &gc);
- WCHAR *cmd = wide_string (a->argv[0], &gc);
+ char *env = env_block(es);
+ WCHAR *cl = wide_cmd_line(a, &gc);
+ WCHAR *cmd = wide_string(a->argv[0], &gc);
- /* this allows console programs to run, and is ignored otherwise */
- DWORD proc_flags = CREATE_NO_WINDOW;
+ /* this allows console programs to run, and is ignored otherwise */
+ DWORD proc_flags = CREATE_NO_WINDOW;
- CLEAR (start_info);
- CLEAR (proc_info);
+ CLEAR(start_info);
+ CLEAR(proc_info);
- /* fill in STARTUPINFO struct */
- GetStartupInfoW(&start_info);
- start_info.cb = sizeof(start_info);
- start_info.dwFlags = STARTF_USESHOWWINDOW;
- start_info.wShowWindow = SW_HIDE;
+ /* fill in STARTUPINFO struct */
+ GetStartupInfoW(&start_info);
+ start_info.cb = sizeof(start_info);
+ start_info.dwFlags = STARTF_USESHOWWINDOW;
+ start_info.wShowWindow = SW_HIDE;
- if (CreateProcessW (cmd, cl, NULL, NULL, FALSE, proc_flags, env, NULL, &start_info, &proc_info))
+ if (CreateProcessW(cmd, cl, NULL, NULL, FALSE, proc_flags, env, NULL, &start_info, &proc_info))
{
- DWORD exit_status = 0;
- CloseHandle (proc_info.hThread);
- WaitForSingleObject (proc_info.hProcess, INFINITE);
- if (GetExitCodeProcess (proc_info.hProcess, &exit_status))
- ret = (int)exit_status;
- else
- msg (M_WARN|M_ERRNO, "openvpn_execve: GetExitCodeProcess %S failed", cmd);
- CloseHandle (proc_info.hProcess);
+ DWORD exit_status = 0;
+ CloseHandle(proc_info.hThread);
+ WaitForSingleObject(proc_info.hProcess, INFINITE);
+ if (GetExitCodeProcess(proc_info.hProcess, &exit_status))
+ {
+ ret = (int)exit_status;
+ }
+ else
+ {
+ msg(M_WARN|M_ERRNO, "openvpn_execve: GetExitCodeProcess %S failed", cmd);
+ }
+ CloseHandle(proc_info.hProcess);
}
- else
+ else
{
- msg (M_WARN|M_ERRNO, "openvpn_execve: CreateProcess %S failed", cmd);
+ msg(M_WARN|M_ERRNO, "openvpn_execve: CreateProcess %S failed", cmd);
}
- free (env);
- gc_free (&gc);
+ free(env);
+ gc_free(&gc);
+ }
+ else if (!exec_warn && (script_security < SSEC_SCRIPTS))
+ {
+ msg(M_WARN, SCRIPT_SECURITY_WARNING);
+ exec_warn = true;
}
- else if (!exec_warn && (script_security < SSEC_SCRIPTS))
- {
- msg (M_WARN, SCRIPT_SECURITY_WARNING);
- exec_warn = true;
- }
}
- else
+ else
{
- msg (M_WARN, "openvpn_execve: called with empty argv");
+ msg(M_WARN, "openvpn_execve: called with empty argv");
}
- return ret;
+ return ret;
}
WCHAR *
-wide_string (const char* utf8, struct gc_arena *gc)
+wide_string(const char *utf8, struct gc_arena *gc)
{
- int n = MultiByteToWideChar (CP_UTF8, 0, utf8, -1, NULL, 0);
- WCHAR *ucs16 = gc_malloc (n * sizeof (WCHAR), false, gc);
- MultiByteToWideChar (CP_UTF8, 0, utf8, -1, ucs16, n);
- return ucs16;
+ int n = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
+ WCHAR *ucs16 = gc_malloc(n * sizeof(WCHAR), false, gc);
+ MultiByteToWideChar(CP_UTF8, 0, utf8, -1, ucs16, n);
+ return ucs16;
}
/*
* call ourself in another process
*/
void
-fork_to_self (const char *cmdline)
+fork_to_self(const char *cmdline)
{
- STARTUPINFO start_info;
- PROCESS_INFORMATION proc_info;
- char self_exe[256];
- char *cl = string_alloc (cmdline, NULL);
- DWORD status;
-
- CLEAR (start_info);
- CLEAR (proc_info);
- CLEAR (self_exe);
-
- status = GetModuleFileName (NULL, self_exe, sizeof(self_exe));
- if (status == 0 || status == sizeof(self_exe))
+ STARTUPINFO start_info;
+ PROCESS_INFORMATION proc_info;
+ char self_exe[256];
+ char *cl = string_alloc(cmdline, NULL);
+ DWORD status;
+
+ CLEAR(start_info);
+ CLEAR(proc_info);
+ CLEAR(self_exe);
+
+ status = GetModuleFileName(NULL, self_exe, sizeof(self_exe));
+ if (status == 0 || status == sizeof(self_exe))
{
- msg (M_WARN|M_ERRNO, "fork_to_self: CreateProcess failed: cannot get module name via GetModuleFileName");
- goto done;
+ msg(M_WARN|M_ERRNO, "fork_to_self: CreateProcess failed: cannot get module name via GetModuleFileName");
+ goto done;
}
- /* fill in STARTUPINFO struct */
- GetStartupInfo(&start_info);
- start_info.cb = sizeof(start_info);
- start_info.dwFlags = STARTF_USESHOWWINDOW;
- start_info.wShowWindow = SW_HIDE;
+ /* fill in STARTUPINFO struct */
+ GetStartupInfo(&start_info);
+ start_info.cb = sizeof(start_info);
+ start_info.dwFlags = STARTF_USESHOWWINDOW;
+ start_info.wShowWindow = SW_HIDE;
- if (CreateProcess (self_exe, cl, NULL, NULL, FALSE, 0, NULL, NULL, &start_info, &proc_info))
+ if (CreateProcess(self_exe, cl, NULL, NULL, FALSE, 0, NULL, NULL, &start_info, &proc_info))
{
- CloseHandle (proc_info.hThread);
- CloseHandle (proc_info.hProcess);
+ CloseHandle(proc_info.hThread);
+ CloseHandle(proc_info.hProcess);
}
- else
+ else
{
- msg (M_WARN|M_ERRNO, "fork_to_self: CreateProcess failed: %s", cmdline);
+ msg(M_WARN|M_ERRNO, "fork_to_self: CreateProcess failed: %s", cmdline);
}
- done:
- free (cl);
+done:
+ free(cl);
}
char *
-get_win_sys_path (void)
+get_win_sys_path(void)
{
- ASSERT (win_sys_path);
- return win_sys_path;
+ ASSERT(win_sys_path);
+ return win_sys_path;
}
void
-set_win_sys_path (const char *newpath, struct env_set *es)
+set_win_sys_path(const char *newpath, struct env_set *es)
{
- free (win_sys_path);
- win_sys_path = string_alloc (newpath, NULL);
- setenv_str (es, SYS_PATH_ENV_VAR_NAME, win_sys_path); /* route.exe needs this */
+ free(win_sys_path);
+ win_sys_path = string_alloc(newpath, NULL);
+ setenv_str(es, SYS_PATH_ENV_VAR_NAME, win_sys_path); /* route.exe needs this */
}
void
-set_win_sys_path_via_env (struct env_set *es)
+set_win_sys_path_via_env(struct env_set *es)
{
- char buf[256];
- DWORD status = GetEnvironmentVariable (SYS_PATH_ENV_VAR_NAME, buf, sizeof(buf));
- if (!status)
- msg (M_ERR, "Cannot find environmental variable %s", SYS_PATH_ENV_VAR_NAME);
- if (status > sizeof (buf) - 1)
- msg (M_FATAL, "String overflow attempting to read environmental variable %s", SYS_PATH_ENV_VAR_NAME);
- set_win_sys_path (buf, es);
+ char buf[256];
+ DWORD status = GetEnvironmentVariable(SYS_PATH_ENV_VAR_NAME, buf, sizeof(buf));
+ if (!status)
+ {
+ msg(M_ERR, "Cannot find environmental variable %s", SYS_PATH_ENV_VAR_NAME);
+ }
+ if (status > sizeof(buf) - 1)
+ {
+ msg(M_FATAL, "String overflow attempting to read environmental variable %s", SYS_PATH_ENV_VAR_NAME);
+ }
+ set_win_sys_path(buf, es);
}
const char *
win_get_tempdir()
{
- static char tmpdir[MAX_PATH];
- WCHAR wtmpdir[MAX_PATH];
+ static char tmpdir[MAX_PATH];
+ WCHAR wtmpdir[MAX_PATH];
- if (!GetTempPathW(_countof(wtmpdir), wtmpdir))
+ if (!GetTempPathW(_countof(wtmpdir), wtmpdir))
{
- /* Warn if we can't find a valid temporary directory, which should
- * be unlikely.
- */
- msg (M_WARN, "Could not find a suitable temporary directory."
- " (GetTempPath() failed). Consider using --tmp-dir");
- return NULL;
+ /* Warn if we can't find a valid temporary directory, which should
+ * be unlikely.
+ */
+ msg(M_WARN, "Could not find a suitable temporary directory."
+ " (GetTempPath() failed). Consider using --tmp-dir");
+ return NULL;
}
- if (WideCharToMultiByte (CP_UTF8, 0, wtmpdir, -1, NULL, 0, NULL, NULL) > sizeof (tmpdir))
+ if (WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, NULL, 0, NULL, NULL) > sizeof(tmpdir))
{
- msg (M_WARN, "Could not get temporary directory. Path is too long."
- " Consider using --tmp-dir");
- return NULL;
+ msg(M_WARN, "Could not get temporary directory. Path is too long."
+ " Consider using --tmp-dir");
+ return NULL;
}
- WideCharToMultiByte (CP_UTF8, 0, wtmpdir, -1, tmpdir, sizeof (tmpdir), NULL, NULL);
- return tmpdir;
+ WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, tmpdir, sizeof(tmpdir), NULL, NULL);
+ return tmpdir;
}
static bool
-win_block_dns_service (bool add, int index, const HANDLE pipe)
+win_block_dns_service(bool add, int index, const HANDLE pipe)
{
- DWORD len;
- bool ret = false;
- ack_message_t ack;
- struct gc_arena gc = gc_new ();
-
- block_dns_message_t data = {
- .header = {
- (add ? msg_add_block_dns : msg_del_block_dns),
- sizeof (block_dns_message_t),
- 0 },
- .iface = { .index = index, .name = "" }
- };
-
- if (!WriteFile (pipe, &data, sizeof (data), &len, NULL) ||
- !ReadFile (pipe, &ack, sizeof (ack), &len, NULL))
+ DWORD len;
+ bool ret = false;
+ ack_message_t ack;
+ struct gc_arena gc = gc_new();
+
+ block_dns_message_t data = {
+ .header = {
+ (add ? msg_add_block_dns : msg_del_block_dns),
+ sizeof(block_dns_message_t),
+ 0
+ },
+ .iface = { .index = index, .name = "" }
+ };
+
+ if (!WriteFile(pipe, &data, sizeof(data), &len, NULL)
+ || !ReadFile(pipe, &ack, sizeof(ack), &len, NULL))
{
- msg (M_WARN, "Block_DNS: could not talk to service: %s [%lu]",
- strerror_win32 (GetLastError (), &gc), GetLastError ());
- goto out;
+ msg(M_WARN, "Block_DNS: could not talk to service: %s [%lu]",
+ strerror_win32(GetLastError(), &gc), GetLastError());
+ goto out;
}
- if (ack.error_number != NO_ERROR)
+ if (ack.error_number != NO_ERROR)
{
- msg (M_WARN, "Block_DNS: %s block dns filters using service failed: %s [status=0x%x if_index=%d]",
- (add ? "adding" : "deleting"), strerror_win32 (ack.error_number, &gc),
- ack.error_number, data.iface.index);
- goto out;
+ msg(M_WARN, "Block_DNS: %s block dns filters using service failed: %s [status=0x%x if_index=%d]",
+ (add ? "adding" : "deleting"), strerror_win32(ack.error_number, &gc),
+ ack.error_number, data.iface.index);
+ goto out;
}
- ret = true;
- msg (M_INFO, "%s outside dns using service succeeded.", (add ? "Blocking" : "Unblocking"));
+ ret = true;
+ msg(M_INFO, "%s outside dns using service succeeded.", (add ? "Blocking" : "Unblocking"));
out:
- gc_free (&gc);
- return ret;
+ gc_free(&gc);
+ return ret;
}
static void
-block_dns_msg_handler (DWORD err, const char *msg)
+block_dns_msg_handler(DWORD err, const char *msg)
{
- struct gc_arena gc = gc_new ();
+ struct gc_arena gc = gc_new();
- if (err == 0)
+ if (err == 0)
{
- msg (M_INFO, "%s", msg);
+ msg(M_INFO, "%s", msg);
}
- else
+ else
{
- msg (M_WARN, "Error in add_block_dns_filters(): %s : %s [status=0x%lx]",
- msg, strerror_win32 (err, &gc), err);
+ msg(M_WARN, "Error in add_block_dns_filters(): %s : %s [status=0x%lx]",
+ msg, strerror_win32(err, &gc), err);
}
- gc_free (&gc);
+ gc_free(&gc);
}
bool
-win_wfp_block_dns (const NET_IFINDEX index, const HANDLE msg_channel)
+win_wfp_block_dns(const NET_IFINDEX index, const HANDLE msg_channel)
{
- WCHAR openvpnpath[MAX_PATH];
- bool ret = false;
- DWORD status;
+ WCHAR openvpnpath[MAX_PATH];
+ bool ret = false;
+ DWORD status;
- if (msg_channel)
+ if (msg_channel)
{
- dmsg (D_LOW, "Using service to add block dns filters");
- ret = win_block_dns_service (true, index, msg_channel);
- goto out;
+ dmsg(D_LOW, "Using service to add block dns filters");
+ ret = win_block_dns_service(true, index, msg_channel);
+ goto out;
}
- status = GetModuleFileNameW (NULL, openvpnpath, sizeof(openvpnpath));
- if (status == 0 || status == sizeof(openvpnpath))
+ status = GetModuleFileNameW(NULL, openvpnpath, sizeof(openvpnpath));
+ if (status == 0 || status == sizeof(openvpnpath))
{
- msg (M_WARN|M_ERRNO, "block_dns: cannot get executable path");
- goto out;
+ msg(M_WARN|M_ERRNO, "block_dns: cannot get executable path");
+ goto out;
}
- status = add_block_dns_filters (&m_hEngineHandle, index, openvpnpath,
- block_dns_msg_handler);
- ret = (status == 0);
+ status = add_block_dns_filters(&m_hEngineHandle, index, openvpnpath,
+ block_dns_msg_handler);
+ ret = (status == 0);
out:
- return ret;
+ return ret;
}
bool
win_wfp_uninit(const HANDLE msg_channel)
{
- dmsg (D_LOW, "Uninitializing WFP");
+ dmsg(D_LOW, "Uninitializing WFP");
if (msg_channel)
- {
- msg (D_LOW, "Using service to delete block dns filters");
- win_block_dns_service (false, -1, msg_channel);
- }
+ {
+ msg(D_LOW, "Using service to delete block dns filters");
+ win_block_dns_service(false, -1, msg_channel);
+ }
else
- {
- delete_block_dns_filters (m_hEngineHandle);
+ {
+ delete_block_dns_filters(m_hEngineHandle);
m_hEngineHandle = NULL;
- }
+ }
return true;
}
@@ -1208,7 +1364,7 @@ win32_version_info()
{
if (!IsWindowsXPOrGreater())
{
- msg (M_FATAL, "Error: Windows version must be XP or greater.");
+ msg(M_FATAL, "Error: Windows version must be XP or greater.");
}
if (!IsWindowsVistaOrGreater())
@@ -1235,13 +1391,13 @@ bool
win32_is_64bit()
{
#if defined(_WIN64)
- return true; // 64-bit programs run only on Win64
+ return true; /* 64-bit programs run only on Win64 */
#elif defined(_WIN32)
- // 32-bit programs run on both 32-bit and 64-bit Windows
+ /* 32-bit programs run on both 32-bit and 64-bit Windows */
BOOL f64 = FALSE;
return IsWow64Process(GetCurrentProcess(), &f64) && f64;
-#else
- return false; // Win64 does not support Win16
+#else /* if defined(_WIN64) */
+ return false; /* Win64 does not support Win16 */
#endif
}
@@ -1249,31 +1405,35 @@ const char *
win32_version_string(struct gc_arena *gc, bool add_name)
{
int version = win32_version_info();
- struct buffer out = alloc_buf_gc (256, gc);
+ struct buffer out = alloc_buf_gc(256, gc);
switch (version)
{
case WIN_XP:
- buf_printf (&out, "5.1%s", add_name ? " (Windows XP)" : "");
+ buf_printf(&out, "5.1%s", add_name ? " (Windows XP)" : "");
break;
+
case WIN_VISTA:
- buf_printf (&out, "6.0%s", add_name ? " (Windows Vista)" : "");
+ buf_printf(&out, "6.0%s", add_name ? " (Windows Vista)" : "");
break;
+
case WIN_7:
- buf_printf (&out, "6.1%s", add_name ? " (Windows 7)" : "");
+ buf_printf(&out, "6.1%s", add_name ? " (Windows 7)" : "");
break;
+
case WIN_8:
- buf_printf (&out, "6.2%s", add_name ? " (Windows 8 or greater)" : "");
+ buf_printf(&out, "6.2%s", add_name ? " (Windows 8 or greater)" : "");
break;
+
default:
- msg (M_NONFATAL, "Unknown Windows version: %d", version);
- buf_printf (&out, "0.0%s", add_name ? " (unknown)" : "");
+ msg(M_NONFATAL, "Unknown Windows version: %d", version);
+ buf_printf(&out, "0.0%s", add_name ? " (unknown)" : "");
break;
}
- buf_printf (&out, win32_is_64bit() ? " 64bit" : " 32bit");
+ buf_printf(&out, win32_is_64bit() ? " 64bit" : " 32bit");
return (const char *)out.data;
}
-#endif
+#endif /* ifdef _WIN32 */