summaryrefslogtreecommitdiff
path: root/src/openvpnserv
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/openvpnserv
parentd53dba59e78da865c4fe820386ff2f4f76925f3b (diff)
New upstream version 2.4.0upstream/2.4.0
Diffstat (limited to 'src/openvpnserv')
-rw-r--r--src/openvpnserv/Makefile.am2
-rw-r--r--src/openvpnserv/Makefile.in8
-rw-r--r--src/openvpnserv/automatic.c520
-rw-r--r--src/openvpnserv/common.c322
-rw-r--r--src/openvpnserv/interactive.c2352
-rw-r--r--src/openvpnserv/service.c340
-rw-r--r--src/openvpnserv/service.h55
-rw-r--r--src/openvpnserv/validate.c124
-rw-r--r--src/openvpnserv/validate.h10
9 files changed, 2000 insertions, 1733 deletions
diff --git a/src/openvpnserv/Makefile.am b/src/openvpnserv/Makefile.am
index 58ecd91..21efc7c 100644
--- a/src/openvpnserv/Makefile.am
+++ b/src/openvpnserv/Makefile.am
@@ -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>
# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com>
#
diff --git a/src/openvpnserv/Makefile.in b/src/openvpnserv/Makefile.in
index b38a76a..e113fee 100644
--- a/src/openvpnserv/Makefile.in
+++ b/src/openvpnserv/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
@@ -21,7 +21,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>
# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com>
#
@@ -504,14 +504,14 @@ distclean-compile:
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/src/openvpnserv/automatic.c b/src/openvpnserv/automatic.c
index aa7618f..6be6c6d 100644
--- a/src/openvpnserv/automatic.c
+++ b/src/openvpnserv/automatic.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
@@ -48,17 +48,17 @@ static SERVICE_STATUS_HANDLE service;
static SERVICE_STATUS status;
openvpn_service_t automatic_service = {
- automatic,
- TEXT(PACKAGE_NAME "ServiceLegacy"),
- TEXT(PACKAGE_NAME " Legacy Service"),
- TEXT(SERVICE_DEPENDENCIES),
- SERVICE_DEMAND_START
+ automatic,
+ TEXT(PACKAGE_NAME "ServiceLegacy"),
+ TEXT(PACKAGE_NAME " Legacy Service"),
+ TEXT(SERVICE_DEPENDENCIES),
+ SERVICE_DEMAND_START
};
struct security_attributes
{
- SECURITY_ATTRIBUTES sa;
- SECURITY_DESCRIPTOR sd;
+ SECURITY_ATTRIBUTES sa;
+ SECURITY_DESCRIPTOR sd;
};
/*
@@ -74,18 +74,22 @@ static HANDLE exit_event = NULL;
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 = TRUE;
- 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 = TRUE;
+ if (!InitializeSecurityDescriptor(&obj->sd, SECURITY_DESCRIPTOR_REVISION))
+ {
+ return false;
+ }
+ if (!SetSecurityDescriptorDacl(&obj->sd, TRUE, NULL, FALSE))
+ {
+ return false;
+ }
+ return true;
}
/*
@@ -98,318 +102,342 @@ init_security_attributes_allow_all (struct security_attributes *obj)
#define EXIT_EVENT_NAME TEXT(PACKAGE "_exit_1")
HANDLE
-create_event (LPCTSTR name, bool allow_all, bool initial_state, bool manual_reset)
+create_event(LPCTSTR name, bool allow_all, bool initial_state, bool manual_reset)
{
- if (allow_all)
+ if (allow_all)
{
- struct security_attributes sa;
- if (!init_security_attributes_allow_all (&sa))
- return NULL;
- return CreateEvent (&sa.sa, (BOOL)manual_reset, (BOOL)initial_state, name);
+ struct security_attributes sa;
+ if (!init_security_attributes_allow_all(&sa))
+ {
+ return NULL;
+ }
+ return CreateEvent(&sa.sa, (BOOL)manual_reset, (BOOL)initial_state, name);
+ }
+ else
+ {
+ return CreateEvent(NULL, (BOOL)manual_reset, (BOOL)initial_state, name);
}
- else
- return CreateEvent (NULL, (BOOL)manual_reset, (BOOL)initial_state, name);
}
void
-close_if_open (HANDLE h)
+close_if_open(HANDLE h)
{
- if (h != NULL)
- CloseHandle (h);
+ if (h != NULL)
+ {
+ CloseHandle(h);
+ }
}
static bool
-match (const WIN32_FIND_DATA *find, LPCTSTR ext)
+match(const WIN32_FIND_DATA *find, LPCTSTR ext)
{
- int i;
+ int i;
- if (find->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- return false;
+ if (find->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ return false;
+ }
- if (!_tcslen (ext))
- return true;
+ if (!_tcslen(ext))
+ {
+ return true;
+ }
- i = _tcslen (find->cFileName) - _tcslen (ext) - 1;
- if (i < 1)
- return false;
+ i = _tcslen(find->cFileName) - _tcslen(ext) - 1;
+ if (i < 1)
+ {
+ return false;
+ }
- return find->cFileName[i] == '.' && !_tcsicmp (find->cFileName + i + 1, ext);
+ return find->cFileName[i] == '.' && !_tcsicmp(find->cFileName + i + 1, ext);
}
/*
* Modify the extension on a filename.
*/
static bool
-modext (LPTSTR dest, int size, LPCTSTR src, LPCTSTR newext)
+modext(LPTSTR dest, int size, LPCTSTR src, LPCTSTR newext)
{
- int i;
+ int i;
- if (size > 0 && (_tcslen (src) + 1) <= size)
+ if (size > 0 && (_tcslen(src) + 1) <= size)
{
- _tcscpy (dest, src);
- dest [size - 1] = TEXT('\0');
- i = _tcslen (dest);
- while (--i >= 0)
+ _tcscpy(dest, src);
+ dest [size - 1] = TEXT('\0');
+ i = _tcslen(dest);
+ while (--i >= 0)
{
- if (dest[i] == TEXT('\\'))
- break;
- if (dest[i] == TEXT('.'))
+ if (dest[i] == TEXT('\\'))
+ {
+ break;
+ }
+ if (dest[i] == TEXT('.'))
{
- dest[i] = TEXT('\0');
- break;
+ dest[i] = TEXT('\0');
+ break;
}
}
- if (_tcslen (dest) + _tcslen(newext) + 2 <= size)
+ if (_tcslen(dest) + _tcslen(newext) + 2 <= size)
{
- _tcscat (dest, TEXT("."));
- _tcscat (dest, newext);
- return true;
+ _tcscat(dest, TEXT("."));
+ _tcscat(dest, newext);
+ return true;
}
- dest[0] = TEXT('\0');
+ dest[0] = TEXT('\0');
}
- return false;
+ return false;
}
static DWORD WINAPI
-ServiceCtrlAutomatic (DWORD ctrl_code, DWORD event, LPVOID data, LPVOID ctx)
+ServiceCtrlAutomatic(DWORD ctrl_code, DWORD event, LPVOID data, LPVOID ctx)
{
- SERVICE_STATUS *status = ctx;
- switch (ctrl_code)
+ SERVICE_STATUS *status = ctx;
+ switch (ctrl_code)
{
- case SERVICE_CONTROL_STOP:
- status->dwCurrentState = SERVICE_STOP_PENDING;
- ReportStatusToSCMgr (service, status);
- if (exit_event)
- SetEvent (exit_event);
- return NO_ERROR;
-
- case SERVICE_CONTROL_INTERROGATE:
- return NO_ERROR;
-
- default:
- return ERROR_CALL_NOT_IMPLEMENTED;
+ case SERVICE_CONTROL_STOP:
+ status->dwCurrentState = SERVICE_STOP_PENDING;
+ ReportStatusToSCMgr(service, status);
+ if (exit_event)
+ {
+ SetEvent(exit_event);
+ }
+ return NO_ERROR;
+
+ case SERVICE_CONTROL_INTERROGATE:
+ return NO_ERROR;
+
+ default:
+ return ERROR_CALL_NOT_IMPLEMENTED;
}
}
VOID WINAPI
-ServiceStartAutomatic (DWORD dwArgc, LPTSTR *lpszArgv)
+ServiceStartAutomatic(DWORD dwArgc, LPTSTR *lpszArgv)
{
- DWORD error = NO_ERROR;
- settings_t settings;
+ DWORD error = NO_ERROR;
+ settings_t settings;
- service = RegisterServiceCtrlHandlerEx (automatic_service.name, ServiceCtrlAutomatic, &status);
- if (!service)
- return;
+ service = RegisterServiceCtrlHandlerEx(automatic_service.name, ServiceCtrlAutomatic, &status);
+ if (!service)
+ {
+ return;
+ }
- status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
- status.dwCurrentState = SERVICE_START_PENDING;
- status.dwServiceSpecificExitCode = NO_ERROR;
- status.dwWin32ExitCode = NO_ERROR;
- status.dwWaitHint = 3000;
+ status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
+ status.dwCurrentState = SERVICE_START_PENDING;
+ status.dwServiceSpecificExitCode = NO_ERROR;
+ status.dwWin32ExitCode = NO_ERROR;
+ status.dwWaitHint = 3000;
- if (!ReportStatusToSCMgr(service, &status))
+ if (!ReportStatusToSCMgr(service, &status))
{
- MsgToEventLog (M_ERR, TEXT("ReportStatusToSCMgr #1 failed"));
- goto finish;
+ MsgToEventLog(M_ERR, TEXT("ReportStatusToSCMgr #1 failed"));
+ goto finish;
}
- /*
- * Create our exit event
- */
- exit_event = create_event (EXIT_EVENT_NAME, false, false, true);
- if (!exit_event)
+ /*
+ * Create our exit event
+ */
+ exit_event = create_event(EXIT_EVENT_NAME, false, false, true);
+ if (!exit_event)
{
- MsgToEventLog (M_ERR, TEXT("CreateEvent failed"));
- goto finish;
+ MsgToEventLog(M_ERR, TEXT("CreateEvent failed"));
+ goto finish;
}
- /*
- * If exit event is already signaled, it means we were not
- * shut down properly.
- */
- if (WaitForSingleObject (exit_event, 0) != WAIT_TIMEOUT)
+ /*
+ * If exit event is already signaled, it means we were not
+ * shut down properly.
+ */
+ if (WaitForSingleObject(exit_event, 0) != WAIT_TIMEOUT)
{
- MsgToEventLog (M_ERR, TEXT("Exit event is already signaled -- we were not shut down properly"));
- goto finish;
+ MsgToEventLog(M_ERR, TEXT("Exit event is already signaled -- we were not shut down properly"));
+ goto finish;
}
- if (!ReportStatusToSCMgr(service, &status))
+ if (!ReportStatusToSCMgr(service, &status))
{
- MsgToEventLog (M_ERR, TEXT("ReportStatusToSCMgr #2 failed"));
- goto finish;
+ MsgToEventLog(M_ERR, TEXT("ReportStatusToSCMgr #2 failed"));
+ goto finish;
}
- /*
- * Read info from registry in key HKLM\SOFTWARE\OpenVPN
- */
- error = GetOpenvpnSettings (&settings);
- if (error != ERROR_SUCCESS)
- goto finish;
-
- /*
- * Instantiate an OpenVPN process for each configuration
- * file found.
- */
- {
- WIN32_FIND_DATA find_obj;
- HANDLE find_handle;
- BOOL more_files;
- TCHAR find_string[MAX_PATH];
-
- openvpn_sntprintf (find_string, MAX_PATH, TEXT("%s\\*"), settings.config_dir);
-
- find_handle = FindFirstFile (find_string, &find_obj);
- if (find_handle == INVALID_HANDLE_VALUE)
- {
- MsgToEventLog (M_ERR, TEXT("Cannot get configuration file list using: %s"), find_string);
+ /*
+ * Read info from registry in key HKLM\SOFTWARE\OpenVPN
+ */
+ error = GetOpenvpnSettings(&settings);
+ if (error != ERROR_SUCCESS)
+ {
goto finish;
- }
+ }
/*
- * Loop over each config file
+ * Instantiate an OpenVPN process for each configuration
+ * file found.
*/
- do {
- HANDLE log_handle = NULL;
- STARTUPINFO start_info;
- PROCESS_INFORMATION proc_info;
- struct security_attributes sa;
- TCHAR log_file[MAX_PATH];
- TCHAR log_path[MAX_PATH];
- TCHAR command_line[256];
-
- CLEAR (start_info);
- CLEAR (proc_info);
- CLEAR (sa);
-
- if (!ReportStatusToSCMgr(service, &status))
+ {
+ WIN32_FIND_DATA find_obj;
+ HANDLE find_handle;
+ BOOL more_files;
+ TCHAR find_string[MAX_PATH];
+
+ openvpn_sntprintf(find_string, MAX_PATH, TEXT("%s\\*"), settings.config_dir);
+
+ find_handle = FindFirstFile(find_string, &find_obj);
+ if (find_handle == INVALID_HANDLE_VALUE)
{
- MsgToEventLog (M_ERR, TEXT("ReportStatusToSCMgr #3 failed"));
- FindClose (find_handle);
- goto finish;
+ MsgToEventLog(M_ERR, TEXT("Cannot get configuration file list using: %s"), find_string);
+ goto finish;
}
- /* does file have the correct type and extension? */
- if (match (&find_obj, settings.ext_string))
- {
- /* get log file pathname */
- if (!modext (log_file, _countof (log_file), find_obj.cFileName, TEXT("log")))
+ /*
+ * Loop over each config file
+ */
+ do {
+ HANDLE log_handle = NULL;
+ STARTUPINFO start_info;
+ PROCESS_INFORMATION proc_info;
+ struct security_attributes sa;
+ TCHAR log_file[MAX_PATH];
+ TCHAR log_path[MAX_PATH];
+ TCHAR command_line[256];
+
+ CLEAR(start_info);
+ CLEAR(proc_info);
+ CLEAR(sa);
+
+ if (!ReportStatusToSCMgr(service, &status))
{
- MsgToEventLog (M_ERR, TEXT("Cannot construct logfile name based on: %s"), find_obj.cFileName);
- FindClose (find_handle);
- goto finish;
+ MsgToEventLog(M_ERR, TEXT("ReportStatusToSCMgr #3 failed"));
+ FindClose(find_handle);
+ goto finish;
}
- openvpn_sntprintf (log_path, _countof (log_path),
- TEXT("%s\\%s"), settings.log_dir, log_file);
-
- /* construct command line */
- openvpn_sntprintf (command_line, _countof (command_line), TEXT(PACKAGE " --service %s 1 --config \"%s\""),
- EXIT_EVENT_NAME,
- find_obj.cFileName);
- /* Make security attributes struct for logfile handle so it can
- be inherited. */
- if (!init_security_attributes_allow_all (&sa))
+ /* does file have the correct type and extension? */
+ if (match(&find_obj, settings.ext_string))
{
- error = MsgToEventLog (M_SYSERR, TEXT("InitializeSecurityDescriptor start_" PACKAGE " failed"));
- goto finish;
- }
+ /* get log file pathname */
+ if (!modext(log_file, _countof(log_file), find_obj.cFileName, TEXT("log")))
+ {
+ MsgToEventLog(M_ERR, TEXT("Cannot construct logfile name based on: %s"), find_obj.cFileName);
+ FindClose(find_handle);
+ goto finish;
+ }
+ openvpn_sntprintf(log_path, _countof(log_path),
+ TEXT("%s\\%s"), settings.log_dir, log_file);
- /* open logfile as stdout/stderr for soon-to-be-spawned subprocess */
- log_handle = CreateFile (log_path,
- GENERIC_WRITE,
- FILE_SHARE_READ,
- &sa.sa,
- settings.append ? OPEN_ALWAYS : CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
+ /* construct command line */
+ openvpn_sntprintf(command_line, _countof(command_line), TEXT(PACKAGE " --service %s 1 --config \"%s\""),
+ EXIT_EVENT_NAME,
+ find_obj.cFileName);
- if (log_handle == INVALID_HANDLE_VALUE)
- {
- error = MsgToEventLog (M_SYSERR, TEXT("Cannot open logfile: %s"), log_path);
- FindClose (find_handle);
- goto finish;
- }
+ /* Make security attributes struct for logfile handle so it can
+ * be inherited. */
+ if (!init_security_attributes_allow_all(&sa))
+ {
+ error = MsgToEventLog(M_SYSERR, TEXT("InitializeSecurityDescriptor start_" PACKAGE " failed"));
+ goto finish;
+ }
- /* append to logfile? */
- if (settings.append)
- {
- if (SetFilePointer (log_handle, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)
+ /* open logfile as stdout/stderr for soon-to-be-spawned subprocess */
+ log_handle = CreateFile(log_path,
+ GENERIC_WRITE,
+ FILE_SHARE_READ,
+ &sa.sa,
+ settings.append ? OPEN_ALWAYS : CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (log_handle == INVALID_HANDLE_VALUE)
{
- error = MsgToEventLog (M_SYSERR, TEXT("Cannot seek to end of logfile: %s"), log_path);
- FindClose (find_handle);
- goto finish;
+ error = MsgToEventLog(M_SYSERR, TEXT("Cannot open logfile: %s"), log_path);
+ FindClose(find_handle);
+ goto finish;
}
- }
- /* fill in STARTUPINFO struct */
- GetStartupInfo(&start_info);
- start_info.cb = sizeof(start_info);
- start_info.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
- start_info.wShowWindow = SW_HIDE;
- start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
- start_info.hStdOutput = start_info.hStdError = log_handle;
-
- /* create an OpenVPN process for one config file */
- if (!CreateProcess(settings.exe_path,
- command_line,
- NULL,
- NULL,
- TRUE,
- settings.priority | CREATE_NEW_CONSOLE,
- NULL,
- settings.config_dir,
- &start_info,
- &proc_info))
- {
- error = MsgToEventLog (M_SYSERR, TEXT("CreateProcess failed, exe='%s' cmdline='%s' dir='%s'"),
- settings.exe_path,
- command_line,
- settings.config_dir);
-
- FindClose (find_handle);
- CloseHandle (log_handle);
- goto finish;
- }
+ /* append to logfile? */
+ if (settings.append)
+ {
+ if (SetFilePointer(log_handle, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)
+ {
+ error = MsgToEventLog(M_SYSERR, TEXT("Cannot seek to end of logfile: %s"), log_path);
+ FindClose(find_handle);
+ goto finish;
+ }
+ }
- /* close unneeded handles */
- Sleep (1000); /* try to prevent race if we close logfile
- handle before child process DUPs it */
- if (!CloseHandle (proc_info.hProcess)
- || !CloseHandle (proc_info.hThread)
- || !CloseHandle (log_handle))
- {
- error = MsgToEventLog (M_SYSERR, TEXT("CloseHandle failed"));
- goto finish;
+ /* fill in STARTUPINFO struct */
+ GetStartupInfo(&start_info);
+ start_info.cb = sizeof(start_info);
+ start_info.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
+ start_info.wShowWindow = SW_HIDE;
+ start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ start_info.hStdOutput = start_info.hStdError = log_handle;
+
+ /* create an OpenVPN process for one config file */
+ if (!CreateProcess(settings.exe_path,
+ command_line,
+ NULL,
+ NULL,
+ TRUE,
+ settings.priority | CREATE_NEW_CONSOLE,
+ NULL,
+ settings.config_dir,
+ &start_info,
+ &proc_info))
+ {
+ error = MsgToEventLog(M_SYSERR, TEXT("CreateProcess failed, exe='%s' cmdline='%s' dir='%s'"),
+ settings.exe_path,
+ command_line,
+ settings.config_dir);
+
+ FindClose(find_handle);
+ CloseHandle(log_handle);
+ goto finish;
+ }
+
+ /* close unneeded handles */
+ Sleep(1000); /* try to prevent race if we close logfile
+ * handle before child process DUPs it */
+ if (!CloseHandle(proc_info.hProcess)
+ || !CloseHandle(proc_info.hThread)
+ || !CloseHandle(log_handle))
+ {
+ error = MsgToEventLog(M_SYSERR, TEXT("CloseHandle failed"));
+ goto finish;
+ }
}
- }
- /* more files to process? */
- more_files = FindNextFile (find_handle, &find_obj);
+ /* more files to process? */
+ more_files = FindNextFile(find_handle, &find_obj);
- } while (more_files);
+ } while (more_files);
- FindClose (find_handle);
- }
+ FindClose(find_handle);
+ }
- /* we are now fully started */
- status.dwCurrentState = SERVICE_RUNNING;
- status.dwWaitHint = 0;
- if (!ReportStatusToSCMgr(service, &status))
+ /* we are now fully started */
+ status.dwCurrentState = SERVICE_RUNNING;
+ status.dwWaitHint = 0;
+ if (!ReportStatusToSCMgr(service, &status))
{
- MsgToEventLog (M_ERR, TEXT("ReportStatusToSCMgr SERVICE_RUNNING failed"));
- goto finish;
+ MsgToEventLog(M_ERR, TEXT("ReportStatusToSCMgr SERVICE_RUNNING failed"));
+ goto finish;
}
- /* wait for our shutdown signal */
- if (WaitForSingleObject (exit_event, INFINITE) != WAIT_OBJECT_0)
- MsgToEventLog (M_ERR, TEXT("wait for shutdown signal failed"));
+ /* wait for our shutdown signal */
+ if (WaitForSingleObject(exit_event, INFINITE) != WAIT_OBJECT_0)
+ {
+ MsgToEventLog(M_ERR, TEXT("wait for shutdown signal failed"));
+ }
finish:
- if (exit_event)
- CloseHandle (exit_event);
+ if (exit_event)
+ {
+ CloseHandle(exit_event);
+ }
- status.dwCurrentState = SERVICE_STOPPED;
- status.dwWin32ExitCode = error;
- ReportStatusToSCMgr (service, &status);
+ status.dwCurrentState = SERVICE_STOPPED;
+ status.dwWin32ExitCode = error;
+ ReportStatusToSCMgr(service, &status);
}
diff --git a/src/openvpnserv/common.c b/src/openvpnserv/common.c
index eafee20..3b9b396 100644
--- a/src/openvpnserv/common.c
+++ b/src/openvpnserv/common.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2011 Heiko Hund <heiko.hund@sophos.com>
+ * Copyright (C) 2011-2017 Heiko Hund <heiko.hund@sophos.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -29,202 +29,236 @@
* that don't guarantee null termination for size > 0.
*/
int
-openvpn_vsntprintf (LPTSTR str, size_t size, LPCTSTR format, va_list arglist)
+openvpn_vsntprintf(LPTSTR str, size_t size, LPCTSTR format, va_list arglist)
{
- int len = -1;
- if (size > 0)
+ int len = -1;
+ if (size > 0)
{
- len = _vsntprintf (str, size, format, arglist);
- str[size - 1] = 0;
+ len = _vsntprintf(str, size, format, arglist);
+ str[size - 1] = 0;
}
- return (len >= 0 && len < size);
+ return (len >= 0 && len < size);
}
int
-openvpn_sntprintf (LPTSTR str, size_t size, LPCTSTR format, ...)
+openvpn_sntprintf(LPTSTR str, size_t size, LPCTSTR format, ...)
{
- va_list arglist;
- int len = -1;
- if (size > 0)
+ va_list arglist;
+ int len = -1;
+ if (size > 0)
{
- va_start (arglist, format);
- len = openvpn_vsntprintf (str, size, format, arglist);
- va_end (arglist);
+ va_start(arglist, format);
+ len = openvpn_vsntprintf(str, size, format, arglist);
+ va_end(arglist);
}
- return len;
+ return len;
}
#define REG_KEY TEXT("SOFTWARE\\" PACKAGE_NAME)
static DWORD
-GetRegString (HKEY key, LPCTSTR value, LPTSTR data, DWORD size)
+GetRegString(HKEY key, LPCTSTR value, LPTSTR data, DWORD size)
{
- DWORD type;
- LONG status = RegQueryValueEx (key, value, NULL, &type, (LPBYTE) data, &size);
+ DWORD type;
+ LONG status = RegQueryValueEx(key, value, NULL, &type, (LPBYTE) data, &size);
- if (status == ERROR_SUCCESS && type != REG_SZ)
- status = ERROR_DATATYPE_MISMATCH;
+ if (status == ERROR_SUCCESS && type != REG_SZ)
+ {
+ status = ERROR_DATATYPE_MISMATCH;
+ }
- if (status != ERROR_SUCCESS)
+ if (status != ERROR_SUCCESS)
{
- SetLastError (status);
- return MsgToEventLog (M_SYSERR, TEXT("Error querying registry value: HKLM\\%s\\%s"), REG_KEY, value);
+ SetLastError(status);
+ return MsgToEventLog(M_SYSERR, TEXT("Error querying registry value: HKLM\\%s\\%s"), REG_KEY, value);
}
- return ERROR_SUCCESS;
+ return ERROR_SUCCESS;
}
DWORD
-GetOpenvpnSettings (settings_t *s)
+GetOpenvpnSettings(settings_t *s)
{
- TCHAR priority[64];
- TCHAR append[2];
- DWORD error;
- HKEY key;
-
- LONG status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_KEY, 0, KEY_READ, &key);
- if (status != ERROR_SUCCESS)
- {
- SetLastError (status);
- return MsgToEventLog (M_SYSERR, TEXT("Could not open Registry key HKLM\\%s not found"), REG_KEY);
- }
-
- error = GetRegString (key, TEXT("exe_path"), s->exe_path, sizeof (s->exe_path));
- if (error != ERROR_SUCCESS)
- goto out;
-
- error = GetRegString (key, TEXT("config_dir"), s->config_dir, sizeof (s->config_dir));
- if (error != ERROR_SUCCESS)
- goto out;
-
- error = GetRegString (key, TEXT("config_ext"), s->ext_string, sizeof (s->ext_string));
- if (error != ERROR_SUCCESS)
- goto out;
-
- error = GetRegString (key, TEXT("log_dir"), s->log_dir, sizeof (s->log_dir));
- if (error != ERROR_SUCCESS)
- goto out;
-
- error = GetRegString (key, TEXT("priority"), priority, sizeof (priority));
- if (error != ERROR_SUCCESS)
- goto out;
-
- error = GetRegString (key, TEXT("log_append"), append, sizeof (append));
- if (error != ERROR_SUCCESS)
- goto out;
-
- /* read if present, else use default */
- error = GetRegString (key, TEXT("ovpn_admin_group"), s->ovpn_admin_group, sizeof (s->ovpn_admin_group));
- if (error != ERROR_SUCCESS)
- {
- openvpn_sntprintf(s->ovpn_admin_group, _countof(s->ovpn_admin_group), OVPN_ADMIN_GROUP);
- error = 0; /* this error is not fatal */
- }
- /* set process priority */
- if (!_tcsicmp (priority, TEXT("IDLE_PRIORITY_CLASS")))
- s->priority = IDLE_PRIORITY_CLASS;
- else if (!_tcsicmp (priority, TEXT("BELOW_NORMAL_PRIORITY_CLASS")))
- s->priority = BELOW_NORMAL_PRIORITY_CLASS;
- else if (!_tcsicmp (priority, TEXT("NORMAL_PRIORITY_CLASS")))
- s->priority = NORMAL_PRIORITY_CLASS;
- else if (!_tcsicmp (priority, TEXT("ABOVE_NORMAL_PRIORITY_CLASS")))
- s->priority = ABOVE_NORMAL_PRIORITY_CLASS;
- else if (!_tcsicmp (priority, TEXT("HIGH_PRIORITY_CLASS")))
- s->priority = HIGH_PRIORITY_CLASS;
- else
- {
- SetLastError (ERROR_INVALID_DATA);
- error = MsgToEventLog (M_SYSERR, TEXT("Unknown priority name: %s"), priority);
- goto out;
- }
-
- /* set log file append/truncate flag */
- if (append[0] == TEXT('0'))
- s->append = FALSE;
- else if (append[0] == TEXT('1'))
- s->append = TRUE;
- else
- {
- SetLastError (ERROR_INVALID_DATA);
- error = MsgToEventLog (M_ERR, TEXT("Log file append flag (given as '%s') must be '0' or '1'"), append);
- goto out;
+ TCHAR priority[64];
+ TCHAR append[2];
+ DWORD error;
+ HKEY key;
+
+ LONG status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_KEY, 0, KEY_READ, &key);
+ if (status != ERROR_SUCCESS)
+ {
+ SetLastError(status);
+ return MsgToEventLog(M_SYSERR, TEXT("Could not open Registry key HKLM\\%s not found"), REG_KEY);
+ }
+
+ error = GetRegString(key, TEXT("exe_path"), s->exe_path, sizeof(s->exe_path));
+ if (error != ERROR_SUCCESS)
+ {
+ goto out;
+ }
+
+ error = GetRegString(key, TEXT("config_dir"), s->config_dir, sizeof(s->config_dir));
+ if (error != ERROR_SUCCESS)
+ {
+ goto out;
+ }
+
+ error = GetRegString(key, TEXT("config_ext"), s->ext_string, sizeof(s->ext_string));
+ if (error != ERROR_SUCCESS)
+ {
+ goto out;
+ }
+
+ error = GetRegString(key, TEXT("log_dir"), s->log_dir, sizeof(s->log_dir));
+ if (error != ERROR_SUCCESS)
+ {
+ goto out;
+ }
+
+ error = GetRegString(key, TEXT("priority"), priority, sizeof(priority));
+ if (error != ERROR_SUCCESS)
+ {
+ goto out;
+ }
+
+ error = GetRegString(key, TEXT("log_append"), append, sizeof(append));
+ if (error != ERROR_SUCCESS)
+ {
+ goto out;
+ }
+
+ /* read if present, else use default */
+ error = GetRegString(key, TEXT("ovpn_admin_group"), s->ovpn_admin_group, sizeof(s->ovpn_admin_group));
+ if (error != ERROR_SUCCESS)
+ {
+ openvpn_sntprintf(s->ovpn_admin_group, _countof(s->ovpn_admin_group), OVPN_ADMIN_GROUP);
+ error = 0; /* this error is not fatal */
+ }
+ /* set process priority */
+ if (!_tcsicmp(priority, TEXT("IDLE_PRIORITY_CLASS")))
+ {
+ s->priority = IDLE_PRIORITY_CLASS;
+ }
+ else if (!_tcsicmp(priority, TEXT("BELOW_NORMAL_PRIORITY_CLASS")))
+ {
+ s->priority = BELOW_NORMAL_PRIORITY_CLASS;
+ }
+ else if (!_tcsicmp(priority, TEXT("NORMAL_PRIORITY_CLASS")))
+ {
+ s->priority = NORMAL_PRIORITY_CLASS;
+ }
+ else if (!_tcsicmp(priority, TEXT("ABOVE_NORMAL_PRIORITY_CLASS")))
+ {
+ s->priority = ABOVE_NORMAL_PRIORITY_CLASS;
+ }
+ else if (!_tcsicmp(priority, TEXT("HIGH_PRIORITY_CLASS")))
+ {
+ s->priority = HIGH_PRIORITY_CLASS;
+ }
+ else
+ {
+ SetLastError(ERROR_INVALID_DATA);
+ error = MsgToEventLog(M_SYSERR, TEXT("Unknown priority name: %s"), priority);
+ goto out;
+ }
+
+ /* set log file append/truncate flag */
+ if (append[0] == TEXT('0'))
+ {
+ s->append = FALSE;
+ }
+ else if (append[0] == TEXT('1'))
+ {
+ s->append = TRUE;
+ }
+ else
+ {
+ SetLastError(ERROR_INVALID_DATA);
+ error = MsgToEventLog(M_ERR, TEXT("Log file append flag (given as '%s') must be '0' or '1'"), append);
+ goto out;
}
out:
- RegCloseKey (key);
- return error;
+ RegCloseKey(key);
+ return error;
}
LPCTSTR
-GetLastErrorText ()
+GetLastErrorText()
{
- static TCHAR buf[256];
- DWORD len;
- LPTSTR tmp = NULL;
+ static TCHAR buf[256];
+ DWORD len;
+ LPTSTR tmp = NULL;
- len = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
- NULL, GetLastError(), LANG_NEUTRAL, (LPTSTR)&tmp, 0, NULL);
+ len = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ NULL, GetLastError(), LANG_NEUTRAL, (LPTSTR)&tmp, 0, NULL);
- if (len == 0 || (long) _countof (buf) < (long) len + 14)
- buf[0] = TEXT('\0');
- else
+ if (len == 0 || (long) _countof(buf) < (long) len + 14)
+ {
+ buf[0] = TEXT('\0');
+ }
+ else
{
- tmp[_tcslen (tmp) - 2] = TEXT('\0'); /* remove CR/LF characters */
- openvpn_sntprintf (buf, _countof (buf), TEXT("%s (0x%x)"), tmp, GetLastError());
+ tmp[_tcslen(tmp) - 2] = TEXT('\0'); /* remove CR/LF characters */
+ openvpn_sntprintf(buf, _countof(buf), TEXT("%s (0x%x)"), tmp, GetLastError());
}
- if (tmp)
- LocalFree (tmp);
+ if (tmp)
+ {
+ LocalFree(tmp);
+ }
- return buf;
+ return buf;
}
DWORD
-MsgToEventLog (DWORD flags, LPCTSTR format, ...)
+MsgToEventLog(DWORD flags, LPCTSTR format, ...)
{
- HANDLE hEventSource;
- TCHAR msg[2][256];
- DWORD error = 0;
- LPCTSTR err_msg = TEXT("");
- va_list arglist;
+ HANDLE hEventSource;
+ TCHAR msg[2][256];
+ DWORD error = 0;
+ LPCTSTR err_msg = TEXT("");
+ va_list arglist;
- if (flags & MSG_FLAGS_SYS_CODE)
+ if (flags & MSG_FLAGS_SYS_CODE)
{
- error = GetLastError ();
- err_msg = GetLastErrorText ();
+ error = GetLastError();
+ err_msg = GetLastErrorText();
}
- hEventSource = RegisterEventSource (NULL, APPNAME);
- if (hEventSource != NULL)
+ hEventSource = RegisterEventSource(NULL, APPNAME);
+ if (hEventSource != NULL)
{
- openvpn_sntprintf (msg[0], _countof (msg[0]),
- TEXT("%s%s: %s"), APPNAME,
- (flags & MSG_FLAGS_ERROR) ? TEXT(" error") : TEXT(""), err_msg);
-
- va_start (arglist, format);
- openvpn_vsntprintf (msg[1], _countof (msg[1]), format, arglist);
- va_end (arglist);
-
- const TCHAR *mesg[] = { msg[0], msg[1] };
- ReportEvent (hEventSource, flags & MSG_FLAGS_ERROR ?
- EVENTLOG_ERROR_TYPE : EVENTLOG_INFORMATION_TYPE,
- 0, 0, NULL, 2, 0, mesg, NULL);
- DeregisterEventSource (hEventSource);
+ openvpn_sntprintf(msg[0], _countof(msg[0]),
+ TEXT("%s%s: %s"), APPNAME,
+ (flags & MSG_FLAGS_ERROR) ? TEXT(" error") : TEXT(""), err_msg);
+
+ va_start(arglist, format);
+ openvpn_vsntprintf(msg[1], _countof(msg[1]), format, arglist);
+ va_end(arglist);
+
+ const TCHAR *mesg[] = { msg[0], msg[1] };
+ ReportEvent(hEventSource, flags & MSG_FLAGS_ERROR ?
+ EVENTLOG_ERROR_TYPE : EVENTLOG_INFORMATION_TYPE,
+ 0, 0, NULL, 2, 0, mesg, NULL);
+ DeregisterEventSource(hEventSource);
}
- return error;
+ return error;
}
/* Convert a utf8 string to utf16. Caller should free the result */
wchar_t *
-utf8to16 (const char *utf8)
+utf8to16(const char *utf8)
{
- int n = MultiByteToWideChar (CP_UTF8, 0, utf8, -1, NULL, 0);
- wchar_t *utf16 = malloc (n * sizeof (wchar_t));
- if (!utf16)
- return NULL;
- MultiByteToWideChar (CP_UTF8, 0, utf8, -1, utf16, n);
- return utf16;
+ int n = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
+ wchar_t *utf16 = malloc(n * sizeof(wchar_t));
+ if (!utf16)
+ {
+ return NULL;
+ }
+ MultiByteToWideChar(CP_UTF8, 0, utf8, -1, utf16, n);
+ return utf16;
}
diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c
index ec54216..dbe2b9b 100644
--- a/src/openvpnserv/interactive.c
+++ b/src/openvpnserv/interactive.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2012 Heiko Hund <heiko.hund@sophos.com>
+ * Copyright (C) 2012-2017 Heiko Hund <heiko.hund@sophos.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -61,265 +61,291 @@ static HANDLE rdns_semaphore = NULL;
openvpn_service_t interactive_service = {
- interactive,
- TEXT(PACKAGE_NAME "ServiceInteractive"),
- TEXT(PACKAGE_NAME " Interactive Service"),
- TEXT(SERVICE_DEPENDENCIES),
- SERVICE_AUTO_START
+ interactive,
+ TEXT(PACKAGE_NAME "ServiceInteractive"),
+ TEXT(PACKAGE_NAME " Interactive Service"),
+ TEXT(SERVICE_DEPENDENCIES),
+ SERVICE_AUTO_START
};
typedef struct {
- WCHAR *directory;
- WCHAR *options;
- WCHAR *std_input;
+ WCHAR *directory;
+ WCHAR *options;
+ WCHAR *std_input;
} STARTUP_DATA;
/* Datatype for linked lists */
typedef struct _list_item {
- struct _list_item *next;
- LPVOID data;
+ struct _list_item *next;
+ LPVOID data;
} list_item_t;
/* Datatypes for undo information */
typedef enum {
- address,
- route,
- block_dns,
- undo_dns4,
- undo_dns6,
- _undo_type_max
+ address,
+ route,
+ block_dns,
+ undo_dns4,
+ undo_dns6,
+ _undo_type_max
} undo_type_t;
-typedef list_item_t* undo_lists_t[_undo_type_max];
+typedef list_item_t *undo_lists_t[_undo_type_max];
static DWORD
-AddListItem (list_item_t **pfirst, LPVOID data)
+AddListItem(list_item_t **pfirst, LPVOID data)
{
- list_item_t *new_item = malloc (sizeof (list_item_t));
- if (new_item == NULL)
- return ERROR_OUTOFMEMORY;
+ list_item_t *new_item = malloc(sizeof(list_item_t));
+ if (new_item == NULL)
+ {
+ return ERROR_OUTOFMEMORY;
+ }
- new_item->next = *pfirst;
- new_item->data = data;
+ new_item->next = *pfirst;
+ new_item->data = data;
- *pfirst = new_item;
- return NO_ERROR;
+ *pfirst = new_item;
+ return NO_ERROR;
}
typedef BOOL (*match_fn_t) (LPVOID item, LPVOID ctx);
static LPVOID
-RemoveListItem (list_item_t **pfirst, match_fn_t match, LPVOID ctx)
+RemoveListItem(list_item_t **pfirst, match_fn_t match, LPVOID ctx)
{
- LPVOID data = NULL;
- list_item_t **pnext;
+ LPVOID data = NULL;
+ list_item_t **pnext;
- for (pnext = pfirst; *pnext; pnext = &(*pnext)->next)
+ for (pnext = pfirst; *pnext; pnext = &(*pnext)->next)
{
- list_item_t *item = *pnext;
- if (!match (item->data, ctx))
- continue;
+ list_item_t *item = *pnext;
+ if (!match(item->data, ctx))
+ {
+ continue;
+ }
- /* Found item, remove from the list and free memory */
- *pnext = item->next;
- data = item->data;
- free (item);
- break;
+ /* Found item, remove from the list and free memory */
+ *pnext = item->next;
+ data = item->data;
+ free(item);
+ break;
}
- return data;
+ return data;
}
static HANDLE
-CloseHandleEx (LPHANDLE handle)
+CloseHandleEx(LPHANDLE handle)
{
- if (handle && *handle && *handle != INVALID_HANDLE_VALUE)
+ if (handle && *handle && *handle != INVALID_HANDLE_VALUE)
{
- CloseHandle (*handle);
- *handle = INVALID_HANDLE_VALUE;
+ CloseHandle(*handle);
+ *handle = INVALID_HANDLE_VALUE;
}
- return INVALID_HANDLE_VALUE;
+ return INVALID_HANDLE_VALUE;
}
static HANDLE
-InitOverlapped (LPOVERLAPPED overlapped)
+InitOverlapped(LPOVERLAPPED overlapped)
{
- ZeroMemory (overlapped, sizeof (OVERLAPPED));
- overlapped->hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
- return overlapped->hEvent;
+ ZeroMemory(overlapped, sizeof(OVERLAPPED));
+ overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ return overlapped->hEvent;
}
static BOOL
-ResetOverlapped (LPOVERLAPPED overlapped)
+ResetOverlapped(LPOVERLAPPED overlapped)
{
- HANDLE io_event = overlapped->hEvent;
- if (!ResetEvent (io_event))
- return FALSE;
- ZeroMemory (overlapped, sizeof (OVERLAPPED));
- overlapped->hEvent = io_event;
- return TRUE;
+ HANDLE io_event = overlapped->hEvent;
+ if (!ResetEvent(io_event))
+ {
+ return FALSE;
+ }
+ ZeroMemory(overlapped, sizeof(OVERLAPPED));
+ overlapped->hEvent = io_event;
+ return TRUE;
}
typedef enum {
- peek,
- read,
- write
+ peek,
+ read,
+ write
} async_op_t;
static DWORD
-AsyncPipeOp (async_op_t op, HANDLE pipe, LPVOID buffer, DWORD size, DWORD count, LPHANDLE events)
+AsyncPipeOp(async_op_t op, HANDLE pipe, LPVOID buffer, DWORD size, DWORD count, LPHANDLE events)
{
- int i;
- BOOL success;
- HANDLE io_event;
- DWORD res, bytes = 0;
- OVERLAPPED overlapped;
- LPHANDLE handles = NULL;
+ int i;
+ BOOL success;
+ HANDLE io_event;
+ DWORD res, bytes = 0;
+ OVERLAPPED overlapped;
+ LPHANDLE handles = NULL;
- io_event = InitOverlapped (&overlapped);
- if (!io_event)
- goto out;
+ io_event = InitOverlapped(&overlapped);
+ if (!io_event)
+ {
+ goto out;
+ }
- handles = malloc ((count + 1) * sizeof (HANDLE));
- if (!handles)
- goto out;
+ handles = malloc((count + 1) * sizeof(HANDLE));
+ if (!handles)
+ {
+ goto out;
+ }
- if (op == write)
- success = WriteFile (pipe, buffer, size, NULL, &overlapped);
- else
- success = ReadFile (pipe, buffer, size, NULL, &overlapped);
- if (!success && GetLastError () != ERROR_IO_PENDING && GetLastError () != ERROR_MORE_DATA)
- goto out;
+ if (op == write)
+ {
+ success = WriteFile(pipe, buffer, size, NULL, &overlapped);
+ }
+ else
+ {
+ success = ReadFile(pipe, buffer, size, NULL, &overlapped);
+ }
+ if (!success && GetLastError() != ERROR_IO_PENDING && GetLastError() != ERROR_MORE_DATA)
+ {
+ goto out;
+ }
- handles[0] = io_event;
- for (i = 0; i < count; i++)
- handles[i + 1] = events[i];
+ handles[0] = io_event;
+ for (i = 0; i < count; i++)
+ handles[i + 1] = events[i];
- res = WaitForMultipleObjects (count + 1, handles, FALSE,
- op == peek ? INFINITE : IO_TIMEOUT);
- if (res != WAIT_OBJECT_0)
+ res = WaitForMultipleObjects(count + 1, handles, FALSE,
+ op == peek ? INFINITE : IO_TIMEOUT);
+ if (res != WAIT_OBJECT_0)
{
- CancelIo (pipe);
- goto out;
+ CancelIo(pipe);
+ goto out;
}
- if (op == peek)
- PeekNamedPipe (pipe, NULL, 0, NULL, &bytes, NULL);
- else
- GetOverlappedResult (pipe, &overlapped, &bytes, TRUE);
+ if (op == peek)
+ {
+ PeekNamedPipe(pipe, NULL, 0, NULL, &bytes, NULL);
+ }
+ else
+ {
+ GetOverlappedResult(pipe, &overlapped, &bytes, TRUE);
+ }
out:
- CloseHandleEx (&io_event);
- free (handles);
- return bytes;
+ CloseHandleEx(&io_event);
+ free(handles);
+ return bytes;
}
static DWORD
-PeekNamedPipeAsync (HANDLE pipe, DWORD count, LPHANDLE events)
+PeekNamedPipeAsync(HANDLE pipe, DWORD count, LPHANDLE events)
{
- return AsyncPipeOp (peek, pipe, NULL, 0, count, events);
+ return AsyncPipeOp(peek, pipe, NULL, 0, count, events);
}
static DWORD
-ReadPipeAsync (HANDLE pipe, LPVOID buffer, DWORD size, DWORD count, LPHANDLE events)
+ReadPipeAsync(HANDLE pipe, LPVOID buffer, DWORD size, DWORD count, LPHANDLE events)
{
- return AsyncPipeOp (read, pipe, buffer, size, count, events);
+ return AsyncPipeOp(read, pipe, buffer, size, count, events);
}
static DWORD
-WritePipeAsync (HANDLE pipe, LPVOID data, DWORD size, DWORD count, LPHANDLE events)
+WritePipeAsync(HANDLE pipe, LPVOID data, DWORD size, DWORD count, LPHANDLE events)
{
- return AsyncPipeOp (write, pipe, data, size, count, events);
+ return AsyncPipeOp(write, pipe, data, size, count, events);
}
static VOID
-ReturnProcessId (HANDLE pipe, DWORD pid, DWORD count, LPHANDLE events)
+ReturnProcessId(HANDLE pipe, DWORD pid, DWORD count, LPHANDLE events)
{
- const WCHAR msg[] = L"Process ID";
- WCHAR buf[22 + _countof(msg)]; /* 10 chars each for error and PID and 2 for line breaks */
+ const WCHAR msg[] = L"Process ID";
+ WCHAR buf[22 + _countof(msg)]; /* 10 chars each for error and PID and 2 for line breaks */
- /*
- * Same format as error messages (3 line string) with error = 0 in
- * 0x%08x format, PID on line 2 and a description "Process ID" on line 3
- */
- _snwprintf (buf, _countof(buf), L"0x%08x\n0x%08x\n%s", 0, pid, msg);
- buf[_countof(buf) - 1] = '\0';
+ /*
+ * Same format as error messages (3 line string) with error = 0 in
+ * 0x%08x format, PID on line 2 and a description "Process ID" on line 3
+ */
+ _snwprintf(buf, _countof(buf), L"0x%08x\n0x%08x\n%s", 0, pid, msg);
+ buf[_countof(buf) - 1] = '\0';
- WritePipeAsync (pipe, buf, wcslen (buf) * 2, count, events);
+ WritePipeAsync(pipe, buf, wcslen(buf) * 2, count, events);
}
static VOID
-ReturnError (HANDLE pipe, DWORD error, LPCWSTR func, DWORD count, LPHANDLE events)
+ReturnError(HANDLE pipe, DWORD error, LPCWSTR func, DWORD count, LPHANDLE events)
{
- DWORD result_len;
- LPWSTR result = L"0xffffffff\nFormatMessage failed\nCould not return result";
- DWORD_PTR args[] = {
- (DWORD_PTR) error,
- (DWORD_PTR) func,
- (DWORD_PTR) ""
- };
+ DWORD result_len;
+ LPWSTR result = L"0xffffffff\nFormatMessage failed\nCould not return result";
+ DWORD_PTR args[] = {
+ (DWORD_PTR) error,
+ (DWORD_PTR) func,
+ (DWORD_PTR) ""
+ };
- if (error != ERROR_OPENVPN_STARTUP)
+ if (error != ERROR_OPENVPN_STARTUP)
{
- FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- 0, error, 0, (LPWSTR) &args[2], 0, NULL);
+ FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
+ |FORMAT_MESSAGE_ALLOCATE_BUFFER
+ |FORMAT_MESSAGE_IGNORE_INSERTS,
+ 0, error, 0, (LPWSTR) &args[2], 0, NULL);
}
- result_len = FormatMessageW (FORMAT_MESSAGE_FROM_STRING |
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_ARGUMENT_ARRAY,
- L"0x%1!08x!\n%2!s!\n%3!s!", 0, 0,
- (LPWSTR) &result, 0, (va_list*) args);
+ result_len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING
+ |FORMAT_MESSAGE_ALLOCATE_BUFFER
+ |FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ L"0x%1!08x!\n%2!s!\n%3!s!", 0, 0,
+ (LPWSTR) &result, 0, (va_list *) args);
- WritePipeAsync (pipe, result, wcslen (result) * 2, count, events);
+ WritePipeAsync(pipe, result, wcslen(result) * 2, count, events);
#ifdef UNICODE
- MsgToEventLog (MSG_FLAGS_ERROR, result);
+ MsgToEventLog(MSG_FLAGS_ERROR, result);
#else
- MsgToEventLog (MSG_FLAGS_ERROR, "%S", result);
+ MsgToEventLog(MSG_FLAGS_ERROR, "%S", result);
#endif
- if (error != ERROR_OPENVPN_STARTUP)
- LocalFree ((LPVOID) args[2]);
- if (result_len)
- LocalFree (result);
+ if (error != ERROR_OPENVPN_STARTUP)
+ {
+ LocalFree((LPVOID) args[2]);
+ }
+ if (result_len)
+ {
+ LocalFree(result);
+ }
}
static VOID
-ReturnLastError (HANDLE pipe, LPCWSTR func)
+ReturnLastError(HANDLE pipe, LPCWSTR func)
{
- ReturnError (pipe, GetLastError (), func, 1, &exit_event);
+ ReturnError(pipe, GetLastError(), func, 1, &exit_event);
}
static VOID
-ReturnOpenvpnOutput (HANDLE pipe, HANDLE ovpn_output, DWORD count, LPHANDLE events)
+ReturnOpenvpnOutput(HANDLE pipe, HANDLE ovpn_output, DWORD count, LPHANDLE events)
{
- WCHAR *wide_output = NULL;
- CHAR output[512];
- DWORD size;
+ WCHAR *wide_output = NULL;
+ CHAR output[512];
+ DWORD size;
- ReadFile (ovpn_output, output, sizeof (output), &size, NULL);
- if (size == 0)
- return;
+ ReadFile(ovpn_output, output, sizeof(output), &size, NULL);
+ if (size == 0)
+ {
+ return;
+ }
- wide_output = malloc ((size) * sizeof (WCHAR));
- if (wide_output)
+ wide_output = malloc((size) * sizeof(WCHAR));
+ if (wide_output)
{
- MultiByteToWideChar (CP_UTF8, 0, output, size, wide_output, size);
- wide_output[size - 1] = 0;
+ MultiByteToWideChar(CP_UTF8, 0, output, size, wide_output, size);
+ wide_output[size - 1] = 0;
}
- ReturnError (pipe, ERROR_OPENVPN_STARTUP, wide_output, count, events);
- free (wide_output);
+ ReturnError(pipe, ERROR_OPENVPN_STARTUP, wide_output, count, events);
+ free(wide_output);
}
/*
@@ -328,7 +354,7 @@ ReturnOpenvpnOutput (HANDLE pipe, HANDLE ovpn_output, DWORD count, LPHANDLE even
* Returns true on success
*/
static BOOL
-ValidateOptions (HANDLE pipe, const WCHAR *workdir, const WCHAR *options)
+ValidateOptions(HANDLE pipe, const WCHAR *workdir, const WCHAR *options)
{
WCHAR **argv;
int argc;
@@ -340,15 +366,15 @@ ValidateOptions (HANDLE pipe, const WCHAR *workdir, const WCHAR *options)
" by adding your account to the \"%s\" group";
const WCHAR *msg2 = L"You have specified an option (%s) that may be used"
- " only with admin approval. This error may be avoided"
- " by adding your account to the \"%s\" group";
+ " only with admin approval. This error may be avoided"
+ " by adding your account to the \"%s\" group";
- argv = CommandLineToArgvW (options, &argc);
+ argv = CommandLineToArgvW(options, &argc);
if (!argv)
{
- ReturnLastError (pipe, L"CommandLineToArgvW");
- ReturnError (pipe, ERROR_STARTUP_DATA, L"Cannot validate options", 1, &exit_event);
+ ReturnLastError(pipe, L"CommandLineToArgvW");
+ ReturnError(pipe, ERROR_STARTUP_DATA, L"Cannot validate options", 1, &exit_event);
goto out;
}
@@ -366,12 +392,12 @@ ValidateOptions (HANDLE pipe, const WCHAR *workdir, const WCHAR *options)
{
WCHAR *argv_tmp[2] = { L"--config", argv[0] };
- if (!CheckOption (workdir, 2, argv_tmp, &settings))
+ if (!CheckOption(workdir, 2, argv_tmp, &settings))
{
- snwprintf (buf, _countof(buf), msg1, argv[0], workdir,
- settings.ovpn_admin_group);
+ snwprintf(buf, _countof(buf), msg1, argv[0], workdir,
+ settings.ovpn_admin_group);
buf[_countof(buf) - 1] = L'\0';
- ReturnError (pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
+ ReturnError(pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
}
goto out;
}
@@ -379,23 +405,25 @@ ValidateOptions (HANDLE pipe, const WCHAR *workdir, const WCHAR *options)
for (i = 0; i < argc; ++i)
{
if (!IsOption(argv[i]))
+ {
continue;
+ }
- if (!CheckOption (workdir, argc-i, &argv[i], &settings))
+ if (!CheckOption(workdir, argc-i, &argv[i], &settings))
{
if (wcscmp(L"--config", argv[i]) == 0 && argc-i > 1)
{
- snwprintf (buf, _countof(buf), msg1, argv[i+1], workdir,
- settings.ovpn_admin_group);
+ snwprintf(buf, _countof(buf), msg1, argv[i+1], workdir,
+ settings.ovpn_admin_group);
buf[_countof(buf) - 1] = L'\0';
- ReturnError (pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
+ ReturnError(pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
}
else
{
- snwprintf (buf, _countof(buf), msg2, argv[i],
- settings.ovpn_admin_group);
+ snwprintf(buf, _countof(buf), msg2, argv[i],
+ settings.ovpn_admin_group);
buf[_countof(buf) - 1] = L'\0';
- ReturnError (pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
+ ReturnError(pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
}
goto out;
}
@@ -406,427 +434,494 @@ ValidateOptions (HANDLE pipe, const WCHAR *workdir, const WCHAR *options)
out:
if (argv)
- LocalFree (argv);
+ {
+ LocalFree(argv);
+ }
return ret;
}
static BOOL
-GetStartupData (HANDLE pipe, STARTUP_DATA *sud)
+GetStartupData(HANDLE pipe, STARTUP_DATA *sud)
{
- size_t len;
- BOOL ret = FALSE;
- WCHAR *data = NULL;
- DWORD size, bytes, read;
+ size_t len;
+ BOOL ret = FALSE;
+ WCHAR *data = NULL;
+ DWORD size, bytes, read;
- bytes = PeekNamedPipeAsync (pipe, 1, &exit_event);
- if (bytes == 0)
+ bytes = PeekNamedPipeAsync(pipe, 1, &exit_event);
+ if (bytes == 0)
{
- MsgToEventLog (M_SYSERR, TEXT("PeekNamedPipeAsync failed"));
- ReturnLastError (pipe, L"PeekNamedPipeAsync");
- goto out;
+ MsgToEventLog(M_SYSERR, TEXT("PeekNamedPipeAsync failed"));
+ ReturnLastError(pipe, L"PeekNamedPipeAsync");
+ goto out;
}
- size = bytes / sizeof (*data);
- data = malloc (bytes);
- if (data == NULL)
+ size = bytes / sizeof(*data);
+ data = malloc(bytes);
+ if (data == NULL)
{
- MsgToEventLog (M_SYSERR, TEXT("malloc failed"));
- ReturnLastError (pipe, L"malloc");
- goto out;
+ MsgToEventLog(M_SYSERR, TEXT("malloc failed"));
+ ReturnLastError(pipe, L"malloc");
+ goto out;
}
- read = ReadPipeAsync (pipe, data, bytes, 1, &exit_event);
- if (bytes != read)
- {
- MsgToEventLog (M_SYSERR, TEXT("ReadPipeAsync failed"));
- ReturnLastError (pipe, L"ReadPipeAsync");
- goto out;
- }
+ read = ReadPipeAsync(pipe, data, bytes, 1, &exit_event);
+ if (bytes != read)
+ {
+ MsgToEventLog(M_SYSERR, TEXT("ReadPipeAsync failed"));
+ ReturnLastError(pipe, L"ReadPipeAsync");
+ goto out;
+ }
- if (data[size - 1] != 0)
+ if (data[size - 1] != 0)
{
- MsgToEventLog (M_ERR, TEXT("Startup data is not NULL terminated"));
- ReturnError (pipe, ERROR_STARTUP_DATA, L"GetStartupData", 1, &exit_event);
- goto out;
+ MsgToEventLog(M_ERR, TEXT("Startup data is not NULL terminated"));
+ ReturnError(pipe, ERROR_STARTUP_DATA, L"GetStartupData", 1, &exit_event);
+ goto out;
}
- sud->directory = data;
- len = wcslen (sud->directory) + 1;
- size -= len;
- if (size <= 0)
+ sud->directory = data;
+ len = wcslen(sud->directory) + 1;
+ size -= len;
+ if (size <= 0)
{
- MsgToEventLog (M_ERR, TEXT("Startup data ends at working directory"));
- ReturnError (pipe, ERROR_STARTUP_DATA, L"GetStartupData", 1, &exit_event);
- goto out;
+ MsgToEventLog(M_ERR, TEXT("Startup data ends at working directory"));
+ ReturnError(pipe, ERROR_STARTUP_DATA, L"GetStartupData", 1, &exit_event);
+ goto out;
}
- sud->options = sud->directory + len;
- len = wcslen (sud->options) + 1;
- size -= len;
- if (size <= 0)
+ sud->options = sud->directory + len;
+ len = wcslen(sud->options) + 1;
+ size -= len;
+ if (size <= 0)
{
- MsgToEventLog (M_ERR, TEXT("Startup data ends at command line options"));
- ReturnError (pipe, ERROR_STARTUP_DATA, L"GetStartupData", 1, &exit_event);
- goto out;
+ MsgToEventLog(M_ERR, TEXT("Startup data ends at command line options"));
+ ReturnError(pipe, ERROR_STARTUP_DATA, L"GetStartupData", 1, &exit_event);
+ goto out;
}
- sud->std_input = sud->options + len;
- data = NULL; /* don't free data */
- ret = TRUE;
+ sud->std_input = sud->options + len;
+ data = NULL; /* don't free data */
+ ret = TRUE;
out:
- free (data);
- return ret;
+ free(data);
+ return ret;
}
static VOID
-FreeStartupData (STARTUP_DATA *sud)
+FreeStartupData(STARTUP_DATA *sud)
{
- free (sud->directory);
+ free(sud->directory);
}
static SOCKADDR_INET
-sockaddr_inet (short family, inet_address_t *addr)
+sockaddr_inet(short family, inet_address_t *addr)
{
- SOCKADDR_INET sa_inet;
- ZeroMemory (&sa_inet, sizeof (sa_inet));
- sa_inet.si_family = family;
- if (family == AF_INET)
- sa_inet.Ipv4.sin_addr = addr->ipv4;
- else if (family == AF_INET6)
- sa_inet.Ipv6.sin6_addr = addr->ipv6;
- return sa_inet;
+ SOCKADDR_INET sa_inet;
+ ZeroMemory(&sa_inet, sizeof(sa_inet));
+ sa_inet.si_family = family;
+ if (family == AF_INET)
+ {
+ sa_inet.Ipv4.sin_addr = addr->ipv4;
+ }
+ else if (family == AF_INET6)
+ {
+ sa_inet.Ipv6.sin6_addr = addr->ipv6;
+ }
+ return sa_inet;
}
static DWORD
-InterfaceLuid (const char *iface_name, PNET_LUID luid)
+InterfaceLuid(const char *iface_name, PNET_LUID luid)
{
- NETIO_STATUS status;
- LPWSTR wide_name;
- int n;
+ NETIO_STATUS status;
+ LPWSTR wide_name;
+ int n;
- typedef NETIO_STATUS WINAPI (*ConvertInterfaceAliasToLuidFn) (LPCWSTR, PNET_LUID);
- static ConvertInterfaceAliasToLuidFn ConvertInterfaceAliasToLuid = NULL;
- if (!ConvertInterfaceAliasToLuid)
+ typedef NETIO_STATUS WINAPI (*ConvertInterfaceAliasToLuidFn) (LPCWSTR, PNET_LUID);
+ static ConvertInterfaceAliasToLuidFn ConvertInterfaceAliasToLuid = NULL;
+ if (!ConvertInterfaceAliasToLuid)
{
- HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll"));
- if (iphlpapi == NULL)
- return GetLastError ();
+ HMODULE iphlpapi = GetModuleHandle(TEXT("iphlpapi.dll"));
+ if (iphlpapi == NULL)
+ {
+ return GetLastError();
+ }
- ConvertInterfaceAliasToLuid = (ConvertInterfaceAliasToLuidFn) GetProcAddress (iphlpapi, "ConvertInterfaceAliasToLuid");
- if (!ConvertInterfaceAliasToLuid)
- return GetLastError ();
+ ConvertInterfaceAliasToLuid = (ConvertInterfaceAliasToLuidFn) GetProcAddress(iphlpapi, "ConvertInterfaceAliasToLuid");
+ if (!ConvertInterfaceAliasToLuid)
+ {
+ return GetLastError();
+ }
}
- n = MultiByteToWideChar (CP_UTF8, 0, iface_name, -1, NULL, 0);
- wide_name = malloc (n * sizeof (WCHAR));
- MultiByteToWideChar (CP_UTF8, 0, iface_name, -1, wide_name, n);
- status = ConvertInterfaceAliasToLuid (wide_name, luid);
- free (wide_name);
+ n = MultiByteToWideChar(CP_UTF8, 0, iface_name, -1, NULL, 0);
+ wide_name = malloc(n * sizeof(WCHAR));
+ MultiByteToWideChar(CP_UTF8, 0, iface_name, -1, wide_name, n);
+ status = ConvertInterfaceAliasToLuid(wide_name, luid);
+ free(wide_name);
- return status;
+ return status;
}
static BOOL
-CmpAddress (LPVOID item, LPVOID address)
+CmpAddress(LPVOID item, LPVOID address)
{
- return memcmp (item, address, sizeof (MIB_UNICASTIPADDRESS_ROW)) == 0 ? TRUE : FALSE;
+ return memcmp(item, address, sizeof(MIB_UNICASTIPADDRESS_ROW)) == 0 ? TRUE : FALSE;
}
static DWORD
-DeleteAddress (PMIB_UNICASTIPADDRESS_ROW addr_row)
+DeleteAddress(PMIB_UNICASTIPADDRESS_ROW addr_row)
{
- typedef NETIOAPI_API (*DeleteUnicastIpAddressEntryFn) (const PMIB_UNICASTIPADDRESS_ROW);
- static DeleteUnicastIpAddressEntryFn DeleteUnicastIpAddressEntry = NULL;
+ typedef NETIOAPI_API (*DeleteUnicastIpAddressEntryFn) (const PMIB_UNICASTIPADDRESS_ROW);
+ static DeleteUnicastIpAddressEntryFn DeleteUnicastIpAddressEntry = NULL;
- if (!DeleteUnicastIpAddressEntry)
+ if (!DeleteUnicastIpAddressEntry)
{
- HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll"));
- if (iphlpapi == NULL)
- return GetLastError ();
+ HMODULE iphlpapi = GetModuleHandle(TEXT("iphlpapi.dll"));
+ if (iphlpapi == NULL)
+ {
+ return GetLastError();
+ }
- DeleteUnicastIpAddressEntry = (DeleteUnicastIpAddressEntryFn) GetProcAddress (iphlpapi, "DeleteUnicastIpAddressEntry");
- if (!DeleteUnicastIpAddressEntry)
- return GetLastError ();
+ DeleteUnicastIpAddressEntry = (DeleteUnicastIpAddressEntryFn) GetProcAddress(iphlpapi, "DeleteUnicastIpAddressEntry");
+ if (!DeleteUnicastIpAddressEntry)
+ {
+ return GetLastError();
+ }
}
- return DeleteUnicastIpAddressEntry (addr_row);
+ return DeleteUnicastIpAddressEntry(addr_row);
}
static DWORD
-HandleAddressMessage (address_message_t *msg, undo_lists_t *lists)
+HandleAddressMessage(address_message_t *msg, undo_lists_t *lists)
{
- DWORD err;
- PMIB_UNICASTIPADDRESS_ROW addr_row;
- BOOL add = msg->header.type == msg_add_address;
+ DWORD err;
+ PMIB_UNICASTIPADDRESS_ROW addr_row;
+ BOOL add = msg->header.type == msg_add_address;
- typedef NETIOAPI_API (*CreateUnicastIpAddressEntryFn) (const PMIB_UNICASTIPADDRESS_ROW);
- typedef NETIOAPI_API (*InitializeUnicastIpAddressEntryFn) (PMIB_UNICASTIPADDRESS_ROW);
- static CreateUnicastIpAddressEntryFn CreateUnicastIpAddressEntry = NULL;
- static InitializeUnicastIpAddressEntryFn InitializeUnicastIpAddressEntry = NULL;
+ typedef NETIOAPI_API (*CreateUnicastIpAddressEntryFn) (const PMIB_UNICASTIPADDRESS_ROW);
+ typedef NETIOAPI_API (*InitializeUnicastIpAddressEntryFn) (PMIB_UNICASTIPADDRESS_ROW);
+ static CreateUnicastIpAddressEntryFn CreateUnicastIpAddressEntry = NULL;
+ static InitializeUnicastIpAddressEntryFn InitializeUnicastIpAddressEntry = NULL;
- if (!CreateUnicastIpAddressEntry || !InitializeUnicastIpAddressEntry)
+ if (!CreateUnicastIpAddressEntry || !InitializeUnicastIpAddressEntry)
{
- HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll"));
- if (iphlpapi == NULL)
- return GetLastError ();
+ HMODULE iphlpapi = GetModuleHandle(TEXT("iphlpapi.dll"));
+ if (iphlpapi == NULL)
+ {
+ return GetLastError();
+ }
- CreateUnicastIpAddressEntry = (CreateUnicastIpAddressEntryFn) GetProcAddress (iphlpapi, "CreateUnicastIpAddressEntry");
- if (!CreateUnicastIpAddressEntry)
- return GetLastError ();
+ CreateUnicastIpAddressEntry = (CreateUnicastIpAddressEntryFn) GetProcAddress(iphlpapi, "CreateUnicastIpAddressEntry");
+ if (!CreateUnicastIpAddressEntry)
+ {
+ return GetLastError();
+ }
- InitializeUnicastIpAddressEntry = (InitializeUnicastIpAddressEntryFn) GetProcAddress (iphlpapi, "InitializeUnicastIpAddressEntry");
- if (!InitializeUnicastIpAddressEntry)
- return GetLastError ();
+ InitializeUnicastIpAddressEntry = (InitializeUnicastIpAddressEntryFn) GetProcAddress(iphlpapi, "InitializeUnicastIpAddressEntry");
+ if (!InitializeUnicastIpAddressEntry)
+ {
+ return GetLastError();
+ }
}
- addr_row = malloc (sizeof (*addr_row));
- if (addr_row == NULL)
- return ERROR_OUTOFMEMORY;
+ addr_row = malloc(sizeof(*addr_row));
+ if (addr_row == NULL)
+ {
+ return ERROR_OUTOFMEMORY;
+ }
- InitializeUnicastIpAddressEntry (addr_row);
- addr_row->Address = sockaddr_inet (msg->family, &msg->address);
- addr_row->OnLinkPrefixLength = (UINT8) msg->prefix_len;
+ InitializeUnicastIpAddressEntry(addr_row);
+ addr_row->Address = sockaddr_inet(msg->family, &msg->address);
+ addr_row->OnLinkPrefixLength = (UINT8) msg->prefix_len;
- if (msg->iface.index != -1)
+ if (msg->iface.index != -1)
{
- addr_row->InterfaceIndex = msg->iface.index;
+ addr_row->InterfaceIndex = msg->iface.index;
}
- else
+ else
{
- NET_LUID luid;
- err = InterfaceLuid (msg->iface.name, &luid);
- if (err)
- goto out;
- addr_row->InterfaceLuid = luid;
+ NET_LUID luid;
+ err = InterfaceLuid(msg->iface.name, &luid);
+ if (err)
+ {
+ goto out;
+ }
+ addr_row->InterfaceLuid = luid;
}
- if (add)
+ if (add)
{
- err = CreateUnicastIpAddressEntry (addr_row);
- if (err)
- goto out;
+ err = CreateUnicastIpAddressEntry(addr_row);
+ if (err)
+ {
+ goto out;
+ }
- err = AddListItem (&(*lists)[address], addr_row);
- if (err)
- DeleteAddress (addr_row);
+ err = AddListItem(&(*lists)[address], addr_row);
+ if (err)
+ {
+ DeleteAddress(addr_row);
+ }
}
- else
+ else
{
- err = DeleteAddress (addr_row);
- if (err)
- goto out;
+ err = DeleteAddress(addr_row);
+ if (err)
+ {
+ goto out;
+ }
- free (RemoveListItem (&(*lists)[address], CmpAddress, addr_row));
+ free(RemoveListItem(&(*lists)[address], CmpAddress, addr_row));
}
out:
- if (!add || err)
- free (addr_row);
+ if (!add || err)
+ {
+ free(addr_row);
+ }
- return err;
+ return err;
}
static BOOL
-CmpRoute (LPVOID item, LPVOID route)
+CmpRoute(LPVOID item, LPVOID route)
{
- return memcmp (item, route, sizeof (MIB_IPFORWARD_ROW2)) == 0 ? TRUE : FALSE;
+ return memcmp(item, route, sizeof(MIB_IPFORWARD_ROW2)) == 0 ? TRUE : FALSE;
}
static DWORD
-DeleteRoute (PMIB_IPFORWARD_ROW2 fwd_row)
+DeleteRoute(PMIB_IPFORWARD_ROW2 fwd_row)
{
- typedef NETIOAPI_API (*DeleteIpForwardEntry2Fn) (PMIB_IPFORWARD_ROW2);
- static DeleteIpForwardEntry2Fn DeleteIpForwardEntry2 = NULL;
+ typedef NETIOAPI_API (*DeleteIpForwardEntry2Fn) (PMIB_IPFORWARD_ROW2);
+ static DeleteIpForwardEntry2Fn DeleteIpForwardEntry2 = NULL;
- if (!DeleteIpForwardEntry2)
+ if (!DeleteIpForwardEntry2)
{
- HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll"));
- if (iphlpapi == NULL)
- return GetLastError ();
+ HMODULE iphlpapi = GetModuleHandle(TEXT("iphlpapi.dll"));
+ if (iphlpapi == NULL)
+ {
+ return GetLastError();
+ }
- DeleteIpForwardEntry2 = (DeleteIpForwardEntry2Fn) GetProcAddress (iphlpapi, "DeleteIpForwardEntry2");
- if (!DeleteIpForwardEntry2)
- return GetLastError ();
+ DeleteIpForwardEntry2 = (DeleteIpForwardEntry2Fn) GetProcAddress(iphlpapi, "DeleteIpForwardEntry2");
+ if (!DeleteIpForwardEntry2)
+ {
+ return GetLastError();
+ }
}
- return DeleteIpForwardEntry2 (fwd_row);
+ return DeleteIpForwardEntry2(fwd_row);
}
static DWORD
-HandleRouteMessage (route_message_t *msg, undo_lists_t *lists)
+HandleRouteMessage(route_message_t *msg, undo_lists_t *lists)
{
- DWORD err;
- PMIB_IPFORWARD_ROW2 fwd_row;
- BOOL add = msg->header.type == msg_add_route;
+ DWORD err;
+ PMIB_IPFORWARD_ROW2 fwd_row;
+ BOOL add = msg->header.type == msg_add_route;
- typedef NETIOAPI_API (*CreateIpForwardEntry2Fn) (PMIB_IPFORWARD_ROW2);
- static CreateIpForwardEntry2Fn CreateIpForwardEntry2 = NULL;
+ typedef NETIOAPI_API (*CreateIpForwardEntry2Fn) (PMIB_IPFORWARD_ROW2);
+ static CreateIpForwardEntry2Fn CreateIpForwardEntry2 = NULL;
- if (!CreateIpForwardEntry2)
+ if (!CreateIpForwardEntry2)
{
- HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll"));
- if (iphlpapi == NULL)
- return GetLastError ();
+ HMODULE iphlpapi = GetModuleHandle(TEXT("iphlpapi.dll"));
+ if (iphlpapi == NULL)
+ {
+ return GetLastError();
+ }
- CreateIpForwardEntry2 = (CreateIpForwardEntry2Fn) GetProcAddress (iphlpapi, "CreateIpForwardEntry2");
- if (!CreateIpForwardEntry2)
- return GetLastError ();
+ CreateIpForwardEntry2 = (CreateIpForwardEntry2Fn) GetProcAddress(iphlpapi, "CreateIpForwardEntry2");
+ if (!CreateIpForwardEntry2)
+ {
+ return GetLastError();
+ }
}
- fwd_row = malloc (sizeof (*fwd_row));
- if (fwd_row == NULL)
- return ERROR_OUTOFMEMORY;
+ fwd_row = malloc(sizeof(*fwd_row));
+ if (fwd_row == NULL)
+ {
+ return ERROR_OUTOFMEMORY;
+ }
- ZeroMemory (fwd_row, sizeof (*fwd_row));
- fwd_row->ValidLifetime = 0xffffffff;
- fwd_row->PreferredLifetime = 0xffffffff;
- fwd_row->Protocol = MIB_IPPROTO_NETMGMT;
- fwd_row->Metric = msg->metric;
- fwd_row->DestinationPrefix.Prefix = sockaddr_inet (msg->family, &msg->prefix);
- fwd_row->DestinationPrefix.PrefixLength = (UINT8) msg->prefix_len;
- fwd_row->NextHop = sockaddr_inet (msg->family, &msg->gateway);
+ ZeroMemory(fwd_row, sizeof(*fwd_row));
+ fwd_row->ValidLifetime = 0xffffffff;
+ fwd_row->PreferredLifetime = 0xffffffff;
+ fwd_row->Protocol = MIB_IPPROTO_NETMGMT;
+ fwd_row->Metric = msg->metric;
+ fwd_row->DestinationPrefix.Prefix = sockaddr_inet(msg->family, &msg->prefix);
+ fwd_row->DestinationPrefix.PrefixLength = (UINT8) msg->prefix_len;
+ fwd_row->NextHop = sockaddr_inet(msg->family, &msg->gateway);
- if (msg->iface.index != -1)
+ if (msg->iface.index != -1)
{
- fwd_row->InterfaceIndex = msg->iface.index;
+ fwd_row->InterfaceIndex = msg->iface.index;
}
- else if (strlen (msg->iface.name))
+ else if (strlen(msg->iface.name))
{
- NET_LUID luid;
- err = InterfaceLuid (msg->iface.name, &luid);
- if (err)
- goto out;
- fwd_row->InterfaceLuid = luid;
+ NET_LUID luid;
+ err = InterfaceLuid(msg->iface.name, &luid);
+ if (err)
+ {
+ goto out;
+ }
+ fwd_row->InterfaceLuid = luid;
}
- if (add)
+ if (add)
{
- err = CreateIpForwardEntry2 (fwd_row);
- if (err)
- goto out;
+ err = CreateIpForwardEntry2(fwd_row);
+ if (err)
+ {
+ goto out;
+ }
- err = AddListItem (&(*lists)[route], fwd_row);
- if (err)
- DeleteRoute (fwd_row);
+ err = AddListItem(&(*lists)[route], fwd_row);
+ if (err)
+ {
+ DeleteRoute(fwd_row);
+ }
}
- else
+ else
{
- err = DeleteRoute (fwd_row);
- if (err)
- goto out;
+ err = DeleteRoute(fwd_row);
+ if (err)
+ {
+ goto out;
+ }
- free (RemoveListItem (&(*lists)[route], CmpRoute, fwd_row));
+ free(RemoveListItem(&(*lists)[route], CmpRoute, fwd_row));
}
out:
- if (!add || err)
- free (fwd_row);
+ if (!add || err)
+ {
+ free(fwd_row);
+ }
- return err;
+ return err;
}
static DWORD
-HandleFlushNeighborsMessage (flush_neighbors_message_t *msg)
+HandleFlushNeighborsMessage(flush_neighbors_message_t *msg)
{
- typedef NETIOAPI_API (*FlushIpNetTable2Fn) (ADDRESS_FAMILY, NET_IFINDEX);
- static FlushIpNetTable2Fn flush_fn = NULL;
+ typedef NETIOAPI_API (*FlushIpNetTable2Fn) (ADDRESS_FAMILY, NET_IFINDEX);
+ static FlushIpNetTable2Fn flush_fn = NULL;
- if (msg->family == AF_INET)
- return FlushIpNetTable (msg->iface.index);
+ if (msg->family == AF_INET)
+ {
+ return FlushIpNetTable(msg->iface.index);
+ }
- if (!flush_fn)
+ if (!flush_fn)
{
- HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll"));
- if (iphlpapi == NULL)
- return GetLastError ();
+ HMODULE iphlpapi = GetModuleHandle(TEXT("iphlpapi.dll"));
+ if (iphlpapi == NULL)
+ {
+ return GetLastError();
+ }
- flush_fn = (FlushIpNetTable2Fn) GetProcAddress (iphlpapi, "FlushIpNetTable2");
- if (!flush_fn)
+ flush_fn = (FlushIpNetTable2Fn) GetProcAddress(iphlpapi, "FlushIpNetTable2");
+ if (!flush_fn)
{
- if (GetLastError () == ERROR_PROC_NOT_FOUND)
- return WSAEPFNOSUPPORT;
- else
- return GetLastError ();
+ if (GetLastError() == ERROR_PROC_NOT_FOUND)
+ {
+ return WSAEPFNOSUPPORT;
+ }
+ else
+ {
+ return GetLastError();
+ }
}
}
- return flush_fn (msg->family, msg->iface.index);
+ return flush_fn(msg->family, msg->iface.index);
}
static void
-BlockDNSErrHandler (DWORD err, const char *msg)
+BlockDNSErrHandler(DWORD err, const char *msg)
{
- TCHAR buf[256];
- LPCTSTR err_str;
+ TCHAR buf[256];
+ LPCTSTR err_str;
- if (!err) return;
+ if (!err)
+ {
+ return;
+ }
- err_str = TEXT("Unknown Win32 Error");
+ err_str = TEXT("Unknown Win32 Error");
- if (FormatMessage (FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM
- | FORMAT_MESSAGE_ARGUMENT_ARRAY,
- NULL, err, 0, buf, sizeof (buf), NULL))
+ if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ NULL, err, 0, buf, sizeof(buf), NULL))
{
- err_str = buf;
+ err_str = buf;
}
#ifdef UNICODE
- MsgToEventLog (M_ERR, L"%S (status = %lu): %s", msg, err, err_str);
+ MsgToEventLog(M_ERR, L"%S (status = %lu): %s", msg, err, err_str);
#else
- MsgToEventLog (M_ERR, "%s (status = %lu): %s", msg, err, err_str);
+ MsgToEventLog(M_ERR, "%s (status = %lu): %s", msg, err, err_str);
#endif
}
/* Use an always-true match_fn to get the head of the list */
static BOOL
-CmpEngine (LPVOID item, LPVOID any)
+CmpEngine(LPVOID item, LPVOID any)
{
- return TRUE;
+ return TRUE;
}
static DWORD
-HandleBlockDNSMessage (const block_dns_message_t *msg, undo_lists_t *lists)
+HandleBlockDNSMessage(const block_dns_message_t *msg, undo_lists_t *lists)
{
- DWORD err = 0;
- HANDLE engine = NULL;
- LPCWSTR exe_path;
+ DWORD err = 0;
+ HANDLE engine = NULL;
+ LPCWSTR exe_path;
#ifdef UNICODE
- exe_path = settings.exe_path;
+ exe_path = settings.exe_path;
#else
- WCHAR wide_path[MAX_PATH];
- MultiByteToWideChar (CP_UTF8, 0, settings.exe_path, MAX_PATH, wide_path, MAX_PATH);
- exe_path = wide_path;
+ WCHAR wide_path[MAX_PATH];
+ MultiByteToWideChar(CP_UTF8, 0, settings.exe_path, MAX_PATH, wide_path, MAX_PATH);
+ exe_path = wide_path;
#endif
- if (msg->header.type == msg_add_block_dns)
+ if (msg->header.type == msg_add_block_dns)
{
- err = add_block_dns_filters (&engine, msg->iface.index, exe_path, BlockDNSErrHandler);
- if (!err)
- err = AddListItem (&(*lists)[block_dns], engine);
+ err = add_block_dns_filters(&engine, msg->iface.index, exe_path, BlockDNSErrHandler);
+ if (!err)
+ {
+ err = AddListItem(&(*lists)[block_dns], engine);
+ }
}
- else
+ else
{
- engine = RemoveListItem (&(*lists)[block_dns], CmpEngine, NULL);
- if (engine)
+ engine = RemoveListItem(&(*lists)[block_dns], CmpEngine, NULL);
+ if (engine)
+ {
+ err = delete_block_dns_filters(engine);
+ engine = NULL;
+ }
+ else
{
- err = delete_block_dns_filters (engine);
- engine = NULL;
+ MsgToEventLog(M_ERR, TEXT("No previous block DNS filters to delete"));
}
- else
- MsgToEventLog (M_ERR, TEXT("No previous block DNS filters to delete"));
}
- if (err && engine)
+ if (err && engine)
{
- delete_block_dns_filters (engine);
+ delete_block_dns_filters(engine);
}
- return err;
+ return err;
}
/*
@@ -835,133 +930,141 @@ HandleBlockDNSMessage (const block_dns_message_t *msg, undo_lists_t *lists)
* the return value is the windows error code WAIT_TIMEOUT = 0x102
*/
static DWORD
-ExecCommand (const WCHAR *argv0, const WCHAR *cmdline, DWORD timeout)
+ExecCommand(const WCHAR *argv0, const WCHAR *cmdline, DWORD timeout)
{
- DWORD exit_code;
- STARTUPINFOW si;
- PROCESS_INFORMATION pi;
- DWORD proc_flags = CREATE_NO_WINDOW|CREATE_UNICODE_ENVIRONMENT;
- WCHAR *cmdline_dup = NULL;
+ DWORD exit_code;
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+ DWORD proc_flags = CREATE_NO_WINDOW|CREATE_UNICODE_ENVIRONMENT;
+ WCHAR *cmdline_dup = NULL;
- ZeroMemory (&si, sizeof(si));
- ZeroMemory (&pi, sizeof(pi));
+ ZeroMemory(&si, sizeof(si));
+ ZeroMemory(&pi, sizeof(pi));
- si.cb = sizeof(si);
+ si.cb = sizeof(si);
- /* CreateProcess needs a modifiable cmdline: make a copy */
- cmdline_dup = wcsdup (cmdline);
- if ( cmdline_dup && CreateProcessW (argv0, cmdline_dup, NULL, NULL, FALSE,
+ /* CreateProcess needs a modifiable cmdline: make a copy */
+ cmdline_dup = wcsdup(cmdline);
+ if (cmdline_dup && CreateProcessW(argv0, cmdline_dup, NULL, NULL, FALSE,
proc_flags, NULL, NULL, &si, &pi) )
{
- WaitForSingleObject (pi.hProcess, timeout ? timeout : INFINITE);
- if (!GetExitCodeProcess (pi.hProcess, &exit_code))
+ WaitForSingleObject(pi.hProcess, timeout ? timeout : INFINITE);
+ if (!GetExitCodeProcess(pi.hProcess, &exit_code))
{
- MsgToEventLog (M_SYSERR, TEXT("ExecCommand: Error getting exit_code:"));
- exit_code = GetLastError();
+ MsgToEventLog(M_SYSERR, TEXT("ExecCommand: Error getting exit_code:"));
+ exit_code = GetLastError();
}
- else if (exit_code == STILL_ACTIVE)
+ else if (exit_code == STILL_ACTIVE)
{
- exit_code = WAIT_TIMEOUT; /* Windows error code 0x102 */
+ exit_code = WAIT_TIMEOUT; /* Windows error code 0x102 */
- /* kill without impunity */
- TerminateProcess (pi.hProcess, exit_code);
- MsgToEventLog (M_ERR, TEXT("ExecCommand: \"%s %s\" killed after timeout"),
- argv0, cmdline);
+ /* kill without impunity */
+ TerminateProcess(pi.hProcess, exit_code);
+ MsgToEventLog(M_ERR, TEXT("ExecCommand: \"%s %s\" killed after timeout"),
+ argv0, cmdline);
}
- else if (exit_code)
- MsgToEventLog (M_ERR, TEXT("ExecCommand: \"%s %s\" exited with status = %lu"),
+ else if (exit_code)
+ {
+ MsgToEventLog(M_ERR, TEXT("ExecCommand: \"%s %s\" exited with status = %lu"),
argv0, cmdline, exit_code);
- else
- MsgToEventLog (M_INFO, TEXT("ExecCommand: \"%s %s\" completed"), argv0, cmdline);
+ }
+ else
+ {
+ MsgToEventLog(M_INFO, TEXT("ExecCommand: \"%s %s\" completed"), argv0, cmdline);
+ }
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
}
- else
+ else
{
- exit_code = GetLastError();
- MsgToEventLog (M_SYSERR, TEXT("ExecCommand: could not run \"%s %s\" :"),
- argv0, cmdline);
+ exit_code = GetLastError();
+ MsgToEventLog(M_SYSERR, TEXT("ExecCommand: could not run \"%s %s\" :"),
+ argv0, cmdline);
}
- free (cmdline_dup);
- return exit_code;
+ free(cmdline_dup);
+ return exit_code;
}
/*
* Entry point for register-dns thread.
*/
static DWORD WINAPI
-RegisterDNS (LPVOID unused)
+RegisterDNS(LPVOID unused)
{
- DWORD err;
- DWORD i;
- WCHAR sys_path[MAX_PATH];
- DWORD timeout = RDNS_TIMEOUT * 1000; /* in milliseconds */
+ DWORD err;
+ DWORD i;
+ WCHAR sys_path[MAX_PATH];
+ DWORD timeout = RDNS_TIMEOUT * 1000; /* in milliseconds */
- /* default path of ipconfig command */
- WCHAR ipcfg[MAX_PATH] = L"C:\\Windows\\system32\\ipconfig.exe";
+ /* default path of ipconfig command */
+ WCHAR ipcfg[MAX_PATH] = L"C:\\Windows\\system32\\ipconfig.exe";
- struct
+ struct
{
- WCHAR *argv0;
- WCHAR *cmdline;
- DWORD timeout;
+ WCHAR *argv0;
+ WCHAR *cmdline;
+ DWORD timeout;
} cmds [] = {
- { ipcfg, L"ipconfig /flushdns", timeout },
- { ipcfg, L"ipconfig /registerdns", timeout },
- };
- int ncmds = sizeof (cmds) / sizeof (cmds[0]);
+ { ipcfg, L"ipconfig /flushdns", timeout },
+ { ipcfg, L"ipconfig /registerdns", timeout },
+ };
+ int ncmds = sizeof(cmds) / sizeof(cmds[0]);
- HANDLE wait_handles[2] = {rdns_semaphore, exit_event};
+ HANDLE wait_handles[2] = {rdns_semaphore, exit_event};
- if(GetSystemDirectory(sys_path, MAX_PATH))
+ if (GetSystemDirectory(sys_path, MAX_PATH))
{
- _snwprintf (ipcfg, MAX_PATH, L"%s\\%s", sys_path, L"ipconfig.exe");
- ipcfg[MAX_PATH-1] = L'\0';
+ _snwprintf(ipcfg, MAX_PATH, L"%s\\%s", sys_path, L"ipconfig.exe");
+ ipcfg[MAX_PATH-1] = L'\0';
}
- if (WaitForMultipleObjects (2, wait_handles, FALSE, timeout) == WAIT_OBJECT_0)
+ if (WaitForMultipleObjects(2, wait_handles, FALSE, timeout) == WAIT_OBJECT_0)
{
- /* Semaphore locked */
- for (i = 0; i < ncmds; ++i)
+ /* Semaphore locked */
+ for (i = 0; i < ncmds; ++i)
+ {
+ ExecCommand(cmds[i].argv0, cmds[i].cmdline, cmds[i].timeout);
+ }
+ err = 0;
+ if (!ReleaseSemaphore(rdns_semaphore, 1, NULL) )
{
- ExecCommand (cmds[i].argv0, cmds[i].cmdline, cmds[i].timeout);
+ err = MsgToEventLog(M_SYSERR, TEXT("RegisterDNS: Failed to release regsiter-dns semaphore:"));
}
- err = 0;
- if ( !ReleaseSemaphore (rdns_semaphore, 1, NULL) )
- err = MsgToEventLog (M_SYSERR, TEXT("RegisterDNS: Failed to release regsiter-dns semaphore:"));
}
- else
+ else
{
- MsgToEventLog (M_ERR, TEXT("RegisterDNS: Failed to lock register-dns semaphore"));
- err = ERROR_SEM_TIMEOUT; /* Windows error code 0x79 */
+ MsgToEventLog(M_ERR, TEXT("RegisterDNS: Failed to lock register-dns semaphore"));
+ err = ERROR_SEM_TIMEOUT; /* Windows error code 0x79 */
}
- return err;
+ return err;
}
static DWORD
-HandleRegisterDNSMessage (void)
+HandleRegisterDNSMessage(void)
{
- DWORD err;
- HANDLE thread = NULL;
+ DWORD err;
+ HANDLE thread = NULL;
- /* Delegate this job to a sub-thread */
- thread = CreateThread (NULL, 0, RegisterDNS, NULL, 0, NULL);
+ /* Delegate this job to a sub-thread */
+ thread = CreateThread(NULL, 0, RegisterDNS, NULL, 0, NULL);
- /*
- * We don't add these thread handles to the undo list -- the thread and
- * processes it spawns are all supposed to terminate or timeout by themselves.
- */
- if (thread)
+ /*
+ * We don't add these thread handles to the undo list -- the thread and
+ * processes it spawns are all supposed to terminate or timeout by themselves.
+ */
+ if (thread)
+ {
+ err = 0;
+ CloseHandle(thread);
+ }
+ else
{
- err = 0;
- CloseHandle (thread);
+ err = GetLastError();
}
- else
- err = GetLastError();
- return err;
+ return err;
}
/**
@@ -974,845 +1077,904 @@ HandleRegisterDNSMessage (void)
* If addr is null and action = "delete" all addresses are deleted.
*/
static DWORD
-netsh_dns_cmd (const wchar_t *action, const wchar_t *proto, const wchar_t *if_name, const wchar_t *addr)
+netsh_dns_cmd(const wchar_t *action, const wchar_t *proto, const wchar_t *if_name, const wchar_t *addr)
{
- DWORD err = 0;
- int timeout = 30000; /* in msec */
- wchar_t argv0[MAX_PATH];
+ DWORD err = 0;
+ int timeout = 30000; /* in msec */
+ wchar_t argv0[MAX_PATH];
- if (!addr)
+ if (!addr)
{
- if (wcscmp(action, L"delete") == 0)
- addr = L"all";
- else /* nothing to do -- return success*/
- goto out;
+ if (wcscmp(action, L"delete") == 0)
+ {
+ addr = L"all";
+ }
+ else /* nothing to do -- return success*/
+ {
+ goto out;
+ }
}
- /* Path of netsh */
- int n = GetSystemDirectory (argv0, MAX_PATH);
- if (n > 0 && n < MAX_PATH) /* got system directory */
- {
- wcsncat(argv0, L"\\netsh.exe", MAX_PATH - n - 1);
- }
- else
- {
- wcsncpy(argv0, L"C:\\Windows\\system32\\netsh.exe", MAX_PATH);
- }
+ /* Path of netsh */
+ int n = GetSystemDirectory(argv0, MAX_PATH);
+ if (n > 0 && n < MAX_PATH) /* got system directory */
+ {
+ wcsncat(argv0, L"\\netsh.exe", MAX_PATH - n - 1);
+ }
+ else
+ {
+ wcsncpy(argv0, L"C:\\Windows\\system32\\netsh.exe", MAX_PATH);
+ }
- /* cmd template:
- * netsh interface $proto $action dns $if_name $addr [validate=no]
- */
- const wchar_t *fmt = L"netsh interface %s %s dns \"%s\" %s";
+ /* cmd template:
+ * netsh interface $proto $action dns $if_name $addr [validate=no]
+ */
+ const wchar_t *fmt = L"netsh interface %s %s dns \"%s\" %s";
- /* max cmdline length in wchars -- include room for worst case and some */
- int ncmdline = wcslen(fmt) + wcslen(if_name) + wcslen(addr) + 32 + 1;
- wchar_t *cmdline = malloc(ncmdline*sizeof(wchar_t));
- if (!cmdline)
- {
- err = ERROR_OUTOFMEMORY;
- goto out;
- }
+ /* max cmdline length in wchars -- include room for worst case and some */
+ int ncmdline = wcslen(fmt) + wcslen(if_name) + wcslen(addr) + 32 + 1;
+ wchar_t *cmdline = malloc(ncmdline*sizeof(wchar_t));
+ if (!cmdline)
+ {
+ err = ERROR_OUTOFMEMORY;
+ goto out;
+ }
- openvpn_sntprintf (cmdline, ncmdline, fmt, proto, action, if_name, addr);
+ openvpn_sntprintf(cmdline, ncmdline, fmt, proto, action, if_name, addr);
- if (IsWindows7OrGreater())
+ if (IsWindows7OrGreater())
{
- wcsncat(cmdline, L" validate=no", ncmdline - wcslen(cmdline) - 1);
+ wcsncat(cmdline, L" validate=no", ncmdline - wcslen(cmdline) - 1);
}
- err = ExecCommand (argv0, cmdline, timeout);
+ err = ExecCommand(argv0, cmdline, timeout);
out:
- free (cmdline);
- return err;
+ free(cmdline);
+ return err;
}
/* Delete all IPv4 or IPv6 dns servers for an interface */
static DWORD
DeleteDNS(short family, wchar_t *if_name)
{
- wchar_t *proto = (family == AF_INET6) ? L"ipv6" : L"ip";
- return netsh_dns_cmd (L"delete", proto, if_name, NULL);
+ wchar_t *proto = (family == AF_INET6) ? L"ipv6" : L"ip";
+ return netsh_dns_cmd(L"delete", proto, if_name, NULL);
}
/* Add an IPv4 or IPv6 dns server to an interface */
static DWORD
AddDNS(short family, wchar_t *if_name, wchar_t *addr)
{
- wchar_t *proto = (family == AF_INET6) ? L"ipv6" : L"ip";
- return netsh_dns_cmd (L"add", proto, if_name, addr);
+ wchar_t *proto = (family == AF_INET6) ? L"ipv6" : L"ip";
+ return netsh_dns_cmd(L"add", proto, if_name, addr);
}
static BOOL
-CmpWString (LPVOID item, LPVOID str)
+CmpWString(LPVOID item, LPVOID str)
{
- return (wcscmp (item, str) == 0) ? TRUE : FALSE;
+ return (wcscmp(item, str) == 0) ? TRUE : FALSE;
}
static DWORD
-HandleDNSConfigMessage (const dns_cfg_message_t *msg, undo_lists_t *lists)
+HandleDNSConfigMessage(const dns_cfg_message_t *msg, undo_lists_t *lists)
{
- DWORD err = 0;
- wchar_t addr[46]; /* large enough to hold string representation of an ipv4 / ipv6 address */
- undo_type_t undo_type = (msg->family == AF_INET6) ? undo_dns4 : undo_dns6;
- int addr_len = msg->addr_len;
+ DWORD err = 0;
+ wchar_t addr[46]; /* large enough to hold string representation of an ipv4 / ipv6 address */
+ undo_type_t undo_type = (msg->family == AF_INET6) ? undo_dns4 : undo_dns6;
+ int addr_len = msg->addr_len;
- /* sanity check */
- if (addr_len > _countof(msg->addr))
- addr_len = _countof(msg->addr);
+ /* sanity check */
+ if (addr_len > _countof(msg->addr))
+ {
+ addr_len = _countof(msg->addr);
+ }
- if (!msg->iface.name[0]) /* interface name is required */
- return ERROR_MESSAGE_DATA;
+ if (!msg->iface.name[0]) /* interface name is required */
+ {
+ return ERROR_MESSAGE_DATA;
+ }
- wchar_t *wide_name = utf8to16(msg->iface.name); /* utf8 to wide-char */
- if (!wide_name)
- return ERROR_OUTOFMEMORY;
+ wchar_t *wide_name = utf8to16(msg->iface.name); /* utf8 to wide-char */
+ if (!wide_name)
+ {
+ return ERROR_OUTOFMEMORY;
+ }
- /* We delete all current addresses before adding any
- * OR if the message type is del_dns_cfg
- */
- if (addr_len > 0 || msg->header.type == msg_del_dns_cfg)
+ /* We delete all current addresses before adding any
+ * OR if the message type is del_dns_cfg
+ */
+ if (addr_len > 0 || msg->header.type == msg_del_dns_cfg)
{
- err = DeleteDNS(msg->family, wide_name);
- if (err)
- goto out;
- free (RemoveListItem (&(*lists)[undo_type], CmpWString, wide_name));
+ err = DeleteDNS(msg->family, wide_name);
+ if (err)
+ {
+ goto out;
+ }
+ free(RemoveListItem(&(*lists)[undo_type], CmpWString, wide_name));
}
- if (msg->header.type == msg_del_dns_cfg) /* job done */
- goto out;
+ if (msg->header.type == msg_del_dns_cfg) /* job done */
+ {
+ goto out;
+ }
- for (int i = 0; i < addr_len; ++i)
+ for (int i = 0; i < addr_len; ++i)
{
- if (msg->family == AF_INET6)
- RtlIpv6AddressToStringW (&msg->addr[i].ipv6, addr);
- else
- RtlIpv4AddressToStringW (&msg->addr[i].ipv4, addr);
- err = AddDNS(msg->family, wide_name, addr);
- if (i == 0 && err)
- goto out;
- /* We do not check for duplicate addresses, so any error in adding
- * additional addresses is ignored.
- */
+ if (msg->family == AF_INET6)
+ {
+ RtlIpv6AddressToStringW(&msg->addr[i].ipv6, addr);
+ }
+ else
+ {
+ RtlIpv4AddressToStringW(&msg->addr[i].ipv4, addr);
+ }
+ err = AddDNS(msg->family, wide_name, addr);
+ if (i == 0 && err)
+ {
+ goto out;
+ }
+ /* We do not check for duplicate addresses, so any error in adding
+ * additional addresses is ignored.
+ */
}
- if (msg->addr_len > 0)
+ if (msg->addr_len > 0)
{
- wchar_t *tmp_name = wcsdup(wide_name);
- if (!tmp_name || AddListItem(&(*lists)[undo_type], tmp_name))
+ wchar_t *tmp_name = wcsdup(wide_name);
+ if (!tmp_name || AddListItem(&(*lists)[undo_type], tmp_name))
{
- free(tmp_name);
- DeleteDNS(msg->family, wide_name);
- err = ERROR_OUTOFMEMORY;
- goto out;
+ free(tmp_name);
+ DeleteDNS(msg->family, wide_name);
+ err = ERROR_OUTOFMEMORY;
+ goto out;
}
}
- err = 0;
+ err = 0;
out:
- free(wide_name);
- return err;
+ free(wide_name);
+ return err;
}
static VOID
-HandleMessage (HANDLE pipe, DWORD bytes, DWORD count, LPHANDLE events, undo_lists_t *lists)
+HandleMessage(HANDLE pipe, DWORD bytes, DWORD count, LPHANDLE events, undo_lists_t *lists)
{
- DWORD read;
- union {
- message_header_t header;
- address_message_t address;
- route_message_t route;
- flush_neighbors_message_t flush_neighbors;
- block_dns_message_t block_dns;
- dns_cfg_message_t dns;
- } msg;
- ack_message_t ack = {
- .header = {
- .type = msg_acknowledgement,
- .size = sizeof (ack),
- .message_id = -1
- },
- .error_number = ERROR_MESSAGE_DATA
- };
-
- read = ReadPipeAsync (pipe, &msg, bytes, count, events);
- if (read != bytes || read < sizeof (msg.header) || read != msg.header.size)
- goto out;
-
- ack.header.message_id = msg.header.message_id;
-
- switch (msg.header.type)
- {
- case msg_add_address:
- case msg_del_address:
- if (msg.header.size == sizeof (msg.address))
- ack.error_number = HandleAddressMessage (&msg.address, lists);
- break;
-
- case msg_add_route:
- case msg_del_route:
- if (msg.header.size == sizeof (msg.route))
- ack.error_number = HandleRouteMessage (&msg.route, lists);
- break;
-
- case msg_flush_neighbors:
- if (msg.header.size == sizeof (msg.flush_neighbors))
- ack.error_number = HandleFlushNeighborsMessage (&msg.flush_neighbors);
- break;
-
- case msg_add_block_dns:
- case msg_del_block_dns:
- if (msg.header.size == sizeof (msg.block_dns))
- ack.error_number = HandleBlockDNSMessage (&msg.block_dns, lists);
- break;
-
- case msg_register_dns:
- ack.error_number = HandleRegisterDNSMessage ();
- break;
+ DWORD read;
+ union {
+ message_header_t header;
+ address_message_t address;
+ route_message_t route;
+ flush_neighbors_message_t flush_neighbors;
+ block_dns_message_t block_dns;
+ dns_cfg_message_t dns;
+ } msg;
+ ack_message_t ack = {
+ .header = {
+ .type = msg_acknowledgement,
+ .size = sizeof(ack),
+ .message_id = -1
+ },
+ .error_number = ERROR_MESSAGE_DATA
+ };
+
+ read = ReadPipeAsync(pipe, &msg, bytes, count, events);
+ if (read != bytes || read < sizeof(msg.header) || read != msg.header.size)
+ {
+ goto out;
+ }
- case msg_add_dns_cfg:
- case msg_del_dns_cfg:
- ack.error_number = HandleDNSConfigMessage (&msg.dns, lists);
- break;
+ ack.header.message_id = msg.header.message_id;
+
+ switch (msg.header.type)
+ {
+ case msg_add_address:
+ case msg_del_address:
+ if (msg.header.size == sizeof(msg.address))
+ {
+ ack.error_number = HandleAddressMessage(&msg.address, lists);
+ }
+ break;
+
+ case msg_add_route:
+ case msg_del_route:
+ if (msg.header.size == sizeof(msg.route))
+ {
+ ack.error_number = HandleRouteMessage(&msg.route, lists);
+ }
+ break;
- default:
- ack.error_number = ERROR_MESSAGE_TYPE;
- MsgToEventLog (MSG_FLAGS_ERROR, TEXT("Unknown message type %d"), msg.header.type);
- break;
+ case msg_flush_neighbors:
+ if (msg.header.size == sizeof(msg.flush_neighbors))
+ {
+ ack.error_number = HandleFlushNeighborsMessage(&msg.flush_neighbors);
+ }
+ break;
+
+ case msg_add_block_dns:
+ case msg_del_block_dns:
+ if (msg.header.size == sizeof(msg.block_dns))
+ {
+ ack.error_number = HandleBlockDNSMessage(&msg.block_dns, lists);
+ }
+ break;
+
+ case msg_register_dns:
+ ack.error_number = HandleRegisterDNSMessage();
+ break;
+
+ case msg_add_dns_cfg:
+ case msg_del_dns_cfg:
+ ack.error_number = HandleDNSConfigMessage(&msg.dns, lists);
+ break;
+
+ default:
+ ack.error_number = ERROR_MESSAGE_TYPE;
+ MsgToEventLog(MSG_FLAGS_ERROR, TEXT("Unknown message type %d"), msg.header.type);
+ break;
}
out:
- WritePipeAsync (pipe, &ack, sizeof (ack), count, events);
+ WritePipeAsync(pipe, &ack, sizeof(ack), count, events);
}
static VOID
-Undo (undo_lists_t *lists)
+Undo(undo_lists_t *lists)
{
- undo_type_t type;
- for (type = 0; type < _undo_type_max; type++)
+ undo_type_t type;
+ for (type = 0; type < _undo_type_max; type++)
{
- list_item_t **pnext = &(*lists)[type];
- while (*pnext)
+ list_item_t **pnext = &(*lists)[type];
+ while (*pnext)
{
- list_item_t *item = *pnext;
- switch (type)
+ list_item_t *item = *pnext;
+ switch (type)
{
- case address:
- DeleteAddress (item->data);
- break;
-
- case route:
- DeleteRoute (item->data);
- break;
-
- case undo_dns4:
- DeleteDNS(AF_INET, item->data);
- break;
-
- case undo_dns6:
- DeleteDNS(AF_INET6, item->data);
- break;
-
- case block_dns:
- delete_block_dns_filters (item->data);
- item->data = NULL;
- break;
+ case address:
+ DeleteAddress(item->data);
+ break;
+
+ case route:
+ DeleteRoute(item->data);
+ break;
+
+ case undo_dns4:
+ DeleteDNS(AF_INET, item->data);
+ break;
+
+ case undo_dns6:
+ DeleteDNS(AF_INET6, item->data);
+ break;
+
+ case block_dns:
+ delete_block_dns_filters(item->data);
+ item->data = NULL;
+ break;
}
- /* Remove from the list and free memory */
- *pnext = item->next;
- free (item->data);
- free (item);
+ /* Remove from the list and free memory */
+ *pnext = item->next;
+ free(item->data);
+ free(item);
}
}
}
static DWORD WINAPI
-RunOpenvpn (LPVOID p)
+RunOpenvpn(LPVOID p)
{
- HANDLE pipe = p;
- HANDLE ovpn_pipe, svc_pipe;
- PTOKEN_USER svc_user, ovpn_user;
- HANDLE svc_token = NULL, imp_token = NULL, pri_token = NULL;
- HANDLE stdin_read = NULL, stdin_write = NULL;
- HANDLE stdout_write = NULL;
- DWORD pipe_mode, len, exit_code = 0;
- STARTUP_DATA sud = { 0, 0, 0 };
- STARTUPINFOW startup_info;
- PROCESS_INFORMATION proc_info;
- LPVOID user_env = NULL;
- TCHAR ovpn_pipe_name[36];
- LPCWSTR exe_path;
- WCHAR *cmdline = NULL;
- size_t cmdline_size;
- undo_lists_t undo_lists;
-
- SECURITY_ATTRIBUTES inheritable = {
- .nLength = sizeof (inheritable),
- .lpSecurityDescriptor = NULL,
- .bInheritHandle = TRUE
- };
-
- PACL ovpn_dacl;
- EXPLICIT_ACCESS ea[2];
- SECURITY_DESCRIPTOR ovpn_sd;
- SECURITY_ATTRIBUTES ovpn_sa = {
- .nLength = sizeof (ovpn_sa),
- .lpSecurityDescriptor = &ovpn_sd,
- .bInheritHandle = FALSE
- };
-
- ZeroMemory (&ea, sizeof (ea));
- ZeroMemory (&startup_info, sizeof (startup_info));
- ZeroMemory (&undo_lists, sizeof (undo_lists));
- ZeroMemory (&proc_info, sizeof (proc_info));
-
- if (!GetStartupData (pipe, &sud))
- goto out;
-
- if (!InitializeSecurityDescriptor (&ovpn_sd, SECURITY_DESCRIPTOR_REVISION))
- {
- ReturnLastError (pipe, L"InitializeSecurityDescriptor");
- goto out;
- }
-
- /* Get SID of user the service is running under */
- if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &svc_token))
- {
- ReturnLastError (pipe, L"OpenProcessToken");
- goto out;
- }
- len = 0;
- svc_user = NULL;
- while (!GetTokenInformation (svc_token, TokenUser, svc_user, len, &len))
- {
- if (GetLastError () != ERROR_INSUFFICIENT_BUFFER)
+ HANDLE pipe = p;
+ HANDLE ovpn_pipe, svc_pipe;
+ PTOKEN_USER svc_user, ovpn_user;
+ HANDLE svc_token = NULL, imp_token = NULL, pri_token = NULL;
+ HANDLE stdin_read = NULL, stdin_write = NULL;
+ HANDLE stdout_write = NULL;
+ DWORD pipe_mode, len, exit_code = 0;
+ STARTUP_DATA sud = { 0, 0, 0 };
+ STARTUPINFOW startup_info;
+ PROCESS_INFORMATION proc_info;
+ LPVOID user_env = NULL;
+ TCHAR ovpn_pipe_name[36];
+ LPCWSTR exe_path;
+ WCHAR *cmdline = NULL;
+ size_t cmdline_size;
+ undo_lists_t undo_lists;
+
+ SECURITY_ATTRIBUTES inheritable = {
+ .nLength = sizeof(inheritable),
+ .lpSecurityDescriptor = NULL,
+ .bInheritHandle = TRUE
+ };
+
+ PACL ovpn_dacl;
+ EXPLICIT_ACCESS ea[2];
+ SECURITY_DESCRIPTOR ovpn_sd;
+ SECURITY_ATTRIBUTES ovpn_sa = {
+ .nLength = sizeof(ovpn_sa),
+ .lpSecurityDescriptor = &ovpn_sd,
+ .bInheritHandle = FALSE
+ };
+
+ ZeroMemory(&ea, sizeof(ea));
+ ZeroMemory(&startup_info, sizeof(startup_info));
+ ZeroMemory(&undo_lists, sizeof(undo_lists));
+ ZeroMemory(&proc_info, sizeof(proc_info));
+
+ if (!GetStartupData(pipe, &sud))
+ {
+ goto out;
+ }
+
+ if (!InitializeSecurityDescriptor(&ovpn_sd, SECURITY_DESCRIPTOR_REVISION))
+ {
+ ReturnLastError(pipe, L"InitializeSecurityDescriptor");
+ goto out;
+ }
+
+ /* Get SID of user the service is running under */
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &svc_token))
+ {
+ ReturnLastError(pipe, L"OpenProcessToken");
+ goto out;
+ }
+ len = 0;
+ svc_user = NULL;
+ while (!GetTokenInformation(svc_token, TokenUser, svc_user, len, &len))
+ {
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
- ReturnLastError (pipe, L"GetTokenInformation (service token)");
- goto out;
+ ReturnLastError(pipe, L"GetTokenInformation (service token)");
+ goto out;
}
- free (svc_user);
- svc_user = malloc (len);
- if (svc_user == NULL)
+ free(svc_user);
+ svc_user = malloc(len);
+ if (svc_user == NULL)
{
- ReturnLastError (pipe, L"malloc (service token user)");
- goto out;
+ ReturnLastError(pipe, L"malloc (service token user)");
+ goto out;
}
}
- if (!IsValidSid (svc_user->User.Sid))
+ if (!IsValidSid(svc_user->User.Sid))
{
- ReturnLastError (pipe, L"IsValidSid (service token user)");
- goto out;
+ ReturnLastError(pipe, L"IsValidSid (service token user)");
+ goto out;
}
- if (!ImpersonateNamedPipeClient (pipe))
+ if (!ImpersonateNamedPipeClient(pipe))
{
- ReturnLastError (pipe, L"ImpersonateNamedPipeClient");
- goto out;
+ ReturnLastError(pipe, L"ImpersonateNamedPipeClient");
+ goto out;
}
- if (!OpenThreadToken (GetCurrentThread (), TOKEN_ALL_ACCESS, FALSE, &imp_token))
+ if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &imp_token))
{
- ReturnLastError (pipe, L"OpenThreadToken");
- goto out;
+ ReturnLastError(pipe, L"OpenThreadToken");
+ goto out;
}
- len = 0;
- ovpn_user = NULL;
- while (!GetTokenInformation (imp_token, TokenUser, ovpn_user, len, &len))
+ len = 0;
+ ovpn_user = NULL;
+ while (!GetTokenInformation(imp_token, TokenUser, ovpn_user, len, &len))
{
- if (GetLastError () != ERROR_INSUFFICIENT_BUFFER)
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
- ReturnLastError (pipe, L"GetTokenInformation (impersonation token)");
- goto out;
+ ReturnLastError(pipe, L"GetTokenInformation (impersonation token)");
+ goto out;
}
- free (ovpn_user);
- ovpn_user = malloc (len);
- if (ovpn_user == NULL)
+ free(ovpn_user);
+ ovpn_user = malloc(len);
+ if (ovpn_user == NULL)
{
- ReturnLastError (pipe, L"malloc (impersonation token user)");
- goto out;
+ ReturnLastError(pipe, L"malloc (impersonation token user)");
+ goto out;
}
}
- if (!IsValidSid (ovpn_user->User.Sid))
+ if (!IsValidSid(ovpn_user->User.Sid))
{
- ReturnLastError (pipe, L"IsValidSid (impersonation token user)");
- goto out;
+ ReturnLastError(pipe, L"IsValidSid (impersonation token user)");
+ goto out;
}
- /* Check user is authorized or options are white-listed */
- if (!IsAuthorizedUser (ovpn_user->User.Sid, &settings) &&
- !ValidateOptions (pipe, sud.directory, sud.options))
+ /* Check user is authorized or options are white-listed */
+ if (!IsAuthorizedUser(ovpn_user->User.Sid, &settings)
+ && !ValidateOptions(pipe, sud.directory, sud.options))
{
- goto out;
+ goto out;
}
- /* OpenVPN process DACL entry for access by service and user */
- ea[0].grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
- ea[0].grfAccessMode = SET_ACCESS;
- ea[0].grfInheritance = NO_INHERITANCE;
- ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
- ea[0].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
- ea[0].Trustee.ptstrName = (LPTSTR) svc_user->User.Sid;
- ea[1].grfAccessPermissions = READ_CONTROL | SYNCHRONIZE | PROCESS_VM_READ |
- SYNCHRONIZE | PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION;
- ea[1].grfAccessMode = SET_ACCESS;
- ea[1].grfInheritance = NO_INHERITANCE;
- ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
- ea[1].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
- ea[1].Trustee.ptstrName = (LPTSTR) ovpn_user->User.Sid;
-
- /* Set owner and DACL of OpenVPN security descriptor */
- if (!SetSecurityDescriptorOwner (&ovpn_sd, svc_user->User.Sid, FALSE))
- {
- ReturnLastError (pipe, L"SetSecurityDescriptorOwner");
- goto out;
+ /* OpenVPN process DACL entry for access by service and user */
+ ea[0].grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
+ ea[0].grfAccessMode = SET_ACCESS;
+ ea[0].grfInheritance = NO_INHERITANCE;
+ ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[0].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
+ ea[0].Trustee.ptstrName = (LPTSTR) svc_user->User.Sid;
+ ea[1].grfAccessPermissions = READ_CONTROL | SYNCHRONIZE | PROCESS_VM_READ
+ |SYNCHRONIZE | PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION;
+ ea[1].grfAccessMode = SET_ACCESS;
+ ea[1].grfInheritance = NO_INHERITANCE;
+ ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[1].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
+ ea[1].Trustee.ptstrName = (LPTSTR) ovpn_user->User.Sid;
+
+ /* Set owner and DACL of OpenVPN security descriptor */
+ if (!SetSecurityDescriptorOwner(&ovpn_sd, svc_user->User.Sid, FALSE))
+ {
+ ReturnLastError(pipe, L"SetSecurityDescriptorOwner");
+ goto out;
}
- if (SetEntriesInAcl (2, ea, NULL, &ovpn_dacl) != ERROR_SUCCESS)
+ if (SetEntriesInAcl(2, ea, NULL, &ovpn_dacl) != ERROR_SUCCESS)
{
- ReturnLastError (pipe, L"SetEntriesInAcl");
- goto out;
+ ReturnLastError(pipe, L"SetEntriesInAcl");
+ goto out;
}
- if (!SetSecurityDescriptorDacl (&ovpn_sd, TRUE, ovpn_dacl, FALSE))
+ if (!SetSecurityDescriptorDacl(&ovpn_sd, TRUE, ovpn_dacl, FALSE))
{
- ReturnLastError (pipe, L"SetSecurityDescriptorDacl");
- goto out;
+ ReturnLastError(pipe, L"SetSecurityDescriptorDacl");
+ goto out;
}
- /* Create primary token from impersonation token */
- if (!DuplicateTokenEx (imp_token, TOKEN_ALL_ACCESS, NULL, 0, TokenPrimary, &pri_token))
+ /* Create primary token from impersonation token */
+ if (!DuplicateTokenEx(imp_token, TOKEN_ALL_ACCESS, NULL, 0, TokenPrimary, &pri_token))
{
- ReturnLastError (pipe, L"DuplicateTokenEx");
- goto out;
+ ReturnLastError(pipe, L"DuplicateTokenEx");
+ goto out;
}
- /* use /dev/null for stdout of openvpn (client should use --log for output) */
- stdout_write = CreateFile(_T("NUL"), GENERIC_WRITE, FILE_SHARE_WRITE,
- &inheritable, OPEN_EXISTING, 0, NULL);
- if (stdout_write == INVALID_HANDLE_VALUE)
+ /* use /dev/null for stdout of openvpn (client should use --log for output) */
+ stdout_write = CreateFile(_T("NUL"), GENERIC_WRITE, FILE_SHARE_WRITE,
+ &inheritable, OPEN_EXISTING, 0, NULL);
+ if (stdout_write == INVALID_HANDLE_VALUE)
{
- ReturnLastError (pipe, L"CreateFile for stdout");
- goto out;
+ ReturnLastError(pipe, L"CreateFile for stdout");
+ goto out;
}
- if (!CreatePipe(&stdin_read, &stdin_write, &inheritable, 0) ||
- !SetHandleInformation(stdin_write, HANDLE_FLAG_INHERIT, 0))
+ if (!CreatePipe(&stdin_read, &stdin_write, &inheritable, 0)
+ || !SetHandleInformation(stdin_write, HANDLE_FLAG_INHERIT, 0))
{
- ReturnLastError (pipe, L"CreatePipe");
- goto out;
+ ReturnLastError(pipe, L"CreatePipe");
+ goto out;
}
- openvpn_sntprintf (ovpn_pipe_name, _countof (ovpn_pipe_name),
- TEXT("\\\\.\\pipe\\openvpn\\service_%lu"), GetCurrentThreadId ());
- ovpn_pipe = CreateNamedPipe (ovpn_pipe_name,
- PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
- PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 128, 128, 0, NULL);
- if (ovpn_pipe == INVALID_HANDLE_VALUE)
+ openvpn_sntprintf(ovpn_pipe_name, _countof(ovpn_pipe_name),
+ TEXT("\\\\.\\pipe\\openvpn\\service_%lu"), GetCurrentThreadId());
+ ovpn_pipe = CreateNamedPipe(ovpn_pipe_name,
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 128, 128, 0, NULL);
+ if (ovpn_pipe == INVALID_HANDLE_VALUE)
{
- ReturnLastError (pipe, L"CreateNamedPipe");
- goto out;
+ ReturnLastError(pipe, L"CreateNamedPipe");
+ goto out;
}
- svc_pipe = CreateFile (ovpn_pipe_name, GENERIC_READ | GENERIC_WRITE, 0,
- &inheritable, OPEN_EXISTING, 0, NULL);
- if (svc_pipe == INVALID_HANDLE_VALUE)
+ svc_pipe = CreateFile(ovpn_pipe_name, GENERIC_READ | GENERIC_WRITE, 0,
+ &inheritable, OPEN_EXISTING, 0, NULL);
+ if (svc_pipe == INVALID_HANDLE_VALUE)
{
- ReturnLastError (pipe, L"CreateFile");
- goto out;
+ ReturnLastError(pipe, L"CreateFile");
+ goto out;
}
- pipe_mode = PIPE_READMODE_MESSAGE;
- if (!SetNamedPipeHandleState (svc_pipe, &pipe_mode, NULL, NULL))
+ pipe_mode = PIPE_READMODE_MESSAGE;
+ if (!SetNamedPipeHandleState(svc_pipe, &pipe_mode, NULL, NULL))
{
- ReturnLastError (pipe, L"SetNamedPipeHandleState");
- goto out;
+ ReturnLastError(pipe, L"SetNamedPipeHandleState");
+ goto out;
}
- cmdline_size = wcslen (sud.options) + 128;
- cmdline = malloc (cmdline_size * sizeof (*cmdline));
- if (cmdline == NULL)
+ cmdline_size = wcslen(sud.options) + 128;
+ cmdline = malloc(cmdline_size * sizeof(*cmdline));
+ if (cmdline == NULL)
{
- ReturnLastError (pipe, L"malloc");
- goto out;
+ ReturnLastError(pipe, L"malloc");
+ goto out;
}
- openvpn_sntprintf (cmdline, cmdline_size, L"openvpn %s --msg-channel %lu",
- sud.options, svc_pipe);
+ openvpn_sntprintf(cmdline, cmdline_size, L"openvpn %s --msg-channel %lu",
+ sud.options, svc_pipe);
- if (!CreateEnvironmentBlock (&user_env, imp_token, FALSE))
+ if (!CreateEnvironmentBlock(&user_env, imp_token, FALSE))
{
- ReturnLastError (pipe, L"CreateEnvironmentBlock");
- goto out;
+ ReturnLastError(pipe, L"CreateEnvironmentBlock");
+ goto out;
}
- startup_info.cb = sizeof (startup_info);
- startup_info.lpDesktop = L"winsta0\\default";
- startup_info.dwFlags = STARTF_USESTDHANDLES;
- startup_info.hStdInput = stdin_read;
- startup_info.hStdOutput = stdout_write;
- startup_info.hStdError = stdout_write;
+ startup_info.cb = sizeof(startup_info);
+ startup_info.lpDesktop = L"winsta0\\default";
+ startup_info.dwFlags = STARTF_USESTDHANDLES;
+ startup_info.hStdInput = stdin_read;
+ startup_info.hStdOutput = stdout_write;
+ startup_info.hStdError = stdout_write;
#ifdef UNICODE
- exe_path = settings.exe_path;
+ exe_path = settings.exe_path;
#else
- WCHAR wide_path[MAX_PATH];
- MultiByteToWideChar (CP_UTF8, 0, settings.exe_path, MAX_PATH, wide_path, MAX_PATH);
- exe_path = wide_path;
+ WCHAR wide_path[MAX_PATH];
+ MultiByteToWideChar(CP_UTF8, 0, settings.exe_path, MAX_PATH, wide_path, MAX_PATH);
+ exe_path = wide_path;
#endif
- // TODO: make sure HKCU is correct or call LoadUserProfile()
- if (!CreateProcessAsUserW (pri_token, exe_path, cmdline, &ovpn_sa, NULL, TRUE,
- settings.priority | CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
- user_env, sud.directory, &startup_info, &proc_info))
+ /* TODO: make sure HKCU is correct or call LoadUserProfile() */
+ if (!CreateProcessAsUserW(pri_token, exe_path, cmdline, &ovpn_sa, NULL, TRUE,
+ settings.priority | CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
+ user_env, sud.directory, &startup_info, &proc_info))
{
- ReturnLastError (pipe, L"CreateProcessAsUser");
- goto out;
+ ReturnLastError(pipe, L"CreateProcessAsUser");
+ goto out;
}
- if (!RevertToSelf ())
+ if (!RevertToSelf())
{
- TerminateProcess (proc_info.hProcess, 1);
- ReturnLastError (pipe, L"RevertToSelf");
- goto out;
+ TerminateProcess(proc_info.hProcess, 1);
+ ReturnLastError(pipe, L"RevertToSelf");
+ goto out;
}
- ReturnProcessId (pipe, proc_info.dwProcessId, 1, &exit_event);
+ ReturnProcessId(pipe, proc_info.dwProcessId, 1, &exit_event);
- CloseHandleEx (&stdout_write);
- CloseHandleEx (&stdin_read);
- CloseHandleEx (&svc_pipe);
+ CloseHandleEx(&stdout_write);
+ CloseHandleEx(&stdin_read);
+ CloseHandleEx(&svc_pipe);
- DWORD input_size = WideCharToMultiByte (CP_UTF8, 0, sud.std_input, -1, NULL, 0, NULL, NULL);
- LPSTR input = NULL;
- if (input_size && (input = malloc (input_size)))
+ DWORD input_size = WideCharToMultiByte(CP_UTF8, 0, sud.std_input, -1, NULL, 0, NULL, NULL);
+ LPSTR input = NULL;
+ if (input_size && (input = malloc(input_size)))
{
- DWORD written;
- WideCharToMultiByte (CP_UTF8, 0, sud.std_input, -1, input, input_size, NULL, NULL);
- WriteFile (stdin_write, input, strlen (input), &written, NULL);
- free (input);
+ DWORD written;
+ WideCharToMultiByte(CP_UTF8, 0, sud.std_input, -1, input, input_size, NULL, NULL);
+ WriteFile(stdin_write, input, strlen(input), &written, NULL);
+ free(input);
}
- while (TRUE)
+ while (TRUE)
{
- DWORD bytes = PeekNamedPipeAsync (ovpn_pipe, 1, &exit_event);
- if (bytes == 0)
- break;
+ DWORD bytes = PeekNamedPipeAsync(ovpn_pipe, 1, &exit_event);
+ if (bytes == 0)
+ {
+ break;
+ }
- HandleMessage (ovpn_pipe, bytes, 1, &exit_event, &undo_lists);
+ HandleMessage(ovpn_pipe, bytes, 1, &exit_event, &undo_lists);
}
- WaitForSingleObject (proc_info.hProcess, IO_TIMEOUT);
- GetExitCodeProcess (proc_info.hProcess, &exit_code);
- if (exit_code == STILL_ACTIVE)
- TerminateProcess (proc_info.hProcess, 1);
- else if (exit_code != 0)
+ WaitForSingleObject(proc_info.hProcess, IO_TIMEOUT);
+ GetExitCodeProcess(proc_info.hProcess, &exit_code);
+ if (exit_code == STILL_ACTIVE)
{
- WCHAR buf[256];
- int len = _snwprintf (buf, _countof (buf),
- L"OpenVPN exited with error: exit code = %lu", exit_code);
- buf[_countof (buf) - 1] = L'\0';
- ReturnError (pipe, ERROR_OPENVPN_STARTUP, buf, 1, &exit_event);
+ TerminateProcess(proc_info.hProcess, 1);
}
- Undo (&undo_lists);
+ else if (exit_code != 0)
+ {
+ WCHAR buf[256];
+ int len = _snwprintf(buf, _countof(buf),
+ L"OpenVPN exited with error: exit code = %lu", exit_code);
+ buf[_countof(buf) - 1] = L'\0';
+ ReturnError(pipe, ERROR_OPENVPN_STARTUP, buf, 1, &exit_event);
+ }
+ Undo(&undo_lists);
out:
- FlushFileBuffers (pipe);
- DisconnectNamedPipe (pipe);
-
- free (ovpn_user);
- free (svc_user);
- free (cmdline);
- DestroyEnvironmentBlock (user_env);
- FreeStartupData (&sud);
- CloseHandleEx (&proc_info.hProcess);
- CloseHandleEx (&proc_info.hThread);
- CloseHandleEx (&stdin_read);
- CloseHandleEx (&stdin_write);
- CloseHandleEx (&stdout_write);
- CloseHandleEx (&svc_token);
- CloseHandleEx (&imp_token);
- CloseHandleEx (&pri_token);
- CloseHandleEx (&ovpn_pipe);
- CloseHandleEx (&svc_pipe);
- CloseHandleEx (&pipe);
-
- return 0;
+ FlushFileBuffers(pipe);
+ DisconnectNamedPipe(pipe);
+
+ free(ovpn_user);
+ free(svc_user);
+ free(cmdline);
+ DestroyEnvironmentBlock(user_env);
+ FreeStartupData(&sud);
+ CloseHandleEx(&proc_info.hProcess);
+ CloseHandleEx(&proc_info.hThread);
+ CloseHandleEx(&stdin_read);
+ CloseHandleEx(&stdin_write);
+ CloseHandleEx(&stdout_write);
+ CloseHandleEx(&svc_token);
+ CloseHandleEx(&imp_token);
+ CloseHandleEx(&pri_token);
+ CloseHandleEx(&ovpn_pipe);
+ CloseHandleEx(&svc_pipe);
+ CloseHandleEx(&pipe);
+
+ return 0;
}
static DWORD WINAPI
-ServiceCtrlInteractive (DWORD ctrl_code, DWORD event, LPVOID data, LPVOID ctx)
+ServiceCtrlInteractive(DWORD ctrl_code, DWORD event, LPVOID data, LPVOID ctx)
{
- SERVICE_STATUS *status = ctx;
- switch (ctrl_code)
+ SERVICE_STATUS *status = ctx;
+ switch (ctrl_code)
{
- case SERVICE_CONTROL_STOP:
- status->dwCurrentState = SERVICE_STOP_PENDING;
- ReportStatusToSCMgr (service, status);
- if (exit_event)
- SetEvent (exit_event);
- return NO_ERROR;
+ case SERVICE_CONTROL_STOP:
+ status->dwCurrentState = SERVICE_STOP_PENDING;
+ ReportStatusToSCMgr(service, status);
+ if (exit_event)
+ {
+ SetEvent(exit_event);
+ }
+ return NO_ERROR;
- case SERVICE_CONTROL_INTERROGATE:
- return NO_ERROR;
+ case SERVICE_CONTROL_INTERROGATE:
+ return NO_ERROR;
- default:
- return ERROR_CALL_NOT_IMPLEMENTED;
+ default:
+ return ERROR_CALL_NOT_IMPLEMENTED;
}
}
static HANDLE
-CreateClientPipeInstance (VOID)
+CreateClientPipeInstance(VOID)
{
- HANDLE pipe = NULL;
- PACL old_dacl, new_dacl;
- PSECURITY_DESCRIPTOR sd;
- static EXPLICIT_ACCESS ea[2];
- static BOOL initialized = FALSE;
- DWORD flags = PIPE_ACCESS_DUPLEX | WRITE_DAC | FILE_FLAG_OVERLAPPED;
+ HANDLE pipe = NULL;
+ PACL old_dacl, new_dacl;
+ PSECURITY_DESCRIPTOR sd;
+ static EXPLICIT_ACCESS ea[2];
+ static BOOL initialized = FALSE;
+ DWORD flags = PIPE_ACCESS_DUPLEX | WRITE_DAC | FILE_FLAG_OVERLAPPED;
- if (!initialized)
+ if (!initialized)
{
- PSID everyone, anonymous;
+ PSID everyone, anonymous;
- ConvertStringSidToSid (TEXT("S-1-1-0"), &everyone);
- ConvertStringSidToSid (TEXT("S-1-5-7"), &anonymous);
+ ConvertStringSidToSid(TEXT("S-1-1-0"), &everyone);
+ ConvertStringSidToSid(TEXT("S-1-5-7"), &anonymous);
- ea[0].grfAccessPermissions = FILE_GENERIC_WRITE;
- ea[0].grfAccessMode = GRANT_ACCESS;
- ea[0].grfInheritance = NO_INHERITANCE;
- ea[0].Trustee.pMultipleTrustee = NULL;
- ea[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
- ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
- ea[0].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
- ea[0].Trustee.ptstrName = (LPTSTR) everyone;
+ ea[0].grfAccessPermissions = FILE_GENERIC_WRITE;
+ ea[0].grfAccessMode = GRANT_ACCESS;
+ ea[0].grfInheritance = NO_INHERITANCE;
+ ea[0].Trustee.pMultipleTrustee = NULL;
+ ea[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
+ ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[0].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
+ ea[0].Trustee.ptstrName = (LPTSTR) everyone;
- ea[1].grfAccessPermissions = 0;
- ea[1].grfAccessMode = REVOKE_ACCESS;
- ea[1].grfInheritance = NO_INHERITANCE;
- ea[1].Trustee.pMultipleTrustee = NULL;
- ea[1].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
- ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
- ea[1].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
- ea[1].Trustee.ptstrName = (LPTSTR) anonymous;
+ ea[1].grfAccessPermissions = 0;
+ ea[1].grfAccessMode = REVOKE_ACCESS;
+ ea[1].grfInheritance = NO_INHERITANCE;
+ ea[1].Trustee.pMultipleTrustee = NULL;
+ ea[1].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
+ ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[1].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
+ ea[1].Trustee.ptstrName = (LPTSTR) anonymous;
- flags |= FILE_FLAG_FIRST_PIPE_INSTANCE;
- initialized = TRUE;
+ flags |= FILE_FLAG_FIRST_PIPE_INSTANCE;
+ initialized = TRUE;
}
- pipe = CreateNamedPipe (TEXT("\\\\.\\pipe\\openvpn\\service"), flags,
- PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
- PIPE_UNLIMITED_INSTANCES, 1024, 1024, 0, NULL);
- if (pipe == INVALID_HANDLE_VALUE)
+ pipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\openvpn\\service"), flags,
+ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
+ PIPE_UNLIMITED_INSTANCES, 1024, 1024, 0, NULL);
+ if (pipe == INVALID_HANDLE_VALUE)
{
- MsgToEventLog (M_SYSERR, TEXT("Could not create named pipe"));
- return INVALID_HANDLE_VALUE;
+ MsgToEventLog(M_SYSERR, TEXT("Could not create named pipe"));
+ return INVALID_HANDLE_VALUE;
}
- if (GetSecurityInfo (pipe, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
+ if (GetSecurityInfo(pipe, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
NULL, NULL, &old_dacl, NULL, &sd) != ERROR_SUCCESS)
{
- MsgToEventLog (M_SYSERR, TEXT("Could not get pipe security info"));
- return CloseHandleEx (&pipe);
+ MsgToEventLog(M_SYSERR, TEXT("Could not get pipe security info"));
+ return CloseHandleEx(&pipe);
}
- if (SetEntriesInAcl (2, ea, old_dacl, &new_dacl) != ERROR_SUCCESS)
+ if (SetEntriesInAcl(2, ea, old_dacl, &new_dacl) != ERROR_SUCCESS)
{
- MsgToEventLog (M_SYSERR, TEXT("Could not set entries in new acl"));
- return CloseHandleEx (&pipe);
+ MsgToEventLog(M_SYSERR, TEXT("Could not set entries in new acl"));
+ return CloseHandleEx(&pipe);
}
- if (SetSecurityInfo (pipe, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
+ if (SetSecurityInfo(pipe, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
NULL, NULL, new_dacl, NULL) != ERROR_SUCCESS)
{
- MsgToEventLog (M_SYSERR, TEXT("Could not set pipe security info"));
- return CloseHandleEx (&pipe);
+ MsgToEventLog(M_SYSERR, TEXT("Could not set pipe security info"));
+ return CloseHandleEx(&pipe);
}
- return pipe;
+ return pipe;
}
static DWORD
-UpdateWaitHandles (LPHANDLE *handles_ptr, LPDWORD count,
- HANDLE io_event, HANDLE exit_event, list_item_t *threads)
+UpdateWaitHandles(LPHANDLE *handles_ptr, LPDWORD count,
+ HANDLE io_event, HANDLE exit_event, list_item_t *threads)
{
- static DWORD size = 10;
- static LPHANDLE handles = NULL;
- DWORD pos = 0;
+ static DWORD size = 10;
+ static LPHANDLE handles = NULL;
+ DWORD pos = 0;
- if (handles == NULL)
+ if (handles == NULL)
{
- handles = malloc (size * sizeof (HANDLE));
- *handles_ptr = handles;
- if (handles == NULL)
- return ERROR_OUTOFMEMORY;
+ handles = malloc(size * sizeof(HANDLE));
+ *handles_ptr = handles;
+ if (handles == NULL)
+ {
+ return ERROR_OUTOFMEMORY;
+ }
}
- handles[pos++] = io_event;
+ handles[pos++] = io_event;
- if (!threads)
- handles[pos++] = exit_event;
+ if (!threads)
+ {
+ handles[pos++] = exit_event;
+ }
- while (threads)
+ while (threads)
{
- if (pos == size)
+ if (pos == size)
{
- LPHANDLE tmp;
- size += 10;
- tmp = realloc (handles, size * sizeof (HANDLE));
- if (tmp == NULL)
+ LPHANDLE tmp;
+ size += 10;
+ tmp = realloc(handles, size * sizeof(HANDLE));
+ if (tmp == NULL)
{
- size -= 10;
- *count = pos;
- return ERROR_OUTOFMEMORY;
+ size -= 10;
+ *count = pos;
+ return ERROR_OUTOFMEMORY;
}
- handles = tmp;
- *handles_ptr = handles;
+ handles = tmp;
+ *handles_ptr = handles;
}
- handles[pos++] = threads->data;
- threads = threads->next;
+ handles[pos++] = threads->data;
+ threads = threads->next;
}
- *count = pos;
- return NO_ERROR;
+ *count = pos;
+ return NO_ERROR;
}
static VOID
-FreeWaitHandles (LPHANDLE h)
+FreeWaitHandles(LPHANDLE h)
{
- free (h);
+ free(h);
}
VOID WINAPI
-ServiceStartInteractive (DWORD dwArgc, LPTSTR *lpszArgv)
+ServiceStartInteractive(DWORD dwArgc, LPTSTR *lpszArgv)
{
- HANDLE pipe, io_event = NULL;
- OVERLAPPED overlapped;
- DWORD error = NO_ERROR;
- list_item_t *threads = NULL;
- PHANDLE handles = NULL;
- DWORD handle_count;
- BOOL CmpHandle (LPVOID item, LPVOID hnd) { return item == hnd; }
-
- service = RegisterServiceCtrlHandlerEx (interactive_service.name, ServiceCtrlInteractive, &status);
- if (!service)
- return;
-
- status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
- status.dwCurrentState = SERVICE_START_PENDING;
- status.dwServiceSpecificExitCode = NO_ERROR;
- status.dwWin32ExitCode = NO_ERROR;
- status.dwWaitHint = 3000;
- ReportStatusToSCMgr (service, &status);
-
- /* Read info from registry in key HKLM\SOFTWARE\OpenVPN */
- error = GetOpenvpnSettings (&settings);
- if (error != ERROR_SUCCESS)
- goto out;
-
- io_event = InitOverlapped (&overlapped);
- exit_event = CreateEvent (NULL, TRUE, FALSE, NULL);
- if (!exit_event || !io_event)
- {
- error = MsgToEventLog (M_SYSERR, TEXT("Could not create event"));
- goto out;
- }
-
- rdns_semaphore = CreateSemaphoreW (NULL, 1, 1, NULL);
- if (!rdns_semaphore)
- {
- error = MsgToEventLog (M_SYSERR, TEXT("Could not create semaphore for register-dns"));
- goto out;
- }
-
- error = UpdateWaitHandles (&handles, &handle_count, io_event, exit_event, threads);
- if (error != NO_ERROR)
- goto out;
-
- pipe = CreateClientPipeInstance ();
- if (pipe == INVALID_HANDLE_VALUE)
- goto out;
-
- status.dwCurrentState = SERVICE_RUNNING;
- status.dwWaitHint = 0;
- ReportStatusToSCMgr (service, &status);
-
- while (TRUE)
- {
- if (ConnectNamedPipe (pipe, &overlapped) == FALSE &&
- GetLastError () != ERROR_PIPE_CONNECTED &&
- GetLastError () != ERROR_IO_PENDING)
+ HANDLE pipe, io_event = NULL;
+ OVERLAPPED overlapped;
+ DWORD error = NO_ERROR;
+ list_item_t *threads = NULL;
+ PHANDLE handles = NULL;
+ DWORD handle_count;
+ BOOL
+ CmpHandle(LPVOID item, LPVOID hnd) {
+ return item == hnd;
+ }
+
+ service = RegisterServiceCtrlHandlerEx(interactive_service.name, ServiceCtrlInteractive, &status);
+ if (!service)
+ {
+ return;
+ }
+
+ status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
+ status.dwCurrentState = SERVICE_START_PENDING;
+ status.dwServiceSpecificExitCode = NO_ERROR;
+ status.dwWin32ExitCode = NO_ERROR;
+ status.dwWaitHint = 3000;
+ ReportStatusToSCMgr(service, &status);
+
+ /* Read info from registry in key HKLM\SOFTWARE\OpenVPN */
+ error = GetOpenvpnSettings(&settings);
+ if (error != ERROR_SUCCESS)
+ {
+ goto out;
+ }
+
+ io_event = InitOverlapped(&overlapped);
+ exit_event = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (!exit_event || !io_event)
+ {
+ error = MsgToEventLog(M_SYSERR, TEXT("Could not create event"));
+ goto out;
+ }
+
+ rdns_semaphore = CreateSemaphoreW(NULL, 1, 1, NULL);
+ if (!rdns_semaphore)
+ {
+ error = MsgToEventLog(M_SYSERR, TEXT("Could not create semaphore for register-dns"));
+ goto out;
+ }
+
+ error = UpdateWaitHandles(&handles, &handle_count, io_event, exit_event, threads);
+ if (error != NO_ERROR)
+ {
+ goto out;
+ }
+
+ pipe = CreateClientPipeInstance();
+ if (pipe == INVALID_HANDLE_VALUE)
+ {
+ goto out;
+ }
+
+ status.dwCurrentState = SERVICE_RUNNING;
+ status.dwWaitHint = 0;
+ ReportStatusToSCMgr(service, &status);
+
+ while (TRUE)
+ {
+ if (ConnectNamedPipe(pipe, &overlapped) == FALSE
+ && GetLastError() != ERROR_PIPE_CONNECTED
+ && GetLastError() != ERROR_IO_PENDING)
{
- MsgToEventLog (M_SYSERR, TEXT("Could not connect pipe"));
- break;
+ MsgToEventLog(M_SYSERR, TEXT("Could not connect pipe"));
+ break;
}
- error = WaitForMultipleObjects (handle_count, handles, FALSE, INFINITE);
- if (error == WAIT_OBJECT_0)
+ error = WaitForMultipleObjects(handle_count, handles, FALSE, INFINITE);
+ if (error == WAIT_OBJECT_0)
{
- /* Client connected, spawn a worker thread for it */
- HANDLE next_pipe = CreateClientPipeInstance ();
- HANDLE thread = CreateThread (NULL, 0, RunOpenvpn, pipe, CREATE_SUSPENDED, NULL);
- if (thread)
+ /* Client connected, spawn a worker thread for it */
+ HANDLE next_pipe = CreateClientPipeInstance();
+ HANDLE thread = CreateThread(NULL, 0, RunOpenvpn, pipe, CREATE_SUSPENDED, NULL);
+ if (thread)
{
- error = AddListItem (&threads, thread);
- if (!error)
- error = UpdateWaitHandles (&handles, &handle_count, io_event, exit_event, threads);
- if (error)
+ error = AddListItem(&threads, thread);
+ if (!error)
+ {
+ error = UpdateWaitHandles(&handles, &handle_count, io_event, exit_event, threads);
+ }
+ if (error)
+ {
+ ReturnError(pipe, error, L"Insufficient resources to service new clients", 1, &exit_event);
+ /* Update wait handles again after removing the last worker thread */
+ RemoveListItem(&threads, CmpHandle, thread);
+ UpdateWaitHandles(&handles, &handle_count, io_event, exit_event, threads);
+ TerminateThread(thread, 1);
+ CloseHandleEx(&thread);
+ CloseHandleEx(&pipe);
+ }
+ else
{
- ReturnError (pipe, error, L"Insufficient resources to service new clients", 1, &exit_event);
- /* Update wait handles again after removing the last worker thread */
- RemoveListItem (&threads, CmpHandle, thread);
- UpdateWaitHandles (&handles, &handle_count, io_event, exit_event, threads);
- TerminateThread (thread, 1);
- CloseHandleEx (&thread);
- CloseHandleEx (&pipe);
+ ResumeThread(thread);
}
- else
- ResumeThread (thread);
}
- else
- CloseHandleEx (&pipe);
+ else
+ {
+ CloseHandleEx(&pipe);
+ }
- ResetOverlapped (&overlapped);
- pipe = next_pipe;
+ ResetOverlapped(&overlapped);
+ pipe = next_pipe;
}
- else
+ else
{
- CancelIo (pipe);
- if (error == WAIT_FAILED)
+ CancelIo(pipe);
+ if (error == WAIT_FAILED)
{
- MsgToEventLog (M_SYSERR, TEXT("WaitForMultipleObjects failed"));
- SetEvent (exit_event);
- /* Give some time for worker threads to exit and then terminate */
- Sleep (1000);
- break;
+ MsgToEventLog(M_SYSERR, TEXT("WaitForMultipleObjects failed"));
+ SetEvent(exit_event);
+ /* Give some time for worker threads to exit and then terminate */
+ Sleep(1000);
+ break;
}
- if (!threads)
+ if (!threads)
{
- /* exit event signaled */
- CloseHandleEx (&pipe);
- ResetEvent (exit_event);
- error = NO_ERROR;
- break;
+ /* exit event signaled */
+ CloseHandleEx(&pipe);
+ ResetEvent(exit_event);
+ error = NO_ERROR;
+ break;
}
- /* Worker thread ended */
- HANDLE thread = RemoveListItem (&threads, CmpHandle, handles[error]);
- UpdateWaitHandles (&handles, &handle_count, io_event, exit_event, threads);
- CloseHandleEx (&thread);
+ /* Worker thread ended */
+ HANDLE thread = RemoveListItem(&threads, CmpHandle, handles[error]);
+ UpdateWaitHandles(&handles, &handle_count, io_event, exit_event, threads);
+ CloseHandleEx(&thread);
}
}
out:
- FreeWaitHandles (handles);
- CloseHandleEx (&io_event);
- CloseHandleEx (&exit_event);
- CloseHandleEx (&rdns_semaphore);
-
- status.dwCurrentState = SERVICE_STOPPED;
- status.dwWin32ExitCode = error;
- ReportStatusToSCMgr (service, &status);
+ FreeWaitHandles(handles);
+ CloseHandleEx(&io_event);
+ CloseHandleEx(&exit_event);
+ CloseHandleEx(&rdns_semaphore);
+
+ status.dwCurrentState = SERVICE_STOPPED;
+ status.dwWin32ExitCode = error;
+ ReportStatusToSCMgr(service, &status);
}
diff --git a/src/openvpnserv/service.c b/src/openvpnserv/service.c
index 82f5551..b79e999 100644
--- a/src/openvpnserv/service.c
+++ b/src/openvpnserv/service.c
@@ -19,227 +19,257 @@ openvpn_service_t openvpn_service[_service_max];
BOOL
-ReportStatusToSCMgr (SERVICE_STATUS_HANDLE service, SERVICE_STATUS *status)
+ReportStatusToSCMgr(SERVICE_STATUS_HANDLE service, SERVICE_STATUS *status)
{
- static DWORD dwCheckPoint = 1;
- BOOL res = TRUE;
-
- if (status->dwCurrentState == SERVICE_START_PENDING)
- status->dwControlsAccepted = 0;
- else
- status->dwControlsAccepted = SERVICE_ACCEPT_STOP;
-
- if (status->dwCurrentState == SERVICE_RUNNING ||
- status->dwCurrentState == SERVICE_STOPPED)
- status->dwCheckPoint = 0;
- else
- status->dwCheckPoint = dwCheckPoint++;
-
- /* Report the status of the service to the service control manager. */
- res = SetServiceStatus (service, status);
- if (!res)
- MsgToEventLog(MSG_FLAGS_ERROR, TEXT("SetServiceStatus"));
-
- return res;
+ static DWORD dwCheckPoint = 1;
+ BOOL res = TRUE;
+
+ if (status->dwCurrentState == SERVICE_START_PENDING)
+ {
+ status->dwControlsAccepted = 0;
+ }
+ else
+ {
+ status->dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ }
+
+ if (status->dwCurrentState == SERVICE_RUNNING
+ || status->dwCurrentState == SERVICE_STOPPED)
+ {
+ status->dwCheckPoint = 0;
+ }
+ else
+ {
+ status->dwCheckPoint = dwCheckPoint++;
+ }
+
+ /* Report the status of the service to the service control manager. */
+ res = SetServiceStatus(service, status);
+ if (!res)
+ {
+ MsgToEventLog(MSG_FLAGS_ERROR, TEXT("SetServiceStatus"));
+ }
+
+ return res;
}
static int
-CmdInstallServices ()
+CmdInstallServices()
{
- SC_HANDLE service;
- SC_HANDLE svc_ctl_mgr;
- TCHAR path[512];
- int i, ret = _service_max;
-
- if (GetModuleFileName (NULL, path + 1, 510) == 0)
- {
- _tprintf (TEXT("Unable to install service - %s\n"), GetLastErrorText ());
- return 1;
- }
-
- path[0] = TEXT('\"');
- _tcscat (path, TEXT("\""));
-
- svc_ctl_mgr = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
- if (svc_ctl_mgr == NULL)
+ SC_HANDLE service;
+ SC_HANDLE svc_ctl_mgr;
+ TCHAR path[512];
+ int i, ret = _service_max;
+
+ if (GetModuleFileName(NULL, path + 1, 510) == 0)
{
- _tprintf (TEXT("OpenSCManager failed - %s\n"), GetLastErrorText ());
- return 1;
+ _tprintf(TEXT("Unable to install service - %s\n"), GetLastErrorText());
+ return 1;
}
- for (i = 0; i < _service_max; i++)
+ path[0] = TEXT('\"');
+ _tcscat(path, TEXT("\""));
+
+ svc_ctl_mgr = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
+ if (svc_ctl_mgr == NULL)
{
- service = CreateService (svc_ctl_mgr,
- openvpn_service[i].name,
- openvpn_service[i].display_name,
- SERVICE_QUERY_STATUS,
- SERVICE_WIN32_SHARE_PROCESS,
- openvpn_service[i].start_type,
- SERVICE_ERROR_NORMAL,
- path, NULL, NULL,
- openvpn_service[i].dependencies,
- NULL, NULL);
- if (service)
+ _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText());
+ return 1;
+ }
+
+ for (i = 0; i < _service_max; i++)
+ {
+ service = CreateService(svc_ctl_mgr,
+ openvpn_service[i].name,
+ openvpn_service[i].display_name,
+ SERVICE_QUERY_STATUS,
+ SERVICE_WIN32_SHARE_PROCESS,
+ openvpn_service[i].start_type,
+ SERVICE_ERROR_NORMAL,
+ path, NULL, NULL,
+ openvpn_service[i].dependencies,
+ NULL, NULL);
+ if (service)
+ {
+ _tprintf(TEXT("%s installed.\n"), openvpn_service[i].display_name);
+ CloseServiceHandle(service);
+ --ret;
+ }
+ else
{
- _tprintf (TEXT("%s installed.\n"), openvpn_service[i].display_name);
- CloseServiceHandle (service);
- --ret;
+ _tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText());
}
- else
- _tprintf (TEXT("CreateService failed - %s\n"), GetLastErrorText ());
}
- CloseServiceHandle (svc_ctl_mgr);
- return ret;
+ CloseServiceHandle(svc_ctl_mgr);
+ return ret;
}
static int
-CmdStartService (openvpn_service_type type)
+CmdStartService(openvpn_service_type type)
{
- int ret = 1;
- SC_HANDLE svc_ctl_mgr;
- SC_HANDLE service;
+ int ret = 1;
+ SC_HANDLE svc_ctl_mgr;
+ SC_HANDLE service;
- svc_ctl_mgr = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if (svc_ctl_mgr == NULL)
+ svc_ctl_mgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if (svc_ctl_mgr == NULL)
{
- _tprintf (TEXT("OpenSCManager failed - %s\n"), GetLastErrorText ());
- return 1;
+ _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText());
+ return 1;
}
- service = OpenService (svc_ctl_mgr, openvpn_service[type].name, SERVICE_ALL_ACCESS);
- if (service)
+ service = OpenService(svc_ctl_mgr, openvpn_service[type].name, SERVICE_ALL_ACCESS);
+ if (service)
{
- if (StartService (service, 0, NULL))
+ if (StartService(service, 0, NULL))
{
- _tprintf (TEXT("Service Started\n"));
- ret = 0;
+ _tprintf(TEXT("Service Started\n"));
+ ret = 0;
+ }
+ else
+ {
+ _tprintf(TEXT("StartService failed - %s\n"), GetLastErrorText());
}
- else
- _tprintf (TEXT("StartService failed - %s\n"), GetLastErrorText ());
- CloseServiceHandle(service);
+ CloseServiceHandle(service);
}
- else
+ else
{
- _tprintf (TEXT("OpenService failed - %s\n"), GetLastErrorText ());
+ _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText());
}
- CloseServiceHandle(svc_ctl_mgr);
- return ret;
+ CloseServiceHandle(svc_ctl_mgr);
+ return ret;
}
static int
-CmdRemoveServices ()
+CmdRemoveServices()
{
- SC_HANDLE service;
- SC_HANDLE svc_ctl_mgr;
- SERVICE_STATUS status;
- int i, ret = _service_max;
+ SC_HANDLE service;
+ SC_HANDLE svc_ctl_mgr;
+ SERVICE_STATUS status;
+ int i, ret = _service_max;
- svc_ctl_mgr = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT);
- if (svc_ctl_mgr == NULL)
+ svc_ctl_mgr = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+ if (svc_ctl_mgr == NULL)
{
- _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText ());
- return 1;
+ _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText());
+ return 1;
}
- for (i = 0; i < _service_max; i++)
+ for (i = 0; i < _service_max; i++)
{
- openvpn_service_t *ovpn_svc = &openvpn_service[i];
- service = OpenService (svc_ctl_mgr, ovpn_svc->name,
- DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS);
- if (service == NULL)
+ openvpn_service_t *ovpn_svc = &openvpn_service[i];
+ service = OpenService(svc_ctl_mgr, ovpn_svc->name,
+ DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS);
+ if (service == NULL)
{
- _tprintf (TEXT("OpenService failed - %s\n"), GetLastErrorText ());
- goto out;
+ _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText());
+ goto out;
}
- /* try to stop the service */
- if (ControlService (service, SERVICE_CONTROL_STOP, &status))
+ /* try to stop the service */
+ if (ControlService(service, SERVICE_CONTROL_STOP, &status))
{
- _tprintf (TEXT("Stopping %s."), ovpn_svc->display_name);
- Sleep (1000);
+ _tprintf(TEXT("Stopping %s."), ovpn_svc->display_name);
+ Sleep(1000);
- while (QueryServiceStatus (service, &status))
+ while (QueryServiceStatus(service, &status))
{
- if (status.dwCurrentState == SERVICE_STOP_PENDING)
+ if (status.dwCurrentState == SERVICE_STOP_PENDING)
{
- _tprintf (TEXT("."));
- Sleep (1000);
+ _tprintf(TEXT("."));
+ Sleep(1000);
+ }
+ else
+ {
+ break;
}
- else
- break;
}
- if (status.dwCurrentState == SERVICE_STOPPED)
- _tprintf (TEXT("\n%s stopped.\n"), ovpn_svc->display_name);
- else
- _tprintf (TEXT("\n%s failed to stop.\n"), ovpn_svc->display_name);
+ if (status.dwCurrentState == SERVICE_STOPPED)
+ {
+ _tprintf(TEXT("\n%s stopped.\n"), ovpn_svc->display_name);
+ }
+ else
+ {
+ _tprintf(TEXT("\n%s failed to stop.\n"), ovpn_svc->display_name);
+ }
}
- /* now remove the service */
- if (DeleteService (service))
+ /* now remove the service */
+ if (DeleteService(service))
{
- _tprintf (TEXT("%s removed.\n"), ovpn_svc->display_name);
- --ret;
+ _tprintf(TEXT("%s removed.\n"), ovpn_svc->display_name);
+ --ret;
+ }
+ else
+ {
+ _tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText());
}
- else
- _tprintf (TEXT("DeleteService failed - %s\n"), GetLastErrorText ());
- CloseServiceHandle (service);
+ CloseServiceHandle(service);
}
out:
- CloseServiceHandle (svc_ctl_mgr);
- return ret;
+ CloseServiceHandle(svc_ctl_mgr);
+ return ret;
}
int
-_tmain (int argc, TCHAR *argv[])
+_tmain(int argc, TCHAR *argv[])
{
- SERVICE_TABLE_ENTRY dispatchTable[] = {
- { automatic_service.name, ServiceStartAutomatic },
- { interactive_service.name, ServiceStartInteractive },
- { NULL, NULL }
- };
-
- openvpn_service[0] = automatic_service;
- openvpn_service[1] = interactive_service;
-
- if (argc > 1 && (*argv[1] == TEXT('-') || *argv[1] == TEXT('/')))
- {
- if (_tcsicmp (TEXT("install"), argv[1] + 1) == 0)
- return CmdInstallServices ();
- else if (_tcsicmp (TEXT("remove"), argv[1] + 1) == 0)
- return CmdRemoveServices ();
- else if (_tcsicmp (TEXT("start"), argv[1] + 1) == 0)
- {
- BOOL is_auto = argc < 3 || _tcsicmp (TEXT("interactive"), argv[2]) != 0;
- return CmdStartService (is_auto ? automatic : interactive);
- }
- else
- goto dispatch;
+ SERVICE_TABLE_ENTRY dispatchTable[] = {
+ { automatic_service.name, ServiceStartAutomatic },
+ { interactive_service.name, ServiceStartInteractive },
+ { NULL, NULL }
+ };
- return 0;
- }
+ openvpn_service[0] = automatic_service;
+ openvpn_service[1] = interactive_service;
- /* If it doesn't match any of the above parameters
- * the service control manager may be starting the service
- * so we must call StartServiceCtrlDispatcher
- */
+ if (argc > 1 && (*argv[1] == TEXT('-') || *argv[1] == TEXT('/')))
+ {
+ if (_tcsicmp(TEXT("install"), argv[1] + 1) == 0)
+ {
+ return CmdInstallServices();
+ }
+ else if (_tcsicmp(TEXT("remove"), argv[1] + 1) == 0)
+ {
+ return CmdRemoveServices();
+ }
+ else if (_tcsicmp(TEXT("start"), argv[1] + 1) == 0)
+ {
+ BOOL is_auto = argc < 3 || _tcsicmp(TEXT("interactive"), argv[2]) != 0;
+ return CmdStartService(is_auto ? automatic : interactive);
+ }
+ else
+ {
+ goto dispatch;
+ }
+
+ return 0;
+ }
+
+ /* If it doesn't match any of the above parameters
+ * the service control manager may be starting the service
+ * so we must call StartServiceCtrlDispatcher
+ */
dispatch:
- _tprintf (TEXT("%s -install to install the services\n"), APPNAME);
- _tprintf (TEXT("%s -start <name> to start a service (\"automatic\" or \"interactive\")\n"), APPNAME);
- _tprintf (TEXT("%s -remove to remove the services\n"), APPNAME);
- _tprintf (TEXT("\nStartServiceCtrlDispatcher being called.\n"));
- _tprintf (TEXT("This may take several seconds. Please wait.\n"));
+ _tprintf(TEXT("%s -install to install the services\n"), APPNAME);
+ _tprintf(TEXT("%s -start <name> to start a service (\"automatic\" or \"interactive\")\n"), APPNAME);
+ _tprintf(TEXT("%s -remove to remove the services\n"), APPNAME);
+ _tprintf(TEXT("\nStartServiceCtrlDispatcher being called.\n"));
+ _tprintf(TEXT("This may take several seconds. Please wait.\n"));
- if (!StartServiceCtrlDispatcher (dispatchTable))
- MsgToEventLog (MSG_FLAGS_ERROR, TEXT("StartServiceCtrlDispatcher failed."));
+ if (!StartServiceCtrlDispatcher(dispatchTable))
+ {
+ MsgToEventLog(MSG_FLAGS_ERROR, TEXT("StartServiceCtrlDispatcher failed."));
+ }
- return 0;
+ return 0;
}
diff --git a/src/openvpnserv/service.h b/src/openvpnserv/service.h
index c5d745f..b1130c9 100644
--- a/src/openvpnserv/service.h
+++ b/src/openvpnserv/service.h
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2013 Heiko Hund <heiko.hund@sophos.com>
+ * Copyright (C) 2013-2017 Heiko Hund <heiko.hund@sophos.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -48,48 +48,51 @@
#define M_ERR (MSG_FLAGS_ERROR) /* error */
typedef enum {
- automatic,
- interactive,
- _service_max
+ automatic,
+ interactive,
+ _service_max
} openvpn_service_type;
typedef struct {
- openvpn_service_type type;
- TCHAR *name;
- TCHAR *display_name;
- TCHAR *dependencies;
- DWORD start_type;
+ openvpn_service_type type;
+ TCHAR *name;
+ TCHAR *display_name;
+ TCHAR *dependencies;
+ DWORD start_type;
} openvpn_service_t;
#define MAX_NAME 256
typedef struct {
- TCHAR exe_path[MAX_PATH];
- TCHAR config_dir[MAX_PATH];
- TCHAR ext_string[16];
- TCHAR log_dir[MAX_PATH];
- TCHAR ovpn_admin_group[MAX_NAME];
- DWORD priority;
- BOOL append;
+ TCHAR exe_path[MAX_PATH];
+ TCHAR config_dir[MAX_PATH];
+ TCHAR ext_string[16];
+ TCHAR log_dir[MAX_PATH];
+ TCHAR ovpn_admin_group[MAX_NAME];
+ DWORD priority;
+ BOOL append;
} settings_t;
extern openvpn_service_t automatic_service;
extern openvpn_service_t interactive_service;
-VOID WINAPI ServiceStartAutomatic (DWORD argc, LPTSTR *argv);
-VOID WINAPI ServiceStartInteractive (DWORD argc, LPTSTR *argv);
+VOID WINAPI ServiceStartAutomatic(DWORD argc, LPTSTR *argv);
-int openvpn_vsntprintf (LPTSTR str, size_t size, LPCTSTR format, va_list arglist);
-int openvpn_sntprintf (LPTSTR str, size_t size, LPCTSTR format, ...);
+VOID WINAPI ServiceStartInteractive(DWORD argc, LPTSTR *argv);
-DWORD GetOpenvpnSettings (settings_t *s);
+int openvpn_vsntprintf(LPTSTR str, size_t size, LPCTSTR format, va_list arglist);
-BOOL ReportStatusToSCMgr (SERVICE_STATUS_HANDLE service, SERVICE_STATUS *status);
+int openvpn_sntprintf(LPTSTR str, size_t size, LPCTSTR format, ...);
-LPCTSTR GetLastErrorText ();
-DWORD MsgToEventLog (DWORD flags, LPCTSTR lpszMsg, ...);
+DWORD GetOpenvpnSettings(settings_t *s);
+
+BOOL ReportStatusToSCMgr(SERVICE_STATUS_HANDLE service, SERVICE_STATUS *status);
+
+LPCTSTR GetLastErrorText();
+
+DWORD MsgToEventLog(DWORD flags, LPCTSTR lpszMsg, ...);
/* Convert a utf8 string to utf16. Caller should free the result */
-wchar_t *utf8to16 (const char *utf8);
+wchar_t *utf8to16(const char *utf8);
-#endif
+#endif /* ifndef _SERVICE_H */
diff --git a/src/openvpnserv/validate.c b/src/openvpnserv/validate.c
index 7458d75..c9c3855 100644
--- a/src/openvpnserv/validate.c
+++ b/src/openvpnserv/validate.c
@@ -29,41 +29,41 @@
#include <lm.h>
static const WCHAR *white_list[] =
- {
- L"auth-retry",
- L"config",
- L"log",
- L"log-append",
- L"management",
- L"management-forget-disconnect",
- L"management-hold",
- L"management-query-passwords",
- L"management-query-proxy",
- L"management-signal",
- L"management-up-down",
- L"mute",
- L"setenv",
- L"service",
- L"verb",
-
- NULL /* last value */
- };
+{
+ L"auth-retry",
+ L"config",
+ L"log",
+ L"log-append",
+ L"management",
+ L"management-forget-disconnect",
+ L"management-hold",
+ L"management-query-passwords",
+ L"management-query-proxy",
+ L"management-signal",
+ L"management-up-down",
+ L"mute",
+ L"setenv",
+ L"service",
+ L"verb",
+
+ NULL /* last value */
+};
/*
* Check workdir\fname is inside config_dir
* The logic here is simple: we may reject some valid paths if ..\ is in any of the strings
*/
static BOOL
-CheckConfigPath (const WCHAR *workdir, const WCHAR *fname, const settings_t *s)
+CheckConfigPath(const WCHAR *workdir, const WCHAR *fname, const settings_t *s)
{
WCHAR tmp[MAX_PATH];
const WCHAR *config_file = NULL;
const WCHAR *config_dir = NULL;
/* convert fname to full path */
- if (PathIsRelativeW (fname) )
+ if (PathIsRelativeW(fname) )
{
- snwprintf (tmp, _countof(tmp), L"%s\\%s", workdir, fname);
+ snwprintf(tmp, _countof(tmp), L"%s\\%s", workdir, fname);
tmp[_countof(tmp)-1] = L'\0';
config_file = tmp;
}
@@ -75,17 +75,19 @@ CheckConfigPath (const WCHAR *workdir, const WCHAR *fname, const settings_t *s)
#ifdef UNICODE
config_dir = s->config_dir;
#else
- if (MultiByteToWideChar (CP_UTF8, 0, s->config_dir, -1, widepath, MAX_PATH) == 0)
+ if (MultiByteToWideChar(CP_UTF8, 0, s->config_dir, -1, widepath, MAX_PATH) == 0)
{
- MsgToEventLog (M_SYSERR, TEXT("Failed to convert config_dir name to WideChar"));
+ MsgToEventLog(M_SYSERR, TEXT("Failed to convert config_dir name to WideChar"));
return FALSE;
}
config_dir = widepath;
#endif
- if (wcsncmp (config_dir, config_file, wcslen(config_dir)) == 0 &&
- wcsstr (config_file + wcslen(config_dir), L"..") == NULL )
+ if (wcsncmp(config_dir, config_file, wcslen(config_dir)) == 0
+ && wcsstr(config_file + wcslen(config_dir), L"..") == NULL)
+ {
return TRUE;
+ }
return FALSE;
}
@@ -96,14 +98,16 @@ CheckConfigPath (const WCHAR *workdir, const WCHAR *fname, const settings_t *s)
* Returns index to the item if found, -1 otherwise.
*/
static int
-OptionLookup (const WCHAR *name, const WCHAR *white_list[])
+OptionLookup(const WCHAR *name, const WCHAR *white_list[])
{
int i;
- for (i = 0 ; white_list[i]; i++)
+ for (i = 0; white_list[i]; i++)
{
- if ( wcscmp(white_list[i], name) == 0 )
+ if (wcscmp(white_list[i], name) == 0)
+ {
return i;
+ }
}
return -1;
@@ -114,7 +118,7 @@ OptionLookup (const WCHAR *name, const WCHAR *white_list[])
* Get the local name of the group using the SID.
*/
static BOOL
-GetBuiltinAdminGroupName (WCHAR *name, DWORD nlen)
+GetBuiltinAdminGroupName(WCHAR *name, DWORD nlen)
{
BOOL b = FALSE;
PSID admin_sid = NULL;
@@ -126,15 +130,17 @@ GetBuiltinAdminGroupName (WCHAR *name, DWORD nlen)
admin_sid = malloc(sid_size);
if (!admin_sid)
+ {
return FALSE;
+ }
b = CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
- if(b)
+ if (b)
{
b = LookupAccountSidW(NULL, admin_sid, name, &nlen, domain, &dlen, &snu);
}
- free (admin_sid);
+ free(admin_sid);
return b;
}
@@ -144,7 +150,7 @@ GetBuiltinAdminGroupName (WCHAR *name, DWORD nlen)
* the group specified in s->ovpn_admin_group
*/
BOOL
-IsAuthorizedUser (SID *sid, settings_t *s)
+IsAuthorizedUser(SID *sid, settings_t *s)
{
LOCALGROUP_USERS_INFO_0 *groups = NULL;
DWORD nread;
@@ -160,19 +166,19 @@ IsAuthorizedUser (SID *sid, settings_t *s)
SID_NAME_USE sid_type;
/* Get username */
- if (!LookupAccountSidW (NULL, sid, username, &len, domain, &len, &sid_type))
+ if (!LookupAccountSidW(NULL, sid, username, &len, domain, &len, &sid_type))
{
- MsgToEventLog (M_SYSERR, TEXT("LookupAccountSid"));
+ MsgToEventLog(M_SYSERR, TEXT("LookupAccountSid"));
goto out;
}
/* Get an array of groups the user is member of */
- err = NetUserGetLocalGroups (NULL, username, 0, LG_INCLUDE_INDIRECT, (LPBYTE *) &groups,
- MAX_PREFERRED_LENGTH, &nread, &nmax);
+ err = NetUserGetLocalGroups(NULL, username, 0, LG_INCLUDE_INDIRECT, (LPBYTE *) &groups,
+ MAX_PREFERRED_LENGTH, &nread, &nmax);
if (err && err != ERROR_MORE_DATA)
{
- SetLastError (err);
- MsgToEventLog (M_SYSERR, TEXT("NetUserGetLocalGroups"));
+ SetLastError(err);
+ MsgToEventLog(M_SYSERR, TEXT("NetUserGetLocalGroups"));
goto out;
}
@@ -182,7 +188,7 @@ IsAuthorizedUser (SID *sid, settings_t *s)
}
else
{
- MsgToEventLog (M_SYSERR, TEXT("Failed to get the name of Administrators group. Using the default."));
+ MsgToEventLog(M_SYSERR, TEXT("Failed to get the name of Administrators group. Using the default."));
/* use the default value */
admin_group[0] = SYSTEM_ADMIN_GROUP;
}
@@ -191,25 +197,25 @@ IsAuthorizedUser (SID *sid, settings_t *s)
admin_group[1] = s->ovpn_admin_group;
#else
tmp = NULL;
- len = MultiByteToWideChar (CP_UTF8, 0, s->ovpn_admin_group, -1, NULL, 0);
- if (len == 0 || (tmp = malloc (len*sizeof(WCHAR))) == NULL)
+ len = MultiByteToWideChar(CP_UTF8, 0, s->ovpn_admin_group, -1, NULL, 0);
+ if (len == 0 || (tmp = malloc(len*sizeof(WCHAR))) == NULL)
{
- MsgToEventLog (M_SYSERR, TEXT("Failed to convert admin group name to WideChar"));
+ MsgToEventLog(M_SYSERR, TEXT("Failed to convert admin group name to WideChar"));
goto out;
}
- MultiByteToWideChar (CP_UTF8, 0, s->ovpn_admin_group, -1, tmp, len);
+ MultiByteToWideChar(CP_UTF8, 0, s->ovpn_admin_group, -1, tmp, len);
admin_group[1] = tmp;
#endif
/* Check if user's groups include any of the admin groups */
for (i = 0; i < nread; i++)
{
- if ( wcscmp (groups[i].lgrui0_name, admin_group[0]) == 0 ||
- wcscmp (groups[i].lgrui0_name, admin_group[1]) == 0
- )
+ if (wcscmp(groups[i].lgrui0_name, admin_group[0]) == 0
+ || wcscmp(groups[i].lgrui0_name, admin_group[1]) == 0
+ )
{
- MsgToEventLog (M_INFO, TEXT("Authorizing user %s by virtue of membership in group %s"),
- username, groups[i].lgrui0_name);
+ MsgToEventLog(M_INFO, TEXT("Authorizing user %s by virtue of membership in group %s"),
+ username, groups[i].lgrui0_name);
ret = TRUE;
break;
}
@@ -217,8 +223,10 @@ IsAuthorizedUser (SID *sid, settings_t *s)
out:
if (groups)
- NetApiBufferFree (groups);
- free (tmp);
+ {
+ NetApiBufferFree(groups);
+ }
+ free(tmp);
return ret;
}
@@ -229,21 +237,23 @@ out:
* The caller should set argc to the number of valid elements in argv[] array.
*/
BOOL
-CheckOption (const WCHAR *workdir, int argc, WCHAR *argv[], const settings_t *s)
+CheckOption(const WCHAR *workdir, int argc, WCHAR *argv[], const settings_t *s)
{
/* Do not modify argv or *argv -- ideally it should be const WCHAR *const *, but alas...*/
- if ( wcscmp (argv[0], L"--config") == 0 &&
- argc > 1 &&
- !CheckConfigPath (workdir, argv[1], s)
- )
+ if (wcscmp(argv[0], L"--config") == 0
+ && argc > 1
+ && !CheckConfigPath(workdir, argv[1], s)
+ )
{
return FALSE;
}
/* option name starts at 2 characters from argv[i] */
- if (OptionLookup (argv[0] + 2, white_list) == -1) /* not found */
+ if (OptionLookup(argv[0] + 2, white_list) == -1) /* not found */
+ {
return FALSE;
+ }
return TRUE;
}
diff --git a/src/openvpnserv/validate.h b/src/openvpnserv/validate.h
index 0d0270a..ece8704 100644
--- a/src/openvpnserv/validate.h
+++ b/src/openvpnserv/validate.h
@@ -34,15 +34,15 @@
/* The last one may be reset in registry: HKLM\Software\OpenVPN\ovpn_admin_group */
BOOL
-IsAuthorizedUser (SID *sid, settings_t *s);
+IsAuthorizedUser(SID *sid, settings_t *s);
BOOL
-CheckOption (const WCHAR *workdir, int narg, WCHAR *argv[], const settings_t *s);
+CheckOption(const WCHAR *workdir, int narg, WCHAR *argv[], const settings_t *s);
static inline BOOL
-IsOption (const WCHAR *o)
+IsOption(const WCHAR *o)
{
- return (wcsncmp (o, L"--", 2) == 0);
+ return (wcsncmp(o, L"--", 2) == 0);
}
-#endif
+#endif /* ifndef VALIDATE_H */