From f7b9d2bae7cf74a9ae51517591b81f1fc4f038c1 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Mon, 22 Jan 2024 16:51:11 +0300 Subject: [PATCH 1/5] added support for awg configs for api --- client/configurators/wireguard_configurator.h | 4 +- client/ui/controllers/apiController.cpp | 59 +++++++++++-------- client/ui/controllers/apiController.h | 14 +++-- 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/client/configurators/wireguard_configurator.h b/client/configurators/wireguard_configurator.h index c1b4aa3c..d2422981 100644 --- a/client/configurators/wireguard_configurator.h +++ b/client/configurators/wireguard_configurator.h @@ -31,11 +31,11 @@ public: QString processConfigWithLocalSettings(QString config); QString processConfigWithExportSettings(QString config); + static ConnectionData genClientKeys(); + private: ConnectionData prepareWireguardConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr); - - ConnectionData genClientKeys(); bool m_isAwg; QString m_serverConfigPath; diff --git a/client/ui/controllers/apiController.cpp b/client/ui/controllers/apiController.cpp index 14a05410..521a5e8f 100644 --- a/client/ui/controllers/apiController.cpp +++ b/client/ui/controllers/apiController.cpp @@ -5,12 +5,14 @@ #include #include "configurators/openvpn_configurator.h" +#include "configurators/wireguard_configurator.h" namespace { namespace configKey { constexpr char cloak[] = "cloak"; + constexpr char awg[] = "awg"; constexpr char apiEdnpoint[] = "api_endpoint"; constexpr char accessToken[] = "api_key"; @@ -26,33 +28,42 @@ ApiController::ApiController(const QSharedPointer &serversModel, { } -QString ApiController::genPublicKey(const QString &protocol) -{ - if (protocol == configKey::cloak) { - return "."; - } - return QString(); -} - -QString ApiController::genCertificateRequest(const QString &protocol) -{ - if (protocol == configKey::cloak) { - m_certRequest = OpenVpnConfigurator::createCertRequest(); - return m_certRequest.request; - } - return QString(); -} - -void ApiController::processCloudConfig(const QString &protocol, QString &config) +void ApiController::processCloudConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData, QString &config) { if (protocol == configKey::cloak) { config.replace("", "\n"); - config.replace("$OPENVPN_PRIV_KEY", m_certRequest.privKey); + config.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey); return; + } else if (protocol == configKey::awg) { + config.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGUardClientPubKey); } return; } +ApiController::ApiPayloadData ApiController::generateApiPayloadData(const QString &protocol) +{ + ApiController::ApiPayloadData apiPayload; + if (protocol == configKey::cloak) { + apiPayload.certRequest = OpenVpnConfigurator::createCertRequest(); + } else if (protocol == configKey::awg) { + auto connData = WireguardConfigurator::genClientKeys(); + apiPayload.wireGUardClientPubKey = connData.clientPubKey; + apiPayload.wireGuardClientPrivKey = connData.clientPrivKey; + } + return apiPayload; +} + +QJsonObject ApiController::fillApiPayload(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData) +{ + QJsonObject obj; + if (protocol == configKey::cloak) { + obj[configKey::certificate] = apiPayloadData.certRequest.request; + } else if (protocol == configKey::awg) { + obj[configKey::publicKey] = apiPayloadData.wireGUardClientPubKey; + } + return obj; +} + bool ApiController::updateServerConfigFromApi() { auto serverConfig = m_serversModel->getDefaultServerConfig(); @@ -71,13 +82,9 @@ bool ApiController::updateServerConfigFromApi() QString protocol = serverConfig.value(configKey::protocol).toString(); - QJsonObject obj; + auto apiPayloadData = generateApiPayloadData(protocol); - obj[configKey::publicKey] = genPublicKey(protocol); - obj[configKey::certificate] = genCertificateRequest(protocol); - - QByteArray requestBody = QJsonDocument(obj).toJson(); - qDebug() << requestBody; + QByteArray requestBody = QJsonDocument(fillApiPayload(protocol, apiPayloadData)).toJson(); QScopedPointer reply; reply.reset(manager.post(request, requestBody)); @@ -100,7 +107,7 @@ bool ApiController::updateServerConfigFromApi() } QString configStr = ba; - processCloudConfig(protocol, configStr); + processCloudConfig(protocol, apiPayloadData, configStr); QJsonObject cloudConfig = QJsonDocument::fromJson(configStr.toUtf8()).object(); diff --git a/client/ui/controllers/apiController.h b/client/ui/controllers/apiController.h index 1ce933c6..d7b15b77 100644 --- a/client/ui/controllers/apiController.h +++ b/client/ui/controllers/apiController.h @@ -22,15 +22,19 @@ signals: void errorOccurred(const QString &errorMessage); private: - QString genPublicKey(const QString &protocol); - QString genCertificateRequest(const QString &protocol); + struct ApiPayloadData { + OpenVpnConfigurator::ConnectionData certRequest; - void processCloudConfig(const QString &protocol, QString &config); + QString wireGuardClientPrivKey; + QString wireGUardClientPubKey; + }; + + ApiPayloadData generateApiPayloadData(const QString &protocol); + QJsonObject fillApiPayload(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData); + void processCloudConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData, QString &config); QSharedPointer m_serversModel; QSharedPointer m_containersModel; - - OpenVpnConfigurator::ConnectionData m_certRequest; }; #endif // APICONTROLLER_H From 3edb6755b4a7c58aea60ebe582681b731aec19a7 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Tue, 30 Jan 2024 00:47:22 +0700 Subject: [PATCH 2/5] fixed filling in the wg private key --- client/ui/controllers/apiController.cpp | 6 +++--- client/ui/controllers/apiController.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/ui/controllers/apiController.cpp b/client/ui/controllers/apiController.cpp index 521a5e8f..d4142751 100644 --- a/client/ui/controllers/apiController.cpp +++ b/client/ui/controllers/apiController.cpp @@ -35,7 +35,7 @@ void ApiController::processCloudConfig(const QString &protocol, const ApiControl config.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey); return; } else if (protocol == configKey::awg) { - config.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGUardClientPubKey); + config.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey); } return; } @@ -47,7 +47,7 @@ ApiController::ApiPayloadData ApiController::generateApiPayloadData(const QStrin apiPayload.certRequest = OpenVpnConfigurator::createCertRequest(); } else if (protocol == configKey::awg) { auto connData = WireguardConfigurator::genClientKeys(); - apiPayload.wireGUardClientPubKey = connData.clientPubKey; + apiPayload.wireGuardClientPubKey = connData.clientPubKey; apiPayload.wireGuardClientPrivKey = connData.clientPrivKey; } return apiPayload; @@ -59,7 +59,7 @@ QJsonObject ApiController::fillApiPayload(const QString &protocol, const ApiCont if (protocol == configKey::cloak) { obj[configKey::certificate] = apiPayloadData.certRequest.request; } else if (protocol == configKey::awg) { - obj[configKey::publicKey] = apiPayloadData.wireGUardClientPubKey; + obj[configKey::publicKey] = apiPayloadData.wireGuardClientPubKey; } return obj; } diff --git a/client/ui/controllers/apiController.h b/client/ui/controllers/apiController.h index d7b15b77..ed7db533 100644 --- a/client/ui/controllers/apiController.h +++ b/client/ui/controllers/apiController.h @@ -26,7 +26,7 @@ private: OpenVpnConfigurator::ConnectionData certRequest; QString wireGuardClientPrivKey; - QString wireGUardClientPubKey; + QString wireGuardClientPubKey; }; ApiPayloadData generateApiPayloadData(const QString &protocol); From 8f510c1431ab07aca0bc936425088e9528960ef3 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Wed, 31 Jan 2024 21:29:39 +0700 Subject: [PATCH 3/5] added allowedIPs processing for configs from the backend --- client/vpnconnection.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index 75483d89..46a14c07 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -385,6 +385,18 @@ void VpnConnection::createProtocolConnections() void VpnConnection::appendSplitTunnelingConfig() { + if (m_vpnConfiguration.value(config_key::configVersion).toInt()) { + auto protocolName = m_vpnConfiguration.value(config_key::vpnproto).toString(); + if (protocolName == ProtocolProps::protoToString(Proto::Awg)) { + auto configData = m_vpnConfiguration.value(protocolName + "_config_data").toObject(); + auto allowedIpsJsonArray = QJsonArray::fromStringList(configData.value("allowed_ips").toString().split(",")); + + m_vpnConfiguration.insert(config_key::splitTunnelType, Settings::RouteMode::VpnOnlyForwardSites); + m_vpnConfiguration.insert(config_key::splitTunnelSites, allowedIpsJsonArray); + return; + } + } + auto routeMode = m_settings->routeMode(); auto sites = m_settings->getVpnIps(routeMode); @@ -394,7 +406,7 @@ void VpnConnection::appendSplitTunnelingConfig() } // Allow traffic to Amezia DNS - if (routeMode == Settings::VpnOnlyForwardSites){ + if (routeMode == Settings::VpnOnlyForwardSites) { sitesJsonArray.append(m_vpnConfiguration.value(config_key::dns1).toString()); sitesJsonArray.append(m_vpnConfiguration.value(config_key::dns2).toString()); } From 1e5c9c9c4d5d4bb22277496d74c0e5c3638f379a Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Wed, 31 Jan 2024 21:41:46 +0700 Subject: [PATCH 4/5] if allowedIps from the backend is empty, split tunneling of the application works --- client/vpnconnection.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index 50984103..d267584a 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -392,11 +392,18 @@ void VpnConnection::appendSplitTunnelingConfig() auto protocolName = m_vpnConfiguration.value(config_key::vpnproto).toString(); if (protocolName == ProtocolProps::protoToString(Proto::Awg)) { auto configData = m_vpnConfiguration.value(protocolName + "_config_data").toObject(); - auto allowedIpsJsonArray = QJsonArray::fromStringList(configData.value("allowed_ips").toString().split(",")); + QJsonArray allowedIpsJsonArray = QJsonArray::fromStringList(configData.value("allowed_ips").toString().split(",")); + QJsonArray defaultAllowedIP = QJsonArray::fromStringList(QString("0.0.0.0/0, ::/0").split(",")); - m_vpnConfiguration.insert(config_key::splitTunnelType, Settings::RouteMode::VpnOnlyForwardSites); - m_vpnConfiguration.insert(config_key::splitTunnelSites, allowedIpsJsonArray); - return; + if (allowedIpsJsonArray != defaultAllowedIP) { + allowedIpsJsonArray.append(m_vpnConfiguration.value(config_key::dns1).toString()); + allowedIpsJsonArray.append(m_vpnConfiguration.value(config_key::dns2).toString()); + + m_vpnConfiguration.insert(config_key::splitTunnelType, Settings::RouteMode::VpnOnlyForwardSites); + m_vpnConfiguration.insert(config_key::splitTunnelSites, allowedIpsJsonArray); + + return; + } } } From 090208bd2c600b412466bb0d8c7af04712bb12f7 Mon Sep 17 00:00:00 2001 From: albexk Date: Wed, 31 Jan 2024 19:59:00 +0300 Subject: [PATCH 5/5] Bug fix for processing exclude routes for older android versions --- client/android/protocolApi/src/main/kotlin/ProtocolConfig.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/android/protocolApi/src/main/kotlin/ProtocolConfig.kt b/client/android/protocolApi/src/main/kotlin/ProtocolConfig.kt index 75ba1abf..78a24e82 100644 --- a/client/android/protocolApi/src/main/kotlin/ProtocolConfig.kt +++ b/client/android/protocolApi/src/main/kotlin/ProtocolConfig.kt @@ -128,7 +128,8 @@ open class ProtocolConfig protected constructor( } private fun processExcludedRoutes() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU && excludedRoutes.isNotEmpty()) { + // todo: rewrite, taking into account the current routes // for older versions of Android, build a list of subnets without excluded routes // and add them to routes val ipRangeSet = IpRangeSet()