feature/mozilla upstream (#1237)
* cherry-pick 4dfcad96506fb5b88c5bb27342b6d9413fc361c9 from mozilla upstream * cherry-pick a95fa8c088b9edaff2de18751336942c2d145a9a from mozilla * cherry-pick commit 4fc1ebbad86a9abcafdc761725a7afd811c8d2d3 from mozilla * cherry-pick 4dfcad96506fb5b88c5bb27342b6d9413fc361c9 from mozilla upstream * cherry-pick 22de4fcbd454c64ff496c3380eeaeeb6afff4d64 from mozilla upstream * cherry-pick 649673be561b66c96367adf379da1545f8838763 from mozilla upstream * cherry-pick 41bdad34517d0ddaef32139482e5505d92e4b533 from mozilla upstream * cherry-pick f6e49a85538eaa230d3a8634fa7600966132ccab from mozilla upstream * cherry-pick 86c585387efa0a09c7937dfe799a90a666404fcd from mozilla upstream * cherry-pick a18c1fac740469ca3566751b74a16227518630c4 from mozilla upstream * fixed missing ; * added excludeLocalNetworks() for linux * build fixes on windows after cherry-picks * Add rules for excluded sites splittunell mode * Fix app splittunell when ipv6 is not setup * Fix Linux build --------- Co-authored-by: Mykola Baibuz <mykola.baibuz@gmail.com>
This commit is contained in:
parent
f1c6067485
commit
8ca31e0c90
27 changed files with 1119 additions and 607 deletions
|
@ -8,6 +8,7 @@
|
|||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <memory>
|
||||
|
||||
// Note: the ws2tcpip.h import must come before the others.
|
||||
// clang-format off
|
||||
|
@ -18,160 +19,78 @@
|
|||
#include <tlhelp32.h>
|
||||
#include <windows.h>
|
||||
|
||||
// States for GetState
|
||||
enum DRIVER_STATE {
|
||||
STATE_UNKNOWN = -1,
|
||||
STATE_NONE = 0,
|
||||
STATE_STARTED = 1,
|
||||
STATE_INITIALIZED = 2,
|
||||
STATE_READY = 3,
|
||||
STATE_RUNNING = 4,
|
||||
STATE_ZOMBIE = 5,
|
||||
};
|
||||
class WindowsFirewall;
|
||||
|
||||
#ifndef CTL_CODE
|
||||
|
||||
# define FILE_ANY_ACCESS 0x0000
|
||||
|
||||
# define METHOD_BUFFERED 0
|
||||
# define METHOD_IN_DIRECT 1
|
||||
# define METHOD_NEITHER 3
|
||||
|
||||
# define CTL_CODE(DeviceType, Function, Method, Access) \
|
||||
(((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
|
||||
#endif
|
||||
|
||||
// Known ControlCodes
|
||||
#define IOCTL_INITIALIZE CTL_CODE(0x8000, 1, METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_DEQUEUE_EVENT \
|
||||
CTL_CODE(0x8000, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_REGISTER_PROCESSES \
|
||||
CTL_CODE(0x8000, 3, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_REGISTER_IP_ADDRESSES \
|
||||
CTL_CODE(0x8000, 4, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_GET_IP_ADDRESSES \
|
||||
CTL_CODE(0x8000, 5, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_SET_CONFIGURATION \
|
||||
CTL_CODE(0x8000, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_GET_CONFIGURATION \
|
||||
CTL_CODE(0x8000, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_CLEAR_CONFIGURATION \
|
||||
CTL_CODE(0x8000, 8, METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_GET_STATE CTL_CODE(0x8000, 9, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_QUERY_PROCESS \
|
||||
CTL_CODE(0x8000, 10, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_ST_RESET CTL_CODE(0x8000, 11, METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||
|
||||
// Driver Configuration structures
|
||||
|
||||
typedef struct {
|
||||
// Offset into buffer region that follows all entries.
|
||||
// The image name uses the device path.
|
||||
SIZE_T ImageNameOffset;
|
||||
// Length of the String
|
||||
USHORT ImageNameLength;
|
||||
} CONFIGURATION_ENTRY;
|
||||
|
||||
typedef struct {
|
||||
// Number of entries immediately following the header.
|
||||
SIZE_T NumEntries;
|
||||
|
||||
// Total byte length: header + entries + string buffer.
|
||||
SIZE_T TotalLength;
|
||||
} CONFIGURATION_HEADER;
|
||||
|
||||
// Used to Configure Which IP is network/vpn
|
||||
typedef struct {
|
||||
IN_ADDR TunnelIpv4;
|
||||
IN_ADDR InternetIpv4;
|
||||
|
||||
IN6_ADDR TunnelIpv6;
|
||||
IN6_ADDR InternetIpv6;
|
||||
} IP_ADDRESSES_CONFIG;
|
||||
|
||||
// Used to Define Which Processes are alive on activation
|
||||
typedef struct {
|
||||
SIZE_T NumEntries;
|
||||
SIZE_T TotalLength;
|
||||
} PROCESS_DISCOVERY_HEADER;
|
||||
|
||||
typedef struct {
|
||||
HANDLE ProcessId;
|
||||
HANDLE ParentProcessId;
|
||||
|
||||
SIZE_T ImageNameOffset;
|
||||
USHORT ImageNameLength;
|
||||
} PROCESS_DISCOVERY_ENTRY;
|
||||
|
||||
typedef struct {
|
||||
DWORD ProcessId;
|
||||
DWORD ParentProcessId;
|
||||
FILETIME CreationTime;
|
||||
std::wstring DevicePath;
|
||||
} ProcessInfo;
|
||||
|
||||
class WindowsSplitTunnel final : public QObject {
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY_MOVE(WindowsSplitTunnel)
|
||||
class WindowsSplitTunnel final {
|
||||
public:
|
||||
explicit WindowsSplitTunnel(QObject* parent);
|
||||
/**
|
||||
* @brief Installs and Initializes the Split Tunnel Driver.
|
||||
*
|
||||
* @param fw -
|
||||
* @return std::unique_ptr<WindowsSplitTunnel> - Is null on failure.
|
||||
*/
|
||||
static std::unique_ptr<WindowsSplitTunnel> create(WindowsFirewall* fw);
|
||||
|
||||
/**
|
||||
* @brief Construct a new Windows Split Tunnel object
|
||||
*
|
||||
* @param driverIO - The Handle to the Driver's IO file, it assumes the driver
|
||||
* is in STATE_INITIALIZED and the Firewall has been setup.
|
||||
* Prefer using create() to get to this state.
|
||||
*/
|
||||
WindowsSplitTunnel(HANDLE driverIO);
|
||||
/**
|
||||
* @brief Destroy the Windows Split Tunnel object and uninstalls the Driver.
|
||||
*/
|
||||
~WindowsSplitTunnel();
|
||||
|
||||
// void excludeApps(const QStringList& paths);
|
||||
// Excludes an Application from the VPN
|
||||
void setRules(const QStringList& appPaths);
|
||||
bool excludeApps(const QStringList& appPaths);
|
||||
|
||||
// Fetches and Pushed needed info to move to engaged mode
|
||||
void start(int inetAdapterIndex, int vpnAdapterIndex = 0);
|
||||
bool start(int inetAdapterIndex, int vpnAdapterIndex = 0);
|
||||
// Deletes Rules and puts the driver into passive mode
|
||||
void stop();
|
||||
// Resets the Whole Driver
|
||||
void reset();
|
||||
|
||||
// Just close connection, leave state as is
|
||||
void close();
|
||||
// Returns true if the split-tunnel driver is now up and running.
|
||||
bool isRunning();
|
||||
|
||||
static bool detectConflict();
|
||||
|
||||
// States for GetState
|
||||
enum DRIVER_STATE {
|
||||
STATE_UNKNOWN = -1,
|
||||
STATE_NONE = 0,
|
||||
STATE_STARTED = 1,
|
||||
STATE_INITIALIZED = 2,
|
||||
STATE_READY = 3,
|
||||
STATE_RUNNING = 4,
|
||||
STATE_ZOMBIE = 5,
|
||||
};
|
||||
|
||||
private:
|
||||
// Installes the Kernel Driver as Driver Service
|
||||
static SC_HANDLE installDriver();
|
||||
static bool uninstallDriver();
|
||||
static bool isInstalled();
|
||||
static bool detectConflict();
|
||||
static bool initDriver(HANDLE driverIO);
|
||||
static DRIVER_STATE getState(HANDLE driverIO);
|
||||
static bool resetDriver(HANDLE driverIO);
|
||||
|
||||
private slots:
|
||||
void initDriver();
|
||||
|
||||
private:
|
||||
HANDLE m_driver = INVALID_HANDLE_VALUE;
|
||||
constexpr static const auto DRIVER_SYMLINK = L"\\\\.\\MULLVADSPLITTUNNEL";
|
||||
constexpr static const auto DRIVER_FILENAME = "mullvad-split-tunnel.sys";
|
||||
constexpr static const auto DRIVER_SERVICE_NAME = L"AmneziaVPNSplitTunnel";
|
||||
constexpr static const auto MV_SERVICE_NAME = L"MullvadVPN";
|
||||
DRIVER_STATE getState();
|
||||
|
||||
int m_tries;
|
||||
// Initializes the WFP Sublayer
|
||||
bool initSublayer();
|
||||
QString stateString();
|
||||
|
||||
// Generates a Configuration for Each APP
|
||||
std::vector<uint8_t> generateAppConfiguration(const QStringList& appPaths);
|
||||
// Generates a Configuration which IP's are VPN and which network
|
||||
std::vector<uint8_t> generateIPConfiguration(int inetAdapterIndex, int vpnAdapterIndex = 0);
|
||||
std::vector<std::byte> generateIPConfiguration(int inetAdapterIndex, int vpnAdapterIndex = 0);
|
||||
std::vector<uint8_t> generateProcessBlob();
|
||||
|
||||
void getAddress(int adapterIndex, IN_ADDR* out_ipv4, IN6_ADDR* out_ipv6);
|
||||
[[nodiscard]] bool getAddress(int adapterIndex, IN_ADDR* out_ipv4,
|
||||
IN6_ADDR* out_ipv6);
|
||||
// Collects info about an Opened Process
|
||||
ProcessInfo getProcessInfo(HANDLE process,
|
||||
const PROCESSENTRY32W& processMeta);
|
||||
|
||||
// Converts a path to a Dos Path:
|
||||
// e.g C:/a.exe -> /harddisk0/a.exe
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue