summaryrefslogtreecommitdiff
path: root/src/openvpnserv/interactive.c
diff options
context:
space:
mode:
authorBernhard Schmidt <berni@debian.org>2020-04-19 15:52:33 +0200
committerBernhard Schmidt <berni@debian.org>2020-04-19 15:52:33 +0200
commit620785fe268a1221c1ba7a9cb5a70f3140a4f1ca (patch)
tree7b876715822d9620801283022ba73f2fce7387a3 /src/openvpnserv/interactive.c
parent8a3450ef8682b9085637d7b94afc5c7e6f92e64b (diff)
New upstream version 2.4.9upstream/2.4.9
Diffstat (limited to 'src/openvpnserv/interactive.c')
-rw-r--r--src/openvpnserv/interactive.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c
index d7c9eea..aecbd84 100644
--- a/src/openvpnserv/interactive.c
+++ b/src/openvpnserv/interactive.c
@@ -360,14 +360,13 @@ ReturnOpenvpnOutput(HANDLE pipe, HANDLE ovpn_output, DWORD count, LPHANDLE event
/*
* Validate options against a white list. Also check the config_file is
* inside the config_dir. The white list is defined in validate.c
- * Returns true on success
+ * Returns true on success, false on error with reason set in errmsg.
*/
static BOOL
-ValidateOptions(HANDLE pipe, const WCHAR *workdir, const WCHAR *options)
+ValidateOptions(HANDLE pipe, const WCHAR *workdir, const WCHAR *options, WCHAR *errmsg, DWORD capacity)
{
WCHAR **argv;
int argc;
- WCHAR buf[256];
BOOL ret = FALSE;
int i;
const WCHAR *msg1 = L"You have specified a config file location (%s relative to %s)"
@@ -382,8 +381,10 @@ ValidateOptions(HANDLE pipe, const WCHAR *workdir, const WCHAR *options)
if (!argv)
{
- ReturnLastError(pipe, L"CommandLineToArgvW");
- ReturnError(pipe, ERROR_STARTUP_DATA, L"Cannot validate options", 1, &exit_event);
+ swprintf(errmsg, capacity,
+ L"Cannot validate options: CommandLineToArgvW failed with error = 0x%08x",
+ GetLastError());
+ errmsg[capacity-1] = L'\0';
goto out;
}
@@ -403,10 +404,9 @@ ValidateOptions(HANDLE pipe, const WCHAR *workdir, const WCHAR *options)
if (!CheckOption(workdir, 2, argv_tmp, &settings))
{
- swprintf(buf, _countof(buf), msg1, argv[0], workdir,
+ swprintf(errmsg, capacity, msg1, argv[0], workdir,
settings.ovpn_admin_group);
- buf[_countof(buf) - 1] = L'\0';
- ReturnError(pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
+ errmsg[capacity-1] = L'\0';
}
goto out;
}
@@ -422,18 +422,15 @@ ValidateOptions(HANDLE pipe, const WCHAR *workdir, const WCHAR *options)
{
if (wcscmp(L"--config", argv[i]) == 0 && argc-i > 1)
{
- swprintf(buf, _countof(buf), msg1, argv[i+1], workdir,
+ swprintf(errmsg, capacity, msg1, argv[i+1], workdir,
settings.ovpn_admin_group);
- buf[_countof(buf) - 1] = L'\0';
- ReturnError(pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
}
else
{
- swprintf(buf, _countof(buf), msg2, argv[i],
+ swprintf(errmsg, capacity, msg2, argv[i],
settings.ovpn_admin_group);
- buf[_countof(buf) - 1] = L'\0';
- ReturnError(pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
}
+ errmsg[capacity-1] = L'\0';
goto out;
}
}
@@ -1352,7 +1349,7 @@ static DWORD WINAPI
RunOpenvpn(LPVOID p)
{
HANDLE pipe = p;
- HANDLE ovpn_pipe, svc_pipe;
+ HANDLE ovpn_pipe = NULL, svc_pipe = NULL;
PTOKEN_USER svc_user = NULL, ovpn_user = NULL;
HANDLE svc_token = NULL, imp_token = NULL, pri_token = NULL;
HANDLE stdin_read = NULL, stdin_write = NULL;
@@ -1367,6 +1364,7 @@ RunOpenvpn(LPVOID p)
WCHAR *cmdline = NULL;
size_t cmdline_size;
undo_lists_t undo_lists;
+ WCHAR errmsg[512] = L"";
SECURITY_ATTRIBUTES inheritable = {
.nLength = sizeof(inheritable),
@@ -1459,10 +1457,17 @@ RunOpenvpn(LPVOID p)
goto out;
}
- /* Check user is authorized or options are white-listed */
- if (!IsAuthorizedUser(ovpn_user->User.Sid, imp_token, settings.ovpn_admin_group)
- && !ValidateOptions(pipe, sud.directory, sud.options))
+ /*
+ * Only authorized users are allowed to use any command line options or
+ * have the config file in locations other than the global config directory.
+ *
+ * Check options are white-listed and config is in the global directory
+ * OR user is authorized to run any config.
+ */
+ if (!ValidateOptions(pipe, sud.directory, sud.options, errmsg, _countof(errmsg))
+ && !IsAuthorizedUser(ovpn_user->User.Sid, imp_token, settings.ovpn_admin_group))
{
+ ReturnError(pipe, ERROR_STARTUP_DATA, errmsg, 1, &exit_event);
goto out;
}