Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD

This commit is contained in:
vladimir.kuznetsov 2023-09-17 17:07:28 +05:00
commit 9b32411659
67 changed files with 4822 additions and 435 deletions

View file

@ -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()

View file

@ -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")

View file

@ -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()

View file

@ -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
};

View file

@ -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);
}

View file

@ -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()

View file

@ -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})

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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