mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-24 02:00:24 +07:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 477a2f3591 | |||
| 3c3870f270 | |||
| ee7ac389a4 | |||
| bd414191e9 | |||
| 4eebb6673a | |||
| a36585d035 | |||
| c4de28bb3b | |||
| dcf1989414 | |||
| bd2288c239 | |||
| 781dba61f1 | |||
| 926d3643a4 |
@@ -233,7 +233,7 @@ jobs:
|
|||||||
- name: 'Setup xcode'
|
- name: 'Setup xcode'
|
||||||
uses: maxim-lobanov/setup-xcode@v1
|
uses: maxim-lobanov/setup-xcode@v1
|
||||||
with:
|
with:
|
||||||
xcode-version: '14.3.1'
|
xcode-version: '13.4'
|
||||||
|
|
||||||
- name: 'Install Qt'
|
- name: 'Install Qt'
|
||||||
uses: jurplel/install-qt-action@v3
|
uses: jurplel/install-qt-action@v3
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
|||||||
|
|
||||||
set(PROJECT AmneziaVPN)
|
set(PROJECT AmneziaVPN)
|
||||||
|
|
||||||
project(${PROJECT} VERSION 4.5.3.0
|
project(${PROJECT} VERSION 4.5.0.0
|
||||||
DESCRIPTION "AmneziaVPN"
|
DESCRIPTION "AmneziaVPN"
|
||||||
HOMEPAGE_URL "https://amnezia.org/"
|
HOMEPAGE_URL "https://amnezia.org/"
|
||||||
)
|
)
|
||||||
@@ -11,7 +11,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
|
|||||||
set(RELEASE_DATE "${CURRENT_DATE}")
|
set(RELEASE_DATE "${CURRENT_DATE}")
|
||||||
|
|
||||||
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||||
set(APP_ANDROID_VERSION_CODE 52)
|
set(APP_ANDROID_VERSION_CODE 50)
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||||
set(MZ_PLATFORM_NAME "linux")
|
set(MZ_PLATFORM_NAME "linux")
|
||||||
|
|||||||
+1
-1
Submodule client/3rd-prebuilt updated: c969f28b84...ab4e6b680d
Vendored
+1
-1
Submodule client/3rd/OpenVPNAdapter updated: 7c821a8d5c...6f71d0743d
@@ -72,7 +72,7 @@ namespace QSimpleCrypto
|
|||||||
/// \param notAfter - X509 end date.
|
/// \param notAfter - X509 end date.
|
||||||
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
|
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
|
||||||
///
|
///
|
||||||
X509* generateSelfSignedCertificate(RSA* rsa, const QMap<QByteArray, QByteArray>& additionalData,
|
X509* generateSelfSignedCertificate(const RSA* rsa, const QMap<QByteArray, QByteArray>& additionalData,
|
||||||
const QByteArray& certificateFileName = "", const EVP_MD* md = EVP_sha512(),
|
const QByteArray& certificateFileName = "", const EVP_MD* md = EVP_sha512(),
|
||||||
const long& serialNumber = 1, const long& version = x509LastVersion,
|
const long& serialNumber = 1, const long& version = x509LastVersion,
|
||||||
const long& notBefore = 0, const long& notAfter = oneYear);
|
const long& notBefore = 0, const long& notAfter = oneYear);
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ X509* QSimpleCrypto::QX509::verifyCertificate(X509* x509, X509_STORE* store)
|
|||||||
/// \param notAfter - X509 end date.
|
/// \param notAfter - X509 end date.
|
||||||
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
|
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
|
||||||
///
|
///
|
||||||
X509* QSimpleCrypto::QX509::generateSelfSignedCertificate(RSA* rsa, const QMap<QByteArray, QByteArray>& additionalData,
|
X509* QSimpleCrypto::QX509::generateSelfSignedCertificate(const RSA* rsa, const QMap<QByteArray, QByteArray>& additionalData,
|
||||||
const QByteArray& certificateFileName, const EVP_MD* md,
|
const QByteArray& certificateFileName, const EVP_MD* md,
|
||||||
const long& serialNumber, const long& version,
|
const long& serialNumber, const long& version,
|
||||||
const long& notBefore, const long& notAfter)
|
const long& notBefore, const long& notAfter)
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ set(AMNEZIAVPN_TS_FILES
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_fa_IR.ts
|
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_fa_IR.ts
|
||||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_ar_EG.ts
|
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_ar_EG.ts
|
||||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_my_MM.ts
|
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_my_MM.ts
|
||||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_uk_UA.ts
|
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB_RECURSE AMNEZIAVPN_TS_SOURCES *.qrc *.cpp *.h *.ui)
|
file(GLOB_RECURSE AMNEZIAVPN_TS_SOURCES *.qrc *.cpp *.h *.ui)
|
||||||
|
|||||||
@@ -9,16 +9,17 @@
|
|||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
|
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "ui/models/installedAppsModel.h"
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
#include "ui/models/installedAppsModel.h"
|
||||||
|
|
||||||
#include "platforms/ios/QRCodeReaderBase.h"
|
#include "platforms/ios/QRCodeReaderBase.h"
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
#include "core/installedAppsImageProvider.h"
|
|
||||||
#include "platforms/android/android_controller.h"
|
#include "platforms/android/android_controller.h"
|
||||||
|
#include "core/installedAppsImageProvider.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "protocols/qml_register_protocols.h"
|
#include "protocols/qml_register_protocols.h"
|
||||||
@@ -31,8 +32,8 @@
|
|||||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||||
AmneziaApplication::AmneziaApplication(int &argc, char *argv[]) : AMNEZIA_BASE_CLASS(argc, argv)
|
AmneziaApplication::AmneziaApplication(int &argc, char *argv[]) : AMNEZIA_BASE_CLASS(argc, argv)
|
||||||
#else
|
#else
|
||||||
AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecondary, SingleApplication::Options options, int timeout,
|
AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecondary, SingleApplication::Options options,
|
||||||
const QString &userData)
|
int timeout, const QString &userData)
|
||||||
: SingleApplication(argc, argv, allowSecondary, options, timeout, userData)
|
: SingleApplication(argc, argv, allowSecondary, options, timeout, userData)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@@ -45,12 +46,12 @@ AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecond
|
|||||||
s.setValue("permFixed", true);
|
s.setValue("permFixed", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString configLoc1 = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first() + "/" + ORGANIZATION_NAME + "/"
|
QString configLoc1 = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first() + "/"
|
||||||
+ APPLICATION_NAME + ".conf";
|
+ ORGANIZATION_NAME + "/" + APPLICATION_NAME + ".conf";
|
||||||
QFile::setPermissions(configLoc1, QFileDevice::ReadOwner | QFileDevice::WriteOwner);
|
QFile::setPermissions(configLoc1, QFileDevice::ReadOwner | QFileDevice::WriteOwner);
|
||||||
|
|
||||||
QString configLoc2 = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first() + "/" + ORGANIZATION_NAME + "/"
|
QString configLoc2 = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first() + "/"
|
||||||
+ APPLICATION_NAME + "/" + APPLICATION_NAME + ".conf";
|
+ ORGANIZATION_NAME + "/" + APPLICATION_NAME + "/" + APPLICATION_NAME + ".conf";
|
||||||
QFile::setPermissions(configLoc2, QFileDevice::ReadOwner | QFileDevice::WriteOwner);
|
QFile::setPermissions(configLoc2, QFileDevice::ReadOwner | QFileDevice::WriteOwner);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -99,13 +100,16 @@ void AmneziaApplication::init()
|
|||||||
connect(m_settings.get(), &Settings::saveLogsChanged, AndroidController::instance(), &AndroidController::setSaveLogs);
|
connect(m_settings.get(), &Settings::saveLogsChanged, AndroidController::instance(), &AndroidController::setSaveLogs);
|
||||||
|
|
||||||
AndroidController::instance()->setScreenshotsEnabled(m_settings->isScreenshotsEnabled());
|
AndroidController::instance()->setScreenshotsEnabled(m_settings->isScreenshotsEnabled());
|
||||||
connect(m_settings.get(), &Settings::screenshotsEnabledChanged, AndroidController::instance(), &AndroidController::setScreenshotsEnabled);
|
connect(m_settings.get(), &Settings::screenshotsEnabledChanged, AndroidController::instance(),
|
||||||
|
&AndroidController::setScreenshotsEnabled);
|
||||||
|
|
||||||
connect(m_settings.get(), &Settings::serverRemoved, AndroidController::instance(), &AndroidController::resetLastServer);
|
connect(m_settings.get(), &Settings::serverRemoved, AndroidController::instance(),
|
||||||
|
&AndroidController::resetLastServer);
|
||||||
|
|
||||||
connect(m_settings.get(), &Settings::settingsCleared, []() { AndroidController::instance()->resetLastServer(-1); });
|
connect(m_settings.get(), &Settings::settingsCleared, []() { AndroidController::instance()->resetLastServer(-1); });
|
||||||
|
|
||||||
connect(AndroidController::instance(), &AndroidController::initConnectionState, this, [this](Vpn::ConnectionState state) {
|
connect(AndroidController::instance(), &AndroidController::initConnectionState, this,
|
||||||
|
[this](Vpn::ConnectionState state) {
|
||||||
m_connectionController->onConnectionStateChanged(state);
|
m_connectionController->onConnectionStateChanged(state);
|
||||||
if (m_vpnConnection)
|
if (m_vpnConnection)
|
||||||
m_vpnConnection->restoreConnection();
|
m_vpnConnection->restoreConnection();
|
||||||
@@ -123,6 +127,8 @@ void AmneziaApplication::init()
|
|||||||
m_engine->addImageProvider(QLatin1String("installedAppImage"), new InstalledAppsImageProvider);
|
m_engine->addImageProvider(QLatin1String("installedAppImage"), new InstalledAppsImageProvider);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
#ifdef Q_OS_IOS
|
||||||
IosController::Instance()->initialize();
|
IosController::Instance()->initialize();
|
||||||
connect(IosController::Instance(), &IosController::importConfigFromOutside, [this](QString data) {
|
connect(IosController::Instance(), &IosController::importConfigFromOutside, [this](QString data) {
|
||||||
@@ -139,7 +145,8 @@ void AmneziaApplication::init()
|
|||||||
|
|
||||||
QTimer::singleShot(0, this, [this]() { AmneziaVPN::toggleScreenshots(m_settings->isScreenshotsEnabled()); });
|
QTimer::singleShot(0, this, [this]() { AmneziaVPN::toggleScreenshots(m_settings->isScreenshotsEnabled()); });
|
||||||
|
|
||||||
connect(m_settings.get(), &Settings::screenshotsEnabledChanged, [](bool enabled) { AmneziaVPN::toggleScreenshots(enabled); });
|
connect(m_settings.get(), &Settings::screenshotsEnabledChanged,
|
||||||
|
[](bool enabled) { AmneziaVPN::toggleScreenshots(enabled); });
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_notificationHandler.reset(NotificationHandler::create(nullptr));
|
m_notificationHandler.reset(NotificationHandler::create(nullptr));
|
||||||
@@ -147,12 +154,14 @@ void AmneziaApplication::init()
|
|||||||
connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, m_notificationHandler.get(),
|
connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, m_notificationHandler.get(),
|
||||||
&NotificationHandler::setConnectionState);
|
&NotificationHandler::setConnectionState);
|
||||||
|
|
||||||
connect(m_notificationHandler.get(), &NotificationHandler::raiseRequested, m_pageController.get(), &PageController::raiseMainWindow);
|
connect(m_notificationHandler.get(), &NotificationHandler::raiseRequested, m_pageController.get(),
|
||||||
|
&PageController::raiseMainWindow);
|
||||||
connect(m_notificationHandler.get(), &NotificationHandler::connectRequested, m_connectionController.get(),
|
connect(m_notificationHandler.get(), &NotificationHandler::connectRequested, m_connectionController.get(),
|
||||||
&ConnectionController::openConnection);
|
&ConnectionController::openConnection);
|
||||||
connect(m_notificationHandler.get(), &NotificationHandler::disconnectRequested, m_connectionController.get(),
|
connect(m_notificationHandler.get(), &NotificationHandler::disconnectRequested, m_connectionController.get(),
|
||||||
&ConnectionController::closeConnection);
|
&ConnectionController::closeConnection);
|
||||||
connect(this, &AmneziaApplication::translationsUpdated, m_notificationHandler.get(), &NotificationHandler::onTranslationsUpdated);
|
connect(this, &AmneziaApplication::translationsUpdated, m_notificationHandler.get(),
|
||||||
|
&NotificationHandler::onTranslationsUpdated);
|
||||||
|
|
||||||
m_engine->load(url);
|
m_engine->load(url);
|
||||||
m_systemController->setQmlRoot(m_engine->rootObjects().value(0));
|
m_systemController->setQmlRoot(m_engine->rootObjects().value(0));
|
||||||
@@ -293,23 +302,6 @@ QQmlApplicationEngine *AmneziaApplication::qmlEngine() const
|
|||||||
return m_engine;
|
return m_engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_MACOS
|
|
||||||
bool AmneziaApplication::event(QEvent *event)
|
|
||||||
{
|
|
||||||
if (event->type() == QEvent::FileOpen) {
|
|
||||||
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
|
|
||||||
const QUrl url = openEvent->url();
|
|
||||||
if (url.isLocalFile()) {
|
|
||||||
m_pageController->replaceStartPage();
|
|
||||||
m_importController->extractConfigFromFile(url.toLocalFile());
|
|
||||||
m_pageController->goToPageViewConfig();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QApplication::event(event);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void AmneziaApplication::initModels()
|
void AmneziaApplication::initModels()
|
||||||
{
|
{
|
||||||
m_containersModel.reset(new ContainersModel(this));
|
m_containersModel.reset(new ContainersModel(this));
|
||||||
@@ -320,7 +312,8 @@ void AmneziaApplication::initModels()
|
|||||||
|
|
||||||
m_serversModel.reset(new ServersModel(m_settings, this));
|
m_serversModel.reset(new ServersModel(m_settings, this));
|
||||||
m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get());
|
m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get());
|
||||||
connect(m_serversModel.get(), &ServersModel::containersUpdated, m_containersModel.get(), &ContainersModel::updateModel);
|
connect(m_serversModel.get(), &ServersModel::containersUpdated, m_containersModel.get(),
|
||||||
|
&ContainersModel::updateModel);
|
||||||
connect(m_serversModel.get(), &ServersModel::defaultServerContainersUpdated, m_defaultServerContainersModel.get(),
|
connect(m_serversModel.get(), &ServersModel::defaultServerContainersUpdated, m_defaultServerContainersModel.get(),
|
||||||
&ContainersModel::updateModel);
|
&ContainersModel::updateModel);
|
||||||
m_serversModel->resetModel();
|
m_serversModel->resetModel();
|
||||||
@@ -373,23 +366,26 @@ void AmneziaApplication::initModels()
|
|||||||
|
|
||||||
void AmneziaApplication::initControllers()
|
void AmneziaApplication::initControllers()
|
||||||
{
|
{
|
||||||
m_connectionController.reset(
|
m_connectionController.reset(new ConnectionController(m_serversModel, m_containersModel, m_clientManagementModel,
|
||||||
new ConnectionController(m_serversModel, m_containersModel, m_clientManagementModel, m_vpnConnection, m_settings));
|
m_vpnConnection, m_settings));
|
||||||
m_engine->rootContext()->setContextProperty("ConnectionController", m_connectionController.get());
|
m_engine->rootContext()->setContextProperty("ConnectionController", m_connectionController.get());
|
||||||
|
|
||||||
connect(m_connectionController.get(), &ConnectionController::connectionErrorOccurred, this, [this](const QString &errorMessage) {
|
connect(m_connectionController.get(), &ConnectionController::connectionErrorOccurred, this,
|
||||||
|
[this](const QString &errorMessage) {
|
||||||
emit m_pageController->showErrorMessage(errorMessage);
|
emit m_pageController->showErrorMessage(errorMessage);
|
||||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||||
});
|
});
|
||||||
connect(m_connectionController.get(), &ConnectionController::connectButtonClicked, m_connectionController.get(),
|
connect(m_connectionController.get(), &ConnectionController::connectButtonClicked, m_connectionController.get(),
|
||||||
&ConnectionController::toggleConnection, Qt::QueuedConnection);
|
&ConnectionController::toggleConnection, Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(this, &AmneziaApplication::translationsUpdated, m_connectionController.get(), &ConnectionController::onTranslationsUpdated);
|
connect(this, &AmneziaApplication::translationsUpdated, m_connectionController.get(),
|
||||||
|
&ConnectionController::onTranslationsUpdated);
|
||||||
|
|
||||||
m_pageController.reset(new PageController(m_serversModel, m_settings));
|
m_pageController.reset(new PageController(m_serversModel, m_settings));
|
||||||
m_engine->rootContext()->setContextProperty("PageController", m_pageController.get());
|
m_engine->rootContext()->setContextProperty("PageController", m_pageController.get());
|
||||||
|
|
||||||
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, m_clientManagementModel, m_settings));
|
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel,
|
||||||
|
m_clientManagementModel, m_settings));
|
||||||
m_engine->rootContext()->setContextProperty("InstallController", m_installController.get());
|
m_engine->rootContext()->setContextProperty("InstallController", m_installController.get());
|
||||||
connect(m_installController.get(), &InstallController::passphraseRequestStarted, m_pageController.get(),
|
connect(m_installController.get(), &InstallController::passphraseRequestStarted, m_pageController.get(),
|
||||||
&PageController::showPassphraseRequestDrawer);
|
&PageController::showPassphraseRequestDrawer);
|
||||||
@@ -405,12 +401,13 @@ void AmneziaApplication::initControllers()
|
|||||||
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
||||||
|
|
||||||
m_settingsController.reset(
|
m_settingsController.reset(
|
||||||
new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_sitesModel, m_appSplitTunnelingModel, m_settings));
|
new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_sitesModel, m_settings));
|
||||||
m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get());
|
m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get());
|
||||||
if (m_settingsController->isAutoConnectEnabled() && m_serversModel->getDefaultServerIndex() >= 0) {
|
if (m_settingsController->isAutoConnectEnabled() && m_serversModel->getDefaultServerIndex() >= 0) {
|
||||||
QTimer::singleShot(1000, this, [this]() { m_connectionController->openConnection(); });
|
QTimer::singleShot(1000, this, [this]() { m_connectionController->openConnection(); });
|
||||||
}
|
}
|
||||||
connect(m_settingsController.get(), &SettingsController::amneziaDnsToggled, m_serversModel.get(), &ServersModel::toggleAmneziaDns);
|
connect(m_settingsController.get(), &SettingsController::amneziaDnsToggled, m_serversModel.get(),
|
||||||
|
&ServersModel::toggleAmneziaDns);
|
||||||
|
|
||||||
m_sitesController.reset(new SitesController(m_settings, m_vpnConnection, m_sitesModel));
|
m_sitesController.reset(new SitesController(m_settings, m_vpnConnection, m_sitesModel));
|
||||||
m_engine->rootContext()->setContextProperty("SitesController", m_sitesController.get());
|
m_engine->rootContext()->setContextProperty("SitesController", m_sitesController.get());
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QFileOpenEvent>
|
|
||||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#else
|
#else
|
||||||
@@ -15,6 +14,8 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "vpnconnection.h"
|
#include "vpnconnection.h"
|
||||||
|
|
||||||
|
#include "core/controllers/apiController.h"
|
||||||
|
|
||||||
#include "ui/controllers/connectionController.h"
|
#include "ui/controllers/connectionController.h"
|
||||||
#include "ui/controllers/exportController.h"
|
#include "ui/controllers/exportController.h"
|
||||||
#include "ui/controllers/importController.h"
|
#include "ui/controllers/importController.h"
|
||||||
@@ -75,10 +76,6 @@ public:
|
|||||||
|
|
||||||
QQmlApplicationEngine *qmlEngine() const;
|
QQmlApplicationEngine *qmlEngine() const;
|
||||||
|
|
||||||
#ifdef Q_OS_MACOS
|
|
||||||
bool event(QEvent *event) override;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void translationsUpdated();
|
void translationsUpdated();
|
||||||
|
|
||||||
@@ -128,6 +125,7 @@ private:
|
|||||||
QScopedPointer<SettingsController> m_settingsController;
|
QScopedPointer<SettingsController> m_settingsController;
|
||||||
QScopedPointer<SitesController> m_sitesController;
|
QScopedPointer<SitesController> m_sitesController;
|
||||||
QScopedPointer<SystemController> m_systemController;
|
QScopedPointer<SystemController> m_systemController;
|
||||||
|
QScopedPointer<ApiController> m_apiController;
|
||||||
QScopedPointer<AppSplitTunnelingController> m_appSplitTunnelingController;
|
QScopedPointer<AppSplitTunnelingController> m_appSplitTunnelingController;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -406,19 +406,16 @@ class AmneziaActivity : QtActivity() {
|
|||||||
Log.v(TAG, "Open file with filter: $filter")
|
Log.v(TAG, "Open file with filter: $filter")
|
||||||
|
|
||||||
val mimeTypes = if (!filter.isNullOrEmpty()) {
|
val mimeTypes = if (!filter.isNullOrEmpty()) {
|
||||||
val extensionRegex = "\\*\\.([a-z0-9]+)".toRegex(IGNORE_CASE)
|
val extensionRegex = "\\*\\.[a-z .]+".toRegex(IGNORE_CASE)
|
||||||
val mime = MimeTypeMap.getSingleton()
|
val mime = MimeTypeMap.getSingleton()
|
||||||
extensionRegex.findAll(filter).map {
|
extensionRegex.findAll(filter).map {
|
||||||
it.groups[1]?.value?.let { mime.getMimeTypeFromExtension(it) } ?: "*/*"
|
mime.getMimeTypeFromExtension(it.value.drop(2))
|
||||||
}.toSet()
|
}.filterNotNull().toSet()
|
||||||
} else emptySet()
|
} else emptySet()
|
||||||
|
|
||||||
Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||||
addCategory(Intent.CATEGORY_OPENABLE)
|
addCategory(Intent.CATEGORY_OPENABLE)
|
||||||
Log.v(TAG, "File mimyType filter: $mimeTypes")
|
Log.v(TAG, "File mimyType filter: $mimeTypes")
|
||||||
if ("*/*" in mimeTypes) {
|
|
||||||
type = "*/*"
|
|
||||||
} else {
|
|
||||||
when (mimeTypes.size) {
|
when (mimeTypes.size) {
|
||||||
1 -> type = mimeTypes.first()
|
1 -> type = mimeTypes.first()
|
||||||
|
|
||||||
@@ -429,7 +426,6 @@ class AmneziaActivity : QtActivity() {
|
|||||||
|
|
||||||
else -> type = "*/*"
|
else -> type = "*/*"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}.also {
|
}.also {
|
||||||
startActivityForResult(it, OPEN_FILE_ACTION_CODE)
|
startActivityForResult(it, OPEN_FILE_ACTION_CODE)
|
||||||
}
|
}
|
||||||
@@ -453,7 +449,7 @@ class AmneziaActivity : QtActivity() {
|
|||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun setSaveLogs(enabled: Boolean) {
|
fun setSaveLogs(enabled: Boolean) {
|
||||||
Log.v(TAG, "Set save logs: $enabled")
|
Log.d(TAG, "Set save logs: $enabled")
|
||||||
mainScope.launch {
|
mainScope.launch {
|
||||||
Log.saveLogs = enabled
|
Log.saveLogs = enabled
|
||||||
vpnServiceMessenger.send {
|
vpnServiceMessenger.send {
|
||||||
@@ -473,10 +469,8 @@ class AmneziaActivity : QtActivity() {
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun clearLogs() {
|
fun clearLogs() {
|
||||||
Log.v(TAG, "Clear logs")
|
Log.v(TAG, "Clear logs")
|
||||||
mainScope.launch {
|
|
||||||
Log.clearLogs()
|
Log.clearLogs()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun setScreenshotsEnabled(enabled: Boolean) {
|
fun setScreenshotsEnabled(enabled: Boolean) {
|
||||||
|
|||||||
@@ -109,13 +109,11 @@ object Log {
|
|||||||
"${deviceInfo()}\n${readLogs()}\nLOGCAT:\n${getLogcat()}"
|
"${deviceInfo()}\n${readLogs()}\nLOGCAT:\n${getLogcat()}"
|
||||||
|
|
||||||
fun clearLogs() {
|
fun clearLogs() {
|
||||||
if (logDir.exists()) {
|
|
||||||
withLock {
|
withLock {
|
||||||
logFile.delete()
|
logFile.delete()
|
||||||
rotateLogFile.delete()
|
rotateLogFile.delete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun log(tag: String, msg: String, priority: Priority) {
|
private fun log(tag: String, msg: String, priority: Priority) {
|
||||||
if (saveLogs && priority != V) saveLogMsg(formatLogMsg(tag, msg, priority))
|
if (saveLogs && priority != V) saveLogMsg(formatLogMsg(tag, msg, priority))
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ foreach(abi IN ITEMS ${QT_ANDROID_ABIS})
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/libovpn3.so
|
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/libovpn3.so
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/libovpnutil.so
|
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/libovpnutil.so
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/librsapss.so
|
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/librsapss.so
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openssl/android/${abi}/libcrypto_3.so
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openssl/android/${abi}/libssl_3.so
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/libssh/android/${abi}/libssh.so
|
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/libssh/android/${abi}/libssh.so
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openssl3/android/${abi}/libcrypto_3.so
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openssl3/android/${abi}/libssl_3.so
|
||||||
)
|
)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|||||||
@@ -108,19 +108,16 @@ target_sources(${PROJECT} PRIVATE
|
|||||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||||
${CLIENT_ROOT_DIR}/platforms/ios/ScreenProtection.swift
|
${CLIENT_ROOT_DIR}/platforms/ios/ScreenProtection.swift
|
||||||
${CLIENT_ROOT_DIR}/platforms/ios/VPNCController.swift
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(${PROJECT} PRIVATE
|
target_sources(${PROJECT} PRIVATE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(ios/networkextension)
|
add_subdirectory(ios/networkextension)
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
message("MAC build")
|
message("MAC build")
|
||||||
|
|
||||||
set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
|
||||||
|
|
||||||
find_library(FW_SYSTEMCONFIG SystemConfiguration)
|
find_library(FW_SYSTEMCONFIG SystemConfiguration)
|
||||||
find_library(FW_SERVICEMGMT ServiceManagement)
|
find_library(FW_SERVICEMGMT ServiceManagement)
|
||||||
find_library(FW_SECURITY Security)
|
find_library(FW_SECURITY Security)
|
||||||
@@ -21,17 +19,6 @@ set(LIBS ${LIBS}
|
|||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(${PROJECT} PROPERTIES MACOSX_BUNDLE TRUE)
|
set_target_properties(${PROJECT} PROPERTIES MACOSX_BUNDLE TRUE)
|
||||||
|
|
||||||
set_target_properties(${PROJECT} PROPERTIES
|
|
||||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Info.plist
|
|
||||||
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPN"
|
|
||||||
XCODE_ATTRIBUTE_BUNDLE_INFO_STRING "AmneziaVPN"
|
|
||||||
MACOSX_BUNDLE_GUI_IDENTIFIER "${BUILD_OSX_APP_IDENTIFIER}"
|
|
||||||
MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
|
||||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${APPLE_PROJECT_VERSION}-${CMAKE_PROJECT_VERSION_TWEAK}"
|
|
||||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APPLE_PROJECT_VERSION}"
|
|
||||||
)
|
|
||||||
|
|
||||||
set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE INTERNAL "" FORCE)
|
set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE INTERNAL "" FORCE)
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15)
|
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15)
|
||||||
|
|
||||||
|
|||||||
@@ -3,13 +3,15 @@
|
|||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
||||||
AwgConfigurator::AwgConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent)
|
#include "core/controllers/serverController.h"
|
||||||
: WireguardConfigurator(settings, serverController, true, parent)
|
|
||||||
|
AwgConfigurator::AwgConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
|
: WireguardConfigurator(settings, true, parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AwgConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
QString AwgConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
ErrorCode errorCode)
|
const QJsonObject &containerConfig, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
QString config = WireguardConfigurator::createConfig(credentials, container, containerConfig, errorCode);
|
QString config = WireguardConfigurator::createConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
@@ -39,8 +41,8 @@ QString AwgConfigurator::createConfig(const ServerCredentials &credentials, Dock
|
|||||||
jsonConfig[config_key::responsePacketMagicHeader] = configMap.value(config_key::responsePacketMagicHeader);
|
jsonConfig[config_key::responsePacketMagicHeader] = configMap.value(config_key::responsePacketMagicHeader);
|
||||||
jsonConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader);
|
jsonConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader);
|
||||||
jsonConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader);
|
jsonConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader);
|
||||||
jsonConfig[config_key::mtu] =
|
jsonConfig[config_key::mtu] = containerConfig.value(ProtocolProps::protoToString(Proto::Awg)).toObject().
|
||||||
containerConfig.value(ProtocolProps::protoToString(Proto::Awg)).toObject().value(config_key::mtu).toString(protocols::awg::defaultMtu);
|
value(config_key::mtu).toString(protocols::awg::defaultMtu);
|
||||||
|
|
||||||
return QJsonDocument(jsonConfig).toJson();
|
return QJsonDocument(jsonConfig).toJson();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class AwgConfigurator : public WireguardConfigurator
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AwgConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
|
AwgConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode errorCode);
|
const QJsonObject &containerConfig, ErrorCode errorCode);
|
||||||
|
|||||||
@@ -1,30 +1,33 @@
|
|||||||
#include "cloak_configurator.h"
|
#include "cloak_configurator.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
|
||||||
#include "core/controllers/serverController.h"
|
#include "core/controllers/serverController.h"
|
||||||
|
#include "containers/containers_defs.h"
|
||||||
|
|
||||||
CloakConfigurator::CloakConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent)
|
CloakConfigurator::CloakConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
||||||
: ConfiguratorBase(settings, serverController, parent)
|
ConfiguratorBase(settings, parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CloakConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
QString CloakConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
ErrorCode errorCode)
|
const QJsonObject &containerConfig, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
QString cloakPublicKey =
|
ServerController serverController(m_settings);
|
||||||
m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::cloak::ckPublicKeyPath, errorCode);
|
|
||||||
|
QString cloakPublicKey = serverController.getTextFileFromContainer(container, credentials,
|
||||||
|
amnezia::protocols::cloak::ckPublicKeyPath, errorCode);
|
||||||
cloakPublicKey.replace("\n", "");
|
cloakPublicKey.replace("\n", "");
|
||||||
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString cloakBypassUid =
|
QString cloakBypassUid = serverController.getTextFileFromContainer(container, credentials,
|
||||||
m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::cloak::ckBypassUidKeyPath, errorCode);
|
amnezia::protocols::cloak::ckBypassUidKeyPath, errorCode);
|
||||||
cloakBypassUid.replace("\n", "");
|
cloakBypassUid.replace("\n", "");
|
||||||
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
@@ -44,8 +47,8 @@ QString CloakConfigurator::createConfig(const ServerCredentials &credentials, Do
|
|||||||
config.insert("RemoteHost", credentials.hostName);
|
config.insert("RemoteHost", credentials.hostName);
|
||||||
config.insert("RemotePort", "$CLOAK_SERVER_PORT");
|
config.insert("RemotePort", "$CLOAK_SERVER_PORT");
|
||||||
|
|
||||||
QString textCfg = m_serverController->replaceVars(QJsonDocument(config).toJson(),
|
QString textCfg = serverController.replaceVars(QJsonDocument(config).toJson(),
|
||||||
m_serverController->genVarsForScript(credentials, container, containerConfig));
|
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
return textCfg;
|
return textCfg;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class CloakConfigurator : public ConfiguratorBase
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
CloakConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
|
CloakConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode errorCode);
|
const QJsonObject &containerConfig, ErrorCode errorCode);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "configurator_base.h"
|
#include "configurator_base.h"
|
||||||
|
|
||||||
ConfiguratorBase::ConfiguratorBase(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent)
|
ConfiguratorBase::ConfiguratorBase(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
: QObject { parent }, m_settings(settings), m_serverController(serverController)
|
: QObject { parent }, m_settings(settings)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,13 @@
|
|||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "core/defs.h"
|
#include "core/defs.h"
|
||||||
#include "core/controllers/serverController.h"
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
class ConfiguratorBase : public QObject
|
class ConfiguratorBase : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ConfiguratorBase(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
|
explicit ConfiguratorBase(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
virtual QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
virtual QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode errorCode) = 0;
|
const QJsonObject &containerConfig, ErrorCode errorCode) = 0;
|
||||||
@@ -26,8 +25,6 @@ protected:
|
|||||||
void processConfigWithDnsSettings(const QPair<QString, QString> &dns, QString &protocolConfigString);
|
void processConfigWithDnsSettings(const QPair<QString, QString> &dns, QString &protocolConfigString);
|
||||||
|
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
QSharedPointer<ServerController> m_serverController;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONFIGURATORBASE_H
|
#endif // CONFIGURATORBASE_H
|
||||||
|
|||||||
@@ -9,18 +9,18 @@
|
|||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "core/controllers/serverController.h"
|
|
||||||
#include "core/scripts_registry.h"
|
#include "core/scripts_registry.h"
|
||||||
#include "core/server_defs.h"
|
#include "core/server_defs.h"
|
||||||
|
#include "core/controllers/serverController.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent)
|
Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
: ConfiguratorBase(settings, serverController, parent)
|
: ConfiguratorBase(settings, parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials, DockerContainer container,
|
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials,
|
||||||
ErrorCode errorCode)
|
DockerContainer container, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
Ikev2Configurator::ConnectionData connData;
|
Ikev2Configurator::ConnectionData connData;
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
@@ -39,14 +39,18 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
|||||||
"--extKeyUsage serverAuth,clientAuth -8 \"%1\"")
|
"--extKeyUsage serverAuth,clientAuth -8 \"%1\"")
|
||||||
.arg(connData.clientId);
|
.arg(connData.clientId);
|
||||||
|
|
||||||
errorCode = m_serverController->runContainerScript(credentials, container, scriptCreateCert);
|
ServerController serverController(m_settings);
|
||||||
|
errorCode = serverController.runContainerScript(credentials, container, scriptCreateCert);
|
||||||
|
|
||||||
QString scriptExportCert =
|
QString scriptExportCert = QString("pk12util -W \"%1\" -d sql:/etc/ipsec.d -n \"%2\" -o \"%3\"")
|
||||||
QString("pk12util -W \"%1\" -d sql:/etc/ipsec.d -n \"%2\" -o \"%3\"").arg(connData.password).arg(connData.clientId).arg(certFileName);
|
.arg(connData.password)
|
||||||
errorCode = m_serverController->runContainerScript(credentials, container, scriptExportCert);
|
.arg(connData.clientId)
|
||||||
|
.arg(certFileName);
|
||||||
|
errorCode = serverController.runContainerScript(credentials, container, scriptExportCert);
|
||||||
|
|
||||||
connData.clientCert = m_serverController->getTextFileFromContainer(container, credentials, certFileName, errorCode);
|
connData.clientCert = serverController.getTextFileFromContainer(container, credentials, certFileName, errorCode);
|
||||||
connData.caCert = m_serverController->getTextFileFromContainer(container, credentials, "/etc/ipsec.d/ca_cert_base64.p12", errorCode);
|
connData.caCert =
|
||||||
|
serverController.getTextFileFromContainer(container, credentials, "/etc/ipsec.d/ca_cert_base64.p12", errorCode);
|
||||||
|
|
||||||
qDebug() << "Ikev2Configurator::ConnectionData client cert size:" << connData.clientCert.size();
|
qDebug() << "Ikev2Configurator::ConnectionData client cert size:" << connData.clientCert.size();
|
||||||
qDebug() << "Ikev2Configurator::ConnectionData ca cert size:" << connData.caCert.size();
|
qDebug() << "Ikev2Configurator::ConnectionData ca cert size:" << connData.caCert.size();
|
||||||
@@ -54,8 +58,8 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
|||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Ikev2Configurator::createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
QString Ikev2Configurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
ErrorCode errorCode)
|
const QJsonObject &containerConfig, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
Q_UNUSED(containerConfig)
|
Q_UNUSED(containerConfig)
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class Ikev2Configurator : public ConfiguratorBase
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Ikev2Configurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
|
Ikev2Configurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
struct ConnectionData {
|
struct ConnectionData {
|
||||||
QByteArray clientCert; // p12 client cert
|
QByteArray clientCert; // p12 client cert
|
||||||
|
|||||||
@@ -24,14 +24,14 @@
|
|||||||
#include <openssl/rsa.h>
|
#include <openssl/rsa.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
|
|
||||||
OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController,
|
OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
QObject *parent)
|
: ConfiguratorBase(settings, parent)
|
||||||
: ConfiguratorBase(settings, serverController, parent)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials,
|
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials,
|
||||||
DockerContainer container, ErrorCode errorCode)
|
DockerContainer container,
|
||||||
|
ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
|
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
@@ -43,7 +43,8 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
|
|||||||
|
|
||||||
QString reqFileName = QString("%1/%2.req").arg(amnezia::protocols::openvpn::clientsDirPath).arg(connData.clientId);
|
QString reqFileName = QString("%1/%2.req").arg(amnezia::protocols::openvpn::clientsDirPath).arg(connData.clientId);
|
||||||
|
|
||||||
errorCode = m_serverController->uploadTextFileToContainer(container, credentials, connData.request, reqFileName);
|
ServerController serverController(m_settings);
|
||||||
|
errorCode = serverController.uploadTextFileToContainer(container, credentials, connData.request, reqFileName);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
@@ -53,16 +54,18 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
|
|||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.caCert =
|
connData.caCert = serverController.getTextFileFromContainer(container, credentials,
|
||||||
m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::caCertPath, errorCode);
|
amnezia::protocols::openvpn::caCertPath, errorCode);
|
||||||
connData.clientCert = m_serverController->getTextFileFromContainer(
|
connData.clientCert = serverController.getTextFileFromContainer(
|
||||||
container, credentials, QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), errorCode);
|
container, credentials,
|
||||||
|
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), errorCode);
|
||||||
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.taKey = m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::taKeyPath, errorCode);
|
connData.taKey = serverController.getTextFileFromContainer(container, credentials,
|
||||||
|
amnezia::protocols::openvpn::taKeyPath, errorCode);
|
||||||
|
|
||||||
if (connData.caCert.isEmpty() || connData.clientCert.isEmpty() || connData.taKey.isEmpty()) {
|
if (connData.caCert.isEmpty() || connData.clientCert.isEmpty() || connData.taKey.isEmpty()) {
|
||||||
errorCode = ErrorCode::SshScpFailureError;
|
errorCode = ErrorCode::SshScpFailureError;
|
||||||
@@ -74,8 +77,10 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
|
|||||||
QString OpenVpnConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString OpenVpnConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode errorCode)
|
const QJsonObject &containerConfig, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::openvpn_template, container),
|
ServerController serverController(m_settings);
|
||||||
m_serverController->genVarsForScript(credentials, container, containerConfig));
|
QString config =
|
||||||
|
serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::openvpn_template, container),
|
||||||
|
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode);
|
ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
@@ -117,15 +122,17 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPair<QString,
|
|||||||
QRegularExpression regex("redirect-gateway.*");
|
QRegularExpression regex("redirect-gateway.*");
|
||||||
config.replace(regex, "");
|
config.replace(regex, "");
|
||||||
|
|
||||||
if (!m_settings->getSitesSplitTunnelingEnabled()) {
|
if (m_settings->routeMode() == Settings::VpnAllSites) {
|
||||||
config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n");
|
config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n");
|
||||||
// Prevent ipv6 leak
|
// Prevent ipv6 leak
|
||||||
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
|
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
|
||||||
config.append("block-ipv6\n");
|
config.append("block-ipv6\n");
|
||||||
} else if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) {
|
}
|
||||||
|
if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) {
|
||||||
|
|
||||||
// no redirect-gateway
|
// no redirect-gateway
|
||||||
} else if (m_settings->routeMode() == Settings::VpnAllExceptSites) {
|
}
|
||||||
|
if (m_settings->routeMode() == Settings::VpnAllExceptSites) {
|
||||||
#ifndef Q_OS_ANDROID
|
#ifndef Q_OS_ANDROID
|
||||||
config.append("\nredirect-gateway ipv6 !ipv4 bypass-dhcp\n");
|
config.append("\nredirect-gateway ipv6 !ipv4 bypass-dhcp\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -189,10 +196,12 @@ ErrorCode OpenVpnConfigurator::signCert(DockerContainer container, const ServerC
|
|||||||
.arg(ContainerProps::containerToString(container))
|
.arg(ContainerProps::containerToString(container))
|
||||||
.arg(clientId);
|
.arg(clientId);
|
||||||
|
|
||||||
|
ServerController serverController(m_settings);
|
||||||
QStringList scriptList { script_import, script_sign };
|
QStringList scriptList { script_import, script_sign };
|
||||||
QString script = m_serverController->replaceVars(scriptList.join("\n"), m_serverController->genVarsForScript(credentials, container));
|
QString script = serverController.replaceVars(scriptList.join("\n"),
|
||||||
|
serverController.genVarsForScript(credentials, container));
|
||||||
|
|
||||||
return m_serverController->runScript(credentials, script);
|
return serverController.runScript(credentials, script);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
||||||
@@ -226,8 +235,8 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||||||
|
|
||||||
X509_NAME_add_entry_by_txt(x509_name, "C", MBSTRING_ASC, (unsigned char *)"ORG", -1, -1, 0);
|
X509_NAME_add_entry_by_txt(x509_name, "C", MBSTRING_ASC, (unsigned char *)"ORG", -1, -1, 0);
|
||||||
X509_NAME_add_entry_by_txt(x509_name, "O", MBSTRING_ASC, (unsigned char *)"", -1, -1, 0);
|
X509_NAME_add_entry_by_txt(x509_name, "O", MBSTRING_ASC, (unsigned char *)"", -1, -1, 0);
|
||||||
X509_NAME_add_entry_by_txt(x509_name, "CN", MBSTRING_ASC, reinterpret_cast<unsigned char const *>(clientIdUtf8.data()),
|
X509_NAME_add_entry_by_txt(x509_name, "CN", MBSTRING_ASC,
|
||||||
clientIdUtf8.size(), -1, 0);
|
reinterpret_cast<unsigned char const *>(clientIdUtf8.data()), clientIdUtf8.size(), -1, 0);
|
||||||
|
|
||||||
// 4. set public key of x509 req
|
// 4. set public key of x509 req
|
||||||
ret = X509_REQ_set_pubkey(x509_req, pKey);
|
ret = X509_REQ_set_pubkey(x509_req, pKey);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class OpenVpnConfigurator : public ConfiguratorBase
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
OpenVpnConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
|
OpenVpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
struct ConnectionData
|
struct ConnectionData
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,23 +1,25 @@
|
|||||||
#include "shadowsocks_configurator.h"
|
#include "shadowsocks_configurator.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "core/controllers/serverController.h"
|
#include "core/controllers/serverController.h"
|
||||||
|
|
||||||
ShadowSocksConfigurator::ShadowSocksConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController,
|
ShadowSocksConfigurator::ShadowSocksConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
||||||
QObject *parent)
|
ConfiguratorBase(settings, parent)
|
||||||
: ConfiguratorBase(settings, serverController, parent)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ShadowSocksConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString ShadowSocksConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode errorCode)
|
const QJsonObject &containerConfig, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
QString ssKey =
|
ServerController serverController(m_settings);
|
||||||
m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::shadowsocks::ssKeyPath, errorCode);
|
|
||||||
|
QString ssKey = serverController.getTextFileFromContainer(container, credentials,
|
||||||
|
amnezia::protocols::shadowsocks::ssKeyPath, errorCode);
|
||||||
ssKey.replace("\n", "");
|
ssKey.replace("\n", "");
|
||||||
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
@@ -32,9 +34,10 @@ QString ShadowSocksConfigurator::createConfig(const ServerCredentials &credentia
|
|||||||
config.insert("timeout", 60);
|
config.insert("timeout", 60);
|
||||||
config.insert("method", "$SHADOWSOCKS_CIPHER");
|
config.insert("method", "$SHADOWSOCKS_CIPHER");
|
||||||
|
|
||||||
QString textCfg = m_serverController->replaceVars(QJsonDocument(config).toJson(),
|
|
||||||
m_serverController->genVarsForScript(credentials, container, containerConfig));
|
|
||||||
|
|
||||||
// qDebug().noquote() << textCfg;
|
QString textCfg = serverController.replaceVars(QJsonDocument(config).toJson(),
|
||||||
|
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
|
//qDebug().noquote() << textCfg;
|
||||||
return textCfg;
|
return textCfg;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class ShadowSocksConfigurator : public ConfiguratorBase
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ShadowSocksConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
|
ShadowSocksConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode errorCode);
|
const QJsonObject &containerConfig, ErrorCode errorCode);
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
#include "core/server_defs.h"
|
#include "core/server_defs.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
SshConfigurator::SshConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent)
|
SshConfigurator::SshConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
: ConfiguratorBase(settings, serverController, parent)
|
: ConfiguratorBase(settings, parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,8 @@ void SshConfigurator::openSshTerminal(const ServerCredentials &credentials)
|
|||||||
// p->setNativeArguments(QString("%1@%2")
|
// p->setNativeArguments(QString("%1@%2")
|
||||||
// .arg(credentials.userName).arg(credentials.hostName).arg(credentials.secretData));
|
// .arg(credentials.userName).arg(credentials.hostName).arg(credentials.secretData));
|
||||||
} else {
|
} else {
|
||||||
p->setNativeArguments(QString("%1@%2 -pw %3").arg(credentials.userName).arg(credentials.hostName).arg(credentials.secretData));
|
p->setNativeArguments(
|
||||||
|
QString("%1@%2 -pw %3").arg(credentials.userName).arg(credentials.hostName).arg(credentials.secretData));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
p->setProgram("/bin/bash");
|
p->setProgram("/bin/bash");
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class SshConfigurator : ConfiguratorBase
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
SshConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
|
SshConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QProcessEnvironment prepareEnv();
|
QProcessEnvironment prepareEnv();
|
||||||
QString convertOpenSShKey(const QString &key);
|
QString convertOpenSShKey(const QString &key);
|
||||||
|
|||||||
@@ -19,13 +19,15 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController,
|
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, bool isAwg, QObject *parent)
|
||||||
bool isAwg, QObject *parent)
|
: ConfiguratorBase(settings, parent), m_isAwg(isAwg)
|
||||||
: ConfiguratorBase(settings, serverController, parent), m_isAwg(isAwg)
|
|
||||||
{
|
{
|
||||||
m_serverConfigPath = m_isAwg ? amnezia::protocols::awg::serverConfigPath : amnezia::protocols::wireguard::serverConfigPath;
|
m_serverConfigPath =
|
||||||
m_serverPublicKeyPath = m_isAwg ? amnezia::protocols::awg::serverPublicKeyPath : amnezia::protocols::wireguard::serverPublicKeyPath;
|
m_isAwg ? amnezia::protocols::awg::serverConfigPath : amnezia::protocols::wireguard::serverConfigPath;
|
||||||
m_serverPskKeyPath = m_isAwg ? amnezia::protocols::awg::serverPskKeyPath : amnezia::protocols::wireguard::serverPskKeyPath;
|
m_serverPublicKeyPath =
|
||||||
|
m_isAwg ? amnezia::protocols::awg::serverPublicKeyPath : amnezia::protocols::wireguard::serverPublicKeyPath;
|
||||||
|
m_serverPskKeyPath =
|
||||||
|
m_isAwg ? amnezia::protocols::awg::serverPskKeyPath : amnezia::protocols::wireguard::serverPskKeyPath;
|
||||||
m_configTemplate = m_isAwg ? ProtocolScriptType::awg_template : ProtocolScriptType::wireguard_template;
|
m_configTemplate = m_isAwg ? ProtocolScriptType::awg_template : ProtocolScriptType::wireguard_template;
|
||||||
|
|
||||||
m_protocolName = m_isAwg ? config_key::awg : config_key::wireguard;
|
m_protocolName = m_isAwg ? config_key::awg : config_key::wireguard;
|
||||||
@@ -65,7 +67,8 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
|||||||
|
|
||||||
WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardConfig(const ServerCredentials &credentials,
|
WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardConfig(const ServerCredentials &credentials,
|
||||||
DockerContainer container,
|
DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode errorCode)
|
const QJsonObject &containerConfig,
|
||||||
|
ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
|
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
@@ -76,6 +79,8 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerController serverController(m_settings);
|
||||||
|
|
||||||
// Get list of already created clients (only IP addresses)
|
// Get list of already created clients (only IP addresses)
|
||||||
QString nextIpNumber;
|
QString nextIpNumber;
|
||||||
{
|
{
|
||||||
@@ -86,7 +91,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
};
|
};
|
||||||
|
|
||||||
errorCode = m_serverController->runContainerScript(credentials, container, script, cbReadStdOut);
|
errorCode = serverController.runContainerScript(credentials, container, script, cbReadStdOut);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
@@ -108,7 +113,8 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString subnetIp = containerConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
QString subnetIp =
|
||||||
|
containerConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
||||||
{
|
{
|
||||||
QStringList l = subnetIp.split(".", Qt::SkipEmptyParts);
|
QStringList l = subnetIp.split(".", Qt::SkipEmptyParts);
|
||||||
if (l.isEmpty()) {
|
if (l.isEmpty()) {
|
||||||
@@ -122,13 +128,14 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get keys
|
// Get keys
|
||||||
connData.serverPubKey = m_serverController->getTextFileFromContainer(container, credentials, m_serverPublicKeyPath, errorCode);
|
connData.serverPubKey =
|
||||||
|
serverController.getTextFileFromContainer(container, credentials, m_serverPublicKeyPath, errorCode);
|
||||||
connData.serverPubKey.replace("\n", "");
|
connData.serverPubKey.replace("\n", "");
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.pskKey = m_serverController->getTextFileFromContainer(container, credentials, m_serverPskKeyPath, errorCode);
|
connData.pskKey = serverController.getTextFileFromContainer(container, credentials, m_serverPskKeyPath, errorCode);
|
||||||
connData.pskKey.replace("\n", "");
|
connData.pskKey.replace("\n", "");
|
||||||
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
@@ -142,17 +149,18 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
"AllowedIPs = %3/32\n\n")
|
"AllowedIPs = %3/32\n\n")
|
||||||
.arg(connData.clientPubKey, connData.pskKey, connData.clientIP);
|
.arg(connData.clientPubKey, connData.pskKey, connData.clientIP);
|
||||||
|
|
||||||
errorCode = m_serverController->uploadTextFileToContainer(container, credentials, configPart, m_serverConfigPath,
|
errorCode = serverController.uploadTextFileToContainer(container, credentials, configPart, m_serverConfigPath,
|
||||||
libssh::ScpOverwriteMode::ScpAppendToExisting);
|
libssh::ScpOverwriteMode::ScpAppendToExisting);
|
||||||
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString script = QString("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'").arg(m_serverConfigPath);
|
QString script = QString("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'")
|
||||||
|
.arg(m_serverConfigPath);
|
||||||
|
|
||||||
errorCode = m_serverController->runScript(
|
errorCode = serverController.runScript(
|
||||||
credentials, m_serverController->replaceVars(script, m_serverController->genVarsForScript(credentials, container)));
|
credentials, serverController.replaceVars(script, serverController.genVarsForScript(credentials, container)));
|
||||||
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
@@ -160,9 +168,10 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
QString WireguardConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString WireguardConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode errorCode)
|
const QJsonObject &containerConfig, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
|
ServerController serverController(m_settings);
|
||||||
QString scriptData = amnezia::scriptData(m_configTemplate, container);
|
QString scriptData = amnezia::scriptData(m_configTemplate, container);
|
||||||
QString config =
|
QString config = serverController.replaceVars(
|
||||||
m_serverController->replaceVars(scriptData, m_serverController->genVarsForScript(credentials, container, containerConfig));
|
scriptData, serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode);
|
ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
@@ -192,16 +201,16 @@ QString WireguardConfigurator::createConfig(const ServerCredentials &credentials
|
|||||||
return QJsonDocument(jConfig).toJson();
|
return QJsonDocument(jConfig).toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WireguardConfigurator::processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
QString WireguardConfigurator::processConfigWithLocalSettings(const QPair<QString, QString> &dns,
|
||||||
QString &protocolConfigString)
|
const bool isApiConfig, QString &protocolConfigString)
|
||||||
{
|
{
|
||||||
processConfigWithDnsSettings(dns, protocolConfigString);
|
processConfigWithDnsSettings(dns, protocolConfigString);
|
||||||
|
|
||||||
return protocolConfigString;
|
return protocolConfigString;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WireguardConfigurator::processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
QString WireguardConfigurator::processConfigWithExportSettings(const QPair<QString, QString> &dns,
|
||||||
QString &protocolConfigString)
|
const bool isApiConfig, QString &protocolConfigString)
|
||||||
{
|
{
|
||||||
processConfigWithDnsSettings(dns, protocolConfigString);
|
processConfigWithDnsSettings(dns, protocolConfigString);
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ class WireguardConfigurator : public ConfiguratorBase
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
WireguardConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, bool isAwg,
|
WireguardConfigurator(std::shared_ptr<Settings> settings, bool isAwg, QObject *parent = nullptr);
|
||||||
QObject *parent = nullptr);
|
|
||||||
|
|
||||||
struct ConnectionData
|
struct ConnectionData
|
||||||
{
|
{
|
||||||
@@ -26,11 +25,13 @@ public:
|
|||||||
QString port;
|
QString port;
|
||||||
};
|
};
|
||||||
|
|
||||||
QString createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
ErrorCode errorCode);
|
const QJsonObject &containerConfig, ErrorCode errorCode);
|
||||||
|
|
||||||
QString processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig, QString &protocolConfigString);
|
QString processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
||||||
QString processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig, QString &protocolConfigString);
|
QString &protocolConfigString);
|
||||||
|
QString processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
||||||
|
QString &protocolConfigString);
|
||||||
|
|
||||||
static ConnectionData genClientKeys();
|
static ConnectionData genClientKeys();
|
||||||
|
|
||||||
|
|||||||
@@ -8,26 +8,26 @@
|
|||||||
#include "core/controllers/serverController.h"
|
#include "core/controllers/serverController.h"
|
||||||
#include "core/scripts_registry.h"
|
#include "core/scripts_registry.h"
|
||||||
|
|
||||||
XrayConfigurator::XrayConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent)
|
XrayConfigurator::XrayConfigurator(std::shared_ptr<Settings> settings, QObject *parent) : ConfiguratorBase(settings, parent)
|
||||||
: ConfiguratorBase(settings, serverController, parent)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QString XrayConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
QString XrayConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
||||||
ErrorCode errorCode)
|
ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::xray_template, container),
|
ServerController serverController(m_settings);
|
||||||
m_serverController->genVarsForScript(credentials, container, containerConfig));
|
|
||||||
|
QString config = serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::xray_template, container),
|
||||||
|
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
QString xrayPublicKey =
|
QString xrayPublicKey =
|
||||||
m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::PublicKeyPath, errorCode);
|
serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::xray::PublicKeyPath, errorCode);
|
||||||
xrayPublicKey.replace("\n", "");
|
xrayPublicKey.replace("\n", "");
|
||||||
|
|
||||||
QString xrayUuid = m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::uuidPath, errorCode);
|
QString xrayUuid = serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::xray::uuidPath, errorCode);
|
||||||
xrayUuid.replace("\n", "");
|
xrayUuid.replace("\n", "");
|
||||||
|
|
||||||
QString xrayShortId =
|
QString xrayShortId = serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::xray::shortidPath, errorCode);
|
||||||
m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::shortidPath, errorCode);
|
|
||||||
xrayShortId.replace("\n", "");
|
xrayShortId.replace("\n", "");
|
||||||
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class XrayConfigurator : public ConfiguratorBase
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
XrayConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
|
XrayConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
QString createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
||||||
ErrorCode errorCode);
|
ErrorCode errorCode);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
|
|
||||||
|
#include "core/errorstrings.h"
|
||||||
#include "configurators/wireguard_configurator.h"
|
#include "configurators/wireguard_configurator.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -19,7 +20,6 @@ namespace
|
|||||||
constexpr char certificate[] = "certificate";
|
constexpr char certificate[] = "certificate";
|
||||||
constexpr char publicKey[] = "public_key";
|
constexpr char publicKey[] = "public_key";
|
||||||
constexpr char protocol[] = "protocol";
|
constexpr char protocol[] = "protocol";
|
||||||
constexpr char uuid[] = "installation_uuid";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,11 +64,11 @@ QJsonObject ApiController::fillApiPayload(const QString &protocol, const ApiCont
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ApiController::updateServerConfigFromApi(const QString &installationUuid, QJsonObject &serverConfig)
|
ErrorCode ApiController::updateServerConfigFromApi(QJsonObject &serverConfig)
|
||||||
{
|
{
|
||||||
QFutureWatcher<ErrorCode> watcher;
|
QFutureWatcher<ErrorCode> watcher;
|
||||||
|
|
||||||
QFuture<ErrorCode> future = QtConcurrent::run([this, &serverConfig, &installationUuid]() {
|
QFuture<ErrorCode> future = QtConcurrent::run([this, &serverConfig]() {
|
||||||
auto containerConfig = serverConfig.value(config_key::containers).toArray();
|
auto containerConfig = serverConfig.value(config_key::containers).toArray();
|
||||||
|
|
||||||
if (serverConfig.value(config_key::configVersion).toInt()) {
|
if (serverConfig.value(config_key::configVersion).toInt()) {
|
||||||
@@ -86,10 +86,7 @@ ErrorCode ApiController::updateServerConfigFromApi(const QString &installationUu
|
|||||||
|
|
||||||
auto apiPayloadData = generateApiPayloadData(protocol);
|
auto apiPayloadData = generateApiPayloadData(protocol);
|
||||||
|
|
||||||
auto apiPayload = fillApiPayload(protocol, apiPayloadData);
|
QByteArray requestBody = QJsonDocument(fillApiPayload(protocol, apiPayloadData)).toJson();
|
||||||
apiPayload[configKey::uuid] = installationUuid;
|
|
||||||
|
|
||||||
QByteArray requestBody = QJsonDocument(apiPayload).toJson();
|
|
||||||
|
|
||||||
QScopedPointer<QNetworkReply> reply;
|
QScopedPointer<QNetworkReply> reply;
|
||||||
reply.reset(manager.post(request, requestBody));
|
reply.reset(manager.post(request, requestBody));
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public:
|
|||||||
explicit ApiController(QObject *parent = nullptr);
|
explicit ApiController(QObject *parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
ErrorCode updateServerConfigFromApi(const QString &installationUuid, QJsonObject &serverConfig);
|
ErrorCode updateServerConfigFromApi(QJsonObject &serverConfig);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ApiPayloadData {
|
struct ApiPayloadData {
|
||||||
|
|||||||
@@ -23,10 +23,10 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "core/networkUtilities.h"
|
#include "logger.h"
|
||||||
#include "core/scripts_registry.h"
|
#include "core/scripts_registry.h"
|
||||||
#include "core/server_defs.h"
|
#include "core/server_defs.h"
|
||||||
#include "logger.h"
|
#include "core/networkUtilities.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "vpnConfigurationController.h"
|
#include "vpnConfigurationController.h"
|
||||||
@@ -95,7 +95,8 @@ ErrorCode ServerController::runScript(const ServerCredentials &credentials, QStr
|
|||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::runContainerScript(const ServerCredentials &credentials, DockerContainer container, QString script,
|
ErrorCode
|
||||||
|
ServerController::runContainerScript(const ServerCredentials &credentials, DockerContainer container, QString script,
|
||||||
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdOut,
|
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdOut,
|
||||||
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdErr)
|
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdErr)
|
||||||
{
|
{
|
||||||
@@ -115,8 +116,9 @@ ErrorCode ServerController::runContainerScript(const ServerCredentials &credenti
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container, const ServerCredentials &credentials, const QString &file,
|
ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container, const ServerCredentials &credentials,
|
||||||
const QString &path, libssh::ScpOverwriteMode overwriteMode)
|
const QString &file, const QString &path,
|
||||||
|
libssh::ScpOverwriteMode overwriteMode)
|
||||||
{
|
{
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
QString tmpFileName = QString("/tmp/%1.tmp").arg(Utils::getRandomString(16));
|
QString tmpFileName = QString("/tmp/%1.tmp").arg(Utils::getRandomString(16));
|
||||||
@@ -154,8 +156,10 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
|||||||
if (e)
|
if (e)
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
e = runScript(credentials,
|
e = runScript(
|
||||||
replaceVars(QString("sudo docker exec -i $CONTAINER_NAME sh -c \"cat %1 >> %2\"").arg(tmpFileName).arg(path),
|
credentials,
|
||||||
|
replaceVars(
|
||||||
|
QString("sudo docker exec -i $CONTAINER_NAME sh -c \"cat %1 >> %2\"").arg(tmpFileName).arg(path),
|
||||||
genVarsForScript(credentials, container)),
|
genVarsForScript(credentials, container)),
|
||||||
cbReadStd, cbReadStd);
|
cbReadStd, cbReadStd);
|
||||||
|
|
||||||
@@ -168,17 +172,20 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
|||||||
return ErrorCode::ServerContainerMissingError;
|
return ErrorCode::ServerContainerMissingError;
|
||||||
}
|
}
|
||||||
|
|
||||||
runScript(credentials, replaceVars(QString("sudo shred -u %1").arg(tmpFileName), genVarsForScript(credentials, container)));
|
runScript(credentials,
|
||||||
|
replaceVars(QString("sudo shred -u %1").arg(tmpFileName), genVarsForScript(credentials, container)));
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray ServerController::getTextFileFromContainer(DockerContainer container, const ServerCredentials &credentials, const QString &path,
|
QByteArray ServerController::getTextFileFromContainer(DockerContainer container, const ServerCredentials &credentials,
|
||||||
ErrorCode errorCode)
|
const QString &path, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
|
|
||||||
errorCode = ErrorCode::NoError;
|
errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
QString script = QString("sudo docker exec -i %1 sh -c \"xxd -p \'%2\'\"").arg(ContainerProps::containerToString(container)).arg(path);
|
QString script = QString("sudo docker exec -i %1 sh -c \"xxd -p \'%2\'\"")
|
||||||
|
.arg(ContainerProps::containerToString(container))
|
||||||
|
.arg(path);
|
||||||
|
|
||||||
QString stdOut;
|
QString stdOut;
|
||||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
||||||
@@ -190,8 +197,8 @@ QByteArray ServerController::getTextFileFromContainer(DockerContainer container,
|
|||||||
return QByteArray::fromHex(stdOut.toUtf8());
|
return QByteArray::fromHex(stdOut.toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath,
|
ErrorCode ServerController::uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data,
|
||||||
libssh::ScpOverwriteMode overwriteMode)
|
const QString &remotePath, libssh::ScpOverwriteMode overwriteMode)
|
||||||
{
|
{
|
||||||
auto error = m_sshClient.connectToHost(credentials);
|
auto error = m_sshClient.connectToHost(credentials);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
@@ -237,10 +244,12 @@ ErrorCode ServerController::removeAllContainers(const ServerCredentials &credent
|
|||||||
ErrorCode ServerController::removeContainer(const ServerCredentials &credentials, DockerContainer container)
|
ErrorCode ServerController::removeContainer(const ServerCredentials &credentials, DockerContainer container)
|
||||||
{
|
{
|
||||||
return runScript(credentials,
|
return runScript(credentials,
|
||||||
replaceVars(amnezia::scriptData(SharedScriptType::remove_container), genVarsForScript(credentials, container)));
|
replaceVars(amnezia::scriptData(SharedScriptType::remove_container),
|
||||||
|
genVarsForScript(credentials, container)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::setupContainer(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config, bool isUpdate)
|
ErrorCode ServerController::setupContainer(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
QJsonObject &config, bool isUpdate)
|
||||||
{
|
{
|
||||||
qDebug().noquote() << "ServerController::setupContainer" << ContainerProps::containerToString(container);
|
qDebug().noquote() << "ServerController::setupContainer" << ContainerProps::containerToString(container);
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
@@ -300,11 +309,12 @@ ErrorCode ServerController::setupContainer(const ServerCredentials &credentials,
|
|||||||
return startupContainerWorker(credentials, container, config);
|
return startupContainerWorker(credentials, container, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::updateContainer(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &oldConfig,
|
ErrorCode ServerController::updateContainer(const ServerCredentials &credentials, DockerContainer container,
|
||||||
QJsonObject &newConfig)
|
const QJsonObject &oldConfig, QJsonObject &newConfig)
|
||||||
{
|
{
|
||||||
bool reinstallRequired = isReinstallContainerRequired(container, oldConfig, newConfig);
|
bool reinstallRequired = isReinstallContainerRequired(container, oldConfig, newConfig);
|
||||||
qDebug() << "ServerController::updateContainer for container" << container << "reinstall required is" << reinstallRequired;
|
qDebug() << "ServerController::updateContainer for container" << container << "reinstall required is"
|
||||||
|
<< reinstallRequired;
|
||||||
|
|
||||||
if (reinstallRequired) {
|
if (reinstallRequired) {
|
||||||
return setupContainer(credentials, container, newConfig, true);
|
return setupContainer(credentials, container, newConfig, true);
|
||||||
@@ -317,7 +327,8 @@ ErrorCode ServerController::updateContainer(const ServerCredentials &credentials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerController::isReinstallContainerRequired(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig)
|
bool ServerController::isReinstallContainerRequired(DockerContainer container, const QJsonObject &oldConfig,
|
||||||
|
const QJsonObject &newConfig)
|
||||||
{
|
{
|
||||||
Proto mainProto = ContainerProps::defaultProtocol(container);
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
|
|
||||||
@@ -370,7 +381,7 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container == DockerContainer::WireGuard) {
|
if (container == DockerContainer::WireGuard){
|
||||||
if (oldProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)
|
if (oldProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)
|
||||||
!= newProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort))
|
!= newProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort))
|
||||||
return true;
|
return true;
|
||||||
@@ -396,7 +407,8 @@ ErrorCode ServerController::installDockerWorker(const ServerCredentials &credent
|
|||||||
};
|
};
|
||||||
|
|
||||||
ErrorCode error =
|
ErrorCode error =
|
||||||
runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::install_docker), genVarsForScript(credentials)),
|
runScript(credentials,
|
||||||
|
replaceVars(amnezia::scriptData(SharedScriptType::install_docker), genVarsForScript(credentials)),
|
||||||
cbReadStdOut, cbReadStdErr);
|
cbReadStdOut, cbReadStdErr);
|
||||||
|
|
||||||
qDebug().noquote() << "ServerController::installDockerWorker" << stdOut;
|
qDebug().noquote() << "ServerController::installDockerWorker" << stdOut;
|
||||||
@@ -408,13 +420,17 @@ ErrorCode ServerController::installDockerWorker(const ServerCredentials &credent
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
ErrorCode ServerController::prepareHostWorker(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
const QJsonObject &config)
|
||||||
{
|
{
|
||||||
// create folder on host
|
// create folder on host
|
||||||
return runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::prepare_host), genVarsForScript(credentials, container)));
|
return runScript(
|
||||||
|
credentials,
|
||||||
|
replaceVars(amnezia::scriptData(SharedScriptType::prepare_host), genVarsForScript(credentials, container)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::buildContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
ErrorCode ServerController::buildContainerWorker(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
const QJsonObject &config)
|
||||||
{
|
{
|
||||||
ErrorCode e = uploadFileToHost(credentials, amnezia::scriptData(ProtocolScriptType::dockerfile, container).toUtf8(),
|
ErrorCode e = uploadFileToHost(credentials, amnezia::scriptData(ProtocolScriptType::dockerfile, container).toUtf8(),
|
||||||
amnezia::server::getDockerfileFolder(container) + "/Dockerfile");
|
amnezia::server::getDockerfileFolder(container) + "/Dockerfile");
|
||||||
@@ -429,7 +445,8 @@ ErrorCode ServerController::buildContainerWorker(const ServerCredentials &creden
|
|||||||
};
|
};
|
||||||
|
|
||||||
e = runScript(credentials,
|
e = runScript(credentials,
|
||||||
replaceVars(amnezia::scriptData(SharedScriptType::build_container), genVarsForScript(credentials, container, config)),
|
replaceVars(amnezia::scriptData(SharedScriptType::build_container),
|
||||||
|
genVarsForScript(credentials, container, config)),
|
||||||
cbReadStdOut);
|
cbReadStdOut);
|
||||||
if (e)
|
if (e)
|
||||||
return e;
|
return e;
|
||||||
@@ -437,7 +454,8 @@ ErrorCode ServerController::buildContainerWorker(const ServerCredentials &creden
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::runContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config)
|
ErrorCode ServerController::runContainerWorker(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
QJsonObject &config)
|
||||||
{
|
{
|
||||||
QString stdOut;
|
QString stdOut;
|
||||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
||||||
@@ -460,7 +478,8 @@ ErrorCode ServerController::runContainerWorker(const ServerCredentials &credenti
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config)
|
ErrorCode ServerController::configureContainerWorker(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
QJsonObject &config)
|
||||||
{
|
{
|
||||||
QString stdOut;
|
QString stdOut;
|
||||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
||||||
@@ -482,7 +501,8 @@ ErrorCode ServerController::configureContainerWorker(const ServerCredentials &cr
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
ErrorCode ServerController::startupContainerWorker(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
const QJsonObject &config)
|
||||||
{
|
{
|
||||||
QString script = amnezia::scriptData(ProtocolScriptType::container_startup, container);
|
QString script = amnezia::scriptData(ProtocolScriptType::container_startup, container);
|
||||||
|
|
||||||
@@ -490,7 +510,8 @@ ErrorCode ServerController::startupContainerWorker(const ServerCredentials &cred
|
|||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode e = uploadTextFileToContainer(container, credentials, replaceVars(script, genVarsForScript(credentials, container, config)),
|
ErrorCode e = uploadTextFileToContainer(container, credentials,
|
||||||
|
replaceVars(script, genVarsForScript(credentials, container, config)),
|
||||||
"/opt/amnezia/start.sh");
|
"/opt/amnezia/start.sh");
|
||||||
if (e)
|
if (e)
|
||||||
return e;
|
return e;
|
||||||
@@ -501,8 +522,8 @@ ErrorCode ServerController::startupContainerWorker(const ServerCredentials &cred
|
|||||||
genVarsForScript(credentials, container, config)));
|
genVarsForScript(credentials, container, config)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerController::Vars ServerController::genVarsForScript(const ServerCredentials &credentials, DockerContainer container,
|
ServerController::Vars ServerController::genVarsForScript(const ServerCredentials &credentials,
|
||||||
const QJsonObject &config)
|
DockerContainer container, const QJsonObject &config)
|
||||||
{
|
{
|
||||||
const QJsonObject &openvpnConfig = config.value(ProtocolProps::protoToString(Proto::OpenVpn)).toObject();
|
const QJsonObject &openvpnConfig = config.value(ProtocolProps::protoToString(Proto::OpenVpn)).toObject();
|
||||||
const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Proto::Cloak)).toObject();
|
const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Proto::Cloak)).toObject();
|
||||||
@@ -517,19 +538,24 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
|||||||
vars.append({ { "$REMOTE_HOST", credentials.hostName } });
|
vars.append({ { "$REMOTE_HOST", credentials.hostName } });
|
||||||
|
|
||||||
// OpenVPN vars
|
// OpenVPN vars
|
||||||
vars.append({ { "$OPENVPN_SUBNET_IP",
|
vars.append(
|
||||||
|
{ { "$OPENVPN_SUBNET_IP",
|
||||||
openvpnConfig.value(config_key::subnet_address).toString(protocols::openvpn::defaultSubnetAddress) } });
|
openvpnConfig.value(config_key::subnet_address).toString(protocols::openvpn::defaultSubnetAddress) } });
|
||||||
vars.append({ { "$OPENVPN_SUBNET_CIDR", openvpnConfig.value(config_key::subnet_cidr).toString(protocols::openvpn::defaultSubnetCidr) } });
|
vars.append({ { "$OPENVPN_SUBNET_CIDR",
|
||||||
vars.append({ { "$OPENVPN_SUBNET_MASK", openvpnConfig.value(config_key::subnet_mask).toString(protocols::openvpn::defaultSubnetMask) } });
|
openvpnConfig.value(config_key::subnet_cidr).toString(protocols::openvpn::defaultSubnetCidr) } });
|
||||||
|
vars.append({ { "$OPENVPN_SUBNET_MASK",
|
||||||
|
openvpnConfig.value(config_key::subnet_mask).toString(protocols::openvpn::defaultSubnetMask) } });
|
||||||
|
|
||||||
vars.append({ { "$OPENVPN_PORT", openvpnConfig.value(config_key::port).toString(protocols::openvpn::defaultPort) } });
|
vars.append({ { "$OPENVPN_PORT", openvpnConfig.value(config_key::port).toString(protocols::openvpn::defaultPort) } });
|
||||||
vars.append({ { "$OPENVPN_TRANSPORT_PROTO",
|
vars.append(
|
||||||
|
{ { "$OPENVPN_TRANSPORT_PROTO",
|
||||||
openvpnConfig.value(config_key::transport_proto).toString(protocols::openvpn::defaultTransportProto) } });
|
openvpnConfig.value(config_key::transport_proto).toString(protocols::openvpn::defaultTransportProto) } });
|
||||||
|
|
||||||
bool isNcpDisabled = openvpnConfig.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable);
|
bool isNcpDisabled = openvpnConfig.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable);
|
||||||
vars.append({ { "$OPENVPN_NCP_DISABLE", isNcpDisabled ? protocols::openvpn::ncpDisableString : "" } });
|
vars.append({ { "$OPENVPN_NCP_DISABLE", isNcpDisabled ? protocols::openvpn::ncpDisableString : "" } });
|
||||||
|
|
||||||
vars.append({ { "$OPENVPN_CIPHER", openvpnConfig.value(config_key::cipher).toString(protocols::openvpn::defaultCipher) } });
|
vars.append({ { "$OPENVPN_CIPHER",
|
||||||
|
openvpnConfig.value(config_key::cipher).toString(protocols::openvpn::defaultCipher) } });
|
||||||
vars.append({ { "$OPENVPN_HASH", openvpnConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash) } });
|
vars.append({ { "$OPENVPN_HASH", openvpnConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash) } });
|
||||||
|
|
||||||
bool isTlsAuth = openvpnConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth);
|
bool isTlsAuth = openvpnConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth);
|
||||||
@@ -540,35 +566,43 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
|||||||
}
|
}
|
||||||
|
|
||||||
vars.append({ { "$OPENVPN_ADDITIONAL_CLIENT_CONFIG",
|
vars.append({ { "$OPENVPN_ADDITIONAL_CLIENT_CONFIG",
|
||||||
openvpnConfig.value(config_key::additional_client_config).toString(protocols::openvpn::defaultAdditionalClientConfig) } });
|
openvpnConfig.value(config_key::additional_client_config)
|
||||||
|
.toString(protocols::openvpn::defaultAdditionalClientConfig) } });
|
||||||
vars.append({ { "$OPENVPN_ADDITIONAL_SERVER_CONFIG",
|
vars.append({ { "$OPENVPN_ADDITIONAL_SERVER_CONFIG",
|
||||||
openvpnConfig.value(config_key::additional_server_config).toString(protocols::openvpn::defaultAdditionalServerConfig) } });
|
openvpnConfig.value(config_key::additional_server_config)
|
||||||
|
.toString(protocols::openvpn::defaultAdditionalServerConfig) } });
|
||||||
|
|
||||||
// ShadowSocks vars
|
// ShadowSocks vars
|
||||||
vars.append({ { "$SHADOWSOCKS_SERVER_PORT", ssConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort) } });
|
vars.append({ { "$SHADOWSOCKS_SERVER_PORT",
|
||||||
|
ssConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort) } });
|
||||||
vars.append({ { "$SHADOWSOCKS_LOCAL_PORT",
|
vars.append({ { "$SHADOWSOCKS_LOCAL_PORT",
|
||||||
ssConfig.value(config_key::local_port).toString(protocols::shadowsocks::defaultLocalProxyPort) } });
|
ssConfig.value(config_key::local_port).toString(protocols::shadowsocks::defaultLocalProxyPort) } });
|
||||||
vars.append({ { "$SHADOWSOCKS_CIPHER", ssConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher) } });
|
vars.append({ { "$SHADOWSOCKS_CIPHER",
|
||||||
|
ssConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher) } });
|
||||||
|
|
||||||
vars.append({ { "$CONTAINER_NAME", ContainerProps::containerToString(container) } });
|
vars.append({ { "$CONTAINER_NAME", ContainerProps::containerToString(container) } });
|
||||||
vars.append({ { "$DOCKERFILE_FOLDER", "/opt/amnezia/" + ContainerProps::containerToString(container) } });
|
vars.append({ { "$DOCKERFILE_FOLDER", "/opt/amnezia/" + ContainerProps::containerToString(container) } });
|
||||||
|
|
||||||
// Cloak vars
|
// Cloak vars
|
||||||
vars.append({ { "$CLOAK_SERVER_PORT", cloakConfig.value(config_key::port).toString(protocols::cloak::defaultPort) } });
|
vars.append({ { "$CLOAK_SERVER_PORT", cloakConfig.value(config_key::port).toString(protocols::cloak::defaultPort) } });
|
||||||
vars.append({ { "$FAKE_WEB_SITE_ADDRESS", cloakConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite) } });
|
vars.append({ { "$FAKE_WEB_SITE_ADDRESS",
|
||||||
|
cloakConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite) } });
|
||||||
|
|
||||||
// Xray vars
|
// Xray vars
|
||||||
vars.append({ { "$XRAY_SITE_NAME", xrayConfig.value(config_key::site).toString(protocols::xray::defaultSite) } });
|
vars.append({ { "$XRAY_SITE_NAME",
|
||||||
|
xrayConfig.value(config_key::site).toString(protocols::xray::defaultSite) } });
|
||||||
|
|
||||||
// Wireguard vars
|
// Wireguard vars
|
||||||
vars.append({ { "$WIREGUARD_SUBNET_IP",
|
vars.append(
|
||||||
|
{ { "$WIREGUARD_SUBNET_IP",
|
||||||
wireguarConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) } });
|
wireguarConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) } });
|
||||||
vars.append({ { "$WIREGUARD_SUBNET_CIDR",
|
vars.append({ { "$WIREGUARD_SUBNET_CIDR",
|
||||||
wireguarConfig.value(config_key::subnet_cidr).toString(protocols::wireguard::defaultSubnetCidr) } });
|
wireguarConfig.value(config_key::subnet_cidr).toString(protocols::wireguard::defaultSubnetCidr) } });
|
||||||
vars.append({ { "$WIREGUARD_SUBNET_MASK",
|
vars.append({ { "$WIREGUARD_SUBNET_MASK",
|
||||||
wireguarConfig.value(config_key::subnet_mask).toString(protocols::wireguard::defaultSubnetMask) } });
|
wireguarConfig.value(config_key::subnet_mask).toString(protocols::wireguard::defaultSubnetMask) } });
|
||||||
|
|
||||||
vars.append({ { "$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) } });
|
vars.append({ { "$WIREGUARD_SERVER_PORT",
|
||||||
|
wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) } });
|
||||||
|
|
||||||
// IPsec vars
|
// IPsec vars
|
||||||
vars.append({ { "$IPSEC_VPN_L2TP_NET", "192.168.42.0/24" } });
|
vars.append({ { "$IPSEC_VPN_L2TP_NET", "192.168.42.0/24" } });
|
||||||
@@ -591,22 +625,30 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
|||||||
vars.append({ { "$SECONDARY_SERVER_DNS", m_settings->secondaryDns() } });
|
vars.append({ { "$SECONDARY_SERVER_DNS", m_settings->secondaryDns() } });
|
||||||
|
|
||||||
// Sftp vars
|
// Sftp vars
|
||||||
vars.append({ { "$SFTP_PORT", sftpConfig.value(config_key::port).toString(QString::number(ProtocolProps::defaultPort(Proto::Sftp))) } });
|
vars.append(
|
||||||
|
{ { "$SFTP_PORT",
|
||||||
|
sftpConfig.value(config_key::port).toString(QString::number(ProtocolProps::defaultPort(Proto::Sftp))) } });
|
||||||
vars.append({ { "$SFTP_USER", sftpConfig.value(config_key::userName).toString() } });
|
vars.append({ { "$SFTP_USER", sftpConfig.value(config_key::userName).toString() } });
|
||||||
vars.append({ { "$SFTP_PASSWORD", sftpConfig.value(config_key::password).toString() } });
|
vars.append({ { "$SFTP_PASSWORD", sftpConfig.value(config_key::password).toString() } });
|
||||||
|
|
||||||
// Amnezia wireguard vars
|
// Amnezia wireguard vars
|
||||||
vars.append({ { "$AWG_SERVER_PORT", amneziaWireguarConfig.value(config_key::port).toString(protocols::awg::defaultPort) } });
|
vars.append({ { "$AWG_SERVER_PORT",
|
||||||
|
amneziaWireguarConfig.value(config_key::port).toString(protocols::awg::defaultPort) } });
|
||||||
|
|
||||||
vars.append({ { "$JUNK_PACKET_COUNT", amneziaWireguarConfig.value(config_key::junkPacketCount).toString() } });
|
vars.append({ { "$JUNK_PACKET_COUNT", amneziaWireguarConfig.value(config_key::junkPacketCount).toString() } });
|
||||||
vars.append({ { "$JUNK_PACKET_MIN_SIZE", amneziaWireguarConfig.value(config_key::junkPacketMinSize).toString() } });
|
vars.append({ { "$JUNK_PACKET_MIN_SIZE", amneziaWireguarConfig.value(config_key::junkPacketMinSize).toString() } });
|
||||||
vars.append({ { "$JUNK_PACKET_MAX_SIZE", amneziaWireguarConfig.value(config_key::junkPacketMaxSize).toString() } });
|
vars.append({ { "$JUNK_PACKET_MAX_SIZE", amneziaWireguarConfig.value(config_key::junkPacketMaxSize).toString() } });
|
||||||
vars.append({ { "$INIT_PACKET_JUNK_SIZE", amneziaWireguarConfig.value(config_key::initPacketJunkSize).toString() } });
|
vars.append({ { "$INIT_PACKET_JUNK_SIZE", amneziaWireguarConfig.value(config_key::initPacketJunkSize).toString() } });
|
||||||
vars.append({ { "$RESPONSE_PACKET_JUNK_SIZE", amneziaWireguarConfig.value(config_key::responsePacketJunkSize).toString() } });
|
vars.append({ { "$RESPONSE_PACKET_JUNK_SIZE",
|
||||||
vars.append({ { "$INIT_PACKET_MAGIC_HEADER", amneziaWireguarConfig.value(config_key::initPacketMagicHeader).toString() } });
|
amneziaWireguarConfig.value(config_key::responsePacketJunkSize).toString() } });
|
||||||
vars.append({ { "$RESPONSE_PACKET_MAGIC_HEADER", amneziaWireguarConfig.value(config_key::responsePacketMagicHeader).toString() } });
|
vars.append({ { "$INIT_PACKET_MAGIC_HEADER",
|
||||||
vars.append({ { "$UNDERLOAD_PACKET_MAGIC_HEADER", amneziaWireguarConfig.value(config_key::underloadPacketMagicHeader).toString() } });
|
amneziaWireguarConfig.value(config_key::initPacketMagicHeader).toString() } });
|
||||||
vars.append({ { "$TRANSPORT_PACKET_MAGIC_HEADER", amneziaWireguarConfig.value(config_key::transportPacketMagicHeader).toString() } });
|
vars.append({ { "$RESPONSE_PACKET_MAGIC_HEADER",
|
||||||
|
amneziaWireguarConfig.value(config_key::responsePacketMagicHeader).toString() } });
|
||||||
|
vars.append({ { "$UNDERLOAD_PACKET_MAGIC_HEADER",
|
||||||
|
amneziaWireguarConfig.value(config_key::underloadPacketMagicHeader).toString() } });
|
||||||
|
vars.append({ { "$TRANSPORT_PACKET_MAGIC_HEADER",
|
||||||
|
amneziaWireguarConfig.value(config_key::transportPacketMagicHeader).toString() } });
|
||||||
|
|
||||||
QString serverIp = NetworkUtilities::getIPAddress(credentials.hostName);
|
QString serverIp = NetworkUtilities::getIPAddress(credentials.hostName);
|
||||||
if (!serverIp.isEmpty()) {
|
if (!serverIp.isEmpty()) {
|
||||||
@@ -642,7 +684,9 @@ void ServerController::cancelInstallation()
|
|||||||
|
|
||||||
ErrorCode ServerController::setupServerFirewall(const ServerCredentials &credentials)
|
ErrorCode ServerController::setupServerFirewall(const ServerCredentials &credentials)
|
||||||
{
|
{
|
||||||
return runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::setup_host_firewall), genVarsForScript(credentials)));
|
return runScript(
|
||||||
|
credentials,
|
||||||
|
replaceVars(amnezia::scriptData(SharedScriptType::setup_host_firewall), genVarsForScript(credentials)));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ServerController::replaceVars(const QString &script, const Vars &vars)
|
QString ServerController::replaceVars(const QString &script, const Vars &vars)
|
||||||
@@ -654,7 +698,8 @@ QString ServerController::replaceVars(const QString &script, const Vars &vars)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
const QJsonObject &config)
|
||||||
{
|
{
|
||||||
if (container == DockerContainer::Dns) {
|
if (container == DockerContainer::Dns) {
|
||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
@@ -677,12 +722,15 @@ ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credential
|
|||||||
QStringList fixedPorts = ContainerProps::fixedPortsForContainer(container);
|
QStringList fixedPorts = ContainerProps::fixedPortsForContainer(container);
|
||||||
|
|
||||||
QString defaultPort("%1");
|
QString defaultPort("%1");
|
||||||
QString port = containerConfig.value(config_key::port).toString(defaultPort.arg(ProtocolProps::defaultPort(protocol)));
|
QString port =
|
||||||
QString defaultTransportProto = ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(protocol), protocol);
|
containerConfig.value(config_key::port).toString(defaultPort.arg(ProtocolProps::defaultPort(protocol)));
|
||||||
|
QString defaultTransportProto =
|
||||||
|
ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(protocol), protocol);
|
||||||
QString transportProto = containerConfig.value(config_key::transport_proto).toString(defaultTransportProto);
|
QString transportProto = containerConfig.value(config_key::transport_proto).toString(defaultTransportProto);
|
||||||
|
|
||||||
// TODO reimplement with netstat
|
// TODO reimplement with netstat
|
||||||
QString script = QString("which lsof &>/dev/null || true && sudo lsof -i -P -n 2>/dev/null | grep -E ':%1 ").arg(port);
|
QString script =
|
||||||
|
QString("which lsof &>/dev/null || true && sudo lsof -i -P -n 2>/dev/null | grep -E ':%1 ").arg(port);
|
||||||
for (auto &port : fixedPorts) {
|
for (auto &port : fixedPorts) {
|
||||||
script = script.append("|:%1").arg(port);
|
script = script.append("|:%1").arg(port);
|
||||||
}
|
}
|
||||||
@@ -692,7 +740,8 @@ ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credential
|
|||||||
script = script.append(" | grep LISTEN");
|
script = script.append(" | grep LISTEN");
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode errorCode = runScript(credentials, replaceVars(script, genVarsForScript(credentials, container)), cbReadStdOut, cbReadStdErr);
|
ErrorCode errorCode = runScript(credentials, replaceVars(script, genVarsForScript(credentials, container)),
|
||||||
|
cbReadStdOut, cbReadStdErr);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
@@ -720,7 +769,8 @@ ErrorCode ServerController::isUserInSudo(const ServerCredentials &credentials, D
|
|||||||
};
|
};
|
||||||
|
|
||||||
const QString scriptData = amnezia::scriptData(SharedScriptType::check_user_in_sudo);
|
const QString scriptData = amnezia::scriptData(SharedScriptType::check_user_in_sudo);
|
||||||
ErrorCode error = runScript(credentials, replaceVars(scriptData, genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr);
|
ErrorCode error =
|
||||||
|
runScript(credentials, replaceVars(scriptData, genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr);
|
||||||
|
|
||||||
if (!stdOut.contains("sudo"))
|
if (!stdOut.contains("sudo"))
|
||||||
return ErrorCode::ServerUserNotInSudo;
|
return ErrorCode::ServerUserNotInSudo;
|
||||||
@@ -750,7 +800,9 @@ ErrorCode ServerController::isServerDpkgBusy(const ServerCredentials &credential
|
|||||||
return ErrorCode::ServerCancelInstallation;
|
return ErrorCode::ServerCancelInstallation;
|
||||||
}
|
}
|
||||||
stdOut.clear();
|
stdOut.clear();
|
||||||
runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::check_server_is_busy), genVarsForScript(credentials)),
|
runScript(credentials,
|
||||||
|
replaceVars(amnezia::scriptData(SharedScriptType::check_server_is_busy),
|
||||||
|
genVarsForScript(credentials)),
|
||||||
cbReadStdOut, cbReadStdErr);
|
cbReadStdOut, cbReadStdErr);
|
||||||
|
|
||||||
if (stdOut.contains("Packet manager not found"))
|
if (stdOut.contains("Packet manager not found"))
|
||||||
|
|||||||
@@ -25,18 +25,19 @@ public:
|
|||||||
ErrorCode rebootServer(const ServerCredentials &credentials);
|
ErrorCode rebootServer(const ServerCredentials &credentials);
|
||||||
ErrorCode removeAllContainers(const ServerCredentials &credentials);
|
ErrorCode removeAllContainers(const ServerCredentials &credentials);
|
||||||
ErrorCode removeContainer(const ServerCredentials &credentials, DockerContainer container);
|
ErrorCode removeContainer(const ServerCredentials &credentials, DockerContainer container);
|
||||||
ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config, bool isUpdate = false);
|
ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config,
|
||||||
ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &oldConfig,
|
bool isUpdate = false);
|
||||||
QJsonObject &newConfig);
|
ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
const QJsonObject &oldConfig, QJsonObject &newConfig);
|
||||||
|
|
||||||
ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container,
|
ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &config = QJsonObject());
|
const QJsonObject &config = QJsonObject());
|
||||||
|
|
||||||
ErrorCode uploadTextFileToContainer(DockerContainer container, const ServerCredentials &credentials, const QString &file,
|
ErrorCode uploadTextFileToContainer(
|
||||||
const QString &path,
|
DockerContainer container, const ServerCredentials &credentials, const QString &file, const QString &path,
|
||||||
libssh::ScpOverwriteMode overwriteMode = libssh::ScpOverwriteMode::ScpOverwriteExisting);
|
libssh::ScpOverwriteMode overwriteMode = libssh::ScpOverwriteMode::ScpOverwriteExisting);
|
||||||
QByteArray getTextFileFromContainer(DockerContainer container, const ServerCredentials &credentials, const QString &path,
|
QByteArray getTextFileFromContainer(DockerContainer container, const ServerCredentials &credentials,
|
||||||
ErrorCode errorCode);
|
const QString &path, ErrorCode errorCode);
|
||||||
|
|
||||||
QString replaceVars(const QString &script, const Vars &vars);
|
QString replaceVars(const QString &script, const Vars &vars);
|
||||||
Vars genVarsForScript(const ServerCredentials &credentials, DockerContainer container = DockerContainer::None,
|
Vars genVarsForScript(const ServerCredentials &credentials, DockerContainer container = DockerContainer::None,
|
||||||
@@ -46,7 +47,8 @@ public:
|
|||||||
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdOut = nullptr,
|
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdOut = nullptr,
|
||||||
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdErr = nullptr);
|
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdErr = nullptr);
|
||||||
|
|
||||||
ErrorCode runContainerScript(const ServerCredentials &credentials, DockerContainer container, QString script,
|
ErrorCode
|
||||||
|
runContainerScript(const ServerCredentials &credentials, DockerContainer container, QString script,
|
||||||
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdOut = nullptr,
|
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdOut = nullptr,
|
||||||
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdErr = nullptr);
|
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdErr = nullptr);
|
||||||
|
|
||||||
@@ -59,14 +61,18 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
|
ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
|
||||||
ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
const QJsonObject &config = QJsonObject());
|
||||||
ErrorCode buildContainerWorker(const ServerCredentials &credentials, DockerContainer container,
|
ErrorCode buildContainerWorker(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &config = QJsonObject());
|
const QJsonObject &config = QJsonObject());
|
||||||
ErrorCode runContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config);
|
ErrorCode runContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config);
|
||||||
ErrorCode configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config);
|
ErrorCode configureContainerWorker(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
QJsonObject &config);
|
||||||
|
|
||||||
ErrorCode isServerPortBusy(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config);
|
ErrorCode isServerPortBusy(const ServerCredentials &credentials, DockerContainer container,
|
||||||
bool isReinstallContainerRequired(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig);
|
const QJsonObject &config);
|
||||||
|
bool isReinstallContainerRequired(DockerContainer container, const QJsonObject &oldConfig,
|
||||||
|
const QJsonObject &newConfig);
|
||||||
ErrorCode isUserInSudo(const ServerCredentials &credentials, DockerContainer container);
|
ErrorCode isUserInSudo(const ServerCredentials &credentials, DockerContainer container);
|
||||||
ErrorCode isServerDpkgBusy(const ServerCredentials &credentials, DockerContainer container);
|
ErrorCode isServerDpkgBusy(const ServerCredentials &credentials, DockerContainer container);
|
||||||
|
|
||||||
|
|||||||
@@ -8,22 +8,21 @@
|
|||||||
#include "configurators/wireguard_configurator.h"
|
#include "configurators/wireguard_configurator.h"
|
||||||
#include "configurators/xray_configurator.h"
|
#include "configurators/xray_configurator.h"
|
||||||
|
|
||||||
VpnConfigurationsController::VpnConfigurationsController(const std::shared_ptr<Settings> &settings,
|
VpnConfigurationsController::VpnConfigurationsController(const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
QSharedPointer<ServerController> serverController, QObject *parent)
|
: QObject { parent }, m_settings(settings)
|
||||||
: QObject { parent }, m_settings(settings), m_serverController(serverController)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QScopedPointer<ConfiguratorBase> VpnConfigurationsController::createConfigurator(const Proto protocol)
|
QScopedPointer<ConfiguratorBase> VpnConfigurationsController::createConfigurator(const Proto protocol)
|
||||||
{
|
{
|
||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
case Proto::OpenVpn: return QScopedPointer<ConfiguratorBase>(new OpenVpnConfigurator(m_settings, m_serverController));
|
case Proto::OpenVpn: return QScopedPointer<ConfiguratorBase>(new OpenVpnConfigurator(m_settings));
|
||||||
case Proto::ShadowSocks: return QScopedPointer<ConfiguratorBase>(new ShadowSocksConfigurator(m_settings, m_serverController));
|
case Proto::ShadowSocks: return QScopedPointer<ConfiguratorBase>(new ShadowSocksConfigurator(m_settings));
|
||||||
case Proto::Cloak: return QScopedPointer<ConfiguratorBase>(new CloakConfigurator(m_settings, m_serverController));
|
case Proto::Cloak: return QScopedPointer<ConfiguratorBase>(new CloakConfigurator(m_settings));
|
||||||
case Proto::WireGuard: return QScopedPointer<ConfiguratorBase>(new WireguardConfigurator(m_settings, m_serverController, false));
|
case Proto::WireGuard: return QScopedPointer<ConfiguratorBase>(new WireguardConfigurator(m_settings, false));
|
||||||
case Proto::Awg: return QScopedPointer<ConfiguratorBase>(new AwgConfigurator(m_settings, m_serverController));
|
case Proto::Awg: return QScopedPointer<ConfiguratorBase>(new AwgConfigurator(m_settings));
|
||||||
case Proto::Ikev2: return QScopedPointer<ConfiguratorBase>(new Ikev2Configurator(m_settings, m_serverController));
|
case Proto::Ikev2: return QScopedPointer<ConfiguratorBase>(new Ikev2Configurator(m_settings));
|
||||||
case Proto::Xray: return QScopedPointer<ConfiguratorBase>(new XrayConfigurator(m_settings, m_serverController));
|
case Proto::Xray: return QScopedPointer<ConfiguratorBase>(new XrayConfigurator(m_settings));
|
||||||
default: return QScopedPointer<ConfiguratorBase>();
|
default: return QScopedPointer<ConfiguratorBase>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class VpnConfigurationsController : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit VpnConfigurationsController(const std::shared_ptr<Settings> &settings, QSharedPointer<ServerController> serverController, QObject *parent = nullptr);
|
explicit VpnConfigurationsController(const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
ErrorCode createProtocolConfigForContainer(const ServerCredentials &credentials, const DockerContainer container,
|
ErrorCode createProtocolConfigForContainer(const ServerCredentials &credentials, const DockerContainer container,
|
||||||
@@ -30,7 +30,6 @@ private:
|
|||||||
QScopedPointer<ConfiguratorBase> createConfigurator(const Proto protocol);
|
QScopedPointer<ConfiguratorBase> createConfigurator(const Proto protocol);
|
||||||
|
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
QSharedPointer<ServerController> m_serverController;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VPNCONFIGIRATIONSCONTROLLER_H
|
#endif // VPNCONFIGIRATIONSCONTROLLER_H
|
||||||
|
|||||||
@@ -23,13 +23,6 @@ namespace libssh {
|
|||||||
|
|
||||||
ErrorCode Client::connectToHost(const ServerCredentials &credentials)
|
ErrorCode Client::connectToHost(const ServerCredentials &credentials)
|
||||||
{
|
{
|
||||||
if (m_session != nullptr) {
|
|
||||||
if (!ssh_is_connected(m_session)) {
|
|
||||||
ssh_free(m_session);
|
|
||||||
m_session = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_session == nullptr) {
|
if (m_session == nullptr) {
|
||||||
m_session = ssh_new();
|
m_session = ssh_new();
|
||||||
|
|
||||||
|
|||||||
@@ -248,10 +248,9 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) {
|
|||||||
|
|
||||||
GETVALUE("privateKey", config.m_privateKey, String);
|
GETVALUE("privateKey", config.m_privateKey, String);
|
||||||
GETVALUE("serverPublicKey", config.m_serverPublicKey, String);
|
GETVALUE("serverPublicKey", config.m_serverPublicKey, String);
|
||||||
|
GETVALUE("serverPskKey", config.m_serverPskKey, String);
|
||||||
GETVALUE("serverPort", config.m_serverPort, Double);
|
GETVALUE("serverPort", config.m_serverPort, Double);
|
||||||
|
|
||||||
config.m_serverPskKey = obj.value("serverPskKey").toString();
|
|
||||||
|
|
||||||
if (!obj.contains("deviceMTU") || obj.value("deviceMTU").toString().toInt() == 0)
|
if (!obj.contains("deviceMTU") || obj.value("deviceMTU").toString().toInt() == 0)
|
||||||
{
|
{
|
||||||
config.m_deviceMTU = 1420;
|
config.m_deviceMTU = 1420;
|
||||||
@@ -374,31 +373,19 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!obj.value("Jc").isNull()) {
|
if (!obj.value("Jc").isNull() && !obj.value("Jmin").isNull()
|
||||||
|
&& !obj.value("Jmax").isNull() && !obj.value("S1").isNull()
|
||||||
|
&& !obj.value("S2").isNull() && !obj.value("H1").isNull()
|
||||||
|
&& !obj.value("H2").isNull() && !obj.value("H3").isNull()
|
||||||
|
&& !obj.value("H4").isNull()) {
|
||||||
config.m_junkPacketCount = obj.value("Jc").toString();
|
config.m_junkPacketCount = obj.value("Jc").toString();
|
||||||
}
|
|
||||||
if (!obj.value("Jmin").isNull()) {
|
|
||||||
config.m_junkPacketMinSize = obj.value("Jmin").toString();
|
config.m_junkPacketMinSize = obj.value("Jmin").toString();
|
||||||
}
|
|
||||||
if (!obj.value("Jmax").isNull()) {
|
|
||||||
config.m_junkPacketMaxSize = obj.value("Jmax").toString();
|
config.m_junkPacketMaxSize = obj.value("Jmax").toString();
|
||||||
}
|
|
||||||
if (!obj.value("S1").isNull()) {
|
|
||||||
config.m_initPacketJunkSize = obj.value("S1").toString();
|
config.m_initPacketJunkSize = obj.value("S1").toString();
|
||||||
}
|
|
||||||
if (!obj.value("S2").isNull()) {
|
|
||||||
config.m_responsePacketJunkSize = obj.value("S2").toString();
|
config.m_responsePacketJunkSize = obj.value("S2").toString();
|
||||||
}
|
|
||||||
if (!obj.value("H1").isNull()) {
|
|
||||||
config.m_initPacketMagicHeader = obj.value("H1").toString();
|
config.m_initPacketMagicHeader = obj.value("H1").toString();
|
||||||
}
|
|
||||||
if (!obj.value("H2").isNull()) {
|
|
||||||
config.m_responsePacketMagicHeader = obj.value("H2").toString();
|
config.m_responsePacketMagicHeader = obj.value("H2").toString();
|
||||||
}
|
|
||||||
if (!obj.value("H3").isNull()) {
|
|
||||||
config.m_underloadPacketMagicHeader = obj.value("H3").toString();
|
config.m_underloadPacketMagicHeader = obj.value("H3").toString();
|
||||||
}
|
|
||||||
if (!obj.value("H4").isNull()) {
|
|
||||||
config.m_transportPacketMagicHeader = obj.value("H4").toString();
|
config.m_transportPacketMagicHeader = obj.value("H4").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>NSPrivacyAccessedAPITypes</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>NSPrivacyAccessedAPIType</key>
|
|
||||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
|
||||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
||||||
<array>
|
|
||||||
<string>C617.1</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>NSPrivacyAccessedAPIType</key>
|
|
||||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
|
||||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
||||||
<array>
|
|
||||||
<string>1C8F.1</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>NSPrivacyAccessedAPIType</key>
|
|
||||||
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
|
|
||||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
||||||
<array>
|
|
||||||
<string>35F9.1</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
@@ -90,14 +90,6 @@ target_sources(networkextension PRIVATE
|
|||||||
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(networkextension PRIVATE
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
|
||||||
)
|
|
||||||
|
|
||||||
set_property(TARGET networkextension APPEND PROPERTY RESOURCE
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
|
||||||
)
|
|
||||||
|
|
||||||
## Build wireguard-go-version.h
|
## Build wireguard-go-version.h
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND go list -m golang.zx2c4.com/wireguard
|
COMMAND go list -m golang.zx2c4.com/wireguard
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>NSPrivacyAccessedAPITypes</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>NSPrivacyAccessedAPIType</key>
|
|
||||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
|
||||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
||||||
<array>
|
|
||||||
<string>1C8F.1</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>NSPrivacyAccessedAPIType</key>
|
|
||||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
|
||||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
||||||
<array>
|
|
||||||
<string>C617.1</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
+34
-54
@@ -2,65 +2,45 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>APPL</string>
|
|
||||||
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
|
||||||
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
|
||||||
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
|
||||||
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
|
||||||
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
|
||||||
|
|
||||||
<key>CFBundleDocumentTypes</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleTypeExtensions</key>
|
|
||||||
<array>
|
|
||||||
<string>conf</string>
|
|
||||||
<string>vpn</string>
|
|
||||||
<string>ovpn</string>
|
|
||||||
<string>backup</string>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleTypeRole</key>
|
|
||||||
<string>Viewer</string>
|
|
||||||
<key>CFBundleTypeName</key>
|
|
||||||
<string>AmneziaVPN configuration file</string>
|
|
||||||
<key>LSItemContentTypes</key>
|
|
||||||
<array>
|
|
||||||
<string>org.amnezia.AmneziaVPN.amnezia-config</string>
|
|
||||||
<string>org.amnezia.AmneziaVPN.wireguard-config</string>
|
|
||||||
<string>org.amnezia.AmneziaVPN.openvpn-config</string>
|
|
||||||
<string>org.amnezia.AmneziaVPN.backup-config</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
|
|
||||||
<key>LSMinimumSystemVersion</key>
|
|
||||||
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
|
|
||||||
|
|
||||||
<key>NSHumanReadableCopyright</key>
|
|
||||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
|
||||||
|
|
||||||
<key>CFBundleIconFile</key>
|
|
||||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
|
||||||
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>en</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
|
|
||||||
<key>CFBundleAllowMixedLocalizations</key>
|
<key>CFBundleAllowMixedLocalizations</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${EXECUTABLE_NAME}</string>
|
||||||
|
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||||
|
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>$(MARKETING_VERSION)</string>
|
||||||
|
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||||
|
|
||||||
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
|
<false/>
|
||||||
|
|
||||||
|
<key>LSApplicationCategoryType</key>
|
||||||
|
<string>public.app-category.utilities</string>
|
||||||
|
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||||
|
|
||||||
|
<key>LSMultipleInstancesProhibited</key>
|
||||||
|
<true/>
|
||||||
|
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string>NSApplication</string>
|
<string>NSApplication</string>
|
||||||
|
|
||||||
|
|||||||
@@ -232,24 +232,6 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
|
|||||||
json.insert(amnezia::config_key::responsePacketMagicHeader, wgConfig.value(amnezia::config_key::responsePacketMagicHeader));
|
json.insert(amnezia::config_key::responsePacketMagicHeader, wgConfig.value(amnezia::config_key::responsePacketMagicHeader));
|
||||||
json.insert(amnezia::config_key::underloadPacketMagicHeader, wgConfig.value(amnezia::config_key::underloadPacketMagicHeader));
|
json.insert(amnezia::config_key::underloadPacketMagicHeader, wgConfig.value(amnezia::config_key::underloadPacketMagicHeader));
|
||||||
json.insert(amnezia::config_key::transportPacketMagicHeader, wgConfig.value(amnezia::config_key::transportPacketMagicHeader));
|
json.insert(amnezia::config_key::transportPacketMagicHeader, wgConfig.value(amnezia::config_key::transportPacketMagicHeader));
|
||||||
} else if (!wgConfig.value(amnezia::config_key::junkPacketCount).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::junkPacketMinSize).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::junkPacketMaxSize).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::initPacketJunkSize).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::responsePacketJunkSize).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::initPacketMagicHeader).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::responsePacketMagicHeader).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::underloadPacketMagicHeader).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::transportPacketMagicHeader).isUndefined()) {
|
|
||||||
json.insert(amnezia::config_key::junkPacketCount, wgConfig.value(amnezia::config_key::junkPacketCount));
|
|
||||||
json.insert(amnezia::config_key::junkPacketMinSize, wgConfig.value(amnezia::config_key::junkPacketMinSize));
|
|
||||||
json.insert(amnezia::config_key::junkPacketMaxSize, wgConfig.value(amnezia::config_key::junkPacketMaxSize));
|
|
||||||
json.insert(amnezia::config_key::initPacketJunkSize, wgConfig.value(amnezia::config_key::initPacketJunkSize));
|
|
||||||
json.insert(amnezia::config_key::responsePacketJunkSize, wgConfig.value(amnezia::config_key::responsePacketJunkSize));
|
|
||||||
json.insert(amnezia::config_key::initPacketMagicHeader, wgConfig.value(amnezia::config_key::initPacketMagicHeader));
|
|
||||||
json.insert(amnezia::config_key::responsePacketMagicHeader, wgConfig.value(amnezia::config_key::responsePacketMagicHeader));
|
|
||||||
json.insert(amnezia::config_key::underloadPacketMagicHeader, wgConfig.value(amnezia::config_key::underloadPacketMagicHeader));
|
|
||||||
json.insert(amnezia::config_key::transportPacketMagicHeader, wgConfig.value(amnezia::config_key::transportPacketMagicHeader));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write(json);
|
write(json);
|
||||||
|
|||||||
@@ -16,11 +16,6 @@ struct Log {
|
|||||||
|
|
||||||
private static let appGroupID = "group.org.amnezia.AmneziaVPN"
|
private static let appGroupID = "group.org.amnezia.AmneziaVPN"
|
||||||
|
|
||||||
static let appLogURL = {
|
|
||||||
let sharedContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupID)!
|
|
||||||
return sharedContainerURL.appendingPathComponent("app.log", isDirectory: false)
|
|
||||||
}()
|
|
||||||
|
|
||||||
static let neLogURL = {
|
static let neLogURL = {
|
||||||
let sharedContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupID)!
|
let sharedContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupID)!
|
||||||
return sharedContainerURL.appendingPathComponent("ne.log", isDirectory: false)
|
return sharedContainerURL.appendingPathComponent("ne.log", isDirectory: false)
|
||||||
@@ -75,12 +70,8 @@ struct Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static func log(_ type: OSLogType, title: String = "", message: String, url: URL = neLogURL) {
|
static func log(_ type: OSLogType, title: String = "", message: String, url: URL = neLogURL) {
|
||||||
NSLog("\(title) \(message)")
|
|
||||||
|
|
||||||
guard isLoggingEnabled else { return }
|
guard isLoggingEnabled else { return }
|
||||||
|
|
||||||
osLog.log(level: type, "\(title) \(message)")
|
|
||||||
|
|
||||||
let date = Date()
|
let date = Date()
|
||||||
let level = Record.Level(from: type)
|
let level = Record.Level(from: type)
|
||||||
let messages = message.split(whereSeparator: \.isNewline)
|
let messages = message.split(whereSeparator: \.isNewline)
|
||||||
@@ -116,7 +107,3 @@ extension Log: CustomStringConvertible {
|
|||||||
.joined(separator: "\n")
|
.joined(separator: "\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func log(_ type: OSLogType, title: String = "", message: String) {
|
|
||||||
Log.log(type, title: "App: \(title)", message: message, url: Log.appLogURL)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,33 +1,50 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
import NetworkExtension
|
||||||
|
|
||||||
public func swiftUpdateLogData(_ qtString: std.string) -> std.string {
|
public func swiftUpdateLogData(_ qtString: std.string) -> std.string {
|
||||||
let qtLog = Log(String(describing: qtString))
|
let qtLog = Log(String(describing: qtString))
|
||||||
var log = qtLog
|
var log = qtLog
|
||||||
|
|
||||||
if let appLog = Log(at: Log.appLogURL) {
|
|
||||||
appLog.records.forEach {
|
|
||||||
log.records.append($0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let neLog = Log(at: Log.neLogURL) {
|
if let neLog = Log(at: Log.neLogURL) {
|
||||||
neLog.records.forEach {
|
neLog.records.forEach {
|
||||||
log.records.append($0)
|
log.records.append($0)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
log.records.sort {
|
log.records.sort {
|
||||||
$0.date < $1.date
|
$0.date < $1.date
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return std.string(log.description)
|
return std.string(log.description)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func swiftDeleteLog() {
|
public func swiftDeleteLog() {
|
||||||
Log.clear(at: Log.appLogURL)
|
|
||||||
Log.clear(at: Log.neLogURL)
|
Log.clear(at: Log.neLogURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func toggleLogging(_ isEnabled: Bool) {
|
public func toggleLogging(_ isEnabled: Bool) {
|
||||||
Log.isLoggingEnabled = isEnabled
|
Log.isLoggingEnabled = isEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func clearSettings() {
|
||||||
|
NETunnelProviderManager.loadAllFromPreferences { managers, error in
|
||||||
|
if let error {
|
||||||
|
NSLog("clearSettings removeFromPreferences error: \(error.localizedDescription)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
managers?.forEach { manager in
|
||||||
|
manager.removeFromPreferences { error in
|
||||||
|
if let error {
|
||||||
|
NSLog("NE removeFromPreferences error: \(error.localizedDescription)")
|
||||||
|
} else {
|
||||||
|
manager.loadFromPreferences { error in
|
||||||
|
if let error {
|
||||||
|
NSLog("NE loadFromPreferences after remove error: \(error.localizedDescription)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -94,8 +94,6 @@ extension PacketTunnelProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func stopOpenVPN(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
|
func stopOpenVPN(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
|
||||||
ovpnLog(.info, message: "Stopping tunnel: reason: \(reason.description)")
|
|
||||||
|
|
||||||
stopHandler = completionHandler
|
stopHandler = completionHandler
|
||||||
if vpnReachability.isTracking {
|
if vpnReachability.isTracking {
|
||||||
vpnReachability.stopTracking()
|
vpnReachability.stopTracking()
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ extension PacketTunnelProvider {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
func stopWireguard(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
|
func stopWireguard(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
|
||||||
wg_log(.info, message: "Stopping tunnel: reason: \(reason.description)")
|
wg_log(.info, staticMessage: "Stopping tunnel")
|
||||||
|
|
||||||
wgAdapter.stop { error in
|
wgAdapter.stop { error in
|
||||||
ErrorNotifier.removeLastErrorFile()
|
ErrorNotifier.removeLastErrorFile()
|
||||||
|
|||||||
@@ -200,46 +200,3 @@ extension WireGuardLogLevel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NEProviderStopReason: CustomStringConvertible {
|
|
||||||
public var description: String {
|
|
||||||
switch self {
|
|
||||||
case .none:
|
|
||||||
return "No specific reason"
|
|
||||||
case .userInitiated:
|
|
||||||
return "The user stopped the NE"
|
|
||||||
case .providerFailed:
|
|
||||||
return "The NE failed to function correctly"
|
|
||||||
case .noNetworkAvailable:
|
|
||||||
return "No network connectivity is currently available"
|
|
||||||
case .unrecoverableNetworkChange:
|
|
||||||
return "The device’s network connectivity changed"
|
|
||||||
case .providerDisabled:
|
|
||||||
return "The NE was disabled"
|
|
||||||
case .authenticationCanceled:
|
|
||||||
return "The authentication process was canceled"
|
|
||||||
case .configurationFailed:
|
|
||||||
return "The VPNC is invalid"
|
|
||||||
case .idleTimeout:
|
|
||||||
return "The session timed out"
|
|
||||||
case .configurationDisabled:
|
|
||||||
return "The VPNC was disabled"
|
|
||||||
case .configurationRemoved:
|
|
||||||
return "The VPNC was removed"
|
|
||||||
case .superceded:
|
|
||||||
return "VPNC was superceded by a higher-priority VPNC"
|
|
||||||
case .userLogout:
|
|
||||||
return "The user logged out"
|
|
||||||
case .userSwitch:
|
|
||||||
return "The current console user changed"
|
|
||||||
case .connectionFailed:
|
|
||||||
return "The connection failed"
|
|
||||||
case .sleep:
|
|
||||||
return "A stop reason indicating the VPNC enabled disconnect on sleep and the device went to sleep"
|
|
||||||
case .appUpdate:
|
|
||||||
return "appUpdat"
|
|
||||||
@unknown default:
|
|
||||||
return "@unknown default"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
import NetworkExtension
|
|
||||||
|
|
||||||
public func removeVPNC(_ vpncName: std.string) {
|
|
||||||
let vpncName = String(describing: vpncName)
|
|
||||||
|
|
||||||
Task {
|
|
||||||
await getManagers()?.first { manager in
|
|
||||||
if let name = manager.localizedDescription, name == vpncName {
|
|
||||||
Task {
|
|
||||||
await remove(manager)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func clearSettings() {
|
|
||||||
Task {
|
|
||||||
await getManagers()?.forEach { manager in
|
|
||||||
Task {
|
|
||||||
await remove(manager)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getManagers() async -> [NETunnelProviderManager]? {
|
|
||||||
do {
|
|
||||||
return try await NETunnelProviderManager.loadAllFromPreferences()
|
|
||||||
} catch {
|
|
||||||
log(.error, title: "VPNC: ", message: "loadAllFromPreferences error: \(error.localizedDescription)")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func remove(_ manager: NETunnelProviderManager) async {
|
|
||||||
let vpncName = manager.localizedDescription ?? "Unknown"
|
|
||||||
do {
|
|
||||||
try await manager.removeFromPreferences()
|
|
||||||
try await manager.loadFromPreferences()
|
|
||||||
log(.info, title: "VPNC: ", message: "Remove \(vpncName)")
|
|
||||||
} catch {
|
|
||||||
log(.error, title: "VPNC: ", message: "Failed to remove \(vpncName) (\(error.localizedDescription))")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -86,9 +86,6 @@ struct WGConfig: Decodable {
|
|||||||
AllowedIPs = \(allowedIPs.joined(separator: ", "))
|
AllowedIPs = \(allowedIPs.joined(separator: ", "))
|
||||||
Endpoint = \(hostName):\(port)
|
Endpoint = \(hostName):\(port)
|
||||||
PersistentKeepalive = \(persistentKeepAlive)
|
PersistentKeepalive = \(persistentKeepAlive)
|
||||||
|
|
||||||
SplitTunnelType = \(splitTunnelType)
|
|
||||||
SplitTunnelSites = \(splitTunnelSites.joined(separator: ", "))
|
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,11 +89,9 @@ bool IosController::initialize()
|
|||||||
|
|
||||||
|
|
||||||
for (NETunnelProviderManager *manager in managers) {
|
for (NETunnelProviderManager *manager in managers) {
|
||||||
qDebug() << "IosController::initialize : VPNC: " << manager.localizedDescription;
|
|
||||||
|
|
||||||
if (manager.connection.status == NEVPNStatusConnected) {
|
if (manager.connection.status == NEVPNStatusConnected) {
|
||||||
m_currentTunnel = manager;
|
m_currentTunnel = manager;
|
||||||
qDebug() << "IosController::initialize : VPN already connected with" << manager.localizedDescription;
|
qDebug() << "IosController::initialize : VPN already connected";
|
||||||
emit connectionStateChanged(Vpn::ConnectionState::Connected);
|
emit connectionStateChanged(Vpn::ConnectionState::Connected);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -140,7 +138,7 @@ bool IosController::connectVpn(amnezia::Proto proto, const QJsonObject& configur
|
|||||||
[NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArray<NETunnelProviderManager *> * _Nullable managers, NSError * _Nullable error) {
|
[NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArray<NETunnelProviderManager *> * _Nullable managers, NSError * _Nullable error) {
|
||||||
@try {
|
@try {
|
||||||
if (error) {
|
if (error) {
|
||||||
qDebug() << "IosController::connectVpn : VPNC: loadAllFromPreferences error:" << [error.localizedDescription UTF8String];
|
qDebug() << "IosController::connectVpn : Error:" << [error.localizedDescription UTF8String];
|
||||||
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
||||||
ok = false;
|
ok = false;
|
||||||
return;
|
return;
|
||||||
@@ -153,7 +151,7 @@ bool IosController::connectVpn(amnezia::Proto proto, const QJsonObject& configur
|
|||||||
for (NETunnelProviderManager *manager in managers) {
|
for (NETunnelProviderManager *manager in managers) {
|
||||||
if ([manager.localizedDescription isEqualToString:tunnelName.toNSString()]) {
|
if ([manager.localizedDescription isEqualToString:tunnelName.toNSString()]) {
|
||||||
m_currentTunnel = manager;
|
m_currentTunnel = manager;
|
||||||
qDebug() << "IosController::connectVpn : Using existing tunnel:" << manager.localizedDescription;
|
qDebug() << "IosController::connectVpn : Using existing tunnel";
|
||||||
if (manager.connection.status == NEVPNStatusConnected) {
|
if (manager.connection.status == NEVPNStatusConnected) {
|
||||||
emit connectionStateChanged(Vpn::ConnectionState::Connected);
|
emit connectionStateChanged(Vpn::ConnectionState::Connected);
|
||||||
return;
|
return;
|
||||||
@@ -164,10 +162,10 @@ bool IosController::connectVpn(amnezia::Proto proto, const QJsonObject& configur
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!m_currentTunnel) {
|
if (!m_currentTunnel) {
|
||||||
|
qDebug() << "IosController::connectVpn : Creating new tunnel";
|
||||||
isNewTunnelCreated = true;
|
isNewTunnelCreated = true;
|
||||||
m_currentTunnel = [[NETunnelProviderManager alloc] init];
|
m_currentTunnel = [[NETunnelProviderManager alloc] init];
|
||||||
m_currentTunnel.localizedDescription = [NSString stringWithUTF8String:tunnelName.toStdString().c_str()];
|
m_currentTunnel.localizedDescription = [NSString stringWithUTF8String:tunnelName.toStdString().c_str()];
|
||||||
qDebug() << "IosController::connectVpn : Creating new tunnel" << m_currentTunnel.localizedDescription;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -426,8 +424,6 @@ bool IosController::setupCloak()
|
|||||||
openVPNConfig.insert(config_key::mtu, protocols::openvpn::defaultMtu);
|
openVPNConfig.insert(config_key::mtu, protocols::openvpn::defaultMtu);
|
||||||
}
|
}
|
||||||
|
|
||||||
openVPNConfig.insert(config_key::splitTunnelType, m_rawConfig[config_key::splitTunnelType]);
|
|
||||||
|
|
||||||
QJsonArray splitTunnelSites = m_rawConfig[config_key::splitTunnelSites].toArray();
|
QJsonArray splitTunnelSites = m_rawConfig[config_key::splitTunnelSites].toArray();
|
||||||
|
|
||||||
for(int index = 0; index < splitTunnelSites.count(); index++) {
|
for(int index = 0; index < splitTunnelSites.count(); index++) {
|
||||||
@@ -600,14 +596,13 @@ void IosController::startTunnel()
|
|||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
|
||||||
if (saveError) {
|
if (saveError) {
|
||||||
qDebug().nospace() << "IosController::startTunnel" << protocolName << ": Connect " << protocolName << " Tunnel Save Error" << saveError.localizedDescription.UTF8String;
|
|
||||||
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[m_currentTunnel loadFromPreferencesWithCompletionHandler:^(NSError *loadError) {
|
[m_currentTunnel loadFromPreferencesWithCompletionHandler:^(NSError *loadError) {
|
||||||
if (loadError) {
|
if (loadError) {
|
||||||
qDebug().nospace() << "IosController::startTunnel :" << m_currentTunnel.localizedDescription << protocolName << ": Connect " << protocolName << " Tunnel Load Error" << loadError.localizedDescription.UTF8String;
|
qDebug().nospace() << "IosController::start" << protocolName << ": Connect " << protocolName << " Tunnel Load Error" << loadError.localizedDescription.UTF8String;
|
||||||
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -618,11 +613,11 @@ void IosController::startTunnel()
|
|||||||
BOOL started = [m_currentTunnel.connection startVPNTunnelWithOptions:nil andReturnError:&startError];
|
BOOL started = [m_currentTunnel.connection startVPNTunnelWithOptions:nil andReturnError:&startError];
|
||||||
|
|
||||||
if (!started || startError) {
|
if (!started || startError) {
|
||||||
qDebug().nospace() << "IosController::startTunnel :" << m_currentTunnel.localizedDescription << protocolName << " : Connect " << protocolName << " Tunnel Start Error"
|
qDebug().nospace() << "IosController::start" << protocolName << " : Connect " << protocolName << " Tunnel Start Error"
|
||||||
<< (startError ? startError.localizedDescription.UTF8String : "");
|
<< (startError ? startError.localizedDescription.UTF8String : "");
|
||||||
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
||||||
} else {
|
} else {
|
||||||
qDebug().nospace() << "IosController::startTunnel :" << m_currentTunnel.localizedDescription << protocolName << " : Starting the tunnel succeeded";
|
qDebug().nospace() << "IosController::start" << protocolName << " : Starting the tunnel succeeded";
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -103,32 +103,15 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) {
|
|||||||
out << "private_key=" << QString(privateKey.toHex()) << "\n";
|
out << "private_key=" << QString(privateKey.toHex()) << "\n";
|
||||||
out << "replace_peers=true\n";
|
out << "replace_peers=true\n";
|
||||||
|
|
||||||
|
if (config.m_junkPacketCount != "") {
|
||||||
if (!config.m_junkPacketCount.isEmpty()) {
|
|
||||||
out << "jc=" << config.m_junkPacketCount << "\n";
|
out << "jc=" << config.m_junkPacketCount << "\n";
|
||||||
}
|
|
||||||
if (!config.m_junkPacketMinSize.isEmpty()) {
|
|
||||||
out << "jmin=" << config.m_junkPacketMinSize << "\n";
|
out << "jmin=" << config.m_junkPacketMinSize << "\n";
|
||||||
}
|
|
||||||
if (!config.m_junkPacketMaxSize.isEmpty()) {
|
|
||||||
out << "jmax=" << config.m_junkPacketMaxSize << "\n";
|
out << "jmax=" << config.m_junkPacketMaxSize << "\n";
|
||||||
}
|
|
||||||
if (!config.m_initPacketJunkSize.isEmpty()) {
|
|
||||||
out << "s1=" << config.m_initPacketJunkSize << "\n";
|
out << "s1=" << config.m_initPacketJunkSize << "\n";
|
||||||
}
|
|
||||||
if (!config.m_responsePacketJunkSize.isEmpty()) {
|
|
||||||
out << "s2=" << config.m_responsePacketJunkSize << "\n";
|
out << "s2=" << config.m_responsePacketJunkSize << "\n";
|
||||||
}
|
|
||||||
if (!config.m_initPacketMagicHeader.isEmpty()) {
|
|
||||||
out << "h1=" << config.m_initPacketMagicHeader << "\n";
|
out << "h1=" << config.m_initPacketMagicHeader << "\n";
|
||||||
}
|
|
||||||
if (!config.m_responsePacketMagicHeader.isEmpty()) {
|
|
||||||
out << "h2=" << config.m_responsePacketMagicHeader << "\n";
|
out << "h2=" << config.m_responsePacketMagicHeader << "\n";
|
||||||
}
|
|
||||||
if (!config.m_underloadPacketMagicHeader.isEmpty()) {
|
|
||||||
out << "h3=" << config.m_underloadPacketMagicHeader << "\n";
|
out << "h3=" << config.m_underloadPacketMagicHeader << "\n";
|
||||||
}
|
|
||||||
if (!config.m_transportPacketMagicHeader.isEmpty()) {
|
|
||||||
out << "h4=" << config.m_transportPacketMagicHeader << "\n";
|
out << "h4=" << config.m_transportPacketMagicHeader << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,9 +182,7 @@ bool WireguardUtilsLinux::updatePeer(const InterfaceConfig& config) {
|
|||||||
QTextStream out(&message);
|
QTextStream out(&message);
|
||||||
out << "set=1\n";
|
out << "set=1\n";
|
||||||
out << "public_key=" << QString(publicKey.toHex()) << "\n";
|
out << "public_key=" << QString(publicKey.toHex()) << "\n";
|
||||||
if (!config.m_serverPskKey.isNull()) {
|
|
||||||
out << "preshared_key=" << QString(pskKey.toHex()) << "\n";
|
out << "preshared_key=" << QString(pskKey.toHex()) << "\n";
|
||||||
}
|
|
||||||
if (!config.m_serverIpv4AddrIn.isNull()) {
|
if (!config.m_serverIpv4AddrIn.isNull()) {
|
||||||
out << "endpoint=" << config.m_serverIpv4AddrIn << ":";
|
out << "endpoint=" << config.m_serverIpv4AddrIn << ":";
|
||||||
} else if (!config.m_serverIpv6AddrIn.isNull()) {
|
} else if (!config.m_serverIpv6AddrIn.isNull()) {
|
||||||
|
|||||||
@@ -101,31 +101,15 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) {
|
|||||||
out << "private_key=" << QString(privateKey.toHex()) << "\n";
|
out << "private_key=" << QString(privateKey.toHex()) << "\n";
|
||||||
out << "replace_peers=true\n";
|
out << "replace_peers=true\n";
|
||||||
|
|
||||||
if (!config.m_junkPacketCount.isEmpty()) {
|
if (config.m_junkPacketCount != "") {
|
||||||
out << "jc=" << config.m_junkPacketCount << "\n";
|
out << "jc=" << config.m_junkPacketCount << "\n";
|
||||||
}
|
|
||||||
if (!config.m_junkPacketMinSize.isEmpty()) {
|
|
||||||
out << "jmin=" << config.m_junkPacketMinSize << "\n";
|
out << "jmin=" << config.m_junkPacketMinSize << "\n";
|
||||||
}
|
|
||||||
if (!config.m_junkPacketMaxSize.isEmpty()) {
|
|
||||||
out << "jmax=" << config.m_junkPacketMaxSize << "\n";
|
out << "jmax=" << config.m_junkPacketMaxSize << "\n";
|
||||||
}
|
|
||||||
if (!config.m_initPacketJunkSize.isEmpty()) {
|
|
||||||
out << "s1=" << config.m_initPacketJunkSize << "\n";
|
out << "s1=" << config.m_initPacketJunkSize << "\n";
|
||||||
}
|
|
||||||
if (!config.m_responsePacketJunkSize.isEmpty()) {
|
|
||||||
out << "s2=" << config.m_responsePacketJunkSize << "\n";
|
out << "s2=" << config.m_responsePacketJunkSize << "\n";
|
||||||
}
|
|
||||||
if (!config.m_initPacketMagicHeader.isEmpty()) {
|
|
||||||
out << "h1=" << config.m_initPacketMagicHeader << "\n";
|
out << "h1=" << config.m_initPacketMagicHeader << "\n";
|
||||||
}
|
|
||||||
if (!config.m_responsePacketMagicHeader.isEmpty()) {
|
|
||||||
out << "h2=" << config.m_responsePacketMagicHeader << "\n";
|
out << "h2=" << config.m_responsePacketMagicHeader << "\n";
|
||||||
}
|
|
||||||
if (!config.m_underloadPacketMagicHeader.isEmpty()) {
|
|
||||||
out << "h3=" << config.m_underloadPacketMagicHeader << "\n";
|
out << "h3=" << config.m_underloadPacketMagicHeader << "\n";
|
||||||
}
|
|
||||||
if (!config.m_transportPacketMagicHeader.isEmpty()) {
|
|
||||||
out << "h4=" << config.m_transportPacketMagicHeader << "\n";
|
out << "h4=" << config.m_transportPacketMagicHeader << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,9 +183,7 @@ bool WireguardUtilsMacos::updatePeer(const InterfaceConfig& config) {
|
|||||||
QTextStream out(&message);
|
QTextStream out(&message);
|
||||||
out << "set=1\n";
|
out << "set=1\n";
|
||||||
out << "public_key=" << QString(publicKey.toHex()) << "\n";
|
out << "public_key=" << QString(publicKey.toHex()) << "\n";
|
||||||
if (!config.m_serverPskKey.isNull()) {
|
|
||||||
out << "preshared_key=" << QString(pskKey.toHex()) << "\n";
|
out << "preshared_key=" << QString(pskKey.toHex()) << "\n";
|
||||||
}
|
|
||||||
if (!config.m_serverIpv4AddrIn.isNull()) {
|
if (!config.m_serverIpv4AddrIn.isNull()) {
|
||||||
out << "endpoint=" << config.m_serverIpv4AddrIn << ":";
|
out << "endpoint=" << config.m_serverIpv4AddrIn << ":";
|
||||||
} else if (!config.m_serverIpv6AddrIn.isNull()) {
|
} else if (!config.m_serverIpv6AddrIn.isNull()) {
|
||||||
|
|||||||
@@ -148,9 +148,7 @@ bool WireguardUtilsWindows::updatePeer(const InterfaceConfig& config) {
|
|||||||
QTextStream out(&message);
|
QTextStream out(&message);
|
||||||
out << "set=1\n";
|
out << "set=1\n";
|
||||||
out << "public_key=" << QString(publicKey.toHex()) << "\n";
|
out << "public_key=" << QString(publicKey.toHex()) << "\n";
|
||||||
if (!config.m_serverPskKey.isNull()) {
|
|
||||||
out << "preshared_key=" << QString(pskKey.toHex()) << "\n";
|
out << "preshared_key=" << QString(pskKey.toHex()) << "\n";
|
||||||
}
|
|
||||||
if (!config.m_serverIpv4AddrIn.isNull()) {
|
if (!config.m_serverIpv4AddrIn.isNull()) {
|
||||||
out << "endpoint=" << config.m_serverIpv4AddrIn << ":";
|
out << "endpoint=" << config.m_serverIpv4AddrIn << ":";
|
||||||
} else if (!config.m_serverIpv6AddrIn.isNull()) {
|
} else if (!config.m_serverIpv6AddrIn.isNull()) {
|
||||||
|
|||||||
@@ -16,6 +16,12 @@
|
|||||||
|
|
||||||
using namespace QKeychain;
|
using namespace QKeychain;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr auto settingsKeyTag{"settingsKeyTag"};
|
||||||
|
constexpr auto settingsIvTag{"settingsIvTag"};
|
||||||
|
constexpr auto keyChainName{"AmneziaVPN-Keychain"};
|
||||||
|
}
|
||||||
|
|
||||||
SecureQSettings::SecureQSettings(const QString &organization, const QString &application, QObject *parent)
|
SecureQSettings::SecureQSettings(const QString &organization, const QString &application, QObject *parent)
|
||||||
: QObject { parent }, m_settings(organization, application, parent), encryptedKeys({ "Servers/serversList" })
|
: QObject { parent }, m_settings(organization, application, parent), encryptedKeys({ "Servers/serversList" })
|
||||||
{
|
{
|
||||||
@@ -50,7 +56,7 @@ QVariant SecureQSettings::value(const QString &key, const QVariant &defaultValue
|
|||||||
// check if value is not encrypted, v. < 2.0.x
|
// check if value is not encrypted, v. < 2.0.x
|
||||||
retVal = m_settings.value(key);
|
retVal = m_settings.value(key);
|
||||||
if (retVal.isValid()) {
|
if (retVal.isValid()) {
|
||||||
if (retVal.userType() == QVariant::ByteArray && retVal.toByteArray().mid(0, magicString.size()) == magicString) {
|
if (retVal.userType() == QMetaType::QByteArray && retVal.toByteArray().mid(0, magicString.size()) == magicString) {
|
||||||
|
|
||||||
if (getEncKey().isEmpty() || getEncIv().isEmpty()) {
|
if (getEncKey().isEmpty() || getEncIv().isEmpty()) {
|
||||||
qCritical() << "SecureQSettings::setValue Decryption requested, but key is empty";
|
qCritical() << "SecureQSettings::setValue Decryption requested, but key is empty";
|
||||||
@@ -125,10 +131,6 @@ QByteArray SecureQSettings::backupAppConfig() const
|
|||||||
QJsonObject cfg;
|
QJsonObject cfg;
|
||||||
|
|
||||||
for (const QString &key : m_settings.allKeys()) {
|
for (const QString &key : m_settings.allKeys()) {
|
||||||
if (key == "Conf/installationUuid") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.insert(key, QJsonValue::fromVariant(value(key)));
|
cfg.insert(key, QJsonValue::fromVariant(value(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,10 +144,6 @@ bool SecureQSettings::restoreAppConfig(const QByteArray &json)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (const QString &key : cfg.keys()) {
|
for (const QString &key : cfg.keys()) {
|
||||||
if (key == "Conf/installationUuid") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
setValue(key, cfg.value(key).toVariant());
|
setValue(key, cfg.value(key).toVariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,6 @@
|
|||||||
|
|
||||||
#include "keychain.h"
|
#include "keychain.h"
|
||||||
|
|
||||||
constexpr const char *settingsKeyTag = "settingsKeyTag";
|
|
||||||
constexpr const char *settingsIvTag = "settingsIvTag";
|
|
||||||
constexpr const char *keyChainName = "AmneziaVPN-Keychain";
|
|
||||||
|
|
||||||
class SecureQSettings : public QObject
|
class SecureQSettings : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -44,7 +40,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
QSettings m_settings;
|
QSettings m_settings;
|
||||||
|
|
||||||
mutable QMap<QString, QVariant> m_cache;
|
mutable QHash<QString, QVariant> m_cache;
|
||||||
|
|
||||||
QStringList encryptedKeys; // encode only key listed here
|
QStringList encryptedKeys; // encode only key listed here
|
||||||
|
|
||||||
|
|||||||
@@ -256,16 +256,6 @@ Settings::RouteMode Settings::routeMode() const
|
|||||||
return static_cast<RouteMode>(value("Conf/routeMode", 0).toInt());
|
return static_cast<RouteMode>(value("Conf/routeMode", 0).toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::getSitesSplitTunnelingEnabled() const
|
|
||||||
{
|
|
||||||
return value("Conf/sitesSplitTunnelingEnabled", false).toBool();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::setSitesSplitTunnelingEnabled(bool enabled)
|
|
||||||
{
|
|
||||||
setValue("Conf/sitesSplitTunnelingEnabled", enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Settings::addVpnSite(RouteMode mode, const QString &site, const QString &ip)
|
bool Settings::addVpnSite(RouteMode mode, const QString &site, const QString &ip)
|
||||||
{
|
{
|
||||||
QVariantMap sites = vpnSites(mode);
|
QVariantMap sites = vpnSites(mode);
|
||||||
@@ -361,9 +351,7 @@ QString Settings::secondaryDns() const
|
|||||||
|
|
||||||
void Settings::clearSettings()
|
void Settings::clearSettings()
|
||||||
{
|
{
|
||||||
auto uuid = getInstallationUuid(false);
|
|
||||||
m_settings.clearSettings();
|
m_settings.clearSettings();
|
||||||
setInstallationUuid(uuid);
|
|
||||||
emit settingsCleared();
|
emit settingsCleared();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,31 +403,6 @@ void Settings::setVpnApps(AppsRouteMode mode, const QVector<InstalledAppInfo> &a
|
|||||||
m_settings.sync();
|
m_settings.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::getAppsSplitTunnelingEnabled() const
|
|
||||||
{
|
|
||||||
return value("Conf/appsSplitTunnelingEnabled", false).toBool();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::setAppsSplitTunnelingEnabled(bool enabled)
|
|
||||||
{
|
|
||||||
setValue("Conf/appsSplitTunnelingEnabled", enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Settings::getInstallationUuid(const bool needCreate)
|
|
||||||
{
|
|
||||||
auto uuid = value("Conf/installationUuid", "").toString();
|
|
||||||
if (needCreate && uuid.isEmpty()) {
|
|
||||||
uuid = QUuid::createUuid().toString();
|
|
||||||
setInstallationUuid(uuid);
|
|
||||||
}
|
|
||||||
return uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::setInstallationUuid(const QString &uuid)
|
|
||||||
{
|
|
||||||
setValue("Conf/installationUuid", uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerCredentials Settings::defaultServerCredentials() const
|
ServerCredentials Settings::defaultServerCredentials() const
|
||||||
{
|
{
|
||||||
return serverCredentials(defaultServerIndex());
|
return serverCredentials(defaultServerIndex());
|
||||||
|
|||||||
@@ -115,9 +115,6 @@ public:
|
|||||||
RouteMode routeMode() const;
|
RouteMode routeMode() const;
|
||||||
void setRouteMode(RouteMode mode) { setValue("Conf/routeMode", mode); }
|
void setRouteMode(RouteMode mode) { setValue("Conf/routeMode", mode); }
|
||||||
|
|
||||||
bool getSitesSplitTunnelingEnabled() const;
|
|
||||||
void setSitesSplitTunnelingEnabled(bool enabled);
|
|
||||||
|
|
||||||
QVariantMap vpnSites(RouteMode mode) const
|
QVariantMap vpnSites(RouteMode mode) const
|
||||||
{
|
{
|
||||||
return value("Conf/" + routeModeString(mode)).toMap();
|
return value("Conf/" + routeModeString(mode)).toMap();
|
||||||
@@ -211,11 +208,6 @@ public:
|
|||||||
QVector<InstalledAppInfo> getVpnApps(AppsRouteMode mode) const;
|
QVector<InstalledAppInfo> getVpnApps(AppsRouteMode mode) const;
|
||||||
void setVpnApps(AppsRouteMode mode, const QVector<InstalledAppInfo> &apps);
|
void setVpnApps(AppsRouteMode mode, const QVector<InstalledAppInfo> &apps);
|
||||||
|
|
||||||
bool getAppsSplitTunnelingEnabled() const;
|
|
||||||
void setAppsSplitTunnelingEnabled(bool enabled);
|
|
||||||
|
|
||||||
QString getInstallationUuid(const bool needCreate);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void saveLogsChanged(bool enabled);
|
void saveLogsChanged(bool enabled);
|
||||||
void screenshotsEnabledChanged(bool enabled);
|
void screenshotsEnabledChanged(bool enabled);
|
||||||
@@ -226,8 +218,6 @@ private:
|
|||||||
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
|
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
|
||||||
void setValue(const QString &key, const QVariant &value);
|
void setValue(const QString &key, const QVariant &value);
|
||||||
|
|
||||||
void setInstallationUuid(const QString &uuid);
|
|
||||||
|
|
||||||
mutable SecureQSettings m_settings;
|
mutable SecureQSettings m_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2906,7 +2906,7 @@ While it offers a blend of security, stability, and speed, it's essential t
|
|||||||
Он может быстро переключаться между сетями и устройствами, что делает его особенно адаптивным в динамичных сетевых средах.
|
Он может быстро переключаться между сетями и устройствами, что делает его особенно адаптивным в динамичных сетевых средах.
|
||||||
Несмотря на сочетание безопасности, стабильности и скорости, необходимо отметить, что IKEv2 легко обнаруживается и подвержен блокировке.
|
Несмотря на сочетание безопасности, стабильности и скорости, необходимо отметить, что IKEv2 легко обнаруживается и подвержен блокировке.
|
||||||
|
|
||||||
* Доступен в AmneziaVPN только для Windows
|
* Доступно в AmneziaVPN только для Windows.
|
||||||
* Низкое энергопотребление, на мобильных устройствах
|
* Низкое энергопотребление, на мобильных устройствах
|
||||||
* Минимальная конфигурация
|
* Минимальная конфигурация
|
||||||
* Распознается системами DPI-анализа
|
* Распознается системами DPI-анализа
|
||||||
@@ -2974,9 +2974,9 @@ It employs its unique security protocol, leveraging the strength of SSL/TLS for
|
|||||||
* Recognised by DPI analysis systems and therefore susceptible to blocking
|
* Recognised by DPI analysis systems and therefore susceptible to blocking
|
||||||
* Can operate over both TCP and UDP network protocols.</source>
|
* Can operate over both TCP and UDP network protocols.</source>
|
||||||
<translation>OpenVPN однин из самых популярных и проверенных временем VPN-протоколов.
|
<translation>OpenVPN однин из самых популярных и проверенных временем VPN-протоколов.
|
||||||
В нем используется уникальный протокол безопасности, опирающийся на протокол SSL/TLS для шифрования и обмена ключами. Кроме того, OpenVPN поддерживает множество методов аутентификации, что делает его универсальным и адаптируемым к широкому спектру устройств и операционных систем. Благодаря открытому исходному коду OpenVPN подвергается тщательному анализу со стороны мирового сообщества, что постоянно повышает его безопасность. Благодаря оптимальному соотношению производительности, безопасности и совместимости OpenVPN остается лучшим выбором как для частных лиц, так и для компаний, заботящихся о конфиденциальности.
|
В нем используется уникальный протокол безопасности, опирающийся на протокол SSL/TLS для шифрования и обмена ключами. Кроме того, поддержка OpenVPN множества методов аутентификации делает его универсальным и адаптируемым к широкому спектру устройств и операционных систем. Благодаря открытому исходному коду OpenVPN подвергается тщательному анализу со стороны мирового сообщества, что постоянно повышает его безопасность. Благодаря оптимальному соотношению производительности, безопасности и совместимости OpenVPN остается лучшим выбором как для частных лиц, так и для компаний, заботящихся о конфиденциальности.
|
||||||
|
|
||||||
* Доступен в AmneziaVPN для всех платформ
|
* Доступность AmneziaVPN для всех платформ
|
||||||
* Нормальное энергопотребление на мобильных устройствах
|
* Нормальное энергопотребление на мобильных устройствах
|
||||||
* Гибкая настройка под нужды пользователя для работы с различными операционными системами и устройствами
|
* Гибкая настройка под нужды пользователя для работы с различными операционными системами и устройствами
|
||||||
* Распознается системами DPI-анализа и поэтому подвержен блокировке
|
* Распознается системами DPI-анализа и поэтому подвержен блокировке
|
||||||
@@ -2994,7 +2994,7 @@ It employs its unique security protocol, leveraging the strength of SSL/TLS for
|
|||||||
* Works over TCP network protocol.</source>
|
* Works over TCP network protocol.</source>
|
||||||
<translation>Shadowsocks, создан на основе протокола SOCKS5, защищает соединение с помощью шифра AEAD. Несмотря на то, что протокол Shadowsocks разработан таким образом, чтобы быть незаметным и сложным для идентификации, он не идентичен стандартному HTTPS-соединению. Однако некоторые системы анализа трафика все же могут обнаружить соединение Shadowsocks. В связи с ограниченной поддержкой в Amnezia рекомендуется использовать протокол AmneziaWG, или OpenVPN over Cloak.
|
<translation>Shadowsocks, создан на основе протокола SOCKS5, защищает соединение с помощью шифра AEAD. Несмотря на то, что протокол Shadowsocks разработан таким образом, чтобы быть незаметным и сложным для идентификации, он не идентичен стандартному HTTPS-соединению. Однако некоторые системы анализа трафика все же могут обнаружить соединение Shadowsocks. В связи с ограниченной поддержкой в Amnezia рекомендуется использовать протокол AmneziaWG, или OpenVPN over Cloak.
|
||||||
|
|
||||||
* Доступен в AmneziaVPN только для ПК и ноутбуков
|
* Доступен в AmneziaVPN только на ПК ноутбуках.
|
||||||
* Настраиваемый протокол шифрования
|
* Настраиваемый протокол шифрования
|
||||||
* Обнаруживается некоторыми DPI-системами
|
* Обнаруживается некоторыми DPI-системами
|
||||||
* Работает по сетевому протоколу TCP.</translation>
|
* Работает по сетевому протоколу TCP.</translation>
|
||||||
@@ -3037,19 +3037,19 @@ If there is a extreme level of Internet censorship in your region, we advise you
|
|||||||
* Not recognised by DPI analysis systems
|
* Not recognised by DPI analysis systems
|
||||||
* Works over TCP network protocol, 443 port.
|
* Works over TCP network protocol, 443 port.
|
||||||
</source>
|
</source>
|
||||||
<translation type="vanished">OpenVPN over Cloak - это комбинация протокола OpenVPN и плагина Cloak, разработанного специально для защиты от обнаружения и блокировок.
|
<translation type="vanished">OpenVPN over Cloak - это комбинация протокола OpenVPN и плагина Cloak, разработанного специально для защиты от блокировок.
|
||||||
|
|
||||||
Протокол OpenVPN обеспечивает безопасное VPN-соединение за счет шифрования всего интернет-трафика между клиентом и сервером.
|
OpenVPN обеспечивает безопасное VPN-соединение за счет шифрования всего интернет-трафика между клиентом и сервером.
|
||||||
|
|
||||||
Плагин Cloak защищает OpenVPN от обнаружения и блокировок.
|
Cloak защищает OpenVPN от обнаружения и блокировок.
|
||||||
|
|
||||||
Cloak может изменять метаданные пакетов. Он полностью маскирует VPN-трафик под обычный веб-трафик, а также защищает VPN от обнаружения с помощью Active Probing. Это делает его очень устойчивым к обнаружению
|
Cloak может изменять метаданные пакетов. Он полностью маскирует VPN-трафик под обычный веб-трафик, а также защищает VPN от обнаружения с помощью Active Probing. Это делает его очень устойчивым к обнаружению
|
||||||
|
|
||||||
Сразу же после получения первого пакета данных Cloak проверяет подлинность входящего соединения. Если аутентификация не проходит, плагин маскирует сервер под поддельный сайт, и ваш VPN становится невидимым для аналитических систем.
|
Сразу же после получения первого пакета данных Cloak проверяет подлинность входящего соединения. Если аутентификация не проходит, плагин маскирует сервер под поддельный сайт, и ваш VPN становится невидимым для аналитических систем.
|
||||||
|
|
||||||
Если в вашем регионе экстремальный уровень цензуры в Интернете, мы советуем вам с первого подключения использовать только OpenVPN over Cloak
|
Если в вашем регионе существует экстремальный уровень цензуры в Интернете, мы советуем вам при первом подключении использовать только OpenVPN через Cloak
|
||||||
|
|
||||||
* Доступен в AmneziaVPN для всех платформ
|
* Доступность AmneziaVPN на всех платформах
|
||||||
* Высокое энергопотребление на мобильных устройствах
|
* Высокое энергопотребление на мобильных устройствах
|
||||||
* Гибкие настройки
|
* Гибкие настройки
|
||||||
* Не распознается системами DPI-анализа
|
* Не распознается системами DPI-анализа
|
||||||
@@ -3070,7 +3070,7 @@ WireGuard is very susceptible to blocking due to its distinct packet signatures.
|
|||||||
Обеспечивает стабильное VPN-соединение, высокую производительность на всех устройствах. Использует жестко заданные настройки шифрования. WireGuard по сравнению с OpenVPN имеет меньшую задержку и лучшую пропускную способность при передаче данных.
|
Обеспечивает стабильное VPN-соединение, высокую производительность на всех устройствах. Использует жестко заданные настройки шифрования. WireGuard по сравнению с OpenVPN имеет меньшую задержку и лучшую пропускную способность при передаче данных.
|
||||||
WireGuard очень восприимчив к блокированию из-за особенностей сигнатур пакетов. В отличие от некоторых других VPN-протоколов, использующих методы обфускации, последовательные сигнатуры пакетов WireGuard легче выявляются и, соответственно, блокируются современными системами глубокой проверки пакетов (DPI) и другими средствами сетевого мониторинга.
|
WireGuard очень восприимчив к блокированию из-за особенностей сигнатур пакетов. В отличие от некоторых других VPN-протоколов, использующих методы обфускации, последовательные сигнатуры пакетов WireGuard легче выявляются и, соответственно, блокируются современными системами глубокой проверки пакетов (DPI) и другими средствами сетевого мониторинга.
|
||||||
|
|
||||||
* Доступен в AmneziaVPN для всех платформ
|
* Доступность AmneziaVPN для всех платформ
|
||||||
* Низкое энергопотребление
|
* Низкое энергопотребление
|
||||||
* Минимальное количество настроек
|
* Минимальное количество настроек
|
||||||
* Легко распознается системами DPI-анализа, подвержен блокировке
|
* Легко распознается системами DPI-анализа, подвержен блокировке
|
||||||
@@ -3091,7 +3091,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
|||||||
Хотя WireGuard известен своей эффективностью, у него были проблемы с обнаружением из-за характерных сигнатур пакетов. AmneziaWG решает эту проблему за счет использования более совершенных методов обфускации, благодаря чему его трафик сливается с обычным интернет-трафиком.
|
Хотя WireGuard известен своей эффективностью, у него были проблемы с обнаружением из-за характерных сигнатур пакетов. AmneziaWG решает эту проблему за счет использования более совершенных методов обфускации, благодаря чему его трафик сливается с обычным интернет-трафиком.
|
||||||
Таким образом, AmneziaWG сохраняет высокую производительность оригинала, добавляя при этом дополнительный уровень скрытности, что делает его отличным выбором для тех, кому нужно быстрое и незаметное VPN-соединение.
|
Таким образом, AmneziaWG сохраняет высокую производительность оригинала, добавляя при этом дополнительный уровень скрытности, что делает его отличным выбором для тех, кому нужно быстрое и незаметное VPN-соединение.
|
||||||
|
|
||||||
* Доступен в AmneziaVPN для всех платформ
|
* Доступность AmneziaVPN на всех платформах
|
||||||
* Низкое энергопотребление
|
* Низкое энергопотребление
|
||||||
* Минимальное количество настроек
|
* Минимальное количество настроек
|
||||||
* Не распознается системами DPI-анализа, устойчив к блокировке
|
* Не распознается системами DPI-анализа, устойчив к блокировке
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -14,8 +14,8 @@
|
|||||||
ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &serversModel,
|
ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||||
const QSharedPointer<VpnConnection> &vpnConnection, const std::shared_ptr<Settings> &settings,
|
const QSharedPointer<VpnConnection> &vpnConnection,
|
||||||
QObject *parent)
|
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
m_serversModel(serversModel),
|
m_serversModel(serversModel),
|
||||||
m_containersModel(containersModel),
|
m_containersModel(containersModel),
|
||||||
@@ -23,9 +23,12 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
|||||||
m_vpnConnection(vpnConnection),
|
m_vpnConnection(vpnConnection),
|
||||||
m_settings(settings)
|
m_settings(settings)
|
||||||
{
|
{
|
||||||
connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, this, &ConnectionController::onConnectionStateChanged);
|
connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, this,
|
||||||
connect(this, &ConnectionController::connectToVpn, m_vpnConnection.get(), &VpnConnection::connectToVpn, Qt::QueuedConnection);
|
&ConnectionController::onConnectionStateChanged);
|
||||||
connect(this, &ConnectionController::disconnectFromVpn, m_vpnConnection.get(), &VpnConnection::disconnectFromVpn, Qt::QueuedConnection);
|
connect(this, &ConnectionController::connectToVpn, m_vpnConnection.get(), &VpnConnection::connectToVpn,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(this, &ConnectionController::disconnectFromVpn, m_vpnConnection.get(), &VpnConnection::disconnectFromVpn,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
m_state = Vpn::ConnectionState::Disconnected;
|
m_state = Vpn::ConnectionState::Disconnected;
|
||||||
}
|
}
|
||||||
@@ -42,7 +45,7 @@ void ConnectionController::openConnection()
|
|||||||
if (serverConfig.value(config_key::configVersion).toInt()
|
if (serverConfig.value(config_key::configVersion).toInt()
|
||||||
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||||
ApiController apiController;
|
ApiController apiController;
|
||||||
errorCode = apiController.updateServerConfigFromApi(m_settings->getInstallationUuid(true), serverConfig);
|
errorCode = apiController.updateServerConfigFromApi(serverConfig);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit connectionErrorOccurred(errorString(errorCode));
|
emit connectionErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
@@ -56,12 +59,8 @@ void ConnectionController::openConnection()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DockerContainer container = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
|
DockerContainer container =
|
||||||
|
qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
|
||||||
if (!m_containersModel->isSupportedByCurrentPlatform(container)) {
|
|
||||||
emit connectionErrorOccurred(tr("The selected protocol is not supported on the current platform"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (container == DockerContainer::None) {
|
if (container == DockerContainer::None) {
|
||||||
emit connectionErrorOccurred(tr("VPN Protocols is not installed.\n Please install VPN container at first"));
|
emit connectionErrorOccurred(tr("VPN Protocols is not installed.\n Please install VPN container at first"));
|
||||||
@@ -70,12 +69,11 @@ void ConnectionController::openConnection()
|
|||||||
|
|
||||||
qApp->processEvents();
|
qApp->processEvents();
|
||||||
|
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
|
||||||
|
|
||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||||
errorCode = updateProtocolConfig(container, credentials, containerConfig, serverController);
|
errorCode = updateProtocolConfig(container, credentials, containerConfig);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit connectionErrorOccurred(errorString(errorCode));
|
emit connectionErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
@@ -84,7 +82,8 @@ void ConnectionController::openConnection()
|
|||||||
auto dns = m_serversModel->getDnsPair(serverIndex);
|
auto dns = m_serversModel->getDnsPair(serverIndex);
|
||||||
serverConfig = m_serversModel->getServerConfig(serverIndex);
|
serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
|
|
||||||
auto vpnConfiguration = vpnConfigurationController.createVpnConfiguration(dns, serverConfig, containerConfig, container, errorCode);
|
auto vpnConfiguration =
|
||||||
|
vpnConfigurationController.createVpnConfiguration(dns, serverConfig, containerConfig, container, errorCode);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit connectionErrorOccurred(tr("unable to create configuration"));
|
emit connectionErrorOccurred(tr("unable to create configuration"));
|
||||||
return;
|
return;
|
||||||
@@ -211,8 +210,10 @@ bool ConnectionController::isConnected() const
|
|||||||
bool ConnectionController::isProtocolConfigExists(const QJsonObject &containerConfig, const DockerContainer container)
|
bool ConnectionController::isProtocolConfigExists(const QJsonObject &containerConfig, const DockerContainer container)
|
||||||
{
|
{
|
||||||
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
|
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
|
||||||
QString protocolConfig =
|
QString protocolConfig = containerConfig.value(ProtocolProps::protoToString(protocol))
|
||||||
containerConfig.value(ProtocolProps::protoToString(protocol)).toObject().value(config_key::last_config).toString();
|
.toObject()
|
||||||
|
.value(config_key::last_config)
|
||||||
|
.toString();
|
||||||
|
|
||||||
if (protocolConfig.isEmpty()) {
|
if (protocolConfig.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -221,27 +222,24 @@ bool ConnectionController::isProtocolConfigExists(const QJsonObject &containerCo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ConnectionController::updateProtocolConfig(const DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode ConnectionController::updateProtocolConfig(const DockerContainer container,
|
||||||
QJsonObject &containerConfig, QSharedPointer<ServerController> serverController)
|
const ServerCredentials &credentials, QJsonObject &containerConfig)
|
||||||
{
|
{
|
||||||
QFutureWatcher<ErrorCode> watcher;
|
QFutureWatcher<ErrorCode> watcher;
|
||||||
|
|
||||||
if (serverController.isNull()) {
|
QFuture<ErrorCode> future = QtConcurrent::run([this, container, &credentials, &containerConfig]() {
|
||||||
serverController.reset(new ServerController(m_settings));
|
|
||||||
}
|
|
||||||
|
|
||||||
QFuture<ErrorCode> future = QtConcurrent::run([this, container, &credentials, &containerConfig, &serverController]() {
|
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
if (!isProtocolConfigExists(containerConfig, container)) {
|
if (!isProtocolConfigExists(containerConfig, container)) {
|
||||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||||
errorCode = vpnConfigurationController.createProtocolConfigForContainer(credentials, container, containerConfig);
|
errorCode =
|
||||||
|
vpnConfigurationController.createProtocolConfigForContainer(credentials, container, containerConfig);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
m_serversModel->updateContainerConfig(container, containerConfig);
|
m_serversModel->updateContainerConfig(container, containerConfig);
|
||||||
|
|
||||||
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig,
|
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig,
|
||||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,11 @@ public:
|
|||||||
Q_PROPERTY(bool isConnectionInProgress READ isConnectionInProgress NOTIFY connectionStateChanged)
|
Q_PROPERTY(bool isConnectionInProgress READ isConnectionInProgress NOTIFY connectionStateChanged)
|
||||||
Q_PROPERTY(QString connectionStateText READ connectionStateText NOTIFY connectionStateChanged)
|
Q_PROPERTY(QString connectionStateText READ connectionStateText NOTIFY connectionStateChanged)
|
||||||
|
|
||||||
explicit ConnectionController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
explicit ConnectionController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||||
const QSharedPointer<VpnConnection> &vpnConnection, const std::shared_ptr<Settings> &settings,
|
const QSharedPointer<VpnConnection> &vpnConnection,
|
||||||
QObject *parent = nullptr);
|
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
~ConnectionController() = default;
|
~ConnectionController() = default;
|
||||||
|
|
||||||
@@ -40,11 +41,12 @@ public slots:
|
|||||||
|
|
||||||
void onTranslationsUpdated();
|
void onTranslationsUpdated();
|
||||||
|
|
||||||
ErrorCode updateProtocolConfig(const DockerContainer container, const ServerCredentials &credentials, QJsonObject &containerConfig,
|
ErrorCode updateProtocolConfig(const DockerContainer container, const ServerCredentials &credentials,
|
||||||
QSharedPointer<ServerController> serverController = nullptr);
|
QJsonObject &containerConfig);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &vpnConfiguration);
|
void connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
const QJsonObject &vpnConfiguration);
|
||||||
void disconnectFromVpn();
|
void disconnectFromVpn();
|
||||||
void connectionStateChanged();
|
void connectionStateChanged();
|
||||||
|
|
||||||
|
|||||||
@@ -95,11 +95,10 @@ void ExportController::generateConnectionConfig(const QString &clientName)
|
|||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
||||||
|
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
|
||||||
ErrorCode errorCode = vpnConfigurationController.createProtocolConfigForContainer(credentials, container, containerConfig);
|
ErrorCode errorCode = vpnConfigurationController.createProtocolConfigForContainer(credentials, container, containerConfig);
|
||||||
|
|
||||||
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig, clientName, serverController);
|
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig, clientName);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
@@ -139,10 +138,10 @@ ErrorCode ExportController::generateNativeConfig(const DockerContainer container
|
|||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
||||||
|
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
|
||||||
|
|
||||||
QString protocolConfigString;
|
QString protocolConfigString;
|
||||||
|
|
||||||
ErrorCode errorCode = vpnConfigurationController.createProtocolConfigString(isApiConfig, dns, credentials, container, containerConfig,
|
ErrorCode errorCode = vpnConfigurationController.createProtocolConfigString(isApiConfig, dns, credentials, container, containerConfig,
|
||||||
protocol, protocolConfigString);
|
protocol, protocolConfigString);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
@@ -153,7 +152,7 @@ ErrorCode ExportController::generateNativeConfig(const DockerContainer container
|
|||||||
|
|
||||||
if (protocol == Proto::OpenVpn || protocol == Proto::WireGuard || protocol == Proto::Awg) {
|
if (protocol == Proto::OpenVpn || protocol == Proto::WireGuard || protocol == Proto::Awg) {
|
||||||
auto clientId = jsonNativeConfig.value(config_key::clientId).toString();
|
auto clientId = jsonNativeConfig.value(config_key::clientId).toString();
|
||||||
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials, serverController);
|
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
|
||||||
}
|
}
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
@@ -317,8 +316,7 @@ void ExportController::exportConfig(const QString &fileName)
|
|||||||
|
|
||||||
void ExportController::updateClientManagementModel(const DockerContainer container, ServerCredentials credentials)
|
void ExportController::updateClientManagementModel(const DockerContainer container, ServerCredentials credentials)
|
||||||
{
|
{
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
ErrorCode errorCode = m_clientManagementModel->updateModel(container, credentials);
|
||||||
ErrorCode errorCode = m_clientManagementModel->updateModel(container, credentials, serverController);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
@@ -326,9 +324,7 @@ void ExportController::updateClientManagementModel(const DockerContainer contain
|
|||||||
|
|
||||||
void ExportController::revokeConfig(const int row, const DockerContainer container, ServerCredentials credentials)
|
void ExportController::revokeConfig(const int row, const DockerContainer container, ServerCredentials credentials)
|
||||||
{
|
{
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
ErrorCode errorCode = m_clientManagementModel->revokeClient(row, container, credentials, m_serversModel->getProcessedServerIndex());
|
||||||
ErrorCode errorCode =
|
|
||||||
m_clientManagementModel->revokeClient(row, container, credentials, m_serversModel->getProcessedServerIndex(), serverController);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
@@ -336,8 +332,7 @@ void ExportController::revokeConfig(const int row, const DockerContainer contain
|
|||||||
|
|
||||||
void ExportController::renameClient(const int row, const QString &clientName, const DockerContainer container, ServerCredentials credentials)
|
void ExportController::renameClient(const int row, const QString &clientName, const DockerContainer container, ServerCredentials credentials)
|
||||||
{
|
{
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
ErrorCode errorCode = m_clientManagementModel->renameClient(row, clientName, container, credentials);
|
||||||
ErrorCode errorCode = m_clientManagementModel->renameClient(row, clientName, container, credentials, serverController);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QRandomGenerator>
|
|
||||||
|
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
@@ -16,6 +15,15 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
enum class ConfigTypes {
|
||||||
|
Amnezia,
|
||||||
|
OpenVpn,
|
||||||
|
WireGuard,
|
||||||
|
Xray,
|
||||||
|
Backup,
|
||||||
|
Invalid
|
||||||
|
};
|
||||||
|
|
||||||
ConfigTypes checkConfigFormat(const QString &config)
|
ConfigTypes checkConfigFormat(const QString &config)
|
||||||
{
|
{
|
||||||
const QString openVpnConfigPatternCli = "client";
|
const QString openVpnConfigPatternCli = "client";
|
||||||
@@ -31,23 +39,19 @@ namespace
|
|||||||
const QString xrayConfigPatternOutbound = "outbounds";
|
const QString xrayConfigPatternOutbound = "outbounds";
|
||||||
|
|
||||||
const QString amneziaConfigPattern = "containers";
|
const QString amneziaConfigPattern = "containers";
|
||||||
const QString amneziaConfigPatternHostName = "hostName";
|
|
||||||
const QString amneziaConfigPatternUserName = "userName";
|
|
||||||
const QString amneziaConfigPatternPassword = "password";
|
|
||||||
const QString amneziaFreeConfigPattern = "api_key";
|
const QString amneziaFreeConfigPattern = "api_key";
|
||||||
const QString backupPattern = "Servers/serversList";
|
const QString backupPattern = "Servers/serversList";
|
||||||
|
|
||||||
if (config.contains(backupPattern)) {
|
if (config.contains(backupPattern)) {
|
||||||
return ConfigTypes::Backup;
|
return ConfigTypes::Backup;
|
||||||
} else if (config.contains(amneziaConfigPattern) || config.contains(amneziaFreeConfigPattern)
|
} else if (config.contains(amneziaConfigPattern) || config.contains(amneziaFreeConfigPattern)) {
|
||||||
|| (config.contains(amneziaConfigPatternHostName) && config.contains(amneziaConfigPatternUserName)
|
|
||||||
&& config.contains(amneziaConfigPatternPassword))) {
|
|
||||||
return ConfigTypes::Amnezia;
|
return ConfigTypes::Amnezia;
|
||||||
} else if (config.contains(openVpnConfigPatternCli)
|
} else if (config.contains(openVpnConfigPatternCli)
|
||||||
&& (config.contains(openVpnConfigPatternProto1) || config.contains(openVpnConfigPatternProto2))
|
&& (config.contains(openVpnConfigPatternProto1) || config.contains(openVpnConfigPatternProto2))
|
||||||
&& (config.contains(openVpnConfigPatternDriver1) || config.contains(openVpnConfigPatternDriver2))) {
|
&& (config.contains(openVpnConfigPatternDriver1) || config.contains(openVpnConfigPatternDriver2))) {
|
||||||
return ConfigTypes::OpenVpn;
|
return ConfigTypes::OpenVpn;
|
||||||
} else if (config.contains(wireguardConfigPatternSectionInterface) && config.contains(wireguardConfigPatternSectionPeer)) {
|
} else if (config.contains(wireguardConfigPatternSectionInterface)
|
||||||
|
&& config.contains(wireguardConfigPatternSectionPeer)) {
|
||||||
return ConfigTypes::WireGuard;
|
return ConfigTypes::WireGuard;
|
||||||
} else if ((config.contains(xrayConfigPatternInbound)) && (config.contains(xrayConfigPatternOutbound))) {
|
} else if ((config.contains(xrayConfigPatternInbound)) && (config.contains(xrayConfigPatternOutbound))) {
|
||||||
return ConfigTypes::Xray;
|
return ConfigTypes::Xray;
|
||||||
@@ -60,7 +64,8 @@ namespace
|
|||||||
#endif
|
#endif
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ImportController::ImportController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
ImportController::ImportController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const std::shared_ptr<Settings> &settings, QObject *parent)
|
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
|
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
|
||||||
{
|
{
|
||||||
@@ -87,25 +92,25 @@ bool ImportController::extractConfigFromFile(const QString &fileName)
|
|||||||
bool ImportController::extractConfigFromData(QString data)
|
bool ImportController::extractConfigFromData(QString data)
|
||||||
{
|
{
|
||||||
QString config = data;
|
QString config = data;
|
||||||
m_configType = checkConfigFormat(config);
|
auto configFormat = checkConfigFormat(config);
|
||||||
if (m_configType == ConfigTypes::Invalid) {
|
if (configFormat == ConfigTypes::Invalid) {
|
||||||
data.replace("vpn://", "");
|
data.replace("vpn://", "");
|
||||||
QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
QByteArray ba =
|
||||||
|
QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
QByteArray ba_uncompressed = qUncompress(ba);
|
QByteArray ba_uncompressed = qUncompress(ba);
|
||||||
if (!ba_uncompressed.isEmpty()) {
|
if (!ba_uncompressed.isEmpty()) {
|
||||||
ba = ba_uncompressed;
|
ba = ba_uncompressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
config = ba;
|
config = ba;
|
||||||
m_configType = checkConfigFormat(config);
|
configFormat = checkConfigFormat(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (m_configType) {
|
switch (configFormat) {
|
||||||
case ConfigTypes::OpenVpn: {
|
case ConfigTypes::OpenVpn: {
|
||||||
m_config = extractOpenVpnConfig(config);
|
m_config = extractOpenVpnConfig(config);
|
||||||
return m_config.empty() ? false : true;
|
return m_config.empty() ? false : true;
|
||||||
}
|
}
|
||||||
case ConfigTypes::Awg:
|
|
||||||
case ConfigTypes::WireGuard: {
|
case ConfigTypes::WireGuard: {
|
||||||
m_config = extractWireGuardConfig(config);
|
m_config = extractWireGuardConfig(config);
|
||||||
return m_config.empty() ? false : true;
|
return m_config.empty() ? false : true;
|
||||||
@@ -161,39 +166,6 @@ QString ImportController::getConfigFileName()
|
|||||||
return m_configFileName;
|
return m_configFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImportController::isNativeWireGuardConfig()
|
|
||||||
{
|
|
||||||
return m_configType == ConfigTypes::WireGuard;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportController::processNativeWireGuardConfig()
|
|
||||||
{
|
|
||||||
auto containers = m_config.value(config_key::containers).toArray();
|
|
||||||
if (!containers.isEmpty()) {
|
|
||||||
auto container = containers.at(0).toObject();
|
|
||||||
auto containerConfig = container.value(ContainerProps::containerTypeToString(DockerContainer::WireGuard)).toObject();
|
|
||||||
auto protocolConfig = QJsonDocument::fromJson(containerConfig.value(config_key::last_config).toString().toUtf8()).object();
|
|
||||||
|
|
||||||
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(3, 10));
|
|
||||||
QString junkPacketMinSize = QString::number(50);
|
|
||||||
QString junkPacketMaxSize = QString::number(1000);
|
|
||||||
protocolConfig[config_key::junkPacketCount] = junkPacketCount;
|
|
||||||
protocolConfig[config_key::junkPacketMinSize] = junkPacketMinSize;
|
|
||||||
protocolConfig[config_key::junkPacketMaxSize] = junkPacketMaxSize;
|
|
||||||
protocolConfig[config_key::initPacketJunkSize] = "0";
|
|
||||||
protocolConfig[config_key::responsePacketJunkSize] = "0";
|
|
||||||
protocolConfig[config_key::initPacketMagicHeader] = "1";
|
|
||||||
protocolConfig[config_key::responsePacketMagicHeader] = "2";
|
|
||||||
protocolConfig[config_key::underloadPacketMagicHeader] = "3";
|
|
||||||
protocolConfig[config_key::transportPacketMagicHeader] = "4";
|
|
||||||
|
|
||||||
containerConfig[config_key::last_config] = QString(QJsonDocument(protocolConfig).toJson());
|
|
||||||
container["wireguard"] = containerConfig;
|
|
||||||
containers.replace(0, container);
|
|
||||||
m_config[config_key::containers] = containers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImportController::importConfig()
|
void ImportController::importConfig()
|
||||||
{
|
{
|
||||||
ServerCredentials credentials;
|
ServerCredentials credentials;
|
||||||
@@ -307,7 +279,8 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
|||||||
lastConfig[config_key::hostName] = hostName;
|
lastConfig[config_key::hostName] = hostName;
|
||||||
lastConfig[config_key::port] = port.toInt();
|
lastConfig[config_key::port] = port.toInt();
|
||||||
|
|
||||||
if (!configMap.value("PrivateKey").isEmpty() && !configMap.value("Address").isEmpty() && !configMap.value("PublicKey").isEmpty()) {
|
if (!configMap.value("PrivateKey").isEmpty() && !configMap.value("Address").isEmpty()
|
||||||
|
&& !configMap.value("PublicKey").isEmpty()) {
|
||||||
lastConfig[config_key::client_priv_key] = configMap.value("PrivateKey");
|
lastConfig[config_key::client_priv_key] = configMap.value("PrivateKey");
|
||||||
lastConfig[config_key::client_ip] = configMap.value("Address");
|
lastConfig[config_key::client_ip] = configMap.value("Address");
|
||||||
|
|
||||||
@@ -333,9 +306,12 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
|||||||
lastConfig[config_key::allowed_ips] = allowedIpsJsonArray;
|
lastConfig[config_key::allowed_ips] = allowedIpsJsonArray;
|
||||||
|
|
||||||
QString protocolName = "wireguard";
|
QString protocolName = "wireguard";
|
||||||
if (!configMap.value(config_key::junkPacketCount).isEmpty() && !configMap.value(config_key::junkPacketMinSize).isEmpty()
|
if (!configMap.value(config_key::junkPacketCount).isEmpty()
|
||||||
&& !configMap.value(config_key::junkPacketMaxSize).isEmpty() && !configMap.value(config_key::initPacketJunkSize).isEmpty()
|
&& !configMap.value(config_key::junkPacketMinSize).isEmpty()
|
||||||
&& !configMap.value(config_key::responsePacketJunkSize).isEmpty() && !configMap.value(config_key::initPacketMagicHeader).isEmpty()
|
&& !configMap.value(config_key::junkPacketMaxSize).isEmpty()
|
||||||
|
&& !configMap.value(config_key::initPacketJunkSize).isEmpty()
|
||||||
|
&& !configMap.value(config_key::responsePacketJunkSize).isEmpty()
|
||||||
|
&& !configMap.value(config_key::initPacketMagicHeader).isEmpty()
|
||||||
&& !configMap.value(config_key::responsePacketMagicHeader).isEmpty()
|
&& !configMap.value(config_key::responsePacketMagicHeader).isEmpty()
|
||||||
&& !configMap.value(config_key::underloadPacketMagicHeader).isEmpty()
|
&& !configMap.value(config_key::underloadPacketMagicHeader).isEmpty()
|
||||||
&& !configMap.value(config_key::transportPacketMagicHeader).isEmpty()) {
|
&& !configMap.value(config_key::transportPacketMagicHeader).isEmpty()) {
|
||||||
@@ -349,7 +325,6 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
|||||||
lastConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader);
|
lastConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader);
|
||||||
lastConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader);
|
lastConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader);
|
||||||
protocolName = "awg";
|
protocolName = "awg";
|
||||||
m_configType = ConfigTypes::Awg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject wireguardConfig;
|
QJsonObject wireguardConfig;
|
||||||
|
|||||||
@@ -3,22 +3,11 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "containers/containers_defs.h"
|
||||||
|
#include "core/defs.h"
|
||||||
#include "ui/models/containers_model.h"
|
#include "ui/models/containers_model.h"
|
||||||
#include "ui/models/servers_model.h"
|
#include "ui/models/servers_model.h"
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
enum class ConfigTypes {
|
|
||||||
Amnezia,
|
|
||||||
OpenVpn,
|
|
||||||
WireGuard,
|
|
||||||
Awg,
|
|
||||||
Xray,
|
|
||||||
Backup,
|
|
||||||
Invalid
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class ImportController : public QObject
|
class ImportController : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -47,9 +36,6 @@ public slots:
|
|||||||
static bool decodeQrCode(const QString &code);
|
static bool decodeQrCode(const QString &code);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool isNativeWireGuardConfig();
|
|
||||||
void processNativeWireGuardConfig();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void importFinished();
|
void importFinished();
|
||||||
void importErrorOccurred(const QString &errorMessage, bool goToPageHome);
|
void importErrorOccurred(const QString &errorMessage, bool goToPageHome);
|
||||||
@@ -73,7 +59,6 @@ private:
|
|||||||
|
|
||||||
QJsonObject m_config;
|
QJsonObject m_config;
|
||||||
QString m_configFileName;
|
QString m_configFileName;
|
||||||
ConfigTypes m_configType;
|
|
||||||
|
|
||||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||||
QMap<int, QByteArray> m_qrCodeChunks;
|
QMap<int, QByteArray> m_qrCodeChunks;
|
||||||
|
|||||||
@@ -10,15 +10,11 @@
|
|||||||
#include "core/controllers/serverController.h"
|
#include "core/controllers/serverController.h"
|
||||||
#include "core/controllers/vpnConfigurationController.h"
|
#include "core/controllers/vpnConfigurationController.h"
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
#include "core/networkUtilities.h"
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
#include "core/networkUtilities.h"
|
||||||
|
#include "utilities.h"
|
||||||
#include "ui/models/protocols/awgConfigModel.h"
|
#include "ui/models/protocols/awgConfigModel.h"
|
||||||
#include "ui/models/protocols/wireguardConfigModel.h"
|
#include "ui/models/protocols/wireguardConfigModel.h"
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
#include <AmneziaVPN-Swift.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -89,20 +85,14 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||||||
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(3, 10));
|
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(3, 10));
|
||||||
QString junkPacketMinSize = QString::number(50);
|
QString junkPacketMinSize = QString::number(50);
|
||||||
QString junkPacketMaxSize = QString::number(1000);
|
QString junkPacketMaxSize = QString::number(1000);
|
||||||
|
QString initPacketJunkSize = QString::number(QRandomGenerator::global()->bounded(15, 150));
|
||||||
int s1 = QRandomGenerator::global()->bounded(15, 150);
|
QString responsePacketJunkSize = QString::number(QRandomGenerator::global()->bounded(15, 150));
|
||||||
int s2 = QRandomGenerator::global()->bounded(15, 150);
|
|
||||||
while (s1 + AwgConstant::messageInitiationSize == s2 + AwgConstant::messageResponseSize) {
|
|
||||||
s2 = QRandomGenerator::global()->bounded(15, 150);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString initPacketJunkSize = QString::number(s1);
|
|
||||||
QString responsePacketJunkSize = QString::number(s2);
|
|
||||||
|
|
||||||
QSet<QString> headersValue;
|
QSet<QString> headersValue;
|
||||||
while (headersValue.size() != 4) {
|
while (headersValue.size() != 4) {
|
||||||
|
|
||||||
auto max = (std::numeric_limits<qint32>::max)();
|
auto max = (std::numeric_limits<qint32>::max)();
|
||||||
headersValue.insert(QString::number(QRandomGenerator::global()->bounded(5, max)));
|
headersValue.insert(QString::number(QRandomGenerator::global()->bounded(1, max)));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto headersValueList = headersValue.values();
|
auto headersValueList = headersValue.values();
|
||||||
@@ -142,12 +132,12 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||||||
serverCredentials = qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
serverCredentials = qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
ServerController serverController(m_settings);
|
||||||
connect(serverController.get(), &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
|
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
|
||||||
connect(this, &InstallController::cancelInstallation, serverController.get(), &ServerController::cancelInstallation);
|
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
|
||||||
|
|
||||||
QMap<DockerContainer, QJsonObject> installedContainers;
|
QMap<DockerContainer, QJsonObject> installedContainers;
|
||||||
ErrorCode errorCode = getAlreadyInstalledContainers(serverCredentials, serverController, installedContainers);
|
ErrorCode errorCode = getAlreadyInstalledContainers(serverCredentials, installedContainers);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
@@ -156,7 +146,7 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||||||
QString finishMessage = "";
|
QString finishMessage = "";
|
||||||
|
|
||||||
if (!installedContainers.contains(container)) {
|
if (!installedContainers.contains(container)) {
|
||||||
errorCode = serverController->setupContainer(serverCredentials, container, config);
|
errorCode = serverController.setupContainer(serverCredentials, container, config);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
@@ -174,15 +164,14 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_shouldCreateServer) {
|
if (m_shouldCreateServer) {
|
||||||
installServer(container, installedContainers, serverCredentials, serverController, finishMessage);
|
installServer(container, installedContainers, serverCredentials, finishMessage);
|
||||||
} else {
|
} else {
|
||||||
installContainer(container, installedContainers, serverCredentials, serverController, finishMessage);
|
installContainer(container, installedContainers, serverCredentials, finishMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallController::installServer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
void InstallController::installServer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
||||||
const ServerCredentials &serverCredentials, const QSharedPointer<ServerController> &serverController,
|
const ServerCredentials &serverCredentials, QString &finishMessage)
|
||||||
QString &finishMessage)
|
|
||||||
{
|
{
|
||||||
if (installedContainers.size() > 1) {
|
if (installedContainers.size() > 1) {
|
||||||
finishMessage += tr("\nAdded containers that were already installed on the server");
|
finishMessage += tr("\nAdded containers that were already installed on the server");
|
||||||
@@ -196,13 +185,11 @@ void InstallController::installServer(const DockerContainer container, const QMa
|
|||||||
server.insert(config_key::description, m_settings->nextAvailableServerName());
|
server.insert(config_key::description, m_settings->nextAvailableServerName());
|
||||||
|
|
||||||
QJsonArray containerConfigs;
|
QJsonArray containerConfigs;
|
||||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||||
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
|
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
|
||||||
auto containerConfig = iterator.value();
|
auto containerConfig = iterator.value();
|
||||||
|
auto errorCode =
|
||||||
if (ContainerProps::isSupportedByCurrentPlatform(container)) {
|
vpnConfigurationController.createProtocolConfigForContainer(m_processedServerCredentials, iterator.key(), containerConfig);
|
||||||
auto errorCode = vpnConfigurationController.createProtocolConfigForContainer(m_processedServerCredentials, iterator.key(),
|
|
||||||
containerConfig);
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
@@ -210,14 +197,11 @@ void InstallController::installServer(const DockerContainer container, const QMa
|
|||||||
containerConfigs.append(containerConfig);
|
containerConfigs.append(containerConfig);
|
||||||
|
|
||||||
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
containerConfigs.append(containerConfig);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
server.insert(config_key::containers, containerConfigs);
|
server.insert(config_key::containers, containerConfigs);
|
||||||
@@ -229,20 +213,16 @@ void InstallController::installServer(const DockerContainer container, const QMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InstallController::installContainer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
void InstallController::installContainer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
||||||
const ServerCredentials &serverCredentials,
|
const ServerCredentials &serverCredentials, QString &finishMessage)
|
||||||
const QSharedPointer<ServerController> &serverController, QString &finishMessage)
|
|
||||||
{
|
{
|
||||||
bool isInstalledContainerAddedToGui = false;
|
bool isInstalledContainerAddedToGui = false;
|
||||||
|
|
||||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||||
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
|
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
|
||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key());
|
QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key());
|
||||||
if (containerConfig.isEmpty()) {
|
if (containerConfig.isEmpty()) {
|
||||||
containerConfig = iterator.value();
|
containerConfig = iterator.value();
|
||||||
|
auto errorCode = vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, iterator.key(), containerConfig);
|
||||||
if (ContainerProps::isSupportedByCurrentPlatform(container)) {
|
|
||||||
auto errorCode =
|
|
||||||
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, iterator.key(), containerConfig);
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
@@ -250,14 +230,11 @@ void InstallController::installContainer(const DockerContainer container, const
|
|||||||
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
|
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
|
||||||
|
|
||||||
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (container != iterator.key()) { // skip the newly installed container
|
if (container != iterator.key()) { // skip the newly installed container
|
||||||
isInstalledContainerAddedToGui = true;
|
isInstalledContainerAddedToGui = true;
|
||||||
@@ -292,39 +269,33 @@ void InstallController::scanServerForInstalledContainers()
|
|||||||
ServerCredentials serverCredentials =
|
ServerCredentials serverCredentials =
|
||||||
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||||
|
|
||||||
|
ServerController serverController(m_settings);
|
||||||
|
|
||||||
QMap<DockerContainer, QJsonObject> installedContainers;
|
QMap<DockerContainer, QJsonObject> installedContainers;
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
ErrorCode errorCode = getAlreadyInstalledContainers(serverCredentials, installedContainers);
|
||||||
ErrorCode errorCode = getAlreadyInstalledContainers(serverCredentials, serverController, installedContainers);
|
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
bool isInstalledContainerAddedToGui = false;
|
bool isInstalledContainerAddedToGui = false;
|
||||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||||
|
|
||||||
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
|
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
|
||||||
auto container = iterator.key();
|
QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key());
|
||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
|
||||||
if (containerConfig.isEmpty()) {
|
if (containerConfig.isEmpty()) {
|
||||||
containerConfig = iterator.value();
|
containerConfig = iterator.value();
|
||||||
|
|
||||||
if (ContainerProps::isSupportedByCurrentPlatform(container)) {
|
|
||||||
auto errorCode =
|
auto errorCode =
|
||||||
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, container, containerConfig);
|
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, iterator.key(), containerConfig);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_serversModel->addContainerConfig(container, containerConfig);
|
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
|
||||||
|
|
||||||
errorCode = m_clientManagementModel->appendClient(container, serverCredentials, containerConfig,
|
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()),
|
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||||
serverController);
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
m_serversModel->addContainerConfig(container, containerConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
isInstalledContainerAddedToGui = true;
|
isInstalledContainerAddedToGui = true;
|
||||||
}
|
}
|
||||||
@@ -338,7 +309,6 @@ void InstallController::scanServerForInstalledContainers()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentials &credentials,
|
ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentials &credentials,
|
||||||
const QSharedPointer<ServerController> &serverController,
|
|
||||||
QMap<DockerContainer, QJsonObject> &installedContainers)
|
QMap<DockerContainer, QJsonObject> &installedContainers)
|
||||||
{
|
{
|
||||||
QString stdOut;
|
QString stdOut;
|
||||||
@@ -351,9 +321,10 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
|||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ServerController serverController(m_settings);
|
||||||
QString script = QString("sudo docker ps --format '{{.Names}} {{.Ports}}'");
|
QString script = QString("sudo docker ps --format '{{.Names}} {{.Ports}}'");
|
||||||
|
|
||||||
ErrorCode errorCode = serverController->runScript(credentials, script, cbReadStdOut, cbReadStdErr);
|
ErrorCode errorCode = serverController.runScript(credentials, script, cbReadStdOut, cbReadStdErr);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
@@ -380,7 +351,7 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
|||||||
containerConfig.insert(config_key::transport_proto, transportProto);
|
containerConfig.insert(config_key::transport_proto, transportProto);
|
||||||
|
|
||||||
if (protocol == Proto::Awg) {
|
if (protocol == Proto::Awg) {
|
||||||
QString serverConfig = serverController->getTextFileFromContainer(container, credentials,
|
QString serverConfig = serverController.getTextFileFromContainer(container, credentials,
|
||||||
protocols::awg::serverConfigPath, errorCode);
|
protocols::awg::serverConfigPath, errorCode);
|
||||||
|
|
||||||
QMap<QString, QString> serverConfigMap;
|
QMap<QString, QString> serverConfigMap;
|
||||||
@@ -412,7 +383,7 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
|||||||
stdOut.clear();
|
stdOut.clear();
|
||||||
script = QString("sudo docker inspect --format '{{.Config.Cmd}}' %1").arg(name);
|
script = QString("sudo docker inspect --format '{{.Config.Cmd}}' %1").arg(name);
|
||||||
|
|
||||||
ErrorCode errorCode = serverController->runScript(credentials, script, cbReadStdOut, cbReadStdErr);
|
ErrorCode errorCode = serverController.runScript(credentials, script, cbReadStdOut, cbReadStdErr);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
@@ -456,7 +427,7 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
|||||||
stdOut.clear();
|
stdOut.clear();
|
||||||
script = QString("sudo docker exec -i %1 sh -c 'cat /var/lib/tor/hidden_service/hostname'").arg(name);
|
script = QString("sudo docker exec -i %1 sh -c 'cat /var/lib/tor/hidden_service/hostname'").arg(name);
|
||||||
|
|
||||||
ErrorCode errorCode = serverController->runScript(credentials, script, cbReadStdOut, cbReadStdErr);
|
ErrorCode errorCode = serverController.runScript(credentials, script, cbReadStdOut, cbReadStdErr);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
@@ -493,12 +464,12 @@ void InstallController::updateContainer(QJsonObject config)
|
|||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
if (isUpdateDockerContainerRequired(container, oldContainerConfig, config)) {
|
if (isUpdateDockerContainerRequired(container, oldContainerConfig, config)) {
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
ServerController serverController(m_settings);
|
||||||
connect(serverController.get(), &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
|
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
|
||||||
connect(this, &InstallController::cancelInstallation, serverController.get(), &ServerController::cancelInstallation);
|
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
|
||||||
|
|
||||||
errorCode = serverController->updateContainer(serverCredentials, container, oldContainerConfig, config);
|
errorCode = serverController.updateContainer(serverCredentials, container, oldContainerConfig, config);
|
||||||
clearCachedProfile(serverController);
|
clearCachedProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
@@ -523,13 +494,8 @@ void InstallController::rebootProcessedServer()
|
|||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
int serverIndex = m_serversModel->getProcessedServerIndex();
|
||||||
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
|
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
|
||||||
|
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
m_serversModel->rebootServer();
|
||||||
const auto errorCode = m_serversModel->rebootServer(serverController);
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
|
||||||
emit rebootProcessedServerFinished(tr("Server '%1' was rebooted").arg(serverName));
|
emit rebootProcessedServerFinished(tr("Server '%1' was rebooted").arg(serverName));
|
||||||
} else {
|
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallController::removeProcessedServer()
|
void InstallController::removeProcessedServer()
|
||||||
@@ -546,8 +512,7 @@ void InstallController::removeAllContainers()
|
|||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
int serverIndex = m_serversModel->getProcessedServerIndex();
|
||||||
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
|
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
|
||||||
|
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
ErrorCode errorCode = m_serversModel->removeAllContainers();
|
||||||
ErrorCode errorCode = m_serversModel->removeAllContainers(serverController);
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
emit removeAllContainersFinished(tr("All containers from server '%1' have been removed").arg(serverName));
|
emit removeAllContainersFinished(tr("All containers from server '%1' have been removed").arg(serverName));
|
||||||
return;
|
return;
|
||||||
@@ -563,8 +528,7 @@ void InstallController::removeProcessedContainer()
|
|||||||
int container = m_containersModel->getProcessedContainerIndex();
|
int container = m_containersModel->getProcessedContainerIndex();
|
||||||
QString containerName = m_containersModel->getProcessedContainerName();
|
QString containerName = m_containersModel->getProcessedContainerName();
|
||||||
|
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
ErrorCode errorCode = m_serversModel->removeContainer(container);
|
||||||
ErrorCode errorCode = m_serversModel->removeContainer(serverController, container);
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
|
|
||||||
emit removeProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName, serverName));
|
emit removeProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName, serverName));
|
||||||
@@ -573,18 +537,9 @@ void InstallController::removeProcessedContainer()
|
|||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallController::removeApiConfig(const int serverIndex)
|
void InstallController::removeApiConfig()
|
||||||
{
|
{
|
||||||
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
auto serverConfig = m_serversModel->getServerConfig(m_serversModel->getDefaultServerIndex());
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
QString vpncName = QString("%1 (%2) %3")
|
|
||||||
.arg(serverConfig[config_key::description].toString())
|
|
||||||
.arg(serverConfig[config_key::hostName].toString())
|
|
||||||
.arg(serverConfig[config_key::vpnproto].toString());
|
|
||||||
|
|
||||||
AmneziaVPN::removeVPNC(vpncName.toStdString());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
serverConfig.remove(config_key::dns1);
|
serverConfig.remove(config_key::dns1);
|
||||||
serverConfig.remove(config_key::dns2);
|
serverConfig.remove(config_key::dns2);
|
||||||
@@ -593,15 +548,11 @@ void InstallController::removeApiConfig(const int serverIndex)
|
|||||||
|
|
||||||
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
|
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
|
||||||
|
|
||||||
m_serversModel->editServer(serverConfig, serverIndex);
|
m_serversModel->editServer(serverConfig, m_serversModel->getDefaultServerIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallController::clearCachedProfile(QSharedPointer<ServerController> serverController)
|
void InstallController::clearCachedProfile()
|
||||||
{
|
{
|
||||||
if (serverController.isNull()) {
|
|
||||||
serverController.reset(new ServerController(m_settings));
|
|
||||||
}
|
|
||||||
|
|
||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
int serverIndex = m_serversModel->getProcessedServerIndex();
|
||||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getProcessedContainerIndex());
|
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getProcessedContainerIndex());
|
||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||||
@@ -609,7 +560,7 @@ void InstallController::clearCachedProfile(QSharedPointer<ServerController> serv
|
|||||||
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||||
|
|
||||||
m_serversModel->clearCachedProfile(container);
|
m_serversModel->clearCachedProfile(container);
|
||||||
m_clientManagementModel->revokeClient(containerConfig, container, serverCredentials, serverIndex, serverController);
|
m_clientManagementModel->revokeClient(containerConfig, container, serverCredentials, serverIndex);
|
||||||
|
|
||||||
emit cachedProfileCleared(tr("%1 cached profile cleared").arg(ContainerProps::containerHumanNames().value(container)));
|
emit cachedProfileCleared(tr("%1 cached profile cleared").arg(ContainerProps::containerHumanNames().value(container)));
|
||||||
}
|
}
|
||||||
@@ -711,15 +662,13 @@ void InstallController::mountSftpDrive(const QString &port, const QString &passw
|
|||||||
process->write((password + "\n").toUtf8());
|
process->write((password + "\n").toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InstallController::checkSshConnection(QSharedPointer<ServerController> serverController)
|
bool InstallController::checkSshConnection()
|
||||||
{
|
{
|
||||||
if (serverController.isNull()) {
|
ServerController serverController(m_settings);
|
||||||
serverController.reset(new ServerController(m_settings));
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
m_privateKeyPassphrase = "";
|
m_privateKeyPassphrase = "";
|
||||||
|
|
||||||
@@ -734,7 +683,7 @@ bool InstallController::checkSshConnection(QSharedPointer<ServerController> serv
|
|||||||
};
|
};
|
||||||
|
|
||||||
QString decryptedPrivateKey;
|
QString decryptedPrivateKey;
|
||||||
errorCode = serverController->getDecryptedPrivateKey(m_processedServerCredentials, decryptedPrivateKey, passphraseCallback);
|
errorCode = serverController.getDecryptedPrivateKey(m_processedServerCredentials, decryptedPrivateKey, passphraseCallback);
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
m_processedServerCredentials.secretData = decryptedPrivateKey;
|
m_processedServerCredentials.secretData = decryptedPrivateKey;
|
||||||
} else {
|
} else {
|
||||||
@@ -744,7 +693,7 @@ bool InstallController::checkSshConnection(QSharedPointer<ServerController> serv
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString output;
|
QString output;
|
||||||
output = serverController->checkSshConnection(m_processedServerCredentials, errorCode);
|
output = serverController.checkSshConnection(m_processedServerCredentials, errorCode);
|
||||||
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
@@ -781,8 +730,7 @@ void InstallController::addEmptyServer()
|
|||||||
emit installServerFinished(tr("Server added successfully"));
|
emit installServerFinished(tr("Server added successfully"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InstallController::isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig,
|
bool InstallController::isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig)
|
||||||
const QJsonObject &newConfig)
|
|
||||||
{
|
{
|
||||||
Proto mainProto = ContainerProps::defaultProtocol(container);
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
|
|
||||||
|
|||||||
@@ -35,16 +35,16 @@ public slots:
|
|||||||
void removeAllContainers();
|
void removeAllContainers();
|
||||||
void removeProcessedContainer();
|
void removeProcessedContainer();
|
||||||
|
|
||||||
void removeApiConfig(const int serverIndex);
|
void removeApiConfig();
|
||||||
|
|
||||||
void clearCachedProfile(QSharedPointer<ServerController> serverController = nullptr);
|
void clearCachedProfile();
|
||||||
|
|
||||||
QRegularExpression ipAddressPortRegExp();
|
QRegularExpression ipAddressPortRegExp();
|
||||||
QRegularExpression ipAddressRegExp();
|
QRegularExpression ipAddressRegExp();
|
||||||
|
|
||||||
void mountSftpDrive(const QString &port, const QString &password, const QString &username);
|
void mountSftpDrive(const QString &port, const QString &password, const QString &username);
|
||||||
|
|
||||||
bool checkSshConnection(QSharedPointer<ServerController> serverController = nullptr);
|
bool checkSshConnection();
|
||||||
|
|
||||||
void setEncryptedPassphrase(QString passphrase);
|
void setEncryptedPassphrase(QString passphrase);
|
||||||
|
|
||||||
@@ -79,15 +79,12 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void installServer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
void installServer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
||||||
const ServerCredentials &serverCredentials, const QSharedPointer<ServerController> &serverController,
|
const ServerCredentials &serverCredentials, QString &finishMessage);
|
||||||
QString &finishMessage);
|
|
||||||
void installContainer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
void installContainer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
||||||
const ServerCredentials &serverCredentials, const QSharedPointer<ServerController> &serverController,
|
const ServerCredentials &serverCredentials, QString &finishMessage);
|
||||||
QString &finishMessage);
|
|
||||||
bool isServerAlreadyExists();
|
bool isServerAlreadyExists();
|
||||||
|
|
||||||
ErrorCode getAlreadyInstalledContainers(const ServerCredentials &credentials, const QSharedPointer<ServerController> &serverController,
|
ErrorCode getAlreadyInstalledContainers(const ServerCredentials &credentials, QMap<DockerContainer, QJsonObject> &installedContainers);
|
||||||
QMap<DockerContainer, QJsonObject> &installedContainers);
|
|
||||||
bool isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig);
|
bool isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig);
|
||||||
|
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
|
|||||||
@@ -123,9 +123,6 @@ signals:
|
|||||||
void escapePressed();
|
void escapePressed();
|
||||||
void closeTopDrawer();
|
void closeTopDrawer();
|
||||||
|
|
||||||
void forceTabBarActiveFocus();
|
|
||||||
void forceStackActiveFocus();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
|
|
||||||
|
|||||||
@@ -18,14 +18,12 @@ SettingsController::SettingsController(const QSharedPointer<ServersModel> &serve
|
|||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<LanguageModel> &languageModel,
|
const QSharedPointer<LanguageModel> &languageModel,
|
||||||
const QSharedPointer<SitesModel> &sitesModel,
|
const QSharedPointer<SitesModel> &sitesModel,
|
||||||
const QSharedPointer<AppSplitTunnelingModel> &appSplitTunnelingModel,
|
|
||||||
const std::shared_ptr<Settings> &settings, QObject *parent)
|
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
m_serversModel(serversModel),
|
m_serversModel(serversModel),
|
||||||
m_containersModel(containersModel),
|
m_containersModel(containersModel),
|
||||||
m_languageModel(languageModel),
|
m_languageModel(languageModel),
|
||||||
m_sitesModel(sitesModel),
|
m_sitesModel(sitesModel),
|
||||||
m_appSplitTunnelingModel(appSplitTunnelingModel),
|
|
||||||
m_settings(settings)
|
m_settings(settings)
|
||||||
{
|
{
|
||||||
m_appVersion = QString("%1 (%2, %3)").arg(QString(APP_VERSION), __DATE__, GIT_COMMIT_HASH);
|
m_appVersion = QString("%1 (%2, %3)").arg(QString(APP_VERSION), __DATE__, GIT_COMMIT_HASH);
|
||||||
@@ -77,8 +75,7 @@ void SettingsController::toggleLogging(bool enable)
|
|||||||
AmneziaVPN::toggleLogging(enable);
|
AmneziaVPN::toggleLogging(enable);
|
||||||
#endif
|
#endif
|
||||||
if (enable == true) {
|
if (enable == true) {
|
||||||
qInfo().noquote() << QString("Logging has enabled on %1 version %2 %3").arg(APPLICATION_NAME, APP_VERSION, GIT_COMMIT_HASH);
|
checkIfNeedDisableLogs();
|
||||||
qInfo().noquote() << QString("%1 (%2)").arg(QSysInfo::prettyProductName(), QSysInfo::currentCpuArchitecture());
|
|
||||||
}
|
}
|
||||||
emit loggingStateChanged();
|
emit loggingStateChanged();
|
||||||
}
|
}
|
||||||
@@ -147,12 +144,7 @@ void SettingsController::clearSettings()
|
|||||||
m_serversModel->resetModel();
|
m_serversModel->resetModel();
|
||||||
m_languageModel->changeLanguage(
|
m_languageModel->changeLanguage(
|
||||||
static_cast<LanguageSettings::AvailableLanguageEnum>(m_languageModel->getCurrentLanguageIndex()));
|
static_cast<LanguageSettings::AvailableLanguageEnum>(m_languageModel->getCurrentLanguageIndex()));
|
||||||
|
m_sitesModel->setRouteMode(Settings::RouteMode::VpnAllSites);
|
||||||
m_sitesModel->setRouteMode(Settings::RouteMode::VpnOnlyForwardSites);
|
|
||||||
m_sitesModel->toggleSplitTunneling(false);
|
|
||||||
|
|
||||||
m_appSplitTunnelingModel->setRouteMode(Settings::AppsRouteMode::VpnAllExceptApps);
|
|
||||||
m_appSplitTunnelingModel->toggleSplitTunneling(false);
|
|
||||||
|
|
||||||
emit changeSettingsFinished(tr("All settings have been reset to default values"));
|
emit changeSettingsFinished(tr("All settings have been reset to default values"));
|
||||||
|
|
||||||
@@ -214,12 +206,10 @@ bool SettingsController::isCameraPresent()
|
|||||||
|
|
||||||
void SettingsController::checkIfNeedDisableLogs()
|
void SettingsController::checkIfNeedDisableLogs()
|
||||||
{
|
{
|
||||||
if (m_settings->isSaveLogs()) {
|
|
||||||
m_loggingDisableDate = m_settings->getLogEnableDate().addDays(14);
|
m_loggingDisableDate = m_settings->getLogEnableDate().addDays(14);
|
||||||
if (m_loggingDisableDate <= QDateTime::currentDateTime()) {
|
if (m_loggingDisableDate <= QDateTime::currentDateTime()) {
|
||||||
toggleLogging(false);
|
toggleLogging(false);
|
||||||
clearLogs();
|
clearLogs();
|
||||||
emit loggingDisableByWatcher();
|
emit loggingDisableByWatcher();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include "ui/models/languageModel.h"
|
#include "ui/models/languageModel.h"
|
||||||
#include "ui/models/servers_model.h"
|
#include "ui/models/servers_model.h"
|
||||||
#include "ui/models/sites_model.h"
|
#include "ui/models/sites_model.h"
|
||||||
#include "ui/models/appSplitTunnelingModel.h"
|
|
||||||
|
|
||||||
class SettingsController : public QObject
|
class SettingsController : public QObject
|
||||||
{
|
{
|
||||||
@@ -17,7 +16,6 @@ public:
|
|||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<LanguageModel> &languageModel,
|
const QSharedPointer<LanguageModel> &languageModel,
|
||||||
const QSharedPointer<SitesModel> &sitesModel,
|
const QSharedPointer<SitesModel> &sitesModel,
|
||||||
const QSharedPointer<AppSplitTunnelingModel> &appSplitTunnelingModel,
|
|
||||||
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
Q_PROPERTY(QString primaryDns READ getPrimaryDns WRITE setPrimaryDns NOTIFY primaryDnsChanged)
|
Q_PROPERTY(QString primaryDns READ getPrimaryDns WRITE setPrimaryDns NOTIFY primaryDnsChanged)
|
||||||
@@ -85,7 +83,6 @@ private:
|
|||||||
QSharedPointer<ContainersModel> m_containersModel;
|
QSharedPointer<ContainersModel> m_containersModel;
|
||||||
QSharedPointer<LanguageModel> m_languageModel;
|
QSharedPointer<LanguageModel> m_languageModel;
|
||||||
QSharedPointer<SitesModel> m_sitesModel;
|
QSharedPointer<SitesModel> m_sitesModel;
|
||||||
QSharedPointer<AppSplitTunnelingModel> m_appSplitTunnelingModel;
|
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
|
|
||||||
QString m_appVersion;
|
QString m_appVersion;
|
||||||
|
|||||||
@@ -5,11 +5,13 @@
|
|||||||
AppSplitTunnelingModel::AppSplitTunnelingModel(std::shared_ptr<Settings> settings, QObject *parent)
|
AppSplitTunnelingModel::AppSplitTunnelingModel(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
: QAbstractListModel(parent), m_settings(settings)
|
: QAbstractListModel(parent), m_settings(settings)
|
||||||
{
|
{
|
||||||
m_isSplitTunnelingEnabled = m_settings->getAppsSplitTunnelingEnabled();
|
auto routeMode = m_settings->getAppsRouteMode();
|
||||||
m_currentRouteMode = m_settings->getAppsRouteMode();
|
if (routeMode == Settings::AppsRouteMode::VpnAllApps) {
|
||||||
if (m_currentRouteMode == Settings::VpnAllApps) { // for old split tunneling configs
|
m_isSplitTunnelingEnabled = false;
|
||||||
m_settings->setAppsRouteMode(static_cast<Settings::AppsRouteMode>(Settings::VpnAllExceptApps));
|
m_currentRouteMode = Settings::AppsRouteMode::VpnAllExceptApps;
|
||||||
m_currentRouteMode = Settings::VpnAllExceptApps;
|
} else {
|
||||||
|
m_isSplitTunnelingEnabled = true;
|
||||||
|
m_currentRouteMode = routeMode;
|
||||||
}
|
}
|
||||||
m_apps = m_settings->getVpnApps(m_currentRouteMode);
|
m_apps = m_settings->getVpnApps(m_currentRouteMode);
|
||||||
}
|
}
|
||||||
@@ -82,7 +84,11 @@ bool AppSplitTunnelingModel::isSplitTunnelingEnabled()
|
|||||||
|
|
||||||
void AppSplitTunnelingModel::toggleSplitTunneling(bool enabled)
|
void AppSplitTunnelingModel::toggleSplitTunneling(bool enabled)
|
||||||
{
|
{
|
||||||
m_settings->setAppsSplitTunnelingEnabled(enabled);
|
if (enabled) {
|
||||||
|
setRouteMode(m_currentRouteMode);
|
||||||
|
} else {
|
||||||
|
m_settings->setAppsRouteMode(Settings::AppsRouteMode::VpnAllApps);
|
||||||
|
}
|
||||||
m_isSplitTunnelingEnabled = enabled;
|
m_isSplitTunnelingEnabled = enabled;
|
||||||
emit splitTunnelingToggled();
|
emit splitTunnelingToggled();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,12 +64,13 @@ void ClientManagementModel::migration(const QByteArray &clientsTableString)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::updateModel(const DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCredentials credentials)
|
||||||
const QSharedPointer<ServerController> &serverController)
|
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_clientsTable = QJsonArray();
|
m_clientsTable = QJsonArray();
|
||||||
|
|
||||||
|
ServerController serverController(m_settings);
|
||||||
|
|
||||||
ErrorCode error = ErrorCode::NoError;
|
ErrorCode error = ErrorCode::NoError;
|
||||||
|
|
||||||
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
||||||
@@ -79,7 +80,7 @@ ErrorCode ClientManagementModel::updateModel(const DockerContainer container, co
|
|||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray clientsTableString = serverController->getTextFileFromContainer(container, credentials, clientsTableFile, error);
|
const QByteArray clientsTableString = serverController.getTextFileFromContainer(container, credentials, clientsTableFile, error);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to get the clientsTable file from the server";
|
logger.error() << "Failed to get the clientsTable file from the server";
|
||||||
endResetModel();
|
endResetModel();
|
||||||
@@ -94,9 +95,9 @@ ErrorCode ClientManagementModel::updateModel(const DockerContainer container, co
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
error = getOpenVpnClients(container, credentials, serverController, count);
|
error = getOpenVpnClients(serverController, container, credentials, count);
|
||||||
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||||
error = getWireGuardClients(container, credentials, serverController, count);
|
error = getWireGuardClients(serverController, container, credentials, count);
|
||||||
}
|
}
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
endResetModel();
|
endResetModel();
|
||||||
@@ -105,7 +106,7 @@ ErrorCode ClientManagementModel::updateModel(const DockerContainer container, co
|
|||||||
|
|
||||||
const QByteArray newClientsTableString = QJsonDocument(m_clientsTable).toJson();
|
const QByteArray newClientsTableString = QJsonDocument(m_clientsTable).toJson();
|
||||||
if (clientsTableString != newClientsTableString) {
|
if (clientsTableString != newClientsTableString) {
|
||||||
error = serverController->uploadTextFileToContainer(container, credentials, newClientsTableString, clientsTableFile);
|
error = serverController.uploadTextFileToContainer(container, credentials, newClientsTableString, clientsTableFile);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to upload the clientsTable file to the server";
|
logger.error() << "Failed to upload the clientsTable file to the server";
|
||||||
}
|
}
|
||||||
@@ -116,8 +117,8 @@ ErrorCode ClientManagementModel::updateModel(const DockerContainer container, co
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::getOpenVpnClients(const DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode ClientManagementModel::getOpenVpnClients(ServerController &serverController, DockerContainer container,
|
||||||
const QSharedPointer<ServerController> &serverController, int &count)
|
ServerCredentials credentials, int &count)
|
||||||
{
|
{
|
||||||
ErrorCode error = ErrorCode::NoError;
|
ErrorCode error = ErrorCode::NoError;
|
||||||
QString stdOut;
|
QString stdOut;
|
||||||
@@ -127,8 +128,8 @@ ErrorCode ClientManagementModel::getOpenVpnClients(const DockerContainer contain
|
|||||||
};
|
};
|
||||||
|
|
||||||
const QString getOpenVpnClientsList = "sudo docker exec -i $CONTAINER_NAME bash -c 'ls /opt/amnezia/openvpn/pki/issued'";
|
const QString getOpenVpnClientsList = "sudo docker exec -i $CONTAINER_NAME bash -c 'ls /opt/amnezia/openvpn/pki/issued'";
|
||||||
QString script = serverController->replaceVars(getOpenVpnClientsList, serverController->genVarsForScript(credentials, container));
|
QString script = serverController.replaceVars(getOpenVpnClientsList, serverController.genVarsForScript(credentials, container));
|
||||||
error = serverController->runScript(credentials, script, cbReadStdOut);
|
error = serverController.runScript(credentials, script, cbReadStdOut);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to retrieve the list of issued certificates on the server";
|
logger.error() << "Failed to retrieve the list of issued certificates on the server";
|
||||||
return error;
|
return error;
|
||||||
@@ -157,13 +158,13 @@ ErrorCode ClientManagementModel::getOpenVpnClients(const DockerContainer contain
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::getWireGuardClients(const DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode ClientManagementModel::getWireGuardClients(ServerController &serverController, DockerContainer container,
|
||||||
const QSharedPointer<ServerController> &serverController, int &count)
|
ServerCredentials credentials, int &count)
|
||||||
{
|
{
|
||||||
ErrorCode error = ErrorCode::NoError;
|
ErrorCode error = ErrorCode::NoError;
|
||||||
|
|
||||||
const QString wireGuardConfigFile = QString("opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg");
|
const QString wireGuardConfigFile = QString("opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg");
|
||||||
const QString wireguardConfigString = serverController->getTextFileFromContainer(container, credentials, wireGuardConfigFile, error);
|
const QString wireguardConfigString = serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, error);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to get the wg conf file from the server";
|
logger.error() << "Failed to get the wg conf file from the server";
|
||||||
return error;
|
return error;
|
||||||
@@ -197,7 +198,7 @@ ErrorCode ClientManagementModel::getWireGuardClients(const DockerContainer conta
|
|||||||
|
|
||||||
bool ClientManagementModel::isClientExists(const QString &clientId)
|
bool ClientManagementModel::isClientExists(const QString &clientId)
|
||||||
{
|
{
|
||||||
for (const QJsonValue &value : std::as_const(m_clientsTable)) {
|
for (const QJsonValue &value : qAsConst(m_clientsTable)) {
|
||||||
if (value.isObject()) {
|
if (value.isObject()) {
|
||||||
QJsonObject obj = value.toObject();
|
QJsonObject obj = value.toObject();
|
||||||
if (obj.contains(configKey::clientId) && obj[configKey::clientId].toString() == clientId) {
|
if (obj.contains(configKey::clientId) && obj[configKey::clientId].toString() == clientId) {
|
||||||
@@ -209,8 +210,7 @@ bool ClientManagementModel::isClientExists(const QString &clientId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::appendClient(const DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode ClientManagementModel::appendClient(const DockerContainer container, const ServerCredentials &credentials,
|
||||||
const QJsonObject &containerConfig, const QString &clientName,
|
const QJsonObject &containerConfig, const QString &clientName)
|
||||||
const QSharedPointer<ServerController> &serverController)
|
|
||||||
{
|
{
|
||||||
Proto protocol;
|
Proto protocol;
|
||||||
if (container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
if (container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
@@ -223,22 +223,22 @@ ErrorCode ClientManagementModel::appendClient(const DockerContainer container, c
|
|||||||
|
|
||||||
auto protocolConfig = ContainerProps::getProtocolConfigFromContainer(protocol, containerConfig);
|
auto protocolConfig = ContainerProps::getProtocolConfigFromContainer(protocol, containerConfig);
|
||||||
|
|
||||||
return appendClient(protocolConfig.value(config_key::clientId).toString(), clientName, container, credentials, serverController);
|
return appendClient(protocolConfig.value(config_key::clientId).toString(), clientName, container, credentials);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QString &clientName, const DockerContainer container,
|
ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QString &clientName, const DockerContainer container,
|
||||||
const ServerCredentials &credentials, const QSharedPointer<ServerController> &serverController)
|
ServerCredentials credentials)
|
||||||
{
|
{
|
||||||
ErrorCode error = ErrorCode::NoError;
|
ErrorCode error = ErrorCode::NoError;
|
||||||
|
|
||||||
error = updateModel(container, credentials, serverController);
|
error = updateModel(container, credentials);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < m_clientsTable.size(); i++) {
|
for (int i = 0; i < m_clientsTable.size(); i++) {
|
||||||
if (m_clientsTable.at(i).toObject().value(configKey::clientId) == clientId) {
|
if (m_clientsTable.at(i).toObject().value(configKey::clientId) == clientId) {
|
||||||
return renameClient(i, clientName, container, credentials, serverController, true);
|
return renameClient(i, clientName, container, credentials, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,6 +255,7 @@ ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QSt
|
|||||||
|
|
||||||
const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
|
const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
|
||||||
|
|
||||||
|
ServerController serverController(m_settings);
|
||||||
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
||||||
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
||||||
@@ -262,7 +263,7 @@ ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QSt
|
|||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
||||||
}
|
}
|
||||||
|
|
||||||
error = serverController->uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
error = serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to upload the clientsTable file to the server";
|
logger.error() << "Failed to upload the clientsTable file to the server";
|
||||||
}
|
}
|
||||||
@@ -271,8 +272,7 @@ ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::renameClient(const int row, const QString &clientName, const DockerContainer container,
|
ErrorCode ClientManagementModel::renameClient(const int row, const QString &clientName, const DockerContainer container,
|
||||||
const ServerCredentials &credentials,
|
ServerCredentials credentials, bool addTimeStamp)
|
||||||
const QSharedPointer<ServerController> &serverController, bool addTimeStamp)
|
|
||||||
{
|
{
|
||||||
auto client = m_clientsTable.at(row).toObject();
|
auto client = m_clientsTable.at(row).toObject();
|
||||||
auto userData = client[configKey::userData].toObject();
|
auto userData = client[configKey::userData].toObject();
|
||||||
@@ -287,6 +287,7 @@ ErrorCode ClientManagementModel::renameClient(const int row, const QString &clie
|
|||||||
|
|
||||||
const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
|
const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
|
||||||
|
|
||||||
|
ServerController serverController(m_settings);
|
||||||
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
||||||
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
||||||
@@ -294,7 +295,7 @@ ErrorCode ClientManagementModel::renameClient(const int row, const QString &clie
|
|||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode error = serverController->uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
ErrorCode error = serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to upload the clientsTable file to the server";
|
logger.error() << "Failed to upload the clientsTable file to the server";
|
||||||
}
|
}
|
||||||
@@ -302,17 +303,17 @@ ErrorCode ClientManagementModel::renameClient(const int row, const QString &clie
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::revokeClient(const int row, const DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode ClientManagementModel::revokeClient(const int row, const DockerContainer container, ServerCredentials credentials,
|
||||||
const int serverIndex, const QSharedPointer<ServerController> &serverController)
|
const int serverIndex)
|
||||||
{
|
{
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
auto client = m_clientsTable.at(row).toObject();
|
auto client = m_clientsTable.at(row).toObject();
|
||||||
QString clientId = client.value(configKey::clientId).toString();
|
QString clientId = client.value(configKey::clientId).toString();
|
||||||
|
|
||||||
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
errorCode = revokeOpenVpn(row, container, credentials, serverIndex, serverController);
|
errorCode = revokeOpenVpn(row, container, credentials, serverIndex);
|
||||||
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||||
errorCode = revokeWireGuard(row, container, credentials, serverController);
|
errorCode = revokeWireGuard(row, container, credentials);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
@@ -339,12 +340,11 @@ ErrorCode ClientManagementModel::revokeClient(const int row, const DockerContain
|
|||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::revokeClient(const QJsonObject &containerConfig, const DockerContainer container,
|
ErrorCode ClientManagementModel::revokeClient(const QJsonObject &containerConfig, const DockerContainer container, ServerCredentials credentials,
|
||||||
const ServerCredentials &credentials, const int serverIndex,
|
const int serverIndex)
|
||||||
const QSharedPointer<ServerController> &serverController)
|
|
||||||
{
|
{
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
errorCode = updateModel(container, credentials, serverController);
|
errorCode = updateModel(container, credentials);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
@@ -375,15 +375,15 @@ ErrorCode ClientManagementModel::revokeClient(const QJsonObject &containerConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
errorCode = revokeOpenVpn(row, container, credentials, serverIndex, serverController);
|
errorCode = revokeOpenVpn(row, container, credentials, serverIndex);
|
||||||
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||||
errorCode = revokeWireGuard(row, container, credentials, serverController);
|
errorCode = revokeWireGuard(row, container, credentials);
|
||||||
}
|
}
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContainer container, ServerCredentials credentials,
|
||||||
const int serverIndex, const QSharedPointer<ServerController> &serverController)
|
const int serverIndex)
|
||||||
{
|
{
|
||||||
auto client = m_clientsTable.at(row).toObject();
|
auto client = m_clientsTable.at(row).toObject();
|
||||||
QString clientId = client.value(configKey::clientId).toString();
|
QString clientId = client.value(configKey::clientId).toString();
|
||||||
@@ -396,8 +396,9 @@ ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContai
|
|||||||
"cp pki/crl.pem .'")
|
"cp pki/crl.pem .'")
|
||||||
.arg(clientId);
|
.arg(clientId);
|
||||||
|
|
||||||
const QString script = serverController->replaceVars(getOpenVpnCertData, serverController->genVarsForScript(credentials, container));
|
ServerController serverController(m_settings);
|
||||||
ErrorCode error = serverController->runScript(credentials, script);
|
const QString script = serverController.replaceVars(getOpenVpnCertData, serverController.genVarsForScript(credentials, container));
|
||||||
|
ErrorCode error = serverController.runScript(credentials, script);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to revoke the certificate";
|
logger.error() << "Failed to revoke the certificate";
|
||||||
return error;
|
return error;
|
||||||
@@ -411,7 +412,7 @@ ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContai
|
|||||||
|
|
||||||
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
||||||
error = serverController->uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
error = serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to upload the clientsTable file to the server";
|
logger.error() << "Failed to upload the clientsTable file to the server";
|
||||||
return error;
|
return error;
|
||||||
@@ -420,14 +421,14 @@ ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContai
|
|||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerContainer container, ServerCredentials credentials)
|
||||||
const QSharedPointer<ServerController> &serverController)
|
|
||||||
{
|
{
|
||||||
ErrorCode error = ErrorCode::NoError;
|
ErrorCode error = ErrorCode::NoError;
|
||||||
|
ServerController serverController(m_settings);
|
||||||
|
|
||||||
const QString wireGuardConfigFile =
|
const QString wireGuardConfigFile =
|
||||||
QString("/opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg");
|
QString("/opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg");
|
||||||
const QString wireguardConfigString = serverController->getTextFileFromContainer(container, credentials, wireGuardConfigFile, error);
|
const QString wireguardConfigString = serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, error);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to get the wg conf file from the server";
|
logger.error() << "Failed to get the wg conf file from the server";
|
||||||
return error;
|
return error;
|
||||||
@@ -445,7 +446,7 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
|
|||||||
}
|
}
|
||||||
QString newWireGuardConfig = configSections.join("[");
|
QString newWireGuardConfig = configSections.join("[");
|
||||||
newWireGuardConfig.insert(0, "[");
|
newWireGuardConfig.insert(0, "[");
|
||||||
error = serverController->uploadTextFileToContainer(container, credentials, newWireGuardConfig, wireGuardConfigFile);
|
error = serverController.uploadTextFileToContainer(container, credentials, newWireGuardConfig, wireGuardConfigFile);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to upload the wg conf file to the server";
|
logger.error() << "Failed to upload the wg conf file to the server";
|
||||||
return error;
|
return error;
|
||||||
@@ -463,16 +464,16 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
|
|||||||
} else {
|
} else {
|
||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
||||||
}
|
}
|
||||||
error = serverController->uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
error = serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to upload the clientsTable file to the server";
|
logger.error() << "Failed to upload the clientsTable file to the server";
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString script = "sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'";
|
const QString script = "sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'";
|
||||||
error = serverController->runScript(
|
error = serverController.runScript(
|
||||||
credentials,
|
credentials,
|
||||||
serverController->replaceVars(script.arg(wireGuardConfigFile), serverController->genVarsForScript(credentials, container)));
|
serverController.replaceVars(script.arg(wireGuardConfigFile), serverController.genVarsForScript(credentials, container)));
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to execute the command 'wg syncconf' on the server";
|
logger.error() << "Failed to execute the command 'wg syncconf' on the server";
|
||||||
return error;
|
return error;
|
||||||
|
|||||||
@@ -23,18 +23,15 @@ public:
|
|||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
ErrorCode updateModel(const DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode updateModel(DockerContainer container, ServerCredentials credentials);
|
||||||
const QSharedPointer<ServerController> &serverController);
|
|
||||||
ErrorCode appendClient(const DockerContainer container, const ServerCredentials &credentials, const QJsonObject &containerConfig,
|
ErrorCode appendClient(const DockerContainer container, const ServerCredentials &credentials, const QJsonObject &containerConfig,
|
||||||
const QString &clientName, const QSharedPointer<ServerController> &serverController);
|
const QString &clientName);
|
||||||
ErrorCode appendClient(const QString &clientId, const QString &clientName, const DockerContainer container,
|
ErrorCode appendClient(const QString &clientId, const QString &clientName, const DockerContainer container,
|
||||||
const ServerCredentials &credentials, const QSharedPointer<ServerController> &serverController);
|
ServerCredentials credentials);
|
||||||
ErrorCode renameClient(const int row, const QString &userName, const DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode renameClient(const int row, const QString &userName, const DockerContainer container, ServerCredentials credentials,
|
||||||
const QSharedPointer<ServerController> &serverController, bool addTimeStamp = false);
|
bool addTimeStamp = false);
|
||||||
ErrorCode revokeClient(const int index, const DockerContainer container, const ServerCredentials &credentials, const int serverIndex,
|
ErrorCode revokeClient(const int index, const DockerContainer container, ServerCredentials credentials, const int serverIndex);
|
||||||
const QSharedPointer<ServerController> &serverController);
|
ErrorCode revokeClient(const QJsonObject &containerConfig, const DockerContainer container, ServerCredentials credentials, const int serverIndex);
|
||||||
ErrorCode revokeClient(const QJsonObject &containerConfig, const DockerContainer container, const ServerCredentials &credentials,
|
|
||||||
const int serverIndex, const QSharedPointer<ServerController> &serverController);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
@@ -47,15 +44,11 @@ private:
|
|||||||
|
|
||||||
void migration(const QByteArray &clientsTableString);
|
void migration(const QByteArray &clientsTableString);
|
||||||
|
|
||||||
ErrorCode revokeOpenVpn(const int row, const DockerContainer container, const ServerCredentials &credentials, const int serverIndex,
|
ErrorCode revokeOpenVpn(const int row, const DockerContainer container, ServerCredentials credentials, const int serverIndex);
|
||||||
const QSharedPointer<ServerController> &serverController);
|
ErrorCode revokeWireGuard(const int row, const DockerContainer container, ServerCredentials credentials);
|
||||||
ErrorCode revokeWireGuard(const int row, const DockerContainer container, const ServerCredentials &credentials,
|
|
||||||
const QSharedPointer<ServerController> &serverController);
|
|
||||||
|
|
||||||
ErrorCode getOpenVpnClients(const DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode getOpenVpnClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count);
|
||||||
const QSharedPointer<ServerController> &serverController, int &count);
|
ErrorCode getWireGuardClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count);
|
||||||
ErrorCode getWireGuardClients(const DockerContainer container, const ServerCredentials &credentials,
|
|
||||||
const QSharedPointer<ServerController> &serverController, int &count);
|
|
||||||
|
|
||||||
QJsonArray m_clientsTable;
|
QJsonArray m_clientsTable;
|
||||||
|
|
||||||
|
|||||||
@@ -83,16 +83,6 @@ QJsonObject ContainersModel::getContainerConfig(const int containerIndex)
|
|||||||
return qvariant_cast<QJsonObject>(data(index(containerIndex), ConfigRole));
|
return qvariant_cast<QJsonObject>(data(index(containerIndex), ConfigRole));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContainersModel::isSupportedByCurrentPlatform(const int containerIndex)
|
|
||||||
{
|
|
||||||
return qvariant_cast<bool>(data(index(containerIndex), IsSupportedRole));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ContainersModel::isServiceContainer(const int containerIndex)
|
|
||||||
{
|
|
||||||
return qvariant_cast<amnezia::ServiceType>(data(index(containerIndex), ServiceTypeRole) == ServiceType::Other);
|
|
||||||
}
|
|
||||||
|
|
||||||
QHash<int, QByteArray> ContainersModel::roleNames() const
|
QHash<int, QByteArray> ContainersModel::roleNames() const
|
||||||
{
|
{
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
|
|||||||
@@ -49,9 +49,6 @@ public slots:
|
|||||||
|
|
||||||
QJsonObject getContainerConfig(const int containerIndex);
|
QJsonObject getContainerConfig(const int containerIndex);
|
||||||
|
|
||||||
bool isSupportedByCurrentPlatform(const int containerIndex);
|
|
||||||
bool isServiceContainer(const int containerIndex);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
|||||||
@@ -37,9 +37,6 @@ QVariant InstalledAppsModel::data(const QModelIndex &index, int role) const
|
|||||||
case PackageNameRole: {
|
case PackageNameRole: {
|
||||||
return m_installedApps.at(index.row()).toObject().value("package");
|
return m_installedApps.at(index.row()).toObject().value("package");
|
||||||
}
|
}
|
||||||
case IsAppSelectedRole: {
|
|
||||||
return m_selectedAppIndexes.contains(index.row());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@@ -67,7 +64,6 @@ QVector<QPair<QString, QString>> InstalledAppsModel::getSelectedAppsInfo()
|
|||||||
appsInfo.push_back({ appName, packageName });
|
appsInfo.push_back({ appName, packageName });
|
||||||
}
|
}
|
||||||
|
|
||||||
m_selectedAppIndexes.clear();
|
|
||||||
return appsInfo;
|
return appsInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,6 +92,5 @@ QHash<int, QByteArray> InstalledAppsModel::roleNames() const
|
|||||||
roles[AppNameRole] = "appName";
|
roles[AppNameRole] = "appName";
|
||||||
roles[AppIconRole] = "appIcon";
|
roles[AppIconRole] = "appIcon";
|
||||||
roles[PackageNameRole] = "packageName";
|
roles[PackageNameRole] = "packageName";
|
||||||
roles[IsAppSelectedRole] = "isAppSelected";
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
#ifndef INSTALLEDAPPSMODEL_H
|
#ifndef INSTALLEDAPPSMODEL_H
|
||||||
#define INSTALLEDAPPSMODEL_H
|
#define INSTALLEDAPPSMODEL_H
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
class InstalledAppsModel : public QAbstractListModel
|
class InstalledAppsModel: public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Roles {
|
enum Roles {
|
||||||
AppNameRole = Qt::UserRole + 1,
|
AppNameRole= Qt::UserRole + 1,
|
||||||
PackageNameRole,
|
PackageNameRole,
|
||||||
AppIconRole,
|
AppIconRole
|
||||||
IsAppSelectedRole
|
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit InstalledAppsModel(QObject *parent = nullptr);
|
explicit InstalledAppsModel(QObject *parent = nullptr);
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ QString LanguageModel::getLocalLanguageName(const LanguageSettings::AvailableLan
|
|||||||
switch (language) {
|
switch (language) {
|
||||||
case LanguageSettings::AvailableLanguageEnum::English: strLanguage = "English"; break;
|
case LanguageSettings::AvailableLanguageEnum::English: strLanguage = "English"; break;
|
||||||
case LanguageSettings::AvailableLanguageEnum::Russian: strLanguage = "Русский"; break;
|
case LanguageSettings::AvailableLanguageEnum::Russian: strLanguage = "Русский"; break;
|
||||||
case LanguageSettings::AvailableLanguageEnum::Ukrainian: strLanguage = "Українська"; break;
|
|
||||||
case LanguageSettings::AvailableLanguageEnum::China_cn: strLanguage = "\347\256\200\344\275\223\344\270\255\346\226\207"; break;
|
case LanguageSettings::AvailableLanguageEnum::China_cn: strLanguage = "\347\256\200\344\275\223\344\270\255\346\226\207"; break;
|
||||||
case LanguageSettings::AvailableLanguageEnum::Persian: strLanguage = "فارسی"; break;
|
case LanguageSettings::AvailableLanguageEnum::Persian: strLanguage = "فارسی"; break;
|
||||||
case LanguageSettings::AvailableLanguageEnum::Arabic: strLanguage = "العربية"; break;
|
case LanguageSettings::AvailableLanguageEnum::Arabic: strLanguage = "العربية"; break;
|
||||||
@@ -61,7 +60,6 @@ void LanguageModel::changeLanguage(const LanguageSettings::AvailableLanguageEnum
|
|||||||
case LanguageSettings::AvailableLanguageEnum::English: emit updateTranslations(QLocale::English); break;
|
case LanguageSettings::AvailableLanguageEnum::English: emit updateTranslations(QLocale::English); break;
|
||||||
case LanguageSettings::AvailableLanguageEnum::Russian: emit updateTranslations(QLocale::Russian); break;
|
case LanguageSettings::AvailableLanguageEnum::Russian: emit updateTranslations(QLocale::Russian); break;
|
||||||
case LanguageSettings::AvailableLanguageEnum::China_cn: emit updateTranslations(QLocale::Chinese); break;
|
case LanguageSettings::AvailableLanguageEnum::China_cn: emit updateTranslations(QLocale::Chinese); break;
|
||||||
case LanguageSettings::AvailableLanguageEnum::Ukrainian: emit updateTranslations(QLocale::Ukrainian); break;
|
|
||||||
case LanguageSettings::AvailableLanguageEnum::Persian: emit updateTranslations(QLocale::Persian); break;
|
case LanguageSettings::AvailableLanguageEnum::Persian: emit updateTranslations(QLocale::Persian); break;
|
||||||
case LanguageSettings::AvailableLanguageEnum::Arabic: emit updateTranslations(QLocale::Arabic); break;
|
case LanguageSettings::AvailableLanguageEnum::Arabic: emit updateTranslations(QLocale::Arabic); break;
|
||||||
case LanguageSettings::AvailableLanguageEnum::Burmese: emit updateTranslations(QLocale::Burmese); break;
|
case LanguageSettings::AvailableLanguageEnum::Burmese: emit updateTranslations(QLocale::Burmese); break;
|
||||||
@@ -76,7 +74,6 @@ int LanguageModel::getCurrentLanguageIndex()
|
|||||||
case QLocale::English: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::English); break;
|
case QLocale::English: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::English); break;
|
||||||
case QLocale::Russian: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Russian); break;
|
case QLocale::Russian: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Russian); break;
|
||||||
case QLocale::Chinese: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::China_cn); break;
|
case QLocale::Chinese: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::China_cn); break;
|
||||||
case QLocale::Ukrainian: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Ukrainian); break;
|
|
||||||
case QLocale::Persian: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Persian); break;
|
case QLocale::Persian: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Persian); break;
|
||||||
case QLocale::Arabic: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Arabic); break;
|
case QLocale::Arabic: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Arabic); break;
|
||||||
case QLocale::Burmese: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Burmese); break;
|
case QLocale::Burmese: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Burmese); break;
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ namespace LanguageSettings
|
|||||||
English,
|
English,
|
||||||
Russian,
|
Russian,
|
||||||
China_cn,
|
China_cn,
|
||||||
Ukrainian,
|
|
||||||
Persian,
|
Persian,
|
||||||
Arabic,
|
Arabic,
|
||||||
Burmese
|
Burmese
|
||||||
|
|||||||
@@ -129,16 +129,6 @@ QJsonObject AwgConfigModel::getConfig()
|
|||||||
return m_fullConfig;
|
return m_fullConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AwgConfigModel::isHeadersEqual(const QString &h1, const QString &h2, const QString &h3, const QString &h4)
|
|
||||||
{
|
|
||||||
return (h1 == h2) || (h1 == h3) || (h1 == h4) || (h2 == h3) || (h2 == h4) || (h3 == h4);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AwgConfigModel::isPacketSizeEqual(const int s1, const int s2)
|
|
||||||
{
|
|
||||||
return (AwgConstant::messageInitiationSize + s1 == AwgConstant::messageResponseSize + s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
QHash<int, QByteArray> AwgConfigModel::roleNames() const
|
QHash<int, QByteArray> AwgConfigModel::roleNames() const
|
||||||
{
|
{
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
|
|||||||
@@ -6,11 +6,6 @@
|
|||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
|
|
||||||
namespace AwgConstant {
|
|
||||||
const int messageInitiationSize = 148;
|
|
||||||
const int messageResponseSize = 92;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AwgConfig
|
struct AwgConfig
|
||||||
{
|
{
|
||||||
AwgConfig(const QJsonObject &jsonConfig);
|
AwgConfig(const QJsonObject &jsonConfig);
|
||||||
@@ -62,9 +57,6 @@ public slots:
|
|||||||
void updateModel(const QJsonObject &config);
|
void updateModel(const QJsonObject &config);
|
||||||
QJsonObject getConfig();
|
QJsonObject getConfig();
|
||||||
|
|
||||||
bool isHeadersEqual(const QString &h1, const QString &h2, const QString &h3, const QString &h4);
|
|
||||||
bool isPacketSizeEqual(const int s1, const int s2);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
|||||||
@@ -105,12 +105,12 @@ void OpenVpnConfigModel::updateModel(const QJsonObject &config)
|
|||||||
m_protocolConfig.insert(config_key::hash,
|
m_protocolConfig.insert(config_key::hash,
|
||||||
protocolConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash));
|
protocolConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash));
|
||||||
m_protocolConfig.insert(config_key::block_outside_dns,
|
m_protocolConfig.insert(config_key::block_outside_dns,
|
||||||
protocolConfig.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns));
|
protocolConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth));
|
||||||
m_protocolConfig.insert(config_key::port,
|
m_protocolConfig.insert(config_key::port,
|
||||||
protocolConfig.value(config_key::port).toString(protocols::openvpn::defaultPort));
|
protocolConfig.value(config_key::port).toString(protocols::openvpn::defaultPort));
|
||||||
m_protocolConfig.insert(
|
m_protocolConfig.insert(
|
||||||
config_key::tls_auth,
|
config_key::tls_auth,
|
||||||
protocolConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth));
|
protocolConfig.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns));
|
||||||
m_protocolConfig.insert(config_key::additional_client_config,
|
m_protocolConfig.insert(config_key::additional_client_config,
|
||||||
protocolConfig.value(config_key::additional_client_config)
|
protocolConfig.value(config_key::additional_client_config)
|
||||||
.toString(protocols::openvpn::defaultAdditionalClientConfig));
|
.toString(protocols::openvpn::defaultAdditionalClientConfig));
|
||||||
|
|||||||
@@ -31,15 +31,10 @@ bool ServersModel::setData(const QModelIndex &index, const QVariant &value, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject server = m_servers.at(index.row()).toObject();
|
QJsonObject server = m_servers.at(index.row()).toObject();
|
||||||
const auto configVersion = server.value(config_key::configVersion).toInt();
|
|
||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case NameRole: {
|
case NameRole: {
|
||||||
if (configVersion) {
|
|
||||||
server.insert(config_key::name, value.toString());
|
|
||||||
} else {
|
|
||||||
server.insert(config_key::description, value.toString());
|
server.insert(config_key::description, value.toString());
|
||||||
}
|
|
||||||
m_settings->editServer(index.row(), server);
|
m_settings->editServer(index.row(), server);
|
||||||
m_servers.replace(index.row(), server);
|
m_servers.replace(index.row(), server);
|
||||||
if (index.row() == m_defaultServerIndex) {
|
if (index.row() == m_defaultServerIndex) {
|
||||||
@@ -384,6 +379,13 @@ void ServersModel::updateContainerConfig(const int containerIndex, const QJsonOb
|
|||||||
}
|
}
|
||||||
|
|
||||||
server.insert(config_key::containers, containers);
|
server.insert(config_key::containers, containers);
|
||||||
|
|
||||||
|
auto defaultContainer = server.value(config_key::defaultContainer).toString();
|
||||||
|
if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None
|
||||||
|
|| ContainerProps::containerService(container) != ServiceType::Other)) {
|
||||||
|
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||||
|
}
|
||||||
|
|
||||||
editServer(server, m_processedServerIndex);
|
editServer(server, m_processedServerIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,9 +400,8 @@ void ServersModel::addContainerConfig(const int containerIndex, const QJsonObjec
|
|||||||
server.insert(config_key::containers, containers);
|
server.insert(config_key::containers, containers);
|
||||||
|
|
||||||
auto defaultContainer = server.value(config_key::defaultContainer).toString();
|
auto defaultContainer = server.value(config_key::defaultContainer).toString();
|
||||||
if (ContainerProps::containerFromString(defaultContainer) == DockerContainer::None
|
if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None
|
||||||
&& ContainerProps::containerService(container) != ServiceType::Other
|
|| ContainerProps::containerService(container) != ServiceType::Other)) {
|
||||||
&& ContainerProps::isSupportedByCurrentPlatform(container)) {
|
|
||||||
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,10 +422,10 @@ const QString ServersModel::getDefaultServerDefaultContainerName()
|
|||||||
return ContainerProps::containerHumanNames().value(defaultContainer);
|
return ContainerProps::containerHumanNames().value(defaultContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServersModel::removeAllContainers(const QSharedPointer<ServerController> &serverController)
|
ErrorCode ServersModel::removeAllContainers()
|
||||||
{
|
{
|
||||||
|
ServerController serverController(m_settings);
|
||||||
ErrorCode errorCode = serverController->removeAllContainers(m_settings->serverCredentials(m_processedServerIndex));
|
ErrorCode errorCode = serverController.removeAllContainers(m_settings->serverCredentials(m_processedServerIndex));
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
QJsonObject s = m_servers.at(m_processedServerIndex).toObject();
|
QJsonObject s = m_servers.at(m_processedServerIndex).toObject();
|
||||||
@@ -436,22 +437,22 @@ ErrorCode ServersModel::removeAllContainers(const QSharedPointer<ServerControlle
|
|||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServersModel::rebootServer(const QSharedPointer<ServerController> &serverController)
|
ErrorCode ServersModel::rebootServer()
|
||||||
{
|
{
|
||||||
|
ServerController serverController(m_settings);
|
||||||
auto credentials = m_settings->serverCredentials(m_processedServerIndex);
|
auto credentials = m_settings->serverCredentials(m_processedServerIndex);
|
||||||
|
|
||||||
ErrorCode errorCode = serverController->rebootServer(credentials);
|
ErrorCode errorCode = serverController.rebootServer(credentials);
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServersModel::removeContainer(const QSharedPointer<ServerController> &serverController, const int containerIndex)
|
ErrorCode ServersModel::removeContainer(const int containerIndex)
|
||||||
{
|
{
|
||||||
|
ServerController serverController(m_settings);
|
||||||
auto credentials = m_settings->serverCredentials(m_processedServerIndex);
|
auto credentials = m_settings->serverCredentials(m_processedServerIndex);
|
||||||
auto dockerContainer = static_cast<DockerContainer>(containerIndex);
|
auto dockerContainer = static_cast<DockerContainer>(containerIndex);
|
||||||
|
|
||||||
ErrorCode errorCode = serverController->removeContainer(credentials, dockerContainer);
|
ErrorCode errorCode = serverController.removeContainer(credentials, dockerContainer);
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
QJsonObject server = m_servers.at(m_processedServerIndex).toObject();
|
QJsonObject server = m_servers.at(m_processedServerIndex).toObject();
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "core/controllers/serverController.h"
|
|
||||||
|
|
||||||
class ServersModel : public QAbstractListModel
|
class ServersModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
@@ -89,9 +88,9 @@ public slots:
|
|||||||
|
|
||||||
void clearCachedProfile(const DockerContainer container);
|
void clearCachedProfile(const DockerContainer container);
|
||||||
|
|
||||||
ErrorCode removeContainer(const QSharedPointer<ServerController> &serverController, const int containerIndex);
|
ErrorCode removeContainer(const int containerIndex);
|
||||||
ErrorCode removeAllContainers(const QSharedPointer<ServerController> &serverController);
|
ErrorCode removeAllContainers();
|
||||||
ErrorCode rebootServer(const QSharedPointer<ServerController> &serverController);
|
ErrorCode rebootServer();
|
||||||
|
|
||||||
void setDefaultContainer(const int serverIndex, const int containerIndex);
|
void setDefaultContainer(const int serverIndex, const int containerIndex);
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,13 @@
|
|||||||
SitesModel::SitesModel(std::shared_ptr<Settings> settings, QObject *parent)
|
SitesModel::SitesModel(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
: QAbstractListModel(parent), m_settings(settings)
|
: QAbstractListModel(parent), m_settings(settings)
|
||||||
{
|
{
|
||||||
m_isSplitTunnelingEnabled = m_settings->getSitesSplitTunnelingEnabled();
|
auto routeMode = m_settings->routeMode();
|
||||||
m_currentRouteMode = m_settings->routeMode();
|
if (routeMode == Settings::RouteMode::VpnAllSites) {
|
||||||
if (m_currentRouteMode == Settings::VpnAllSites) { // for old split tunneling configs
|
m_isSplitTunnelingEnabled = false;
|
||||||
m_settings->setRouteMode(static_cast<Settings::RouteMode>(Settings::VpnOnlyForwardSites));
|
m_currentRouteMode = Settings::RouteMode::VpnOnlyForwardSites;
|
||||||
m_currentRouteMode = Settings::VpnOnlyForwardSites;
|
} else {
|
||||||
|
m_isSplitTunnelingEnabled = true;
|
||||||
|
m_currentRouteMode = routeMode;
|
||||||
}
|
}
|
||||||
fillSites();
|
fillSites();
|
||||||
}
|
}
|
||||||
@@ -105,7 +107,11 @@ bool SitesModel::isSplitTunnelingEnabled()
|
|||||||
|
|
||||||
void SitesModel::toggleSplitTunneling(bool enabled)
|
void SitesModel::toggleSplitTunneling(bool enabled)
|
||||||
{
|
{
|
||||||
m_settings->setSitesSplitTunnelingEnabled(enabled);
|
if (enabled) {
|
||||||
|
setRouteMode(m_currentRouteMode);
|
||||||
|
} else {
|
||||||
|
m_settings->setRouteMode(Settings::RouteMode::VpnAllSites);
|
||||||
|
}
|
||||||
m_isSplitTunnelingEnabled = enabled;
|
m_isSplitTunnelingEnabled = enabled;
|
||||||
emit splitTunnelingToggled();
|
emit splitTunnelingToggled();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,26 +49,10 @@ Button {
|
|||||||
verticalOffset: 0
|
verticalOffset: 0
|
||||||
radius: 10
|
radius: 10
|
||||||
samples: 25
|
samples: 25
|
||||||
color: root.activeFocus ? "#D7D8DB" : "#FBB26A"
|
color: "#FBB26A"
|
||||||
source: backgroundCircle
|
source: backgroundCircle
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapePath {
|
|
||||||
fillColor: "transparent"
|
|
||||||
strokeColor: "#D7D8DB"
|
|
||||||
strokeWidth: root.activeFocus ? 1 : 0
|
|
||||||
capStyle: ShapePath.RoundCap
|
|
||||||
|
|
||||||
PathAngleArc {
|
|
||||||
centerX: backgroundCircle.width / 2
|
|
||||||
centerY: backgroundCircle.height / 2
|
|
||||||
radiusX: 94
|
|
||||||
radiusY: 94
|
|
||||||
startAngle: 0
|
|
||||||
sweepAngle: 360
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ShapePath {
|
ShapePath {
|
||||||
fillColor: "transparent"
|
fillColor: "transparent"
|
||||||
strokeColor: {
|
strokeColor: {
|
||||||
@@ -80,14 +64,14 @@ Button {
|
|||||||
return defaultButtonColor
|
return defaultButtonColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strokeWidth: root.activeFocus ? 2 : 3
|
strokeWidth: 3
|
||||||
capStyle: ShapePath.RoundCap
|
capStyle: ShapePath.RoundCap
|
||||||
|
|
||||||
PathAngleArc {
|
PathAngleArc {
|
||||||
centerX: backgroundCircle.width / 2
|
centerX: backgroundCircle.width / 2
|
||||||
centerY: backgroundCircle.height / 2
|
centerY: backgroundCircle.height / 2
|
||||||
radiusX: 93 - (root.activeFocus ? 2 : 0)
|
radiusX: 93
|
||||||
radiusY: 93 - (root.activeFocus ? 2 : 0)
|
radiusY: 93
|
||||||
startAngle: 0
|
startAngle: 0
|
||||||
sweepAngle: 360
|
sweepAngle: 360
|
||||||
}
|
}
|
||||||
@@ -157,7 +141,4 @@ Button {
|
|||||||
ServersModel.setProcessedServerIndex(ServersModel.defaultIndex)
|
ServersModel.setProcessedServerIndex(ServersModel.defaultIndex)
|
||||||
ConnectionController.connectButtonClicked()
|
ConnectionController.connectButtonClicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onEnterPressed: this.clicked()
|
|
||||||
Keys.onReturnPressed: this.clicked()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,14 +26,6 @@ DrawerType2 {
|
|||||||
root.expandedHeight = content.implicitHeight + 32
|
root.expandedHeight = content.implicitHeight + 32
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
enabled: !GC.isMobile()
|
|
||||||
function onOpened() {
|
|
||||||
focusItem.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Header2Type {
|
Header2Type {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
@@ -44,11 +36,6 @@ DrawerType2 {
|
|||||||
headerText: qsTr("Add new connection")
|
headerText: qsTr("Add new connection")
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
|
||||||
id: focusItem
|
|
||||||
KeyNavigation.tab: ip.rightButton
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
id: ip
|
id: ip
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -61,14 +48,11 @@ DrawerType2 {
|
|||||||
PageController.goToPage(PageEnum.PageSetupWizardCredentials)
|
PageController.goToPage(PageEnum.PageSetupWizardCredentials)
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyNavigation.tab: qrCode.rightButton
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
id: qrCode
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Open config file, key or QR code")
|
text: qsTr("Open config file, key or QR code")
|
||||||
@@ -78,8 +62,6 @@ DrawerType2 {
|
|||||||
PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
|
PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyNavigation.tab: focusItem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|||||||
@@ -17,56 +17,12 @@ ListView {
|
|||||||
property var rootWidth
|
property var rootWidth
|
||||||
property var selectedText
|
property var selectedText
|
||||||
|
|
||||||
property bool a: true
|
|
||||||
|
|
||||||
width: rootWidth
|
width: rootWidth
|
||||||
height: menuContent.contentItem.height
|
height: menuContent.contentItem.height
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
property FlickableType parentFlickable
|
|
||||||
property var lastItemTabClicked
|
|
||||||
|
|
||||||
property int currentFocusIndex: 0
|
|
||||||
|
|
||||||
activeFocusOnTab: true
|
|
||||||
onActiveFocusChanged: {
|
|
||||||
if (activeFocus) {
|
|
||||||
this.currentFocusIndex = 0
|
|
||||||
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onTabPressed: {
|
|
||||||
if (currentFocusIndex < this.count - 1) {
|
|
||||||
currentFocusIndex += 1
|
|
||||||
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
|
|
||||||
} else {
|
|
||||||
currentFocusIndex = 0
|
|
||||||
if (lastItemTabClicked && typeof lastItemTabClicked === "function") {
|
|
||||||
lastItemTabClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onVisibleChanged: {
|
|
||||||
if (visible) {
|
|
||||||
currentFocusIndex = 0
|
|
||||||
focusItem.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: focusItem
|
|
||||||
}
|
|
||||||
|
|
||||||
onCurrentFocusIndexChanged: {
|
|
||||||
if (parentFlickable) {
|
|
||||||
parentFlickable.ensureVisible(this.itemAtIndex(currentFocusIndex))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ButtonGroup {
|
ButtonGroup {
|
||||||
id: containersRadioButtonGroup
|
id: containersRadioButtonGroup
|
||||||
}
|
}
|
||||||
@@ -75,12 +31,6 @@ ListView {
|
|||||||
implicitWidth: rootWidth
|
implicitWidth: rootWidth
|
||||||
implicitHeight: content.implicitHeight
|
implicitHeight: content.implicitHeight
|
||||||
|
|
||||||
onActiveFocusChanged: {
|
|
||||||
if (activeFocus) {
|
|
||||||
containerRadioButton.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
@@ -101,7 +51,7 @@ ListView {
|
|||||||
imageSource: "qrc:/images/controls/download.svg"
|
imageSource: "qrc:/images/controls/download.svg"
|
||||||
showImage: !isInstalled
|
showImage: !isInstalled
|
||||||
|
|
||||||
checkable: isInstalled && !ConnectionController.isConnected
|
checkable: isInstalled && !ConnectionController.isConnected && isSupported
|
||||||
checked: proxyDefaultServerContainersModel.mapToSource(index) === ServersModel.getDefaultServerData("defaultContainer")
|
checked: proxyDefaultServerContainersModel.mapToSource(index) === ServersModel.getDefaultServerData("defaultContainer")
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
@@ -114,6 +64,11 @@ ListView {
|
|||||||
containersDropDown.close()
|
containersDropDown.close()
|
||||||
ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyDefaultServerContainersModel.mapToSource(index))
|
ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyDefaultServerContainersModel.mapToSource(index))
|
||||||
} else {
|
} else {
|
||||||
|
if (!isSupported && isInstalled) {
|
||||||
|
PageController.showErrorMessage(qsTr("The selected protocol is not supported on the current platform"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ContainersModel.setProcessedContainerIndex(proxyDefaultServerContainersModel.mapToSource(index))
|
ContainersModel.setProcessedContainerIndex(proxyDefaultServerContainersModel.mapToSource(index))
|
||||||
InstallController.setShouldCreateServer(false)
|
InstallController.setShouldCreateServer(false)
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
|
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
|
||||||
@@ -126,19 +81,6 @@ ListView {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onEnterPressed: {
|
|
||||||
if (checkable) {
|
|
||||||
checked = true
|
|
||||||
}
|
|
||||||
containerRadioButton.clicked()
|
|
||||||
}
|
|
||||||
Keys.onReturnPressed: {
|
|
||||||
if (checkable) {
|
|
||||||
checked = true
|
|
||||||
}
|
|
||||||
containerRadioButton.clicked()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {
|
DividerType {
|
||||||
|
|||||||
@@ -24,14 +24,6 @@ DrawerType2 {
|
|||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
enabled: !GC.isMobile()
|
|
||||||
function onOpened() {
|
|
||||||
focusItem.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Header2Type {
|
Header2Type {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
@@ -43,13 +35,7 @@ DrawerType2 {
|
|||||||
descriptionText: qsTr("Allows you to connect to some sites or applications through a VPN connection and bypass others")
|
descriptionText: qsTr("Allows you to connect to some sites or applications through a VPN connection and bypass others")
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
|
||||||
id: focusItem
|
|
||||||
KeyNavigation.tab: splitTunnelingSwitch.visible ? splitTunnelingSwitch : siteBasedSplitTunnelingSwitch.rightButton
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
id: splitTunnelingSwitch
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
@@ -59,8 +45,6 @@ DrawerType2 {
|
|||||||
descriptionText: qsTr("Enabled \nCan't be disabled for current server")
|
descriptionText: qsTr("Enabled \nCan't be disabled for current server")
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
KeyNavigation.tab: siteBasedSplitTunnelingSwitch.visible ? siteBasedSplitTunnelingSwitch.rightButton : focusItem
|
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
// PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
// PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
||||||
// root.close()
|
// root.close()
|
||||||
@@ -72,18 +56,15 @@ DrawerType2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
id: siteBasedSplitTunnelingSwitch
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
enabled: !ServersModel.isDefaultServerDefaultContainerHasSplitTunneling || !ServersModel.getDefaultServerData("isServerFromApi")
|
||||||
|
|
||||||
text: qsTr("Site-based split tunneling")
|
text: qsTr("Site-based split tunneling")
|
||||||
descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
KeyNavigation.tab: appSplitTunnelingSwitch.visible ?
|
|
||||||
appSplitTunnelingSwitch.rightButton :
|
|
||||||
focusItem
|
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
||||||
root.close()
|
root.close()
|
||||||
@@ -94,7 +75,6 @@ DrawerType2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
id: appSplitTunnelingSwitch
|
|
||||||
visible: isAppSplitTinnelingEnabled
|
visible: isAppSplitTinnelingEnabled
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -103,8 +83,6 @@ DrawerType2 {
|
|||||||
descriptionText: AppSplitTunnelingModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
descriptionText: AppSplitTunnelingModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
KeyNavigation.tab: focusItem
|
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsAppSplitTunneling)
|
PageController.goToPage(PageEnum.PageSettingsAppSplitTunneling)
|
||||||
root.close()
|
root.close()
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import QtQuick.Layouts
|
|||||||
import "../Controls2"
|
import "../Controls2"
|
||||||
import "../Controls2/TextTypes"
|
import "../Controls2/TextTypes"
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
|
||||||
|
|
||||||
import InstalledAppsModel 1.0
|
import InstalledAppsModel 1.0
|
||||||
|
|
||||||
DrawerType2 {
|
DrawerType2 {
|
||||||
@@ -36,7 +34,7 @@ DrawerType2 {
|
|||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: searchField.top
|
anchors.bottom: addButton.top
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
@@ -68,15 +66,7 @@ DrawerType2 {
|
|||||||
clip: true
|
clip: true
|
||||||
interactive: true
|
interactive: true
|
||||||
|
|
||||||
model: SortFilterProxyModel {
|
model: installedAppsModel
|
||||||
id: proxyInstalledAppsModel
|
|
||||||
sourceModel: installedAppsModel
|
|
||||||
filters: RegExpFilter {
|
|
||||||
roleName: "appName"
|
|
||||||
pattern: ".*" + searchField.textField.text + ".*"
|
|
||||||
caseSensitivity: Qt.CaseInsensitive
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ScrollBar.vertical: ScrollBar {
|
ScrollBar.vertical: ScrollBar {
|
||||||
id: scrollBar
|
id: scrollBar
|
||||||
@@ -101,9 +91,9 @@ DrawerType2 {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: appName
|
text: appName
|
||||||
checked: isAppSelected
|
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
installedAppsModel.selectedStateChanged(proxyInstalledAppsModel.mapToSource(index), checked)
|
listView.model.selectedStateChanged(index, checked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,21 +113,6 @@ DrawerType2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
|
||||||
id: searchField
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: addButton.top
|
|
||||||
anchors.bottomMargin: 16
|
|
||||||
anchors.rightMargin: 16
|
|
||||||
anchors.leftMargin: 16
|
|
||||||
|
|
||||||
backgroundColor: "#2C2D30"
|
|
||||||
|
|
||||||
textFieldPlaceholderText: qsTr("application name")
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
id: addButton
|
id: addButton
|
||||||
|
|
||||||
@@ -152,7 +127,7 @@ DrawerType2 {
|
|||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
AppSplitTunnelingController.addApps(installedAppsModel.getSelectedAppsInfo())
|
AppSplitTunnelingController.addApps(listView.model.getSelectedAppsInfo())
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import QtQuick.Layouts
|
|||||||
import "../Controls2"
|
import "../Controls2"
|
||||||
import "../Controls2/TextTypes"
|
import "../Controls2/TextTypes"
|
||||||
|
|
||||||
import "../Config"
|
|
||||||
|
|
||||||
DrawerType2 {
|
DrawerType2 {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
@@ -31,14 +29,6 @@ DrawerType2 {
|
|||||||
root.expandedHeight = content.implicitHeight + 32
|
root.expandedHeight = content.implicitHeight + 32
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
enabled: !GC.isMobile()
|
|
||||||
function onOpened() {
|
|
||||||
focusItem.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Header2TextType {
|
Header2TextType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
@@ -57,13 +47,7 @@ DrawerType2 {
|
|||||||
text: descriptionText
|
text: descriptionText
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
|
||||||
id: focusItem
|
|
||||||
KeyNavigation.tab: yesButton
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
id: yesButton
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
@@ -76,12 +60,9 @@ DrawerType2 {
|
|||||||
yesButtonFunction()
|
yesButtonFunction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyNavigation.tab: noButton
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
id: noButton
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
@@ -100,8 +81,6 @@ DrawerType2 {
|
|||||||
noButtonFunction()
|
noButtonFunction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyNavigation.tab: focusItem
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import QtQuick.Layouts
|
|||||||
|
|
||||||
import "../Controls2"
|
import "../Controls2"
|
||||||
import "../Controls2/TextTypes"
|
import "../Controls2/TextTypes"
|
||||||
import "../Config"
|
|
||||||
|
|
||||||
DrawerType2 {
|
DrawerType2 {
|
||||||
id: root
|
id: root
|
||||||
@@ -18,21 +17,8 @@ DrawerType2 {
|
|||||||
root.expandedHeight = container.implicitHeight
|
root.expandedHeight = container.implicitHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
enabled: !GC.isMobile()
|
|
||||||
function onOpened() {
|
|
||||||
focusItem.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: focusItem
|
|
||||||
KeyNavigation.tab: backButton
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: backButtonLayout
|
id: backButton
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -40,15 +26,15 @@ DrawerType2 {
|
|||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
|
||||||
backButtonImage: "qrc:/images/controls/arrow-left.svg"
|
backButtonImage: "qrc:/images/controls/arrow-left.svg"
|
||||||
backButtonFunction: function() { root.close() }
|
backButtonFunction: function() {
|
||||||
KeyNavigation.tab: listView
|
root.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
anchors.top: backButtonLayout.bottom
|
anchors.top: backButton.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
@@ -85,50 +71,10 @@ DrawerType2 {
|
|||||||
id: buttonGroup
|
id: buttonGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
property int currentFocusIndex: 0
|
|
||||||
|
|
||||||
activeFocusOnTab: true
|
|
||||||
onActiveFocusChanged: {
|
|
||||||
if (activeFocus) {
|
|
||||||
this.currentFocusIndex = 0
|
|
||||||
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onTabPressed: {
|
|
||||||
if (currentFocusIndex < this.count - 1) {
|
|
||||||
currentFocusIndex += 1
|
|
||||||
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
|
|
||||||
} else {
|
|
||||||
listViewFocusItem.forceActiveFocus()
|
|
||||||
focusItem.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: listViewFocusItem
|
|
||||||
Keys.onTabPressed: {
|
|
||||||
root.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onVisibleChanged: {
|
|
||||||
if (visible) {
|
|
||||||
listViewFocusItem.forceActiveFocus()
|
|
||||||
focusItem.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
implicitWidth: root.width
|
implicitWidth: root.width
|
||||||
implicitHeight: delegateContent.implicitHeight
|
implicitHeight: delegateContent.implicitHeight
|
||||||
|
|
||||||
onActiveFocusChanged: {
|
|
||||||
if (activeFocus) {
|
|
||||||
radioButton.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: delegateContent
|
id: delegateContent
|
||||||
|
|
||||||
@@ -143,18 +89,12 @@ DrawerType2 {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|
||||||
indicator: Rectangle {
|
indicator: Rectangle {
|
||||||
width: parent.width - 1
|
anchors.fill: parent
|
||||||
height: parent.height
|
|
||||||
color: radioButton.hovered ? "#2C2D30" : "#1C1D21"
|
color: radioButton.hovered ? "#2C2D30" : "#1C1D21"
|
||||||
border.color: radioButton.focus ? "#D7D8DB" : "transparent"
|
|
||||||
border.width: radioButton.focus ? 1 : 0
|
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
PropertyAnimation { duration: 200 }
|
PropertyAnimation { duration: 200 }
|
||||||
}
|
}
|
||||||
Behavior on border.color {
|
|
||||||
PropertyAnimation { duration: 200 }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
@@ -197,9 +137,6 @@ DrawerType2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onEnterPressed: radioButton.clicked()
|
|
||||||
Keys.onReturnPressed: radioButton.clicked()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,52 +22,16 @@ ListView {
|
|||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
activeFocusOnTab: true
|
|
||||||
Keys.onTabPressed: {
|
|
||||||
if (currentIndex < this.count - 1) {
|
|
||||||
this.incrementCurrentIndex()
|
|
||||||
} else {
|
|
||||||
currentIndex = 0
|
|
||||||
lastItemTabClickedSignal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
|
||||||
if (visible) {
|
|
||||||
if (fl.contentHeight > fl.height) {
|
|
||||||
var item = this.currentItem
|
|
||||||
if (item.y < fl.height) {
|
|
||||||
fl.contentY = item.y
|
|
||||||
} else if (item.y + item.height > fl.contentY + fl.height) {
|
|
||||||
fl.contentY = item.y + item.height - fl.height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onVisibleChanged: {
|
|
||||||
if (visible) {
|
|
||||||
this.currentIndex = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
implicitWidth: root.width
|
implicitWidth: root.width
|
||||||
implicitHeight: delegateContent.implicitHeight
|
implicitHeight: delegateContent.implicitHeight
|
||||||
|
|
||||||
onActiveFocusChanged: {
|
|
||||||
if (activeFocus) {
|
|
||||||
containerRadioButton.rightButton.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: delegateContent
|
id: delegateContent
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
id: containerRadioButton
|
|
||||||
implicitWidth: parent.width
|
implicitWidth: parent.width
|
||||||
|
|
||||||
text: name
|
text: name
|
||||||
|
|||||||
@@ -121,9 +121,6 @@ DrawerType2 {
|
|||||||
text: qsTr("Copy")
|
text: qsTr("Copy")
|
||||||
imageSource: "qrc:/images/controls/copy.svg"
|
imageSource: "qrc:/images/controls/copy.svg"
|
||||||
|
|
||||||
Keys.onReturnPressed: { copyConfigTextButton.clicked() }
|
|
||||||
Keys.onEnterPressed: { copyConfigTextButton.clicked() }
|
|
||||||
|
|
||||||
KeyNavigation.tab: copyNativeConfigStringButton.visible ? copyNativeConfigStringButton : showSettingsButton
|
KeyNavigation.tab: copyNativeConfigStringButton.visible ? copyNativeConfigStringButton : showSettingsButton
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,30 +174,11 @@ DrawerType2 {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
expandedHeight: parent.height * 0.9
|
expandedHeight: parent.height * 0.9
|
||||||
|
|
||||||
onClosed: {
|
|
||||||
if (!GC.isMobile()) {
|
|
||||||
header.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
expandedContent: Item {
|
expandedContent: Item {
|
||||||
id: configContentContainer
|
id: configContentContainer
|
||||||
|
|
||||||
implicitHeight: configContentDrawer.expandedHeight
|
implicitHeight: configContentDrawer.expandedHeight
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: configContentDrawer
|
|
||||||
enabled: !GC.isMobile()
|
|
||||||
function onOpened() {
|
|
||||||
focusItem.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: focusItem
|
|
||||||
KeyNavigation.tab: backButton
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: copyNativeConfigStringButton
|
target: copyNativeConfigStringButton
|
||||||
function onClicked() {
|
function onClicked() {
|
||||||
@@ -218,7 +196,6 @@ DrawerType2 {
|
|||||||
configText.copy()
|
configText.copy()
|
||||||
configText.select(0, 0)
|
configText.select(0, 0)
|
||||||
PageController.showNotificationMessage(qsTr("Copied"))
|
PageController.showNotificationMessage(qsTr("Copied"))
|
||||||
header.forceActiveFocus()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,9 +207,9 @@ DrawerType2 {
|
|||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
|
|
||||||
backButtonFunction: function() { configContentDrawer.close() }
|
backButtonFunction: function() {
|
||||||
|
configContentDrawer.close()
|
||||||
KeyNavigation.tab: focusItem
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
@@ -279,7 +256,6 @@ DrawerType2 {
|
|||||||
height: 24
|
height: 24
|
||||||
|
|
||||||
readOnly: true
|
readOnly: true
|
||||||
activeFocusOnTab: false
|
|
||||||
|
|
||||||
color: "#D7D8DB"
|
color: "#D7D8DB"
|
||||||
selectionColor: "#633303"
|
selectionColor: "#633303"
|
||||||
|
|||||||
@@ -17,19 +17,12 @@ Rectangle {
|
|||||||
color: "#1C1D21"
|
color: "#1C1D21"
|
||||||
radius: 16
|
radius: 16
|
||||||
|
|
||||||
onFocusChanged: {
|
|
||||||
if (focus) {
|
|
||||||
udpButton.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: transportProtoButtonGroup
|
id: transportProtoButtonGroup
|
||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
HorizontalRadioButton {
|
HorizontalRadioButton {
|
||||||
id: udpButton
|
|
||||||
checked: root.currentIndex === 0
|
checked: root.currentIndex === 0
|
||||||
|
|
||||||
hoverEnabled: root.enabled
|
hoverEnabled: root.enabled
|
||||||
@@ -37,15 +30,12 @@ Rectangle {
|
|||||||
implicitWidth: (rootWidth - 32) / 2
|
implicitWidth: (rootWidth - 32) / 2
|
||||||
text: "UDP"
|
text: "UDP"
|
||||||
|
|
||||||
KeyNavigation.tab: tcpButton
|
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.currentIndex = 0
|
root.currentIndex = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalRadioButton {
|
HorizontalRadioButton {
|
||||||
id: tcpButton
|
|
||||||
checked: root.currentIndex === 1
|
checked: root.currentIndex === 1
|
||||||
|
|
||||||
hoverEnabled: root.enabled
|
hoverEnabled: root.enabled
|
||||||
|
|||||||
@@ -13,12 +13,6 @@ Item {
|
|||||||
|
|
||||||
visible: backButtonImage !== ""
|
visible: backButtonImage !== ""
|
||||||
|
|
||||||
onActiveFocusChanged: {
|
|
||||||
if (activeFocus) {
|
|
||||||
backButton.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
@@ -26,7 +20,6 @@ Item {
|
|||||||
anchors.leftMargin: 8
|
anchors.leftMargin: 8
|
||||||
|
|
||||||
ImageButtonType {
|
ImageButtonType {
|
||||||
id: backButton
|
|
||||||
image: backButtonImage
|
image: backButtonImage
|
||||||
imageColor: "#D7D8DB"
|
imageColor: "#D7D8DB"
|
||||||
|
|
||||||
@@ -49,7 +42,4 @@ Item {
|
|||||||
color: "transparent"
|
color: "transparent"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onEnterPressed: backButton.clicked()
|
|
||||||
Keys.onReturnPressed: backButton.clicked()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,29 +26,18 @@ Button {
|
|||||||
|
|
||||||
property bool squareLeftSide: false
|
property bool squareLeftSide: false
|
||||||
|
|
||||||
property FlickableType parentFlickable
|
|
||||||
|
|
||||||
property var clickedFunc
|
property var clickedFunc
|
||||||
|
|
||||||
implicitHeight: 56
|
implicitHeight: 56
|
||||||
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
focusPolicy: Qt.TabFocus
|
|
||||||
|
|
||||||
onFocusChanged: {
|
|
||||||
if (root.activeFocus) {
|
|
||||||
if (root.parentFlickable) {
|
|
||||||
root.parentFlickable.ensureVisible(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
id: focusBorder
|
id: focusBorder
|
||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: root.activeFocus ? root.borderFocusedColor : "transparent"
|
border.color: root.activeFocus ? root.borderFocusedColor : "transparent"
|
||||||
border.width: root.activeFocus ? root.borderFocusedWidth : 0
|
border.width: root.activeFocus ? root.borderFocusedWidth : "transparent"
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ CheckBox {
|
|||||||
property string checkedBorderColor: "#FBB26A"
|
property string checkedBorderColor: "#FBB26A"
|
||||||
property string checkedBorderDisabledColor: "#402102"
|
property string checkedBorderDisabledColor: "#402102"
|
||||||
|
|
||||||
property string borderFocusedColor: "#D7D8DB"
|
|
||||||
|
|
||||||
property string checkedImageColor: "#FBB26A"
|
property string checkedImageColor: "#FBB26A"
|
||||||
property string pressedImageColor: "#A85809"
|
property string pressedImageColor: "#A85809"
|
||||||
property string defaultImageColor: "transparent"
|
property string defaultImageColor: "transparent"
|
||||||
@@ -32,24 +30,7 @@ CheckBox {
|
|||||||
|
|
||||||
property string imageSource: "qrc:/images/controls/check.svg"
|
property string imageSource: "qrc:/images/controls/check.svg"
|
||||||
|
|
||||||
property var parentFlickable
|
|
||||||
onFocusChanged: {
|
|
||||||
if (root.activeFocus) {
|
|
||||||
if (root.parentFlickable) {
|
|
||||||
root.parentFlickable.ensureVisible(root)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hoverEnabled: enabled ? true : false
|
hoverEnabled: enabled ? true : false
|
||||||
focusPolicy: Qt.NoFocus
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
color: "transparent"
|
|
||||||
border.color: root.focus ? borderFocusedColor : "transparent"
|
|
||||||
border.width: 1
|
|
||||||
radius: 16
|
|
||||||
}
|
|
||||||
|
|
||||||
indicator: Rectangle {
|
indicator: Rectangle {
|
||||||
id: background
|
id: background
|
||||||
@@ -78,11 +59,7 @@ CheckBox {
|
|||||||
width: 24
|
width: 24
|
||||||
height: 24
|
height: 24
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: root.checked ?
|
border.color: root.checked ? (root.enabled ? checkedBorderColor : checkedBorderDisabledColor) : defaultBorderColor
|
||||||
(root.enabled ?
|
|
||||||
checkedBorderColor :
|
|
||||||
checkedBorderDisabledColor) :
|
|
||||||
defaultBorderColor
|
|
||||||
border.width: 1
|
border.width: 1
|
||||||
radius: 4
|
radius: 4
|
||||||
|
|
||||||
@@ -153,16 +130,6 @@ CheckBox {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Keys.onEnterPressed: {
|
|
||||||
root.checked = !root.checked
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onReturnPressed: {
|
|
||||||
root.checked = !root.checked
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user