mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-24 02:00:24 +07:00
Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/graphview
This commit is contained in:
@@ -68,6 +68,7 @@ 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)
|
||||||
@@ -119,7 +120,9 @@ set(HEADERS ${HEADERS}
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/core/errorstrings.h
|
${CMAKE_CURRENT_LIST_DIR}/core/errorstrings.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/scripts_registry.h
|
${CMAKE_CURRENT_LIST_DIR}/core/scripts_registry.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/server_defs.h
|
${CMAKE_CURRENT_LIST_DIR}/core/server_defs.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/core/controllers/apiController.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/controllers/serverController.h
|
${CMAKE_CURRENT_LIST_DIR}/core/controllers/serverController.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/core/controllers/vpnConfigurationController.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/qml_register_protocols.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/qml_register_protocols.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.h
|
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.h
|
||||||
@@ -159,7 +162,9 @@ set(SOURCES ${SOURCES}
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/core/errorstrings.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/errorstrings.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/scripts_registry.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/scripts_registry.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/server_defs.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/server_defs.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/core/controllers/apiController.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/controllers/serverController.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/controllers/serverController.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/core/controllers/vpnConfigurationController.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.cpp
|
${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.cpp
|
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/qautostart.cpp
|
${CMAKE_CURRENT_LIST_DIR}/ui/qautostart.cpp
|
||||||
|
|||||||
@@ -84,8 +84,7 @@ void AmneziaApplication::init()
|
|||||||
|
|
||||||
m_engine->rootContext()->setContextProperty("Debug", &Logger::Instance());
|
m_engine->rootContext()->setContextProperty("Debug", &Logger::Instance());
|
||||||
|
|
||||||
m_configurator = std::shared_ptr<VpnConfigurator>(new VpnConfigurator(m_settings, this));
|
m_vpnConnection.reset(new VpnConnection(m_settings));
|
||||||
m_vpnConnection.reset(new VpnConnection(m_settings, m_configurator));
|
|
||||||
m_vpnConnection->moveToThread(&m_vpnConnectionThread);
|
m_vpnConnection->moveToThread(&m_vpnConnectionThread);
|
||||||
m_vpnConnectionThread.start();
|
m_vpnConnectionThread.start();
|
||||||
|
|
||||||
@@ -98,18 +97,16 @@ void AmneziaApplication::init()
|
|||||||
qFatal("Android logging initialization failed");
|
qFatal("Android logging initialization failed");
|
||||||
}
|
}
|
||||||
AndroidController::instance()->setSaveLogs(m_settings->isSaveLogs());
|
AndroidController::instance()->setSaveLogs(m_settings->isSaveLogs());
|
||||||
connect(m_settings.get(), &Settings::saveLogsChanged,
|
connect(m_settings.get(), &Settings::saveLogsChanged, AndroidController::instance(), &AndroidController::setSaveLogs);
|
||||||
AndroidController::instance(), &AndroidController::setSaveLogs);
|
|
||||||
|
|
||||||
AndroidController::instance()->setScreenshotsEnabled(m_settings->isScreenshotsEnabled());
|
AndroidController::instance()->setScreenshotsEnabled(m_settings->isScreenshotsEnabled());
|
||||||
connect(m_settings.get(), &Settings::screenshotsEnabledChanged,
|
connect(m_settings.get(), &Settings::screenshotsEnabledChanged, AndroidController::instance(),
|
||||||
AndroidController::instance(), &AndroidController::setScreenshotsEnabled);
|
&AndroidController::setScreenshotsEnabled);
|
||||||
|
|
||||||
connect(m_settings.get(), &Settings::serverRemoved,
|
connect(m_settings.get(), &Settings::serverRemoved, AndroidController::instance(),
|
||||||
AndroidController::instance(), &AndroidController::resetLastServer);
|
&AndroidController::resetLastServer);
|
||||||
|
|
||||||
connect(m_settings.get(), &Settings::settingsCleared,
|
connect(m_settings.get(), &Settings::settingsCleared, []() { AndroidController::instance()->resetLastServer(-1); });
|
||||||
[](){ AndroidController::instance()->resetLastServer(-1); });
|
|
||||||
|
|
||||||
connect(AndroidController::instance(), &AndroidController::initConnectionState, this,
|
connect(AndroidController::instance(), &AndroidController::initConnectionState, this,
|
||||||
[this](Vpn::ConnectionState state) {
|
[this](Vpn::ConnectionState state) {
|
||||||
@@ -146,13 +143,10 @@ void AmneziaApplication::init()
|
|||||||
m_settingsController->importBackupFromOutside(filePath);
|
m_settingsController->importBackupFromOutside(filePath);
|
||||||
});
|
});
|
||||||
|
|
||||||
QTimer::singleShot(0, this, [this](){
|
QTimer::singleShot(0, this, [this]() { AmneziaVPN::toggleScreenshots(m_settings->isScreenshotsEnabled()); });
|
||||||
AmneziaVPN::toggleScreenshots(m_settings->isScreenshotsEnabled());
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_settings.get(), &Settings::screenshotsEnabledChanged, [](bool enabled) {
|
connect(m_settings.get(), &Settings::screenshotsEnabledChanged,
|
||||||
AmneziaVPN::toggleScreenshots(enabled);
|
[](bool enabled) { AmneziaVPN::toggleScreenshots(enabled); });
|
||||||
});
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_notificationHandler.reset(NotificationHandler::create(nullptr));
|
m_notificationHandler.reset(NotificationHandler::create(nullptr));
|
||||||
@@ -368,28 +362,30 @@ void AmneziaApplication::initModels()
|
|||||||
m_engine->rootContext()->setContextProperty("ClientManagementModel", m_clientManagementModel.get());
|
m_engine->rootContext()->setContextProperty("ClientManagementModel", m_clientManagementModel.get());
|
||||||
connect(m_clientManagementModel.get(), &ClientManagementModel::adminConfigRevoked, m_serversModel.get(),
|
connect(m_clientManagementModel.get(), &ClientManagementModel::adminConfigRevoked, m_serversModel.get(),
|
||||||
&ServersModel::clearCachedProfile);
|
&ServersModel::clearCachedProfile);
|
||||||
|
|
||||||
connect(m_configurator.get(), &VpnConfigurator::newVpnConfigCreated, this,
|
|
||||||
[this](const QString &clientId, const QString &clientName, const DockerContainer container,
|
|
||||||
ServerCredentials credentials) {
|
|
||||||
m_serversModel->reloadDefaultServerContainerConfig();
|
|
||||||
m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
|
|
||||||
emit m_configurator->clientModelUpdated();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmneziaApplication::initControllers()
|
void AmneziaApplication::initControllers()
|
||||||
{
|
{
|
||||||
m_connectionController.reset(new ConnectionController(m_serversModel, m_containersModel, m_vpnConnection));
|
m_connectionController.reset(new ConnectionController(m_serversModel, m_containersModel, m_clientManagementModel,
|
||||||
|
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) {
|
||||||
|
emit m_pageController->showErrorMessage(errorMessage);
|
||||||
|
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||||
|
});
|
||||||
|
connect(m_connectionController.get(), &ConnectionController::connectButtonClicked, m_connectionController.get(),
|
||||||
|
&ConnectionController::toggleConnection, Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(this, &AmneziaApplication::translationsUpdated, m_connectionController.get(),
|
connect(this, &AmneziaApplication::translationsUpdated, m_connectionController.get(),
|
||||||
&ConnectionController::onTranslationsUpdated);
|
&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_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);
|
||||||
@@ -401,8 +397,7 @@ void AmneziaApplication::initControllers()
|
|||||||
m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings));
|
m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings));
|
||||||
m_engine->rootContext()->setContextProperty("ImportController", m_importController.get());
|
m_engine->rootContext()->setContextProperty("ImportController", m_importController.get());
|
||||||
|
|
||||||
m_exportController.reset(new ExportController(m_serversModel, m_containersModel, m_clientManagementModel,
|
m_exportController.reset(new ExportController(m_serversModel, m_containersModel, m_clientManagementModel, m_settings));
|
||||||
m_settings, m_configurator));
|
|
||||||
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
||||||
|
|
||||||
m_settingsController.reset(
|
m_settingsController.reset(
|
||||||
@@ -422,18 +417,4 @@ void AmneziaApplication::initControllers()
|
|||||||
|
|
||||||
m_systemController.reset(new SystemController(m_settings));
|
m_systemController.reset(new SystemController(m_settings));
|
||||||
m_engine->rootContext()->setContextProperty("SystemController", m_systemController.get());
|
m_engine->rootContext()->setContextProperty("SystemController", m_systemController.get());
|
||||||
|
|
||||||
m_apiController.reset(new ApiController(m_serversModel, m_containersModel));
|
|
||||||
m_engine->rootContext()->setContextProperty("ApiController", m_apiController.get());
|
|
||||||
connect(m_apiController.get(), &ApiController::updateStarted, this,
|
|
||||||
[this]() { emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Connecting); });
|
|
||||||
connect(m_apiController.get(), &ApiController::errorOccurred, this, [this](const QString &errorMessage) {
|
|
||||||
if (m_connectionController->isConnectionInProgress()) {
|
|
||||||
emit m_pageController->showErrorMessage(errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
|
||||||
});
|
|
||||||
connect(m_apiController.get(), &ApiController::updateFinished, m_connectionController.get(),
|
|
||||||
&ConnectionController::toggleConnection);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "vpnconnection.h"
|
#include "vpnconnection.h"
|
||||||
|
|
||||||
#include "configurators/vpn_configurator.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"
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
#include "ui/controllers/settingsController.h"
|
#include "ui/controllers/settingsController.h"
|
||||||
#include "ui/controllers/sitesController.h"
|
#include "ui/controllers/sitesController.h"
|
||||||
#include "ui/controllers/systemController.h"
|
#include "ui/controllers/systemController.h"
|
||||||
#include "ui/controllers/apiController.h"
|
|
||||||
#include "ui/controllers/appSplitTunnelingController.h"
|
#include "ui/controllers/appSplitTunnelingController.h"
|
||||||
#include "ui/models/containers_model.h"
|
#include "ui/models/containers_model.h"
|
||||||
#include "ui/models/languageModel.h"
|
#include "ui/models/languageModel.h"
|
||||||
@@ -82,7 +81,6 @@ private:
|
|||||||
|
|
||||||
QQmlApplicationEngine *m_engine {};
|
QQmlApplicationEngine *m_engine {};
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
std::shared_ptr<VpnConfigurator> m_configurator;
|
|
||||||
|
|
||||||
QSharedPointer<ContainerProps> m_containerProps;
|
QSharedPointer<ContainerProps> m_containerProps;
|
||||||
QSharedPointer<ProtocolProps> m_protocolProps;
|
QSharedPointer<ProtocolProps> m_protocolProps;
|
||||||
|
|||||||
@@ -406,16 +406,19 @@ 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-z .]+".toRegex(IGNORE_CASE)
|
val extensionRegex = "\\*\\.([a-z0-9]+)".toRegex(IGNORE_CASE)
|
||||||
val mime = MimeTypeMap.getSingleton()
|
val mime = MimeTypeMap.getSingleton()
|
||||||
extensionRegex.findAll(filter).map {
|
extensionRegex.findAll(filter).map {
|
||||||
mime.getMimeTypeFromExtension(it.value.drop(2))
|
it.groups[1]?.value?.let { mime.getMimeTypeFromExtension(it) } ?: "*/*"
|
||||||
}.filterNotNull().toSet()
|
}.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()
|
||||||
|
|
||||||
@@ -426,6 +429,7 @@ class AmneziaActivity : QtActivity() {
|
|||||||
|
|
||||||
else -> type = "*/*"
|
else -> type = "*/*"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}.also {
|
}.also {
|
||||||
startActivityForResult(it, OPEN_FILE_ACTION_CODE)
|
startActivityForResult(it, OPEN_FILE_ACTION_CODE)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,11 +113,13 @@ target_sources(${PROJECT} PRIVATE
|
|||||||
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)
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ AwgConfigurator::AwgConfigurator(std::shared_ptr<Settings> settings, QObject *pa
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AwgConfigurator::genAwgConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString AwgConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
QString config = WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, clientId, errorCode);
|
QString config = WireguardConfigurator::createConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
QJsonObject jsonConfig = QJsonDocument::fromJson(config.toUtf8()).object();
|
QJsonObject jsonConfig = QJsonDocument::fromJson(config.toUtf8()).object();
|
||||||
QString awgConfig = jsonConfig.value(config_key::config).toString();
|
QString awgConfig = jsonConfig.value(config_key::config).toString();
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ class AwgConfigurator : public WireguardConfigurator
|
|||||||
public:
|
public:
|
||||||
AwgConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
AwgConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString genAwgConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode errorCode);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AWGCONFIGURATOR_H
|
#endif // AWGCONFIGURATOR_H
|
||||||
|
|||||||
@@ -13,22 +13,24 @@ CloakConfigurator::CloakConfigurator(std::shared_ptr<Settings> settings, QObject
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CloakConfigurator::genCloakConfig(const ServerCredentials &credentials,
|
QString CloakConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
ErrorCode e = ErrorCode::NoError;
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
|
|
||||||
QString cloakPublicKey = serverController.getTextFileFromContainer(container, credentials,
|
QString cloakPublicKey = serverController.getTextFileFromContainer(container, credentials,
|
||||||
amnezia::protocols::cloak::ckPublicKeyPath, &e);
|
amnezia::protocols::cloak::ckPublicKeyPath, errorCode);
|
||||||
cloakPublicKey.replace("\n", "");
|
cloakPublicKey.replace("\n", "");
|
||||||
|
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
QString cloakBypassUid = serverController.getTextFileFromContainer(container, credentials,
|
QString cloakBypassUid = serverController.getTextFileFromContainer(container, credentials,
|
||||||
amnezia::protocols::cloak::ckBypassUidKeyPath, &e);
|
amnezia::protocols::cloak::ckBypassUidKeyPath, errorCode);
|
||||||
cloakBypassUid.replace("\n", "");
|
cloakBypassUid.replace("\n", "");
|
||||||
|
|
||||||
if (e) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
if (errorCode) *errorCode = e;
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,14 @@
|
|||||||
|
|
||||||
using namespace amnezia;
|
using namespace amnezia;
|
||||||
|
|
||||||
class CloakConfigurator : ConfiguratorBase
|
class CloakConfigurator : public ConfiguratorBase
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
CloakConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
CloakConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString genCloakConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode errorCode);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CLOAK_CONFIGURATOR_H
|
#endif // CLOAK_CONFIGURATOR_H
|
||||||
|
|||||||
@@ -1,8 +1,26 @@
|
|||||||
#include "configurator_base.h"
|
#include "configurator_base.h"
|
||||||
|
|
||||||
ConfiguratorBase::ConfiguratorBase(std::shared_ptr<Settings> settings, QObject *parent)
|
ConfiguratorBase::ConfiguratorBase(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
: QObject{parent},
|
: QObject { parent }, m_settings(settings)
|
||||||
m_settings(settings)
|
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ConfiguratorBase::processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
||||||
|
QString &protocolConfigString)
|
||||||
|
{
|
||||||
|
processConfigWithDnsSettings(dns, protocolConfigString);
|
||||||
|
return protocolConfigString;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ConfiguratorBase::processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
||||||
|
QString &protocolConfigString)
|
||||||
|
{
|
||||||
|
processConfigWithDnsSettings(dns, protocolConfigString);
|
||||||
|
return protocolConfigString;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfiguratorBase::processConfigWithDnsSettings(const QPair<QString, QString> &dns, QString &protocolConfigString)
|
||||||
|
{
|
||||||
|
protocolConfigString.replace("$PRIMARY_DNS", dns.first);
|
||||||
|
protocolConfigString.replace("$SECONDARY_DNS", dns.second);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,9 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class Settings;
|
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "core/defs.h"
|
#include "core/defs.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
class ConfiguratorBase : public QObject
|
class ConfiguratorBase : public QObject
|
||||||
{
|
{
|
||||||
@@ -14,7 +13,17 @@ class ConfiguratorBase : public QObject
|
|||||||
public:
|
public:
|
||||||
explicit ConfiguratorBase(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
explicit ConfiguratorBase(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
virtual QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
const QJsonObject &containerConfig, ErrorCode errorCode) = 0;
|
||||||
|
|
||||||
|
virtual QString processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
||||||
|
QString &protocolConfigString);
|
||||||
|
virtual QString processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
||||||
|
QString &protocolConfigString);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void processConfigWithDnsSettings(const QPair<QString, QString> &dns, QString &protocolConfigString);
|
||||||
|
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, QObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials,
|
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials,
|
||||||
DockerContainer container, ErrorCode *errorCode)
|
DockerContainer container, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
Ikev2Configurator::ConnectionData connData;
|
Ikev2Configurator::ConnectionData connData;
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
@@ -40,17 +40,17 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
|||||||
.arg(connData.clientId);
|
.arg(connData.clientId);
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
ErrorCode e = serverController.runContainerScript(credentials, container, scriptCreateCert);
|
errorCode = serverController.runContainerScript(credentials, container, scriptCreateCert);
|
||||||
|
|
||||||
QString scriptExportCert = QString("pk12util -W \"%1\" -d sql:/etc/ipsec.d -n \"%2\" -o \"%3\"")
|
QString scriptExportCert = QString("pk12util -W \"%1\" -d sql:/etc/ipsec.d -n \"%2\" -o \"%3\"")
|
||||||
.arg(connData.password)
|
.arg(connData.password)
|
||||||
.arg(connData.clientId)
|
.arg(connData.clientId)
|
||||||
.arg(certFileName);
|
.arg(certFileName);
|
||||||
e = serverController.runContainerScript(credentials, container, scriptExportCert);
|
errorCode = serverController.runContainerScript(credentials, container, scriptExportCert);
|
||||||
|
|
||||||
connData.clientCert = serverController.getTextFileFromContainer(container, credentials, certFileName, &e);
|
connData.clientCert = serverController.getTextFileFromContainer(container, credentials, certFileName, errorCode);
|
||||||
connData.caCert =
|
connData.caCert =
|
||||||
serverController.getTextFileFromContainer(container, credentials, "/etc/ipsec.d/ca_cert_base64.p12", &e);
|
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();
|
||||||
@@ -58,13 +58,13 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
|||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Ikev2Configurator::genIkev2Config(const ServerCredentials &credentials, DockerContainer container,
|
QString Ikev2Configurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
Q_UNUSED(containerConfig)
|
Q_UNUSED(containerConfig)
|
||||||
|
|
||||||
ConnectionData connData = prepareIkev2Config(credentials, container, errorCode);
|
ConnectionData connData = prepareIkev2Config(credentials, container, errorCode);
|
||||||
if (errorCode && *errorCode) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "configurator_base.h"
|
#include "configurator_base.h"
|
||||||
#include "core/defs.h"
|
#include "core/defs.h"
|
||||||
|
|
||||||
class Ikev2Configurator : ConfiguratorBase
|
class Ikev2Configurator : public ConfiguratorBase
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@@ -21,15 +21,15 @@ public:
|
|||||||
QString host; // host ip
|
QString host; // host ip
|
||||||
};
|
};
|
||||||
|
|
||||||
QString genIkev2Config(const ServerCredentials &credentials, DockerContainer container,
|
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode errorCode);
|
||||||
|
|
||||||
QString genIkev2Config(const ConnectionData &connData);
|
QString genIkev2Config(const ConnectionData &connData);
|
||||||
QString genMobileConfig(const ConnectionData &connData);
|
QString genMobileConfig(const ConnectionData &connData);
|
||||||
QString genStrongSwanConfig(const ConnectionData &connData);
|
QString genStrongSwanConfig(const ConnectionData &connData);
|
||||||
|
|
||||||
ConnectionData prepareIkev2Config(const ServerCredentials &credentials,
|
ConnectionData prepareIkev2Config(const ServerCredentials &credentials,
|
||||||
DockerContainer container, ErrorCode *errorCode = nullptr);
|
DockerContainer container, ErrorCode errorCode);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IKEV2_CONFIGURATOR_H
|
#endif // IKEV2_CONFIGURATOR_H
|
||||||
|
|||||||
@@ -14,9 +14,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#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 "settings.h"
|
#include "settings.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
@@ -31,59 +31,51 @@ OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr<Settings> settings, QOb
|
|||||||
|
|
||||||
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials,
|
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials,
|
||||||
DockerContainer container,
|
DockerContainer container,
|
||||||
ErrorCode *errorCode)
|
ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
|
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
|
|
||||||
if (connData.privKey.isEmpty() || connData.request.isEmpty()) {
|
if (connData.privKey.isEmpty() || connData.request.isEmpty()) {
|
||||||
if (errorCode)
|
errorCode = ErrorCode::OpenSslFailed;
|
||||||
*errorCode = ErrorCode::OpenSslFailed;
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
ErrorCode e = serverController.uploadTextFileToContainer(container, credentials, connData.request, reqFileName);
|
errorCode = serverController.uploadTextFileToContainer(container, credentials, connData.request, reqFileName);
|
||||||
if (e) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
if (errorCode)
|
|
||||||
*errorCode = e;
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
e = signCert(container, credentials, connData.clientId);
|
errorCode = signCert(container, credentials, connData.clientId);
|
||||||
if (e) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
if (errorCode)
|
|
||||||
*errorCode = e;
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.caCert = serverController.getTextFileFromContainer(container, credentials,
|
connData.caCert = serverController.getTextFileFromContainer(container, credentials,
|
||||||
amnezia::protocols::openvpn::caCertPath, &e);
|
amnezia::protocols::openvpn::caCertPath, errorCode);
|
||||||
connData.clientCert = serverController.getTextFileFromContainer(
|
connData.clientCert = serverController.getTextFileFromContainer(
|
||||||
container, credentials,
|
container, credentials,
|
||||||
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), &e);
|
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), errorCode);
|
||||||
|
|
||||||
if (e) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
if (errorCode)
|
|
||||||
*errorCode = e;
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.taKey = serverController.getTextFileFromContainer(container, credentials,
|
connData.taKey = serverController.getTextFileFromContainer(container, credentials,
|
||||||
amnezia::protocols::openvpn::taKeyPath, &e);
|
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()) {
|
||||||
if (errorCode)
|
errorCode = ErrorCode::SshScpFailureError;
|
||||||
*errorCode = ErrorCode::SshScpFailureError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString OpenVpnConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
QString config =
|
QString config =
|
||||||
@@ -91,7 +83,7 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
|
|||||||
serverController.genVarsForScript(credentials, container, containerConfig));
|
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode);
|
ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode);
|
||||||
if (errorCode && *errorCode) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,17 +105,20 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
|
|||||||
QJsonObject jConfig;
|
QJsonObject jConfig;
|
||||||
jConfig[config_key::config] = config;
|
jConfig[config_key::config] = config;
|
||||||
|
|
||||||
clientId = connData.clientId;
|
jConfig[config_key::clientId] = connData.clientId;
|
||||||
|
|
||||||
return QJsonDocument(jConfig).toJson();
|
return QJsonDocument(jConfig).toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OpenVpnConfigurator::processConfigWithLocalSettings(QString jsonConfig, const int serverIndex)
|
QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
||||||
|
QString &protocolConfigString)
|
||||||
{
|
{
|
||||||
QJsonObject json = QJsonDocument::fromJson(jsonConfig.toUtf8()).object();
|
processConfigWithDnsSettings(dns, protocolConfigString);
|
||||||
|
|
||||||
|
QJsonObject json = QJsonDocument::fromJson(protocolConfigString.toUtf8()).object();
|
||||||
QString config = json[config_key::config].toString();
|
QString config = json[config_key::config].toString();
|
||||||
|
|
||||||
if (!m_settings->server(serverIndex).value(config_key::configVersion).toInt()) {
|
if (!isApiConfig) {
|
||||||
QRegularExpression regex("redirect-gateway.*");
|
QRegularExpression regex("redirect-gateway.*");
|
||||||
config.replace(regex, "");
|
config.replace(regex, "");
|
||||||
|
|
||||||
@@ -164,9 +159,12 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString jsonConfig,
|
|||||||
return QJsonDocument(json).toJson();
|
return QJsonDocument(json).toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OpenVpnConfigurator::processConfigWithExportSettings(QString jsonConfig)
|
QString OpenVpnConfigurator::processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
||||||
|
QString &protocolConfigString)
|
||||||
{
|
{
|
||||||
QJsonObject json = QJsonDocument::fromJson(jsonConfig.toUtf8()).object();
|
processConfigWithDnsSettings(dns, protocolConfigString);
|
||||||
|
|
||||||
|
QJsonObject json = QJsonDocument::fromJson(protocolConfigString.toUtf8()).object();
|
||||||
QString config = json[config_key::config].toString();
|
QString config = json[config_key::config].toString();
|
||||||
|
|
||||||
QRegularExpression regex("redirect-gateway.*");
|
QRegularExpression regex("redirect-gateway.*");
|
||||||
|
|||||||
@@ -7,13 +7,14 @@
|
|||||||
#include "configurator_base.h"
|
#include "configurator_base.h"
|
||||||
#include "core/defs.h"
|
#include "core/defs.h"
|
||||||
|
|
||||||
class OpenVpnConfigurator : ConfiguratorBase
|
class OpenVpnConfigurator : public ConfiguratorBase
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
OpenVpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
OpenVpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
struct ConnectionData {
|
struct ConnectionData
|
||||||
|
{
|
||||||
QString clientId;
|
QString clientId;
|
||||||
QString request; // certificate request
|
QString request; // certificate request
|
||||||
QString privKey; // client private key
|
QString privKey; // client private key
|
||||||
@@ -23,21 +24,20 @@ public:
|
|||||||
QString host; // host ip
|
QString host; // host ip
|
||||||
};
|
};
|
||||||
|
|
||||||
QString genOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode errorCode);
|
||||||
|
|
||||||
QString processConfigWithLocalSettings(QString jsonConfig, const int serverIndex);
|
QString processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
||||||
QString processConfigWithExportSettings(QString jsonConfig);
|
QString &protocolConfigString);
|
||||||
|
QString processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
||||||
ErrorCode signCert(DockerContainer container,
|
QString &protocolConfigString);
|
||||||
const ServerCredentials &credentials, QString clientId);
|
|
||||||
|
|
||||||
static ConnectionData createCertRequest();
|
static ConnectionData createCertRequest();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConnectionData prepareOpenVpnConfig(const ServerCredentials &credentials,
|
ConnectionData prepareOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, ErrorCode *errorCode = nullptr);
|
ErrorCode errorCode);
|
||||||
|
ErrorCode signCert(DockerContainer container, const ServerCredentials &credentials, QString clientId);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OPENVPN_CONFIGURATOR_H
|
#endif // OPENVPN_CONFIGURATOR_H
|
||||||
|
|||||||
@@ -13,18 +13,16 @@ ShadowSocksConfigurator::ShadowSocksConfigurator(std::shared_ptr<Settings> setti
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ShadowSocksConfigurator::genShadowSocksConfig(const ServerCredentials &credentials,
|
QString ShadowSocksConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
ErrorCode e = ErrorCode::NoError;
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
|
|
||||||
QString ssKey = serverController.getTextFileFromContainer(container, credentials,
|
QString ssKey = serverController.getTextFileFromContainer(container, credentials,
|
||||||
amnezia::protocols::shadowsocks::ssKeyPath, &e);
|
amnezia::protocols::shadowsocks::ssKeyPath, errorCode);
|
||||||
ssKey.replace("\n", "");
|
ssKey.replace("\n", "");
|
||||||
|
|
||||||
if (e) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
if (errorCode) *errorCode = e;
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,14 @@
|
|||||||
#include "configurator_base.h"
|
#include "configurator_base.h"
|
||||||
#include "core/defs.h"
|
#include "core/defs.h"
|
||||||
|
|
||||||
class ShadowSocksConfigurator : ConfiguratorBase
|
class ShadowSocksConfigurator : public ConfiguratorBase
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ShadowSocksConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
ShadowSocksConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString genShadowSocksConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode errorCode);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHADOWSOCKS_CONFIGURATOR_H
|
#endif // SHADOWSOCKS_CONFIGURATOR_H
|
||||||
|
|||||||
@@ -1,131 +0,0 @@
|
|||||||
#include "vpn_configurator.h"
|
|
||||||
#include "cloak_configurator.h"
|
|
||||||
#include "ikev2_configurator.h"
|
|
||||||
#include "openvpn_configurator.h"
|
|
||||||
#include "shadowsocks_configurator.h"
|
|
||||||
#include "ssh_configurator.h"
|
|
||||||
#include "wireguard_configurator.h"
|
|
||||||
#include "awg_configurator.h"
|
|
||||||
#include "xray_configurator.h"
|
|
||||||
#include <QFile>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
|
||||||
#include "settings.h"
|
|
||||||
#include "core/networkUtilities.h"
|
|
||||||
|
|
||||||
VpnConfigurator::VpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
|
||||||
: ConfiguratorBase(settings, parent)
|
|
||||||
{
|
|
||||||
openVpnConfigurator = std::shared_ptr<OpenVpnConfigurator>(new OpenVpnConfigurator(settings, this));
|
|
||||||
shadowSocksConfigurator = std::shared_ptr<ShadowSocksConfigurator>(new ShadowSocksConfigurator(settings, this));
|
|
||||||
cloakConfigurator = std::shared_ptr<CloakConfigurator>(new CloakConfigurator(settings, this));
|
|
||||||
wireguardConfigurator = std::shared_ptr<WireguardConfigurator>(new WireguardConfigurator(settings, false, this));
|
|
||||||
ikev2Configurator = std::shared_ptr<Ikev2Configurator>(new Ikev2Configurator(settings, this));
|
|
||||||
sshConfigurator = std::shared_ptr<SshConfigurator>(new SshConfigurator(settings, this));
|
|
||||||
awgConfigurator = std::shared_ptr<AwgConfigurator>(new AwgConfigurator(settings, this));
|
|
||||||
xrayConfigurator = std::shared_ptr<XrayConfigurator>(new XrayConfigurator(settings, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
|
|
||||||
const QJsonObject &containerConfig, Proto proto, QString &clientId, ErrorCode *errorCode)
|
|
||||||
{
|
|
||||||
switch (proto) {
|
|
||||||
case Proto::OpenVpn:
|
|
||||||
return openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig, clientId, errorCode);
|
|
||||||
|
|
||||||
case Proto::ShadowSocks:
|
|
||||||
return shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, errorCode);
|
|
||||||
|
|
||||||
case Proto::Cloak: return cloakConfigurator->genCloakConfig(credentials, container, containerConfig, errorCode);
|
|
||||||
|
|
||||||
case Proto::WireGuard:
|
|
||||||
return wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, clientId, errorCode);
|
|
||||||
|
|
||||||
case Proto::Awg:
|
|
||||||
return awgConfigurator->genAwgConfig(credentials, container, containerConfig, clientId, errorCode);
|
|
||||||
|
|
||||||
case Proto::Xray:
|
|
||||||
return xrayConfigurator->genXrayConfig(credentials, container, containerConfig, clientId, errorCode);
|
|
||||||
|
|
||||||
case Proto::Ikev2: return ikev2Configurator->genIkev2Config(credentials, container, containerConfig, errorCode);
|
|
||||||
|
|
||||||
default: return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QPair<QString, QString> VpnConfigurator::getDnsForConfig(int serverIndex)
|
|
||||||
{
|
|
||||||
QPair<QString, QString> dns;
|
|
||||||
|
|
||||||
bool useAmneziaDns = m_settings->useAmneziaDns();
|
|
||||||
const QJsonObject &server = m_settings->server(serverIndex);
|
|
||||||
|
|
||||||
dns.first = server.value(config_key::dns1).toString();
|
|
||||||
dns.second = server.value(config_key::dns2).toString();
|
|
||||||
|
|
||||||
if (dns.first.isEmpty() || !NetworkUtilities::checkIPv4Format(dns.first)) {
|
|
||||||
if (useAmneziaDns && m_settings->containers(serverIndex).contains(DockerContainer::Dns)) {
|
|
||||||
dns.first = protocols::dns::amneziaDnsIp;
|
|
||||||
} else
|
|
||||||
dns.first = m_settings->primaryDns();
|
|
||||||
}
|
|
||||||
if (dns.second.isEmpty() || !NetworkUtilities::checkIPv4Format(dns.second)) {
|
|
||||||
dns.second = m_settings->secondaryDns();
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << "VpnConfigurator::getDnsForConfig" << dns.first << dns.second;
|
|
||||||
return dns;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString &VpnConfigurator::processConfigWithDnsSettings(int serverIndex, DockerContainer container, Proto proto,
|
|
||||||
QString &config)
|
|
||||||
{
|
|
||||||
auto dns = getDnsForConfig(serverIndex);
|
|
||||||
|
|
||||||
config.replace("$PRIMARY_DNS", dns.first);
|
|
||||||
config.replace("$SECONDARY_DNS", dns.second);
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString &VpnConfigurator::processConfigWithLocalSettings(int serverIndex, DockerContainer container, Proto proto,
|
|
||||||
QString &config)
|
|
||||||
{
|
|
||||||
processConfigWithDnsSettings(serverIndex, container, proto, config);
|
|
||||||
|
|
||||||
if (proto == Proto::OpenVpn) {
|
|
||||||
config = openVpnConfigurator->processConfigWithLocalSettings(config, serverIndex);
|
|
||||||
}
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString &VpnConfigurator::processConfigWithExportSettings(int serverIndex, DockerContainer container, Proto proto,
|
|
||||||
QString &config)
|
|
||||||
{
|
|
||||||
processConfigWithDnsSettings(serverIndex, container, proto, config);
|
|
||||||
|
|
||||||
if (proto == Proto::OpenVpn) {
|
|
||||||
config = openVpnConfigurator->processConfigWithExportSettings(config);
|
|
||||||
}
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnConfigurator::updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig,
|
|
||||||
const QString &stdOut)
|
|
||||||
{
|
|
||||||
Proto mainProto = ContainerProps::defaultProtocol(container);
|
|
||||||
|
|
||||||
if (container == DockerContainer::TorWebSite) {
|
|
||||||
QJsonObject protocol = containerConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
|
|
||||||
|
|
||||||
qDebug() << "amnezia-tor onions" << stdOut;
|
|
||||||
|
|
||||||
QString onion = stdOut;
|
|
||||||
onion.replace("\n", "");
|
|
||||||
protocol.insert(config_key::site, onion);
|
|
||||||
|
|
||||||
containerConfig.insert(ProtocolProps::protoToString(mainProto), protocol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
#ifndef VPN_CONFIGURATOR_H
|
|
||||||
#define VPN_CONFIGURATOR_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
#include "configurator_base.h"
|
|
||||||
#include "core/defs.h"
|
|
||||||
|
|
||||||
class OpenVpnConfigurator;
|
|
||||||
class ShadowSocksConfigurator;
|
|
||||||
class CloakConfigurator;
|
|
||||||
class WireguardConfigurator;
|
|
||||||
class Ikev2Configurator;
|
|
||||||
class SshConfigurator;
|
|
||||||
class AwgConfigurator;
|
|
||||||
class XrayConfigurator;
|
|
||||||
|
|
||||||
// Retrieve connection settings from server
|
|
||||||
class VpnConfigurator : public ConfiguratorBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit VpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
|
|
||||||
const QJsonObject &containerConfig, Proto proto, QString &clientId,
|
|
||||||
ErrorCode *errorCode = nullptr);
|
|
||||||
|
|
||||||
QPair<QString, QString> getDnsForConfig(int serverIndex);
|
|
||||||
QString &processConfigWithDnsSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
|
|
||||||
|
|
||||||
QString &processConfigWithLocalSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
|
|
||||||
QString &processConfigWithExportSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
|
|
||||||
|
|
||||||
// workaround for containers which is not support normal configuration
|
|
||||||
void updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig,
|
|
||||||
const QString &stdOut);
|
|
||||||
|
|
||||||
std::shared_ptr<OpenVpnConfigurator> openVpnConfigurator;
|
|
||||||
std::shared_ptr<ShadowSocksConfigurator> shadowSocksConfigurator;
|
|
||||||
std::shared_ptr<CloakConfigurator> cloakConfigurator;
|
|
||||||
std::shared_ptr<WireguardConfigurator> wireguardConfigurator;
|
|
||||||
std::shared_ptr<Ikev2Configurator> ikev2Configurator;
|
|
||||||
std::shared_ptr<SshConfigurator> sshConfigurator;
|
|
||||||
std::shared_ptr<AwgConfigurator> awgConfigurator;
|
|
||||||
std::shared_ptr<XrayConfigurator> xrayConfigurator;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void newVpnConfigCreated(const QString &clientId, const QString &clientName, const DockerContainer container,
|
|
||||||
ServerCredentials credentials);
|
|
||||||
void clientModelUpdated();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // VPN_CONFIGURATOR_H
|
|
||||||
@@ -13,23 +13,22 @@
|
|||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
|
|
||||||
#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 "settings.h"
|
#include "settings.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, bool isAwg, QObject *parent)
|
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, bool isAwg, QObject *parent)
|
||||||
: ConfiguratorBase(settings, parent), m_isAwg(isAwg)
|
: ConfiguratorBase(settings, parent), m_isAwg(isAwg)
|
||||||
{
|
{
|
||||||
m_serverConfigPath = m_isAwg ? amnezia::protocols::awg::serverConfigPath
|
m_serverConfigPath =
|
||||||
: amnezia::protocols::wireguard::serverConfigPath;
|
m_isAwg ? amnezia::protocols::awg::serverConfigPath : amnezia::protocols::wireguard::serverConfigPath;
|
||||||
m_serverPublicKeyPath = m_isAwg ? amnezia::protocols::awg::serverPublicKeyPath
|
m_serverPublicKeyPath =
|
||||||
: amnezia::protocols::wireguard::serverPublicKeyPath;
|
m_isAwg ? amnezia::protocols::awg::serverPublicKeyPath : amnezia::protocols::wireguard::serverPublicKeyPath;
|
||||||
m_serverPskKeyPath = m_isAwg ? amnezia::protocols::awg::serverPskKeyPath
|
m_serverPskKeyPath =
|
||||||
: amnezia::protocols::wireguard::serverPskKeyPath;
|
m_isAwg ? amnezia::protocols::awg::serverPskKeyPath : amnezia::protocols::wireguard::serverPskKeyPath;
|
||||||
m_configTemplate = m_isAwg ? ProtocolScriptType::awg_template
|
m_configTemplate = m_isAwg ? ProtocolScriptType::awg_template : ProtocolScriptType::wireguard_template;
|
||||||
: ProtocolScriptType::wireguard_template;
|
|
||||||
|
|
||||||
m_protocolName = m_isAwg ? config_key::awg : config_key::wireguard;
|
m_protocolName = m_isAwg ? config_key::awg : config_key::wireguard;
|
||||||
m_defaultPort = m_isAwg ? protocols::wireguard::defaultPort : protocols::awg::defaultPort;
|
m_defaultPort = m_isAwg ? protocols::wireguard::defaultPort : protocols::awg::defaultPort;
|
||||||
@@ -69,19 +68,17 @@ 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,
|
const QJsonObject &containerConfig,
|
||||||
ErrorCode *errorCode)
|
ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
|
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
connData.port = containerConfig.value(m_protocolName).toObject().value(config_key::port).toString(m_defaultPort);
|
connData.port = containerConfig.value(m_protocolName).toObject().value(config_key::port).toString(m_defaultPort);
|
||||||
|
|
||||||
if (connData.clientPrivKey.isEmpty() || connData.clientPubKey.isEmpty()) {
|
if (connData.clientPrivKey.isEmpty() || connData.clientPubKey.isEmpty()) {
|
||||||
if (errorCode)
|
errorCode = ErrorCode::InternalError;
|
||||||
*errorCode = ErrorCode::InternalError;
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
|
|
||||||
// Get list of already created clients (only IP addresses)
|
// Get list of already created clients (only IP addresses)
|
||||||
@@ -94,9 +91,8 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
};
|
};
|
||||||
|
|
||||||
e = serverController.runContainerScript(credentials, container, script, cbReadStdOut);
|
errorCode = serverController.runContainerScript(credentials, container, script, cbReadStdOut);
|
||||||
if (errorCode && e) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
*errorCode = e;
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,8 +106,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
} else {
|
} else {
|
||||||
int next = ips.last().split(".").last().toInt() + 1;
|
int next = ips.last().split(".").last().toInt() + 1;
|
||||||
if (next > 254) {
|
if (next > 254) {
|
||||||
if (errorCode)
|
errorCode = ErrorCode::AddressPoolError;
|
||||||
*errorCode = ErrorCode::AddressPoolError;
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
nextIpNumber = QString::number(next);
|
nextIpNumber = QString::number(next);
|
||||||
@@ -123,8 +118,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
{
|
{
|
||||||
QStringList l = subnetIp.split(".", Qt::SkipEmptyParts);
|
QStringList l = subnetIp.split(".", Qt::SkipEmptyParts);
|
||||||
if (l.isEmpty()) {
|
if (l.isEmpty()) {
|
||||||
if (errorCode)
|
errorCode = ErrorCode::AddressPoolError;
|
||||||
*errorCode = ErrorCode::AddressPoolError;
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
l.removeLast();
|
l.removeLast();
|
||||||
@@ -134,20 +128,17 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get keys
|
// Get keys
|
||||||
connData.serverPubKey = serverController.getTextFileFromContainer(container, credentials, m_serverPublicKeyPath, &e);
|
connData.serverPubKey =
|
||||||
|
serverController.getTextFileFromContainer(container, credentials, m_serverPublicKeyPath, errorCode);
|
||||||
connData.serverPubKey.replace("\n", "");
|
connData.serverPubKey.replace("\n", "");
|
||||||
if (e) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
if (errorCode)
|
|
||||||
*errorCode = e;
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.pskKey = serverController.getTextFileFromContainer(container, credentials, m_serverPskKeyPath, &e);
|
connData.pskKey = serverController.getTextFileFromContainer(container, credentials, m_serverPskKeyPath, errorCode);
|
||||||
connData.pskKey.replace("\n", "");
|
connData.pskKey.replace("\n", "");
|
||||||
|
|
||||||
if (e) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
if (errorCode)
|
|
||||||
*errorCode = e;
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,26 +149,24 @@ 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);
|
||||||
|
|
||||||
e = serverController.uploadTextFileToContainer(container, credentials, configPart, m_serverConfigPath,
|
errorCode = serverController.uploadTextFileToContainer(container, credentials, configPart, m_serverConfigPath,
|
||||||
libssh::ScpOverwriteMode::ScpAppendToExisting);
|
libssh::ScpOverwriteMode::ScpAppendToExisting);
|
||||||
|
|
||||||
if (e) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
if (errorCode)
|
|
||||||
*errorCode = e;
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString script = QString("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'")
|
QString script = QString("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'")
|
||||||
.arg(m_serverConfigPath);
|
.arg(m_serverConfigPath);
|
||||||
|
|
||||||
e = serverController.runScript(
|
errorCode = serverController.runScript(
|
||||||
credentials, serverController.replaceVars(script, serverController.genVarsForScript(credentials, container)));
|
credentials, serverController.replaceVars(script, serverController.genVarsForScript(credentials, container)));
|
||||||
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString WireguardConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
QString scriptData = amnezia::scriptData(m_configTemplate, container);
|
QString scriptData = amnezia::scriptData(m_configTemplate, container);
|
||||||
@@ -185,7 +174,7 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede
|
|||||||
scriptData, 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) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,30 +194,25 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede
|
|||||||
jConfig[config_key::client_pub_key] = connData.clientPubKey;
|
jConfig[config_key::client_pub_key] = connData.clientPubKey;
|
||||||
jConfig[config_key::psk_key] = connData.pskKey;
|
jConfig[config_key::psk_key] = connData.pskKey;
|
||||||
jConfig[config_key::server_pub_key] = connData.serverPubKey;
|
jConfig[config_key::server_pub_key] = connData.serverPubKey;
|
||||||
|
|
||||||
jConfig[config_key::mtu] = wireguarConfig.value(config_key::mtu).toString(protocols::wireguard::defaultMtu);
|
jConfig[config_key::mtu] = wireguarConfig.value(config_key::mtu).toString(protocols::wireguard::defaultMtu);
|
||||||
|
|
||||||
clientId = connData.clientPubKey;
|
jConfig[config_key::clientId] = connData.clientPubKey;
|
||||||
|
|
||||||
return QJsonDocument(jConfig).toJson();
|
return QJsonDocument(jConfig).toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WireguardConfigurator::processConfigWithLocalSettings(QString config)
|
QString WireguardConfigurator::processConfigWithLocalSettings(const QPair<QString, QString> &dns,
|
||||||
|
const bool isApiConfig, QString &protocolConfigString)
|
||||||
{
|
{
|
||||||
// TODO replace DNS if it already set
|
processConfigWithDnsSettings(dns, protocolConfigString);
|
||||||
config.replace("$PRIMARY_DNS", m_settings->primaryDns());
|
|
||||||
config.replace("$SECONDARY_DNS", m_settings->secondaryDns());
|
|
||||||
|
|
||||||
QJsonObject jConfig;
|
return protocolConfigString;
|
||||||
jConfig[config_key::config] = config;
|
|
||||||
|
|
||||||
return QJsonDocument(jConfig).toJson();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WireguardConfigurator::processConfigWithExportSettings(QString config)
|
QString WireguardConfigurator::processConfigWithExportSettings(const QPair<QString, QString> &dns,
|
||||||
|
const bool isApiConfig, QString &protocolConfigString)
|
||||||
{
|
{
|
||||||
config.replace("$PRIMARY_DNS", m_settings->primaryDns());
|
processConfigWithDnsSettings(dns, protocolConfigString);
|
||||||
config.replace("$SECONDARY_DNS", m_settings->secondaryDns());
|
|
||||||
|
|
||||||
return config;
|
return protocolConfigString;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,17 +25,19 @@ public:
|
|||||||
QString port;
|
QString port;
|
||||||
};
|
};
|
||||||
|
|
||||||
QString genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode errorCode);
|
||||||
|
|
||||||
QString processConfigWithLocalSettings(QString config);
|
QString processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
||||||
QString processConfigWithExportSettings(QString config);
|
QString &protocolConfigString);
|
||||||
|
QString processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
|
||||||
|
QString &protocolConfigString);
|
||||||
|
|
||||||
static ConnectionData genClientKeys();
|
static ConnectionData genClientKeys();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConnectionData prepareWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
ConnectionData prepareWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode errorCode);
|
||||||
|
|
||||||
bool m_isAwg;
|
bool m_isAwg;
|
||||||
QString m_serverConfigPath;
|
QString m_serverConfigPath;
|
||||||
|
|||||||
@@ -1,43 +1,36 @@
|
|||||||
#include "xray_configurator.h"
|
#include "xray_configurator.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
#include "core/scripts_registry.h"
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "core/controllers/serverController.h"
|
#include "core/controllers/serverController.h"
|
||||||
|
#include "core/scripts_registry.h"
|
||||||
|
|
||||||
XrayConfigurator::XrayConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
XrayConfigurator::XrayConfigurator(std::shared_ptr<Settings> settings, QObject *parent) : ConfiguratorBase(settings, parent)
|
||||||
ConfiguratorBase(settings, parent)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString XrayConfigurator::genXrayConfig(const ServerCredentials &credentials,
|
QString XrayConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode)
|
ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
ErrorCode e = ErrorCode::NoError;
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
|
|
||||||
QString config =
|
QString config = serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::xray_template, container),
|
||||||
serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::xray_template, container),
|
|
||||||
serverController.genVarsForScript(credentials, container, containerConfig));
|
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
QString xrayPublicKey = serverController.getTextFileFromContainer(container, credentials,
|
QString xrayPublicKey =
|
||||||
amnezia::protocols::xray::PublicKeyPath, &e);
|
serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::xray::PublicKeyPath, errorCode);
|
||||||
xrayPublicKey.replace("\n", "");
|
xrayPublicKey.replace("\n", "");
|
||||||
|
|
||||||
QString xrayUuid = serverController.getTextFileFromContainer(container, credentials,
|
QString xrayUuid = serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::xray::uuidPath, errorCode);
|
||||||
amnezia::protocols::xray::uuidPath, &e);
|
|
||||||
xrayUuid.replace("\n", "");
|
xrayUuid.replace("\n", "");
|
||||||
|
|
||||||
QString xrayShortId = serverController.getTextFileFromContainer(container, credentials,
|
QString xrayShortId = serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::xray::shortidPath, errorCode);
|
||||||
amnezia::protocols::xray::shortidPath, &e);
|
|
||||||
xrayShortId.replace("\n", "");
|
xrayShortId.replace("\n", "");
|
||||||
|
|
||||||
if (e) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
if (errorCode) *errorCode = e;
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,14 @@
|
|||||||
#include "configurator_base.h"
|
#include "configurator_base.h"
|
||||||
#include "core/defs.h"
|
#include "core/defs.h"
|
||||||
|
|
||||||
class XrayConfigurator : ConfiguratorBase
|
class XrayConfigurator : public ConfiguratorBase
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
XrayConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
XrayConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString genXrayConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
||||||
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode = nullptr);
|
ErrorCode errorCode);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // XRAY_CONFIGURATOR_H
|
#endif // XRAY_CONFIGURATOR_H
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#include "containers_defs.h"
|
#include "containers_defs.h"
|
||||||
|
|
||||||
|
#include "QJsonObject"
|
||||||
|
#include "QJsonDocument"
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const amnezia::DockerContainer &c)
|
QDebug operator<<(QDebug debug, const amnezia::DockerContainer &c)
|
||||||
{
|
{
|
||||||
QDebugStateSaver saver(debug);
|
QDebugStateSaver saver(debug);
|
||||||
@@ -363,3 +366,13 @@ bool ContainerProps::isShareable(DockerContainer container)
|
|||||||
default: return true;
|
default: return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject ContainerProps::getProtocolConfigFromContainer(const Proto protocol, const QJsonObject &containerConfig)
|
||||||
|
{
|
||||||
|
QString protocolConfigString = containerConfig.value(ProtocolProps::protoToString(protocol))
|
||||||
|
.toObject()
|
||||||
|
.value(config_key::last_config)
|
||||||
|
.toString();
|
||||||
|
|
||||||
|
return QJsonDocument::fromJson(protocolConfigString.toUtf8()).object();
|
||||||
|
}
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ namespace amnezia
|
|||||||
static int easySetupOrder(amnezia::DockerContainer container);
|
static int easySetupOrder(amnezia::DockerContainer container);
|
||||||
|
|
||||||
static bool isShareable(amnezia::DockerContainer container);
|
static bool isShareable(amnezia::DockerContainer container);
|
||||||
|
|
||||||
|
static QJsonObject getProtocolConfigFromContainer(const amnezia::Proto protocol, const QJsonObject &containerConfig);
|
||||||
};
|
};
|
||||||
|
|
||||||
static void declareQmlContainerEnum()
|
static void declareQmlContainerEnum()
|
||||||
|
|||||||
+16
-41
@@ -5,9 +5,8 @@
|
|||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
|
|
||||||
#include "configurators/openvpn_configurator.h"
|
|
||||||
#include "configurators/wireguard_configurator.h"
|
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
|
#include "configurators/wireguard_configurator.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -24,9 +23,7 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiController::ApiController(const QSharedPointer<ServersModel> &serversModel,
|
ApiController::ApiController(QObject *parent) : QObject(parent)
|
||||||
const QSharedPointer<ContainersModel> &containersModel, QObject *parent)
|
|
||||||
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,21 +64,14 @@ QJsonObject ApiController::fillApiPayload(const QString &protocol, const ApiCont
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiController::updateServerConfigFromApi()
|
ErrorCode ApiController::updateServerConfigFromApi(QJsonObject &serverConfig)
|
||||||
{
|
{
|
||||||
QtConcurrent::run([this]() {
|
QFutureWatcher<ErrorCode> watcher;
|
||||||
if (m_isConfigUpdateStarted) {
|
|
||||||
emit updateFinished(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto serverConfig = m_serversModel->getDefaultServerConfig();
|
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() && containerConfig.isEmpty()) {
|
if (serverConfig.value(config_key::configVersion).toInt()) {
|
||||||
emit updateStarted();
|
|
||||||
m_isConfigUpdateStarted = true;
|
|
||||||
|
|
||||||
QNetworkAccessManager manager;
|
QNetworkAccessManager manager;
|
||||||
|
|
||||||
QNetworkRequest request;
|
QNetworkRequest request;
|
||||||
@@ -114,9 +104,7 @@ void ApiController::updateServerConfigFromApi()
|
|||||||
QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
|
|
||||||
if (ba.isEmpty()) {
|
if (ba.isEmpty()) {
|
||||||
emit errorOccurred(errorString(ApiConfigDownloadError));
|
return ErrorCode::ApiConfigDownloadError;
|
||||||
m_isConfigUpdateStarted = false;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray ba_uncompressed = qUncompress(ba);
|
QByteArray ba_uncompressed = qUncompress(ba);
|
||||||
@@ -136,35 +124,22 @@ void ApiController::updateServerConfigFromApi()
|
|||||||
|
|
||||||
auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString();
|
auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString();
|
||||||
serverConfig.insert(config_key::defaultContainer, defaultContainer);
|
serverConfig.insert(config_key::defaultContainer, defaultContainer);
|
||||||
m_serversModel->editServer(serverConfig, m_serversModel->getDefaultServerIndex());
|
|
||||||
} else {
|
} else {
|
||||||
QString err = reply->errorString();
|
QString err = reply->errorString();
|
||||||
qDebug() << QString::fromUtf8(reply->readAll());
|
qDebug() << QString::fromUtf8(reply->readAll());
|
||||||
qDebug() << reply->error();
|
qDebug() << reply->error();
|
||||||
qDebug() << err;
|
qDebug() << err;
|
||||||
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||||||
emit errorOccurred(errorString(ApiConfigDownloadError));
|
return ErrorCode::ApiConfigDownloadError;
|
||||||
m_isConfigUpdateStarted = false;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ErrorCode::NoError;
|
||||||
emit updateFinished(m_isConfigUpdateStarted);
|
|
||||||
m_isConfigUpdateStarted = false;
|
|
||||||
return;
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
QEventLoop wait;
|
||||||
void ApiController::clearApiConfig()
|
connect(&watcher, &QFutureWatcher<ErrorCode>::finished, &wait, &QEventLoop::quit);
|
||||||
{
|
watcher.setFuture(future);
|
||||||
auto serverConfig = m_serversModel->getDefaultServerConfig();
|
wait.exec();
|
||||||
|
|
||||||
serverConfig.remove(config_key::dns1);
|
return watcher.result();
|
||||||
serverConfig.remove(config_key::dns2);
|
|
||||||
serverConfig.remove(config_key::containers);
|
|
||||||
serverConfig.remove(config_key::hostName);
|
|
||||||
|
|
||||||
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
|
|
||||||
|
|
||||||
m_serversModel->editServer(serverConfig, m_serversModel->getDefaultServerIndex());
|
|
||||||
}
|
}
|
||||||
@@ -4,26 +4,16 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "configurators/openvpn_configurator.h"
|
#include "configurators/openvpn_configurator.h"
|
||||||
#include "ui/models/containers_model.h"
|
|
||||||
#include "ui/models/servers_model.h"
|
|
||||||
|
|
||||||
class ApiController : public QObject
|
class ApiController : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ApiController(const QSharedPointer<ServersModel> &serversModel,
|
explicit ApiController(QObject *parent = nullptr);
|
||||||
const QSharedPointer<ContainersModel> &containersModel, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateServerConfigFromApi();
|
ErrorCode updateServerConfigFromApi(QJsonObject &serverConfig);
|
||||||
|
|
||||||
void clearApiConfig();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void updateStarted();
|
|
||||||
void updateFinished(bool isConfigUpdateStarted);
|
|
||||||
void errorOccurred(const QString &errorMessage);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ApiPayloadData {
|
struct ApiPayloadData {
|
||||||
@@ -36,11 +26,6 @@ private:
|
|||||||
ApiPayloadData generateApiPayloadData(const QString &protocol);
|
ApiPayloadData generateApiPayloadData(const QString &protocol);
|
||||||
QJsonObject fillApiPayload(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData);
|
QJsonObject fillApiPayload(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData);
|
||||||
void processApiConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData, QString &config);
|
void processApiConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData, QString &config);
|
||||||
|
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
|
||||||
QSharedPointer<ContainersModel> m_containersModel;
|
|
||||||
|
|
||||||
bool m_isConfigUpdateStarted = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // APICONTROLLER_H
|
#endif // APICONTROLLER_H
|
||||||
@@ -29,8 +29,7 @@
|
|||||||
#include "core/networkUtilities.h"
|
#include "core/networkUtilities.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
#include "vpnConfigurationController.h"
|
||||||
#include <configurators/vpn_configurator.h>
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -179,11 +178,10 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
|||||||
}
|
}
|
||||||
|
|
||||||
QByteArray ServerController::getTextFileFromContainer(DockerContainer container, const ServerCredentials &credentials,
|
QByteArray ServerController::getTextFileFromContainer(DockerContainer container, const ServerCredentials &credentials,
|
||||||
const QString &path, ErrorCode *errorCode)
|
const QString &path, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (errorCode)
|
errorCode = ErrorCode::NoError;
|
||||||
*errorCode = ErrorCode::NoError;
|
|
||||||
|
|
||||||
QString script = QString("sudo docker exec -i %1 sh -c \"xxd -p \'%2\'\"")
|
QString script = QString("sudo docker exec -i %1 sh -c \"xxd -p \'%2\'\"")
|
||||||
.arg(ContainerProps::containerToString(container))
|
.arg(ContainerProps::containerToString(container))
|
||||||
@@ -195,7 +193,7 @@ QByteArray ServerController::getTextFileFromContainer(DockerContainer container,
|
|||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
};
|
};
|
||||||
|
|
||||||
*errorCode = runScript(credentials, script, cbReadStdOut);
|
errorCode = runScript(credentials, script, cbReadStdOut);
|
||||||
return QByteArray::fromHex(stdOut.toUtf8());
|
return QByteArray::fromHex(stdOut.toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,7 +496,7 @@ ErrorCode ServerController::configureContainerWorker(const ServerCredentials &cr
|
|||||||
genVarsForScript(credentials, container, config)),
|
genVarsForScript(credentials, container, config)),
|
||||||
cbReadStdOut, cbReadStdErr);
|
cbReadStdOut, cbReadStdErr);
|
||||||
|
|
||||||
m_configurator->updateContainerConfigAfterInstallation(container, config, stdOut);
|
VpnConfigurationsController::updateContainerConfigAfterInstallation(container, config, stdOut);
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -662,7 +660,7 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
|||||||
return vars;
|
return vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ServerController::checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode)
|
QString ServerController::checkSshConnection(const ServerCredentials &credentials, ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
QString stdOut;
|
QString stdOut;
|
||||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
||||||
@@ -674,11 +672,7 @@ QString ServerController::checkSshConnection(const ServerCredentials &credential
|
|||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
};
|
};
|
||||||
|
|
||||||
ErrorCode e =
|
errorCode = runScript(credentials, amnezia::scriptData(SharedScriptType::check_connection), cbReadStdOut, cbReadStdErr);
|
||||||
runScript(credentials, amnezia::scriptData(SharedScriptType::check_connection), cbReadStdOut, cbReadStdErr);
|
|
||||||
|
|
||||||
if (errorCode)
|
|
||||||
*errorCode = e;
|
|
||||||
|
|
||||||
return stdOut;
|
return stdOut;
|
||||||
}
|
}
|
||||||
@@ -839,147 +833,6 @@ ErrorCode ServerController::isServerDpkgBusy(const ServerCredentials &credential
|
|||||||
return future.result();
|
return future.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::getAlreadyInstalledContainers(const ServerCredentials &credentials,
|
|
||||||
QMap<DockerContainer, QJsonObject> &installedContainers)
|
|
||||||
{
|
|
||||||
QString stdOut;
|
|
||||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
|
||||||
stdOut += data + "\n";
|
|
||||||
return ErrorCode::NoError;
|
|
||||||
};
|
|
||||||
auto cbReadStdErr = [&](const QString &data, libssh::Client &) {
|
|
||||||
stdOut += data + "\n";
|
|
||||||
return ErrorCode::NoError;
|
|
||||||
};
|
|
||||||
|
|
||||||
QString script = QString("sudo docker ps --format '{{.Names}} {{.Ports}}'");
|
|
||||||
|
|
||||||
ErrorCode errorCode = runScript(credentials, script, cbReadStdOut, cbReadStdErr);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto containersInfo = stdOut.split("\n");
|
|
||||||
for (auto &containerInfo : containersInfo) {
|
|
||||||
if (containerInfo.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const static QRegularExpression containerAndPortRegExp("(amnezia[-a-z]*).*?:([0-9]*)->[0-9]*/(udp|tcp).*");
|
|
||||||
QRegularExpressionMatch containerAndPortMatch = containerAndPortRegExp.match(containerInfo);
|
|
||||||
if (containerAndPortMatch.hasMatch()) {
|
|
||||||
QString name = containerAndPortMatch.captured(1);
|
|
||||||
QString port = containerAndPortMatch.captured(2);
|
|
||||||
QString transportProto = containerAndPortMatch.captured(3);
|
|
||||||
DockerContainer container = ContainerProps::containerFromString(name);
|
|
||||||
|
|
||||||
QJsonObject config;
|
|
||||||
Proto mainProto = ContainerProps::defaultProtocol(container);
|
|
||||||
for (auto protocol : ContainerProps::protocolsForContainer(container)) {
|
|
||||||
QJsonObject containerConfig;
|
|
||||||
if (protocol == mainProto) {
|
|
||||||
containerConfig.insert(config_key::port, port);
|
|
||||||
containerConfig.insert(config_key::transport_proto, transportProto);
|
|
||||||
|
|
||||||
if (protocol == Proto::Awg) {
|
|
||||||
QString serverConfig = getTextFileFromContainer(container, credentials, protocols::awg::serverConfigPath, &errorCode);
|
|
||||||
|
|
||||||
QMap<QString, QString> serverConfigMap;
|
|
||||||
auto serverConfigLines = serverConfig.split("\n");
|
|
||||||
for (auto &line : serverConfigLines) {
|
|
||||||
auto trimmedLine = line.trimmed();
|
|
||||||
if (trimmedLine.startsWith("[") && trimmedLine.endsWith("]")) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
QStringList parts = trimmedLine.split(" = ");
|
|
||||||
if (parts.count() == 2) {
|
|
||||||
serverConfigMap.insert(parts[0].trimmed(), parts[1].trimmed());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
containerConfig[config_key::junkPacketCount] = serverConfigMap.value(config_key::junkPacketCount);
|
|
||||||
containerConfig[config_key::junkPacketMinSize] = serverConfigMap.value(config_key::junkPacketMinSize);
|
|
||||||
containerConfig[config_key::junkPacketMaxSize] = serverConfigMap.value(config_key::junkPacketMaxSize);
|
|
||||||
containerConfig[config_key::initPacketJunkSize] = serverConfigMap.value(config_key::initPacketJunkSize);
|
|
||||||
containerConfig[config_key::responsePacketJunkSize] = serverConfigMap.value(config_key::responsePacketJunkSize);
|
|
||||||
containerConfig[config_key::initPacketMagicHeader] = serverConfigMap.value(config_key::initPacketMagicHeader);
|
|
||||||
containerConfig[config_key::responsePacketMagicHeader] = serverConfigMap.value(config_key::responsePacketMagicHeader);
|
|
||||||
containerConfig[config_key::underloadPacketMagicHeader] = serverConfigMap.value(config_key::underloadPacketMagicHeader);
|
|
||||||
containerConfig[config_key::transportPacketMagicHeader] = serverConfigMap.value(config_key::transportPacketMagicHeader);
|
|
||||||
} else if (protocol == Proto::Sftp) {
|
|
||||||
stdOut.clear();
|
|
||||||
script = QString("sudo docker inspect --format '{{.Config.Cmd}}' %1").arg(name);
|
|
||||||
|
|
||||||
ErrorCode errorCode = runScript(credentials, script, cbReadStdOut, cbReadStdErr);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto sftpInfo = stdOut.split(":");
|
|
||||||
if (sftpInfo.size() < 2) {
|
|
||||||
logger.error() << "Key parameters for the sftp container are missing";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto userName = sftpInfo.at(0);
|
|
||||||
userName = userName.remove(0, 1);
|
|
||||||
auto password = sftpInfo.at(1);
|
|
||||||
|
|
||||||
containerConfig.insert(config_key::userName, userName);
|
|
||||||
containerConfig.insert(config_key::password, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
config.insert(config_key::container, ContainerProps::containerToString(container));
|
|
||||||
}
|
|
||||||
config.insert(ProtocolProps::protoToString(protocol), containerConfig);
|
|
||||||
}
|
|
||||||
installedContainers.insert(container, config);
|
|
||||||
}
|
|
||||||
const static QRegularExpression torOrDnsRegExp("(amnezia-(?:torwebsite|dns)).*?([0-9]*)/(udp|tcp).*");
|
|
||||||
QRegularExpressionMatch torOrDnsRegMatch = torOrDnsRegExp.match(containerInfo);
|
|
||||||
if (torOrDnsRegMatch.hasMatch()) {
|
|
||||||
QString name = torOrDnsRegMatch.captured(1);
|
|
||||||
QString port = torOrDnsRegMatch.captured(2);
|
|
||||||
QString transportProto = torOrDnsRegMatch.captured(3);
|
|
||||||
DockerContainer container = ContainerProps::containerFromString(name);
|
|
||||||
|
|
||||||
QJsonObject config;
|
|
||||||
Proto mainProto = ContainerProps::defaultProtocol(container);
|
|
||||||
for (auto protocol : ContainerProps::protocolsForContainer(container)) {
|
|
||||||
QJsonObject containerConfig;
|
|
||||||
if (protocol == mainProto) {
|
|
||||||
containerConfig.insert(config_key::port, port);
|
|
||||||
containerConfig.insert(config_key::transport_proto, transportProto);
|
|
||||||
|
|
||||||
if (protocol == Proto::TorWebSite) {
|
|
||||||
stdOut.clear();
|
|
||||||
script = QString("sudo docker exec -i %1 sh -c 'cat /var/lib/tor/hidden_service/hostname'").arg(name);
|
|
||||||
|
|
||||||
ErrorCode errorCode = runScript(credentials, script, cbReadStdOut, cbReadStdErr);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stdOut.isEmpty()) {
|
|
||||||
logger.error() << "Key parameters for the tor container are missing";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString onion = stdOut;
|
|
||||||
onion.replace("\n", "");
|
|
||||||
containerConfig.insert(config_key::site, onion);
|
|
||||||
}
|
|
||||||
|
|
||||||
config.insert(config_key::container, ContainerProps::containerToString(container));
|
|
||||||
}
|
|
||||||
config.insert(ProtocolProps::protoToString(protocol), containerConfig);
|
|
||||||
}
|
|
||||||
installedContainers.insert(container, config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ErrorCode::NoError;
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode ServerController::getDecryptedPrivateKey(const ServerCredentials &credentials, QString &decryptedPrivateKey,
|
ErrorCode ServerController::getDecryptedPrivateKey(const ServerCredentials &credentials, QString &decryptedPrivateKey,
|
||||||
const std::function<QString()> &callback)
|
const std::function<QString()> &callback)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,9 +30,6 @@ public:
|
|||||||
ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container,
|
ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &oldConfig, QJsonObject &newConfig);
|
const QJsonObject &oldConfig, QJsonObject &newConfig);
|
||||||
|
|
||||||
ErrorCode getAlreadyInstalledContainers(const ServerCredentials &credentials,
|
|
||||||
QMap<DockerContainer, QJsonObject> &installedContainers);
|
|
||||||
|
|
||||||
ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container,
|
ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &config = QJsonObject());
|
const QJsonObject &config = QJsonObject());
|
||||||
|
|
||||||
@@ -40,7 +37,7 @@ public:
|
|||||||
DockerContainer container, const ServerCredentials &credentials, const QString &file, 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,
|
QByteArray getTextFileFromContainer(DockerContainer container, const ServerCredentials &credentials,
|
||||||
const QString &path, ErrorCode *errorCode = nullptr);
|
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,
|
||||||
@@ -55,7 +52,7 @@ 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);
|
||||||
|
|
||||||
QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr);
|
QString checkSshConnection(const ServerCredentials &credentials, ErrorCode errorCode);
|
||||||
|
|
||||||
void cancelInstallation();
|
void cancelInstallation();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
#include "vpnConfigurationController.h"
|
||||||
|
|
||||||
|
#include "configurators/awg_configurator.h"
|
||||||
|
#include "configurators/cloak_configurator.h"
|
||||||
|
#include "configurators/ikev2_configurator.h"
|
||||||
|
#include "configurators/openvpn_configurator.h"
|
||||||
|
#include "configurators/shadowsocks_configurator.h"
|
||||||
|
#include "configurators/wireguard_configurator.h"
|
||||||
|
#include "configurators/xray_configurator.h"
|
||||||
|
|
||||||
|
VpnConfigurationsController::VpnConfigurationsController(const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
|
: QObject { parent }, m_settings(settings)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QScopedPointer<ConfiguratorBase> VpnConfigurationsController::createConfigurator(const Proto protocol)
|
||||||
|
{
|
||||||
|
switch (protocol) {
|
||||||
|
case Proto::OpenVpn: return QScopedPointer<ConfiguratorBase>(new OpenVpnConfigurator(m_settings));
|
||||||
|
case Proto::ShadowSocks: return QScopedPointer<ConfiguratorBase>(new ShadowSocksConfigurator(m_settings));
|
||||||
|
case Proto::Cloak: return QScopedPointer<ConfiguratorBase>(new CloakConfigurator(m_settings));
|
||||||
|
case Proto::WireGuard: return QScopedPointer<ConfiguratorBase>(new WireguardConfigurator(m_settings, false));
|
||||||
|
case Proto::Awg: return QScopedPointer<ConfiguratorBase>(new AwgConfigurator(m_settings));
|
||||||
|
case Proto::Ikev2: return QScopedPointer<ConfiguratorBase>(new Ikev2Configurator(m_settings));
|
||||||
|
case Proto::Xray: return QScopedPointer<ConfiguratorBase>(new XrayConfigurator(m_settings));
|
||||||
|
default: return QScopedPointer<ConfiguratorBase>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode VpnConfigurationsController::createProtocolConfigForContainer(const ServerCredentials &credentials,
|
||||||
|
const DockerContainer container, QJsonObject &containerConfig)
|
||||||
|
{
|
||||||
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
|
if (ContainerProps::containerService(container) == ServiceType::Other) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
|
||||||
|
QJsonObject protocolConfig = containerConfig.value(ProtocolProps::protoToString(protocol)).toObject();
|
||||||
|
|
||||||
|
auto configurator = createConfigurator(protocol);
|
||||||
|
QString protocolConfigString = configurator->createConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
protocolConfig.insert(config_key::last_config, protocolConfigString);
|
||||||
|
containerConfig.insert(ProtocolProps::protoToString(protocol), protocolConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode VpnConfigurationsController::createProtocolConfigString(const bool isApiConfig, const QPair<QString, QString> &dns,
|
||||||
|
const ServerCredentials &credentials, const DockerContainer container,
|
||||||
|
const QJsonObject &containerConfig, const Proto protocol,
|
||||||
|
QString &protocolConfigString)
|
||||||
|
{
|
||||||
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
|
if (ContainerProps::containerService(container) == ServiceType::Other) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto configurator = createConfigurator(protocol);
|
||||||
|
|
||||||
|
protocolConfigString = configurator->createConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
protocolConfigString = configurator->processConfigWithExportSettings(dns, isApiConfig, protocolConfigString);
|
||||||
|
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject VpnConfigurationsController::createVpnConfiguration(const QPair<QString, QString> &dns, const QJsonObject &serverConfig,
|
||||||
|
const QJsonObject &containerConfig, const DockerContainer container,
|
||||||
|
ErrorCode errorCode)
|
||||||
|
{
|
||||||
|
QJsonObject vpnConfiguration {};
|
||||||
|
|
||||||
|
if (ContainerProps::containerService(container) == ServiceType::Other) {
|
||||||
|
return vpnConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isApiConfig = serverConfig.value(config_key::configVersion).toInt();
|
||||||
|
|
||||||
|
for (ProtocolEnumNS::Proto proto : ContainerProps::protocolsForContainer(container)) {
|
||||||
|
if (isApiConfig && container == DockerContainer::Cloak && proto == ProtocolEnumNS::Proto::ShadowSocks) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString protocolConfigString =
|
||||||
|
containerConfig.value(ProtocolProps::protoToString(proto)).toObject().value(config_key::last_config).toString();
|
||||||
|
|
||||||
|
auto configurator = createConfigurator(proto);
|
||||||
|
protocolConfigString = configurator->processConfigWithLocalSettings(dns, isApiConfig, protocolConfigString);
|
||||||
|
|
||||||
|
QJsonObject vpnConfigData = QJsonDocument::fromJson(protocolConfigString.toUtf8()).object();
|
||||||
|
vpnConfigData = QJsonDocument::fromJson(protocolConfigString.toUtf8()).object();
|
||||||
|
vpnConfiguration.insert(ProtocolProps::key_proto_config_data(proto), vpnConfigData);
|
||||||
|
}
|
||||||
|
|
||||||
|
Proto proto = ContainerProps::defaultProtocol(container);
|
||||||
|
vpnConfiguration[config_key::vpnproto] = ProtocolProps::protoToString(proto);
|
||||||
|
|
||||||
|
vpnConfiguration[config_key::dns1] = dns.first;
|
||||||
|
vpnConfiguration[config_key::dns2] = dns.second;
|
||||||
|
|
||||||
|
vpnConfiguration[config_key::hostName] = serverConfig.value(config_key::hostName).toString();
|
||||||
|
vpnConfiguration[config_key::description] = serverConfig.value(config_key::description).toString();
|
||||||
|
|
||||||
|
vpnConfiguration[config_key::configVersion] = serverConfig.value(config_key::configVersion).toInt();
|
||||||
|
// TODO: try to get hostName, port, description for 3rd party configs
|
||||||
|
// vpnConfiguration[config_key::port] = ...;
|
||||||
|
|
||||||
|
return vpnConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnConfigurationsController::updateContainerConfigAfterInstallation(const DockerContainer container, QJsonObject &containerConfig,
|
||||||
|
const QString &stdOut)
|
||||||
|
{
|
||||||
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
|
|
||||||
|
if (container == DockerContainer::TorWebSite) {
|
||||||
|
QJsonObject protocol = containerConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
|
||||||
|
|
||||||
|
qDebug() << "amnezia-tor onions" << stdOut;
|
||||||
|
|
||||||
|
QString onion = stdOut;
|
||||||
|
onion.replace("\n", "");
|
||||||
|
protocol.insert(config_key::site, onion);
|
||||||
|
|
||||||
|
containerConfig.insert(ProtocolProps::protoToString(mainProto), protocol);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef VPNCONFIGIRATIONSCONTROLLER_H
|
||||||
|
#define VPNCONFIGIRATIONSCONTROLLER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "configurators/configurator_base.h"
|
||||||
|
#include "containers/containers_defs.h"
|
||||||
|
#include "core/defs.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
class VpnConfigurationsController : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit VpnConfigurationsController(const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
ErrorCode createProtocolConfigForContainer(const ServerCredentials &credentials, const DockerContainer container,
|
||||||
|
QJsonObject &containerConfig);
|
||||||
|
ErrorCode createProtocolConfigString(const bool isApiConfig, const QPair<QString, QString> &dns, const ServerCredentials &credentials,
|
||||||
|
const DockerContainer container, const QJsonObject &containerConfig, const Proto protocol,
|
||||||
|
QString &protocolConfigString);
|
||||||
|
QJsonObject createVpnConfiguration(const QPair<QString, QString> &dns, const QJsonObject &serverConfig,
|
||||||
|
const QJsonObject &containerConfig, const DockerContainer container, ErrorCode errorCode);
|
||||||
|
|
||||||
|
static void updateContainerConfigAfterInstallation(const DockerContainer container, QJsonObject &containerConfig, const QString &stdOut);
|
||||||
|
signals:
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<ConfiguratorBase> createConfigurator(const Proto protocol);
|
||||||
|
|
||||||
|
std::shared_ptr<Settings> m_settings;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VPNCONFIGIRATIONSCONTROLLER_H
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?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,6 +90,14 @@ 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
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?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>
|
||||||
@@ -424,6 +424,8 @@ 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++) {
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ namespace amnezia
|
|||||||
|
|
||||||
constexpr char crc[] = "crc";
|
constexpr char crc[] = "crc";
|
||||||
|
|
||||||
|
constexpr char clientId[] = "clientId";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace protocols
|
namespace protocols
|
||||||
|
|||||||
@@ -256,6 +256,16 @@ 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);
|
||||||
@@ -403,6 +413,16 @@ 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);
|
||||||
|
}
|
||||||
|
|
||||||
ServerCredentials Settings::defaultServerCredentials() const
|
ServerCredentials Settings::defaultServerCredentials() const
|
||||||
{
|
{
|
||||||
return serverCredentials(defaultServerIndex());
|
return serverCredentials(defaultServerIndex());
|
||||||
|
|||||||
@@ -115,6 +115,9 @@ 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();
|
||||||
@@ -208,6 +211,9 @@ 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);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void saveLogsChanged(bool enabled);
|
void saveLogsChanged(bool enabled);
|
||||||
void screenshotsEnabledChanged(bool enabled);
|
void screenshotsEnabledChanged(bool enabled);
|
||||||
|
|||||||
@@ -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 через Cloak
|
Если в вашем регионе экстремальный уровень цензуры в Интернете, мы советуем вам с первого подключения использовать только OpenVPN over 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
@@ -5,13 +5,23 @@
|
|||||||
#else
|
#else
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#endif
|
#endif
|
||||||
|
#include <QtConcurrent>
|
||||||
|
|
||||||
|
#include "core/controllers/apiController.h"
|
||||||
|
#include "core/controllers/vpnConfigurationController.h"
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
|
|
||||||
ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &serversModel,
|
ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<VpnConnection> &vpnConnection, QObject *parent)
|
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||||
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_vpnConnection(vpnConnection)
|
const QSharedPointer<VpnConnection> &vpnConnection,
|
||||||
|
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
|
: QObject(parent),
|
||||||
|
m_serversModel(serversModel),
|
||||||
|
m_containersModel(containersModel),
|
||||||
|
m_clientManagementModel(clientManagementModel),
|
||||||
|
m_vpnConnection(vpnConnection),
|
||||||
|
m_settings(settings)
|
||||||
{
|
{
|
||||||
connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, this,
|
connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, this,
|
||||||
&ConnectionController::onConnectionStateChanged);
|
&ConnectionController::onConnectionStateChanged);
|
||||||
@@ -45,16 +55,36 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
|||||||
void ConnectionController::openConnection()
|
void ConnectionController::openConnection()
|
||||||
{
|
{
|
||||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||||
|
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
|
|
||||||
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
|
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Preparing);
|
||||||
|
|
||||||
|
if (serverConfig.value(config_key::configVersion).toInt()
|
||||||
|
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||||
|
ApiController apiController;
|
||||||
|
errorCode = apiController.updateServerConfigFromApi(serverConfig);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
emit connectionErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_serversModel->editServer(serverConfig, serverIndex);
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
if (!m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||||
emit noInstalledContainers();
|
emit noInstalledContainers();
|
||||||
|
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
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)) {
|
||||||
const QJsonObject &containerConfig = m_containersModel->getContainerConfig(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"));
|
||||||
@@ -63,7 +93,27 @@ void ConnectionController::openConnection()
|
|||||||
|
|
||||||
qApp->processEvents();
|
qApp->processEvents();
|
||||||
|
|
||||||
emit connectToVpn(serverIndex, credentials, container, containerConfig);
|
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||||
|
|
||||||
|
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||||
|
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||||
|
errorCode = updateProtocolConfig(container, credentials, containerConfig);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
emit connectionErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dns = m_serversModel->getDnsPair(serverIndex);
|
||||||
|
serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
|
|
||||||
|
auto vpnConfiguration =
|
||||||
|
vpnConfigurationController.createVpnConfiguration(dns, serverConfig, containerConfig, container, errorCode);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
emit connectionErrorOccurred(tr("unable to create configuration"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit connectToVpn(serverIndex, credentials, container, vpnConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionController::closeConnection()
|
void ConnectionController::closeConnection()
|
||||||
@@ -112,6 +162,7 @@ void ConnectionController::onConnectionStateChanged(Vpn::ConnectionState state)
|
|||||||
}
|
}
|
||||||
case Vpn::ConnectionState::Preparing: {
|
case Vpn::ConnectionState::Preparing: {
|
||||||
m_isConnectionInProgress = true;
|
m_isConnectionInProgress = true;
|
||||||
|
m_connectionStateText = tr("Preparing...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Vpn::ConnectionState::Error: {
|
case Vpn::ConnectionState::Error: {
|
||||||
@@ -180,10 +231,14 @@ QVector<quint64> ConnectionController::getTimes() const
|
|||||||
{
|
{
|
||||||
return m_times;
|
return m_times;
|
||||||
}
|
}
|
||||||
|
void ConnectionController::toggleConnection()
|
||||||
void ConnectionController::toggleConnection(bool skipConnectionInProgressCheck)
|
|
||||||
{
|
{
|
||||||
if (!skipConnectionInProgressCheck && isConnectionInProgress()) {
|
if (m_state == Vpn::ConnectionState::Preparing) {
|
||||||
|
emit preparingConfig();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isConnectionInProgress()) {
|
||||||
closeConnection();
|
closeConnection();
|
||||||
} else if (isConnected()) {
|
} else if (isConnected()) {
|
||||||
closeConnection();
|
closeConnection();
|
||||||
@@ -201,3 +256,51 @@ bool ConnectionController::isConnected() const
|
|||||||
{
|
{
|
||||||
return m_isConnected;
|
return m_isConnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConnectionController::isProtocolConfigExists(const QJsonObject &containerConfig, const DockerContainer container)
|
||||||
|
{
|
||||||
|
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
|
||||||
|
QString protocolConfig = containerConfig.value(ProtocolProps::protoToString(protocol))
|
||||||
|
.toObject()
|
||||||
|
.value(config_key::last_config)
|
||||||
|
.toString();
|
||||||
|
|
||||||
|
if (protocolConfig.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode ConnectionController::updateProtocolConfig(const DockerContainer container,
|
||||||
|
const ServerCredentials &credentials, QJsonObject &containerConfig)
|
||||||
|
{
|
||||||
|
QFutureWatcher<ErrorCode> watcher;
|
||||||
|
|
||||||
|
QFuture<ErrorCode> future = QtConcurrent::run([this, container, &credentials, &containerConfig]() {
|
||||||
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
if (!isProtocolConfigExists(containerConfig, container)) {
|
||||||
|
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||||
|
errorCode =
|
||||||
|
vpnConfigurationController.createProtocolConfigForContainer(credentials, container, containerConfig);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
m_serversModel->updateContainerConfig(container, containerConfig);
|
||||||
|
|
||||||
|
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig,
|
||||||
|
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errorCode;
|
||||||
|
});
|
||||||
|
|
||||||
|
QEventLoop wait;
|
||||||
|
connect(&watcher, &QFutureWatcher<ErrorCode>::finished, &wait, &QEventLoop::quit);
|
||||||
|
watcher.setFuture(future);
|
||||||
|
wait.exec();
|
||||||
|
|
||||||
|
return watcher.result();
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define CONNECTIONCONTROLLER_H
|
#define CONNECTIONCONTROLLER_H
|
||||||
|
|
||||||
#include "protocols/vpnprotocol.h"
|
#include "protocols/vpnprotocol.h"
|
||||||
|
#include "ui/models/clientManagementModel.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"
|
||||||
#include "vpnconnection.h"
|
#include "vpnconnection.h"
|
||||||
@@ -19,7 +20,9 @@ public:
|
|||||||
|
|
||||||
explicit ConnectionController(const QSharedPointer<ServersModel> &serversModel,
|
explicit ConnectionController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<VpnConnection> &vpnConnection, QObject *parent = nullptr);
|
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||||
|
const QSharedPointer<VpnConnection> &vpnConnection,
|
||||||
|
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
~ConnectionController() = default;
|
~ConnectionController() = default;
|
||||||
|
|
||||||
@@ -34,7 +37,7 @@ public:
|
|||||||
Q_INVOKABLE QVector<quint64> getTimes() const;
|
Q_INVOKABLE QVector<quint64> getTimes() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void toggleConnection(bool skipConnectionInProgressCheck);
|
void toggleConnection();
|
||||||
|
|
||||||
void openConnection();
|
void openConnection();
|
||||||
void closeConnection();
|
void closeConnection();
|
||||||
@@ -46,9 +49,12 @@ public slots:
|
|||||||
|
|
||||||
void onTranslationsUpdated();
|
void onTranslationsUpdated();
|
||||||
|
|
||||||
|
ErrorCode updateProtocolConfig(const DockerContainer container, const ServerCredentials &credentials,
|
||||||
|
QJsonObject &containerConfig);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container,
|
void connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig);
|
const QJsonObject &vpnConfiguration);
|
||||||
void disconnectFromVpn();
|
void disconnectFromVpn();
|
||||||
void connectionStateChanged();
|
void connectionStateChanged();
|
||||||
|
|
||||||
@@ -58,14 +64,21 @@ signals:
|
|||||||
|
|
||||||
void noInstalledContainers();
|
void noInstalledContainers();
|
||||||
|
|
||||||
|
void connectButtonClicked();
|
||||||
|
void preparingConfig();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vpn::ConnectionState getCurrentConnectionState();
|
Vpn::ConnectionState getCurrentConnectionState();
|
||||||
|
bool isProtocolConfigExists(const QJsonObject &containerConfig, const DockerContainer container);
|
||||||
|
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
QSharedPointer<ContainersModel> m_containersModel;
|
QSharedPointer<ContainersModel> m_containersModel;
|
||||||
|
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||||
|
|
||||||
QSharedPointer<VpnConnection> m_vpnConnection;
|
QSharedPointer<VpnConnection> m_vpnConnection;
|
||||||
|
|
||||||
|
std::shared_ptr<Settings> m_settings;
|
||||||
|
|
||||||
bool m_isConnected = false;
|
bool m_isConnected = false;
|
||||||
bool m_isConnectionInProgress = false;
|
bool m_isConnectionInProgress = false;
|
||||||
QString m_connectionStateText = tr("Connect");
|
QString m_connectionStateText = tr("Connect");
|
||||||
|
|||||||
@@ -8,11 +8,7 @@
|
|||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#include "configurators/awg_configurator.h"
|
#include "core/controllers/vpnConfigurationController.h"
|
||||||
#include "configurators/cloak_configurator.h"
|
|
||||||
#include "configurators/openvpn_configurator.h"
|
|
||||||
#include "configurators/shadowsocks_configurator.h"
|
|
||||||
#include "configurators/wireguard_configurator.h"
|
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
#include "systemController.h"
|
#include "systemController.h"
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
@@ -20,25 +16,20 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "qrcodegen.hpp"
|
#include "qrcodegen.hpp"
|
||||||
|
|
||||||
ExportController::ExportController(const QSharedPointer<ServersModel> &serversModel,
|
ExportController::ExportController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
|
||||||
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||||
const std::shared_ptr<Settings> &settings,
|
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
const std::shared_ptr<VpnConfigurator> &configurator, QObject *parent)
|
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
m_serversModel(serversModel),
|
m_serversModel(serversModel),
|
||||||
m_containersModel(containersModel),
|
m_containersModel(containersModel),
|
||||||
m_clientManagementModel(clientManagementModel),
|
m_clientManagementModel(clientManagementModel),
|
||||||
m_settings(settings),
|
m_settings(settings)
|
||||||
m_configurator(configurator)
|
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
m_authResultNotifier.reset(new AuthResultNotifier);
|
m_authResultNotifier.reset(new AuthResultNotifier);
|
||||||
m_authResultReceiver.reset(new AuthResultReceiver(m_authResultNotifier));
|
m_authResultReceiver.reset(new AuthResultReceiver(m_authResultNotifier));
|
||||||
connect(m_authResultNotifier.get(), &AuthResultNotifier::authFailed, this,
|
connect(m_authResultNotifier.get(), &AuthResultNotifier::authFailed, this, [this]() { emit exportErrorOccurred(tr("Access error!")); });
|
||||||
[this]() { emit exportErrorOccurred(tr("Access error!")); });
|
connect(m_authResultNotifier.get(), &AuthResultNotifier::authSuccessful, this, &ExportController::generateFullAccessConfig);
|
||||||
connect(m_authResultNotifier.get(), &AuthResultNotifier::authSuccessful, this,
|
|
||||||
&ExportController::generateFullAccessConfig);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,9 +38,9 @@ void ExportController::generateFullAccessConfig()
|
|||||||
clearPreviousConfig();
|
clearPreviousConfig();
|
||||||
|
|
||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
int serverIndex = m_serversModel->getProcessedServerIndex();
|
||||||
QJsonObject config = m_settings->server(serverIndex);
|
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
|
|
||||||
QJsonArray containers = config.value(config_key::containers).toArray();
|
QJsonArray containers = serverConfig.value(config_key::containers).toArray();
|
||||||
for (auto i = 0; i < containers.size(); i++) {
|
for (auto i = 0; i < containers.size(); i++) {
|
||||||
auto containerConfig = containers.at(i).toObject();
|
auto containerConfig = containers.at(i).toObject();
|
||||||
auto containerType = ContainerProps::containerFromString(containerConfig.value(config_key::container).toString());
|
auto containerType = ContainerProps::containerFromString(containerConfig.value(config_key::container).toString());
|
||||||
@@ -63,13 +54,11 @@ void ExportController::generateFullAccessConfig()
|
|||||||
|
|
||||||
containers.replace(i, containerConfig);
|
containers.replace(i, containerConfig);
|
||||||
}
|
}
|
||||||
config[config_key::containers] = containers;
|
serverConfig[config_key::containers] = containers;
|
||||||
|
|
||||||
QByteArray compressedConfig = QJsonDocument(config).toJson();
|
QByteArray compressedConfig = QJsonDocument(serverConfig).toJson();
|
||||||
compressedConfig = qCompress(compressedConfig, 8);
|
compressedConfig = qCompress(compressedConfig, 8);
|
||||||
m_config = QString("vpn://%1")
|
m_config = QString("vpn://%1").arg(QString(compressedConfig.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)));
|
||||||
.arg(QString(compressedConfig.toBase64(QByteArray::Base64UrlEncoding
|
|
||||||
| QByteArray::OmitTrailingEquals)));
|
|
||||||
|
|
||||||
m_qrCodes = generateQrCodeImageSeries(compressedConfig);
|
m_qrCodes = generateQrCodeImageSeries(compressedConfig);
|
||||||
emit exportConfigChanged();
|
emit exportConfigChanged();
|
||||||
@@ -83,8 +72,7 @@ void ExportController::generateFullAccessConfigAndroid()
|
|||||||
auto appContext = activity.callObjectMethod("getApplicationContext", "()Landroid/content/Context;");
|
auto appContext = activity.callObjectMethod("getApplicationContext", "()Landroid/content/Context;");
|
||||||
if (appContext.isValid()) {
|
if (appContext.isValid()) {
|
||||||
auto intent = QJniObject::callStaticObjectMethod("org/amnezia/vpn/AuthHelper", "getAuthIntent",
|
auto intent = QJniObject::callStaticObjectMethod("org/amnezia/vpn/AuthHelper", "getAuthIntent",
|
||||||
"(Landroid/content/Context;)Landroid/content/Intent;",
|
"(Landroid/content/Context;)Landroid/content/Intent;", appContext.object());
|
||||||
appContext.object());
|
|
||||||
if (intent.isValid()) {
|
if (intent.isValid()) {
|
||||||
if (intent.object<jobject>() != nullptr) {
|
if (intent.object<jobject>() != nullptr) {
|
||||||
QtAndroidPrivate::startActivity(intent.object<jobject>(), 1, m_authResultReceiver.get());
|
QtAndroidPrivate::startActivity(intent.object<jobject>(), 1, m_authResultReceiver.get());
|
||||||
@@ -103,116 +91,108 @@ void ExportController::generateConnectionConfig(const QString &clientName)
|
|||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
int serverIndex = m_serversModel->getProcessedServerIndex();
|
||||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||||
|
|
||||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getProcessedContainerIndex());
|
||||||
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));
|
||||||
|
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||||
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
|
ErrorCode errorCode = vpnConfigurationController.createProtocolConfigForContainer(credentials, container, containerConfig);
|
||||||
QJsonObject protocolConfig = m_settings->protocolConfig(serverIndex, container, protocol);
|
|
||||||
|
|
||||||
QString clientId;
|
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig, clientName);
|
||||||
QString vpnConfig = m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, protocol,
|
if (errorCode != ErrorCode::NoError) {
|
||||||
clientId, &errorCode);
|
|
||||||
if (errorCode) {
|
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
protocolConfig.insert(config_key::last_config, vpnConfig);
|
|
||||||
containerConfig.insert(ProtocolProps::protoToString(protocol), protocolConfig);
|
|
||||||
if (protocol == Proto::OpenVpn || protocol == Proto::Awg || protocol == Proto::WireGuard) {
|
|
||||||
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
|
|
||||||
if (errorCode) {
|
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject config = m_settings->server(serverIndex); // todo change to servers_model
|
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
if (!errorCode) {
|
if (!errorCode) {
|
||||||
config.remove(config_key::userName);
|
serverConfig.remove(config_key::userName);
|
||||||
config.remove(config_key::password);
|
serverConfig.remove(config_key::password);
|
||||||
config.remove(config_key::port);
|
serverConfig.remove(config_key::port);
|
||||||
config.insert(config_key::containers, QJsonArray { containerConfig });
|
serverConfig.insert(config_key::containers, QJsonArray { containerConfig });
|
||||||
config.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||||
|
|
||||||
auto dns = m_configurator->getDnsForConfig(serverIndex);
|
auto dns = m_serversModel->getDnsPair(serverIndex);
|
||||||
config.insert(config_key::dns1, dns.first);
|
serverConfig.insert(config_key::dns1, dns.first);
|
||||||
config.insert(config_key::dns2, dns.second);
|
serverConfig.insert(config_key::dns2, dns.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray compressedConfig = QJsonDocument(config).toJson();
|
QByteArray compressedConfig = QJsonDocument(serverConfig).toJson();
|
||||||
compressedConfig = qCompress(compressedConfig, 8);
|
compressedConfig = qCompress(compressedConfig, 8);
|
||||||
m_config = QString("vpn://%1")
|
m_config = QString("vpn://%1").arg(QString(compressedConfig.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)));
|
||||||
.arg(QString(compressedConfig.toBase64(QByteArray::Base64UrlEncoding
|
|
||||||
| QByteArray::OmitTrailingEquals)));
|
|
||||||
|
|
||||||
m_qrCodes = generateQrCodeImageSeries(compressedConfig);
|
m_qrCodes = generateQrCodeImageSeries(compressedConfig);
|
||||||
emit exportConfigChanged();
|
emit exportConfigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportController::generateOpenVpnConfig(const QString &clientName)
|
ErrorCode ExportController::generateNativeConfig(const DockerContainer container, const QString &clientName, const Proto &protocol,
|
||||||
|
QJsonObject &jsonNativeConfig)
|
||||||
{
|
{
|
||||||
clearPreviousConfig();
|
clearPreviousConfig();
|
||||||
|
|
||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
int serverIndex = m_serversModel->getProcessedServerIndex();
|
||||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||||
|
auto dns = m_serversModel->getDnsPair(serverIndex);
|
||||||
|
bool isApiConfig = qvariant_cast<bool>(m_serversModel->data(serverIndex, ServersModel::IsServerFromApiRole));
|
||||||
|
|
||||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
|
||||||
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));
|
||||||
|
|
||||||
|
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||||
|
|
||||||
|
QString protocolConfigString;
|
||||||
|
|
||||||
|
ErrorCode errorCode = vpnConfigurationController.createProtocolConfigString(isApiConfig, dns, credentials, container, containerConfig,
|
||||||
|
protocol, protocolConfigString);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonNativeConfig = QJsonDocument::fromJson(protocolConfigString.toUtf8()).object();
|
||||||
|
|
||||||
|
if (protocol == Proto::OpenVpn || protocol == Proto::WireGuard || protocol == Proto::Awg) {
|
||||||
|
auto clientId = jsonNativeConfig.value(config_key::clientId).toString();
|
||||||
|
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
|
||||||
|
}
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExportController::generateOpenVpnConfig(const QString &clientName)
|
||||||
|
{
|
||||||
|
QJsonObject nativeConfig;
|
||||||
|
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getProcessedContainerIndex());
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
QString clientId;
|
|
||||||
QString config = m_configurator->openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig,
|
if (container == DockerContainer::Cloak || container == DockerContainer::ShadowSocks) {
|
||||||
clientId, &errorCode);
|
errorCode = generateNativeConfig(container, clientName, Proto::OpenVpn, nativeConfig);
|
||||||
|
} else {
|
||||||
|
errorCode = generateNativeConfig(container, clientName, ContainerProps::defaultProtocol(container), nativeConfig);
|
||||||
|
}
|
||||||
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::OpenVpn, config);
|
|
||||||
|
|
||||||
auto configJson = QJsonDocument::fromJson(config.toUtf8()).object();
|
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
||||||
QStringList lines = configJson.value(config_key::config).toString().replace("\r", "").split("\n");
|
|
||||||
for (const QString &line : lines) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_qrCodes = generateQrCodeImageSeries(m_config.toUtf8());
|
m_qrCodes = generateQrCodeImageSeries(m_config.toUtf8());
|
||||||
|
|
||||||
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
|
|
||||||
if (errorCode) {
|
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit exportConfigChanged();
|
emit exportConfigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportController::generateWireGuardConfig(const QString &clientName)
|
void ExportController::generateWireGuardConfig(const QString &clientName)
|
||||||
{
|
{
|
||||||
clearPreviousConfig();
|
QJsonObject nativeConfig;
|
||||||
|
ErrorCode errorCode = generateNativeConfig(DockerContainer::WireGuard, clientName, Proto::WireGuard, nativeConfig);
|
||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
|
||||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
|
||||||
|
|
||||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
|
||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
|
||||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
|
||||||
|
|
||||||
QString clientId;
|
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
|
||||||
QString config = m_configurator->wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig,
|
|
||||||
clientId, &errorCode);
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::WireGuard, config);
|
|
||||||
|
|
||||||
auto configJson = QJsonDocument::fromJson(config.toUtf8()).object();
|
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
||||||
QStringList lines = configJson.value(config_key::config).toString().replace("\r", "").split("\n");
|
|
||||||
for (const QString &line : lines) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
@@ -220,38 +200,19 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
|
|||||||
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(m_config.toUtf8(), qrcodegen::QrCode::Ecc::LOW);
|
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(m_config.toUtf8(), qrcodegen::QrCode::Ecc::LOW);
|
||||||
m_qrCodes << svgToBase64(QString::fromStdString(toSvgString(qr, 1)));
|
m_qrCodes << svgToBase64(QString::fromStdString(toSvgString(qr, 1)));
|
||||||
|
|
||||||
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
|
|
||||||
if (errorCode) {
|
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit exportConfigChanged();
|
emit exportConfigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportController::generateAwgConfig(const QString &clientName)
|
void ExportController::generateAwgConfig(const QString &clientName)
|
||||||
{
|
{
|
||||||
clearPreviousConfig();
|
QJsonObject nativeConfig;
|
||||||
|
ErrorCode errorCode = generateNativeConfig(DockerContainer::Awg, clientName, Proto::Awg, nativeConfig);
|
||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
|
||||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
|
||||||
|
|
||||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
|
||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
|
||||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
|
||||||
|
|
||||||
QString clientId;
|
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
|
||||||
QString config = m_configurator->awgConfigurator->genAwgConfig(credentials, container, containerConfig,
|
|
||||||
clientId, &errorCode);
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::Awg, config);
|
|
||||||
|
|
||||||
auto configJson = QJsonDocument::fromJson(config.toUtf8()).object();
|
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
||||||
QStringList lines = configJson.value(config_key::config).toString().replace("\r", "").split("\n");
|
|
||||||
for (const QString &line : lines) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
@@ -259,42 +220,34 @@ void ExportController::generateAwgConfig(const QString &clientName)
|
|||||||
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(m_config.toUtf8(), qrcodegen::QrCode::Ecc::LOW);
|
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(m_config.toUtf8(), qrcodegen::QrCode::Ecc::LOW);
|
||||||
m_qrCodes << svgToBase64(QString::fromStdString(toSvgString(qr, 1)));
|
m_qrCodes << svgToBase64(QString::fromStdString(toSvgString(qr, 1)));
|
||||||
|
|
||||||
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
|
|
||||||
if (errorCode) {
|
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit exportConfigChanged();
|
emit exportConfigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportController::generateShadowSocksConfig()
|
void ExportController::generateShadowSocksConfig()
|
||||||
{
|
{
|
||||||
clearPreviousConfig();
|
QJsonObject nativeConfig;
|
||||||
|
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getProcessedContainerIndex());
|
||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
|
||||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
|
||||||
|
|
||||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
|
||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
|
||||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
|
||||||
|
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
QString config = m_configurator->shadowSocksConfigurator->genShadowSocksConfig(credentials, container,
|
|
||||||
containerConfig, &errorCode);
|
|
||||||
|
|
||||||
config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::ShadowSocks, config);
|
if (container == DockerContainer::Cloak) {
|
||||||
QJsonObject configJson = QJsonDocument::fromJson(config.toUtf8()).object();
|
errorCode = generateNativeConfig(container, "", Proto::ShadowSocks, nativeConfig);
|
||||||
|
} else {
|
||||||
|
errorCode = generateNativeConfig(container, "", ContainerProps::defaultProtocol(container), nativeConfig);
|
||||||
|
}
|
||||||
|
|
||||||
QStringList lines = QString(QJsonDocument(configJson).toJson()).replace("\r", "").split("\n");
|
if (errorCode) {
|
||||||
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
||||||
for (const QString &line : lines) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_nativeConfigString =
|
m_nativeConfigString = QString("%1:%2@%3:%4")
|
||||||
QString("%1:%2@%3:%4")
|
.arg(nativeConfig.value("method").toString(), nativeConfig.value("password").toString(),
|
||||||
.arg(configJson.value("method").toString(), configJson.value("password").toString(),
|
nativeConfig.value("server").toString(), nativeConfig.value("server_port").toString());
|
||||||
configJson.value("server").toString(), configJson.value("server_port").toString());
|
|
||||||
|
|
||||||
m_nativeConfigString = "ss://" + m_nativeConfigString.toUtf8().toBase64();
|
m_nativeConfigString = "ss://" + m_nativeConfigString.toUtf8().toBase64();
|
||||||
|
|
||||||
@@ -306,30 +259,17 @@ void ExportController::generateShadowSocksConfig()
|
|||||||
|
|
||||||
void ExportController::generateCloakConfig()
|
void ExportController::generateCloakConfig()
|
||||||
{
|
{
|
||||||
clearPreviousConfig();
|
QJsonObject nativeConfig;
|
||||||
|
ErrorCode errorCode = generateNativeConfig(DockerContainer::Cloak, "", Proto::Cloak, nativeConfig);
|
||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
|
||||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
|
||||||
|
|
||||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
|
||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
|
||||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
|
||||||
|
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
|
||||||
QString config =
|
|
||||||
m_configurator->cloakConfigurator->genCloakConfig(credentials, container, containerConfig, &errorCode);
|
|
||||||
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::Cloak, config);
|
|
||||||
QJsonObject configJson = QJsonDocument::fromJson(config.toUtf8()).object();
|
|
||||||
|
|
||||||
configJson.remove(config_key::transport_proto);
|
nativeConfig.remove(config_key::transport_proto);
|
||||||
configJson.insert("ProxyMethod", "shadowsocks");
|
nativeConfig.insert("ProxyMethod", "shadowsocks");
|
||||||
|
|
||||||
QStringList lines = QString(QJsonDocument(configJson).toJson()).replace("\r", "").split("\n");
|
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
||||||
for (const QString &line : lines) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
@@ -339,29 +279,14 @@ void ExportController::generateCloakConfig()
|
|||||||
|
|
||||||
void ExportController::generateXrayConfig()
|
void ExportController::generateXrayConfig()
|
||||||
{
|
{
|
||||||
clearPreviousConfig();
|
QJsonObject nativeConfig;
|
||||||
|
ErrorCode errorCode = generateNativeConfig(DockerContainer::Xray, "", Proto::Xray, nativeConfig);
|
||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
|
||||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
|
||||||
|
|
||||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
|
||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
|
||||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
|
||||||
|
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
|
||||||
|
|
||||||
QString clientId;
|
|
||||||
QString config =
|
|
||||||
m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, Proto::Xray, clientId, &errorCode);
|
|
||||||
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::Xray, config);
|
|
||||||
QJsonObject configJson = QJsonDocument::fromJson(config.toUtf8()).object();
|
|
||||||
|
|
||||||
QStringList lines = QString(QJsonDocument(configJson).toJson()).replace("\r", "").split("\n");
|
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
||||||
for (const QString &line : lines) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
@@ -399,8 +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)
|
||||||
{
|
{
|
||||||
ErrorCode errorCode = m_clientManagementModel->revokeClient(row, container, credentials,
|
ErrorCode errorCode = m_clientManagementModel->revokeClient(row, container, credentials, m_serversModel->getProcessedServerIndex());
|
||||||
m_serversModel->getProcessedServerIndex());
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,9 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "configurators/vpn_configurator.h"
|
#include "ui/models/clientManagementModel.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"
|
||||||
#include "ui/models/clientManagementModel.h"
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
#include "platforms/android/authResultReceiver.h"
|
#include "platforms/android/authResultReceiver.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -15,11 +14,9 @@ class ExportController : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ExportController(const QSharedPointer<ServersModel> &serversModel,
|
explicit ExportController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ClientManagementModel> &clientManagementModel, const std::shared_ptr<Settings> &settings,
|
||||||
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
QObject *parent = nullptr);
|
||||||
const std::shared_ptr<Settings> &settings,
|
|
||||||
const std::shared_ptr<VpnConfigurator> &configurator, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
Q_PROPERTY(QList<QString> qrCodes READ getQrCodes NOTIFY exportConfigChanged)
|
Q_PROPERTY(QList<QString> qrCodes READ getQrCodes NOTIFY exportConfigChanged)
|
||||||
Q_PROPERTY(int qrCodesCount READ getQrCodesCount NOTIFY exportConfigChanged)
|
Q_PROPERTY(int qrCodesCount READ getQrCodesCount NOTIFY exportConfigChanged)
|
||||||
@@ -65,11 +62,13 @@ private:
|
|||||||
|
|
||||||
void clearPreviousConfig();
|
void clearPreviousConfig();
|
||||||
|
|
||||||
|
ErrorCode generateNativeConfig(const DockerContainer container, const QString &clientName, const Proto &protocol,
|
||||||
|
QJsonObject &jsonNativeConfig);
|
||||||
|
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
QSharedPointer<ContainersModel> m_containersModel;
|
QSharedPointer<ContainersModel> m_containersModel;
|
||||||
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
std::shared_ptr<VpnConfigurator> m_configurator;
|
|
||||||
|
|
||||||
QString m_config;
|
QString m_config;
|
||||||
QString m_nativeConfigString;
|
QString m_nativeConfigString;
|
||||||
|
|||||||
@@ -4,11 +4,13 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QEventLoop>
|
#include <QEventLoop>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QStandardPaths>
|
|
||||||
#include <QRandomGenerator>
|
#include <QRandomGenerator>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#include "core/errorstrings.h"
|
|
||||||
#include "core/controllers/serverController.h"
|
#include "core/controllers/serverController.h"
|
||||||
|
#include "core/controllers/vpnConfigurationController.h"
|
||||||
|
#include "core/errorstrings.h"
|
||||||
|
#include "logger.h"
|
||||||
#include "core/networkUtilities.h"
|
#include "core/networkUtilities.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "ui/models/protocols/awgConfigModel.h"
|
#include "ui/models/protocols/awgConfigModel.h"
|
||||||
@@ -16,6 +18,8 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
Logger logger("ServerController");
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
QString getNextDriverLetter()
|
QString getNextDriverLetter()
|
||||||
{
|
{
|
||||||
@@ -42,14 +46,15 @@ namespace
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallController::InstallController(const QSharedPointer<ServersModel> &serversModel,
|
InstallController::InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
|
||||||
const QSharedPointer<ProtocolsModel> &protocolsModel,
|
const QSharedPointer<ProtocolsModel> &protocolsModel,
|
||||||
|
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||||
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_protocolModel(protocolsModel),
|
m_protocolModel(protocolsModel),
|
||||||
|
m_clientManagementModel(clientManagementModel),
|
||||||
m_settings(settings)
|
m_settings(settings)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -74,8 +79,7 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||||||
|
|
||||||
if (protocol == mainProto) {
|
if (protocol == mainProto) {
|
||||||
containerConfig.insert(config_key::port, QString::number(port));
|
containerConfig.insert(config_key::port, QString::number(port));
|
||||||
containerConfig.insert(config_key::transport_proto,
|
containerConfig.insert(config_key::transport_proto, ProtocolProps::transportProtoToString(transportProto, protocol));
|
||||||
ProtocolProps::transportProtoToString(transportProto, protocol));
|
|
||||||
|
|
||||||
if (container == DockerContainer::Awg) {
|
if (container == DockerContainer::Awg) {
|
||||||
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(3, 10));
|
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(3, 10));
|
||||||
@@ -107,9 +111,7 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||||||
containerConfig[config_key::responsePacketMagicHeader] = responsePacketMagicHeader;
|
containerConfig[config_key::responsePacketMagicHeader] = responsePacketMagicHeader;
|
||||||
containerConfig[config_key::underloadPacketMagicHeader] = underloadPacketMagicHeader;
|
containerConfig[config_key::underloadPacketMagicHeader] = underloadPacketMagicHeader;
|
||||||
containerConfig[config_key::transportPacketMagicHeader] = transportPacketMagicHeader;
|
containerConfig[config_key::transportPacketMagicHeader] = transportPacketMagicHeader;
|
||||||
}
|
} else if (container == DockerContainer::Sftp) {
|
||||||
|
|
||||||
if (container == DockerContainer::Sftp) {
|
|
||||||
containerConfig.insert(config_key::userName, protocols::sftp::defaultUserName);
|
containerConfig.insert(config_key::userName, protocols::sftp::defaultUserName);
|
||||||
containerConfig.insert(config_key::password, Utils::getRandomString(10));
|
containerConfig.insert(config_key::password, Utils::getRandomString(10));
|
||||||
}
|
}
|
||||||
@@ -119,50 +121,92 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||||||
config.insert(ProtocolProps::protoToString(protocol), containerConfig);
|
config.insert(ProtocolProps::protoToString(protocol), containerConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerCredentials serverCredentials;
|
||||||
if (m_shouldCreateServer) {
|
if (m_shouldCreateServer) {
|
||||||
if (isServerAlreadyExists()) {
|
if (isServerAlreadyExists()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
installServer(container, config);
|
serverCredentials = m_processedServerCredentials;
|
||||||
} else {
|
} else {
|
||||||
installContainer(container, config);
|
int serverIndex = m_serversModel->getProcessedServerIndex();
|
||||||
}
|
serverCredentials = qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallController::installServer(DockerContainer container, QJsonObject &config)
|
|
||||||
{
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
|
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
|
||||||
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
|
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
|
||||||
|
|
||||||
QMap<DockerContainer, QJsonObject> installedContainers;
|
QMap<DockerContainer, QJsonObject> installedContainers;
|
||||||
ErrorCode errorCode =
|
ErrorCode errorCode = getAlreadyInstalledContainers(serverCredentials, installedContainers);
|
||||||
serverController.getAlreadyInstalledContainers(m_currentlyInstalledServerCredentials, installedContainers);
|
if (errorCode) {
|
||||||
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QString finishMessage = "";
|
QString finishMessage = "";
|
||||||
|
|
||||||
if (!installedContainers.contains(container)) {
|
if (!installedContainers.contains(container)) {
|
||||||
errorCode = serverController.setupContainer(m_currentlyInstalledServerCredentials, container, config);
|
errorCode = serverController.setupContainer(serverCredentials, container, config);
|
||||||
|
if (errorCode) {
|
||||||
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
installedContainers.insert(container, config);
|
installedContainers.insert(container, config);
|
||||||
finishMessage = tr("%1 installed successfully. ").arg(ContainerProps::containerHumanNames().value(container));
|
finishMessage = tr("%1 installed successfully. ").arg(ContainerProps::containerHumanNames().value(container));
|
||||||
} else {
|
} else {
|
||||||
finishMessage = tr("%1 is already installed on the server. ").arg(ContainerProps::containerHumanNames().value(container));
|
finishMessage = tr("%1 is already installed on the server. ").arg(ContainerProps::containerHumanNames().value(container));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (errorCode) {
|
||||||
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_shouldCreateServer) {
|
||||||
|
installServer(container, installedContainers, serverCredentials, finishMessage);
|
||||||
|
} else {
|
||||||
|
installContainer(container, installedContainers, serverCredentials, finishMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstallController::installServer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
||||||
|
const ServerCredentials &serverCredentials, 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");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
|
||||||
QJsonObject server;
|
QJsonObject server;
|
||||||
server.insert(config_key::hostName, m_currentlyInstalledServerCredentials.hostName);
|
server.insert(config_key::hostName, m_processedServerCredentials.hostName);
|
||||||
server.insert(config_key::userName, m_currentlyInstalledServerCredentials.userName);
|
server.insert(config_key::userName, m_processedServerCredentials.userName);
|
||||||
server.insert(config_key::password, m_currentlyInstalledServerCredentials.secretData);
|
server.insert(config_key::password, m_processedServerCredentials.secretData);
|
||||||
server.insert(config_key::port, m_currentlyInstalledServerCredentials.port);
|
server.insert(config_key::port, m_processedServerCredentials.port);
|
||||||
server.insert(config_key::description, m_settings->nextAvailableServerName());
|
server.insert(config_key::description, m_settings->nextAvailableServerName());
|
||||||
|
|
||||||
QJsonArray containerConfigs;
|
QJsonArray containerConfigs;
|
||||||
for (const QJsonObject &containerConfig : qAsConst(installedContainers)) {
|
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||||
|
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
|
||||||
|
auto containerConfig = iterator.value();
|
||||||
|
|
||||||
|
if (ContainerProps::isSupportedByCurrentPlatform(container)) {
|
||||||
|
auto errorCode =
|
||||||
|
vpnConfigurationController.createProtocolConfigForContainer(m_processedServerCredentials, iterator.key(), containerConfig);
|
||||||
|
if (errorCode) {
|
||||||
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
containerConfigs.append(containerConfig);
|
containerConfigs.append(containerConfig);
|
||||||
|
|
||||||
|
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||||
|
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||||
|
if (errorCode) {
|
||||||
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
containerConfigs.append(containerConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
server.insert(config_key::containers, containerConfigs);
|
server.insert(config_key::containers, containerConfigs);
|
||||||
@@ -171,42 +215,37 @@ void InstallController::installServer(DockerContainer container, QJsonObject &co
|
|||||||
m_serversModel->addServer(server);
|
m_serversModel->addServer(server);
|
||||||
|
|
||||||
emit installServerFinished(finishMessage);
|
emit installServerFinished(finishMessage);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
void InstallController::installContainer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
||||||
}
|
const ServerCredentials &serverCredentials, QString &finishMessage)
|
||||||
|
|
||||||
void InstallController::installContainer(DockerContainer container, QJsonObject &config)
|
|
||||||
{
|
{
|
||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
|
||||||
ServerCredentials serverCredentials =
|
|
||||||
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
|
|
||||||
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
|
|
||||||
|
|
||||||
QMap<DockerContainer, QJsonObject> installedContainers;
|
|
||||||
ErrorCode errorCode = serverController.getAlreadyInstalledContainers(serverCredentials, installedContainers);
|
|
||||||
|
|
||||||
QString finishMessage = "";
|
|
||||||
|
|
||||||
if (!installedContainers.contains(container)) {
|
|
||||||
errorCode = serverController.setupContainer(serverCredentials, container, config);
|
|
||||||
installedContainers.insert(container, config);
|
|
||||||
finishMessage = tr("%1 installed successfully. ").arg(ContainerProps::containerHumanNames().value(container));
|
|
||||||
} else {
|
|
||||||
finishMessage = tr("%1 is already installed on the server. ").arg(ContainerProps::containerHumanNames().value(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isInstalledContainerAddedToGui = false;
|
bool isInstalledContainerAddedToGui = false;
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
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()) {
|
||||||
m_serversModel->addContainerConfig(iterator.key(), iterator.value());
|
containerConfig = iterator.value();
|
||||||
|
|
||||||
|
if (ContainerProps::isSupportedByCurrentPlatform(container)) {
|
||||||
|
auto errorCode = vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, iterator.key(), containerConfig);
|
||||||
|
if (errorCode) {
|
||||||
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
|
||||||
|
|
||||||
|
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||||
|
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||||
|
if (errorCode) {
|
||||||
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
@@ -218,10 +257,6 @@ void InstallController::installContainer(DockerContainer container, QJsonObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
emit installContainerFinished(finishMessage, ContainerProps::containerService(container) == ServiceType::Other);
|
emit installContainerFinished(finishMessage, ContainerProps::containerService(container) == ServiceType::Other);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InstallController::isServerAlreadyExists()
|
bool InstallController::isServerAlreadyExists()
|
||||||
@@ -230,8 +265,7 @@ bool InstallController::isServerAlreadyExists()
|
|||||||
auto modelIndex = m_serversModel->index(i);
|
auto modelIndex = m_serversModel->index(i);
|
||||||
const ServerCredentials credentials =
|
const ServerCredentials credentials =
|
||||||
qvariant_cast<ServerCredentials>(m_serversModel->data(modelIndex, ServersModel::Roles::CredentialsRole));
|
qvariant_cast<ServerCredentials>(m_serversModel->data(modelIndex, ServersModel::Roles::CredentialsRole));
|
||||||
if (m_currentlyInstalledServerCredentials.hostName == credentials.hostName
|
if (m_processedServerCredentials.hostName == credentials.hostName && m_processedServerCredentials.port == credentials.port) {
|
||||||
&& m_currentlyInstalledServerCredentials.port == credentials.port) {
|
|
||||||
emit serverAlreadyExists(i);
|
emit serverAlreadyExists(i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -248,15 +282,37 @@ void InstallController::scanServerForInstalledContainers()
|
|||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
|
|
||||||
QMap<DockerContainer, QJsonObject> installedContainers;
|
QMap<DockerContainer, QJsonObject> installedContainers;
|
||||||
ErrorCode errorCode = serverController.getAlreadyInstalledContainers(serverCredentials, installedContainers);
|
ErrorCode errorCode = getAlreadyInstalledContainers(serverCredentials, installedContainers);
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
bool isInstalledContainerAddedToGui = false;
|
bool isInstalledContainerAddedToGui = false;
|
||||||
|
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());
|
auto container = iterator.key();
|
||||||
|
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||||
if (containerConfig.isEmpty()) {
|
if (containerConfig.isEmpty()) {
|
||||||
m_serversModel->addContainerConfig(iterator.key(), iterator.value());
|
containerConfig = iterator.value();
|
||||||
|
|
||||||
|
if (ContainerProps::isSupportedByCurrentPlatform(container)) {
|
||||||
|
auto errorCode =
|
||||||
|
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, container, containerConfig);
|
||||||
|
if (errorCode) {
|
||||||
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_serversModel->addContainerConfig(container, containerConfig);
|
||||||
|
|
||||||
|
errorCode = m_clientManagementModel->appendClient(container, serverCredentials, containerConfig,
|
||||||
|
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||||
|
if (errorCode) {
|
||||||
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_serversModel->addContainerConfig(container, containerConfig);
|
||||||
|
}
|
||||||
|
|
||||||
isInstalledContainerAddedToGui = true;
|
isInstalledContainerAddedToGui = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,6 +324,151 @@ void InstallController::scanServerForInstalledContainers()
|
|||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentials &credentials,
|
||||||
|
QMap<DockerContainer, QJsonObject> &installedContainers)
|
||||||
|
{
|
||||||
|
QString stdOut;
|
||||||
|
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
||||||
|
stdOut += data + "\n";
|
||||||
|
return ErrorCode::NoError;
|
||||||
|
};
|
||||||
|
auto cbReadStdErr = [&](const QString &data, libssh::Client &) {
|
||||||
|
stdOut += data + "\n";
|
||||||
|
return ErrorCode::NoError;
|
||||||
|
};
|
||||||
|
|
||||||
|
ServerController serverController(m_settings);
|
||||||
|
QString script = QString("sudo docker ps --format '{{.Names}} {{.Ports}}'");
|
||||||
|
|
||||||
|
ErrorCode errorCode = serverController.runScript(credentials, script, cbReadStdOut, cbReadStdErr);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto containersInfo = stdOut.split("\n");
|
||||||
|
for (auto &containerInfo : containersInfo) {
|
||||||
|
if (containerInfo.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const static QRegularExpression containerAndPortRegExp("(amnezia[-a-z]*).*?:([0-9]*)->[0-9]*/(udp|tcp).*");
|
||||||
|
QRegularExpressionMatch containerAndPortMatch = containerAndPortRegExp.match(containerInfo);
|
||||||
|
if (containerAndPortMatch.hasMatch()) {
|
||||||
|
QString name = containerAndPortMatch.captured(1);
|
||||||
|
QString port = containerAndPortMatch.captured(2);
|
||||||
|
QString transportProto = containerAndPortMatch.captured(3);
|
||||||
|
DockerContainer container = ContainerProps::containerFromString(name);
|
||||||
|
|
||||||
|
QJsonObject config;
|
||||||
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
|
for (auto protocol : ContainerProps::protocolsForContainer(container)) {
|
||||||
|
QJsonObject containerConfig;
|
||||||
|
if (protocol == mainProto) {
|
||||||
|
containerConfig.insert(config_key::port, port);
|
||||||
|
containerConfig.insert(config_key::transport_proto, transportProto);
|
||||||
|
|
||||||
|
if (protocol == Proto::Awg) {
|
||||||
|
QString serverConfig = serverController.getTextFileFromContainer(container, credentials,
|
||||||
|
protocols::awg::serverConfigPath, errorCode);
|
||||||
|
|
||||||
|
QMap<QString, QString> serverConfigMap;
|
||||||
|
auto serverConfigLines = serverConfig.split("\n");
|
||||||
|
for (auto &line : serverConfigLines) {
|
||||||
|
auto trimmedLine = line.trimmed();
|
||||||
|
if (trimmedLine.startsWith("[") && trimmedLine.endsWith("]")) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
QStringList parts = trimmedLine.split(" = ");
|
||||||
|
if (parts.count() == 2) {
|
||||||
|
serverConfigMap.insert(parts[0].trimmed(), parts[1].trimmed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
containerConfig[config_key::junkPacketCount] = serverConfigMap.value(config_key::junkPacketCount);
|
||||||
|
containerConfig[config_key::junkPacketMinSize] = serverConfigMap.value(config_key::junkPacketMinSize);
|
||||||
|
containerConfig[config_key::junkPacketMaxSize] = serverConfigMap.value(config_key::junkPacketMaxSize);
|
||||||
|
containerConfig[config_key::initPacketJunkSize] = serverConfigMap.value(config_key::initPacketJunkSize);
|
||||||
|
containerConfig[config_key::responsePacketJunkSize] = serverConfigMap.value(config_key::responsePacketJunkSize);
|
||||||
|
containerConfig[config_key::initPacketMagicHeader] = serverConfigMap.value(config_key::initPacketMagicHeader);
|
||||||
|
containerConfig[config_key::responsePacketMagicHeader] = serverConfigMap.value(config_key::responsePacketMagicHeader);
|
||||||
|
containerConfig[config_key::underloadPacketMagicHeader] =
|
||||||
|
serverConfigMap.value(config_key::underloadPacketMagicHeader);
|
||||||
|
containerConfig[config_key::transportPacketMagicHeader] =
|
||||||
|
serverConfigMap.value(config_key::transportPacketMagicHeader);
|
||||||
|
} else if (protocol == Proto::Sftp) {
|
||||||
|
stdOut.clear();
|
||||||
|
script = QString("sudo docker inspect --format '{{.Config.Cmd}}' %1").arg(name);
|
||||||
|
|
||||||
|
ErrorCode errorCode = serverController.runScript(credentials, script, cbReadStdOut, cbReadStdErr);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto sftpInfo = stdOut.split(":");
|
||||||
|
if (sftpInfo.size() < 2) {
|
||||||
|
logger.error() << "Key parameters for the sftp container are missing";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto userName = sftpInfo.at(0);
|
||||||
|
userName = userName.remove(0, 1);
|
||||||
|
auto password = sftpInfo.at(1);
|
||||||
|
|
||||||
|
containerConfig.insert(config_key::userName, userName);
|
||||||
|
containerConfig.insert(config_key::password, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
config.insert(config_key::container, ContainerProps::containerToString(container));
|
||||||
|
}
|
||||||
|
config.insert(ProtocolProps::protoToString(protocol), containerConfig);
|
||||||
|
}
|
||||||
|
installedContainers.insert(container, config);
|
||||||
|
}
|
||||||
|
const static QRegularExpression torOrDnsRegExp("(amnezia-(?:torwebsite|dns)).*?([0-9]*)/(udp|tcp).*");
|
||||||
|
QRegularExpressionMatch torOrDnsRegMatch = torOrDnsRegExp.match(containerInfo);
|
||||||
|
if (torOrDnsRegMatch.hasMatch()) {
|
||||||
|
QString name = torOrDnsRegMatch.captured(1);
|
||||||
|
QString port = torOrDnsRegMatch.captured(2);
|
||||||
|
QString transportProto = torOrDnsRegMatch.captured(3);
|
||||||
|
DockerContainer container = ContainerProps::containerFromString(name);
|
||||||
|
|
||||||
|
QJsonObject config;
|
||||||
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
|
for (auto protocol : ContainerProps::protocolsForContainer(container)) {
|
||||||
|
QJsonObject containerConfig;
|
||||||
|
if (protocol == mainProto) {
|
||||||
|
containerConfig.insert(config_key::port, port);
|
||||||
|
containerConfig.insert(config_key::transport_proto, transportProto);
|
||||||
|
|
||||||
|
if (protocol == Proto::TorWebSite) {
|
||||||
|
stdOut.clear();
|
||||||
|
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);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stdOut.isEmpty()) {
|
||||||
|
logger.error() << "Key parameters for the tor container are missing";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString onion = stdOut;
|
||||||
|
onion.replace("\n", "");
|
||||||
|
containerConfig.insert(config_key::site, onion);
|
||||||
|
}
|
||||||
|
|
||||||
|
config.insert(config_key::container, ContainerProps::containerToString(container));
|
||||||
|
}
|
||||||
|
config.insert(ProtocolProps::protoToString(protocol), containerConfig);
|
||||||
|
}
|
||||||
|
installedContainers.insert(container, config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrorCode::NoError;
|
||||||
|
}
|
||||||
|
|
||||||
void InstallController::updateContainer(QJsonObject config)
|
void InstallController::updateContainer(QJsonObject config)
|
||||||
{
|
{
|
||||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
int serverIndex = m_serversModel->getProcessedServerIndex();
|
||||||
@@ -284,6 +485,7 @@ void InstallController::updateContainer(QJsonObject config)
|
|||||||
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
|
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
|
||||||
|
|
||||||
errorCode = serverController.updateContainer(serverCredentials, container, oldContainerConfig, config);
|
errorCode = serverController.updateContainer(serverCredentials, container, oldContainerConfig, config);
|
||||||
|
clearCachedProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
@@ -334,23 +536,51 @@ void InstallController::removeAllContainers()
|
|||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallController::removeCurrentlyProcessedContainer()
|
void InstallController::removeProcessedContainer()
|
||||||
{
|
{
|
||||||
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();
|
||||||
|
|
||||||
int container = m_containersModel->getCurrentlyProcessedContainerIndex();
|
int container = m_containersModel->getProcessedContainerIndex();
|
||||||
QString containerName = m_containersModel->getCurrentlyProcessedContainerName();
|
QString containerName = m_containersModel->getProcessedContainerName();
|
||||||
|
|
||||||
ErrorCode errorCode = m_serversModel->removeContainer(container);
|
ErrorCode errorCode = m_serversModel->removeContainer(container);
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
|
|
||||||
emit removeCurrentlyProcessedContainerFinished(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));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InstallController::removeApiConfig()
|
||||||
|
{
|
||||||
|
auto serverConfig = m_serversModel->getServerConfig(m_serversModel->getDefaultServerIndex());
|
||||||
|
|
||||||
|
serverConfig.remove(config_key::dns1);
|
||||||
|
serverConfig.remove(config_key::dns2);
|
||||||
|
serverConfig.remove(config_key::containers);
|
||||||
|
serverConfig.remove(config_key::hostName);
|
||||||
|
|
||||||
|
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
|
||||||
|
|
||||||
|
m_serversModel->editServer(serverConfig, m_serversModel->getDefaultServerIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstallController::clearCachedProfile()
|
||||||
|
{
|
||||||
|
int serverIndex = m_serversModel->getProcessedServerIndex();
|
||||||
|
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getProcessedContainerIndex());
|
||||||
|
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||||
|
ServerCredentials serverCredentials =
|
||||||
|
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||||
|
|
||||||
|
m_serversModel->clearCachedProfile(container);
|
||||||
|
m_clientManagementModel->revokeClient(containerConfig, container, serverCredentials, serverIndex);
|
||||||
|
|
||||||
|
emit cachedProfileCleared(tr("%1 cached profile cleared").arg(ContainerProps::containerHumanNames().value(container)));
|
||||||
|
}
|
||||||
|
|
||||||
QRegularExpression InstallController::ipAddressPortRegExp()
|
QRegularExpression InstallController::ipAddressPortRegExp()
|
||||||
{
|
{
|
||||||
return NetworkUtilities::ipAddressPortRegExp();
|
return NetworkUtilities::ipAddressPortRegExp();
|
||||||
@@ -361,17 +591,15 @@ QRegularExpression InstallController::ipAddressRegExp()
|
|||||||
return NetworkUtilities::ipAddressRegExp();
|
return NetworkUtilities::ipAddressRegExp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallController::setCurrentlyInstalledServerCredentials(const QString &hostName, const QString &userName,
|
void InstallController::setProcessedServerCredentials(const QString &hostName, const QString &userName, const QString &secretData)
|
||||||
const QString &secretData)
|
|
||||||
{
|
{
|
||||||
m_currentlyInstalledServerCredentials.hostName = hostName;
|
m_processedServerCredentials.hostName = hostName;
|
||||||
if (m_currentlyInstalledServerCredentials.hostName.contains(":")) {
|
if (m_processedServerCredentials.hostName.contains(":")) {
|
||||||
m_currentlyInstalledServerCredentials.port =
|
m_processedServerCredentials.port = m_processedServerCredentials.hostName.split(":").at(1).toInt();
|
||||||
m_currentlyInstalledServerCredentials.hostName.split(":").at(1).toInt();
|
m_processedServerCredentials.hostName = m_processedServerCredentials.hostName.split(":").at(0);
|
||||||
m_currentlyInstalledServerCredentials.hostName = m_currentlyInstalledServerCredentials.hostName.split(":").at(0);
|
|
||||||
}
|
}
|
||||||
m_currentlyInstalledServerCredentials.userName = userName;
|
m_processedServerCredentials.userName = userName;
|
||||||
m_currentlyInstalledServerCredentials.secretData = secretData;
|
m_processedServerCredentials.secretData = secretData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallController::setShouldCreateServer(bool shouldCreateServer)
|
void InstallController::setShouldCreateServer(bool shouldCreateServer)
|
||||||
@@ -398,8 +626,7 @@ void InstallController::mountSftpDrive(const QString &port, const QString &passw
|
|||||||
|
|
||||||
cmd = "C:\\Program Files\\SSHFS-Win\\bin\\sshfs.exe";
|
cmd = "C:\\Program Files\\SSHFS-Win\\bin\\sshfs.exe";
|
||||||
#elif defined AMNEZIA_DESKTOP
|
#elif defined AMNEZIA_DESKTOP
|
||||||
mountPath =
|
mountPath = QString("%1/sftp:%2:%3").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation), hostname, port);
|
||||||
QString("%1/sftp:%2:%3").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation), hostname, port);
|
|
||||||
QDir dir(mountPath);
|
QDir dir(mountPath);
|
||||||
if (!dir.exists()) {
|
if (!dir.exists()) {
|
||||||
dir.mkpath(mountPath);
|
dir.mkpath(mountPath);
|
||||||
@@ -461,8 +688,7 @@ bool InstallController::checkSshConnection()
|
|||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
m_privateKeyPassphrase = "";
|
m_privateKeyPassphrase = "";
|
||||||
|
|
||||||
if (m_currentlyInstalledServerCredentials.secretData.contains("BEGIN")
|
if (m_processedServerCredentials.secretData.contains("BEGIN") && m_processedServerCredentials.secretData.contains("PRIVATE KEY")) {
|
||||||
&& m_currentlyInstalledServerCredentials.secretData.contains("PRIVATE KEY")) {
|
|
||||||
auto passphraseCallback = [this]() {
|
auto passphraseCallback = [this]() {
|
||||||
emit passphraseRequestStarted();
|
emit passphraseRequestStarted();
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
@@ -473,10 +699,9 @@ bool InstallController::checkSshConnection()
|
|||||||
};
|
};
|
||||||
|
|
||||||
QString decryptedPrivateKey;
|
QString decryptedPrivateKey;
|
||||||
errorCode = serverController.getDecryptedPrivateKey(m_currentlyInstalledServerCredentials, decryptedPrivateKey,
|
errorCode = serverController.getDecryptedPrivateKey(m_processedServerCredentials, decryptedPrivateKey, passphraseCallback);
|
||||||
passphraseCallback);
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
m_currentlyInstalledServerCredentials.secretData = decryptedPrivateKey;
|
m_processedServerCredentials.secretData = decryptedPrivateKey;
|
||||||
} else {
|
} else {
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return false;
|
return false;
|
||||||
@@ -484,7 +709,7 @@ bool InstallController::checkSshConnection()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString output;
|
QString output;
|
||||||
output = serverController.checkSshConnection(m_currentlyInstalledServerCredentials, &errorCode);
|
output = serverController.checkSshConnection(m_processedServerCredentials, errorCode);
|
||||||
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit installationErrorOccurred(errorString(errorCode));
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
@@ -508,10 +733,10 @@ void InstallController::setEncryptedPassphrase(QString passphrase)
|
|||||||
void InstallController::addEmptyServer()
|
void InstallController::addEmptyServer()
|
||||||
{
|
{
|
||||||
QJsonObject server;
|
QJsonObject server;
|
||||||
server.insert(config_key::hostName, m_currentlyInstalledServerCredentials.hostName);
|
server.insert(config_key::hostName, m_processedServerCredentials.hostName);
|
||||||
server.insert(config_key::userName, m_currentlyInstalledServerCredentials.userName);
|
server.insert(config_key::userName, m_processedServerCredentials.userName);
|
||||||
server.insert(config_key::password, m_currentlyInstalledServerCredentials.secretData);
|
server.insert(config_key::password, m_processedServerCredentials.secretData);
|
||||||
server.insert(config_key::port, m_currentlyInstalledServerCredentials.port);
|
server.insert(config_key::port, m_processedServerCredentials.port);
|
||||||
server.insert(config_key::description, m_settings->nextAvailableServerName());
|
server.insert(config_key::description, m_settings->nextAvailableServerName());
|
||||||
|
|
||||||
server.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
|
server.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
|
||||||
@@ -532,17 +757,17 @@ bool InstallController::isUpdateDockerContainerRequired(const DockerContainer co
|
|||||||
const AwgConfig oldConfig(oldProtoConfig);
|
const AwgConfig oldConfig(oldProtoConfig);
|
||||||
const AwgConfig newConfig(newProtoConfig);
|
const AwgConfig newConfig(newProtoConfig);
|
||||||
|
|
||||||
if (!oldConfig.hasEqualServerSettings(newConfig)) {
|
if (oldConfig.hasEqualServerSettings(newConfig)) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (container == DockerContainer::WireGuard) {
|
} else if (container == DockerContainer::WireGuard) {
|
||||||
const WgConfig oldConfig(oldProtoConfig);
|
const WgConfig oldConfig(oldProtoConfig);
|
||||||
const WgConfig newConfig(newProtoConfig);
|
const WgConfig newConfig(newProtoConfig);
|
||||||
|
|
||||||
if (!oldConfig.hasEqualServerSettings(newConfig)) {
|
if (oldConfig.hasEqualServerSettings(newConfig)) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,24 +6,24 @@
|
|||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "core/defs.h"
|
#include "core/defs.h"
|
||||||
|
#include "ui/models/clientManagementModel.h"
|
||||||
#include "ui/models/containers_model.h"
|
#include "ui/models/containers_model.h"
|
||||||
#include "ui/models/servers_model.h"
|
|
||||||
#include "ui/models/protocols_model.h"
|
#include "ui/models/protocols_model.h"
|
||||||
|
#include "ui/models/servers_model.h"
|
||||||
|
|
||||||
class InstallController : public QObject
|
class InstallController : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit InstallController(const QSharedPointer<ServersModel> &serversModel,
|
explicit InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
|
||||||
const QSharedPointer<ProtocolsModel> &protocolsModel,
|
const QSharedPointer<ProtocolsModel> &protocolsModel,
|
||||||
|
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||||
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||||
~InstallController();
|
~InstallController();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void install(DockerContainer container, int port, TransportProto transportProto);
|
void install(DockerContainer container, int port, TransportProto transportProto);
|
||||||
void setCurrentlyInstalledServerCredentials(const QString &hostName, const QString &userName,
|
void setProcessedServerCredentials(const QString &hostName, const QString &userName, const QString &secretData);
|
||||||
const QString &secretData);
|
|
||||||
void setShouldCreateServer(bool shouldCreateServer);
|
void setShouldCreateServer(bool shouldCreateServer);
|
||||||
|
|
||||||
void scanServerForInstalledContainers();
|
void scanServerForInstalledContainers();
|
||||||
@@ -33,7 +33,11 @@ public slots:
|
|||||||
void removeProcessedServer();
|
void removeProcessedServer();
|
||||||
void rebootProcessedServer();
|
void rebootProcessedServer();
|
||||||
void removeAllContainers();
|
void removeAllContainers();
|
||||||
void removeCurrentlyProcessedContainer();
|
void removeProcessedContainer();
|
||||||
|
|
||||||
|
void removeApiConfig();
|
||||||
|
|
||||||
|
void clearCachedProfile();
|
||||||
|
|
||||||
QRegularExpression ipAddressPortRegExp();
|
QRegularExpression ipAddressPortRegExp();
|
||||||
QRegularExpression ipAddressRegExp();
|
QRegularExpression ipAddressRegExp();
|
||||||
@@ -57,7 +61,7 @@ signals:
|
|||||||
void rebootProcessedServerFinished(const QString &finishedMessage);
|
void rebootProcessedServerFinished(const QString &finishedMessage);
|
||||||
void removeProcessedServerFinished(const QString &finishedMessage);
|
void removeProcessedServerFinished(const QString &finishedMessage);
|
||||||
void removeAllContainersFinished(const QString &finishedMessage);
|
void removeAllContainersFinished(const QString &finishedMessage);
|
||||||
void removeCurrentlyProcessedContainerFinished(const QString &finishedMessage);
|
void removeProcessedContainerFinished(const QString &finishedMessage);
|
||||||
|
|
||||||
void installationErrorOccurred(const QString &errorMessage);
|
void installationErrorOccurred(const QString &errorMessage);
|
||||||
|
|
||||||
@@ -71,19 +75,25 @@ signals:
|
|||||||
|
|
||||||
void currentContainerUpdated();
|
void currentContainerUpdated();
|
||||||
|
|
||||||
|
void cachedProfileCleared(const QString &message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void installServer(DockerContainer container, QJsonObject &config);
|
void installServer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
||||||
void installContainer(DockerContainer container, QJsonObject &config);
|
const ServerCredentials &serverCredentials, QString &finishMessage);
|
||||||
|
void installContainer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
||||||
|
const ServerCredentials &serverCredentials, QString &finishMessage);
|
||||||
bool isServerAlreadyExists();
|
bool isServerAlreadyExists();
|
||||||
|
|
||||||
|
ErrorCode getAlreadyInstalledContainers(const ServerCredentials &credentials, 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;
|
||||||
QSharedPointer<ContainersModel> m_containersModel;
|
QSharedPointer<ContainersModel> m_containersModel;
|
||||||
QSharedPointer<ProtocolsModel> m_protocolModel;
|
QSharedPointer<ProtocolsModel> m_protocolModel;
|
||||||
|
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
|
|
||||||
ServerCredentials m_currentlyInstalledServerCredentials;
|
ServerCredentials m_processedServerCredentials;
|
||||||
|
|
||||||
bool m_shouldCreateServer;
|
bool m_shouldCreateServer;
|
||||||
|
|
||||||
|
|||||||
@@ -153,12 +153,6 @@ void SettingsController::clearSettings()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsController::clearCachedProfiles()
|
|
||||||
{
|
|
||||||
m_serversModel->clearCachedProfiles();
|
|
||||||
emit changeSettingsFinished(tr("Cached profiles cleared"));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SettingsController::isAutoConnectEnabled()
|
bool SettingsController::isAutoConnectEnabled()
|
||||||
{
|
{
|
||||||
return m_settings->isAutoConnect();
|
return m_settings->isAutoConnect();
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ public slots:
|
|||||||
QString getAppVersion();
|
QString getAppVersion();
|
||||||
|
|
||||||
void clearSettings();
|
void clearSettings();
|
||||||
void clearCachedProfiles();
|
|
||||||
|
|
||||||
bool isAutoConnectEnabled();
|
bool isAutoConnectEnabled();
|
||||||
void toggleAutoConnect(bool enable);
|
void toggleAutoConnect(bool enable);
|
||||||
|
|||||||
@@ -5,14 +5,8 @@
|
|||||||
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)
|
||||||
{
|
{
|
||||||
auto routeMode = m_settings->getAppsRouteMode();
|
m_isSplitTunnelingEnabled = m_settings->getAppsSplitTunnelingEnabled();
|
||||||
if (routeMode == Settings::AppsRouteMode::VpnAllApps) {
|
m_currentRouteMode = m_settings->getAppsRouteMode();
|
||||||
m_isSplitTunnelingEnabled = false;
|
|
||||||
m_currentRouteMode = Settings::AppsRouteMode::VpnAllExceptApps;
|
|
||||||
} else {
|
|
||||||
m_isSplitTunnelingEnabled = true;
|
|
||||||
m_currentRouteMode = routeMode;
|
|
||||||
}
|
|
||||||
m_apps = m_settings->getVpnApps(m_currentRouteMode);
|
m_apps = m_settings->getVpnApps(m_currentRouteMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,11 +78,7 @@ bool AppSplitTunnelingModel::isSplitTunnelingEnabled()
|
|||||||
|
|
||||||
void AppSplitTunnelingModel::toggleSplitTunneling(bool enabled)
|
void AppSplitTunnelingModel::toggleSplitTunneling(bool enabled)
|
||||||
{
|
{
|
||||||
if (enabled) {
|
m_settings->setAppsSplitTunnelingEnabled(enabled);
|
||||||
setRouteMode(m_currentRouteMode);
|
|
||||||
} else {
|
|
||||||
m_settings->setAppsRouteMode(Settings::AppsRouteMode::VpnAllApps);
|
|
||||||
}
|
|
||||||
m_isSplitTunnelingEnabled = enabled;
|
m_isSplitTunnelingEnabled = enabled;
|
||||||
emit splitTunnelingToggled();
|
emit splitTunnelingToggled();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ namespace
|
|||||||
{
|
{
|
||||||
Logger logger("ClientManagementModel");
|
Logger logger("ClientManagementModel");
|
||||||
|
|
||||||
namespace configKey {
|
namespace configKey
|
||||||
|
{
|
||||||
constexpr char clientId[] = "clientId";
|
constexpr char clientId[] = "clientId";
|
||||||
constexpr char clientName[] = "clientName";
|
constexpr char clientName[] = "clientName";
|
||||||
constexpr char container[] = "container";
|
constexpr char container[] = "container";
|
||||||
@@ -61,7 +62,6 @@ void ClientManagementModel::migration(const QByteArray &clientsTableString)
|
|||||||
|
|
||||||
m_clientsTable.push_back(client);
|
m_clientsTable.push_back(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCredentials credentials)
|
ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCredentials credentials)
|
||||||
@@ -74,15 +74,13 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
|
|||||||
ErrorCode error = ErrorCode::NoError;
|
ErrorCode error = ErrorCode::NoError;
|
||||||
|
|
||||||
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
||||||
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks
|
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
|| container == DockerContainer::Cloak) {
|
|
||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
||||||
} else {
|
} else {
|
||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray clientsTableString =
|
const QByteArray clientsTableString = serverController.getTextFileFromContainer(container, credentials, clientsTableFile, error);
|
||||||
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();
|
||||||
@@ -96,8 +94,7 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
|
|||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks
|
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
|| container == DockerContainer::Cloak) {
|
|
||||||
error = getOpenVpnClients(serverController, container, credentials, 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(serverController, container, credentials, count);
|
error = getWireGuardClients(serverController, container, credentials, count);
|
||||||
@@ -109,8 +106,7 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
|
|||||||
|
|
||||||
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,
|
error = serverController.uploadTextFileToContainer(container, credentials, newClientsTableString, clientsTableFile);
|
||||||
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";
|
||||||
}
|
}
|
||||||
@@ -121,7 +117,8 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::getOpenVpnClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count)
|
ErrorCode ClientManagementModel::getOpenVpnClients(ServerController &serverController, DockerContainer container,
|
||||||
|
ServerCredentials credentials, int &count)
|
||||||
{
|
{
|
||||||
ErrorCode error = ErrorCode::NoError;
|
ErrorCode error = ErrorCode::NoError;
|
||||||
QString stdOut;
|
QString stdOut;
|
||||||
@@ -130,10 +127,8 @@ ErrorCode ClientManagementModel::getOpenVpnClients(ServerController &serverContr
|
|||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
};
|
};
|
||||||
|
|
||||||
const QString getOpenVpnClientsList =
|
const QString getOpenVpnClientsList = "sudo docker exec -i $CONTAINER_NAME bash -c 'ls /opt/amnezia/openvpn/pki/issued'";
|
||||||
"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";
|
||||||
@@ -163,14 +158,13 @@ ErrorCode ClientManagementModel::getOpenVpnClients(ServerController &serverContr
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::getWireGuardClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count)
|
ErrorCode ClientManagementModel::getWireGuardClients(ServerController &serverController, DockerContainer container,
|
||||||
|
ServerCredentials credentials, int &count)
|
||||||
{
|
{
|
||||||
ErrorCode error = ErrorCode::NoError;
|
ErrorCode error = ErrorCode::NoError;
|
||||||
|
|
||||||
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;
|
||||||
@@ -215,10 +209,27 @@ bool ClientManagementModel::isClientExists(const QString &clientId)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QString &clientName,
|
ErrorCode ClientManagementModel::appendClient(const DockerContainer container, const ServerCredentials &credentials,
|
||||||
const DockerContainer container, ServerCredentials credentials)
|
const QJsonObject &containerConfig, const QString &clientName)
|
||||||
{
|
{
|
||||||
ErrorCode error;
|
Proto protocol;
|
||||||
|
if (container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
|
protocol = Proto::OpenVpn;
|
||||||
|
} else if (container == DockerContainer::OpenVpn || container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||||
|
protocol = ContainerProps::defaultProtocol(container);
|
||||||
|
} else {
|
||||||
|
return ErrorCode::NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto protocolConfig = ContainerProps::getProtocolConfigFromContainer(protocol, containerConfig);
|
||||||
|
|
||||||
|
return appendClient(protocolConfig.value(config_key::clientId).toString(), clientName, container, credentials);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QString &clientName, const DockerContainer container,
|
||||||
|
ServerCredentials credentials)
|
||||||
|
{
|
||||||
|
ErrorCode error = ErrorCode::NoError;
|
||||||
|
|
||||||
error = updateModel(container, credentials);
|
error = updateModel(container, credentials);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
@@ -246,8 +257,7 @@ ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QSt
|
|||||||
|
|
||||||
ServerController serverController(m_settings);
|
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
|
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
|| container == DockerContainer::Cloak) {
|
|
||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
||||||
} else {
|
} else {
|
||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
||||||
@@ -279,15 +289,13 @@ ErrorCode ClientManagementModel::renameClient(const int row, const QString &clie
|
|||||||
|
|
||||||
ServerController serverController(m_settings);
|
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
|
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
|| container == DockerContainer::Cloak) {
|
|
||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
||||||
} else {
|
} else {
|
||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode error =
|
ErrorCode error = serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
||||||
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";
|
||||||
}
|
}
|
||||||
@@ -295,15 +303,14 @@ ErrorCode ClientManagementModel::renameClient(const int row, const QString &clie
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::revokeClient(const int row, const DockerContainer container,
|
ErrorCode ClientManagementModel::revokeClient(const int row, const DockerContainer container, ServerCredentials credentials,
|
||||||
ServerCredentials credentials, const int serverIndex)
|
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
|
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
|| container == DockerContainer::Cloak) {
|
|
||||||
errorCode = revokeOpenVpn(row, container, credentials, serverIndex);
|
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);
|
errorCode = revokeWireGuard(row, container, credentials);
|
||||||
@@ -333,8 +340,50 @@ ErrorCode ClientManagementModel::revokeClient(const int row, const DockerContain
|
|||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContainer container,
|
ErrorCode ClientManagementModel::revokeClient(const QJsonObject &containerConfig, const DockerContainer container, ServerCredentials credentials,
|
||||||
ServerCredentials credentials, const int serverIndex)
|
const int serverIndex)
|
||||||
|
{
|
||||||
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
errorCode = updateModel(container, credentials);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
Proto protocol;
|
||||||
|
if (container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
|
protocol = Proto::OpenVpn;
|
||||||
|
} else if (container == DockerContainer::OpenVpn || container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||||
|
protocol = ContainerProps::defaultProtocol(container);
|
||||||
|
} else {
|
||||||
|
return ErrorCode::NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto protocolConfig = ContainerProps::getProtocolConfigFromContainer(protocol, containerConfig);
|
||||||
|
|
||||||
|
int row;
|
||||||
|
bool clientExists = false;
|
||||||
|
QString clientId = protocolConfig.value(config_key::clientId).toString();
|
||||||
|
for (row = 0; row < rowCount(); row++) {
|
||||||
|
auto client = m_clientsTable.at(row).toObject();
|
||||||
|
if (clientId == client.value(configKey::clientId).toString()) {
|
||||||
|
clientExists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!clientExists) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
|
errorCode = revokeOpenVpn(row, container, credentials, serverIndex);
|
||||||
|
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||||
|
errorCode = revokeWireGuard(row, container, credentials);
|
||||||
|
}
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContainer container, ServerCredentials credentials,
|
||||||
|
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();
|
||||||
@@ -348,8 +397,7 @@ ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContai
|
|||||||
.arg(clientId);
|
.arg(clientId);
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
const QString script =
|
const QString script = serverController.replaceVars(getOpenVpnCertData, serverController.genVarsForScript(credentials, container));
|
||||||
serverController.replaceVars(getOpenVpnCertData, serverController.genVarsForScript(credentials, container));
|
|
||||||
ErrorCode error = serverController.runScript(credentials, script);
|
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";
|
||||||
@@ -373,16 +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,
|
ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerContainer container, ServerCredentials credentials)
|
||||||
ServerCredentials credentials)
|
|
||||||
{
|
{
|
||||||
ErrorCode error;
|
ErrorCode error = ErrorCode::NoError;
|
||||||
ServerController serverController(m_settings);
|
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 =
|
const QString wireguardConfigString = serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, error);
|
||||||
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;
|
||||||
@@ -413,8 +459,7 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
|
|||||||
const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
|
const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
|
||||||
|
|
||||||
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
||||||
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks
|
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||||
|| container == DockerContainer::Cloak) {
|
|
||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(DockerContainer::OpenVpn));
|
||||||
} else {
|
} else {
|
||||||
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
clientsTableFile = clientsTableFile.arg(ContainerProps::containerTypeToString(container));
|
||||||
@@ -428,8 +473,7 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
|
|||||||
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.replaceVars(script.arg(wireGuardConfigFile), serverController.genVarsForScript(credentials, container)));
|
||||||
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;
|
||||||
|
|||||||
@@ -24,11 +24,14 @@ public:
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
ErrorCode updateModel(DockerContainer container, ServerCredentials credentials);
|
ErrorCode updateModel(DockerContainer container, ServerCredentials credentials);
|
||||||
|
ErrorCode appendClient(const DockerContainer container, const ServerCredentials &credentials, const QJsonObject &containerConfig,
|
||||||
|
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,
|
||||||
ServerCredentials credentials);
|
ServerCredentials credentials);
|
||||||
ErrorCode renameClient(const int row, const QString &userName, const DockerContainer container,
|
ErrorCode renameClient(const int row, const QString &userName, const DockerContainer container, ServerCredentials credentials,
|
||||||
ServerCredentials credentials, bool addTimeStamp = false);
|
bool addTimeStamp = false);
|
||||||
ErrorCode revokeClient(const int index, const DockerContainer container, ServerCredentials credentials, const int serverIndex);
|
ErrorCode revokeClient(const int index, const DockerContainer container, ServerCredentials credentials, const int serverIndex);
|
||||||
|
ErrorCode revokeClient(const QJsonObject &containerConfig, const DockerContainer container, ServerCredentials credentials, const int serverIndex);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ QVariant ContainersModel::data(const QModelIndex &index, int role) const
|
|||||||
case EasySetupDescriptionRole: return ContainerProps::easySetupDescription(container);
|
case EasySetupDescriptionRole: return ContainerProps::easySetupDescription(container);
|
||||||
case EasySetupOrderRole: return ContainerProps::easySetupOrder(container);
|
case EasySetupOrderRole: return ContainerProps::easySetupOrder(container);
|
||||||
case IsInstalledRole: return m_containers.contains(container);
|
case IsInstalledRole: return m_containers.contains(container);
|
||||||
case IsCurrentlyProcessedRole: return container == static_cast<DockerContainer>(m_currentlyProcessedContainerIndex);
|
case IsCurrentlyProcessedRole: return container == static_cast<DockerContainer>(m_processedContainerIndex);
|
||||||
case IsSupportedRole: return ContainerProps::isSupportedByCurrentPlatform(container);
|
case IsSupportedRole: return ContainerProps::isSupportedByCurrentPlatform(container);
|
||||||
case IsShareableRole: return ContainerProps::isShareable(container);
|
case IsShareableRole: return ContainerProps::isShareable(container);
|
||||||
}
|
}
|
||||||
@@ -63,19 +63,19 @@ void ContainersModel::updateModel(const QJsonArray &containers)
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContainersModel::setCurrentlyProcessedContainerIndex(int index)
|
void ContainersModel::setProcessedContainerIndex(int index)
|
||||||
{
|
{
|
||||||
m_currentlyProcessedContainerIndex = index;
|
m_processedContainerIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ContainersModel::getCurrentlyProcessedContainerIndex()
|
int ContainersModel::getProcessedContainerIndex()
|
||||||
{
|
{
|
||||||
return m_currentlyProcessedContainerIndex;
|
return m_processedContainerIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ContainersModel::getCurrentlyProcessedContainerName()
|
QString ContainersModel::getProcessedContainerName()
|
||||||
{
|
{
|
||||||
return ContainerProps::containerHumanNames().value(static_cast<DockerContainer>(m_currentlyProcessedContainerIndex));
|
return ContainerProps::containerHumanNames().value(static_cast<DockerContainer>(m_processedContainerIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject ContainersModel::getContainerConfig(const int containerIndex)
|
QJsonObject ContainersModel::getContainerConfig(const int containerIndex)
|
||||||
@@ -83,6 +83,16 @@ 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;
|
||||||
|
|||||||
@@ -42,13 +42,16 @@ public:
|
|||||||
public slots:
|
public slots:
|
||||||
void updateModel(const QJsonArray &containers);
|
void updateModel(const QJsonArray &containers);
|
||||||
|
|
||||||
void setCurrentlyProcessedContainerIndex(int containerIndex);
|
void setProcessedContainerIndex(int containerIndex);
|
||||||
int getCurrentlyProcessedContainerIndex();
|
int getProcessedContainerIndex();
|
||||||
|
|
||||||
QString getCurrentlyProcessedContainerName();
|
QString getProcessedContainerName();
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@@ -58,7 +61,7 @@ signals:
|
|||||||
private:
|
private:
|
||||||
QMap<DockerContainer, QJsonObject> m_containers;
|
QMap<DockerContainer, QJsonObject> m_containers;
|
||||||
|
|
||||||
int m_currentlyProcessedContainerIndex;
|
int m_processedContainerIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONTAINERS_MODEL_H
|
#endif // CONTAINERS_MODEL_H
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ QVector<QPair<QString, QString>> InstalledAppsModel::getSelectedAppsInfo()
|
|||||||
appsInfo.push_back({ appName, packageName });
|
appsInfo.push_back({ appName, packageName });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_selectedAppIndexes.clear();
|
||||||
return appsInfo;
|
return appsInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ 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;
|
||||||
@@ -60,6 +61,7 @@ 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;
|
||||||
@@ -74,6 +76,7 @@ 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,6 +13,7 @@ namespace LanguageSettings
|
|||||||
English,
|
English,
|
||||||
Russian,
|
Russian,
|
||||||
China_cn,
|
China_cn,
|
||||||
|
Ukrainian,
|
||||||
Persian,
|
Persian,
|
||||||
Arabic,
|
Arabic,
|
||||||
Burmese
|
Burmese
|
||||||
|
|||||||
@@ -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::tls_auth).toBool(protocols::openvpn::defaultTlsAuth));
|
protocolConfig.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns));
|
||||||
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::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns));
|
protocolConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth));
|
||||||
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));
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ QVariant ShadowSocksConfigModel::data(const QModelIndex &index, int role) const
|
|||||||
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort);
|
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort);
|
||||||
case Roles::CipherRole:
|
case Roles::CipherRole:
|
||||||
return m_protocolConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher);
|
return m_protocolConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher);
|
||||||
|
case Roles::IsPortEditableRole: return m_container == DockerContainer::ShadowSocks ? true : false;
|
||||||
|
case Roles::IsCipherEditableRole: return m_container == DockerContainer::ShadowSocks ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@@ -71,6 +73,8 @@ QHash<int, QByteArray> ShadowSocksConfigModel::roleNames() const
|
|||||||
|
|
||||||
roles[PortRole] = "port";
|
roles[PortRole] = "port";
|
||||||
roles[CipherRole] = "cipher";
|
roles[CipherRole] = "cipher";
|
||||||
|
roles[IsPortEditableRole] = "isPortEditable";
|
||||||
|
roles[IsCipherEditableRole] = "isCipherEditable";
|
||||||
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ class ShadowSocksConfigModel : public QAbstractListModel
|
|||||||
public:
|
public:
|
||||||
enum Roles {
|
enum Roles {
|
||||||
PortRole = Qt::UserRole + 1,
|
PortRole = Qt::UserRole + 1,
|
||||||
CipherRole
|
CipherRole,
|
||||||
|
IsPortEditableRole,
|
||||||
|
IsCipherEditableRole
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit ShadowSocksConfigModel(QObject *parent = nullptr);
|
explicit ShadowSocksConfigModel(QObject *parent = nullptr);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ void WireGuardConfigModel::updateModel(const QJsonObject &config)
|
|||||||
|
|
||||||
QJsonObject WireGuardConfigModel::getConfig()
|
QJsonObject WireGuardConfigModel::getConfig()
|
||||||
{
|
{
|
||||||
const WgConfig oldConfig(m_fullConfig.value(config_key::awg).toObject());
|
const WgConfig oldConfig(m_fullConfig.value(config_key::wireguard).toObject());
|
||||||
const WgConfig newConfig(m_protocolConfig);
|
const WgConfig newConfig(m_protocolConfig);
|
||||||
|
|
||||||
if (!oldConfig.hasEqualServerSettings(newConfig)) {
|
if (!oldConfig.hasEqualServerSettings(newConfig)) {
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ PageLoader::PageEnum ProtocolsModel::protocolPage(Proto protocol) const
|
|||||||
case Proto::Cloak: return PageLoader::PageEnum::PageProtocolCloakSettings;
|
case Proto::Cloak: return PageLoader::PageEnum::PageProtocolCloakSettings;
|
||||||
case Proto::ShadowSocks: return PageLoader::PageEnum::PageProtocolShadowSocksSettings;
|
case Proto::ShadowSocks: return PageLoader::PageEnum::PageProtocolShadowSocksSettings;
|
||||||
case Proto::WireGuard: return PageLoader::PageEnum::PageProtocolWireGuardSettings;
|
case Proto::WireGuard: return PageLoader::PageEnum::PageProtocolWireGuardSettings;
|
||||||
|
case Proto::Awg: return PageLoader::PageEnum::PageProtocolAwgSettings;
|
||||||
case Proto::Ikev2: return PageLoader::PageEnum::PageProtocolIKev2Settings;
|
case Proto::Ikev2: return PageLoader::PageEnum::PageProtocolIKev2Settings;
|
||||||
case Proto::L2tp: return PageLoader::PageEnum::PageProtocolIKev2Settings;
|
case Proto::L2tp: return PageLoader::PageEnum::PageProtocolIKev2Settings;
|
||||||
case Proto::Xray: return PageLoader::PageEnum::PageProtocolXraySettings;
|
case Proto::Xray: return PageLoader::PageEnum::PageProtocolXraySettings;
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
#include "servers_model.h"
|
#include "servers_model.h"
|
||||||
|
|
||||||
#include "core/controllers/serverController.h"
|
#include "core/controllers/serverController.h"
|
||||||
|
#include "core/networkUtilities.h"
|
||||||
|
|
||||||
ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
|
ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent) : m_settings(settings), QAbstractListModel(parent)
|
||||||
: m_settings(settings), QAbstractListModel(parent)
|
|
||||||
{
|
{
|
||||||
|
m_isAmneziaDnsEnabled = m_settings->useAmneziaDns();
|
||||||
|
|
||||||
connect(this, &ServersModel::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged);
|
connect(this, &ServersModel::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged);
|
||||||
|
|
||||||
connect(this, &ServersModel::defaultServerIndexChanged, this, [this](const int serverIndex) {
|
connect(this, &ServersModel::defaultServerIndexChanged, this, [this](const int serverIndex) {
|
||||||
auto defaultContainer = ContainerProps::containerFromString(m_servers.at(serverIndex).toObject().value(config_key::defaultContainer).toString());
|
auto defaultContainer =
|
||||||
|
ContainerProps::containerFromString(m_servers.at(serverIndex).toObject().value(config_key::defaultContainer).toString());
|
||||||
emit ServersModel::defaultServerDefaultContainerChanged(defaultContainer);
|
emit ServersModel::defaultServerDefaultContainerChanged(defaultContainer);
|
||||||
emit ServersModel::defaultServerNameChanged();
|
emit ServersModel::defaultServerNameChanged();
|
||||||
updateDefaultServerContainersModel();
|
updateDefaultServerContainersModel();
|
||||||
@@ -28,10 +31,15 @@ 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) {
|
||||||
@@ -336,9 +344,9 @@ void ServersModel::updateDefaultServerContainersModel()
|
|||||||
emit defaultServerContainersUpdated(containers);
|
emit defaultServerContainersUpdated(containers);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject ServersModel::getDefaultServerConfig()
|
QJsonObject ServersModel::getServerConfig(const int serverIndex)
|
||||||
{
|
{
|
||||||
return m_servers.at(m_defaultServerIndex).toObject();
|
return m_servers.at(serverIndex).toObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServersModel::reloadDefaultServerContainerConfig()
|
void ServersModel::reloadDefaultServerContainerConfig()
|
||||||
@@ -378,7 +386,8 @@ 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();
|
auto defaultContainer = server.value(config_key::defaultContainer).toString();
|
||||||
if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None || ContainerProps::containerService(container) != ServiceType::Other)) {
|
if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None
|
||||||
|
|| ContainerProps::containerService(container) != ServiceType::Other)) {
|
||||||
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,7 +405,9 @@ 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 || ContainerProps::containerService(container) != ServiceType::Other)) {
|
if (ContainerProps::containerFromString(defaultContainer) == DockerContainer::None
|
||||||
|
&& ContainerProps::containerService(container) != ServiceType::Other
|
||||||
|
&& ContainerProps::isSupportedByCurrentPlatform(container)) {
|
||||||
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,8 +431,7 @@ const QString ServersModel::getDefaultServerDefaultContainerName()
|
|||||||
ErrorCode ServersModel::removeAllContainers()
|
ErrorCode ServersModel::removeAllContainers()
|
||||||
{
|
{
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
ErrorCode errorCode =
|
ErrorCode errorCode = serverController.removeAllContainers(m_settings->serverCredentials(m_processedServerIndex));
|
||||||
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();
|
||||||
@@ -468,7 +478,8 @@ ErrorCode ServersModel::removeContainer(const int containerIndex)
|
|||||||
if (containers.empty()) {
|
if (containers.empty()) {
|
||||||
defaultContainer = DockerContainer::None;
|
defaultContainer = DockerContainer::None;
|
||||||
} else {
|
} else {
|
||||||
defaultContainer = ContainerProps::containerFromString(containers.begin()->toObject().value(config_key::container).toString());
|
defaultContainer =
|
||||||
|
ContainerProps::containerFromString(containers.begin()->toObject().value(config_key::container).toString());
|
||||||
}
|
}
|
||||||
server.insert(config_key::defaultContainer, ContainerProps::containerToString(defaultContainer));
|
server.insert(config_key::defaultContainer, ContainerProps::containerToString(defaultContainer));
|
||||||
}
|
}
|
||||||
@@ -478,24 +489,9 @@ ErrorCode ServersModel::removeContainer(const int containerIndex)
|
|||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServersModel::clearCachedProfiles()
|
|
||||||
{
|
|
||||||
const auto &containers = m_settings->containers(m_processedServerIndex);
|
|
||||||
for (DockerContainer container : containers.keys()) {
|
|
||||||
m_settings->clearLastConnectionConfig(m_processedServerIndex, container);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_servers.replace(m_processedServerIndex, m_settings->server(m_processedServerIndex));
|
|
||||||
if (m_processedServerIndex == m_defaultServerIndex) {
|
|
||||||
updateDefaultServerContainersModel();
|
|
||||||
}
|
|
||||||
updateContainersModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServersModel::clearCachedProfile(const DockerContainer container)
|
void ServersModel::clearCachedProfile(const DockerContainer container)
|
||||||
{
|
{
|
||||||
m_settings->clearLastConnectionConfig(m_processedServerIndex, container);
|
m_settings->clearLastConnectionConfig(m_processedServerIndex, container);
|
||||||
|
|
||||||
m_servers.replace(m_processedServerIndex, m_settings->server(m_processedServerIndex));
|
m_servers.replace(m_processedServerIndex, m_settings->server(m_processedServerIndex));
|
||||||
if (m_processedServerIndex == m_defaultServerIndex) {
|
if (m_processedServerIndex == m_defaultServerIndex) {
|
||||||
updateDefaultServerContainersModel();
|
updateDefaultServerContainersModel();
|
||||||
@@ -515,6 +511,36 @@ bool ServersModel::isAmneziaDnsContainerInstalled(const int serverIndex) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPair<QString, QString> ServersModel::getDnsPair(int serverIndex)
|
||||||
|
{
|
||||||
|
QPair<QString, QString> dns;
|
||||||
|
|
||||||
|
const QJsonObject &server = m_servers.at(m_processedServerIndex).toObject();
|
||||||
|
const auto containers = server.value(config_key::containers).toArray();
|
||||||
|
bool isDnsContainerInstalled = false;
|
||||||
|
for (const QJsonValue &container : containers) {
|
||||||
|
if (ContainerProps::containerFromString(container.toObject().value(config_key::container).toString()) == DockerContainer::Dns) {
|
||||||
|
isDnsContainerInstalled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dns.first = server.value(config_key::dns1).toString();
|
||||||
|
dns.second = server.value(config_key::dns2).toString();
|
||||||
|
|
||||||
|
if (dns.first.isEmpty() || !NetworkUtilities::checkIPv4Format(dns.first)) {
|
||||||
|
if (m_isAmneziaDnsEnabled && isDnsContainerInstalled) {
|
||||||
|
dns.first = protocols::dns::amneziaDnsIp;
|
||||||
|
} else
|
||||||
|
dns.first = m_settings->primaryDns();
|
||||||
|
}
|
||||||
|
if (dns.second.isEmpty() || !NetworkUtilities::checkIPv4Format(dns.second)) {
|
||||||
|
dns.second = m_settings->secondaryDns();
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "VpnConfigurator::getDnsForConfig" << dns.first << dns.second;
|
||||||
|
return dns;
|
||||||
|
}
|
||||||
|
|
||||||
QStringList ServersModel::getAllInstalledServicesName(const int serverIndex)
|
QStringList ServersModel::getAllInstalledServicesName(const int serverIndex)
|
||||||
{
|
{
|
||||||
QStringList servicesName;
|
QStringList servicesName;
|
||||||
@@ -598,7 +624,8 @@ bool ServersModel::isDefaultServerDefaultContainerHasSplitTunneling()
|
|||||||
|
|
||||||
if (defaultContainer == DockerContainer::Awg || defaultContainer == DockerContainer::WireGuard) {
|
if (defaultContainer == DockerContainer::Awg || defaultContainer == DockerContainer::WireGuard) {
|
||||||
return !(protocolConfig.value(config_key::last_config).toString().contains("AllowedIPs = 0.0.0.0/0, ::/0"));
|
return !(protocolConfig.value(config_key::last_config).toString().contains("AllowedIPs = 0.0.0.0/0, ::/0"));
|
||||||
} else if (defaultContainer == DockerContainer::Cloak || defaultContainer == DockerContainer::OpenVpn || defaultContainer == DockerContainer::ShadowSocks) {
|
} else if (defaultContainer == DockerContainer::Cloak || defaultContainer == DockerContainer::OpenVpn
|
||||||
|
|| defaultContainer == DockerContainer::ShadowSocks) {
|
||||||
return !(protocolConfig.value(config_key::last_config).toString().contains("redirect-gateway"));
|
return !(protocolConfig.value(config_key::last_config).toString().contains("redirect-gateway"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,13 +80,12 @@ public slots:
|
|||||||
void editServer(const QJsonObject &server, const int serverIndex);
|
void editServer(const QJsonObject &server, const int serverIndex);
|
||||||
void removeServer();
|
void removeServer();
|
||||||
|
|
||||||
QJsonObject getDefaultServerConfig();
|
QJsonObject getServerConfig(const int serverIndex);
|
||||||
|
|
||||||
void reloadDefaultServerContainerConfig();
|
void reloadDefaultServerContainerConfig();
|
||||||
void updateContainerConfig(const int containerIndex, const QJsonObject config);
|
void updateContainerConfig(const int containerIndex, const QJsonObject config);
|
||||||
void addContainerConfig(const int containerIndex, const QJsonObject config);
|
void addContainerConfig(const int containerIndex, const QJsonObject config);
|
||||||
|
|
||||||
void clearCachedProfiles();
|
|
||||||
void clearCachedProfile(const DockerContainer container);
|
void clearCachedProfile(const DockerContainer container);
|
||||||
|
|
||||||
ErrorCode removeContainer(const int containerIndex);
|
ErrorCode removeContainer(const int containerIndex);
|
||||||
@@ -98,6 +97,7 @@ public slots:
|
|||||||
QStringList getAllInstalledServicesName(const int serverIndex);
|
QStringList getAllInstalledServicesName(const int serverIndex);
|
||||||
|
|
||||||
void toggleAmneziaDns(bool enabled);
|
void toggleAmneziaDns(bool enabled);
|
||||||
|
QPair<QString, QString> getDnsPair(const int serverIndex);
|
||||||
|
|
||||||
bool isServerFromApiAlreadyExists(const quint16 crc);
|
bool isServerFromApiAlreadyExists(const quint16 crc);
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,8 @@
|
|||||||
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)
|
||||||
{
|
{
|
||||||
auto routeMode = m_settings->routeMode();
|
m_isSplitTunnelingEnabled = m_settings->getSitesSplitTunnelingEnabled();
|
||||||
if (routeMode == Settings::RouteMode::VpnAllSites) {
|
m_currentRouteMode = m_settings->routeMode();
|
||||||
m_isSplitTunnelingEnabled = false;
|
|
||||||
m_currentRouteMode = Settings::RouteMode::VpnOnlyForwardSites;
|
|
||||||
} else {
|
|
||||||
m_isSplitTunnelingEnabled = true;
|
|
||||||
m_currentRouteMode = routeMode;
|
|
||||||
}
|
|
||||||
fillSites();
|
fillSites();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,11 +101,7 @@ bool SitesModel::isSplitTunnelingEnabled()
|
|||||||
|
|
||||||
void SitesModel::toggleSplitTunneling(bool enabled)
|
void SitesModel::toggleSplitTunneling(bool enabled)
|
||||||
{
|
{
|
||||||
if (enabled) {
|
m_settings->setSitesSplitTunnelingEnabled(enabled);
|
||||||
setRouteMode(m_currentRouteMode);
|
|
||||||
} else {
|
|
||||||
m_settings->setRouteMode(Settings::RouteMode::VpnAllSites);
|
|
||||||
}
|
|
||||||
m_isSplitTunnelingEnabled = enabled;
|
m_isSplitTunnelingEnabled = enabled;
|
||||||
emit splitTunnelingToggled();
|
emit splitTunnelingToggled();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,16 @@ Button {
|
|||||||
implicitWidth: 190
|
implicitWidth: 190
|
||||||
implicitHeight: 190
|
implicitHeight: 190
|
||||||
|
|
||||||
|
text: ConnectionController.connectionStateText
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: ConnectionController
|
target: ConnectionController
|
||||||
|
|
||||||
function onConnectionErrorOccurred(errorMessage) {
|
function onPreparingConfig() {
|
||||||
PageController.showErrorMessage(errorMessage)
|
PageController.showNotificationMessage(qsTr("Unable to disconnect during configuration preparation"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
text: ConnectionController.connectionStateText
|
|
||||||
|
|
||||||
// enabled: !ConnectionController.isConnectionInProgress
|
// enabled: !ConnectionController.isConnectionInProgress
|
||||||
|
|
||||||
background: Item {
|
background: Item {
|
||||||
@@ -139,6 +139,6 @@ Button {
|
|||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
ServersModel.setProcessedServerIndex(ServersModel.defaultIndex)
|
ServersModel.setProcessedServerIndex(ServersModel.defaultIndex)
|
||||||
ApiController.updateServerConfigFromApi()
|
ConnectionController.connectButtonClicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ ListView {
|
|||||||
imageSource: "qrc:/images/controls/download.svg"
|
imageSource: "qrc:/images/controls/download.svg"
|
||||||
showImage: !isInstalled
|
showImage: !isInstalled
|
||||||
|
|
||||||
checkable: isInstalled && !ConnectionController.isConnected && isSupported
|
checkable: isInstalled && !ConnectionController.isConnected
|
||||||
checked: proxyDefaultServerContainersModel.mapToSource(index) === ServersModel.getDefaultServerData("defaultContainer")
|
checked: proxyDefaultServerContainersModel.mapToSource(index) === ServersModel.getDefaultServerData("defaultContainer")
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
@@ -64,12 +64,7 @@ ListView {
|
|||||||
containersDropDown.close()
|
containersDropDown.close()
|
||||||
ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyDefaultServerContainersModel.mapToSource(index))
|
ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyDefaultServerContainersModel.mapToSource(index))
|
||||||
} else {
|
} else {
|
||||||
if (!isSupported && isInstalled) {
|
ContainersModel.setProcessedContainerIndex(proxyDefaultServerContainersModel.mapToSource(index))
|
||||||
PageController.showErrorMessage(qsTr("The selected protocol is not supported on the current platform"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ContainersModel.setCurrentlyProcessedContainerIndex(proxyDefaultServerContainersModel.mapToSource(index))
|
|
||||||
InstallController.setShouldCreateServer(false)
|
InstallController.setShouldCreateServer(false)
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
|
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
|
||||||
containersDropDown.close()
|
containersDropDown.close()
|
||||||
|
|||||||
@@ -59,8 +59,6 @@ DrawerType2 {
|
|||||||
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"
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ 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 {
|
||||||
@@ -34,7 +36,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: addButton.top
|
anchors.bottom: searchField.top
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
@@ -66,7 +68,15 @@ DrawerType2 {
|
|||||||
clip: true
|
clip: true
|
||||||
interactive: true
|
interactive: true
|
||||||
|
|
||||||
model: installedAppsModel
|
model: SortFilterProxyModel {
|
||||||
|
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
|
||||||
@@ -93,7 +103,7 @@ DrawerType2 {
|
|||||||
text: appName
|
text: appName
|
||||||
|
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
listView.model.selectedStateChanged(index, checked)
|
installedAppsModel.selectedStateChanged(proxyInstalledAppsModel.mapToSource(index), checked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,6 +123,21 @@ 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
|
||||||
|
|
||||||
@@ -127,7 +152,7 @@ DrawerType2 {
|
|||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
AppSplitTunnelingController.addApps(listView.model.getSelectedAppsInfo())
|
AppSplitTunnelingController.addApps(installedAppsModel.getSelectedAppsInfo())
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ ListView {
|
|||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
if (isInstalled) {
|
if (isInstalled) {
|
||||||
var containerIndex = root.model.mapToSource(index)
|
var containerIndex = root.model.mapToSource(index)
|
||||||
ContainersModel.setCurrentlyProcessedContainerIndex(containerIndex)
|
ContainersModel.setProcessedContainerIndex(containerIndex)
|
||||||
|
|
||||||
if (serviceType !== ProtocolEnum.Other) {
|
if (serviceType !== ProtocolEnum.Other) {
|
||||||
if (config[ContainerProps.containerTypeToString(containerIndex)]["isThirdPartyConfig"]) {
|
if (config[ContainerProps.containerTypeToString(containerIndex)]["isThirdPartyConfig"]) {
|
||||||
@@ -52,27 +52,6 @@ ListView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (containerIndex) {
|
switch (containerIndex) {
|
||||||
case ContainerEnum.OpenVpn: {
|
|
||||||
OpenVpnConfigModel.updateModel(config)
|
|
||||||
PageController.goToPage(PageEnum.PageProtocolOpenVpnSettings)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case ContainerEnum.Xray: {
|
|
||||||
XrayConfigModel.updateModel(config)
|
|
||||||
PageController.goToPage(PageEnum.PageProtocolXraySettings)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case ContainerEnum.WireGuard: {
|
|
||||||
WireGuardConfigModel.updateModel(config)
|
|
||||||
PageController.goToPage(PageEnum.PageProtocolWireGuardSettings)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case ContainerEnum.Awg: {
|
|
||||||
AwgConfigModel.updateModel(config)
|
|
||||||
PageController.goToPage(PageEnum.PageProtocolAwgSettings)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case ContainerEnum.Ipsec: {
|
case ContainerEnum.Ipsec: {
|
||||||
ProtocolsModel.updateModel(config)
|
ProtocolsModel.updateModel(config)
|
||||||
PageController.goToPage(PageEnum.PageProtocolRaw)
|
PageController.goToPage(PageEnum.PageProtocolRaw)
|
||||||
@@ -98,7 +77,7 @@ ListView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ContainersModel.setCurrentlyProcessedContainerIndex(root.model.mapToSource(index))
|
ContainersModel.setProcessedContainerIndex(root.model.mapToSource(index))
|
||||||
InstallController.setShouldCreateServer(false)
|
InstallController.setShouldCreateServer(false)
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
|
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ PageType {
|
|||||||
|
|
||||||
Header1TextType {
|
Header1TextType {
|
||||||
id: collapsedButtonHeader
|
id: collapsedButtonHeader
|
||||||
Layout.maximumWidth: drawer.isCollapsed ? drawer.width - 48 - 18 - 12 : drawer.width// todo
|
Layout.maximumWidth: drawer.width - 48 - 18 - 12
|
||||||
|
|
||||||
maximumLineCount: 2
|
maximumLineCount: 2
|
||||||
elide: Qt.ElideRight
|
elide: Qt.ElideRight
|
||||||
|
|||||||
@@ -311,34 +311,6 @@ PageType {
|
|||||||
KeyNavigation.tab: saveRestartButton
|
KeyNavigation.tab: saveRestartButton
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
Layout.topMargin: 24
|
|
||||||
Layout.leftMargin: -8
|
|
||||||
implicitHeight: 32
|
|
||||||
|
|
||||||
defaultColor: "transparent"
|
|
||||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
|
||||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
|
||||||
textColor: "#EB5757"
|
|
||||||
|
|
||||||
text: qsTr("Remove AmneziaWG")
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
var headerText = qsTr("Remove AmneziaWG from server?")
|
|
||||||
var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
|
|
||||||
var yesButtonText = qsTr("Continue")
|
|
||||||
var noButtonText = qsTr("Cancel")
|
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
|
||||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
|
||||||
InstallController.removeCurrentlyProcessedContainer()
|
|
||||||
}
|
|
||||||
var noButtonFunction = function() {
|
|
||||||
}
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
id: saveRestartButton
|
id: saveRestartButton
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,6 @@ PageType {
|
|||||||
TextFieldWithHeaderType {
|
TextFieldWithHeaderType {
|
||||||
id: portTextField
|
id: portTextField
|
||||||
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 40
|
Layout.topMargin: 40
|
||||||
|
|
||||||
@@ -366,37 +365,6 @@ PageType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
Layout.topMargin: 24
|
|
||||||
Layout.leftMargin: -8
|
|
||||||
implicitHeight: 32
|
|
||||||
|
|
||||||
visible: ContainersModel.getCurrentlyProcessedContainerIndex() === ContainerEnum.OpenVpn
|
|
||||||
|
|
||||||
defaultColor: "transparent"
|
|
||||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
|
||||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
|
||||||
textColor: "#EB5757"
|
|
||||||
|
|
||||||
text: qsTr("Remove OpenVPN")
|
|
||||||
|
|
||||||
clickedFunc: function() {
|
|
||||||
var headerText = qsTr("Remove OpenVpn from server?")
|
|
||||||
var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
|
|
||||||
var yesButtonText = qsTr("Continue")
|
|
||||||
var noButtonText = qsTr("Cancel")
|
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
|
||||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
|
||||||
InstallController.removeCurrentlyProcessedContainer()
|
|
||||||
}
|
|
||||||
var noButtonFunction = function() {
|
|
||||||
}
|
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
id: saveRestartButton
|
id: saveRestartButton
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ PageType {
|
|||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
headerText: ContainersModel.getCurrentlyProcessedContainerName() + qsTr(" settings")
|
headerText: ContainersModel.getProcessedContainerName() + qsTr(" settings")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,18 +177,18 @@ PageType {
|
|||||||
|
|
||||||
visible: ServersModel.isProcessedServerHasWriteAccess()
|
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||||
|
|
||||||
text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName()
|
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getCurrentlyProcessedContainerName())
|
var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getProcessedContainerName())
|
||||||
var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
|
var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
|
||||||
var yesButtonText = qsTr("Continue")
|
var yesButtonText = qsTr("Continue")
|
||||||
var noButtonText = qsTr("Cancel")
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||||
InstallController.removeCurrentlyProcessedContainer()
|
InstallController.removeProcessedContainer()
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ PageType {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 40
|
Layout.topMargin: 40
|
||||||
|
|
||||||
|
enabled: isPortEditable
|
||||||
|
|
||||||
headerText: qsTr("Port")
|
headerText: qsTr("Port")
|
||||||
textFieldText: port
|
textFieldText: port
|
||||||
textField.maximumLength: 5
|
textField.maximumLength: 5
|
||||||
@@ -105,6 +107,8 @@ PageType {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
|
|
||||||
|
enabled: isCipherEditable
|
||||||
|
|
||||||
descriptionText: qsTr("Cipher")
|
descriptionText: qsTr("Cipher")
|
||||||
headerText: qsTr("Cipher")
|
headerText: qsTr("Cipher")
|
||||||
|
|
||||||
@@ -148,6 +152,8 @@ PageType {
|
|||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
|
enabled: isPortEditable | isCipherEditable
|
||||||
|
|
||||||
text: qsTr("Save")
|
text: qsTr("Save")
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
|
|||||||
@@ -114,35 +114,6 @@ PageType {
|
|||||||
checkEmptyText: true
|
checkEmptyText: true
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
Layout.topMargin: 24
|
|
||||||
Layout.leftMargin: -8
|
|
||||||
implicitHeight: 32
|
|
||||||
|
|
||||||
defaultColor: "transparent"
|
|
||||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
|
||||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
|
||||||
textColor: "#EB5757"
|
|
||||||
|
|
||||||
text: qsTr("Remove WG")
|
|
||||||
|
|
||||||
clickedFunc: function() {
|
|
||||||
var headerText = qsTr("Remove WG from server?")
|
|
||||||
var descriptionText = qsTr("All users with whom you shared a connection will no longer be able to connect to it.")
|
|
||||||
var yesButtonText = qsTr("Continue")
|
|
||||||
var noButtonText = qsTr("Cancel")
|
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
|
||||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
|
||||||
InstallController.removeCurrentlyProcessedContainer()
|
|
||||||
}
|
|
||||||
var noButtonFunction = function() {
|
|
||||||
}
|
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
@@ -163,9 +134,5 @@ PageType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QuestionDrawer {
|
|
||||||
id: questionDrawer
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,43 +98,12 @@ PageType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
Layout.topMargin: 24
|
|
||||||
Layout.leftMargin: -8
|
|
||||||
implicitHeight: 32
|
|
||||||
|
|
||||||
visible: ContainersModel.getCurrentlyProcessedContainerIndex() === ContainerEnum.Xray
|
|
||||||
|
|
||||||
defaultColor: "transparent"
|
|
||||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
|
||||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
|
||||||
textColor: "#EB5757"
|
|
||||||
|
|
||||||
text: qsTr("Remove XRay")
|
|
||||||
|
|
||||||
clickedFunc: function() {
|
|
||||||
var headerText = qsTr("Remove XRay from server?")
|
|
||||||
var descriptionText = qsTr("All users with whom you shared a connection will no longer be able to connect to it.")
|
|
||||||
var yesButtonText = qsTr("Continue")
|
|
||||||
var noButtonText = qsTr("Cancel")
|
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
|
||||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
|
||||||
InstallController.removeCurrentlyProcessedContainer()
|
|
||||||
}
|
|
||||||
var noButtonFunction = function() {
|
|
||||||
}
|
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
text: qsTr("Save and Restart Amnezia")
|
text: qsTr("Save")
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
@@ -146,10 +115,6 @@ PageType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QuestionDrawer {
|
|
||||||
id: questionDrawer
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,17 +59,23 @@ PageType {
|
|||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName()
|
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getCurrentlyProcessedContainerName())
|
var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getProcessedContainerName())
|
||||||
var yesButtonText = qsTr("Continue")
|
var yesButtonText = qsTr("Continue")
|
||||||
var noButtonText = qsTr("Cancel")
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
|
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
|
||||||
|
&& SettingsController.isAmneziaDnsEnabled()) {
|
||||||
|
PageController.showNotificationMessage(qsTr("Cannot remove Amnezia DNS from running server"))
|
||||||
|
} else
|
||||||
|
{
|
||||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||||
InstallController.removeCurrentlyProcessedContainer()
|
InstallController.removeProcessedContainer()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ PageType {
|
|||||||
|
|
||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||||
InstallController.removeCurrentlyProcessedContainer()
|
InstallController.removeProcessedContainer()
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ PageType {
|
|||||||
|
|
||||||
text: qsTr("Website address")
|
text: qsTr("Website address")
|
||||||
descriptionText: {
|
descriptionText: {
|
||||||
var containerIndex = ContainersModel.getCurrentlyProcessedContainerIndex()
|
var containerIndex = ContainersModel.getProcessedContainerIndex()
|
||||||
var config = ContainersModel.getContainerConfig(containerIndex)
|
var config = ContainersModel.getContainerConfig(containerIndex)
|
||||||
return config[ContainerProps.containerTypeToString(containerIndex)]["site"]
|
return config[ContainerProps.containerTypeToString(containerIndex)]["site"]
|
||||||
}
|
}
|
||||||
@@ -132,7 +132,7 @@ PageType {
|
|||||||
|
|
||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||||
InstallController.removeCurrentlyProcessedContainer()
|
InstallController.removeProcessedContainer()
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,17 @@ import "../Components"
|
|||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property bool pageEnabled
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (ConnectionController.isConnected) {
|
||||||
|
PageController.showNotificationMessage(qsTr("Cannot change split tunneling settings during active connection"))
|
||||||
|
root.pageEnabled = false
|
||||||
|
} else {
|
||||||
|
root.pageEnabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: routeMode
|
id: routeMode
|
||||||
property int allApps: 0
|
property int allApps: 0
|
||||||
@@ -70,6 +81,8 @@ PageType {
|
|||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("App split tunneling")
|
headerText: qsTr("App split tunneling")
|
||||||
|
|
||||||
|
enabled: root.pageEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitcherType {
|
SwitcherType {
|
||||||
@@ -78,6 +91,8 @@ PageType {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
enabled: root.pageEnabled
|
||||||
|
|
||||||
checked: AppSplitTunnelingModel.isTunnelingEnabled
|
checked: AppSplitTunnelingModel.isTunnelingEnabled
|
||||||
onToggled: {
|
onToggled: {
|
||||||
AppSplitTunnelingModel.toggleSplitTunneling(checked)
|
AppSplitTunnelingModel.toggleSplitTunneling(checked)
|
||||||
@@ -99,7 +114,7 @@ PageType {
|
|||||||
|
|
||||||
headerText: qsTr("Mode")
|
headerText: qsTr("Mode")
|
||||||
|
|
||||||
enabled: Qt.platform.os === "android"
|
enabled: Qt.platform.os === "android" && root.pageEnabled
|
||||||
|
|
||||||
listView: ListViewWithRadioButtonType {
|
listView: ListViewWithRadioButtonType {
|
||||||
rootWidth: root.width
|
rootWidth: root.width
|
||||||
@@ -139,6 +154,8 @@ PageType {
|
|||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
contentHeight: col.implicitHeight + addAppButton.implicitHeight + addAppButton.anchors.bottomMargin + addAppButton.anchors.topMargin
|
contentHeight: col.implicitHeight + addAppButton.implicitHeight + addAppButton.anchors.bottomMargin + addAppButton.anchors.topMargin
|
||||||
|
|
||||||
|
enabled: root.pageEnabled
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: col
|
id: col
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
@@ -213,6 +230,8 @@ PageType {
|
|||||||
RowLayout {
|
RowLayout {
|
||||||
id: addAppButton
|
id: addAppButton
|
||||||
|
|
||||||
|
enabled: root.pageEnabled
|
||||||
|
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|||||||
@@ -169,9 +169,14 @@ PageType {
|
|||||||
var noButtonText = qsTr("Cancel")
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
|
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||||
|
PageController.showNotificationMessage(qsTr("Cannot reset settings during active connection"))
|
||||||
|
} else
|
||||||
|
{
|
||||||
SettingsController.clearSettings()
|
SettingsController.clearSettings()
|
||||||
PageController.replaceStartPage()
|
PageController.replaceStartPage()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,10 +135,15 @@ PageType {
|
|||||||
var noButtonText = qsTr("Cancel")
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
|
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||||
|
PageController.showNotificationMessage(qsTr("Cannot restore backup settings during active connection"))
|
||||||
|
} else
|
||||||
|
{
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
SettingsController.restoreAppConfig(filePath)
|
SettingsController.restoreAppConfig(filePath)
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ PageType {
|
|||||||
PageController.showNotificationMessage(finishedMessage)
|
PageController.showNotificationMessage(finishedMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRemoveCurrentlyProcessedContainerFinished(finishedMessage) {
|
function onRemoveProcessedContainerFinished(finishedMessage) {
|
||||||
PageController.closePage() // close deInstalling page
|
PageController.closePage() // close deInstalling page
|
||||||
PageController.closePage() // close page with remove button
|
PageController.closePage() // close page with remove button
|
||||||
PageController.showNotificationMessage(finishedMessage)
|
PageController.showNotificationMessage(finishedMessage)
|
||||||
@@ -84,35 +84,6 @@ PageType {
|
|||||||
|
|
||||||
property bool isServerWithWriteAccess: ServersModel.isProcessedServerHasWriteAccess()
|
property bool isServerWithWriteAccess: ServersModel.isProcessedServerHasWriteAccess()
|
||||||
|
|
||||||
LabelWithButtonType {
|
|
||||||
visible: content.isServerWithWriteAccess
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
text: qsTr("Clear Amnezia cache")
|
|
||||||
descriptionText: qsTr("May be needed when changing other settings")
|
|
||||||
|
|
||||||
clickedFunction: function() {
|
|
||||||
var headerText = qsTr("Clear cached profiles?")
|
|
||||||
var descriptionText = qsTr("")
|
|
||||||
var yesButtonText = qsTr("Continue")
|
|
||||||
var noButtonText = qsTr("Cancel")
|
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
|
||||||
PageController.showBusyIndicator(true)
|
|
||||||
SettingsController.clearCachedProfiles()
|
|
||||||
PageController.showBusyIndicator(false)
|
|
||||||
}
|
|
||||||
var noButtonFunction = function() {
|
|
||||||
}
|
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DividerType {
|
|
||||||
visible: content.isServerWithWriteAccess
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
visible: content.isServerWithWriteAccess
|
visible: content.isServerWithWriteAccess
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -145,13 +116,14 @@ PageType {
|
|||||||
var noButtonText = qsTr("Cancel")
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
PageController.showBusyIndicator(true)
|
|
||||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||||
ConnectionController.closeConnection()
|
PageController.showNotificationMessage(qsTr("Cannot reboot server during active connection"))
|
||||||
}
|
} else {
|
||||||
|
PageController.showBusyIndicator(true)
|
||||||
InstallController.rebootProcessedServer()
|
InstallController.rebootProcessedServer()
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,13 +148,14 @@ PageType {
|
|||||||
var noButtonText = qsTr("Cancel")
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
PageController.showBusyIndicator(true)
|
|
||||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||||
ConnectionController.closeConnection()
|
PageController.showNotificationMessage(qsTr("Cannot remove server during active connection"))
|
||||||
}
|
} else {
|
||||||
|
PageController.showBusyIndicator(true)
|
||||||
InstallController.removeProcessedServer()
|
InstallController.removeProcessedServer()
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,12 +179,13 @@ PageType {
|
|||||||
var noButtonText = qsTr("Cancel")
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
|
||||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||||
ConnectionController.closeConnection()
|
PageController.showNotificationMessage(qsTr("Cannot clear server from Amnezia software during active connection"))
|
||||||
}
|
} else {
|
||||||
|
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||||
InstallController.removeAllContainers()
|
InstallController.removeAllContainers()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,10 +211,14 @@ PageType {
|
|||||||
var noButtonText = qsTr("Cancel")
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
|
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||||
|
PageController.showNotificationMessage(qsTr("Cannot reset API config during active connection"))
|
||||||
|
} else {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
ApiController.clearApiConfig()
|
InstallController.removeApiConfig()
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,32 +34,17 @@ PageType {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
|
Layout.bottomMargin: 32
|
||||||
|
|
||||||
headerText: ContainersModel.getCurrentlyProcessedContainerName() + qsTr(" settings")
|
headerText: ContainersModel.getProcessedContainerName() + qsTr(" settings")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
FlickableType {
|
|
||||||
id: fl
|
|
||||||
anchors.top: header.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
contentHeight: content.height
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: content
|
|
||||||
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.topMargin: 32
|
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: protocols
|
id: protocols
|
||||||
width: parent.width
|
Layout.fillWidth: true
|
||||||
height: protocols.contentItem.height
|
height: protocols.contentItem.height
|
||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: true
|
||||||
model: ProtocolsModel
|
model: ProtocolsModel
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
@@ -84,8 +69,9 @@ PageType {
|
|||||||
case ProtocolEnum.OpenVpn: OpenVpnConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
case ProtocolEnum.OpenVpn: OpenVpnConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||||
case ProtocolEnum.ShadowSocks: ShadowSocksConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
case ProtocolEnum.ShadowSocks: ShadowSocksConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||||
case ProtocolEnum.Cloak: CloakConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
case ProtocolEnum.Cloak: CloakConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||||
case ProtocolEnum.Xray: XrayConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
|
||||||
case ProtocolEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
case ProtocolEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||||
|
case ProtocolEnum.Awg: AwgConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||||
|
case ProtocolEnum.Xray: XrayConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||||
case ProtocolEnum.Ipsec: Ikev2ConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
case ProtocolEnum.Ipsec: Ikev2ConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||||
}
|
}
|
||||||
PageController.goToPage(protocolPage);
|
PageController.goToPage(protocolPage);
|
||||||
@@ -104,24 +90,71 @@ PageType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
id: removeButton
|
id: clearCacheButton
|
||||||
|
|
||||||
width: parent.width
|
Layout.fillWidth: true
|
||||||
|
|
||||||
visible: ServersModel.isProcessedServerHasWriteAccess()
|
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||||
|
|
||||||
text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName()
|
text: qsTr("Clear %1 profile").arg(ContainersModel.getProcessedContainerName())
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
var headerText = qsTr("Clear %1 profile?").arg(ContainersModel.getProcessedContainerName())
|
||||||
|
var descriptionText = qsTr("")
|
||||||
|
var yesButtonText = qsTr("Continue")
|
||||||
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
|
var yesButtonFunction = function() {
|
||||||
|
PageController.showBusyIndicator(true)
|
||||||
|
InstallController.clearCachedProfile()
|
||||||
|
PageController.showBusyIndicator(false)
|
||||||
|
}
|
||||||
|
var noButtonFunction = function() {
|
||||||
|
}
|
||||||
|
|
||||||
|
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: clearCacheButton
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DividerType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
id: removeButton
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||||
|
|
||||||
|
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getCurrentlyProcessedContainerName())
|
var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getProcessedContainerName())
|
||||||
var descriptionText = qsTr("All users with whom you shared a connection will no longer be able to connect to it.")
|
var descriptionText = qsTr("All users with whom you shared a connection will no longer be able to connect to it.")
|
||||||
var yesButtonText = qsTr("Continue")
|
var yesButtonText = qsTr("Continue")
|
||||||
var noButtonText = qsTr("Cancel")
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
|
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
|
||||||
|
&& ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
|
||||||
|
PageController.showNotificationMessage(qsTr("Cannot remove active container"))
|
||||||
|
} else
|
||||||
|
{
|
||||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||||
InstallController.removeCurrentlyProcessedContainer()
|
InstallController.removeProcessedContainer()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
}
|
}
|
||||||
@@ -136,11 +169,12 @@ PageType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {
|
||||||
}
|
Layout.fillWidth: true
|
||||||
}
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
QuestionDrawer {
|
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||||
id: questionDrawer
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,7 @@ PageType {
|
|||||||
|
|
||||||
defaultActiveFocusItem: searchField.textField
|
defaultActiveFocusItem: searchField.textField
|
||||||
|
|
||||||
property bool pageEnabled: {
|
property bool pageEnabled
|
||||||
return !ConnectionController.isConnected && !isServerFromApi
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (ConnectionController.isConnected) {
|
if (ConnectionController.isConnected) {
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ PageType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
InstallController.setShouldCreateServer(true)
|
InstallController.setShouldCreateServer(true)
|
||||||
InstallController.setCurrentlyInstalledServerCredentials(hostname.textField.text, username.textField.text, secretData.textField.text)
|
InstallController.setProcessedServerCredentials(hostname.textField.text, username.textField.text, secretData.textField.text)
|
||||||
|
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
var isConnectionOpened = InstallController.checkSshConnection()
|
var isConnectionOpened = InstallController.checkSshConnection()
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ PageType {
|
|||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
if (root.isEasySetup) {
|
if (root.isEasySetup) {
|
||||||
ContainersModel.setCurrentlyProcessedContainerIndex(containers.dockerContainer)
|
ContainersModel.setProcessedContainerIndex(containers.dockerContainer)
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling)
|
PageController.goToPage(PageEnum.PageSetupWizardInstalling)
|
||||||
InstallController.install(containers.dockerContainer,
|
InstallController.install(containers.dockerContainer,
|
||||||
containers.containerDefaultPort,
|
containers.containerDefaultPort,
|
||||||
|
|||||||
@@ -25,8 +25,9 @@ PageType {
|
|||||||
target: InstallController
|
target: InstallController
|
||||||
|
|
||||||
function onInstallContainerFinished(finishedMessage, isServiceInstall) {
|
function onInstallContainerFinished(finishedMessage, isServiceInstall) {
|
||||||
if (!ConnectionController.isConnected && !isServiceInstall) {
|
var containerIndex = ContainersModel.getProcessedContainerIndex()
|
||||||
ServersModel.setDefaultContainer(ServersModel.processedIndex, ContainersModel.getCurrentlyProcessedContainerIndex())
|
if (!ConnectionController.isConnected && !ContainersModel.isServiceContainer(containerIndex)) {
|
||||||
|
ServersModel.setDefaultContainer(ServersModel.processedIndex, containerIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
PageController.closePage() // close installing page
|
PageController.closePage() // close installing page
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ PageType {
|
|||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(index))
|
ContainersModel.setProcessedContainerIndex(proxyContainersModel.mapToSource(index))
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
|
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import "./"
|
|||||||
import "../Controls2"
|
import "../Controls2"
|
||||||
import "../Controls2/TextTypes"
|
import "../Controls2/TextTypes"
|
||||||
import "../Components"
|
import "../Components"
|
||||||
|
import "../Config"
|
||||||
|
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
@@ -32,7 +33,7 @@ PageType {
|
|||||||
onRevokeConfig: function(index) {
|
onRevokeConfig: function(index) {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
ExportController.revokeConfig(index,
|
ExportController.revokeConfig(index,
|
||||||
ContainersModel.getCurrentlyProcessedContainerIndex(),
|
ContainersModel.getProcessedContainerIndex(),
|
||||||
ServersModel.getProcessedServerCredentials())
|
ServersModel.getProcessedServerCredentials())
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
PageController.showNotificationMessage(qsTr("Config revoked"))
|
PageController.showNotificationMessage(qsTr("Config revoked"))
|
||||||
@@ -258,7 +259,7 @@ PageType {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
accessTypeSelector.currentIndex = 1
|
accessTypeSelector.currentIndex = 1
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
|
ExportController.updateClientManagementModel(ContainersModel.getProcessedContainerIndex(),
|
||||||
ServersModel.getProcessedServerCredentials())
|
ServersModel.getProcessedServerCredentials())
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
@@ -418,13 +419,13 @@ PageType {
|
|||||||
|
|
||||||
protocolSelector.text = selectedText
|
protocolSelector.text = selectedText
|
||||||
|
|
||||||
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(currentIndex))
|
ContainersModel.setProcessedContainerIndex(proxyContainersModel.mapToSource(currentIndex))
|
||||||
|
|
||||||
fillConnectionTypeModel()
|
fillConnectionTypeModel()
|
||||||
|
|
||||||
if (accessTypeSelector.currentIndex === 1) {
|
if (accessTypeSelector.currentIndex === 1) {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
|
ExportController.updateClientManagementModel(ContainersModel.getProcessedContainerIndex(),
|
||||||
ServersModel.getProcessedServerCredentials())
|
ServersModel.getProcessedServerCredentials())
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
@@ -696,7 +697,7 @@ PageType {
|
|||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
ExportController.renameClient(index,
|
ExportController.renameClient(index,
|
||||||
clientNameEditor.textFieldText,
|
clientNameEditor.textFieldText,
|
||||||
ContainersModel.getCurrentlyProcessedContainerIndex(),
|
ContainersModel.getProcessedContainerIndex(),
|
||||||
ServersModel.getProcessedServerCredentials())
|
ServersModel.getProcessedServerCredentials())
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
clientNameEditDrawer.close()
|
clientNameEditDrawer.close()
|
||||||
|
|||||||
@@ -108,6 +108,10 @@ PageType {
|
|||||||
PageController.showNotificationMessage(message)
|
PageController.showNotificationMessage(message)
|
||||||
PageController.closePage()
|
PageController.closePage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onCachedProfileCleared(message) {
|
||||||
|
PageController.showNotificationMessage(message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|||||||
@@ -67,7 +67,9 @@ void SystemTrayNotificationHandler::onTranslationsUpdated()
|
|||||||
void SystemTrayNotificationHandler::setTrayIcon(const QString &iconPath)
|
void SystemTrayNotificationHandler::setTrayIcon(const QString &iconPath)
|
||||||
{
|
{
|
||||||
QIcon trayIconMask(QPixmap(iconPath).scaled(128,128));
|
QIcon trayIconMask(QPixmap(iconPath).scaled(128,128));
|
||||||
|
#ifndef Q_OS_MAC
|
||||||
trayIconMask.setIsMask(true);
|
trayIconMask.setIsMask(true);
|
||||||
|
#endif
|
||||||
m_systemTrayIcon.setIcon(trayIconMask);
|
m_systemTrayIcon.setIcon(trayIconMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-119
@@ -9,7 +9,6 @@
|
|||||||
#include <configurators/cloak_configurator.h>
|
#include <configurators/cloak_configurator.h>
|
||||||
#include <configurators/openvpn_configurator.h>
|
#include <configurators/openvpn_configurator.h>
|
||||||
#include <configurators/shadowsocks_configurator.h>
|
#include <configurators/shadowsocks_configurator.h>
|
||||||
#include <configurators/vpn_configurator.h>
|
|
||||||
#include <configurators/wireguard_configurator.h>
|
#include <configurators/wireguard_configurator.h>
|
||||||
#include "core/controllers/serverController.h"
|
#include "core/controllers/serverController.h"
|
||||||
|
|
||||||
@@ -30,9 +29,8 @@
|
|||||||
#include "core/networkUtilities.h"
|
#include "core/networkUtilities.h"
|
||||||
#include "vpnconnection.h"
|
#include "vpnconnection.h"
|
||||||
|
|
||||||
VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, std::shared_ptr<VpnConfigurator> configurator,
|
VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
QObject *parent)
|
: QObject(parent), m_settings(settings), m_checkTimer(new QTimer(this))
|
||||||
: QObject(parent), m_settings(settings), m_configurator(configurator), m_checkTimer(new QTimer(this))
|
|
||||||
{
|
{
|
||||||
m_checkTimer.setInterval(1000);
|
m_checkTimer.setInterval(1000);
|
||||||
#ifdef Q_OS_IOS
|
#ifdef Q_OS_IOS
|
||||||
@@ -212,109 +210,8 @@ ErrorCode VpnConnection::lastError() const
|
|||||||
return m_vpnProtocol.data()->lastError();
|
return m_vpnProtocol.data()->lastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<Proto, QString> VpnConnection::getLastVpnConfig(const QJsonObject &containerConfig)
|
|
||||||
{
|
|
||||||
QMap<Proto, QString> configs;
|
|
||||||
for (Proto proto : ProtocolProps::allProtocols()) {
|
|
||||||
|
|
||||||
QString cfg = containerConfig.value(ProtocolProps::protoToString(proto))
|
|
||||||
.toObject()
|
|
||||||
.value(config_key::last_config)
|
|
||||||
.toString();
|
|
||||||
|
|
||||||
if (!cfg.isEmpty())
|
|
||||||
configs.insert(proto, cfg);
|
|
||||||
}
|
|
||||||
return configs;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString VpnConnection::createVpnConfigurationForProto(int serverIndex, const ServerCredentials &credentials,
|
|
||||||
DockerContainer container, const QJsonObject &containerConfig,
|
|
||||||
Proto proto, ErrorCode *errorCode)
|
|
||||||
{
|
|
||||||
QMap<Proto, QString> lastVpnConfig = getLastVpnConfig(containerConfig);
|
|
||||||
|
|
||||||
QString configData;
|
|
||||||
if (lastVpnConfig.contains(proto)) {
|
|
||||||
configData = lastVpnConfig.value(proto);
|
|
||||||
configData = m_configurator->processConfigWithLocalSettings(serverIndex, container, proto, configData);
|
|
||||||
} else {
|
|
||||||
QString clientId;
|
|
||||||
configData = m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, proto, clientId, errorCode);
|
|
||||||
|
|
||||||
if (errorCode && *errorCode) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
QString configDataBeforeLocalProcessing = configData;
|
|
||||||
|
|
||||||
configData = m_configurator->processConfigWithLocalSettings(serverIndex, container, proto, configData);
|
|
||||||
|
|
||||||
if (serverIndex >= 0) {
|
|
||||||
qDebug() << "VpnConnection::createVpnConfiguration: saving config for server #" << serverIndex << container;
|
|
||||||
QJsonObject protoObject = m_settings->protocolConfig(serverIndex, container, proto);
|
|
||||||
protoObject.insert(config_key::last_config, configDataBeforeLocalProcessing);
|
|
||||||
m_settings->setProtocolConfig(serverIndex, container, proto, protoObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((container != DockerContainer::Cloak && container != DockerContainer::ShadowSocks) ||
|
|
||||||
((container == DockerContainer::Cloak || container == DockerContainer::ShadowSocks) && proto == Proto::OpenVpn)) {
|
|
||||||
QEventLoop wait;
|
|
||||||
emit m_configurator->newVpnConfigCreated(clientId, QString("Admin [%1]").arg(QSysInfo::prettyProductName()), container, credentials);
|
|
||||||
QObject::connect(m_configurator.get(), &VpnConfigurator::clientModelUpdated, &wait, &QEventLoop::quit);
|
|
||||||
wait.exec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return configData;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject VpnConnection::createVpnConfiguration(int serverIndex, const ServerCredentials &credentials,
|
|
||||||
DockerContainer container, const QJsonObject &containerConfig,
|
|
||||||
ErrorCode *errorCode)
|
|
||||||
{
|
|
||||||
QJsonObject vpnConfiguration;
|
|
||||||
vpnConfiguration[config_key::serverIndex] = serverIndex;
|
|
||||||
|
|
||||||
for (ProtocolEnumNS::Proto proto : ContainerProps::protocolsForContainer(container)) {
|
|
||||||
auto s = m_settings->server(serverIndex);
|
|
||||||
if (m_settings->server(serverIndex).value(config_key::configVersion).toInt() &&
|
|
||||||
container == DockerContainer::Cloak && proto == ProtocolEnumNS::Proto::ShadowSocks) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject vpnConfigData =
|
|
||||||
QJsonDocument::fromJson(createVpnConfigurationForProto(serverIndex, credentials, container,
|
|
||||||
containerConfig, proto, errorCode).toUtf8()).object();
|
|
||||||
|
|
||||||
if (errorCode && *errorCode) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
vpnConfiguration.insert(ProtocolProps::key_proto_config_data(proto), vpnConfigData);
|
|
||||||
}
|
|
||||||
|
|
||||||
Proto proto = ContainerProps::defaultProtocol(container);
|
|
||||||
vpnConfiguration[config_key::vpnproto] = ProtocolProps::protoToString(proto);
|
|
||||||
|
|
||||||
auto dns = m_configurator->getDnsForConfig(serverIndex);
|
|
||||||
|
|
||||||
vpnConfiguration[config_key::dns1] = dns.first;
|
|
||||||
vpnConfiguration[config_key::dns2] = dns.second;
|
|
||||||
|
|
||||||
const QJsonObject &server = m_settings->server(serverIndex);
|
|
||||||
vpnConfiguration[config_key::hostName] = server.value(config_key::hostName).toString();
|
|
||||||
vpnConfiguration[config_key::description] = server.value(config_key::description).toString();
|
|
||||||
|
|
||||||
vpnConfiguration[config_key::configVersion] = server.value(config_key::configVersion).toInt();
|
|
||||||
// TODO: try to get hostName, port, description for 3rd party configs
|
|
||||||
// vpnConfiguration[config_key::port] = ...;
|
|
||||||
|
|
||||||
return vpnConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container,
|
void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig)
|
const QJsonObject &vpnConfiguration)
|
||||||
{
|
{
|
||||||
qDebug() << QString("ConnectToVpn, Server index is %1, container is %2, route mode is")
|
qDebug() << QString("ConnectToVpn, Server index is %1, container is %2, route mode is")
|
||||||
.arg(serverIndex)
|
.arg(serverIndex)
|
||||||
@@ -346,15 +243,7 @@ void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &crede
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
m_vpnConfiguration = vpnConfiguration;
|
||||||
|
|
||||||
m_vpnConfiguration = createVpnConfiguration(serverIndex, credentials, container, containerConfig, &e);
|
|
||||||
|
|
||||||
if (e) {
|
|
||||||
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
appendSplitTunnelingConfig();
|
appendSplitTunnelingConfig();
|
||||||
|
|
||||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||||
@@ -378,8 +267,8 @@ void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &crede
|
|||||||
|
|
||||||
createProtocolConnections();
|
createProtocolConnections();
|
||||||
|
|
||||||
e = m_vpnProtocol.data()->start();
|
ErrorCode errorCode = m_vpnProtocol.data()->start();
|
||||||
if (e)
|
if (errorCode != ErrorCode::NoError)
|
||||||
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,7 +301,11 @@ void VpnConnection::appendSplitTunnelingConfig()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto routeMode = m_settings->routeMode();
|
Settings::RouteMode routeMode = Settings::RouteMode::VpnAllSites;
|
||||||
|
if (m_settings->getSitesSplitTunnelingEnabled()) {
|
||||||
|
routeMode = m_settings->routeMode();
|
||||||
|
}
|
||||||
|
|
||||||
auto sites = m_settings->getVpnIps(routeMode);
|
auto sites = m_settings->getVpnIps(routeMode);
|
||||||
|
|
||||||
QJsonArray sitesJsonArray;
|
QJsonArray sitesJsonArray;
|
||||||
@@ -429,7 +322,11 @@ void VpnConnection::appendSplitTunnelingConfig()
|
|||||||
m_vpnConfiguration.insert(config_key::splitTunnelType, routeMode);
|
m_vpnConfiguration.insert(config_key::splitTunnelType, routeMode);
|
||||||
m_vpnConfiguration.insert(config_key::splitTunnelSites, sitesJsonArray);
|
m_vpnConfiguration.insert(config_key::splitTunnelSites, sitesJsonArray);
|
||||||
|
|
||||||
auto appsRouteMode = m_settings->getAppsRouteMode();
|
Settings::AppsRouteMode appsRouteMode = Settings::AppsRouteMode::VpnAllApps;
|
||||||
|
if (m_settings->getAppsSplitTunnelingEnabled()) {
|
||||||
|
appsRouteMode = m_settings->getAppsRouteMode();
|
||||||
|
}
|
||||||
|
|
||||||
auto apps = m_settings->getVpnApps(appsRouteMode);
|
auto apps = m_settings->getVpnApps(appsRouteMode);
|
||||||
|
|
||||||
QJsonArray appsJsonArray;
|
QJsonArray appsJsonArray;
|
||||||
|
|||||||
+2
-19
@@ -11,7 +11,6 @@
|
|||||||
#include "core/defs.h"
|
#include "core/defs.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef AMNEZIA_DESKTOP
|
#ifdef AMNEZIA_DESKTOP
|
||||||
#include "core/ipcclient.h"
|
#include "core/ipcclient.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -20,9 +19,6 @@
|
|||||||
#include "protocols/android_vpnprotocol.h"
|
#include "protocols/android_vpnprotocol.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class VpnConfigurator;
|
|
||||||
class ServerController;
|
|
||||||
|
|
||||||
using namespace amnezia;
|
using namespace amnezia;
|
||||||
|
|
||||||
class VpnConnection : public QObject
|
class VpnConnection : public QObject
|
||||||
@@ -30,24 +26,13 @@ class VpnConnection : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit VpnConnection(std::shared_ptr<Settings> settings,
|
explicit VpnConnection(std::shared_ptr<Settings> settings, QObject* parent = nullptr);
|
||||||
std::shared_ptr<VpnConfigurator> configurator, QObject* parent = nullptr);
|
|
||||||
~VpnConnection() override;
|
~VpnConnection() override;
|
||||||
|
|
||||||
static QString bytesPerSecToText(quint64 bytes);
|
static QString bytesPerSecToText(quint64 bytes);
|
||||||
|
|
||||||
ErrorCode lastError() const;
|
ErrorCode lastError() const;
|
||||||
|
|
||||||
static QMap<Proto, QString> getLastVpnConfig(const QJsonObject &containerConfig);
|
|
||||||
QString createVpnConfigurationForProto(int serverIndex,
|
|
||||||
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, Proto proto,
|
|
||||||
ErrorCode *errorCode = nullptr);
|
|
||||||
|
|
||||||
QJsonObject createVpnConfiguration(int serverIndex,
|
|
||||||
const ServerCredentials &credentials, DockerContainer container,
|
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
|
||||||
|
|
||||||
|
|
||||||
bool isConnected() const;
|
bool isConnected() const;
|
||||||
bool isDisconnected() const;
|
bool isDisconnected() const;
|
||||||
|
|
||||||
@@ -63,7 +48,7 @@ public:
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void connectToVpn(int serverIndex,
|
void connectToVpn(int serverIndex,
|
||||||
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig);
|
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &vpnConfiguration);
|
||||||
|
|
||||||
void disconnectFromVpn();
|
void disconnectFromVpn();
|
||||||
|
|
||||||
@@ -88,8 +73,6 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
std::shared_ptr<VpnConfigurator> m_configurator;
|
|
||||||
|
|
||||||
QJsonObject m_vpnConfiguration;
|
QJsonObject m_vpnConfiguration;
|
||||||
QJsonObject m_routeMode;
|
QJsonObject m_routeMode;
|
||||||
QString m_remoteAddress;
|
QString m_remoteAddress;
|
||||||
|
|||||||
Reference in New Issue
Block a user