WireGuard rework for MacOS and Windows (#314)
WireGuard rework for MacOS and Windows
This commit is contained in:
parent
421a27ceae
commit
07c38e9b6c
60 changed files with 4779 additions and 434 deletions
|
|
@ -9,7 +9,3 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||
if(NOT IOS AND NOT ANDROID)
|
||||
add_subdirectory(server)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
add_subdirectory(wireguard-service)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ project(${PROJECT})
|
|||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Network RemoteObjects Core5Compat)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Network Widgets RemoteObjects Core5Compat)
|
||||
qt_standard_project_setup()
|
||||
|
||||
configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
|
||||
|
|
@ -50,7 +50,7 @@ set(HEADERS ${HEADERS}
|
|||
${CMAKE_CURRENT_LIST_DIR}/../../client/mozilla/models/server.h
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../client/mozilla/controllerimpl.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../client/mozilla/dnspingsender.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../client/mozilla/dnspingsender.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../client/mozilla/localsocketcontroller.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../client/mozilla/networkwatcher.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../client/mozilla/networkwatcherimpl.h
|
||||
|
|
@ -69,7 +69,8 @@ set(SOURCES ${SOURCES}
|
|||
${CMAKE_CURRENT_LIST_DIR}/../../client/mozilla/models/server.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../client/platforms/dummy/dummynetworkwatcher.cpp
|
||||
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../client/daemon/interfaceconfig.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../client/mozilla/shared/ipaddress.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../client/mozilla/shared/leakdetector.cpp
|
||||
|
||||
|
|
@ -107,11 +108,39 @@ if(WIN32)
|
|||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/tapcontroller_win.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/router_win.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowsdaemon.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowsdaemontunnel.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowsfirewall.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/windowscommons.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/windowsservicemanager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/dnsutilswindows.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowssplittunnel.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowstunnelservice.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/wireguardutilswindows.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowstunnellogger.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowsroutemonitor.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/windowsutils.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/windowspingsender.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/windowsnetworkwatcher.h
|
||||
)
|
||||
|
||||
set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/tapcontroller_win.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/router_win.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowsdaemon.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowsdaemontunnel.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowsfirewall.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/windowscommons.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/windowsservicemanager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/dnsutilswindows.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowssplittunnel.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowstunnelservice.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/wireguardutilswindows.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowstunnellogger.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/daemon/windowsroutemonitor.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/windowspingsender.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/windowsnetworkwatcher.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/windowsutils.cpp
|
||||
)
|
||||
|
||||
set(LIBS
|
||||
|
|
@ -188,7 +217,7 @@ include_directories(
|
|||
)
|
||||
|
||||
add_executable(${PROJECT} ${SOURCES} ${HEADERS})
|
||||
target_link_libraries(${PROJECT} PRIVATE Qt6::Core Qt6::Network Qt6::RemoteObjects Qt6::Core5Compat ${LIBS})
|
||||
target_link_libraries(${PROJECT} PRIVATE Qt6::Core Qt6::Widgets Qt6::Network Qt6::RemoteObjects Qt6::Core5Compat ${LIBS})
|
||||
target_compile_definitions(${PROJECT} PRIVATE "MZ_$<UPPER_CASE:${MZ_PLATFORM_NAME}>")
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#endif
|
||||
|
||||
namespace {
|
||||
Logger logger("MacOSDaemonServer");
|
||||
Logger logger("WgDaemonServer");
|
||||
}
|
||||
|
||||
LocalServer::LocalServer(QObject *parent) : QObject(parent),
|
||||
|
|
@ -40,17 +40,25 @@ LocalServer::LocalServer(QObject *parent) : QObject(parent),
|
|||
}
|
||||
});
|
||||
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
// Init Mozilla Wireguard Daemon
|
||||
#ifdef Q_OS_MAC
|
||||
if (!server.initialize()) {
|
||||
logger.error() << "Failed to initialize the server";
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
// Signal handling for a proper shutdown.
|
||||
QObject::connect(qApp, &QCoreApplication::aboutToQuit,
|
||||
[]() { MacOSDaemon::instance()->deactivate(); });
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Signal handling for a proper shutdown.
|
||||
QObject::connect(qApp, &QCoreApplication::aboutToQuit,
|
||||
[]() { WindowsDaemon::instance()->deactivate(); });
|
||||
#endif
|
||||
}
|
||||
|
||||
LocalServer::~LocalServer()
|
||||
|
|
|
|||
|
|
@ -10,9 +10,14 @@
|
|||
|
||||
#include "ipcserver.h"
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include "macos/daemon/macosdaemon.h"
|
||||
#ifdef Q_OS_WIN
|
||||
#include "../../client/daemon/daemonlocalserver.h"
|
||||
#include "windows/daemon/windowsdaemon.h"
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include "../../client/daemon/daemonlocalserver.h"
|
||||
#include "macos/daemon/macosdaemon.h"
|
||||
#endif
|
||||
|
||||
class QLocalServer;
|
||||
|
|
@ -33,9 +38,13 @@ public:
|
|||
QRemoteObjectHost m_serverNode;
|
||||
bool m_isRemotingEnabled = false;
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
MacOSDaemon daemon;
|
||||
#ifdef Q_OS_WIN
|
||||
DaemonLocalServer server{qApp};
|
||||
WindowsDaemon daemon;
|
||||
#endif
|
||||
#ifdef Q_OS_MAC
|
||||
DaemonLocalServer server{qApp};
|
||||
MacOSDaemon daemon;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,13 +6,39 @@
|
|||
#include "systemservice.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "platforms/windows/daemon/windowsdaemontunnel.h"
|
||||
|
||||
namespace {
|
||||
int s_argc = 0;
|
||||
char** s_argv = nullptr;
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
int runApplication(int argc, char** argv)
|
||||
{
|
||||
QCoreApplication app(argc,argv);
|
||||
LocalServer localServer;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if(argc > 2){
|
||||
s_argc = argc;
|
||||
s_argv = argv;
|
||||
QStringList tokens;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
tokens.append(QString(argv[i]));
|
||||
}
|
||||
|
||||
if (!tokens.empty() && tokens[0] == "tunneldaemon") {
|
||||
WindowsDaemonTunnel *daemon = new WindowsDaemonTunnel();
|
||||
daemon->run(tokens);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
LocalServer localServer;
|
||||
return app.exec();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -22,7 +48,7 @@ int main(int argc, char **argv)
|
|||
|
||||
Logger::init();
|
||||
|
||||
if (argc == 2) {
|
||||
if (argc >= 2) {
|
||||
qInfo() << "Started as console application";
|
||||
return runApplication(argc, argv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,39 @@
|
|||
#include "localserver.h"
|
||||
#include "systemservice.h"
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "platforms/windows/daemon/windowsdaemontunnel.h"
|
||||
|
||||
namespace {
|
||||
int s_argc = 0;
|
||||
char** s_argv = nullptr;
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
SystemService::SystemService(int argc, char **argv)
|
||||
: QtService<QCoreApplication>(argc, argv, SERVICE_NAME)
|
||||
{
|
||||
setServiceDescription("Service for AmneziaVPN");
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if(argc > 2){
|
||||
s_argc = argc;
|
||||
s_argv = argv;
|
||||
QStringList tokens;
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
tokens.append(QString(argv[i]));
|
||||
}
|
||||
|
||||
if (!tokens.empty() && tokens[0] == "tunneldaemon") {
|
||||
WindowsDaemonTunnel *daemon = new WindowsDaemonTunnel();
|
||||
daemon->run(tokens);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void SystemService::start()
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||
|
||||
set(PROJECT wireguard-service)
|
||||
project(${PROJECT} LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core)
|
||||
qt_standard_project_setup()
|
||||
|
||||
set(SOURCES
|
||||
${CMAKE_CURRENT_LIST_DIR}/main.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/wireguardtunnelservice.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
${CMAKE_CURRENT_LIST_DIR}/wireguardtunnelservice.h
|
||||
)
|
||||
|
||||
set(LIBS
|
||||
user32
|
||||
rasapi32
|
||||
shlwapi
|
||||
iphlpapi
|
||||
ws2_32
|
||||
iphlpapi
|
||||
gdi32
|
||||
Advapi32
|
||||
Kernel32
|
||||
)
|
||||
|
||||
add_executable(${PROJECT} ${SOURCES} ${HEADERS})
|
||||
target_link_libraries(${PROJECT} PRIVATE Qt6::Core ${LIBS})
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#include "wireguardtunnelservice.h"
|
||||
#include <strsafe.h>
|
||||
#include <Windows.h>
|
||||
|
||||
int wmain(int argc, wchar_t** argv)
|
||||
{
|
||||
if (argc != 3) {
|
||||
debug_log(L"Wrong argument provided");
|
||||
return 1;
|
||||
}
|
||||
TCHAR option[20];
|
||||
TCHAR configFile[5000];
|
||||
|
||||
StringCchCopy(option, 20, argv[1]);
|
||||
StringCchCopy(configFile, 5000, argv[2]);
|
||||
|
||||
WireguardTunnelService tunnel(configFile);
|
||||
|
||||
if (lstrcmpi(option, TEXT("--run")) == 0) {
|
||||
debug_log(L"start tunnel");
|
||||
tunnel.startTunnel();
|
||||
} else if (lstrcmpi(option, TEXT("--add")) == 0) {
|
||||
tunnel.addService();
|
||||
} else if (lstrcmpi(option, TEXT("--remove")) == 0) {
|
||||
tunnel.removeService();
|
||||
} else {
|
||||
debug_log(L"Wrong argument provided");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
#include "wireguardtunnelservice.h"
|
||||
#include <Windows.h>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <strsafe.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
void debug_log(const std::wstring& msg)
|
||||
{
|
||||
std::wcerr << msg << std::endl;
|
||||
}
|
||||
|
||||
WireguardTunnelService::WireguardTunnelService(const std::wstring& configFile):
|
||||
m_configFile{configFile}
|
||||
{
|
||||
}
|
||||
|
||||
void WireguardTunnelService::addService()
|
||||
{
|
||||
SC_HANDLE scm;
|
||||
SC_HANDLE service;
|
||||
scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||
if (NULL == scm) {
|
||||
debug_log(L"OpenSCManager failed");
|
||||
return;
|
||||
}
|
||||
WCHAR szFileName[MAX_PATH];
|
||||
|
||||
GetModuleFileNameW(NULL, szFileName, MAX_PATH);
|
||||
std::wstring runCommand = szFileName;
|
||||
runCommand += TEXT(" --run ");
|
||||
runCommand += m_configFile;
|
||||
|
||||
debug_log(runCommand);
|
||||
// check if service is already running
|
||||
service = OpenServiceW(
|
||||
scm,
|
||||
SVCNAME,
|
||||
SERVICE_ALL_ACCESS
|
||||
);
|
||||
if (NULL != service) {
|
||||
//service is already running, remove it before add new service
|
||||
debug_log(L"service is already running, remove it before add new service");
|
||||
CloseServiceHandle(service);
|
||||
removeService();
|
||||
}
|
||||
service = CreateServiceW(
|
||||
scm,
|
||||
SVCNAME,
|
||||
SVCNAME,
|
||||
SERVICE_ALL_ACCESS,
|
||||
SERVICE_WIN32_OWN_PROCESS,
|
||||
SERVICE_DEMAND_START,
|
||||
SERVICE_ERROR_NORMAL,
|
||||
runCommand.c_str(),
|
||||
NULL,
|
||||
NULL,
|
||||
TEXT("Nsi\0TcpIp"),
|
||||
NULL,
|
||||
NULL);
|
||||
if (NULL == service) {
|
||||
debug_log(L"CreateServiceW failed");
|
||||
CloseServiceHandle(scm);
|
||||
return;
|
||||
}
|
||||
SERVICE_SID_INFO info;
|
||||
info.dwServiceSidType = SERVICE_SID_TYPE_UNRESTRICTED;
|
||||
if (ChangeServiceConfig2W(service,
|
||||
SERVICE_CONFIG_SERVICE_SID_INFO,
|
||||
&info) == 0) {
|
||||
debug_log(L"ChangeServiceConfig2 failed");
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(scm);
|
||||
return;
|
||||
}
|
||||
if (StartServiceW(service, 0, NULL) == 0) {
|
||||
debug_log(L"StartServiceW failed");
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(scm);
|
||||
return;
|
||||
}
|
||||
if (DeleteService(service) == 0) {
|
||||
debug_log(L"DeleteService failed");
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(scm);
|
||||
return;
|
||||
}
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(scm);
|
||||
}
|
||||
|
||||
void WireguardTunnelService::removeService()
|
||||
{
|
||||
SC_HANDLE scm;
|
||||
SC_HANDLE service;
|
||||
scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||
if (NULL == scm) {
|
||||
debug_log(L"OpenSCManager failed");
|
||||
return;
|
||||
}
|
||||
service = OpenServiceW(
|
||||
scm,
|
||||
SVCNAME,
|
||||
SERVICE_ALL_ACCESS
|
||||
);
|
||||
if (NULL == service) {
|
||||
debug_log(L"OpenServiceW failed");
|
||||
CloseServiceHandle(scm);
|
||||
return;
|
||||
}
|
||||
SERVICE_STATUS stt;
|
||||
if (ControlService(service, SERVICE_CONTROL_STOP, &stt) == 0) {
|
||||
debug_log(L"ControlService failed");
|
||||
DeleteService(service);
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(scm);
|
||||
return;
|
||||
}
|
||||
for (int i = 0;
|
||||
i < 180 && QueryServiceStatus(scm, &stt) && stt.dwCurrentState != SERVICE_STOPPED;
|
||||
++i) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds{1});
|
||||
}
|
||||
DeleteService(service);
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(scm);
|
||||
}
|
||||
|
||||
|
||||
int WireguardTunnelService::startTunnel()
|
||||
{
|
||||
debug_log(TEXT(__FUNCTION__));
|
||||
|
||||
HMODULE tunnelLib = LoadLibrary(TEXT("tunnel.dll"));
|
||||
if (!tunnelLib) {
|
||||
debug_log(L"Failed to load tunnel.dll");
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef bool WireGuardTunnelService(const LPCWSTR settings);
|
||||
|
||||
WireGuardTunnelService* tunnelProc = (WireGuardTunnelService*)GetProcAddress(
|
||||
tunnelLib, "WireGuardTunnelService");
|
||||
if (!tunnelProc) {
|
||||
debug_log(L"Failed to get WireGuardTunnelService function");
|
||||
return 1;
|
||||
}
|
||||
|
||||
debug_log(m_configFile.c_str());
|
||||
|
||||
if (!tunnelProc(m_configFile.c_str())) {
|
||||
debug_log(L"Failed to activate the tunnel service");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
#ifndef WIREGUARDTUNNELSERVICE_H
|
||||
#define WIREGUARDTUNNELSERVICE_H
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
|
||||
#define SVCNAME TEXT("AmneziaVPNWireGuardService")
|
||||
|
||||
class WireguardTunnelService
|
||||
{
|
||||
public:
|
||||
WireguardTunnelService(const std::wstring& configFile);
|
||||
void addService();
|
||||
void removeService();
|
||||
int startTunnel();
|
||||
private:
|
||||
std::wstring m_configFile;
|
||||
};
|
||||
|
||||
void debug_log(const std::wstring& msg);
|
||||
|
||||
#endif // WIREGUARDTUNNELSERVICE_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue