mirror of
https://github.com/OpenVPN/openvpn3.git
synced 2024-09-20 04:02:15 +02:00
In HTTP server (httpserv.hpp), allow users to specify the Windows SDDL string used to set the permissions on created named pipes.
Also, refactor some Windows-specific code into secattr.hpp (SECURITY_ATTRIBUTES stuff) and npinfo.hpp (getting info about named pipe peer).
This commit is contained in:
parent
c81b4ac4ff
commit
22061c8135
165
openvpn/win/npinfo.hpp
Normal file
165
openvpn/win/npinfo.hpp
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012-2015 OpenVPN Technologies, Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Get info about named pipe peer
|
||||||
|
|
||||||
|
#ifndef OPENVPN_WIN_NPINFO_H
|
||||||
|
#define OPENVPN_WIN_NPINFO_H
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <sddl.h>
|
||||||
|
#include <aclapi.h>
|
||||||
|
|
||||||
|
#include <openvpn/common/exception.hpp>
|
||||||
|
#include <openvpn/win/winerr.hpp>
|
||||||
|
#include <openvpn/win/scoped_handle.hpp>
|
||||||
|
#include <openvpn/win/secattr.hpp>
|
||||||
|
|
||||||
|
namespace openvpn {
|
||||||
|
namespace Win {
|
||||||
|
struct NamedPipePeerInfo
|
||||||
|
{
|
||||||
|
OPENVPN_EXCEPTION(npinfo_error);
|
||||||
|
|
||||||
|
// Servers must call this method to modify their process
|
||||||
|
// access rights to grant clients the
|
||||||
|
// PROCESS_QUERY_LIMITED_INFORMATION right, so that clients
|
||||||
|
// can validate the server's exe path via get_exe_path().
|
||||||
|
static void allow_client_query()
|
||||||
|
{
|
||||||
|
SecurityAttributes sa(
|
||||||
|
"D:" // discretionary ACL
|
||||||
|
"(A;OICI;0x1000;;;S-1-1-0)" // allow PROCESS_QUERY_LIMITED_INFORMATION access to Everyone
|
||||||
|
,
|
||||||
|
false,
|
||||||
|
"client query");
|
||||||
|
|
||||||
|
ACL* dacl;
|
||||||
|
BOOL bDaclPresent, bDaclDefaulted;
|
||||||
|
if (!::GetSecurityDescriptorDacl(sa.sa.lpSecurityDescriptor,
|
||||||
|
&bDaclPresent,
|
||||||
|
&dacl,
|
||||||
|
&bDaclDefaulted))
|
||||||
|
{
|
||||||
|
const Win::LastError err;
|
||||||
|
OPENVPN_THROW(npinfo_error, "allow_client_query: GetSecurityDescriptorDacl failed: " << err.message());
|
||||||
|
}
|
||||||
|
if (!bDaclPresent)
|
||||||
|
OPENVPN_THROW(npinfo_error, "allow_client_query: missing DACL");
|
||||||
|
const DWORD ssi_status = ::SetSecurityInfo(
|
||||||
|
GetCurrentProcess(),
|
||||||
|
SE_KERNEL_OBJECT,
|
||||||
|
DACL_SECURITY_INFORMATION,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
dacl,
|
||||||
|
NULL);
|
||||||
|
if (ssi_status != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
const Win::Error err(ssi_status);
|
||||||
|
OPENVPN_THROW(npinfo_error, "allow_client_query: SetSecurityInfo failed: " << err.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get PID of process at other end of named pipe
|
||||||
|
static ULONG get_pid(const HANDLE np_handle, const bool client)
|
||||||
|
{
|
||||||
|
ULONG pid = 0;
|
||||||
|
if (client)
|
||||||
|
{
|
||||||
|
if (!::GetNamedPipeClientProcessId(np_handle, &pid))
|
||||||
|
{
|
||||||
|
const Win::LastError err;
|
||||||
|
OPENVPN_THROW(npinfo_error, "GetNamedPipeClientProcessId failed: " << err.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!::GetNamedPipeServerProcessId(np_handle, &pid))
|
||||||
|
{
|
||||||
|
const Win::LastError err;
|
||||||
|
OPENVPN_THROW(npinfo_error, "GetNamedPipeServerProcessId failed: " << err.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get process handle given PID.
|
||||||
|
static Win::ScopedHANDLE get_process(const ULONG pid, const bool limited)
|
||||||
|
{
|
||||||
|
// open process
|
||||||
|
Win::ScopedHANDLE proc(::OpenProcess(
|
||||||
|
limited ? PROCESS_QUERY_LIMITED_INFORMATION : PROCESS_ALL_ACCESS,
|
||||||
|
FALSE,
|
||||||
|
pid));
|
||||||
|
if (!proc.defined())
|
||||||
|
{
|
||||||
|
const Win::LastError err;
|
||||||
|
OPENVPN_THROW(npinfo_error, "OpenProcess failed: " << err.message());
|
||||||
|
}
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get exe path given process handle.
|
||||||
|
static std::wstring get_exe_path(const HANDLE proc)
|
||||||
|
{
|
||||||
|
// get exe path
|
||||||
|
const size_t exe_cap = 256;
|
||||||
|
wchar_t exe[exe_cap];
|
||||||
|
DWORD exe_size = exe_cap;
|
||||||
|
if (!::QueryFullProcessImageNameW(proc, 0, exe, &exe_size))
|
||||||
|
{
|
||||||
|
const Win::LastError err;
|
||||||
|
OPENVPN_THROW(npinfo_error, "QueryFullProcessImageName failed: " << err.message());
|
||||||
|
}
|
||||||
|
return std::wstring(exe, exe_size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used by server to get info about clients
|
||||||
|
struct NamedPipePeerInfoClient : public NamedPipePeerInfo
|
||||||
|
{
|
||||||
|
NamedPipePeerInfoClient(const HANDLE handle)
|
||||||
|
{
|
||||||
|
const ULONG pid = get_pid(handle, true);
|
||||||
|
Win::ScopedHANDLE proc = get_process(pid, false);
|
||||||
|
exe_path = get_exe_path(proc());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring exe_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used by clients to get info about the server
|
||||||
|
struct NamedPipePeerInfoServer : public NamedPipePeerInfo
|
||||||
|
{
|
||||||
|
NamedPipePeerInfoServer(const HANDLE handle)
|
||||||
|
{
|
||||||
|
const ULONG pid = get_pid(handle, false);
|
||||||
|
Win::ScopedHANDLE proc = get_process(pid, true);
|
||||||
|
exe_path = get_exe_path(proc());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring exe_path;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user