From fdd600794e1fdad9b6c119b7beddea719b4cdf72 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Mon, 8 Apr 2024 16:13:26 +0500 Subject: [PATCH] fixed adding/removing routes when split tunneling is disabled --- client/amnezia_application.cpp | 71 ++++++++----------- client/configurators/openvpn_configurator.cpp | 8 +-- client/ui/controllers/settingsController.cpp | 9 ++- client/ui/controllers/settingsController.h | 3 + client/ui/models/appSplitTunnelingModel.cpp | 4 ++ client/ui/models/sites_model.cpp | 4 ++ client/vpnconnection.cpp | 66 +++++++++-------- 7 files changed, 86 insertions(+), 79 deletions(-) diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp index f57861ed..12be2dfe 100644 --- a/client/amnezia_application.cpp +++ b/client/amnezia_application.cpp @@ -13,13 +13,13 @@ #include #include "logger.h" -#include "version.h" #include "ui/models/installedAppsModel.h" +#include "version.h" #include "platforms/ios/QRCodeReaderBase.h" #if defined(Q_OS_ANDROID) - #include "platforms/android/android_controller.h" #include "core/installedAppsImageProvider.h" + #include "platforms/android/android_controller.h" #endif #include "protocols/qml_register_protocols.h" @@ -32,8 +32,8 @@ #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) AmneziaApplication::AmneziaApplication(int &argc, char *argv[]) : AMNEZIA_BASE_CLASS(argc, argv) #else -AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecondary, SingleApplication::Options options, - int timeout, const QString &userData) +AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecondary, SingleApplication::Options options, int timeout, + const QString &userData) : SingleApplication(argc, argv, allowSecondary, options, timeout, userData) #endif { @@ -46,12 +46,12 @@ AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecond s.setValue("permFixed", true); } - QString configLoc1 = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first() + "/" - + ORGANIZATION_NAME + "/" + APPLICATION_NAME + ".conf"; + QString configLoc1 = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first() + "/" + ORGANIZATION_NAME + "/" + + APPLICATION_NAME + ".conf"; QFile::setPermissions(configLoc1, QFileDevice::ReadOwner | QFileDevice::WriteOwner); - QString configLoc2 = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first() + "/" - + ORGANIZATION_NAME + "/" + APPLICATION_NAME + "/" + APPLICATION_NAME + ".conf"; + QString configLoc2 = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first() + "/" + ORGANIZATION_NAME + "/" + + APPLICATION_NAME + "/" + APPLICATION_NAME + ".conf"; QFile::setPermissions(configLoc2, QFileDevice::ReadOwner | QFileDevice::WriteOwner); #endif @@ -100,20 +100,17 @@ void AmneziaApplication::init() connect(m_settings.get(), &Settings::saveLogsChanged, AndroidController::instance(), &AndroidController::setSaveLogs); AndroidController::instance()->setScreenshotsEnabled(m_settings->isScreenshotsEnabled()); - connect(m_settings.get(), &Settings::screenshotsEnabledChanged, AndroidController::instance(), - &AndroidController::setScreenshotsEnabled); + connect(m_settings.get(), &Settings::screenshotsEnabledChanged, AndroidController::instance(), &AndroidController::setScreenshotsEnabled); - connect(m_settings.get(), &Settings::serverRemoved, AndroidController::instance(), - &AndroidController::resetLastServer); + connect(m_settings.get(), &Settings::serverRemoved, AndroidController::instance(), &AndroidController::resetLastServer); connect(m_settings.get(), &Settings::settingsCleared, []() { AndroidController::instance()->resetLastServer(-1); }); - connect(AndroidController::instance(), &AndroidController::initConnectionState, this, - [this](Vpn::ConnectionState state) { - m_connectionController->onConnectionStateChanged(state); - if (m_vpnConnection) - m_vpnConnection->restoreConnection(); - }); + connect(AndroidController::instance(), &AndroidController::initConnectionState, this, [this](Vpn::ConnectionState state) { + m_connectionController->onConnectionStateChanged(state); + if (m_vpnConnection) + m_vpnConnection->restoreConnection(); + }); if (!AndroidController::instance()->initialize()) { qFatal("Android controller initialization failed"); } @@ -127,8 +124,6 @@ void AmneziaApplication::init() m_engine->addImageProvider(QLatin1String("installedAppImage"), new InstalledAppsImageProvider); #endif - - #ifdef Q_OS_IOS IosController::Instance()->initialize(); connect(IosController::Instance(), &IosController::importConfigFromOutside, [this](QString data) { @@ -145,8 +140,7 @@ void AmneziaApplication::init() QTimer::singleShot(0, this, [this]() { AmneziaVPN::toggleScreenshots(m_settings->isScreenshotsEnabled()); }); - connect(m_settings.get(), &Settings::screenshotsEnabledChanged, - [](bool enabled) { AmneziaVPN::toggleScreenshots(enabled); }); + connect(m_settings.get(), &Settings::screenshotsEnabledChanged, [](bool enabled) { AmneziaVPN::toggleScreenshots(enabled); }); #endif m_notificationHandler.reset(NotificationHandler::create(nullptr)); @@ -154,14 +148,12 @@ void AmneziaApplication::init() connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, m_notificationHandler.get(), &NotificationHandler::setConnectionState); - connect(m_notificationHandler.get(), &NotificationHandler::raiseRequested, m_pageController.get(), - &PageController::raiseMainWindow); + connect(m_notificationHandler.get(), &NotificationHandler::raiseRequested, m_pageController.get(), &PageController::raiseMainWindow); connect(m_notificationHandler.get(), &NotificationHandler::connectRequested, m_connectionController.get(), &ConnectionController::openConnection); connect(m_notificationHandler.get(), &NotificationHandler::disconnectRequested, m_connectionController.get(), &ConnectionController::closeConnection); - connect(this, &AmneziaApplication::translationsUpdated, m_notificationHandler.get(), - &NotificationHandler::onTranslationsUpdated); + connect(this, &AmneziaApplication::translationsUpdated, m_notificationHandler.get(), &NotificationHandler::onTranslationsUpdated); m_engine->load(url); m_systemController->setQmlRoot(m_engine->rootObjects().value(0)); @@ -312,8 +304,7 @@ void AmneziaApplication::initModels() m_serversModel.reset(new ServersModel(m_settings, this)); m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get()); - connect(m_serversModel.get(), &ServersModel::containersUpdated, m_containersModel.get(), - &ContainersModel::updateModel); + connect(m_serversModel.get(), &ServersModel::containersUpdated, m_containersModel.get(), &ContainersModel::updateModel); connect(m_serversModel.get(), &ServersModel::defaultServerContainersUpdated, m_defaultServerContainersModel.get(), &ContainersModel::updateModel); m_serversModel->resetModel(); @@ -366,26 +357,23 @@ void AmneziaApplication::initModels() void AmneziaApplication::initControllers() { - m_connectionController.reset(new ConnectionController(m_serversModel, m_containersModel, m_clientManagementModel, - m_vpnConnection, m_settings)); + m_connectionController.reset( + new ConnectionController(m_serversModel, m_containersModel, m_clientManagementModel, m_vpnConnection, m_settings)); 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::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(), - &ConnectionController::onTranslationsUpdated); + connect(this, &AmneziaApplication::translationsUpdated, m_connectionController.get(), &ConnectionController::onTranslationsUpdated); m_pageController.reset(new PageController(m_serversModel, m_settings)); m_engine->rootContext()->setContextProperty("PageController", m_pageController.get()); - m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, - m_clientManagementModel, m_settings)); + m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, m_clientManagementModel, m_settings)); m_engine->rootContext()->setContextProperty("InstallController", m_installController.get()); connect(m_installController.get(), &InstallController::passphraseRequestStarted, m_pageController.get(), &PageController::showPassphraseRequestDrawer); @@ -401,13 +389,12 @@ void AmneziaApplication::initControllers() m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get()); m_settingsController.reset( - new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_sitesModel, m_settings)); + new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_sitesModel, m_appSplitTunnelingModel, m_settings)); m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get()); if (m_settingsController->isAutoConnectEnabled() && m_serversModel->getDefaultServerIndex() >= 0) { QTimer::singleShot(1000, this, [this]() { m_connectionController->openConnection(); }); } - connect(m_settingsController.get(), &SettingsController::amneziaDnsToggled, m_serversModel.get(), - &ServersModel::toggleAmneziaDns); + connect(m_settingsController.get(), &SettingsController::amneziaDnsToggled, m_serversModel.get(), &ServersModel::toggleAmneziaDns); m_sitesController.reset(new SitesController(m_settings, m_vpnConnection, m_sitesModel)); m_engine->rootContext()->setContextProperty("SitesController", m_sitesController.get()); diff --git a/client/configurators/openvpn_configurator.cpp b/client/configurators/openvpn_configurator.cpp index 22628ce7..9631162b 100644 --- a/client/configurators/openvpn_configurator.cpp +++ b/client/configurators/openvpn_configurator.cpp @@ -122,17 +122,15 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPairrouteMode() == Settings::VpnAllSites) { + if (!m_settings->getSitesSplitTunnelingEnabled()) { config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n"); // Prevent ipv6 leak config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n"); config.append("block-ipv6\n"); - } - if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { + } else if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { // no redirect-gateway - } - if (m_settings->routeMode() == Settings::VpnAllExceptSites) { + } else if (m_settings->routeMode() == Settings::VpnAllExceptSites) { #ifndef Q_OS_ANDROID config.append("\nredirect-gateway ipv6 !ipv4 bypass-dhcp\n"); #endif diff --git a/client/ui/controllers/settingsController.cpp b/client/ui/controllers/settingsController.cpp index 4ac67504..c3640719 100644 --- a/client/ui/controllers/settingsController.cpp +++ b/client/ui/controllers/settingsController.cpp @@ -18,12 +18,14 @@ SettingsController::SettingsController(const QSharedPointer &serve const QSharedPointer &containersModel, const QSharedPointer &languageModel, const QSharedPointer &sitesModel, + const QSharedPointer &appSplitTunnelingModel, const std::shared_ptr &settings, QObject *parent) : QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_languageModel(languageModel), m_sitesModel(sitesModel), + m_appSplitTunnelingModel(appSplitTunnelingModel), m_settings(settings) { m_appVersion = QString("%1 (%2, %3)").arg(QString(APP_VERSION), __DATE__, GIT_COMMIT_HASH); @@ -144,7 +146,12 @@ void SettingsController::clearSettings() m_serversModel->resetModel(); m_languageModel->changeLanguage( static_cast(m_languageModel->getCurrentLanguageIndex())); - m_sitesModel->setRouteMode(Settings::RouteMode::VpnAllSites); + + m_sitesModel->setRouteMode(Settings::RouteMode::VpnOnlyForwardSites); + m_sitesModel->toggleSplitTunneling(false); + + m_appSplitTunnelingModel->setRouteMode(Settings::AppsRouteMode::VpnAllExceptApps); + m_appSplitTunnelingModel->toggleSplitTunneling(false); emit changeSettingsFinished(tr("All settings have been reset to default values")); diff --git a/client/ui/controllers/settingsController.h b/client/ui/controllers/settingsController.h index 2678c65d..b97ae3e0 100644 --- a/client/ui/controllers/settingsController.h +++ b/client/ui/controllers/settingsController.h @@ -7,6 +7,7 @@ #include "ui/models/languageModel.h" #include "ui/models/servers_model.h" #include "ui/models/sites_model.h" +#include "ui/models/appSplitTunnelingModel.h" class SettingsController : public QObject { @@ -16,6 +17,7 @@ public: const QSharedPointer &containersModel, const QSharedPointer &languageModel, const QSharedPointer &sitesModel, + const QSharedPointer &appSplitTunnelingModel, const std::shared_ptr &settings, QObject *parent = nullptr); Q_PROPERTY(QString primaryDns READ getPrimaryDns WRITE setPrimaryDns NOTIFY primaryDnsChanged) @@ -83,6 +85,7 @@ private: QSharedPointer m_containersModel; QSharedPointer m_languageModel; QSharedPointer m_sitesModel; + QSharedPointer m_appSplitTunnelingModel; std::shared_ptr m_settings; QString m_appVersion; diff --git a/client/ui/models/appSplitTunnelingModel.cpp b/client/ui/models/appSplitTunnelingModel.cpp index 84d01f99..55db08b0 100644 --- a/client/ui/models/appSplitTunnelingModel.cpp +++ b/client/ui/models/appSplitTunnelingModel.cpp @@ -7,6 +7,10 @@ AppSplitTunnelingModel::AppSplitTunnelingModel(std::shared_ptr setting { m_isSplitTunnelingEnabled = m_settings->getAppsSplitTunnelingEnabled(); m_currentRouteMode = m_settings->getAppsRouteMode(); + if (m_currentRouteMode == Settings::VpnAllApps) { // for old split tunneling configs + m_settings->setAppsRouteMode(static_cast(Settings::VpnAllExceptApps)); + m_currentRouteMode = Settings::VpnAllExceptApps; + } m_apps = m_settings->getVpnApps(m_currentRouteMode); } diff --git a/client/ui/models/sites_model.cpp b/client/ui/models/sites_model.cpp index e6d12835..cc3dd188 100644 --- a/client/ui/models/sites_model.cpp +++ b/client/ui/models/sites_model.cpp @@ -5,6 +5,10 @@ SitesModel::SitesModel(std::shared_ptr settings, QObject *parent) { m_isSplitTunnelingEnabled = m_settings->getSitesSplitTunnelingEnabled(); m_currentRouteMode = m_settings->routeMode(); + if (m_currentRouteMode == Settings::VpnAllSites) { // for old split tunneling configs + m_settings->setRouteMode(static_cast(Settings::VpnOnlyForwardSites)); + m_currentRouteMode = Settings::VpnOnlyForwardSites; + } fillSites(); } diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index 512dc229..c36348b3 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -65,32 +65,38 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state) IpcClient::Interface()->flushDns(); if (!m_vpnConfiguration.value(config_key::configVersion).toInt()) { - if (m_settings->routeMode() != Settings::VpnAllSites) { - IpcClient::Interface()->routeDeleteList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0"); - // qDebug() << "VpnConnection::onConnectionStateChanged :: adding custom routes, count:" << forwardIps.size(); - } QString dns1 = m_vpnConfiguration.value(config_key::dns1).toString(); QString dns2 = m_vpnConfiguration.value(config_key::dns2).toString(); + qDebug() << NetworkUtilities::ipAddressFromIpWithSubnet(dns1); + IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << dns1 << dns2); - if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { - QTimer::singleShot(1000, m_vpnProtocol.data(), - [this]() { addSitesRoutes(m_vpnProtocol->vpnGateway(), m_settings->routeMode()); }); - } else if (m_settings->routeMode() == Settings::VpnAllExceptSites) { - IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0/1"); - IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << "128.0.0.0/1"); + if (m_settings->getSitesSplitTunnelingEnabled()) { + if (m_settings->routeMode() != Settings::VpnAllSites) { + IpcClient::Interface()->routeDeleteList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0"); + // qDebug() << "VpnConnection::onConnectionStateChanged :: adding custom routes, count:" << forwardIps.size(); + } + if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { + QTimer::singleShot(1000, m_vpnProtocol.data(), + [this]() { addSitesRoutes(m_vpnProtocol->vpnGateway(), m_settings->routeMode()); }); + } else if (m_settings->routeMode() == Settings::VpnAllExceptSites) { + IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0/1"); + IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << "128.0.0.0/1"); - IpcClient::Interface()->routeAddList(m_vpnProtocol->routeGateway(), QStringList() << remoteAddress()); - addSitesRoutes(m_vpnProtocol->routeGateway(), m_settings->routeMode()); + IpcClient::Interface()->routeAddList(m_vpnProtocol->routeGateway(), QStringList() << remoteAddress()); + addSitesRoutes(m_vpnProtocol->routeGateway(), m_settings->routeMode()); + } } } } else if (state == Vpn::ConnectionState::Error) { IpcClient::Interface()->flushDns(); - if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { - IpcClient::Interface()->clearSavedRoutes(); + if (m_settings->getSitesSplitTunnelingEnabled()) { + if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { + IpcClient::Interface()->clearSavedRoutes(); + } } } else if (state == Vpn::ConnectionState::Connecting) { @@ -302,36 +308,34 @@ void VpnConnection::appendSplitTunnelingConfig() } Settings::RouteMode routeMode = Settings::RouteMode::VpnAllSites; + QJsonArray sitesJsonArray; if (m_settings->getSitesSplitTunnelingEnabled()) { routeMode = m_settings->routeMode(); - } - auto sites = m_settings->getVpnIps(routeMode); + auto sites = m_settings->getVpnIps(routeMode); + for (const auto &site : sites) { + sitesJsonArray.append(site); + } - QJsonArray sitesJsonArray; - for (const auto &site : sites) { - sitesJsonArray.append(site); - } - - // Allow traffic to Amezia DNS - if (routeMode == Settings::VpnOnlyForwardSites) { - sitesJsonArray.append(m_vpnConfiguration.value(config_key::dns1).toString()); - sitesJsonArray.append(m_vpnConfiguration.value(config_key::dns2).toString()); + // Allow traffic to Amezia DNS + if (routeMode == Settings::VpnOnlyForwardSites) { + sitesJsonArray.append(m_vpnConfiguration.value(config_key::dns1).toString()); + sitesJsonArray.append(m_vpnConfiguration.value(config_key::dns2).toString()); + } } m_vpnConfiguration.insert(config_key::splitTunnelType, routeMode); m_vpnConfiguration.insert(config_key::splitTunnelSites, sitesJsonArray); Settings::AppsRouteMode appsRouteMode = Settings::AppsRouteMode::VpnAllApps; + QJsonArray appsJsonArray; if (m_settings->getAppsSplitTunnelingEnabled()) { appsRouteMode = m_settings->getAppsRouteMode(); - } - auto apps = m_settings->getVpnApps(appsRouteMode); - - QJsonArray appsJsonArray; - for (const auto &app : apps) { - appsJsonArray.append(app.appPath.isEmpty() ? app.packageName : app.appPath); + auto apps = m_settings->getVpnApps(appsRouteMode); + for (const auto &app : apps) { + appsJsonArray.append(app.appPath.isEmpty() ? app.packageName : app.appPath); + } } m_vpnConfiguration.insert(config_key::appSplitTunnelType, appsRouteMode);