diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0c9dfb32..86779f33 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -255,6 +255,7 @@ jobs: env: # Keep compat with MacOS 10.15 aka Catalina by Qt 6.4 QT_VERSION: 6.4.3 + QIF_VERSION: 4.6 PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }} PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }} DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }} @@ -282,6 +283,11 @@ jobs: set-env: 'true' extra: '--external 7z --base ${{ env.QT_MIRROR }}' + - name: 'Install Qt Installer Framework ${{ env.QIF_VERSION }}' + run: | + mkdir -pv ${{ runner.temp }}/Qt/Tools/QtInstallerFramework + wget https://qt.amzsvc.com/tools/ifw/${{ env.QIF_VERSION }}.zip + unzip ${{ env.QIF_VERSION }}.zip -d ${{ runner.temp }}/Qt/Tools/QtInstallerFramework/ - name: 'Get sources' uses: actions/checkout@v4 @@ -295,13 +301,14 @@ jobs: - name: 'Build project' run: | export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin" + export QIF_BIN_DIR="${{ runner.temp }}/Qt/Tools/QtInstallerFramework/${{ env.QIF_VERSION }}/bin" bash deploy/build_macos.sh - name: 'Upload installer artifact' uses: actions/upload-artifact@v4 with: name: AmneziaVPN_MacOS_old_installer - path: deploy/build/pkg/AmneziaVPN.pkg + path: AmneziaVPN.dmg retention-days: 7 - name: 'Upload unpacked artifact' @@ -318,6 +325,7 @@ jobs: env: QT_VERSION: 6.8.0 + QIF_VERSION: 4.8.1 PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }} PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }} DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }} @@ -345,6 +353,11 @@ jobs: set-env: 'true' extra: '--external 7z --base ${{ env.QT_MIRROR }}' + - name: 'Install Qt Installer Framework ${{ env.QIF_VERSION }}' + run: | + mkdir -pv ${{ runner.temp }}/Qt/Tools/QtInstallerFramework + wget https://qt.amzsvc.com/tools/ifw/${{ env.QIF_VERSION }}.zip + unzip ${{ env.QIF_VERSION }}.zip -d ${{ runner.temp }}/Qt/Tools/QtInstallerFramework/ - name: 'Get sources' uses: actions/checkout@v4 @@ -358,13 +371,14 @@ jobs: - name: 'Build project' run: | export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin" + export QIF_BIN_DIR="${{ runner.temp }}/Qt/Tools/QtInstallerFramework/${{ env.QIF_VERSION }}/bin" bash deploy/build_macos.sh - name: 'Upload installer artifact' uses: actions/upload-artifact@v4 with: name: AmneziaVPN_MacOS_installer - path: deploy/build/pkg/AmneziaVPN.pkg + path: AmneziaVPN.dmg retention-days: 7 - name: 'Upload unpacked artifact' diff --git a/CMakeLists.txt b/CMakeLists.txt index fec613de..424dcf3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR) set(PROJECT AmneziaVPN) -project(${PROJECT} VERSION 4.8.8.1 +project(${PROJECT} VERSION 4.8.7.2 DESCRIPTION "AmneziaVPN" HOMEPAGE_URL "https://amnezia.org/" ) @@ -11,7 +11,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d") set(RELEASE_DATE "${CURRENT_DATE}") set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH}) -set(APP_ANDROID_VERSION_CODE 2087) +set(APP_ANDROID_VERSION_CODE 2086) if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(MZ_PLATFORM_NAME "linux") diff --git a/client/3rd-prebuilt b/client/3rd-prebuilt index 840b7b07..e3b6a332 160000 --- a/client/3rd-prebuilt +++ b/client/3rd-prebuilt @@ -1 +1 @@ -Subproject commit 840b7b070e6ac8b90dda2fac6e98859b23727c0c +Subproject commit e3b6a332056ff0f9234a02f5ce363cdfa5259db2 diff --git a/client/3rd/amneziawg-apple b/client/3rd/amneziawg-apple index 811af0a8..76e7db55 160000 --- a/client/3rd/amneziawg-apple +++ b/client/3rd/amneziawg-apple @@ -1 +1 @@ -Subproject commit 811af0a83b3faeade89a9093a588595666d32066 +Subproject commit 76e7db556a6d7e2582f9481df91db188a46c009c diff --git a/client/android/wireguard/src/main/kotlin/org/amnezia/vpn/protocol/wireguard/Wireguard.kt b/client/android/wireguard/src/main/kotlin/org/amnezia/vpn/protocol/wireguard/Wireguard.kt index 42a27de4..bf3a525c 100644 --- a/client/android/wireguard/src/main/kotlin/org/amnezia/vpn/protocol/wireguard/Wireguard.kt +++ b/client/android/wireguard/src/main/kotlin/org/amnezia/vpn/protocol/wireguard/Wireguard.kt @@ -120,20 +120,18 @@ open class Wireguard : Protocol() { configData.optStringOrNull("Jmax")?.let { setJmax(it.toInt()) } configData.optStringOrNull("S1")?.let { setS1(it.toInt()) } configData.optStringOrNull("S2")?.let { setS2(it.toInt()) } - configData.optStringOrNull("S3")?.let { setS3(it.toInt()) } - configData.optStringOrNull("S4")?.let { setS4(it.toInt()) } configData.optStringOrNull("H1")?.let { setH1(it.toLong()) } configData.optStringOrNull("H2")?.let { setH2(it.toLong()) } configData.optStringOrNull("H3")?.let { setH3(it.toLong()) } configData.optStringOrNull("H4")?.let { setH4(it.toLong()) } - configData.optStringOrNull("I1")?.let { setI1(it) } - configData.optStringOrNull("I2")?.let { setI2(it) } - configData.optStringOrNull("I3")?.let { setI3(it) } - configData.optStringOrNull("I4")?.let { setI4(it) } - configData.optStringOrNull("I5")?.let { setI5(it) } - configData.optStringOrNull("J1")?.let { setJ1(it) } - configData.optStringOrNull("J2")?.let { setJ2(it) } - configData.optStringOrNull("J3")?.let { setJ3(it) } + configData.optStringOrNull("I1")?.let { setI1(it.toString()) } + configData.optStringOrNull("I2")?.let { setI2(it.toString()) } + configData.optStringOrNull("I3")?.let { setI3(it.toString()) } + configData.optStringOrNull("I4")?.let { setI4(it.toString()) } + configData.optStringOrNull("I5")?.let { setI5(it.toString()) } + configData.optStringOrNull("J1")?.let { setJ1(it.toString()) } + configData.optStringOrNull("J2")?.let { setJ2(it.toString()) } + configData.optStringOrNull("J3")?.let { setJ3(it.toString()) } configData.optStringOrNull("Itime")?.let { setItime(it.toInt()) } } diff --git a/client/android/wireguard/src/main/kotlin/org/amnezia/vpn/protocol/wireguard/WireguardConfig.kt b/client/android/wireguard/src/main/kotlin/org/amnezia/vpn/protocol/wireguard/WireguardConfig.kt index 2dfbbae8..65dfb34e 100644 --- a/client/android/wireguard/src/main/kotlin/org/amnezia/vpn/protocol/wireguard/WireguardConfig.kt +++ b/client/android/wireguard/src/main/kotlin/org/amnezia/vpn/protocol/wireguard/WireguardConfig.kt @@ -20,21 +20,10 @@ open class WireguardConfig protected constructor( val jmax: Int?, val s1: Int?, val s2: Int?, - val s3: Int?, - val s4: Int?, val h1: Long?, val h2: Long?, val h3: Long?, - val h4: Long?, - var i1: String?, - var i2: String?, - var i3: String?, - var i4: String?, - var i5: String?, - var j1: String?, - var j2: String?, - var j3: String?, - var itime: Int? + val h4: Long? ) : ProtocolConfig(protocolConfigBuilder) { protected constructor(builder: Builder) : this( @@ -50,21 +39,10 @@ open class WireguardConfig protected constructor( builder.jmax, builder.s1, builder.s2, - builder.s3, - builder.s4, builder.h1, builder.h2, builder.h3, - builder.h4, - builder.i1, - builder.i2, - builder.i3, - builder.i4, - builder.i5, - builder.j1, - builder.j2, - builder.j3, - builder.itime + builder.h4 ) fun toWgUserspaceString(): String = with(StringBuilder()) { @@ -83,21 +61,10 @@ open class WireguardConfig protected constructor( appendLine("jmax=$jmax") appendLine("s1=$s1") appendLine("s2=$s2") - s3?.let { appendLine("s3=$it") } - s4?.let { appendLine("s4=$it") } appendLine("h1=$h1") appendLine("h2=$h2") appendLine("h3=$h3") appendLine("h4=$h4") - i1?.let { appendLine("i1=$it") } - i2?.let { appendLine("i2=$it") } - i3?.let { appendLine("i3=$it") } - i4?.let { appendLine("i4=$it") } - i5?.let { appendLine("i5=$it") } - j1?.let { appendLine("j1=$it") } - j2?.let { appendLine("j2=$it") } - j3?.let { appendLine("j3=$it") } - itime?.let { appendLine("itime=$it") } } } @@ -150,8 +117,6 @@ open class WireguardConfig protected constructor( internal var jmax: Int? = null internal var s1: Int? = null internal var s2: Int? = null - internal var s3: Int? = null - internal var s4: Int? = null internal var h1: Long? = null internal var h2: Long? = null internal var h3: Long? = null @@ -183,8 +148,6 @@ open class WireguardConfig protected constructor( fun setJmax(jmax: Int) = apply { this.jmax = jmax } fun setS1(s1: Int) = apply { this.s1 = s1 } fun setS2(s2: Int) = apply { this.s2 = s2 } - fun setS3(s3: Int) = apply { this.s3 = s3 } - fun setS4(s4: Int) = apply { this.s4 = s4 } fun setH1(h1: Long) = apply { this.h1 = h1 } fun setH2(h2: Long) = apply { this.h2 = h2 } fun setH3(h3: Long) = apply { this.h3 = h3 } diff --git a/client/configurators/awg_configurator.cpp b/client/configurators/awg_configurator.cpp index f83acb19..f5e21cf0 100644 --- a/client/configurators/awg_configurator.cpp +++ b/client/configurators/awg_configurator.cpp @@ -1,5 +1,4 @@ #include "awg_configurator.h" -#include "protocols/protocols_defs.h" #include #include @@ -40,20 +39,15 @@ QString AwgConfigurator::createConfig(const ServerCredentials &credentials, Dock jsonConfig[config_key::responsePacketMagicHeader] = configMap.value(config_key::responsePacketMagicHeader); jsonConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader); jsonConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader); - - // jsonConfig[config_key::cookieReplyPacketJunkSize] = configMap.value(config_key::cookieReplyPacketJunkSize); - // jsonConfig[config_key::transportPacketJunkSize] = configMap.value(config_key::transportPacketJunkSize); - - // jsonConfig[config_key::specialJunk1] = configMap.value(amnezia::config_key::specialJunk1); - // jsonConfig[config_key::specialJunk2] = configMap.value(amnezia::config_key::specialJunk2); - // jsonConfig[config_key::specialJunk3] = configMap.value(amnezia::config_key::specialJunk3); - // jsonConfig[config_key::specialJunk4] = configMap.value(amnezia::config_key::specialJunk4); - // jsonConfig[config_key::specialJunk5] = configMap.value(amnezia::config_key::specialJunk5); - // jsonConfig[config_key::controlledJunk1] = configMap.value(amnezia::config_key::controlledJunk1); - // jsonConfig[config_key::controlledJunk2] = configMap.value(amnezia::config_key::controlledJunk2); - // jsonConfig[config_key::controlledJunk3] = configMap.value(amnezia::config_key::controlledJunk3); - // jsonConfig[config_key::specialHandshakeTimeout] = configMap.value(amnezia::config_key::specialHandshakeTimeout); - + jsonConfig[config_key::specialJunk1] = configMap.value(amnezia::config_key::specialJunk1); + jsonConfig[config_key::specialJunk2] = configMap.value(amnezia::config_key::specialJunk2); + jsonConfig[config_key::specialJunk3] = configMap.value(amnezia::config_key::specialJunk3); + jsonConfig[config_key::specialJunk4] = configMap.value(amnezia::config_key::specialJunk4); + jsonConfig[config_key::specialJunk5] = configMap.value(amnezia::config_key::specialJunk5); + jsonConfig[config_key::controlledJunk1] = configMap.value(amnezia::config_key::controlledJunk1); + jsonConfig[config_key::controlledJunk2] = configMap.value(amnezia::config_key::controlledJunk2); + jsonConfig[config_key::controlledJunk3] = configMap.value(amnezia::config_key::controlledJunk3); + jsonConfig[config_key::specialHandshakeTimeout] = configMap.value(amnezia::config_key::specialHandshakeTimeout); jsonConfig[config_key::mtu] = containerConfig.value(ProtocolProps::protoToString(Proto::Awg)).toObject().value(config_key::mtu).toString(protocols::awg::defaultMtu); diff --git a/client/configurators/openvpn_configurator.cpp b/client/configurators/openvpn_configurator.cpp index f6996320..6d6603da 100644 --- a/client/configurators/openvpn_configurator.cpp +++ b/client/configurators/openvpn_configurator.cpp @@ -118,12 +118,6 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPairisSitesSplitTunnelingEnabled()) { config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n"); config.append("block-ipv6\n"); @@ -167,12 +161,6 @@ QString OpenVpnConfigurator::processConfigWithExportSettings(const QPair resolvers; - resolvers.append(QHostAddress(config.m_primaryDnsServer)); - if (!config.m_secondaryDnsServer.isEmpty()) { - resolvers.append(QHostAddress(config.m_secondaryDnsServer)); - } + resolvers.append(QHostAddress(config.m_dnsServer)); // If the DNS is not the Gateway, it's a user defined DNS // thus, not add any other :) - if (config.m_primaryDnsServer == config.m_serverIpv4Gateway) { + if (config.m_dnsServer == config.m_serverIpv4Gateway) { resolvers.append(QHostAddress(config.m_serverIpv6Gateway)); } @@ -282,26 +279,15 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) { config.m_serverIpv4Gateway = obj.value("serverIpv4Gateway").toString(); config.m_serverIpv6Gateway = obj.value("serverIpv6Gateway").toString(); - if (!obj.contains("primaryDnsServer")) { - config.m_primaryDnsServer = QString(); + if (!obj.contains("dnsServer")) { + config.m_dnsServer = QString(); } else { - QJsonValue value = obj.value("primaryDnsServer"); + QJsonValue value = obj.value("dnsServer"); if (!value.isString()) { logger.error() << "dnsServer is not a string"; return false; } - config.m_primaryDnsServer = value.toString(); - } - - if (!obj.contains("secondaryDnsServer")) { - config.m_secondaryDnsServer = QString(); - } else { - QJsonValue value = obj.value("secondaryDnsServer"); - if (!value.isString()) { - logger.error() << "dnsServer is not a string"; - return false; - } - config.m_secondaryDnsServer = value.toString(); + config.m_dnsServer = value.toString(); } if (!obj.contains("hopType")) { @@ -405,13 +391,6 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) { if (!obj.value("S2").isNull()) { config.m_responsePacketJunkSize = obj.value("S2").toString(); } - if (!obj.value("S3").isNull()) { - config.m_cookieReplyPacketJunkSize = obj.value("S3").toString(); - } - if (!obj.value("S4").isNull()) { - config.m_transportPacketJunkSize = obj.value("S4").toString(); - } - if (!obj.value("H1").isNull()) { config.m_initPacketMagicHeader = obj.value("H1").toString(); } @@ -426,31 +405,31 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) { } if (!obj.value("I1").isNull()) { - config.m_specialJunk["I1"] = obj.value("I1").toString(); + config.m_specialJunk["I1"] = obj.value("I1").toString(); } if (!obj.value("I2").isNull()) { - config.m_specialJunk["I2"] = obj.value("I2").toString(); + config.m_specialJunk["I2"] = obj.value("I2").toString(); } if (!obj.value("I3").isNull()) { - config.m_specialJunk["I3"] = obj.value("I3").toString(); + config.m_specialJunk["I3"] = obj.value("I3").toString(); } if (!obj.value("I4").isNull()) { - config.m_specialJunk["I4"] = obj.value("I4").toString(); + config.m_specialJunk["I4"] = obj.value("I4").toString(); } if (!obj.value("I5").isNull()) { - config.m_specialJunk["I5"] = obj.value("I5").toString(); + config.m_specialJunk["I5"] = obj.value("I5").toString(); } if (!obj.value("J1").isNull()) { - config.m_controlledJunk["J1"] = obj.value("J1").toString(); + config.m_controlledJunk["J1"] = obj.value("J1").toString(); } if (!obj.value("J2").isNull()) { - config.m_controlledJunk["J2"] = obj.value("J2").toString(); + config.m_controlledJunk["J2"] = obj.value("J2").toString(); } if (!obj.value("J3").isNull()) { - config.m_controlledJunk["J3"] = obj.value("J3").toString(); + config.m_controlledJunk["J3"] = obj.value("J3").toString(); } if (!obj.value("Itime").isNull()) { - config.m_specialHandshakeTimeout = obj.value("Itime").toString(); + config.m_specialHandshakeTimeout = obj.value("Itime").toString(); } return true; @@ -495,7 +474,7 @@ bool Daemon::deactivate(bool emitSignals) { m_connections.clear(); // Delete the interface - return wgutils()->deleteInterface(); + return wgutils()->deleteInterface(); } QString Daemon::logs() { diff --git a/client/daemon/interfaceconfig.cpp b/client/daemon/interfaceconfig.cpp index 53da5d36..c02d19f9 100644 --- a/client/daemon/interfaceconfig.cpp +++ b/client/daemon/interfaceconfig.cpp @@ -28,8 +28,7 @@ QJsonObject InterfaceConfig::toJson() const { (m_hopType == InterfaceConfig::SingleHop)) { json.insert("serverIpv4Gateway", QJsonValue(m_serverIpv4Gateway)); json.insert("serverIpv6Gateway", QJsonValue(m_serverIpv6Gateway)); - json.insert("primaryDnsServer", QJsonValue(m_primaryDnsServer)); - json.insert("secondaryDnsServer", QJsonValue(m_secondaryDnsServer)); + json.insert("dnsServer", QJsonValue(m_dnsServer)); } QJsonArray allowedIPAddesses; @@ -101,15 +100,11 @@ QString InterfaceConfig::toWgConf(const QMap& extra) const { out << "MTU = " << m_deviceMTU << "\n"; } - if (!m_primaryDnsServer.isNull()) { - QStringList dnsServers; - dnsServers.append(m_primaryDnsServer); - if (!m_secondaryDnsServer.isNull()) { - dnsServers.append(m_secondaryDnsServer); - } + if (!m_dnsServer.isNull()) { + QStringList dnsServers(m_dnsServer); // If the DNS is not the Gateway, it's a user defined DNS // thus, not add any other :) - if (m_primaryDnsServer == m_serverIpv4Gateway) { + if (m_dnsServer == m_serverIpv4Gateway) { dnsServers.append(m_serverIpv6Gateway); } out << "DNS = " << dnsServers.join(", ") << "\n"; @@ -130,12 +125,6 @@ QString InterfaceConfig::toWgConf(const QMap& extra) const { if (!m_responsePacketJunkSize.isNull()) { out << "S2 = " << m_responsePacketJunkSize << "\n"; } - if (!m_cookieReplyPacketJunkSize.isNull()) { - out << "S3 = " << m_cookieReplyPacketJunkSize << "\n"; - } - if (!m_transportPacketJunkSize.isNull()) { - out << "S4 = " << m_transportPacketJunkSize << "\n"; - } if (!m_initPacketMagicHeader.isNull()) { out << "H1 = " << m_initPacketMagicHeader << "\n"; } diff --git a/client/daemon/interfaceconfig.h b/client/daemon/interfaceconfig.h index 06288e80..1cb432a0 100644 --- a/client/daemon/interfaceconfig.h +++ b/client/daemon/interfaceconfig.h @@ -32,8 +32,7 @@ class InterfaceConfig { QString m_serverIpv4AddrIn; QString m_serverPskKey; QString m_serverIpv6AddrIn; - QString m_primaryDnsServer; - QString m_secondaryDnsServer; + QString m_dnsServer; int m_serverPort = 0; int m_deviceMTU = 1420; QList m_allowedIPAddressRanges; @@ -50,8 +49,6 @@ class InterfaceConfig { QString m_junkPacketMaxSize; QString m_initPacketJunkSize; QString m_responsePacketJunkSize; - QString m_cookieReplyPacketJunkSize; - QString m_transportPacketJunkSize; QString m_initPacketMagicHeader; QString m_responsePacketMagicHeader; QString m_underloadPacketMagicHeader; diff --git a/client/mozilla/localsocketcontroller.cpp b/client/mozilla/localsocketcontroller.cpp index 9abab81c..db7295a5 100644 --- a/client/mozilla/localsocketcontroller.cpp +++ b/client/mozilla/localsocketcontroller.cpp @@ -149,14 +149,7 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) { json.insert("serverPort", wgConfig.value(amnezia::config_key::port).toInt()); json.insert("serverIpv4Gateway", wgConfig.value(amnezia::config_key::hostName)); // json.insert("serverIpv6Gateway", QJsonValue(hop.m_server.ipv6Gateway())); - - json.insert("primaryDnsServer", rawConfig.value(amnezia::config_key::dns1)); - - // We don't use secondary DNS if primary DNS is AmneziaDNS - if (!rawConfig.value(amnezia::config_key::dns1).toString(). - contains(amnezia::protocols::dns::amneziaDnsIp)) { - json.insert("secondaryDnsServer", rawConfig.value(amnezia::config_key::dns2)); - } + json.insert("dnsServer", rawConfig.value(amnezia::config_key::dns1)); QJsonArray jsAllowedIPAddesses; @@ -244,8 +237,6 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) { json.insert(amnezia::config_key::junkPacketMaxSize, wgConfig.value(amnezia::config_key::junkPacketMaxSize)); json.insert(amnezia::config_key::initPacketJunkSize, wgConfig.value(amnezia::config_key::initPacketJunkSize)); json.insert(amnezia::config_key::responsePacketJunkSize, wgConfig.value(amnezia::config_key::responsePacketJunkSize)); - json.insert(amnezia::config_key::cookieReplyPacketJunkSize, wgConfig.value(amnezia::config_key::cookieReplyPacketJunkSize)); - json.insert(amnezia::config_key::transportPacketJunkSize, wgConfig.value(amnezia::config_key::transportPacketJunkSize)); json.insert(amnezia::config_key::initPacketMagicHeader, wgConfig.value(amnezia::config_key::initPacketMagicHeader)); json.insert(amnezia::config_key::responsePacketMagicHeader, wgConfig.value(amnezia::config_key::responsePacketMagicHeader)); json.insert(amnezia::config_key::underloadPacketMagicHeader, wgConfig.value(amnezia::config_key::underloadPacketMagicHeader)); @@ -264,8 +255,6 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) { && !wgConfig.value(amnezia::config_key::junkPacketMaxSize).isUndefined() && !wgConfig.value(amnezia::config_key::initPacketJunkSize).isUndefined() && !wgConfig.value(amnezia::config_key::responsePacketJunkSize).isUndefined() - && !wgConfig.value(amnezia::config_key::cookieReplyPacketJunkSize).isUndefined() - && !wgConfig.value(amnezia::config_key::transportPacketJunkSize).isUndefined() && !wgConfig.value(amnezia::config_key::initPacketMagicHeader).isUndefined() && !wgConfig.value(amnezia::config_key::responsePacketMagicHeader).isUndefined() && !wgConfig.value(amnezia::config_key::underloadPacketMagicHeader).isUndefined() @@ -284,8 +273,6 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) { json.insert(amnezia::config_key::junkPacketMaxSize, wgConfig.value(amnezia::config_key::junkPacketMaxSize)); json.insert(amnezia::config_key::initPacketJunkSize, wgConfig.value(amnezia::config_key::initPacketJunkSize)); json.insert(amnezia::config_key::responsePacketJunkSize, wgConfig.value(amnezia::config_key::responsePacketJunkSize)); - json.insert(amnezia::config_key::cookieReplyPacketJunkSize, wgConfig.value(amnezia::config_key::cookieReplyPacketJunkSize)); - json.insert(amnezia::config_key::transportPacketJunkSize, wgConfig.value(amnezia::config_key::transportPacketJunkSize)); json.insert(amnezia::config_key::initPacketMagicHeader, wgConfig.value(amnezia::config_key::initPacketMagicHeader)); json.insert(amnezia::config_key::responsePacketMagicHeader, wgConfig.value(amnezia::config_key::responsePacketMagicHeader)); json.insert(amnezia::config_key::underloadPacketMagicHeader, wgConfig.value(amnezia::config_key::underloadPacketMagicHeader)); diff --git a/client/platforms/ios/WGConfig.swift b/client/platforms/ios/WGConfig.swift index 537687f1..0146950d 100644 --- a/client/platforms/ios/WGConfig.swift +++ b/client/platforms/ios/WGConfig.swift @@ -4,7 +4,7 @@ struct WGConfig: Decodable { let initPacketMagicHeader, responsePacketMagicHeader: String? let underloadPacketMagicHeader, transportPacketMagicHeader: String? let junkPacketCount, junkPacketMinSize, junkPacketMaxSize: String? - let initPacketJunkSize, responsePacketJunkSize, cookieReplyPacketJunkSize, transportPacketJunkSize: String? + let initPacketJunkSize, responsePacketJunkSize: String? let specialJunk1, specialJunk2, specialJunk3, specialJunk4, specialJunk5: String? let controlledJunk1, controlledJunk2, controlledJunk3: String? let specialHandshakeTimeout: String? @@ -26,7 +26,7 @@ struct WGConfig: Decodable { case initPacketMagicHeader = "H1", responsePacketMagicHeader = "H2" case underloadPacketMagicHeader = "H3", transportPacketMagicHeader = "H4" case junkPacketCount = "Jc", junkPacketMinSize = "Jmin", junkPacketMaxSize = "Jmax" - case initPacketJunkSize = "S1", responsePacketJunkSize = "S2", cookieReplyPacketJunkSize = "S3", transportPacketJunkSize = "S4" + case initPacketJunkSize = "S1", responsePacketJunkSize = "S2" case specialJunk1 = "I1", specialJunk2 = "I2", specialJunk3 = "I3", specialJunk4 = "I4", specialJunk5 = "I5" case controlledJunk1 = "J1", controlledJunk2 = "J2", controlledJunk3 = "J3" case specialHandshakeTimeout = "Itime" @@ -46,59 +46,27 @@ struct WGConfig: Decodable { } var settings: String { - guard junkPacketCount != nil else { return "" } - - var settingsLines: [String] = [] - - // Required parameters when junkPacketCount is present - settingsLines.append("Jc = \(junkPacketCount!)") - settingsLines.append("Jmin = \(junkPacketMinSize!)") - settingsLines.append("Jmax = \(junkPacketMaxSize!)") - settingsLines.append("S1 = \(initPacketJunkSize!)") - settingsLines.append("S2 = \(responsePacketJunkSize!)") - - settingsLines.append("H1 = \(initPacketMagicHeader!)") - settingsLines.append("H2 = \(responsePacketMagicHeader!)") - settingsLines.append("H3 = \(underloadPacketMagicHeader!)") - settingsLines.append("H4 = \(transportPacketMagicHeader!)") - - // Optional parameters - only add if not nil and not empty - if let s3 = cookieReplyPacketJunkSize, !s3.isEmpty { - settingsLines.append("S3 = \(s3)") - } - if let s4 = transportPacketJunkSize, !s4.isEmpty { - settingsLines.append("S4 = \(s4)") - } - - if let i1 = specialJunk1, !i1.isEmpty { - settingsLines.append("I1 = \(i1)") - } - if let i2 = specialJunk2, !i2.isEmpty { - settingsLines.append("I2 = \(i2)") - } - if let i3 = specialJunk3, !i3.isEmpty { - settingsLines.append("I3 = \(i3)") - } - if let i4 = specialJunk4, !i4.isEmpty { - settingsLines.append("I4 = \(i4)") - } - if let i5 = specialJunk5, !i5.isEmpty { - settingsLines.append("I5 = \(i5)") - } - if let j1 = controlledJunk1, !j1.isEmpty { - settingsLines.append("J1 = \(j1)") - } - if let j2 = controlledJunk2, !j2.isEmpty { - settingsLines.append("J2 = \(j2)") - } - if let j3 = controlledJunk3, !j3.isEmpty { - settingsLines.append("J3 = \(j3)") - } - if let itime = specialHandshakeTimeout, !itime.isEmpty { - settingsLines.append("Itime = \(itime)") - } - - return settingsLines.joined(separator: "\n") + junkPacketCount == nil ? "" : + """ + Jc = \(junkPacketCount!) + Jmin = \(junkPacketMinSize!) + Jmax = \(junkPacketMaxSize!) + S1 = \(initPacketJunkSize!) + S2 = \(responsePacketJunkSize!) + H1 = \(initPacketMagicHeader!) + H2 = \(responsePacketMagicHeader!) + H3 = \(underloadPacketMagicHeader!) + H4 = \(transportPacketMagicHeader!) + I1 = \(specialJunk1!) + I2 = \(specialJunk2!) + I3 = \(specialJunk3!) + I4 = \(specialJunk4!) + I5 = \(specialJunk5!) + J1 = \(controlledJunk1!) + J2 = \(controlledJunk2!) + J3 = \(controlledJunk3!) + Itime = \(specialHandshakeTimeout!) + """ } var str: String { diff --git a/client/platforms/ios/ios_controller.mm b/client/platforms/ios/ios_controller.mm index e64c6dce..85fb50b7 100644 --- a/client/platforms/ios/ios_controller.mm +++ b/client/platforms/ios/ios_controller.mm @@ -507,8 +507,6 @@ bool IosController::setupWireGuard() wgConfig.insert(config_key::initPacketJunkSize, config[config_key::initPacketJunkSize]); wgConfig.insert(config_key::responsePacketJunkSize, config[config_key::responsePacketJunkSize]); - wgConfig.insert(config_key::cookieReplyPacketJunkSize, config[config_key::cookieReplyPacketJunkSize]); - wgConfig.insert(config_key::transportPacketJunkSize, config[config_key::transportPacketJunkSize]); wgConfig.insert(config_key::junkPacketCount, config[config_key::junkPacketCount]); wgConfig.insert(config_key::junkPacketMinSize, config[config_key::junkPacketMinSize]); @@ -607,23 +605,11 @@ bool IosController::setupAwg() wgConfig.insert(config_key::initPacketJunkSize, config[config_key::initPacketJunkSize]); wgConfig.insert(config_key::responsePacketJunkSize, config[config_key::responsePacketJunkSize]); - wgConfig.insert(config_key::cookieReplyPacketJunkSize, config[config_key::cookieReplyPacketJunkSize]); - wgConfig.insert(config_key::transportPacketJunkSize, config[config_key::transportPacketJunkSize]); wgConfig.insert(config_key::junkPacketCount, config[config_key::junkPacketCount]); wgConfig.insert(config_key::junkPacketMinSize, config[config_key::junkPacketMinSize]); wgConfig.insert(config_key::junkPacketMaxSize, config[config_key::junkPacketMaxSize]); - wgConfig.insert(config_key::specialJunk1, config[config_key::specialJunk1]); - wgConfig.insert(config_key::specialJunk2, config[config_key::specialJunk2]); - wgConfig.insert(config_key::specialJunk3, config[config_key::specialJunk3]); - wgConfig.insert(config_key::specialJunk4, config[config_key::specialJunk4]); - wgConfig.insert(config_key::specialJunk5, config[config_key::specialJunk5]); - wgConfig.insert(config_key::controlledJunk1, config[config_key::controlledJunk1]); - wgConfig.insert(config_key::controlledJunk2, config[config_key::controlledJunk2]); - wgConfig.insert(config_key::controlledJunk3, config[config_key::controlledJunk3]); - wgConfig.insert(config_key::specialHandshakeTimeout, config[config_key::specialHandshakeTimeout]); - QJsonDocument wgConfigDoc(wgConfig); QString wgConfigDocStr(wgConfigDoc.toJson(QJsonDocument::Compact)); @@ -808,9 +794,9 @@ bool IosController::shareText(const QStringList& filesToSend) { if (!qtController) return; UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil]; - + __block bool isAccepted = false; - + [activityController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) { isAccepted = completed; emit finished(); @@ -822,11 +808,11 @@ bool IosController::shareText(const QStringList& filesToSend) { popController.sourceView = qtController.view; popController.sourceRect = CGRectMake(100, 100, 100, 100); } - + QEventLoop wait; QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit); wait.exec(); - + return isAccepted; } @@ -840,7 +826,7 @@ QString IosController::openFile() { if (!qtController) return; [qtController presentViewController:documentPicker animated:YES completion:nil]; - + __block QString filePath; documentPickerDelegate.documentPickerClosedCallback = ^(NSString *path) { @@ -855,7 +841,7 @@ QString IosController::openFile() { QEventLoop wait; QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit); wait.exec(); - + return filePath; } diff --git a/client/platforms/linux/daemon/wireguardutilslinux.cpp b/client/platforms/linux/daemon/wireguardutilslinux.cpp index cfde73e2..58227581 100644 --- a/client/platforms/linux/daemon/wireguardutilslinux.cpp +++ b/client/platforms/linux/daemon/wireguardutilslinux.cpp @@ -121,12 +121,6 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) { if (!config.m_responsePacketJunkSize.isEmpty()) { out << "s2=" << config.m_responsePacketJunkSize << "\n"; } - if (!config.m_cookieReplyPacketJunkSize.isEmpty()) { - out << "s3=" << config.m_cookieReplyPacketJunkSize << "\n"; - } - if (!config.m_transportPacketJunkSize.isEmpty()) { - out << "s4=" << config.m_transportPacketJunkSize << "\n"; - } if (!config.m_initPacketMagicHeader.isEmpty()) { out << "h1=" << config.m_initPacketMagicHeader << "\n"; } @@ -156,10 +150,7 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) { } else { if (config.m_killSwitchEnabled) { FirewallParams params { }; - params.dnsServers.append(config.m_primaryDnsServer); - if (!config.m_secondaryDnsServer.isEmpty()) { - params.dnsServers.append(config.m_secondaryDnsServer); - } + params.dnsServers.append(config.m_dnsServer); if (config.m_allowedIPAddressRanges.contains(IPAddress("0.0.0.0/0"))) { params.blockAll = true; if (config.m_excludedAddresses.size()) { diff --git a/client/platforms/macos/daemon/macosfirewall.cpp b/client/platforms/macos/daemon/macosfirewall.cpp index 5211c440..0fe51f23 100644 --- a/client/platforms/macos/daemon/macosfirewall.cpp +++ b/client/platforms/macos/daemon/macosfirewall.cpp @@ -43,16 +43,8 @@ namespace { #include "macosfirewall.h" -#include -#include - -// Read-only rules bundled with the application. -#define ResourceDir (qApp->applicationDirPath() + "/pf") - -// Writable location that does NOT live inside the signed bundle. Using a -// constant path under /Library/Application Support keeps the signature intact -// and is accessible to the root helper. -#define DaemonDataDir QStringLiteral("/Library/Application Support/AmneziaVPN/pf") +#define ResourceDir qApp->applicationDirPath() + "/pf" +#define DaemonDataDir qApp->applicationDirPath() + "/pf" #include @@ -129,8 +121,6 @@ void MacOSFirewall::install() logger.info() << "Installing PF root anchor"; installRootAnchors(); - // Ensure writable directory exists, then store the token there. - QDir().mkpath(DaemonDataDir); execute(QStringLiteral("pfctl -E 2>&1 | grep -F 'Token : ' | cut -c9- > '%1/pf.token'").arg(DaemonDataDir)); } diff --git a/client/platforms/macos/daemon/wireguardutilsmacos.cpp b/client/platforms/macos/daemon/wireguardutilsmacos.cpp index cce4afab..1d8aa6e0 100644 --- a/client/platforms/macos/daemon/wireguardutilsmacos.cpp +++ b/client/platforms/macos/daemon/wireguardutilsmacos.cpp @@ -119,12 +119,6 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) { if (!config.m_responsePacketJunkSize.isEmpty()) { out << "s2=" << config.m_responsePacketJunkSize << "\n"; } - if (!config.m_cookieReplyPacketJunkSize.isEmpty()) { - out << "s3=" << config.m_cookieReplyPacketJunkSize << "\n"; - } - if (!config.m_transportPacketJunkSize.isEmpty()) { - out << "s4=" << config.m_transportPacketJunkSize << "\n"; - } if (!config.m_initPacketMagicHeader.isEmpty()) { out << "h1=" << config.m_initPacketMagicHeader << "\n"; } @@ -138,43 +132,30 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) { out << "h4=" << config.m_transportPacketMagicHeader << "\n"; } - for (const QString& key : config.m_specialJunk.keys()) { - out << key.toLower() << "=" << config.m_specialJunk.value(key) << "\n"; - } - for (const QString& key : config.m_controlledJunk.keys()) { - out << key.toLower() << "=" << config.m_controlledJunk.value(key) << "\n"; - } - if (!config.m_specialHandshakeTimeout.isEmpty()) { - out << "itime=" << config.m_specialHandshakeTimeout << "\n"; - } - int err = uapiErrno(uapiCommand(message)); if (err != 0) { logger.error() << "Interface configuration failed:" << strerror(err); } else { - if (config.m_killSwitchEnabled) { - FirewallParams params { }; - params.dnsServers.append(config.m_primaryDnsServer); - if (!config.m_secondaryDnsServer.isEmpty()) { - params.dnsServers.append(config.m_secondaryDnsServer); - } + if (config.m_killSwitchEnabled) { + FirewallParams params { }; + params.dnsServers.append(config.m_dnsServer); - if (config.m_allowedIPAddressRanges.contains(IPAddress("0.0.0.0/0"))) { + if (config.m_allowedIPAddressRanges.contains(IPAddress("0.0.0.0/0"))) { params.blockAll = true; if (config.m_excludedAddresses.size()) { - params.allowNets = true; - foreach (auto net, config.m_excludedAddresses) { - params.allowAddrs.append(net.toUtf8()); - } + params.allowNets = true; + foreach (auto net, config.m_excludedAddresses) { + params.allowAddrs.append(net.toUtf8()); + } } - } else { + } else { params.blockNets = true; foreach (auto net, config.m_allowedIPAddressRanges) { - params.blockAddrs.append(net.toString()); + params.blockAddrs.append(net.toString()); } + } + applyFirewallRules(params); } - applyFirewallRules(params); - } } return (err == 0); } diff --git a/client/platforms/windows/daemon/windowsfirewall.cpp b/client/platforms/windows/daemon/windowsfirewall.cpp index 2556c417..1834452e 100644 --- a/client/platforms/windows/daemon/windowsfirewall.cpp +++ b/client/platforms/windows/daemon/windowsfirewall.cpp @@ -291,32 +291,15 @@ bool WindowsFirewall::enablePeerTraffic(const InterfaceConfig& config) { "Block Internet", config.m_serverPublicKey)) { return false; } - if (!config.m_primaryDnsServer.isEmpty()) { - if (!allowTrafficTo(QHostAddress(config.m_primaryDnsServer), 53, HIGH_WEIGHT, + if (!config.m_dnsServer.isEmpty()) { + if (!allowTrafficTo(QHostAddress(config.m_dnsServer), 53, HIGH_WEIGHT, "Allow DNS-Server", config.m_serverPublicKey)) { return false; } // In some cases, we might configure a 2nd DNS server for IPv6, however // this should probably be cleaned up by converting m_dnsServer into // a QStringList instead. - if (config.m_primaryDnsServer == config.m_serverIpv4Gateway) { - if (!allowTrafficTo(QHostAddress(config.m_serverIpv6Gateway), 53, - HIGH_WEIGHT, "Allow extra IPv6 DNS-Server", - config.m_serverPublicKey)) { - return false; - } - } - } - - if (!config.m_secondaryDnsServer.isEmpty()) { - if (!allowTrafficTo(QHostAddress(config.m_secondaryDnsServer), 53, HIGH_WEIGHT, - "Allow DNS-Server", config.m_serverPublicKey)) { - return false; - } - // In some cases, we might configure a 2nd DNS server for IPv6, however - // this should probably be cleaned up by converting m_dnsServer into - // a QStringList instead. - if (config.m_secondaryDnsServer == config.m_serverIpv4Gateway) { + if (config.m_dnsServer == config.m_serverIpv4Gateway) { if (!allowTrafficTo(QHostAddress(config.m_serverIpv6Gateway), 53, HIGH_WEIGHT, "Allow extra IPv6 DNS-Server", config.m_serverPublicKey)) { diff --git a/client/platforms/windows/daemon/wireguardutilswindows.cpp b/client/platforms/windows/daemon/wireguardutilswindows.cpp index a5c9c84d..d01ef54a 100644 --- a/client/platforms/windows/daemon/wireguardutilswindows.cpp +++ b/client/platforms/windows/daemon/wireguardutilswindows.cpp @@ -130,7 +130,6 @@ bool WireguardUtilsWindows::addInterface(const InterfaceConfig& config) { // Enable the windows firewall NET_IFINDEX ifindex; ConvertInterfaceLuidToIndex(&luid, &ifindex); - m_firewall->allowAllTraffic(); m_firewall->enableInterface(ifindex); } diff --git a/client/protocols/openvpnprotocol.cpp b/client/protocols/openvpnprotocol.cpp index 0bbdbd07..429b85a6 100644 --- a/client/protocols/openvpnprotocol.cpp +++ b/client/protocols/openvpnprotocol.cpp @@ -343,7 +343,7 @@ void OpenVpnProtocol::updateVpnGateway(const QString &line) // killSwitch toggle if (m_vpnLocalAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) { if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) { - IpcClient::Interface()->enableKillSwitch(m_configData, netInterfaces.at(i).index()); + IpcClient::Interface()->enableKillSwitch(QJsonObject(), netInterfaces.at(i).index()); } m_configData.insert("vpnAdapterIndex", netInterfaces.at(i).index()); m_configData.insert("vpnGateway", m_vpnGateway); diff --git a/client/protocols/protocols_defs.h b/client/protocols/protocols_defs.h index b4cbb6de..e29201cb 100644 --- a/client/protocols/protocols_defs.h +++ b/client/protocols/protocols_defs.h @@ -72,8 +72,6 @@ namespace amnezia constexpr char junkPacketMaxSize[] = "Jmax"; constexpr char initPacketJunkSize[] = "S1"; constexpr char responsePacketJunkSize[] = "S2"; - constexpr char cookieReplyPacketJunkSize[] = "S3"; - constexpr char transportPacketJunkSize[] = "S4"; constexpr char initPacketMagicHeader[] = "H1"; constexpr char responsePacketMagicHeader[] = "H2"; constexpr char underloadPacketMagicHeader[] = "H3"; @@ -114,8 +112,6 @@ namespace amnezia constexpr char clientId[] = "clientId"; - constexpr char nameOverriddenByUser[] = "nameOverriddenByUser"; - } namespace protocols @@ -227,9 +223,6 @@ namespace amnezia constexpr char defaultJunkPacketMaxSize[] = "30"; constexpr char defaultInitPacketJunkSize[] = "15"; constexpr char defaultResponsePacketJunkSize[] = "18"; - constexpr char defaultCookieReplyPacketJunkSize[] = "20"; - constexpr char defaultTransportPacketJunkSize[] = "23"; - constexpr char defaultInitPacketMagicHeader[] = "1020325451"; constexpr char defaultResponsePacketMagicHeader[] = "3288052141"; constexpr char defaultTransportPacketMagicHeader[] = "2528465083"; @@ -242,7 +235,7 @@ namespace amnezia constexpr char defaultControlledJunk1[] = ""; constexpr char defaultControlledJunk2[] = ""; constexpr char defaultControlledJunk3[] = ""; - constexpr char defaultSpecialHandshakeTimeout[] = ""; + constexpr char defaultSpecialHandshakeTimeout[] = "0"; } namespace socks5Proxy diff --git a/client/protocols/xrayprotocol.cpp b/client/protocols/xrayprotocol.cpp index 84922634..faad8e94 100755 --- a/client/protocols/xrayprotocol.cpp +++ b/client/protocols/xrayprotocol.cpp @@ -98,13 +98,8 @@ ErrorCode XrayProtocol::startTun2Sock() if (vpnState == Vpn::ConnectionState::Connected) { setConnectionState(Vpn::ConnectionState::Connecting); QList dnsAddr; - dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns1).toString())); - // We don't use secondary DNS if primary DNS is AmneziaDNS - if (!m_configData.value(amnezia::config_key::dns1).toString(). - contains(amnezia::protocols::dns::amneziaDnsIp)) { - dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns2).toString())); - } + dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns2).toString())); #ifdef Q_OS_WIN QThread::msleep(8000); #endif @@ -139,7 +134,7 @@ ErrorCode XrayProtocol::startTun2Sock() // killSwitch toggle if (m_vpnLocalAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) { if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) { - IpcClient::Interface()->enableKillSwitch(m_configData, netInterfaces.at(i).index()); + IpcClient::Interface()->enableKillSwitch(QJsonObject(), netInterfaces.at(i).index()); } m_configData.insert("vpnAdapterIndex", netInterfaces.at(i).index()); m_configData.insert("vpnGateway", m_vpnGateway); diff --git a/client/resources.qrc b/client/resources.qrc index 54b5846c..72eb15c7 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -239,7 +239,6 @@ ui/qml/Components/ApiPremV1MigrationDrawer.qml ui/qml/Components/ApiPremV1SubListDrawer.qml ui/qml/Components/OtpCodeDrawer.qml - ui/qml/Components/AwgTextField.qml images/flagKit/ZW.svg diff --git a/client/server_scripts/awg/Dockerfile b/client/server_scripts/awg/Dockerfile index a6118a84..f4174d47 100644 --- a/client/server_scripts/awg/Dockerfile +++ b/client/server_scripts/awg/Dockerfile @@ -1,4 +1,4 @@ -FROM amneziavpn/amnezia-wg:latest +FROM marko1777/awg:latest LABEL maintainer="AmneziaVPN" diff --git a/client/server_scripts/check_server_is_busy.sh b/client/server_scripts/check_server_is_busy.sh index feddfed3..4e6a2c26 100644 --- a/client/server_scripts/check_server_is_busy.sh +++ b/client/server_scripts/check_server_is_busy.sh @@ -1,7 +1,6 @@ -if which apt-get > /dev/null 2>&1; then LOCK_CMD="fuser"; LOCK_FILE="/var/lib/dpkg/lock-frontend";\ -elif which dnf > /dev/null 2>&1; then LOCK_CMD="fuser"; LOCK_FILE="/var/cache/dnf/* /var/run/dnf/* /var/lib/dnf/* /var/lib/rpm/*";\ -elif which yum > /dev/null 2>&1; then LOCK_CMD="cat"; LOCK_FILE="/var/run/yum.pid";\ -elif which zypper > /dev/null 2>&1; then LOCK_CMD="cat"; LOCK_FILE="/var/run/zypp.pid";\ -elif which pacman > /dev/null 2>&1; then LOCK_CMD="fuser"; LOCK_FILE="/var/lib/pacman/db.lck";\ +if which apt-get > /dev/null 2>&1; then LOCK_FILE="/var/lib/dpkg/lock-frontend";\ +elif which dnf > /dev/null 2>&1; then LOCK_FILE="/var/run/dnf.pid";\ +elif which yum > /dev/null 2>&1; then LOCK_FILE="/var/run/yum.pid";\ +elif which pacman > /dev/null 2>&1; then LOCK_FILE="/var/lib/pacman/db.lck";\ else echo "Packet manager not found"; echo "Internal error"; exit 1; fi;\ -if command -v $LOCK_CMD > /dev/null 2>&1; then sudo $LOCK_CMD $LOCK_FILE 2>/dev/null; else echo "$LOCK_CMD not installed"; fi +if command -v fuser > /dev/null 2>&1; then sudo fuser $LOCK_FILE 2>/dev/null; else echo "fuser not installed"; fi diff --git a/client/server_scripts/check_user_in_sudo.sh b/client/server_scripts/check_user_in_sudo.sh index f83f2fd7..685e6a18 100644 --- a/client/server_scripts/check_user_in_sudo.sh +++ b/client/server_scripts/check_user_in_sudo.sh @@ -1,7 +1,6 @@ if which apt-get > /dev/null 2>&1; then pm=$(which apt-get); opt="--version";\ elif which dnf > /dev/null 2>&1; then pm=$(which dnf); opt="--version";\ elif which yum > /dev/null 2>&1; then pm=$(which yum); opt="--version";\ -elif which zypper > /dev/null 2>&1; then pm=$(which zypper); opt="--version";\ elif which pacman > /dev/null 2>&1; then pm=$(which pacman); opt="--version";\ else pm="uname"; opt="-a";\ fi;\ diff --git a/client/server_scripts/install_docker.sh b/client/server_scripts/install_docker.sh index 1e41bb5a..619b08d6 100644 --- a/client/server_scripts/install_docker.sh +++ b/client/server_scripts/install_docker.sh @@ -1,7 +1,6 @@ if which apt-get > /dev/null 2>&1; then pm=$(which apt-get); silent_inst="-yq install"; check_pkgs="-yq update"; docker_pkg="docker.io"; dist="debian";\ elif which dnf > /dev/null 2>&1; then pm=$(which dnf); silent_inst="-yq install"; check_pkgs="-yq check-update"; docker_pkg="docker"; dist="fedora";\ elif which yum > /dev/null 2>&1; then pm=$(which yum); silent_inst="-y -q install"; check_pkgs="-y -q check-update"; docker_pkg="docker"; dist="centos";\ -elif which zypper > /dev/null 2>&1; then pm=$(which zypper); silent_inst="-nq install"; check_pkgs="-nq refresh"; docker_pkg="docker"; dist="opensuse";\ elif which pacman > /dev/null 2>&1; then pm=$(which pacman); silent_inst="-S --noconfirm --noprogressbar --quiet"; check_pkgs="-Sup"; docker_pkg="docker"; dist="archlinux";\ else echo "Packet manager not found"; exit 1; fi;\ echo "Dist: $dist, Packet manager: $pm, Install command: $silent_inst, Check pkgs command: $check_pkgs, Docker pkg: $docker_pkg";\ diff --git a/client/translations/amneziavpn_ar_EG.ts b/client/translations/amneziavpn_ar_EG.ts index 4b84502b..b3ea77c8 100644 --- a/client/translations/amneziavpn_ar_EG.ts +++ b/client/translations/amneziavpn_ar_EG.ts @@ -9,6 +9,54 @@ + + AllowedDnsController + + + The address does not look like a valid IP address + + + + + New DNS server added: %1 + + + + + DNS server already exists: %1 + + + + + DNS server removed: %1 + + + + + Can't open file: %1 + لا يمكن فتح ملف: %1 + + + + Failed to parse JSON data from file: %1 + فشل قراءه بيانات JSON من الملف: %1 + + + + The JSON data is not an array in file: %1 + بيانات ال JSON ليست مصفوفة في الملف: %1 + + + + Import completed + اكتمل الاستيراد + + + + Export completed + اكتمل التصدير + + ApiAccountInfoModel @@ -33,39 +81,131 @@ - + Free unlimited access to a basic set of websites such as Facebook, Instagram, Twitter (X), Discord, Telegram and more. YouTube is not included in the free plan. - - - amnezia_free_support_bot - - - - - amnezia_premium_support_bot - - ApiConfigsController - + %1 installed successfully. تم تحميل %1 بنجاح - + API config reloaded تمت إعادة تحميل تكوين API - + Successfully changed the country of connection to %1 تم تغيير بلد الاتصال بنجاح إلى %1 + + ApiPremV1MigrationDrawer + + + Switch to the new Amnezia Premium subscription + + + + + We'll preserve all remaining days of your current subscription and give you an extra month as a thank you. + + + + + This new subscription type will be actively developed with more locations and features added regularly. Currently available: + + + + + <li>13 locations (with more coming soon)</li> + + + + + <li>Easier switching between countries in the app</li> + + + + + <li>Personal dashboard to manage your subscription</li> + + + + + Old keys will be deactivated after switching. + + + + + Email + + + + + mail@example.com + + + + + No old format subscriptions for a given email + + + + + Enter the email you used for your current subscription + + + + + + Continue + واصل + + + + Remind me later + + + + + Don't remind me again + + + + + No more reminders? You can always switch to the new format in the server settings + + + + + Cancel + إلغاء + + + + ApiPremV1SubListDrawer + + + Choose Subscription + + + + + Order ID: + + + + + Purchase Date: + + + ApiServicesModel @@ -97,7 +237,7 @@ - AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan. + Amnezia Free provides unlimited, free access to a basic set of websites and apps, including Facebook, Instagram, Twitter (X), Discord, Telegram, and more. YouTube is not included in the free plan. @@ -115,6 +255,11 @@ %1 days %1 ايام + + + + + VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a> @@ -272,7 +417,7 @@ HomeContainersListView - + Unable change protocol while there is an active connection غير قادر علي تغيير البروتوكول اثناء تواجد اتصال @@ -335,17 +480,17 @@ Can't be disabled for current server ملف تكوين غير صحيح - + Scanned %1 of %2. تم فحص%1 من %2. - + This configuration contains an OpenVPN setup. OpenVPN configurations can include malicious scripts, so only add it if you fully trust the provider of this config. - + <br>In the imported configuration, potentially dangerous lines were found: @@ -357,24 +502,24 @@ Can't be disabled for current server InstallController - + %1 installed successfully. %1 تم التثبيت بنجاح. - + %1 is already installed on the server. %1 بالفعل مٌثبت علي الخادم. - + Added containers that were already installed on the server تمت إضافة الحاويات التي كانت مٌثبتة بالفعل علي الخادم - + Already installed containers were found on the server. All installed containers have been added to the application @@ -382,47 +527,47 @@ Already installed containers were found on the server. All installed containers تمت إضافة جميع الحاويات المٌثبتة إلي التطبيق - + Settings updated successfully تم تحديث الاعدادات بنجاح - + Server '%1' was rebooted تمت إعادة تشغيل الخادم%1 - + Server '%1' was removed تمت إزالة الخادم '%1' - + All containers from server '%1' have been removed قد تم حذفها '%1' جميع الحاويات من الخادم - + %1 has been removed from the server '%2' %1 تم حدف '%2' اسم الخادم - + Api config removed تم حذف تكوين Api - + %1 cached profile cleared تم مسح ملف تعريف %1 المخزن مؤقتًا - + Please login as the user من فضلك قم بتسجيل الدخول كمستخدم - + Server added successfully تمت إضافة الخادم بنجاح @@ -504,6 +649,24 @@ Already installed containers were found on the server. All installed containers تم العثور علي شبكة غير مؤمنة: + + OtpCodeDrawer + + + OTP code was sent to your email + + + + + OTP Code + + + + + Continue + واصل + + PageDeinstalling @@ -533,27 +696,43 @@ Already installed containers were found on the server. All installed containers PageHome - + + You've successfully switched to the new Amnezia Premium subscription! + + + + + Old keys will no longer work. Please use your new subscription key to connect. +Thank you for staying with us! + + + + + Continue + واصل + + + Logging enabled تم تمكين التسجيل - + Split tunneling enabled تقسيم الانفاق مٌفعل - + Split tunneling disabled تقسيم الانفاق مٌعطل - + VPN protocol بروتوكول VPN - + Servers الخوادم @@ -575,42 +754,87 @@ Already installed containers were found on the server. All installed containers - + Server settings - + Port منفذ - + + I1 - First special junk packet + + + + + I2 - Second special junk packet + + + + + I3 - Third special junk packet + + + + + I4 - Fourth special junk packet + + + + + I5 - Fifth special junk packet + + + + + J1 - First controlled junk packet + + + + + J2 - Second controlled junk packet + + + + + J3 - Third controlled junk packet + + + + + Itime - Special handshake timeout + + + + Save احفظ - + Save settings? احفظ الإعدادات؟ - + Only the settings for this device will be changed - + Continue واصل - + Cancel إلغاء - + Unable change settings while there is an active connection لا يمكن تغيير الإعدادات أثناء وجود اتصال نشط @@ -628,12 +852,12 @@ Already installed containers were found on the server. All installed containers منفذ - + All users with whom you shared a connection with will no longer be able to connect to it. جميع المستخدمين الذين شاركت معهم اتصال لن يكونو قادرين علي الاتصال مرة اخري. - + Save احفظ @@ -678,42 +902,42 @@ Already installed containers were found on the server. All installed containers H2 - رأس حزمة الاستجابة السحرية - + H4 - Transport packet magic header H4 - رأس حزمة النقل السحرية - + H3 - Underload packet magic header H3 - رأس حزمة السحر غير المحمل - + The values of the H1-H4 fields must be unique يجب أن تكون قيم الحقول H1-H4 فريدة - + The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) يجب ألا تساوي قيمة الحقل S1 + حجم بدء الرسالة (148) S2 + حجم استجابة الرسالة (92) - + Save settings? احفظ الإعدادات؟ - + Continue واصل - + Cancel إلغاء - + Unable change settings while there is an active connection لا يمكن تغيير الإعدادات أثناء وجود اتصال نشط @@ -1114,12 +1338,17 @@ Already installed containers were found on the server. All installed containers متنكراً في حركة مرور من - + + Port + منفذ + + + Save احفظ - + Unable change settings while there is an active connection لا يمكن تغيير الإعدادات أثناء وجود اتصال نشط @@ -1532,7 +1761,7 @@ Already installed containers were found on the server. All installed containers - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -1849,7 +2078,7 @@ Already installed containers were found on the server. All installed containers - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -1885,31 +2114,16 @@ Already installed containers were found on the server. All installed containers Email - - - support@amnezia.org - - Email Billing & Orders - - - help@vpnpay.io - - Website موقع - - - amnezia.org - - Support @@ -1921,12 +2135,12 @@ Already installed containers were found on the server. All installed containers - + Support tag علامة الدعم - + Copied @@ -1954,37 +2168,37 @@ Already installed containers were found on the server. All installed containers تقسيم نفق التطبيق - + Mode وضع - + Remove احذف - + Continue واصل - + Cancel إلغاء - + application name اسم التطبيق - + Open executable file افتح ملف قابل للتنفيذ - + Executable files (*.*) ملفات قابلة للتنفيذ (*.*) @@ -2184,7 +2398,7 @@ Already installed containers were found on the server. All installed containers عندما يكون AmneziaDNS غير مٌثبت او غير مستخدم - + Allows you to use the VPN only for certain Apps يسمح لك بأستخدام ال VPN علي تطبيقات معينة @@ -2214,24 +2428,23 @@ Already installed containers were found on the server. All installed containers يسمح لك بتحديد اي موقع تريد الوصول له عن طريق ال VPN - + App-based split tunneling انقسام الانفاق القائم علي التطبيق - + KillSwitch - - Disables your internet if your encrypted VPN connection drops out for any reason. - يعطل اتصال الإنترنت الخاص بك إذا انقطع اتصال VPN المشفر لأي سبب من الأسباب. + + Blocks network connections without VPN + - - Cannot change KillSwitch settings during active connection - + Disables your internet if your encrypted VPN connection drops out for any reason. + يعطل اتصال الإنترنت الخاص بك إذا انقطع اتصال VPN المشفر لأي سبب من الأسباب. Cannot change killSwitch settings during active connection @@ -2301,6 +2514,155 @@ Already installed containers were found on the server. All installed containers تم حفظ الإعدادات + + PageSettingsKillSwitch + + + KillSwitch + + + + + Enable to ensure network traffic goes through a secure VPN tunnel, preventing accidental exposure of your IP and DNS queries if the connection drops + + + + + KillSwitch settings cannot be changed during an active connection + + + + + Soft KillSwitch + + + + + Internet access is blocked if the VPN disconnects unexpectedly + + + + + Strict KillSwitch + + + + + Internet connection is blocked even when VPN is turned off manually or hasn't started + + + + + Just a little heads-up + + + + + If the VPN disconnects or drops while Strict KillSwitch is enabled, internet access will be blocked. To restore access, reconnect VPN or disable/change the KillSwitch. + + + + + Continue + واصل + + + + Cancel + إلغاء + + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active. + + + + + PageSettingsKillSwitchExceptions + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active + + + + + Delete + + + + + Continue + واصل + + + + Cancel + إلغاء + + + + IPv4 address + + + + + Import / Export addresses + + + + + Import + استرد + + + + Save address list + + + + + Save addresses + + + + + + + Address files (*.json) + + + + + Import address list + + + + + Replace address list + + + + + + Open address file + + + + + Add imported addresses to existing ones + + + PageSettingsLogging @@ -2430,11 +2792,6 @@ Already installed containers were found on the server. All installed containers Do you want to clear server from Amnezia software? هل تريد حذف الخادم من Amnezia? - - - - - @@ -2516,6 +2873,11 @@ Already installed containers were found on the server. All installed containers Cannot reset API config during active connection لا يمكن إعادة تعيين تكوين API أثناء الاتصال النشط + + + Switch to the new Amnezia Premium subscription + + All installed AmneziaVPN services will still remain on the server. @@ -2569,11 +2931,6 @@ Already installed containers were found on the server. All installed containers Clear %1 profile? مسح ملف تعريف %1؟ - - - - - Unable to clear %1 profile while there is an active connection @@ -2658,27 +3015,27 @@ Already installed containers were found on the server. All installed containers لا يجب الولوج للعنواين المذكورة هنا من خلال ال VPN - + Split tunneling تقسيم الانفاق - + Mode وضع - + Remove احذف - + Continue واصل - + Cancel إلغاء @@ -2693,55 +3050,55 @@ Already installed containers were found on the server. All installed containers لا يمكن تغير إعدادات تقسيم الانفاق بينما هناك اتصال مٌفعل - + website or IP موقع او IP - + Import / Export Sites - + Import استرد - + Save site list احفظ قائمة المواقع - + Save sites احفظ المواقع - - - + + + Sites files (*.json) - + Import a list of sites استرد قائمة من المواقع - + Replace site list تبديل قائمة المواقع - - + + Open sites file افتح ملف المواقع - + Add imported sites to existing ones إضافة المواقع المستردة للمواقع الموجودة @@ -2795,117 +3152,140 @@ Already installed containers were found on the server. All installed containers PageSetupWizardConfigSource - + Connection الاتصال - + Settings إعدادات - + Enable logs + Export client logs + + + + + Save + احفظ + + + + Logs files (*.log) + ملفات الولوج (*.log) + + + + Logs file saved + تم حفظ ملف السجل + + + Support tag علامة الدعم - + Copied - + Insert the key, add a configuration file or scan the QR-code أدخل المفتاح، أضف ملف تكوين أو امسح رمز الاستجابة السريعة - + Insert key أدخل مفتاح - + Insert أدخل - + Continue واصل - + Other connection options اختيارات اتصال اخري - + Site Amnezia - + VPN by Amnezia VPN بواسطة Amnezia - + Connect to classic paid and free VPN services from Amnezia اتصل بخدمات VPN الكلاسيكية المدفوعة والمجانية من Amnezia - + Self-hosted VPN VPN ذاتية الاستضافة - + Configure Amnezia VPN on your own server قم بتكوين Amnezia VPN على الخادم الخاص بك - + Restore from backup استرجاع من ملف يحتوي علي نسخة احتياطية - + + + + - + Open backup file افتح ملف نسخ احتياطي - + Backup files (*.backup) ملفات نٌسخ احتياطية (*.backup) - + File with connection settings ملف إعدادات اتصال - + Open config file افتح ملف تكوين - + QR code رمز QR - + I have nothing ليس لدي اي شئ @@ -3718,7 +4098,7 @@ Already installed containers were found on the server. All installed containers - + SOCKS5 proxy server @@ -3769,58 +4149,58 @@ Already installed containers were found on the server. All installed containers المستخدم ليس عضوًا في مجموعة sudo - + SSH request was denied طلب SSH محظو - + SSH request was interrupted إنقطع طلب SSH - + SSH internal error مشكلة داخلية SSH - + Invalid private key or invalid passphrase entered مفتا ح خاص غير صحيح او عبارة مرور غير صحيحة - + The selected private key format is not supported, use openssh ED25519 key types or PEM key types التنسيق المٌحدد للمفتاح الخاص غير مدعوم, استخدم نوع مفتاح openssh ED25519 او نوع مفتاح PEM - + Timeout connecting to server انتهت مدة الاتصال بالخادم - + VPN connection error - - + + Error when retrieving configuration from API خطأ عند استرداد التكوين من API - + This config has already been added to the application هذا التكوين بالفعل تمت إضافتة للبرنامج - + ErrorCode: %1. - + OpenVPN config missing OpenVPN تكوين مفقود @@ -3860,138 +4240,158 @@ Already installed containers were found on the server. All installed containers - + + Docker error: runc doesn't work on cgroups v2 + + + + + Server error: cgroup mountpoint does not exist + + + + SCP error: Generic failure خطأ SCP: فشل عام - + OpenVPN management server error OpenVPN خطأ في إدارة الخادم - + OpenVPN executable missing OpenVPN executable مفقود - + Shadowsocks (ss-local) executable missing Shadowsocks (ss-local) executable مفقود - + Cloak (ck-client) executable missing Cloak (ck-client) executable مفقود - + Amnezia helper service error خطأ في خدمة مٌساعد Amnezia - + OpenSSL failed فشل OpenSSL - + Can't connect: another VPN connection is active لا يمكن الاتصال: هناك اتصال VPN اخر بالفعل يعمل - + Can't setup OpenVPN TAP network adapter لا يمك نتثبيت محول شبكة OpenVPN TAP - + VPN pool error: no available addresses VPN pool error: لا يوجد عنواين مٌتاحة - + The config does not contain any containers and credentials for connecting to the server التكوين لا يحتوي علي اي حاويات و اعتماد للأتصال بالخادم - + Unable to open config file - + VPN Protocols is not installed. Please install VPN container at first لم يتم تثبيت بروتوكولات VPN, من فضلك قم بتنزيل حاوية VPN اولاً - + In the response from the server, an empty config was received في الاستجابة من الخادم، تم تلقي تكوين فارغ - + SSL error occurred حدث خطأ SSL - + Server response timeout on api request انتهت مهلة استجابة الخادم عند طلب واجهة برمجة التطبيقات - + Missing AGW public key مفتاح AGW عام مفقود - + Failed to decrypt response payload - + Missing list of available services - + The limit of allowed configurations per subscription has been exceeded + A migration error has occurred. Please contact our technical support + + + + + Please update the application to use this feature + + + + QFile error: The file could not be opened خطأ QFile: لا يمكن فتح الملف - + QFile error: An error occurred when reading from the file خطأ QFile: ظهر خطأ اثناء القراءه من الملف - + QFile error: The file could not be accessed خطأ QFile: لا يمكن الوصول للملف - + QFile error: An unspecified error occurred خطأ QFile: ظهر خطأ غير محدد - + QFile error: A fatal error occurred خطأ QFile: حدث خطأ فادح - + QFile error: The operation was aborted خطأ QFile: تم إحباط العملية - + Internal error خطأ داخلي @@ -4002,7 +4402,7 @@ Already installed containers were found on the server. All installed containers - + Website in Tor network موقع في شبكة Tor @@ -4047,69 +4447,100 @@ Already installed containers were found on the server. All installed containers - - OpenVPN stands as one of the most popular and time-tested VPN protocols available. -It employs its unique security protocol, leveraging the strength of SSL/TLS for encryption and key exchange. Furthermore, OpenVPN's support for a multitude of authentication methods makes it versatile and adaptable, catering to a wide range of devices and operating systems. Due to its open-source nature, OpenVPN benefits from extensive scrutiny by the global community, which continually reinforces its security. With a strong balance of performance, security, and compatibility, OpenVPN remains a top choice for privacy-conscious individuals and businesses alike. - -* Available in the AmneziaVPN across all platforms -* Normal power consumption on mobile devices -* Flexible customisation to suit user needs to work with different operating systems and devices -* Recognised by DPI systems and therefore susceptible to blocking -* Can operate over both TCP and UDP network protocols. + + - - This is a combination of the OpenVPN protocol and the Cloak plugin designed specifically for protecting against detection. + + OpenVPN is one of the most popular and reliable VPN protocols. It uses SSL/TLS encryption, supports a wide variety of devices and operating systems, and is continuously improved by the community due to its open-source nature. It provides a good balance between speed and security but is easily recognized by DPI systems, making it susceptible to blocking. -OpenVPN provides a secure VPN connection by encrypting all internet traffic between the client and the server. +Features: +* Available on all AmneziaVPN platforms +* Normal battery consumption on mobile devices +* Flexible customization for various devices and OS +* Operates over both TCP and UDP protocols + + + + + Shadowsocks is based on the SOCKS5 protocol and encrypts connections using AEAD cipher. Although designed to be discreet, it doesn't mimic a standard HTTPS connection and can be detected by some DPI systems. Due to limited support in Amnezia, we recommend using the AmneziaWG protocol. -Cloak protects OpenVPN from detection. - -Cloak can modify packet metadata so that it completely masks VPN traffic as normal web traffic, and also protects the VPN from detection by Active Probing. This makes it very resistant to being detected - -Immediately after receiving the first data packet, Cloak authenticates the incoming connection. If authentication fails, the plugin masks the server as a fake website and your VPN becomes invisible to analysis systems. - -* Available in the AmneziaVPN across all platforms -* High power consumption on mobile devices -* Flexible settings -* Not recognised by detection systems -* Works over TCP network protocol, 443 port. +Features: +* Available in AmneziaVPN only on desktop platforms +* Customizable encryption protocol +* Detectable by some DPI systems +* Operates over TCP protocol - - A relatively new popular VPN protocol with a simplified architecture. -WireGuard provides stable VPN connection and high performance on all devices. It uses hard-coded encryption settings. WireGuard compared to OpenVPN has lower latency and better data transfer throughput. -WireGuard is very susceptible to detection and blocking due to its distinct packet signatures. Unlike some other VPN protocols that employ obfuscation techniques, the consistent signature patterns of WireGuard packets can be more easily identified and thus blocked by advanced Deep Packet Inspection (DPI) systems and other network monitoring tools. + + This combination includes the OpenVPN protocol and the Cloak plugin, specifically designed to protect against blocking. -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Easily recognised by DPI analysis systems, susceptible to blocking -* Works over UDP network protocol. +OpenVPN securely encrypts all internet traffic between your device and the server. + +The Cloak plugin further protects the connection from DPI detection. It modifies traffic metadata to disguise VPN traffic as regular web traffic and prevents detection through active probing. If an incoming connection fails authentication, Cloak serves a fake website, making your VPN invisible to traffic analysis systems. + +In regions with heavy internet censorship, we strongly recommend using OpenVPN with Cloak from your first connection. + +Features: +* Available on all AmneziaVPN platforms +* High power consumption on mobile devices +* Flexible configuration options +* Undetectable by DPI systems +* Operates over TCP protocol on port 443 + + + + + WireGuard is a modern, streamlined VPN protocol offering stable connectivity and excellent performance across all devices. It uses fixed encryption settings, delivering lower latency and higher data transfer speeds compared to OpenVPN. However, WireGuard is easily identifiable by DPI systems due to its distinctive packet signatures, making it susceptible to blocking. + +Features: +* Available on all AmneziaVPN platforms +* Low power consumption on mobile devices +* Minimal configuration required +* Easily detected by DPI systems (susceptible to blocking) +* Operates over UDP protocol + + + + + AmneziaWG is a modern VPN protocol based on WireGuard, combining simplified architecture with high performance across all devices. It addresses WireGuard's main vulnerability (easy detection by DPI systems) through advanced obfuscation techniques, making VPN traffic indistinguishable from regular internet traffic. + +AmneziaWG is an excellent choice for those seeking a fast, stealthy VPN connection. + +Features: +* Available on all AmneziaVPN platforms +* Low battery consumption on mobile devices +* Minimal settings required +* Undetectable by traffic analysis systems (DPI) +* Operates over UDP protocol - A modern iteration of the popular VPN protocol, AmneziaWG builds upon the foundation set by WireGuard, retaining its simplified architecture and high-performance capabilities across devices. -While WireGuard is known for its efficiency, it had issues with being easily detected due to its distinct packet signatures. AmneziaWG solves this problem by using better obfuscation methods, making its traffic blend in with regular internet traffic. -This means that AmneziaWG keeps the fast performance of the original while adding an extra layer of stealth, making it a great choice for those wanting a fast and discreet VPN connection. + REALITY is an innovative protocol developed by the creators of XRay, designed specifically to combat high levels of internet censorship. REALITY identifies censorship systems during the TLS handshake, redirecting suspicious traffic seamlessly to legitimate websites like google.com while providing genuine TLS certificates. This allows VPN traffic to blend indistinguishably with regular web traffic without special configuration. +Unlike older protocols such as VMess, VLESS, and XTLS-Vision, REALITY incorporates an advanced built-in "friend-or-foe" detection mechanism, effectively protecting against DPI and other traffic analysis methods. -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Not recognised by traffic analysis systems -* Works over UDP network protocol. +Features: +* Resistant to active probing and DPI detection +* No special configuration required to disguise traffic +* Highly effective in heavily censored regions +* Minimal battery consumption on devices +* Operates over TCP protocol - - The REALITY protocol, a pioneering development by the creators of XRay, is designed to provide the highest level of protection against detection through its innovative approach to security and privacy. -It uniquely identifies attackers during the TLS handshake phase, seamlessly operating as a proxy for legitimate clients while diverting attackers to genuine websites, thus presenting an authentic TLS certificate and data. -This advanced capability differentiates REALITY from similar technologies by its ability to disguise web traffic as coming from random, legitimate sites without the need for specific configurations. -Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REALITY's innovative "friend or foe" recognition at the TLS handshake enhances security. This makes REALITY a robust solution for maintaining internet freedom. + + IKEv2, combined with IPSec encryption, is a modern and reliable VPN protocol. It reconnects quickly when switching networks or devices, making it ideal for dynamic network environments. While it provides good security and speed, it's easily recognized by DPI systems and susceptible to blocking. + +Features: +* Available in AmneziaVPN only on Windows +* Low battery consumption on mobile devices +* Minimal configuration required +* Detectable by DPI analysis systems(easily blocked) +* Operates over UDP protocol(ports 500 and 4500) @@ -4207,7 +4638,7 @@ Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REAL على عكس البروتوكولات القديمة مثل VMess وVLESS ونقل XTLS-Vision، فإن التعرف المبتكر على "الصديق أو العدو" من REALITY عند مصافحة TLS يعزز الأمان ويتحايل على الكشف بواسطة أنظمة DPI المتطورة التي تستخدم تقنيات التحقيق النشطة. وهذا يجعل من REALITY حلاً قويًا للحفاظ على حرية الإنترنت في البيئات التي تخضع لرقابة صارمة. - + After installation, Amnezia will create a file storage on your server. You will be able to access it using @@ -4262,14 +4693,13 @@ It employs its unique security protocol, leveraging the strength of SSL/TLS for * يمكن ان يعمل علي بروتوكولات شبكة TCP و UDP. - Shadowsocks, inspired by the SOCKS5 protocol, safeguards the connection using the AEAD cipher. Although Shadowsocks is designed to be discreet and challenging to identify, it isn't identical to a standard HTTPS connection.However, certain traffic analysis systems might still detect a Shadowsocks connection. Due to limited support in Amnezia, it's recommended to use AmneziaWG protocol. * Available in the AmneziaVPN only on desktop platforms * Configurable encryption protocol * Detectable by some DPI systems * Works over TCP network protocol. - Shadowsocks, مستوحي من بروتوكول SOCKS5, يحمي الاتصال بأستعمال شفرة AEAD. كذلك Shadowsocks صٌمم كي يكون متحفظاً ويصعب تحديدة, إنه ليس مطابقًا لاتصال HTTPS القياسي. عمتاُ. بعض انظمة تحليل حركات المرور قد تتعرف علي اتصال Shadowsocks. بسبب الدعم المحدود في Amnezia, يٌنصح بأستخدام بروتوكول AmneziaWG. + Shadowsocks, مستوحي من بروتوكول SOCKS5, يحمي الاتصال بأستعمال شفرة AEAD. كذلك Shadowsocks صٌمم كي يكون متحفظاً ويصعب تحديدة, إنه ليس مطابقًا لاتصال HTTPS القياسي. عمتاُ. بعض انظمة تحليل حركات المرور قد تتعرف علي اتصال Shadowsocks. بسبب الدعم المحدود في Amnezia, يٌنصح بأستخدام بروتوكول AmneziaWG. * مٌتاح في AmneziaVPN عبر جميع المنصات * بروتوكول تشفير قابل للتكوين @@ -4297,7 +4727,6 @@ This means that AmneziaWG keeps the fast performance of the original while addin * يعمل عبر بروتوكول شبكة UDP. - IKEv2, paired with the IPSec encryption layer, stands as a modern and stable VPN protocol. One of its distinguishing features is its ability to swiftly switch between networks and devices, making it particularly adaptive in dynamic network environments. While it offers a blend of security, stability, and speed, it's essential to note that IKEv2 can be easily detected and is susceptible to blocking. @@ -4307,7 +4736,7 @@ While it offers a blend of security, stability, and speed, it's essential t * Minimal configuration * Recognised by DPI analysis systems * Works over UDP network protocol, ports 500 and 4500. - IKEv2, مقترن مع طبقة التشفير IPSec, يبقا بروتوكول VPN مستقر و حديث. + IKEv2, مقترن مع طبقة التشفير IPSec, يبقا بروتوكول VPN مستقر و حديث. من مميزاتةقدرته على التبديل بسرعة بين الشبكات والأجهزة، مما يجعله قابلاً للتكيف بشكل خاص في بيئات الشبكات الديناميكية. *. مٌتاح في AmneziaVPN فقط علي منصة وندوز @@ -4317,7 +4746,7 @@ While it offers a blend of security, stability, and speed, it's essential t * يعمل عبر بروتوكول شبكة UDP, منفذ 500 و منفذ 4500. - + DNS Service خدمة ال DNS @@ -4554,12 +4983,12 @@ While it offers a blend of security, stability, and speed, it's essential t SettingsController - + Backup file is corrupted ملف النسخه الاحتياطيه تالف - + All settings have been reset to default values تم استرجاع جميع الإعدادات للإعدادات الافتراضية @@ -4691,7 +5120,7 @@ While it offers a blend of security, stability, and speed, it's essential t VpnConnection - + Mbps @@ -4758,12 +5187,12 @@ While it offers a blend of security, stability, and speed, it's essential t أريد تجاوز الرقابة. يوصى بهذا الخيار في معظم الحالات. - + Automatic - + AmneziaWG protocol will be installed. It provides high connection speed and ensures stable operation even in the most challenging network conditions. diff --git a/client/translations/amneziavpn_fa_IR.ts b/client/translations/amneziavpn_fa_IR.ts index c1155b9b..e9033f31 100644 --- a/client/translations/amneziavpn_fa_IR.ts +++ b/client/translations/amneziavpn_fa_IR.ts @@ -9,6 +9,54 @@ + + AllowedDnsController + + + The address does not look like a valid IP address + + + + + New DNS server added: %1 + + + + + DNS server already exists: %1 + + + + + DNS server removed: %1 + + + + + Can't open file: %1 + فایل باز نشد: %1 + + + + Failed to parse JSON data from file: %1 + مشکل در تحلیل داده‎های JSON در فایل: %1 + + + + The JSON data is not an array in file: %1 + داده‎های JSON در فایل به صورت آرایه نیستند: %1 + + + + Import completed + بارگذاری کامل شد + + + + Export completed + خروجی گرفتن کامل شد + + ApiAccountInfoModel @@ -33,39 +81,131 @@ - + Free unlimited access to a basic set of websites such as Facebook, Instagram, Twitter (X), Discord, Telegram and more. YouTube is not included in the free plan. - - - amnezia_free_support_bot - - - - - amnezia_premium_support_bot - - ApiConfigsController - + %1 installed successfully. %1 با موفقیت نصب شد. - + API config reloaded پیکربندی API دوباره بارگذاری شد. - + Successfully changed the country of connection to %1 کشور اتصال با موفقیت به %1 تغییر یافت. + + ApiPremV1MigrationDrawer + + + Switch to the new Amnezia Premium subscription + + + + + We'll preserve all remaining days of your current subscription and give you an extra month as a thank you. + + + + + This new subscription type will be actively developed with more locations and features added regularly. Currently available: + + + + + <li>13 locations (with more coming soon)</li> + + + + + <li>Easier switching between countries in the app</li> + + + + + <li>Personal dashboard to manage your subscription</li> + + + + + Old keys will be deactivated after switching. + + + + + Email + + + + + mail@example.com + + + + + No old format subscriptions for a given email + + + + + Enter the email you used for your current subscription + + + + + + Continue + + + + + Remind me later + + + + + Don't remind me again + + + + + No more reminders? You can always switch to the new format in the server settings + + + + + Cancel + + + + + ApiPremV1SubListDrawer + + + Choose Subscription + + + + + Order ID: + + + + + Purchase Date: + + + ApiServicesModel @@ -97,7 +237,7 @@ - AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan. + Amnezia Free provides unlimited, free access to a basic set of websites and apps, including Facebook, Instagram, Twitter (X), Discord, Telegram, and more. YouTube is not included in the free plan. @@ -115,6 +255,11 @@ %1 days %1 روز + + + + + VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a> @@ -274,7 +419,7 @@ HomeContainersListView - + Unable change protocol while there is an active connection امکان تغییر پروتکل در هنگام متصل بودن وجود ندارد @@ -340,17 +485,17 @@ Can't be disabled for current server فایل پیکربندی نامعتبر است. - + Scanned %1 of %2. ارزیابی %1 از %2. - + This configuration contains an OpenVPN setup. OpenVPN configurations can include malicious scripts, so only add it if you fully trust the provider of this config. - + <br>In the imported configuration, potentially dangerous lines were found: @@ -362,71 +507,71 @@ Can't be disabled for current server InstallController - + %1 installed successfully. %1 با موفقیت نصب شد. - + %1 is already installed on the server. %1 در حال حاضر بر روی سرور نصب شده است. - + Added containers that were already installed on the server کانتینرهایی که بر روی سرور موجود بودند اضافه شدند - + Already installed containers were found on the server. All installed containers have been added to the application کانتینرهای نصب شده بر روی سرور شناسایی شدند. تمام کانتینترهای نصب شده به نرم افزار اضافه شدند - + Settings updated successfully تنظیمات با موفقیت به‎روز‎رسانی شدند - + Server '%1' was rebooted سرور %1 راه اندازی مجدد شد - + Server '%1' was removed سرور %1 حذف شد - + All containers from server '%1' have been removed تمام کانتینترها از سرور %1 حذف شدند - + %1 has been removed from the server '%2' %1 از سرور %2 حذف شد - + Api config removed پیکربندی API حذف شد. - + %1 cached profile cleared %1 پروفایل ذخیره شده پاک شد. - + Please login as the user لطفا به عنوان کاربر وارد شوید - + Server added successfully سرور با موفقیت اضافه شد @@ -508,6 +653,24 @@ Already installed containers were found on the server. All installed containers شبکه ناامن شناسایی شد: + + OtpCodeDrawer + + + OTP code was sent to your email + + + + + OTP Code + + + + + Continue + + + PageDeinstalling @@ -537,27 +700,43 @@ Already installed containers were found on the server. All installed containers PageHome - + + You've successfully switched to the new Amnezia Premium subscription! + + + + + Old keys will no longer work. Please use your new subscription key to connect. +Thank you for staying with us! + + + + + Continue + + + + Logging enabled لاگ‌برداری فعال شد - + Split tunneling enabled فعال شدن تونل تقسیم‌شده - + Split tunneling disabled تونل تقسیم‌شده غیرفعال شده - + VPN protocol پروتکل وی‎پی‎ان - + Servers سرورها @@ -579,42 +758,87 @@ Already installed containers were found on the server. All installed containers - + Server settings - + Port پورت - + + I1 - First special junk packet + + + + + I2 - Second special junk packet + + + + + I3 - Third special junk packet + + + + + I4 - Fourth special junk packet + + + + + I5 - Fifth special junk packet + + + + + J1 - First controlled junk packet + + + + + J2 - Second controlled junk packet + + + + + J3 - Third controlled junk packet + + + + + Itime - Special handshake timeout + + + + Save ذخیره - + Save settings? تنظیمات را ذخیره کن? - + Only the settings for this device will be changed - + Continue - + Cancel - + Unable change settings while there is an active connection نمی‌توان تنظیمات را تغییر داد در حالی که اتصال فعال است. @@ -640,12 +864,12 @@ Already installed containers were found on the server. All installed containers آیا میخواهید AmneziaWG از سرور حذف شود؟ - + All users with whom you shared a connection with will no longer be able to connect to it. همه کاربرانی که با آن‌ها ارتباطی به اشتراک گذاشته‌اید دیگر قادر به اتصال به آن نخواهند بود. - + Save ذخیره @@ -691,41 +915,41 @@ Already installed containers were found on the server. All installed containers - H4 - Transport packet magic header - - - - H3 - Underload packet magic header - + + H4 - Transport packet magic header + + + + The values of the H1-H4 fields must be unique - + The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) - + Save settings? تنظیمات را ذخیره کن? - + Continue ادامه - + Cancel کنسل - + Unable change settings while there is an active connection نمی‌توان تنظیمات را تغییر داد در حالی که اتصال فعال است. @@ -1154,12 +1378,17 @@ Already installed containers were found on the server. All installed containers به‌عنوان ترافیک از طرف زیر نمایش داده می‌شود - + + Port + پورت + + + Save ذخیره - + Unable change settings while there is an active connection نمی‌توان تنظیمات را تغییر داد در حالی که اتصال فعال است. @@ -1619,7 +1848,7 @@ Already installed containers were found on the server. All installed containers - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -1932,7 +2161,7 @@ Already installed containers were found on the server. All installed containers - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -1968,31 +2197,16 @@ Already installed containers were found on the server. All installed containers Email - - - support@amnezia.org - - Email Billing & Orders - - - help@vpnpay.io - - Website وب سایت - - - amnezia.org - - Support @@ -2004,12 +2218,12 @@ Already installed containers were found on the server. All installed containers - + Support tag - + Copied کپی شد @@ -2037,37 +2251,37 @@ Already installed containers were found on the server. All installed containers تقسیم تونلینگ برنامه‌ها - + Mode حالت - + Remove حذف - + Continue ادامه دهید - + Cancel کنسل - + application name نام برنامه - + Open executable file فایل اجرایی را باز کنید - + Executable files (*.*) فایل‌های اجرایی (*.*) @@ -2282,24 +2496,23 @@ Already installed containers were found on the server. All installed containers وقتی AmneziaDNS استفاده نشده یا نصب نشده است - + Allows you to use the VPN only for certain Apps به شما امکان می دهد از VPN فقط برای برخی برنامه ها استفاده کنید - + KillSwitch KillSwitch - - Disables your internet if your encrypted VPN connection drops out for any reason. - اگر به هر دلیلی اتصال VPN رمزگذاری شده شما قطع شود، اینترنت شما را غیرفعال می‌کند. + + Blocks network connections without VPN + - - Cannot change KillSwitch settings during active connection - + Disables your internet if your encrypted VPN connection drops out for any reason. + اگر به هر دلیلی اتصال VPN رمزگذاری شده شما قطع شود، اینترنت شما را غیرفعال می‌کند. Cannot change killSwitch settings during active connection @@ -2316,7 +2529,7 @@ Already installed containers were found on the server. All installed containers میتوانید مشخص کنید که چه سایت‎هایی از وی‎پی‎ان استفاده کنند - + App-based split tunneling جداسازی ترافیک بر اساس نرم‎افزار @@ -2384,6 +2597,155 @@ Already installed containers were found on the server. All installed containers ذخیره تنظیمات + + PageSettingsKillSwitch + + + KillSwitch + KillSwitch + + + + Enable to ensure network traffic goes through a secure VPN tunnel, preventing accidental exposure of your IP and DNS queries if the connection drops + + + + + KillSwitch settings cannot be changed during an active connection + + + + + Soft KillSwitch + + + + + Internet access is blocked if the VPN disconnects unexpectedly + + + + + Strict KillSwitch + + + + + Internet connection is blocked even when VPN is turned off manually or hasn't started + + + + + Just a little heads-up + + + + + If the VPN disconnects or drops while Strict KillSwitch is enabled, internet access will be blocked. To restore access, reconnect VPN or disable/change the KillSwitch. + + + + + Continue + + + + + Cancel + + + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active. + + + + + PageSettingsKillSwitchExceptions + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active + + + + + Delete + + + + + Continue + + + + + Cancel + + + + + IPv4 address + + + + + Import / Export addresses + + + + + Import + بارگذاری + + + + Save address list + + + + + Save addresses + + + + + + + Address files (*.json) + + + + + Import address list + + + + + Replace address list + + + + + + Open address file + + + + + Add imported addresses to existing ones + + + PageSettingsLogging @@ -2515,11 +2877,6 @@ Already installed containers were found on the server. All installed containers No new installed containers found کانتینر نصب شده جدیدی پیدا نشد - - - - - @@ -2606,6 +2963,11 @@ Already installed containers were found on the server. All installed containers Cannot reset API config during active connection نمی‌توان پیکربندی API را در حین اتصال فعال بازنشانی کرد. + + + Switch to the new Amnezia Premium subscription + + Remove server from application @@ -2664,11 +3026,6 @@ Already installed containers were found on the server. All installed containers Clear %1 profile? آیا می‌خواهید پروفایل %1 را پاک کنید؟ - - - - - Unable to clear %1 profile while there is an active connection @@ -2753,27 +3110,27 @@ Already installed containers were found on the server. All installed containers دسترسی به آدرس‎های لیست بدون وی‎پی‎ان - + Split tunneling جداسازی ترافیک - + Mode حالت - + Remove حذف - + Continue ادامه - + Cancel کنسل @@ -2788,55 +3145,55 @@ Already installed containers were found on the server. All installed containers تنها سایت‌های موجود در اینجا از طریق VPN دسترسی داده خواهند شد - + website or IP وب‌سایت یا آدرس IP - + Import / Export Sites وارد کردن / صادر کردن وب‌سایت‌ها - + Import بارگذاری - + Save site list ذخیره لیست سایت‎ها - + Save sites ذخیره سایت‎ها - - - + + + Sites files (*.json) Sites files (*.json) - + Import a list of sites بارگذاری لیست سایت‎ها - + Replace site list جایگزین کردن لیست سایت - - + + Open sites file باز کردن فایل سایت‎ها - + Add imported sites to existing ones اضافه کردن سایت‎های بارگذاری شده به سایت‎های موجود @@ -2910,7 +3267,7 @@ It's okay as long as it's from someone you trust. چی داری؟ - + File with connection settings فایل شامل تنظیمات اتصال @@ -2919,112 +3276,135 @@ It's okay as long as it's from someone you trust. فایل شامل تنظیمات اتصال یا بک‎آپ - + Connection ارتباط - + Settings تنظیمات - + Enable logs + Export client logs + + + + + Save + ذخیره + + + + Logs files (*.log) + Logs files (*.log) + + + + Logs file saved + فایل گزارشات ذخیره شد + + + Support tag - + Copied کپی شد - + Insert the key, add a configuration file or scan the QR-code کلید را وارد کنید، فایل پیکربندی را اضافه کنید یا کد QR را اسکن کنید - + Insert key کلید را وارد کنید - + Insert وارد کردن - + Continue ادامه دهید - + Other connection options گزینه‌های اتصال دیگر - + Site Amnezia - + VPN by Amnezia VPN توسط Amnezia - + Connect to classic paid and free VPN services from Amnezia اتصال به سرویس‌های VPN کلاسیک پولی و رایگان از Amnezia - + Self-hosted VPN Self-hosted VPN - + Configure Amnezia VPN on your own server پیکربندی VPN Amnezia بر روی سرور خودتان - + Restore from backup بازیابی از پشتیبان - + + + + - + Open backup file باز کردن فایل پشتیبان - + Backup files (*.backup) Backup files (*.backup) - + Open config file باز کردن فایل تنظیمات - + QR code QR-Code - + I have nothing من هیچی ندارم @@ -3903,32 +4283,32 @@ It's okay as long as it's from someone you trust. کاربر عضو گروه sudo نیست - + SSH request was denied SSH request was denied - + SSH request was interrupted SSH request was interrupted - + SSH internal error SSH internal error - + Invalid private key or invalid passphrase entered Invalid private key or invalid passphrase entered - + The selected private key format is not supported, use openssh ED25519 key types or PEM key types The selected private key format is not supported, use openssh ED25519 key types or PEM key types - + Timeout connecting to server Timeout connecting to server @@ -3985,33 +4365,33 @@ It's okay as long as it's from someone you trust. Sftp error: No media was in remote drive - + The config does not contain any containers and credentials for connecting to the server تنظیمات شامل هیچ کانتینر یا اعتبارنامه‎ای برای اتصال به سرور نیست - + VPN connection error خطای اتصال VPN - - + + Error when retrieving configuration from API خطا هنگام بازیابی پیکربندی از API - + This config has already been added to the application این پیکربندی قبلاً به برنامه اضافه شده است - + ErrorCode: %1. کد خطا: %1. - + OpenVPN config missing OpenVPN config missing @@ -4051,134 +4431,154 @@ It's okay as long as it's from someone you trust. - + + Docker error: runc doesn't work on cgroups v2 + + + + + Server error: cgroup mountpoint does not exist + + + + SCP error: Generic failure SCP error: Generic failure - + OpenVPN management server error OpenVPN management server error - + OpenVPN executable missing OpenVPN executable missing - + Shadowsocks (ss-local) executable missing Shadowsocks (ss-local) executable missing - + Cloak (ck-client) executable missing Cloak (ck-client) executable missing - + Amnezia helper service error Amnezia helper service error - + OpenSSL failed OpenSSL failed - + Can't connect: another VPN connection is active Can't connect: another VPN connection is active - + Can't setup OpenVPN TAP network adapter Can't setup OpenVPN TAP network adapter - + VPN pool error: no available addresses VPN pool error: no available addresses - + Unable to open config file - + VPN Protocols is not installed. Please install VPN container at first پروتکل وی‎پی‎ان نصب نشده است لطفا کانتینر وی‎پی‎ان را نصب کنید - + In the response from the server, an empty config was received در پاسخ از سرور، پیکربندی خالی دریافت شد - + SSL error occurred SSL error occurred - + Server response timeout on api request Server response timeout on api request - + Missing AGW public key - + Failed to decrypt response payload - + Missing list of available services - + The limit of allowed configurations per subscription has been exceeded - QFile error: The file could not be opened + A migration error has occurred. Please contact our technical support - QFile error: An error occurred when reading from the file - - - - - QFile error: The file could not be accessed - - - - - QFile error: An unspecified error occurred + Please update the application to use this feature - QFile error: A fatal error occurred + QFile error: The file could not be opened - QFile error: The operation was aborted + QFile error: An error occurred when reading from the file + + + + + QFile error: The file could not be accessed + + + + + QFile error: An unspecified error occurred + + + + + QFile error: A fatal error occurred + QFile error: The operation was aborted + + + + Internal error Internal error @@ -4279,7 +4679,6 @@ REALITY به‌طور منحصربه‌فردی سانسورچیان را در این قابلیت پیشرفته، REALITY را از فناوری‌های مشابه متمایز می‌کند، زیرا می‌تواند ترافیک وب را بدون نیاز به پیکربندی‌های خاص، به‌عنوان ترافیک از سایت‌های تصادفی و معتبر جا بزند. برخلاف پروتکل‌های قدیمی‌تر مانند VMess، VLESS و انتقال XTLS-Vision، تشخیص نوآورانه "دوست یا دشمن" REALITY در مرحله دست‌دهی TLS امنیت را افزایش داده و از شناسایی توسط سیستم‌های پیشرفته DPI که از تکنیک‌های پروب فعال استفاده می‌کنند، جلوگیری می‌کند. این ویژگی REALITY را به یک راه‌حل قوی برای حفظ آزادی اینترنت در محیط‌هایی با سانسور شدید تبدیل می‌کند. - IKEv2, paired with the IPSec encryption layer, stands as a modern and stable VPN protocol. One of its distinguishing features is its ability to swiftly switch between networks and devices, making it particularly adaptive in dynamic network environments. While it offers a blend of security, stability, and speed, it's essential to note that IKEv2 can be easily detected and is susceptible to blocking. @@ -4289,7 +4688,7 @@ While it offers a blend of security, stability, and speed, it's essential t * Minimal configuration * Recognised by DPI analysis systems * Works over UDP network protocol, ports 500 and 4500. - پروتکل IKEv2 به همراه لایه رمزنگاری IPSec به عنوان پروتکل وی‎پی‎ان مدرن و پایدار است. + پروتکل IKEv2 به همراه لایه رمزنگاری IPSec به عنوان پروتکل وی‎پی‎ان مدرن و پایدار است. یکی از قابلیت‎‎های متمایز این پروتکل قابلیت سوییچ بین شبکه‎ها و دستگاه‎هاست که قابلیت انطباق بالایی در محیط شبکه‎های دینامیک را دارد در حالیکه ترکیبی از امنیت، پایداری و سرعت را ارائه میدهد اما مهم است که اشاره کنیم IKEv2 به راحتی قابل تشخیص در شبکه و بلاک شدن میباشد. @@ -4300,7 +4699,7 @@ While it offers a blend of security, stability, and speed, it's essential t * روی پروتکل شبکه UDP، پورت‎های 500 و 4500 کار می‎کند. - + DNS Service سرویس DNS @@ -4311,7 +4710,7 @@ While it offers a blend of security, stability, and speed, it's essential t - + Website in Tor network وب سایت در شبکه Tor @@ -4351,69 +4750,100 @@ While it offers a blend of security, stability, and speed, it's essential t - - OpenVPN stands as one of the most popular and time-tested VPN protocols available. -It employs its unique security protocol, leveraging the strength of SSL/TLS for encryption and key exchange. Furthermore, OpenVPN's support for a multitude of authentication methods makes it versatile and adaptable, catering to a wide range of devices and operating systems. Due to its open-source nature, OpenVPN benefits from extensive scrutiny by the global community, which continually reinforces its security. With a strong balance of performance, security, and compatibility, OpenVPN remains a top choice for privacy-conscious individuals and businesses alike. - -* Available in the AmneziaVPN across all platforms -* Normal power consumption on mobile devices -* Flexible customisation to suit user needs to work with different operating systems and devices -* Recognised by DPI systems and therefore susceptible to blocking -* Can operate over both TCP and UDP network protocols. + + - - This is a combination of the OpenVPN protocol and the Cloak plugin designed specifically for protecting against detection. + + OpenVPN is one of the most popular and reliable VPN protocols. It uses SSL/TLS encryption, supports a wide variety of devices and operating systems, and is continuously improved by the community due to its open-source nature. It provides a good balance between speed and security but is easily recognized by DPI systems, making it susceptible to blocking. -OpenVPN provides a secure VPN connection by encrypting all internet traffic between the client and the server. +Features: +* Available on all AmneziaVPN platforms +* Normal battery consumption on mobile devices +* Flexible customization for various devices and OS +* Operates over both TCP and UDP protocols + + + + + Shadowsocks is based on the SOCKS5 protocol and encrypts connections using AEAD cipher. Although designed to be discreet, it doesn't mimic a standard HTTPS connection and can be detected by some DPI systems. Due to limited support in Amnezia, we recommend using the AmneziaWG protocol. -Cloak protects OpenVPN from detection. - -Cloak can modify packet metadata so that it completely masks VPN traffic as normal web traffic, and also protects the VPN from detection by Active Probing. This makes it very resistant to being detected - -Immediately after receiving the first data packet, Cloak authenticates the incoming connection. If authentication fails, the plugin masks the server as a fake website and your VPN becomes invisible to analysis systems. - -* Available in the AmneziaVPN across all platforms -* High power consumption on mobile devices -* Flexible settings -* Not recognised by detection systems -* Works over TCP network protocol, 443 port. +Features: +* Available in AmneziaVPN only on desktop platforms +* Customizable encryption protocol +* Detectable by some DPI systems +* Operates over TCP protocol - - A relatively new popular VPN protocol with a simplified architecture. -WireGuard provides stable VPN connection and high performance on all devices. It uses hard-coded encryption settings. WireGuard compared to OpenVPN has lower latency and better data transfer throughput. -WireGuard is very susceptible to detection and blocking due to its distinct packet signatures. Unlike some other VPN protocols that employ obfuscation techniques, the consistent signature patterns of WireGuard packets can be more easily identified and thus blocked by advanced Deep Packet Inspection (DPI) systems and other network monitoring tools. + + This combination includes the OpenVPN protocol and the Cloak plugin, specifically designed to protect against blocking. -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Easily recognised by DPI analysis systems, susceptible to blocking -* Works over UDP network protocol. +OpenVPN securely encrypts all internet traffic between your device and the server. + +The Cloak plugin further protects the connection from DPI detection. It modifies traffic metadata to disguise VPN traffic as regular web traffic and prevents detection through active probing. If an incoming connection fails authentication, Cloak serves a fake website, making your VPN invisible to traffic analysis systems. + +In regions with heavy internet censorship, we strongly recommend using OpenVPN with Cloak from your first connection. + +Features: +* Available on all AmneziaVPN platforms +* High power consumption on mobile devices +* Flexible configuration options +* Undetectable by DPI systems +* Operates over TCP protocol on port 443 + + + + + WireGuard is a modern, streamlined VPN protocol offering stable connectivity and excellent performance across all devices. It uses fixed encryption settings, delivering lower latency and higher data transfer speeds compared to OpenVPN. However, WireGuard is easily identifiable by DPI systems due to its distinctive packet signatures, making it susceptible to blocking. + +Features: +* Available on all AmneziaVPN platforms +* Low power consumption on mobile devices +* Minimal configuration required +* Easily detected by DPI systems (susceptible to blocking) +* Operates over UDP protocol + + + + + AmneziaWG is a modern VPN protocol based on WireGuard, combining simplified architecture with high performance across all devices. It addresses WireGuard's main vulnerability (easy detection by DPI systems) through advanced obfuscation techniques, making VPN traffic indistinguishable from regular internet traffic. + +AmneziaWG is an excellent choice for those seeking a fast, stealthy VPN connection. + +Features: +* Available on all AmneziaVPN platforms +* Low battery consumption on mobile devices +* Minimal settings required +* Undetectable by traffic analysis systems (DPI) +* Operates over UDP protocol - A modern iteration of the popular VPN protocol, AmneziaWG builds upon the foundation set by WireGuard, retaining its simplified architecture and high-performance capabilities across devices. -While WireGuard is known for its efficiency, it had issues with being easily detected due to its distinct packet signatures. AmneziaWG solves this problem by using better obfuscation methods, making its traffic blend in with regular internet traffic. -This means that AmneziaWG keeps the fast performance of the original while adding an extra layer of stealth, making it a great choice for those wanting a fast and discreet VPN connection. + REALITY is an innovative protocol developed by the creators of XRay, designed specifically to combat high levels of internet censorship. REALITY identifies censorship systems during the TLS handshake, redirecting suspicious traffic seamlessly to legitimate websites like google.com while providing genuine TLS certificates. This allows VPN traffic to blend indistinguishably with regular web traffic without special configuration. +Unlike older protocols such as VMess, VLESS, and XTLS-Vision, REALITY incorporates an advanced built-in "friend-or-foe" detection mechanism, effectively protecting against DPI and other traffic analysis methods. -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Not recognised by traffic analysis systems -* Works over UDP network protocol. +Features: +* Resistant to active probing and DPI detection +* No special configuration required to disguise traffic +* Highly effective in heavily censored regions +* Minimal battery consumption on devices +* Operates over TCP protocol - - The REALITY protocol, a pioneering development by the creators of XRay, is designed to provide the highest level of protection against detection through its innovative approach to security and privacy. -It uniquely identifies attackers during the TLS handshake phase, seamlessly operating as a proxy for legitimate clients while diverting attackers to genuine websites, thus presenting an authentic TLS certificate and data. -This advanced capability differentiates REALITY from similar technologies by its ability to disguise web traffic as coming from random, legitimate sites without the need for specific configurations. -Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REALITY's innovative "friend or foe" recognition at the TLS handshake enhances security. This makes REALITY a robust solution for maintaining internet freedom. + + IKEv2, combined with IPSec encryption, is a modern and reliable VPN protocol. It reconnects quickly when switching networks or devices, making it ideal for dynamic network environments. While it provides good security and speed, it's easily recognized by DPI systems and susceptible to blocking. + +Features: +* Available in AmneziaVPN only on Windows +* Low battery consumption on mobile devices +* Minimal configuration required +* Detectable by DPI analysis systems(easily blocked) +* Operates over UDP protocol(ports 500 and 4500) @@ -4461,14 +4891,13 @@ It employs its unique security protocol, leveraging the strength of SSL/TLS for * امکان کار بر روی دو پروتکل TCP و UDP - Shadowsocks, inspired by the SOCKS5 protocol, safeguards the connection using the AEAD cipher. Although Shadowsocks is designed to be discreet and challenging to identify, it isn't identical to a standard HTTPS connection.However, certain traffic analysis systems might still detect a Shadowsocks connection. Due to limited support in Amnezia, it's recommended to use AmneziaWG protocol. * Available in the AmneziaVPN only on desktop platforms * Configurable encryption protocol * Detectable by some DPI systems * Works over TCP network protocol. - پروتکل Shadowsocks، الهام گرفته از پروتکل Socks5، اتصال را با استفاده از رمزگذاری AEAD امن میکند. اگرچه Shadowsocks طوری طراحی شده که برای شناسایی در شبکه چالش‎برانگیز باشد و محتاط عمل کند اما این پروتکل مانند یک اتصال استاندارد HTTPS نیست و برخی از سیستم‎های تحلیل ترافیک مشخص ممکن است بتوانند اتصال Shadowsocks را شناسایی کنند. به دلیل محدودیت پشتیبانی در Amnezia پیشنهاد می‎شود که از َAmneziaWG استفاده شود. + پروتکل Shadowsocks، الهام گرفته از پروتکل Socks5، اتصال را با استفاده از رمزگذاری AEAD امن میکند. اگرچه Shadowsocks طوری طراحی شده که برای شناسایی در شبکه چالش‎برانگیز باشد و محتاط عمل کند اما این پروتکل مانند یک اتصال استاندارد HTTPS نیست و برخی از سیستم‎های تحلیل ترافیک مشخص ممکن است بتوانند اتصال Shadowsocks را شناسایی کنند. به دلیل محدودیت پشتیبانی در Amnezia پیشنهاد می‎شود که از َAmneziaWG استفاده شود. * فقط بر روی پلتفرم دسکتاپ بر روی Amnezia قابل دسترس است * پروتکل رمزنگاری قابل پیکربندی @@ -4496,7 +4925,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin * کار بر روی پروتکل شبکه UDP - + After installation, Amnezia will create a file storage on your server. You will be able to access it using @@ -4522,7 +4951,7 @@ For more detailed information, you can - + SOCKS5 proxy server سرور پروکسی SOCKS5 @@ -4759,7 +5188,7 @@ For more detailed information, you can SettingsController - + All settings have been reset to default values تمام تنظیمات به مقادیر پیش فرض ریست شد @@ -4768,7 +5197,7 @@ For more detailed information, you can پروفایل ذخیره شده پاک شد - + Backup file is corrupted فایل بک‎آپ خراب شده است @@ -4900,7 +5329,7 @@ For more detailed information, you can VpnConnection - + Mbps Mbps @@ -4975,12 +5404,12 @@ For more detailed information, you can اکثر پروتکل‎های وی‎پی‎ان مسدود شده‎اند. در مواردی که بقیه گزینه‎ها کار نمی‎کنند توصی می‎شود. - + Automatic - + AmneziaWG protocol will be installed. It provides high connection speed and ensures stable operation even in the most challenging network conditions. diff --git a/client/translations/amneziavpn_hi_IN.ts b/client/translations/amneziavpn_hi_IN.ts index 18dcfc65..9d5a91bb 100644 --- a/client/translations/amneziavpn_hi_IN.ts +++ b/client/translations/amneziavpn_hi_IN.ts @@ -9,6 +9,54 @@ + + AllowedDnsController + + + The address does not look like a valid IP address + + + + + New DNS server added: %1 + + + + + DNS server already exists: %1 + + + + + DNS server removed: %1 + + + + + Can't open file: %1 + फ़ाइल नहीं खुल सकती: %1 + + + + Failed to parse JSON data from file: %1 + फ़ाइल से JSON डेटा पार्स करने में विफल:%1 + + + + The JSON data is not an array in file: %1 + JSON डेटा फ़ाइल में कोई सरणी नहीं है: %1 + + + + Import completed + आयात पूरा हुआ + + + + Export completed + निर्यात पूरा हुआ + + ApiAccountInfoModel @@ -33,39 +81,131 @@ - + Free unlimited access to a basic set of websites such as Facebook, Instagram, Twitter (X), Discord, Telegram and more. YouTube is not included in the free plan. - - - amnezia_free_support_bot - - - - - amnezia_premium_support_bot - - ApiConfigsController - + %1 installed successfully. - + API config reloaded - + Successfully changed the country of connection to %1 + + ApiPremV1MigrationDrawer + + + Switch to the new Amnezia Premium subscription + + + + + We'll preserve all remaining days of your current subscription and give you an extra month as a thank you. + + + + + This new subscription type will be actively developed with more locations and features added regularly. Currently available: + + + + + <li>13 locations (with more coming soon)</li> + + + + + <li>Easier switching between countries in the app</li> + + + + + <li>Personal dashboard to manage your subscription</li> + + + + + Old keys will be deactivated after switching. + + + + + Email + + + + + mail@example.com + + + + + No old format subscriptions for a given email + + + + + Enter the email you used for your current subscription + + + + + + Continue + जारी रखना + + + + Remind me later + + + + + Don't remind me again + + + + + No more reminders? You can always switch to the new format in the server settings + + + + + Cancel + रद्द करना + + + + ApiPremV1SubListDrawer + + + Choose Subscription + + + + + Order ID: + + + + + Purchase Date: + + + ApiServicesModel @@ -81,7 +221,7 @@ - AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan. + Amnezia Free provides unlimited, free access to a basic set of websites and apps, including Facebook, Instagram, Twitter (X), Discord, Telegram, and more. YouTube is not included in the free plan. @@ -99,6 +239,11 @@ %1 days + + + + + VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a> @@ -257,7 +402,7 @@ HomeContainersListView - + Unable change protocol while there is an active connection सक्रिय कनेक्शन होने पर प्रोटोकॉल बदलने में असमर्थ @@ -320,17 +465,17 @@ Can't be disabled for current server अमान्य कॉन्फ़िगरेशन फ़ाइल - + Scanned %1 of %2. %2 में से %1 स्कैन किया गया. - + This configuration contains an OpenVPN setup. OpenVPN configurations can include malicious scripts, so only add it if you fully trust the provider of this config. - + <br>In the imported configuration, potentially dangerous lines were found: @@ -338,71 +483,71 @@ Can't be disabled for current server InstallController - + %1 installed successfully. %1 सफलतापूर्वक स्थापित हुआ. - + %1 is already installed on the server. %1 पहले से ही सर्वर पर स्थापित है. - + Added containers that were already installed on the server सर्वर पर पहले से स्थापित कंटेनर जोड़े गए - + Already installed containers were found on the server. All installed containers have been added to the application सर्वर पर पहले से स्थापित कंटेनर पाए गए। सभी स्थापित कंटेनरों को एप्लिकेशन में जोड़ दिया गया है - + Settings updated successfully सेटिंग्स सफलतापूर्वक अपडेट हो गईं - + Server '%1' was rebooted सर्वर '%1' रीबूट किया गया था - + Server '%1' was removed सर्वर '%1' रीबूट किया गया था - + All containers from server '%1' have been removed सर्वर '%1' से सभी कंटेनर हटा दिए गए हैं - + %1 has been removed from the server '%2' %1 को सर्वर '%2' से हटा दिया गया है - + Api config removed - + %1 cached profile cleared %1 कैश्ड प्रोफ़ाइल साफ़ की गई - + Please login as the user कृपया उपयोगकर्ता के रूप में लॉगिन करें - + Server added successfully सर्वर सफलतापूर्वक जोड़ा गया @@ -472,6 +617,24 @@ Already installed containers were found on the server. All installed containers असुरक्षित नेटवर्क का पता चला: + + OtpCodeDrawer + + + OTP code was sent to your email + + + + + OTP Code + + + + + Continue + जारी रखना + + PageDeinstalling @@ -501,27 +664,43 @@ Already installed containers were found on the server. All installed containers PageHome - + + You've successfully switched to the new Amnezia Premium subscription! + + + + + Old keys will no longer work. Please use your new subscription key to connect. +Thank you for staying with us! + + + + + Continue + जारी रखना + + + Logging enabled लॉगिंग सक्षम - + Split tunneling enabled स्प्लिट टनलिंग सक्षम - + Split tunneling disabled स्प्लिट टनलिंग अक्षम - + VPN protocol VPN प्रोटोकॉल - + Servers सर्वर @@ -543,42 +722,87 @@ Already installed containers were found on the server. All installed containers एमटीयू - + Server settings - + Port - + + I1 - First special junk packet + + + + + I2 - Second special junk packet + + + + + I3 - Third special junk packet + + + + + I4 - Fourth special junk packet + + + + + I5 - Fifth special junk packet + + + + + J1 - First controlled junk packet + + + + + J2 - Second controlled junk packet + + + + + J3 - Third controlled junk packet + + + + + Itime - Special handshake timeout + + + + Save सहेजें - + Save settings? सेटिंग्स सेव करें? - + Only the settings for this device will be changed - + Continue जारी रखना - + Cancel रद्द करना - + Unable change settings while there is an active connection सक्रिय कनेक्शन होने पर सेटिंग बदलने में असमर्थ @@ -604,6 +828,41 @@ Already installed containers were found on the server. All installed containers MTU एमटीयू + + + Save + सहेजें + + + + The values of the H1-H4 fields must be unique + H1-H4 फ़ील्ड का मान अद्वितीय होना चाहिए + + + + The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) + फ़ील्ड S1 + संदेश आरंभ आकार (148) का मान S2 + संदेश प्रतिक्रिया आकार (92) के बराबर नहीं होना चाहिए + + + + Save settings? + सेटिंग्स सेव करें? + + + + All users with whom you shared a connection with will no longer be able to connect to it. + वे सभी उपयोगकर्ता जिनके साथ आपने कनेक्शन साझा किया था, वे अब इससे कनेक्ट नहीं हो पाएंगे. + + + + Unable change settings while there is an active connection + सक्रिय कनेक्शन होने पर सेटिंग बदलने में असमर्थ + + + + Continue + जारी रखना + Jc - Junk packet count @@ -641,51 +900,16 @@ Already installed containers were found on the server. All installed containers - H4 - Transport packet magic header - - - - H3 - Underload packet magic header - - Save - सहेजें + + H4 - Transport packet magic header + - - The values of the H1-H4 fields must be unique - H1-H4 फ़ील्ड का मान अद्वितीय होना चाहिए - - - - The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) - फ़ील्ड S1 + संदेश आरंभ आकार (148) का मान S2 + संदेश प्रतिक्रिया आकार (92) के बराबर नहीं होना चाहिए - - - - Save settings? - सेटिंग्स सेव करें? - - - - All users with whom you shared a connection with will no longer be able to connect to it. - वे सभी उपयोगकर्ता जिनके साथ आपने कनेक्शन साझा किया था, वे अब इससे कनेक्ट नहीं हो पाएंगे. - - - - Unable change settings while there is an active connection - सक्रिय कनेक्शन होने पर सेटिंग बदलने में असमर्थ - - - - Continue - जारी रखना - - - + Cancel रद्द करना @@ -1090,12 +1314,17 @@ Already installed containers were found on the server. All installed containers से यातायात के रूप में प्रच्छन्न - + + Port + + + + Save सहेजें - + Unable change settings while there is an active connection सक्रिय कनेक्शन होने पर सेटिंग बदलने में असमर्थ @@ -1544,7 +1773,7 @@ Already installed containers were found on the server. All installed containers - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -1841,7 +2070,7 @@ Already installed containers were found on the server. All installed containers - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -1877,31 +2106,16 @@ Already installed containers were found on the server. All installed containers Email - - - support@amnezia.org - - Email Billing & Orders - - - help@vpnpay.io - - Website वेबसाइट - - - amnezia.org - - Support @@ -1913,12 +2127,12 @@ Already installed containers were found on the server. All installed containers - + Support tag - + Copied कॉपी किया गया @@ -1954,37 +2168,37 @@ Already installed containers were found on the server. All installed containers ऐप स्प्लिट टनलिंग - + Mode तरीका - + Remove निकालना - + Continue जारी रखना - + Cancel रद्द करना - + application name आवेदन का नाम - + Open executable file निष्पादन योग्य फ़ाइल खोलें - + Executable files (*.*) निष्पादनीय फाइल (*.*) @@ -2184,7 +2398,7 @@ Already installed containers were found on the server. All installed containers जब AmneziaDNS का उपयोग या स्थापित नहीं किया जाता है - + Allows you to use the VPN only for certain Apps आपको केवल कुछ ऐप्स के लिए वीपीएन का उपयोग करने की अनुमति देता है @@ -2214,24 +2428,23 @@ Already installed containers were found on the server. All installed containers आपको यह चुनने की अनुमति देता है कि आप वीपीएन के माध्यम से किन साइटों तक पहुंचना चाहते हैं - + App-based split tunneling ऐप-आधारित स्प्लिट टनलिंग - + KillSwitch स्विच बन्द कर दो - - Disables your internet if your encrypted VPN connection drops out for any reason. - यदि आपका एन्क्रिप्टेड वीपीएन कनेक्शन किसी भी कारण से बंद हो जाता है तो आपका इंटरनेट अक्षम कर देता है. + + Blocks network connections without VPN + - - Cannot change KillSwitch settings during active connection - + Disables your internet if your encrypted VPN connection drops out for any reason. + यदि आपका एन्क्रिप्टेड वीपीएन कनेक्शन किसी भी कारण से बंद हो जाता है तो आपका इंटरनेट अक्षम कर देता है. Cannot change killSwitch settings during active connection @@ -2301,6 +2514,155 @@ Already installed containers were found on the server. All installed containers सेटिंग्स को सहेजा गया + + PageSettingsKillSwitch + + + KillSwitch + स्विच बन्द कर दो + + + + Enable to ensure network traffic goes through a secure VPN tunnel, preventing accidental exposure of your IP and DNS queries if the connection drops + + + + + KillSwitch settings cannot be changed during an active connection + + + + + Soft KillSwitch + + + + + Internet access is blocked if the VPN disconnects unexpectedly + + + + + Strict KillSwitch + + + + + Internet connection is blocked even when VPN is turned off manually or hasn't started + + + + + Just a little heads-up + + + + + If the VPN disconnects or drops while Strict KillSwitch is enabled, internet access will be blocked. To restore access, reconnect VPN or disable/change the KillSwitch. + + + + + Continue + जारी रखना + + + + Cancel + रद्द करना + + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active. + + + + + PageSettingsKillSwitchExceptions + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active + + + + + Delete + + + + + Continue + जारी रखना + + + + Cancel + रद्द करना + + + + IPv4 address + + + + + Import / Export addresses + + + + + Import + आयात + + + + Save address list + + + + + Save addresses + + + + + + + Address files (*.json) + + + + + Import address list + + + + + Replace address list + + + + + + Open address file + + + + + Add imported addresses to existing ones + + + PageSettingsLogging @@ -2430,11 +2792,6 @@ Already installed containers were found on the server. All installed containers Do you want to clear server from Amnezia software? क्या आप एमनेज़िया सॉफ़्टवेयर से सर्वर साफ़ करना चाहते हैं? - - - - - @@ -2516,6 +2873,11 @@ Already installed containers were found on the server. All installed containers Cannot reset API config during active connection सक्रिय कनेक्शन के दौरान एपीआई कॉन्फिगरेशन को रीसेट नहीं किया जा सकता + + + Switch to the new Amnezia Premium subscription + + All installed AmneziaVPN services will still remain on the server. @@ -2569,11 +2931,6 @@ Already installed containers were found on the server. All installed containers Clear %1 profile? %1 प्रोफ़ाइल साफ़ करें? - - - - - Unable to clear %1 profile while there is an active connection @@ -2658,27 +3015,27 @@ Already installed containers were found on the server. All installed containers सूची के पतों को वीपीएन के माध्यम से एक्सेस नहीं किया जाना चाहिए - + Split tunneling विभाजित सुरंग - + Mode तरीका - + Remove निकालना - + Continue जारी रखना - + Cancel रद्द करना @@ -2693,55 +3050,55 @@ Already installed containers were found on the server. All installed containers सक्रिय कनेक्शन के दौरान स्प्लिट टनलिंग सेटिंग्स को नहीं बदला जा सकता - + website or IP वेबसाइट या आईपी - + Import / Export Sites आयात/निर्यात साइटें - + Import आयात - + Save site list साइट सूची सहेजें - + Save sites साइटें सहेजें - - - + + + Sites files (*.json) - + Import a list of sites साइटों की सूची आयात करें - + Replace site list साइट सूची बदलें - - + + Open sites file साइट फ़ाइल खोलें - + Add imported sites to existing ones आयातित साइटों को मौजूदा साइटों में जोड़ें @@ -2811,117 +3168,140 @@ Already installed containers were found on the server. All installed containers कनेक्शन सेटिंग्स वाली फ़ाइल - + Connection कनेक्शन - + Settings समायोजन - + Enable logs + Export client logs + + + + + Save + सहेजें + + + + Logs files (*.log) + लॉग फ़ाइलें (*.log) + + + + Logs file saved + लॉग फ़ाइल सहेजी गई + + + Support tag - + Copied कॉपी किया गया - + Insert the key, add a configuration file or scan the QR-code - + Insert key - + Insert डालना - + Continue जारी रखना - + Other connection options - + Site Amnezia - + VPN by Amnezia - + Connect to classic paid and free VPN services from Amnezia - + Self-hosted VPN - + Configure Amnezia VPN on your own server - + Restore from backup बैकअप से बहाल करना - + + + + - + Open backup file बैकअप फ़ाइल खोलें - + Backup files (*.backup) बैकअप फ़ाइलें (*.backup) - + File with connection settings कनेक्शन सेटिंग्स वाली फ़ाइल - + Open config file कॉन्फ़िग फ़ाइल खोलें - + QR code क्यू आर संहिता - + I have nothing मेरे पास कुछ नहीं है @@ -3765,7 +4145,7 @@ Already installed containers were found on the server. All installed containers - + SOCKS5 proxy server @@ -3851,195 +4231,215 @@ Already installed containers were found on the server. All installed containers - + + Docker error: runc doesn't work on cgroups v2 + + + + + Server error: cgroup mountpoint does not exist + + + + SSH request was denied SSH अनुरोध अस्वीकार कर दिया गया - + SSH request was interrupted SSH अनुरोध बाधित हो गया था - + SSH internal error SSH आंतरिक त्रुटि - + Invalid private key or invalid passphrase entered अमान्य निजी कुंजी या अमान्य पासफ़्रेज़ दर्ज किया गया - + The selected private key format is not supported, use openssh ED25519 key types or PEM key types चयनित निजी कुंजी प्रारूप समर्थित नहीं है, ओपनश ED25519 कुंजी प्रकार या PEM कुंजी प्रकार का उपयोग करें - + Timeout connecting to server सर्वर से कनेक्ट होने का समय समाप्त - + Unable to open config file - + VPN Protocols is not installed. Please install VPN container at first पीएन प्रोटोकॉल स्थापित नहीं है. कृपया पहले वीपीएन कंटेनर स्थापित करें - + VPN connection error VPN कनेक्शन त्रुटि - - + + Error when retrieving configuration from API एपीआई से कॉन्फ़िगरेशन पुनर्प्राप्त करते समय त्रुटि - + This config has already been added to the application यह कॉन्फ़िगरेशन पहले ही एप्लिकेशन में जोड़ा जा चुका है - + In the response from the server, an empty config was received - + SSL error occurred - + Server response timeout on api request - + Missing AGW public key - + Failed to decrypt response payload - + Missing list of available services - + The limit of allowed configurations per subscription has been exceeded - + + A migration error has occurred. Please contact our technical support + + + + + Please update the application to use this feature + + + + ErrorCode: %1. ErrorCode: %1. - + OpenVPN config missing OpenVPN प्रबंधन सर्वर त्रुटि - + SCP error: Generic failure एससीपी त्रुटि: सामान्य विफलता - + OpenVPN management server error OpenVPN प्रबंधन सर्वर त्रुटि - + OpenVPN executable missing OpenVPN निष्पादन योग्य गायब है - + Shadowsocks (ss-local) executable missing शैडोसॉक्स (एसएस-स्थानीय) निष्पादन योग्य गायब है - + Cloak (ck-client) executable missing क्लोक (सीके-क्लाइंट) निष्पादन योग्य गायब है - + Amnezia helper service error Amnezia भूलने की बीमारी सहायक सेवा त्रुटि - + OpenSSL failed ओपनएसएसएल विफल रहा - + Can't connect: another VPN connection is active कनेक्ट नहीं हो सकता: कोई अन्य वीपीएन कनेक्शन सक्रिय है - + Can't setup OpenVPN TAP network adapter OpenVPN TAP नेटवर्क एडाप्टर सेटअप नहीं कर सकता - + VPN pool error: no available addresses VPN pool error: لا يوجد عنواين مٌتاحة - + The config does not contain any containers and credentials for connecting to the server कॉन्फ़िगरेशन में सर्वर से कनेक्ट करने के लिए कोई कंटेनर और क्रेडेंशियल नहीं है - + QFile error: The file could not be opened Qफ़ाइल त्रुटि: फ़ाइल खोली नहीं जा सकी - + QFile error: An error occurred when reading from the file Qफ़ाइल त्रुटि: फ़ाइल से पढ़ते समय एक त्रुटि उत्पन्न हुई - + QFile error: The file could not be accessed Qफ़ाइल त्रुटि: फ़ाइल तक नहीं पहुंचा जा सका - + QFile error: An unspecified error occurred Qफ़ाइल त्रुटि: एक अनिर्दिष्ट त्रुटि उत्पन्न हुई - + QFile error: A fatal error occurred Qफ़ाइल त्रुटि: एक घातक त्रुटि उत्पन्न हुई - + QFile error: The operation was aborted Qफ़ाइल त्रुटि: ऑपरेशन निरस्त कर दिया गया था - + Internal error आंतरिक त्रुटि @@ -4050,7 +4450,7 @@ Already installed containers were found on the server. All installed containers - + Website in Tor network टोर नेटवर्क में वेबसाइट @@ -4095,69 +4495,100 @@ Already installed containers were found on the server. All installed containers - - OpenVPN stands as one of the most popular and time-tested VPN protocols available. -It employs its unique security protocol, leveraging the strength of SSL/TLS for encryption and key exchange. Furthermore, OpenVPN's support for a multitude of authentication methods makes it versatile and adaptable, catering to a wide range of devices and operating systems. Due to its open-source nature, OpenVPN benefits from extensive scrutiny by the global community, which continually reinforces its security. With a strong balance of performance, security, and compatibility, OpenVPN remains a top choice for privacy-conscious individuals and businesses alike. - -* Available in the AmneziaVPN across all platforms -* Normal power consumption on mobile devices -* Flexible customisation to suit user needs to work with different operating systems and devices -* Recognised by DPI systems and therefore susceptible to blocking -* Can operate over both TCP and UDP network protocols. + + - - This is a combination of the OpenVPN protocol and the Cloak plugin designed specifically for protecting against detection. + + OpenVPN is one of the most popular and reliable VPN protocols. It uses SSL/TLS encryption, supports a wide variety of devices and operating systems, and is continuously improved by the community due to its open-source nature. It provides a good balance between speed and security but is easily recognized by DPI systems, making it susceptible to blocking. -OpenVPN provides a secure VPN connection by encrypting all internet traffic between the client and the server. +Features: +* Available on all AmneziaVPN platforms +* Normal battery consumption on mobile devices +* Flexible customization for various devices and OS +* Operates over both TCP and UDP protocols + + + + + Shadowsocks is based on the SOCKS5 protocol and encrypts connections using AEAD cipher. Although designed to be discreet, it doesn't mimic a standard HTTPS connection and can be detected by some DPI systems. Due to limited support in Amnezia, we recommend using the AmneziaWG protocol. -Cloak protects OpenVPN from detection. - -Cloak can modify packet metadata so that it completely masks VPN traffic as normal web traffic, and also protects the VPN from detection by Active Probing. This makes it very resistant to being detected - -Immediately after receiving the first data packet, Cloak authenticates the incoming connection. If authentication fails, the plugin masks the server as a fake website and your VPN becomes invisible to analysis systems. - -* Available in the AmneziaVPN across all platforms -* High power consumption on mobile devices -* Flexible settings -* Not recognised by detection systems -* Works over TCP network protocol, 443 port. +Features: +* Available in AmneziaVPN only on desktop platforms +* Customizable encryption protocol +* Detectable by some DPI systems +* Operates over TCP protocol - - A relatively new popular VPN protocol with a simplified architecture. -WireGuard provides stable VPN connection and high performance on all devices. It uses hard-coded encryption settings. WireGuard compared to OpenVPN has lower latency and better data transfer throughput. -WireGuard is very susceptible to detection and blocking due to its distinct packet signatures. Unlike some other VPN protocols that employ obfuscation techniques, the consistent signature patterns of WireGuard packets can be more easily identified and thus blocked by advanced Deep Packet Inspection (DPI) systems and other network monitoring tools. + + This combination includes the OpenVPN protocol and the Cloak plugin, specifically designed to protect against blocking. -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Easily recognised by DPI analysis systems, susceptible to blocking -* Works over UDP network protocol. +OpenVPN securely encrypts all internet traffic between your device and the server. + +The Cloak plugin further protects the connection from DPI detection. It modifies traffic metadata to disguise VPN traffic as regular web traffic and prevents detection through active probing. If an incoming connection fails authentication, Cloak serves a fake website, making your VPN invisible to traffic analysis systems. + +In regions with heavy internet censorship, we strongly recommend using OpenVPN with Cloak from your first connection. + +Features: +* Available on all AmneziaVPN platforms +* High power consumption on mobile devices +* Flexible configuration options +* Undetectable by DPI systems +* Operates over TCP protocol on port 443 + + + + + WireGuard is a modern, streamlined VPN protocol offering stable connectivity and excellent performance across all devices. It uses fixed encryption settings, delivering lower latency and higher data transfer speeds compared to OpenVPN. However, WireGuard is easily identifiable by DPI systems due to its distinctive packet signatures, making it susceptible to blocking. + +Features: +* Available on all AmneziaVPN platforms +* Low power consumption on mobile devices +* Minimal configuration required +* Easily detected by DPI systems (susceptible to blocking) +* Operates over UDP protocol + + + + + AmneziaWG is a modern VPN protocol based on WireGuard, combining simplified architecture with high performance across all devices. It addresses WireGuard's main vulnerability (easy detection by DPI systems) through advanced obfuscation techniques, making VPN traffic indistinguishable from regular internet traffic. + +AmneziaWG is an excellent choice for those seeking a fast, stealthy VPN connection. + +Features: +* Available on all AmneziaVPN platforms +* Low battery consumption on mobile devices +* Minimal settings required +* Undetectable by traffic analysis systems (DPI) +* Operates over UDP protocol - A modern iteration of the popular VPN protocol, AmneziaWG builds upon the foundation set by WireGuard, retaining its simplified architecture and high-performance capabilities across devices. -While WireGuard is known for its efficiency, it had issues with being easily detected due to its distinct packet signatures. AmneziaWG solves this problem by using better obfuscation methods, making its traffic blend in with regular internet traffic. -This means that AmneziaWG keeps the fast performance of the original while adding an extra layer of stealth, making it a great choice for those wanting a fast and discreet VPN connection. + REALITY is an innovative protocol developed by the creators of XRay, designed specifically to combat high levels of internet censorship. REALITY identifies censorship systems during the TLS handshake, redirecting suspicious traffic seamlessly to legitimate websites like google.com while providing genuine TLS certificates. This allows VPN traffic to blend indistinguishably with regular web traffic without special configuration. +Unlike older protocols such as VMess, VLESS, and XTLS-Vision, REALITY incorporates an advanced built-in "friend-or-foe" detection mechanism, effectively protecting against DPI and other traffic analysis methods. -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Not recognised by traffic analysis systems -* Works over UDP network protocol. +Features: +* Resistant to active probing and DPI detection +* No special configuration required to disguise traffic +* Highly effective in heavily censored regions +* Minimal battery consumption on devices +* Operates over TCP protocol - - The REALITY protocol, a pioneering development by the creators of XRay, is designed to provide the highest level of protection against detection through its innovative approach to security and privacy. -It uniquely identifies attackers during the TLS handshake phase, seamlessly operating as a proxy for legitimate clients while diverting attackers to genuine websites, thus presenting an authentic TLS certificate and data. -This advanced capability differentiates REALITY from similar technologies by its ability to disguise web traffic as coming from random, legitimate sites without the need for specific configurations. -Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REALITY's innovative "friend or foe" recognition at the TLS handshake enhances security. This makes REALITY a robust solution for maintaining internet freedom. + + IKEv2, combined with IPSec encryption, is a modern and reliable VPN protocol. It reconnects quickly when switching networks or devices, making it ideal for dynamic network environments. While it provides good security and speed, it's easily recognized by DPI systems and susceptible to blocking. + +Features: +* Available in AmneziaVPN only on Windows +* Low battery consumption on mobile devices +* Minimal configuration required +* Detectable by DPI analysis systems(easily blocked) +* Operates over UDP protocol(ports 500 and 4500) @@ -4241,7 +4672,7 @@ WireGuard is very susceptible to blocking due to its distinct packet signatures. * यूडीपी नेटवर्क प्रोटोकॉल पर काम करता है।. - + After installation, Amnezia will create a file storage on your server. You will be able to access it using @@ -4300,14 +4731,13 @@ It employs its unique security protocol, leveraging the strength of SSL/TLS for * टीसीपी और यूडीपी दोनों नेटवर्क प्रोटोकॉल पर काम कर सकता है।. - Shadowsocks, inspired by the SOCKS5 protocol, safeguards the connection using the AEAD cipher. Although Shadowsocks is designed to be discreet and challenging to identify, it isn't identical to a standard HTTPS connection.However, certain traffic analysis systems might still detect a Shadowsocks connection. Due to limited support in Amnezia, it's recommended to use AmneziaWG protocol. * Available in the AmneziaVPN only on desktop platforms * Configurable encryption protocol * Detectable by some DPI systems * Works over TCP network protocol. - शैडोसॉक्स, SOCKS5 प्रोटोकॉल से प्रेरित होकर, AEAD सिफर का उपयोग करके कनेक्शन की सुरक्षा करता है। हालाँकि शैडोसॉक्स को विवेकपूर्ण और पहचानने में चुनौतीपूर्ण बनाया गया है, यह एक मानक HTTPS कनेक्शन के समान नहीं है। हालाँकि, कुछ ट्रैफ़िक विश्लेषण प्रणालियाँ अभी भी शैडोसॉक्स कनेक्शन का पता लगा सकती हैं। Amnezia में सीमित समर्थन के कारण, AmneziaWG प्रोटोकॉल का उपयोग करने की अनुशंसा की जाती है। + शैडोसॉक्स, SOCKS5 प्रोटोकॉल से प्रेरित होकर, AEAD सिफर का उपयोग करके कनेक्शन की सुरक्षा करता है। हालाँकि शैडोसॉक्स को विवेकपूर्ण और पहचानने में चुनौतीपूर्ण बनाया गया है, यह एक मानक HTTPS कनेक्शन के समान नहीं है। हालाँकि, कुछ ट्रैफ़िक विश्लेषण प्रणालियाँ अभी भी शैडोसॉक्स कनेक्शन का पता लगा सकती हैं। Amnezia में सीमित समर्थन के कारण, AmneziaWG प्रोटोकॉल का उपयोग करने की अनुशंसा की जाती है। * AmneziaVPN केवल डेस्कटॉप प्लेटफ़ॉर्म पर उपलब्ध है * कॉन्फ़िगर करने योग्य एन्क्रिप्शन प्रोटोकॉल @@ -4345,7 +4775,6 @@ Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REAL VMess, VLESS और XTLS-Vision ट्रांसपोर्ट जैसे पुराने प्रोटोकॉल के विपरीत, TLS हैंडशेक पर REALITY की अभिनव "दोस्त या दुश्मन" पहचान सुरक्षा को बढ़ाती है और सक्रिय जांच तकनीकों को नियोजित करने वाले परिष्कृत DPI सिस्टम द्वारा पहचान को रोकती है। यह REALITY को कठोर सेंसरशिप वाले वातावरण में इंटरनेट की स्वतंत्रता बनाए रखने के लिए एक मजबूत समाधान बनाता है. - IKEv2, paired with the IPSec encryption layer, stands as a modern and stable VPN protocol. One of its distinguishing features is its ability to swiftly switch between networks and devices, making it particularly adaptive in dynamic network environments. While it offers a blend of security, stability, and speed, it's essential to note that IKEv2 can be easily detected and is susceptible to blocking. @@ -4355,7 +4784,7 @@ While it offers a blend of security, stability, and speed, it's essential t * Minimal configuration * Recognised by DPI analysis systems * Works over UDP network protocol, ports 500 and 4500. - IKEv2, IPSec एन्क्रिप्शन परत के साथ मिलकर, एक आधुनिक और स्थिर वीपीएन प्रोटोकॉल के रूप में खड़ा है। + IKEv2, IPSec एन्क्रिप्शन परत के साथ मिलकर, एक आधुनिक और स्थिर वीपीएन प्रोटोकॉल के रूप में खड़ा है। इसकी विशिष्ट विशेषताओं में से एक नेटवर्क और उपकरणों के बीच तेजी से स्विच करने की क्षमता है, जो इसे गतिशील नेटवर्क वातावरण में विशेष रूप से अनुकूली बनाती है। हालाँकि यह सुरक्षा, स्थिरता और गति का मिश्रण प्रदान करता है, यह ध्यान रखना आवश्यक है कि IKEv2 को आसानी से पहचाना जा सकता है और अवरुद्ध होने की संभावना है। @@ -4366,7 +4795,7 @@ While it offers a blend of security, stability, and speed, it's essential t * यूडीपी नेटवर्क प्रोटोकॉल, पोर्ट 500 और 4500 पर काम करता है. - + DNS Service DNS सेवाएँ @@ -4603,12 +5032,12 @@ While it offers a blend of security, stability, and speed, it's essential t SettingsController - + Backup file is corrupted बैकअप फ़ाइल दूषित है - + All settings have been reset to default values सभी सेटिंग्स को डिफ़ॉल्ट मानों पर रीसेट कर दिया गया है @@ -4740,7 +5169,7 @@ While it offers a blend of security, stability, and speed, it's essential t VpnConnection - + Mbps @@ -4815,12 +5244,12 @@ While it offers a blend of security, stability, and speed, it's essential t अधिकांश वीपीएन प्रोटोकॉल अवरुद्ध हैं। यदि अन्य विकल्प काम नहीं कर रहे हों तो अनुशंसित. - + Automatic - + AmneziaWG protocol will be installed. It provides high connection speed and ensures stable operation even in the most challenging network conditions. diff --git a/client/translations/amneziavpn_my_MM.ts b/client/translations/amneziavpn_my_MM.ts index 1e81c5aa..a26cd525 100644 --- a/client/translations/amneziavpn_my_MM.ts +++ b/client/translations/amneziavpn_my_MM.ts @@ -9,6 +9,54 @@ + + AllowedDnsController + + + The address does not look like a valid IP address + + + + + New DNS server added: %1 + + + + + DNS server already exists: %1 + + + + + DNS server removed: %1 + + + + + Can't open file: %1 + ဖိုင်ကိုဖွင့်၍မရပါ: %1 + + + + Failed to parse JSON data from file: %1 + JSON ဒေတာကို ဖိုင်မှ ခွဲခြမ်းထုပ်ယူမှု မအောင်မြင်ပါ: %1 + + + + The JSON data is not an array in file: %1 + JSON ဒေတာသည် ဖိုင်ထဲရှိ array တစ်ခုမဟုတ်ပါ: %1 + + + + Import completed + တင်သွင်းခြင်းပြီးဆုံးသွားပါပြီ + + + + Export completed + ထုတ်ယူခြင်းပြီးဆုံးသွားပါပြီ + + ApiAccountInfoModel @@ -33,39 +81,131 @@ - + Free unlimited access to a basic set of websites such as Facebook, Instagram, Twitter (X), Discord, Telegram and more. YouTube is not included in the free plan. - - - amnezia_free_support_bot - - - - - amnezia_premium_support_bot - - ApiConfigsController - + %1 installed successfully. %1 ခုကို အောင်မြင်စွာ ထည့်သွင်းပြီးပါပြီ. - + API config reloaded API config ကို ပြန်လည်စတင်လိုက်ပါပြီ - + Successfully changed the country of connection to %1 ချိတ်ဆက်မှုနိုင်ငံကို %1 သို့ အောင်မြင်စွာ ပြောင်းလဲလိုက်ပါပြီ + + ApiPremV1MigrationDrawer + + + Switch to the new Amnezia Premium subscription + + + + + We'll preserve all remaining days of your current subscription and give you an extra month as a thank you. + + + + + This new subscription type will be actively developed with more locations and features added regularly. Currently available: + + + + + <li>13 locations (with more coming soon)</li> + + + + + <li>Easier switching between countries in the app</li> + + + + + <li>Personal dashboard to manage your subscription</li> + + + + + Old keys will be deactivated after switching. + + + + + Email + + + + + mail@example.com + + + + + No old format subscriptions for a given email + + + + + Enter the email you used for your current subscription + + + + + + Continue + ဆက်လက်လုပ်ဆောင်မည် + + + + Remind me later + + + + + Don't remind me again + + + + + No more reminders? You can always switch to the new format in the server settings + + + + + Cancel + ပယ်ဖျက်မည် + + + + ApiPremV1SubListDrawer + + + Choose Subscription + + + + + Order ID: + + + + + Purchase Date: + + + ApiServicesModel @@ -97,7 +237,7 @@ - AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan. + Amnezia Free provides unlimited, free access to a basic set of websites and apps, including Facebook, Instagram, Twitter (X), Discord, Telegram, and more. YouTube is not included in the free plan. @@ -115,6 +255,11 @@ %1 days %1 ရက် + + + + + VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a> @@ -273,7 +418,7 @@ HomeContainersListView - + Unable change protocol while there is an active connection လက်ရှိချိတ်ဆက်မှုတစ်ခုရှိနေချိန်တွင် ပရိုတိုကောကို ပြောင်းလဲ၍မရပါ။ @@ -336,17 +481,17 @@ Can't be disabled for current server Configuration ဖိုင် မမှန်ကန်ပါ - + Scanned %1 of %2. %2 ၏ %1 ကို စကင်န်ဖတ်ထားသည်. - + This configuration contains an OpenVPN setup. OpenVPN configurations can include malicious scripts, so only add it if you fully trust the provider of this config. - + <br>In the imported configuration, potentially dangerous lines were found: @@ -358,71 +503,71 @@ Can't be disabled for current server InstallController - + %1 installed successfully. %1 ကို အောင်မြင်စွာ ထည့်သွင်းပြီးပါပြီ. - + %1 is already installed on the server. %1 ကို ဆာဗာတွင် ထည့်သွင်းပြီးဖြစ်သည်. - + Added containers that were already installed on the server ဆာဗာတွင် ထည့်သွင်းပြီးသား ကွန်တိန်နာများကို ပေါင်းထည့်ပြီးပါပြီ။ - + Already installed containers were found on the server. All installed containers have been added to the application ထည့်သွင်းပြီးသား ကွန်တိန်နာများကို ဆာဗာပေါ်တွင် တွေ့ရှိခဲ့သည်။ ထည့်သွင်းထားသည့် ကွန်တိန်နာအားလုံးကို အပလီကေးရှင်းထဲသို့ ပေါင်းထည့်ပြီးပါပြီ။ - + Settings updated successfully ဆက်တင်များကို အောင်မြင်စွာ အပ်ဒိတ်လုပ်ပြီးပါပြီ။ - + Server '%1' was rebooted ဆာဗာ '%1' ကို ပြန်လည်စတင်ခဲ့သည်။ - + Server '%1' was removed ဆာဗာ '%1' ကို ဖယ်ရှားခဲ့သည်။ - + All containers from server '%1' have been removed ဆာဗာ '%1' မှ ကွန်တိန်နာအားလုံးကို ဖယ်ရှားလိုက်ပါပြီ။ - + %1 has been removed from the server '%2' %1 ကို ဆာဗာ '%2' မှ ဖယ်ရှားလိုက်ပါပြီ - + Api config removed Api config ကိုဖယ်ရှားလိုက်သည် - + %1 cached profile cleared ကက်ရှ်လုပ်ထားတဲ့ ပရိုဖိုင် %1 ခုကို ရှင်းပြီးပါပြီ - + Please login as the user အသုံးပြုသူအဖြစ် log in ဝင်ရောက်ပါ - + Server added successfully ဆာဗာကို အောင်မြင်စွာ ထည့်သွင်းပြီးပါပြီ @@ -504,6 +649,24 @@ Already installed containers were found on the server. All installed containers လုံခြုံမှုမရှိသောကွန်ရက်မှန်း ထောက်လှန်းမိသည်: + + OtpCodeDrawer + + + OTP code was sent to your email + + + + + OTP Code + + + + + Continue + ဆက်လက်လုပ်ဆောင်မည် + + PageDeinstalling @@ -533,27 +696,43 @@ Already installed containers were found on the server. All installed containers PageHome - + + You've successfully switched to the new Amnezia Premium subscription! + + + + + Old keys will no longer work. Please use your new subscription key to connect. +Thank you for staying with us! + + + + + Continue + ဆက်လက်လုပ်ဆောင်မည် + + + Logging enabled Logging ဖွင့်ထားပါသည် - + Split tunneling enabled split tunnelling ဖွင့်ထားပါသည် - + Split tunneling disabled split tunnelling ပိတ်ထားပါသည် - + VPN protocol VPN ပရိုတိုကော - + Servers ဆာဗာများ @@ -575,42 +754,87 @@ Already installed containers were found on the server. All installed containers MTU - + Server settings - + Port Port - + + I1 - First special junk packet + + + + + I2 - Second special junk packet + + + + + I3 - Third special junk packet + + + + + I4 - Fourth special junk packet + + + + + I5 - Fifth special junk packet + + + + + J1 - First controlled junk packet + + + + + J2 - Second controlled junk packet + + + + + J3 - Third controlled junk packet + + + + + Itime - Special handshake timeout + + + + Save သိမ်းဆည်းမည် - + Save settings? ဆက်တင်များကို သိမ်းဆည်းမည်လား? - + Only the settings for this device will be changed - + Continue ဆက်လက်လုပ်ဆောင်မည် - + Cancel ပယ်ဖျက်မည် - + Unable change settings while there is an active connection လက်ရှိချိတ်ဆက်မှုတစ်ခုရှိနေချိန်တွင် ဆက်တင်များကို ပြောင်းလဲ၍မရပါ @@ -632,12 +856,12 @@ Already installed containers were found on the server. All installed containers MTU - + All users with whom you shared a connection with will no longer be able to connect to it. သင်နှင့်အတူချိတ်ဆက်မှုတစ်ခုကို မျှဝေထားသည့် အသုံးပြုသူအားလုံး ချိတ်ဆက်နိုင်တော့မည်မဟုတ်ပါ. - + Save သိမ်းဆည်းမည် @@ -682,42 +906,42 @@ Already installed containers were found on the server. All installed containers H2 - Response packet magic header - + H4 - Transport packet magic header H4 - Transport packet magic header - + H3 - Underload packet magic header H3 - Underload packet magic header - + The values of the H1-H4 fields must be unique H1-H4 အကွက်များ၏ တန်ဖိုးများသည် အခြားတန်ဖိုးများနှင့်မတူ တမူထူးခြားနေရပါမည် - + The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) အကွက် S1 + မက်ဆေ့ချ် စတင်ခြင်း အရွယ်အစား (148) ၏ တန်ဖိုးသည် S2 + မက်ဆေ့ချ် တုံ့ပြန်မှု အရွယ်အစား (92) နှင့် မညီမျှရပါ - + Save settings? ဆက်တင်များကို သိမ်းဆည်းမည်လား? - + Continue ဆက်လက်လုပ်ဆောင်မည် - + Cancel ပယ်ဖျက်မည် - + Unable change settings while there is an active connection လက်ရှိချိတ်ဆက်မှုတစ်ခုရှိနေချိန်တွင် ဆက်တင်များကို ပြောင်းလဲ၍မရပါ @@ -1122,12 +1346,17 @@ Already installed containers were found on the server. All installed containers traffic အဖြစ် အသွင်ယူထားသည် - + + Port + Port + + + Save သိမ်းဆည်းမည် - + Unable change settings while there is an active connection လက်ရှိချိတ်ဆက်မှုတစ်ခုရှိနေချိန်တွင် ဆက်တင်များကို ပြောင်းလဲ၍မရပါ @@ -1544,7 +1773,7 @@ Already installed containers were found on the server. All installed containers - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -1861,7 +2090,7 @@ Already installed containers were found on the server. All installed containers - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -1897,31 +2126,16 @@ Already installed containers were found on the server. All installed containers Email - - - support@amnezia.org - - Email Billing & Orders - - - help@vpnpay.io - - Website ဝဘ်ဆိုက် - - - amnezia.org - - Support @@ -1933,12 +2147,12 @@ Already installed containers were found on the server. All installed containers - + Support tag ကူညီပံ့ပိုးမှု tag - + Copied ကူးယူပြီးပါပြီ @@ -1966,37 +2180,37 @@ Already installed containers were found on the server. All installed containers App split tunneling - + Mode Mode - + Remove ဖယ်ရှားမည် - + Continue ဆက်လက်လုပ်ဆောင်မည် - + Cancel ပယ်ဖျက်မည် - + application name အပလီကေးရှင်းအမည် - + Open executable file စီမံလုပ်ဆောင်နိုင်မှုဖိုင်ကိုဖွင့်မည် - + Executable files (*.*) စီမံလုပ်ဆောင်နိုင်မှုဖိုင်များ (*.*) @@ -2211,24 +2425,23 @@ Already installed containers were found on the server. All installed containers AmneziaDNS ကို အသုံးမပြု သို့မဟုတ် ထည့်သွင်းခြင်းမပြုသည့်အခါ - + Allows you to use the VPN only for certain Apps အချို့သောအက်ပ်များအတွက်သာ VPN ကို အသုံးပြုခွင့်ပေးသည် - + KillSwitch KillSwitch - - Disables your internet if your encrypted VPN connection drops out for any reason. - အကြောင်းတစ်ခုခုကြောင့် VPN ချိတ်ဆက်မှု ပျက်သွားပါက သင့်အင်တာနက်ကို ချက်ချင်းရပ်ဆိုင်းပေးသည်. + + Blocks network connections without VPN + - - Cannot change KillSwitch settings during active connection - + Disables your internet if your encrypted VPN connection drops out for any reason. + အကြောင်းတစ်ခုခုကြောင့် VPN ချိတ်ဆက်မှု ပျက်သွားပါက သင့်အင်တာနက်ကို ချက်ချင်းရပ်ဆိုင်းပေးသည်. Cannot change killSwitch settings during active connection @@ -2245,7 +2458,7 @@ Already installed containers were found on the server. All installed containers VPN မှတဆင့် သင်ဝင်ရောက်လိုသည့်ဆိုဒ်များကို ရွေးချယ်စေနိုင်သည် - + App-based split tunneling App အခြေပြု split tunneling @@ -2313,6 +2526,155 @@ Already installed containers were found on the server. All installed containers ဆက်တင်များကို သိမ်းဆည်းပြီးပြီ + + PageSettingsKillSwitch + + + KillSwitch + KillSwitch + + + + Enable to ensure network traffic goes through a secure VPN tunnel, preventing accidental exposure of your IP and DNS queries if the connection drops + + + + + KillSwitch settings cannot be changed during an active connection + + + + + Soft KillSwitch + + + + + Internet access is blocked if the VPN disconnects unexpectedly + + + + + Strict KillSwitch + + + + + Internet connection is blocked even when VPN is turned off manually or hasn't started + + + + + Just a little heads-up + + + + + If the VPN disconnects or drops while Strict KillSwitch is enabled, internet access will be blocked. To restore access, reconnect VPN or disable/change the KillSwitch. + + + + + Continue + ဆက်လက်လုပ်ဆောင်မည် + + + + Cancel + ပယ်ဖျက်မည် + + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active. + + + + + PageSettingsKillSwitchExceptions + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active + + + + + Delete + + + + + Continue + ဆက်လက်လုပ်ဆောင်မည် + + + + Cancel + ပယ်ဖျက်မည် + + + + IPv4 address + + + + + Import / Export addresses + + + + + Import + တင်သွင်းမည် + + + + Save address list + + + + + Save addresses + + + + + + + Address files (*.json) + + + + + Import address list + + + + + Replace address list + + + + + + Open address file + + + + + Add imported addresses to existing ones + + + PageSettingsLogging @@ -2433,11 +2795,6 @@ Already installed containers were found on the server. All installed containers No new installed containers found အသစ်ထည့်သွင်းထားသော ကွန်တိန်နာများ မတွေ့ရှိပါ - - - - - @@ -2524,6 +2881,11 @@ Already installed containers were found on the server. All installed containers Cannot reset API config during active connection လက်ရှိချိတ်ဆက်မှုတစ်ခုရှိနေချိန်တွင် API config ကို ပြန်လည်သတ်မှတ်၍မရပါ + + + Switch to the new Amnezia Premium subscription + + Remove server from application @@ -2582,11 +2944,6 @@ Already installed containers were found on the server. All installed containers Clear %1 profile? %1 ပရိုဖိုင်ကို ရှင်းလင်းမည်လား? - - - - - Unable to clear %1 profile while there is an active connection @@ -2671,32 +3028,32 @@ Already installed containers were found on the server. All installed containers စာရင်းတွင်ဖော်ပြထားသောလိပ်စာများကို VPN ဖြင့် ဝင်ရောက်ခြင်းပြုနိုင်လိမ့်မည် မဟုတ်ပေ - + Split tunneling Split tunneling - + Mode Mode - + Remove ဖယ်ရှားမည် - + Continue ဆက်လက်လုပ်ဆောင်မည် - + Cancel ပယ်ဖျက်မည် - + Import / Export Sites ဆိုက်များ သွင်း/ထုတ်မည် @@ -2711,50 +3068,50 @@ Already installed containers were found on the server. All installed containers လက်ရှိချိတ်ဆက်မှုတစ်ခုရှိနေချိန်တွင် split tunneling ဆက်တင်များကို ပြောင်းလဲ၍မရပါ - + website or IP ဝဘ်ဆိုက် သို့မဟုတ် IP - + Import တင်သွင်းမည် - + Save site list ဆိုက်စာရင်းကို သိမ်းဆည်းမည် - + Save sites ဆိုက်များသိမ်းဆည်းမည် - - - + + + Sites files (*.json) ဆိုက်ဖိုင်များ (*.json) - + Import a list of sites ဆိုက်စာရင်းတစ်ခု တင်သွင်းမည် - + Replace site list ဆိုက်စာရင်းကို အစားထိုးမည် - - + + Open sites file ဆိုက်ဖိုင်များ ဖွင့်မည် - + Add imported sites to existing ones တင်သွင်းထားသော ဆိုက်များကို ရှိပြီးသားဆိုက်များထဲသို့ ထည့်မည် @@ -2808,117 +3165,140 @@ Already installed containers were found on the server. All installed containers PageSetupWizardConfigSource - + File with connection settings ချိတ်ဆက်မှုဆက်တင်များပါဝင်သောဖိုင် - + Connection ချိတ်ဆက်မှု - + Settings ဆက်တင်များ - + Enable logs + Export client logs + + + + + Save + သိမ်းဆည်းမည် + + + + Logs files (*.log) + မှတ်တမ်းဖိုင်များ (*.log) + + + + Logs file saved + မှတ်တမ်းဖိုင်များသိမ်းဆည်းပြီးပါပြီ + + + Support tag ကူညီပံ့ပိုးမှု tag - + Copied ကူးယူပြီးပါပြီ - + Insert the key, add a configuration file or scan the QR-code Key ကိုထည့်မည်၊ ဖွဲ့စည်းမှုဖိုင်တစ်ခုကိုထည့်မည် သို့မဟုတ် QR-ကုဒ်ကို စကင်န်ဖတ်မည် - + Insert key Key ကိုထည့်သွင်းမည် - + Insert ထည့်သွင်းမည် - + Continue ဆက်လက်လုပ်ဆောင်မည် - + Other connection options အခြားချိတ်ဆက်မှုရွေးချယ်စရာများ - + Site Amnezia - + VPN by Amnezia Amnezia မှ VPN - + Connect to classic paid and free VPN services from Amnezia Amnezia မှ အခပေးနှင့် အခမဲ့ မူလ VPN ဝန်ဆောင်မှုများသို့ ချိတ်ဆက်မည် - + Self-hosted VPN ကိုယ်တိုင် host လုပ်ထားသော VPN - + Configure Amnezia VPN on your own server Amnezia VPN ကို သင်၏ကိုယ်ပိုင်ဆာဗာပေါ်တွင် စီစဥ်ချိန်ညှိမည် - + Restore from backup အရံဖိုင်မှ ပြန်လည်ရယူမည် - + + + + - + Open backup file အရံဖိုင်ကို ဖွင့်မည် - + Backup files (*.backup) အရံဖိုင်များ (*.backup) - + Open config file config ဖိုင်ကိုဖွင့်မည် - + QR code QR-ကုဒ် - + I have nothing ကျွန်ုပ်တွင်ဘာမှမရှိပါ @@ -3769,58 +4149,58 @@ Already installed containers were found on the server. All installed containers ဤအသုံးပြုသူသည် sudo အုပ်စု၏အဖွဲ့ဝင်မဟုတ်ပါ - + SSH request was denied SSH တောင်းဆိုမှု ငြင်းဆိုခံလိုက်ရပါသည် - + SSH request was interrupted SSH တောင်းဆိုမှု အနှောက်အယက်ခံလိုက်ရပါသည် - + SSH internal error စက်တွင်းဖြစ်သော SSH မှားယွင်းမှု - + Invalid private key or invalid passphrase entered မမှန်ကန်သော ကိုယ်ပိုင် key သို့မဟုတ် မမှန်ကန်သော စကားဝှက်ကို ထည့်သွင်းထားသည် - + The selected private key format is not supported, use openssh ED25519 key types or PEM key types ရွေးချယ်ထားသော ကိုယ်ပိုင် key ဖော်မတ်ကို ထောက်ပံ့မှုမပေးပါ၊ openssh ED25519 key အမျိုးအစားများ သို့မဟုတ် PEM သော့အမျိုးအစားများကို အသုံးပြုပါ - + Timeout connecting to server ဆာဗာသို့ ချိတ်ဆက်ခြင်း အချိန်ကုန်သွားသည် - + The config does not contain any containers and credentials for connecting to the server Config တွင် ဆာဗာသို့ချိတ်ဆက်ရန်အတွက် ကွန်တိန်နာများနှင့် အထောက်အထားများ မပါဝင်ပါ - - + + Error when retrieving configuration from API API မှ စီစဉ်သတ်မှတ်မှုကို ရယူသည့်အခါ အမှားအယွင်းဖြစ်ပေါ်နေသည် - + This config has already been added to the application ဤ config ကို အပလီကေးရှင်းထဲသို့ ထည့်သွင်းပြီးဖြစ်သည် - + ErrorCode: %1. မှားယွင်းမှုကုတ်: %1. - + OpenVPN config missing OpenVPN config ပျောက်ဆုံးနေပါသည် @@ -3860,139 +4240,159 @@ Already installed containers were found on the server. All installed containers - + + Docker error: runc doesn't work on cgroups v2 + + + + + Server error: cgroup mountpoint does not exist + + + + SCP error: Generic failure SCP မှားယွင်းမှု: ယေဘုယ မအောင်မြင်ခြင်း - + OpenVPN management server error OpenVPN စီမံခန့်ခွဲမှုဆာဗာ အမှားအယွင်း - + OpenVPN executable missing OpenVPN စီမံလုပ်ဆောင်နိုင်မှု ပျောက်ဆုံးနေပါသည် - + Shadowsocks (ss-local) executable missing Shadowsocks (ss-local) executable ပျောက်နေပါသည် - + Cloak (ck-client) executable missing Cloak (ck-client) စီမံလုပ်ဆောင်နိုင်မှု ပျောက်ဆုံးနေပါသည် - + Amnezia helper service error Amnezia helper ဝန်ဆောင်မှု မှားယွင်းမှု - + OpenSSL failed OpenSSL မအောင်မြင်ပါ - + Can't connect: another VPN connection is active ချိတ်ဆက်၍မရပါ: အခြား VPN ချိတ်ဆက်မှုတစ်ခုရှိနေပါသည် - + Can't setup OpenVPN TAP network adapter OpenVPN TAP ကွန်ရက် adapter ကို စနစ်တည်ဆောက်၍မရပါ - + VPN pool error: no available addresses VPN pool မှားယွင်းမှု: ရရှိနိုင်သောလိပ်စာများမရှိပါ - + Unable to open config file - + VPN Protocols is not installed. Please install VPN container at first VPN ပရိုတိုကောများကို မထည့်သွင်းရသေးပါ။ ကျေးဇူးပြု၍ VPN ကွန်တိန်နာကို အရင်ထည့်သွင်းပါ။ - + VPN connection error VPN ချိတ်ဆက်မှုမှားယွင်းနေပါသည် - + In the response from the server, an empty config was received ဆာဗာမှ တုံ့ပြန်မှုတွင်၊ config အလွတ်တစ်ခုကို လက်ခံရရှိခဲ့သည် - + SSL error occurred SSL မှားယွင်းမှုဖြစ်သွားသည် - + Server response timeout on api request Api တောင်းဆိုမှုတွင် ဆာဗာတုံ့ပြန်မှု အချိန်ကုန်သွားသည် - + Missing AGW public key AGW public key ပျောက်ဆုံးနေသည် - + Failed to decrypt response payload - + Missing list of available services - + The limit of allowed configurations per subscription has been exceeded + A migration error has occurred. Please contact our technical support + + + + + Please update the application to use this feature + + + + QFile error: The file could not be opened QFile မှားယွင်းမှု: ဖိုင်ကို ဖွင့်၍မရပါ - + QFile error: An error occurred when reading from the file QFile မှားယွင်းမှု: ဖိုင်ကိုဖတ်နေစဥ်အတွင်း မှားယွင်းမှုဖြစ်သွားသည် - + QFile error: The file could not be accessed QFile မှားယွင်းမှု: ဖိုင်ကို ဝင်၍မရပါ - + QFile error: An unspecified error occurred QFile မှားယွင်းမှု: သတ်မှတ်မထားသော မှားယွင်းမှုတစ်ခု ဖြစ်ပွားခဲ့သည် - + QFile error: A fatal error occurred QFile မှားယွင်းမှု: ကြီးမားသော မှားယွင်းမှုတစ်ခု ဖြစ်ပွားခဲ့သည် - + QFile error: The operation was aborted QFile မှားယွင်းမှု: လုပ်ငန်းစဥ်ကို ဖျက်သိမ်းလိုက်ရသည် - + Internal error စက်တွင်းဖြစ်သော မှားယွင်းမှု @@ -4092,7 +4492,6 @@ This advanced capability differentiates REALITY from similar technologies by its Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REALITY's innovative "friend or foe" recognition at the TLS handshake enhances security and circumvents detection by sophisticated DPI systems employing active probing techniques. This makes REALITY a robust solution for maintaining internet freedom in environments with stringent censorship. - IKEv2, paired with the IPSec encryption layer, stands as a modern and stable VPN protocol. One of its distinguishing features is its ability to swiftly switch between networks and devices, making it particularly adaptive in dynamic network environments. While it offers a blend of security, stability, and speed, it's essential to note that IKEv2 can be easily detected and is susceptible to blocking. @@ -4102,7 +4501,7 @@ While it offers a blend of security, stability, and speed, it's essential t * Minimal configuration * Recognised by DPI analysis systems * Works over UDP network protocol, ports 500 and 4500. - IPSec ကုဒ်ဝှက်ခြင်းအလွှာနှင့်တွဲဆက်ထားသည့် IKEv2 သည် ခေတ်မီပြီး တည်ငြိမ်သော VPN ပရိုတိုကောဖြစ်သည်။ + IPSec ကုဒ်ဝှက်ခြင်းအလွှာနှင့်တွဲဆက်ထားသည့် IKEv2 သည် ခေတ်မီပြီး တည်ငြိမ်သော VPN ပရိုတိုကောဖြစ်သည်။ ၎င်း၏ထူးခြားသောအင်္ဂါရပ်များထဲမှတစ်ခုမှာ ကွန်ရက်များနှင့် စက်ပစ္စည်းများကြား လျင်မြန်စွာပြောင်းလဲနိုင်သည့်စွမ်းရည်ဖြစ်ပြီး ဤစွမ်းရည်ကပင် dynamic ဖြစ်သောကွန်ရက်ပတ်ဝန်းကျင်များတွင် လိုက်လျောညီထွေဖြစ်စေရန်အကူအညီပေးပါသည်။ IKEv2 သည် လုံခြုံရေး၊ တည်ငြိမ်မှု၊ နှင့် အမြန်နှုန်းတို့ ပေးစွမ်းနိုင်သော်လည်း၊ အလွယ်တကူ ထောက်လှန်းသိရှိခံရနိုင်ပြီး ပိတ်ဆို့ခြင်း ခံရနိုင်သည်ကို သတိပြုရန် အရေးကြီးပါသည်။ @@ -4113,7 +4512,7 @@ IKEv2 သည် လုံခြုံရေး၊ တည်ငြိမ်မှ * UDP ကွန်ရက်ပရိုတိုကော၊ port 500 နှင့် 4500 ကျော်တွင် အလုပ်လုပ်သည်။. - + DNS Service DNS ဝန်ဆောင်မှု @@ -4124,7 +4523,7 @@ IKEv2 သည် လုံခြုံရေး၊ တည်ငြိမ်မှ - + Website in Tor network Tor ကွန်ရက်ထဲရှိ ဝဘ်ဆိုဒ် @@ -4164,69 +4563,100 @@ IKEv2 သည် လုံခြုံရေး၊ တည်ငြိမ်မှ - - OpenVPN stands as one of the most popular and time-tested VPN protocols available. -It employs its unique security protocol, leveraging the strength of SSL/TLS for encryption and key exchange. Furthermore, OpenVPN's support for a multitude of authentication methods makes it versatile and adaptable, catering to a wide range of devices and operating systems. Due to its open-source nature, OpenVPN benefits from extensive scrutiny by the global community, which continually reinforces its security. With a strong balance of performance, security, and compatibility, OpenVPN remains a top choice for privacy-conscious individuals and businesses alike. - -* Available in the AmneziaVPN across all platforms -* Normal power consumption on mobile devices -* Flexible customisation to suit user needs to work with different operating systems and devices -* Recognised by DPI systems and therefore susceptible to blocking -* Can operate over both TCP and UDP network protocols. + + - - This is a combination of the OpenVPN protocol and the Cloak plugin designed specifically for protecting against detection. + + OpenVPN is one of the most popular and reliable VPN protocols. It uses SSL/TLS encryption, supports a wide variety of devices and operating systems, and is continuously improved by the community due to its open-source nature. It provides a good balance between speed and security but is easily recognized by DPI systems, making it susceptible to blocking. -OpenVPN provides a secure VPN connection by encrypting all internet traffic between the client and the server. +Features: +* Available on all AmneziaVPN platforms +* Normal battery consumption on mobile devices +* Flexible customization for various devices and OS +* Operates over both TCP and UDP protocols + + + + + Shadowsocks is based on the SOCKS5 protocol and encrypts connections using AEAD cipher. Although designed to be discreet, it doesn't mimic a standard HTTPS connection and can be detected by some DPI systems. Due to limited support in Amnezia, we recommend using the AmneziaWG protocol. -Cloak protects OpenVPN from detection. - -Cloak can modify packet metadata so that it completely masks VPN traffic as normal web traffic, and also protects the VPN from detection by Active Probing. This makes it very resistant to being detected - -Immediately after receiving the first data packet, Cloak authenticates the incoming connection. If authentication fails, the plugin masks the server as a fake website and your VPN becomes invisible to analysis systems. - -* Available in the AmneziaVPN across all platforms -* High power consumption on mobile devices -* Flexible settings -* Not recognised by detection systems -* Works over TCP network protocol, 443 port. +Features: +* Available in AmneziaVPN only on desktop platforms +* Customizable encryption protocol +* Detectable by some DPI systems +* Operates over TCP protocol - - A relatively new popular VPN protocol with a simplified architecture. -WireGuard provides stable VPN connection and high performance on all devices. It uses hard-coded encryption settings. WireGuard compared to OpenVPN has lower latency and better data transfer throughput. -WireGuard is very susceptible to detection and blocking due to its distinct packet signatures. Unlike some other VPN protocols that employ obfuscation techniques, the consistent signature patterns of WireGuard packets can be more easily identified and thus blocked by advanced Deep Packet Inspection (DPI) systems and other network monitoring tools. + + This combination includes the OpenVPN protocol and the Cloak plugin, specifically designed to protect against blocking. -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Easily recognised by DPI analysis systems, susceptible to blocking -* Works over UDP network protocol. +OpenVPN securely encrypts all internet traffic between your device and the server. + +The Cloak plugin further protects the connection from DPI detection. It modifies traffic metadata to disguise VPN traffic as regular web traffic and prevents detection through active probing. If an incoming connection fails authentication, Cloak serves a fake website, making your VPN invisible to traffic analysis systems. + +In regions with heavy internet censorship, we strongly recommend using OpenVPN with Cloak from your first connection. + +Features: +* Available on all AmneziaVPN platforms +* High power consumption on mobile devices +* Flexible configuration options +* Undetectable by DPI systems +* Operates over TCP protocol on port 443 + + + + + WireGuard is a modern, streamlined VPN protocol offering stable connectivity and excellent performance across all devices. It uses fixed encryption settings, delivering lower latency and higher data transfer speeds compared to OpenVPN. However, WireGuard is easily identifiable by DPI systems due to its distinctive packet signatures, making it susceptible to blocking. + +Features: +* Available on all AmneziaVPN platforms +* Low power consumption on mobile devices +* Minimal configuration required +* Easily detected by DPI systems (susceptible to blocking) +* Operates over UDP protocol + + + + + AmneziaWG is a modern VPN protocol based on WireGuard, combining simplified architecture with high performance across all devices. It addresses WireGuard's main vulnerability (easy detection by DPI systems) through advanced obfuscation techniques, making VPN traffic indistinguishable from regular internet traffic. + +AmneziaWG is an excellent choice for those seeking a fast, stealthy VPN connection. + +Features: +* Available on all AmneziaVPN platforms +* Low battery consumption on mobile devices +* Minimal settings required +* Undetectable by traffic analysis systems (DPI) +* Operates over UDP protocol - A modern iteration of the popular VPN protocol, AmneziaWG builds upon the foundation set by WireGuard, retaining its simplified architecture and high-performance capabilities across devices. -While WireGuard is known for its efficiency, it had issues with being easily detected due to its distinct packet signatures. AmneziaWG solves this problem by using better obfuscation methods, making its traffic blend in with regular internet traffic. -This means that AmneziaWG keeps the fast performance of the original while adding an extra layer of stealth, making it a great choice for those wanting a fast and discreet VPN connection. + REALITY is an innovative protocol developed by the creators of XRay, designed specifically to combat high levels of internet censorship. REALITY identifies censorship systems during the TLS handshake, redirecting suspicious traffic seamlessly to legitimate websites like google.com while providing genuine TLS certificates. This allows VPN traffic to blend indistinguishably with regular web traffic without special configuration. +Unlike older protocols such as VMess, VLESS, and XTLS-Vision, REALITY incorporates an advanced built-in "friend-or-foe" detection mechanism, effectively protecting against DPI and other traffic analysis methods. -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Not recognised by traffic analysis systems -* Works over UDP network protocol. +Features: +* Resistant to active probing and DPI detection +* No special configuration required to disguise traffic +* Highly effective in heavily censored regions +* Minimal battery consumption on devices +* Operates over TCP protocol - - The REALITY protocol, a pioneering development by the creators of XRay, is designed to provide the highest level of protection against detection through its innovative approach to security and privacy. -It uniquely identifies attackers during the TLS handshake phase, seamlessly operating as a proxy for legitimate clients while diverting attackers to genuine websites, thus presenting an authentic TLS certificate and data. -This advanced capability differentiates REALITY from similar technologies by its ability to disguise web traffic as coming from random, legitimate sites without the need for specific configurations. -Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REALITY's innovative "friend or foe" recognition at the TLS handshake enhances security. This makes REALITY a robust solution for maintaining internet freedom. + + IKEv2, combined with IPSec encryption, is a modern and reliable VPN protocol. It reconnects quickly when switching networks or devices, making it ideal for dynamic network environments. While it provides good security and speed, it's easily recognized by DPI systems and susceptible to blocking. + +Features: +* Available in AmneziaVPN only on Windows +* Low battery consumption on mobile devices +* Minimal configuration required +* Detectable by DPI analysis systems(easily blocked) +* Operates over UDP protocol(ports 500 and 4500) @@ -4266,14 +4696,13 @@ It employs its unique security protocol, leveraging the strength of SSL/TLS for * TCP နှင့် UDP ကွန်ရက် ပရိုတိုကော နှစ်ခုလုံးတွင် လည်ပတ်နိုင်သည်။. - Shadowsocks, inspired by the SOCKS5 protocol, safeguards the connection using the AEAD cipher. Although Shadowsocks is designed to be discreet and challenging to identify, it isn't identical to a standard HTTPS connection.However, certain traffic analysis systems might still detect a Shadowsocks connection. Due to limited support in Amnezia, it's recommended to use AmneziaWG protocol. * Available in the AmneziaVPN only on desktop platforms * Configurable encryption protocol * Detectable by some DPI systems * Works over TCP network protocol. - SOCKS5 ပရိုတိုကောကို အတုယူအခြေခံတည်ဆောက်ထားသော Shadowsocks သည် AEAD cipher ကိုအသုံးပြု၍ ချိတ်ဆက်မှုကိုကာကွယ်ပေးသည်။ Shadowsocks သည် ထောက်လှန်းသိရှိခံရခြင်းမှရှောင်ရှားနိုင်ရန်နှင့် ထောက်လှန်းသည့်သူများခက်ခဲစေရန် ဒီဇိုင်းထုတ်ထားသော်လည်း စံသတ်မှတ်ထားသည့် HTTPS ချိတ်ဆက်မှုနှင့် ထပ်တူမကျပါ။ သို့သော်၊ အချို့သောလမ်းကြောင်းဆိုင်ရာ ခွဲခြမ်းစိတ်ဖြာမှုစနစ်များသည် Shadowsocks ချိတ်ဆက်မှုကို ရှာဖွေတွေ့ရှိနိုင်သေးသည်။ Amnezia တွင် ထောက်ပံ့မှုအကန့်အသတ်ရှိသောကြောင့် AmneziaWG ပရိုတိုကောကို အသုံးပြုရန် အကြံပြုထားသည်။ + SOCKS5 ပရိုတိုကောကို အတုယူအခြေခံတည်ဆောက်ထားသော Shadowsocks သည် AEAD cipher ကိုအသုံးပြု၍ ချိတ်ဆက်မှုကိုကာကွယ်ပေးသည်။ Shadowsocks သည် ထောက်လှန်းသိရှိခံရခြင်းမှရှောင်ရှားနိုင်ရန်နှင့် ထောက်လှန်းသည့်သူများခက်ခဲစေရန် ဒီဇိုင်းထုတ်ထားသော်လည်း စံသတ်မှတ်ထားသည့် HTTPS ချိတ်ဆက်မှုနှင့် ထပ်တူမကျပါ။ သို့သော်၊ အချို့သောလမ်းကြောင်းဆိုင်ရာ ခွဲခြမ်းစိတ်ဖြာမှုစနစ်များသည် Shadowsocks ချိတ်ဆက်မှုကို ရှာဖွေတွေ့ရှိနိုင်သေးသည်။ Amnezia တွင် ထောက်ပံ့မှုအကန့်အသတ်ရှိသောကြောင့် AmneziaWG ပရိုတိုကောကို အသုံးပြုရန် အကြံပြုထားသည်။ * Desktop ပလပ်ဖောင်းများတွင်ရှိ‌သော AmneziaVPN တွင်သာအသုံးပြုနိုင်ပါသည်။ * ပြင်ဆင်သတ်မှတ်နိုင်သော စာဝှက်စနစ် ပရိုတိုကော @@ -4301,7 +4730,7 @@ WireGuard သည် ၎င်း၏ စွမ်းဆောင်ရည်အ * UDP ကွန်ရက်ပရိုတိုကောပေါ်တွင် အလုပ်လုပ်သည်။. - + After installation, Amnezia will create a file storage on your server. You will be able to access it using @@ -4327,7 +4756,7 @@ For more detailed information, you can - + SOCKS5 proxy server SOCKS5 proxy ဆာဗာ @@ -4564,12 +4993,12 @@ For more detailed information, you can SettingsController - + All settings have been reset to default values ဆက်တင်အားလုံးကို မူရင်းတန်ဖိုးများအဖြစ် ပြန်လည်သတ်မှတ်ထားသည် - + Backup file is corrupted အရံဖိုင်ပျက်ဆီးနေသည် @@ -4701,7 +5130,7 @@ For more detailed information, you can VpnConnection - + Mbps Mbps @@ -4768,12 +5197,12 @@ For more detailed information, you can ဆင်ဆာဖြတ်တောက်ခြင်းကို ကျော်ဖြတ်ချင်ပါသည်. ဤရွေးချယ်မှုကို ကိစ္စအများစုအတွက် အကြံပြုထားသည်. - + Automatic - + AmneziaWG protocol will be installed. It provides high connection speed and ensures stable operation even in the most challenging network conditions. diff --git a/client/translations/amneziavpn_ru_RU.ts b/client/translations/amneziavpn_ru_RU.ts index 1d8766ac..be914c35 100644 --- a/client/translations/amneziavpn_ru_RU.ts +++ b/client/translations/amneziavpn_ru_RU.ts @@ -358,7 +358,7 @@ ContextMenuType - + C&ut Вырезать @@ -368,12 +368,12 @@ Копировать - + &Paste Вставить - + &SelectAll Выбрать всё @@ -436,17 +436,17 @@ Can't be disabled for current server ImportController - + Scanned %1 of %2. Отсканировано %1 из %2. - + This configuration contains an OpenVPN setup. OpenVPN configurations can include malicious scripts, so only add it if you fully trust the provider of this config. Эта конфигурация содержит настройки OpenVPN. Конфигурации OpenVPN могут содержать вредоносные скрипты, поэтому добавляйте их только в том случае, если полностью доверяете источнику этого файла. - + <br>In the imported configuration, potentially dangerous lines were found: <br>В импортированной конфигурации обнаружены потенциально опасные строки: @@ -454,71 +454,71 @@ Can't be disabled for current server InstallController - + %1 installed successfully. %1 успешно установлен. - + %1 is already installed on the server. %1 уже установлен на сервер. - + Added containers that were already installed on the server Добавлены сервисы и протоколы, которые были ранее установлены на сервер - + Already installed containers were found on the server. All installed containers have been added to the application На сервере обнаружены установленные протоколы и сервисы. Все они были добавлены в приложение - + Settings updated successfully Настройки успешно обновлены - + Server '%1' was rebooted Сервер '%1' был перезагружен - + Server '%1' was removed Сервер '%1' был удален - + All containers from server '%1' have been removed Все протоколы и сервисы были удалены с сервера '%1' - + %1 has been removed from the server '%2' %1 был удален с сервера '%2' - + Api config removed Конфигурация API удалена - + %1 cached profile cleared %1 закэшированный профиль очищен - + Please login as the user Пожалуйста, войдите в систему от имени пользователя - + Server added successfully Сервер успешно добавлен @@ -690,42 +690,87 @@ Thank you for staying with us! MTU - + Server settings Настройки сервера - + Port Порт - + + I1 - First special junk packet + + + + + I2 - Second special junk packet + + + + + I3 - Third special junk packet + + + + + I4 - Fourth special junk packet + + + + + I5 - Fifth special junk packet + + + + + J1 - First controlled junk packet + + + + + J2 - Second controlled junk packet + + + + + J3 - Third controlled junk packet + + + + + Itime - Special handshake timeout + + + + Save Сохранить - + Save settings? Сохранить настройки? - + Only the settings for this device will be changed Будут изменены настройки только для этого устройства - + Continue Продолжить - + Cancel Отменить - + Unable change settings while there is an active connection Невозможно изменить настройки во время активного соединения @@ -743,12 +788,12 @@ Thank you for staying with us! Порт - + All users with whom you shared a connection with will no longer be able to connect to it. Все пользователи, с которыми вы поделились конфигурацией вашего VPN, больше не смогут к нему подключаться. - + Save Сохранить @@ -793,42 +838,42 @@ Thank you for staying with us! H2 - Response packet magic header - + H4 - Transport packet magic header H4 - Transport packet magic header - + H3 - Underload packet magic header H3 - Underload packet magic header - + The values of the H1-H4 fields must be unique Значения в полях H1-H4 должны быть уникальными - + The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) Значение в поле S1 + размер инициации сообщения (148) не должно равняться значению в поле S2 + размер ответа на сообщение (92) - + Save settings? Сохранить настройки? - + Continue Продолжить - + Cancel Отменить - + Unable change settings while there is an active connection Невозможно изменить настройки во время активного соединения @@ -4766,12 +4811,12 @@ For more detailed information, you can SettingsController - + All settings have been reset to default values Все настройки сброшены до значений по умолчанию - + Backup file is corrupted Файл резервной копии поврежден diff --git a/client/translations/amneziavpn_uk_UA.ts b/client/translations/amneziavpn_uk_UA.ts index 3fa42c9f..8bdca6a3 100644 --- a/client/translations/amneziavpn_uk_UA.ts +++ b/client/translations/amneziavpn_uk_UA.ts @@ -9,6 +9,54 @@ + + AllowedDnsController + + + The address does not look like a valid IP address + + + + + New DNS server added: %1 + + + + + DNS server already exists: %1 + + + + + DNS server removed: %1 + + + + + Can't open file: %1 + Неможливо відкрити файл: %1 + + + + Failed to parse JSON data from file: %1 + Не вдалося розібрати JSON-данні із файлу: %1 + + + + The JSON data is not an array in file: %1 + Данні JSON не являються масивом в файлі: %1 + + + + Import completed + Імпорт завершено + + + + Export completed + Експорт завершено + + AmneziaApplication @@ -56,39 +104,131 @@ - + Free unlimited access to a basic set of websites such as Facebook, Instagram, Twitter (X), Discord, Telegram and more. YouTube is not included in the free plan. - - - amnezia_free_support_bot - - - - - amnezia_premium_support_bot - - ApiConfigsController - + %1 installed successfully. %1 встановлено успішно. - + API config reloaded Конфігурацію API перезавантажено - + Successfully changed the country of connection to %1 Успішно змінено країну підключення на %1 + + ApiPremV1MigrationDrawer + + + Switch to the new Amnezia Premium subscription + + + + + We'll preserve all remaining days of your current subscription and give you an extra month as a thank you. + + + + + This new subscription type will be actively developed with more locations and features added regularly. Currently available: + + + + + <li>13 locations (with more coming soon)</li> + + + + + <li>Easier switching between countries in the app</li> + + + + + <li>Personal dashboard to manage your subscription</li> + + + + + Old keys will be deactivated after switching. + + + + + Email + + + + + mail@example.com + + + + + No old format subscriptions for a given email + + + + + Enter the email you used for your current subscription + + + + + + Continue + Продовжити + + + + Remind me later + + + + + Don't remind me again + + + + + No more reminders? You can always switch to the new format in the server settings + + + + + Cancel + Відмінити + + + + ApiPremV1SubListDrawer + + + Choose Subscription + + + + + Order ID: + + + + + Purchase Date: + + + ApiServicesModel @@ -120,7 +260,7 @@ - AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan. + Amnezia Free provides unlimited, free access to a basic set of websites and apps, including Facebook, Instagram, Twitter (X), Discord, Telegram, and more. YouTube is not included in the free plan. @@ -138,6 +278,11 @@ %1 days %1 днів + + + + + VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a> @@ -296,7 +441,7 @@ HomeContainersListView - + Unable change protocol while there is an active connection Неможливо змінити протокол при активному підключенні @@ -367,17 +512,17 @@ Can't be disabled for current server Недійсний файл конфігурації - + Scanned %1 of %2. Відскановано %1 з %2. - + This configuration contains an OpenVPN setup. OpenVPN configurations can include malicious scripts, so only add it if you fully trust the provider of this config. - + <br>In the imported configuration, potentially dangerous lines were found: @@ -389,70 +534,70 @@ Can't be disabled for current server InstallController - + %1 installed successfully. %1 встановлено. - + %1 is already installed on the server. %1 вже встановлено на сервері. - + Added containers that were already installed on the server Додані сервіси і протоколи, які були раніше встановлені на сервері - + Already installed containers were found on the server. All installed containers have been added to the application На сервері знайдені сервіси та протоколи, всі вони додані в застосунок - + Settings updated successfully Налаштування оновлено - + Server '%1' was rebooted Сервер '%1' перезавантажено - + Server '%1' was removed Сервер '%1' був видалений - + All containers from server '%1' have been removed Всі сервіси та протоколи були видалені з сервера '%1' - + %1 has been removed from the server '%2' %1 був видалений з сервера '%2' - + Api config removed Конфігурацію API видалено - + %1 cached profile cleared Кешований профіль %1 очищено - + Please login as the user Буль-ласка, увійдіть в систему від імені користувача - + Server added successfully Сервер додано @@ -534,6 +679,24 @@ Already installed containers were found on the server. All installed containers Знайдена не захищена мережа: + + OtpCodeDrawer + + + OTP code was sent to your email + + + + + OTP Code + + + + + Continue + Продовжити + + PageDeinstalling @@ -563,27 +726,43 @@ Already installed containers were found on the server. All installed containers PageHome - + + You've successfully switched to the new Amnezia Premium subscription! + + + + + Old keys will no longer work. Please use your new subscription key to connect. +Thank you for staying with us! + + + + + Continue + Продовжити + + + Logging enabled Логування увімкнено - + Split tunneling enabled Роздільне тунелювання увімкнено - + Split tunneling disabled Роздільне тунелювання вимкнено - + VPN protocol VPN протокол - + Servers Сервери @@ -605,42 +784,87 @@ Already installed containers were found on the server. All installed containers MTU - + Server settings - + Port Порт - + + I1 - First special junk packet + + + + + I2 - Second special junk packet + + + + + I3 - Third special junk packet + + + + + I4 - Fourth special junk packet + + + + + I5 - Fifth special junk packet + + + + + J1 - First controlled junk packet + + + + + J2 - Second controlled junk packet + + + + + J3 - Third controlled junk packet + + + + + Itime - Special handshake timeout + + + + Save Зберегти - + Save settings? Зберегти налаштування? - + Only the settings for this device will be changed - + Continue Продовжити - + Cancel Відмінити - + Unable change settings while there is an active connection Неможливо змінити налаштування, поки є активне підключення @@ -699,41 +923,41 @@ Already installed containers were found on the server. All installed containers - H4 - Transport packet magic header - - - - H3 - Underload packet magic header - + + H4 - Transport packet magic header + + + + Save Зберегти - + The values of the H1-H4 fields must be unique Значення полів H1-H4 мають бути унікальними - + The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) Значення поля S1 + розмір повідомлення ініціалізації (148) не має бути рівним значенню S2 + розмір повідомлення відповіді (92) - + Save settings? Зберегти налаштування? - + All users with whom you shared a connection with will no longer be able to connect to it. Усі користувачі, з якими ви поділилися підключенням, більше не зможуть підключитися до нього. - + Unable change settings while there is an active connection Неможливо змінити налаштування, поки є активне підключення @@ -754,12 +978,12 @@ Already installed containers were found on the server. All installed containers Користувачі, з якими ви поділились цим протоколм, більше не зможуть до нього підключитись. - + Continue Продовжити - + Cancel Відмінити @@ -1216,12 +1440,17 @@ Already installed containers were found on the server. All installed containers Замаскувати трафік під - + + Port + Порт + + + Save Зберегти - + Unable change settings while there is an active connection Неможливо змінити налаштування, поки є активне підключення @@ -1713,7 +1942,7 @@ Already installed containers were found on the server. All installed containers - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -2026,7 +2255,7 @@ Already installed containers were found on the server. All installed containers - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -2062,31 +2291,16 @@ Already installed containers were found on the server. All installed containers Email - - - support@amnezia.org - - Email Billing & Orders - - - help@vpnpay.io - - Website Веб-сайт - - - amnezia.org - - Support @@ -2098,12 +2312,12 @@ Already installed containers were found on the server. All installed containers - + Support tag - + Copied Скопійовано @@ -2131,37 +2345,37 @@ Already installed containers were found on the server. All installed containers Split tunneling для додатка - + Mode Режим - + Remove Видалити - + Continue Продовжити - + Cancel Відмінити - + application name назва додатка - + Open executable file Відкрити виконуваний файл - + Executable files (*.*) Виконувані файли (*.*) @@ -2392,24 +2606,23 @@ Already installed containers were found on the server. All installed containers Ці адреси будуть використовуватись коли вимкнений AmneziaDNS - + Allows you to use the VPN only for certain Apps Дозволяє використовувати VPN тільки для вибраних застосунків - + KillSwitch KillSwitch - - Disables your internet if your encrypted VPN connection drops out for any reason. - Вимикає ваш інтернет, якщо ваше захищене VPN-підключення зникає з будь-якої причини. + + Blocks network connections without VPN + - - Cannot change KillSwitch settings during active connection - + Disables your internet if your encrypted VPN connection drops out for any reason. + Вимикає ваш інтернет, якщо ваше захищене VPN-підключення зникає з будь-якої причини. Cannot change killSwitch settings during active connection @@ -2426,7 +2639,7 @@ Already installed containers were found on the server. All installed containers Дозволяє доступ до одних сайтів через VPN, а для інших в обхід VPN - + App-based split tunneling Роздільне VPN-тунелювання застосунків @@ -2502,6 +2715,155 @@ Already installed containers were found on the server. All installed containers Зберегти налаштування + + PageSettingsKillSwitch + + + KillSwitch + KillSwitch + + + + Enable to ensure network traffic goes through a secure VPN tunnel, preventing accidental exposure of your IP and DNS queries if the connection drops + + + + + KillSwitch settings cannot be changed during an active connection + + + + + Soft KillSwitch + + + + + Internet access is blocked if the VPN disconnects unexpectedly + + + + + Strict KillSwitch + + + + + Internet connection is blocked even when VPN is turned off manually or hasn't started + + + + + Just a little heads-up + + + + + If the VPN disconnects or drops while Strict KillSwitch is enabled, internet access will be blocked. To restore access, reconnect VPN or disable/change the KillSwitch. + + + + + Continue + Продовжити + + + + Cancel + Відмінити + + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active. + + + + + PageSettingsKillSwitchExceptions + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active + + + + + Delete + + + + + Continue + Продовжити + + + + Cancel + Відмінити + + + + IPv4 address + + + + + Import / Export addresses + + + + + Import + Імпорт + + + + Save address list + + + + + Save addresses + + + + + + + Address files (*.json) + + + + + Import address list + + + + + Replace address list + + + + + + Open address file + + + + + Add imported addresses to existing ones + + + PageSettingsLogging @@ -2633,11 +2995,6 @@ Already installed containers were found on the server. All installed containers No new installed containers found Нові встановлені протоколи і сервіси не виявлені - - - - - @@ -2724,6 +3081,11 @@ Already installed containers were found on the server. All installed containers Cannot reset API config during active connection Неможливо скинути конфігурацію API під час активного підключення + + + Switch to the new Amnezia Premium subscription + + Do you want to clear server Amnezia-installed services? Ви хочете очистити сервер від сервісів Amnezia? @@ -2845,11 +3207,6 @@ Already installed containers were found on the server. All installed containers Cannot remove active container Неможливо видалити активний контейнер - - - - - Remove @@ -2902,27 +3259,27 @@ Already installed containers were found on the server. All installed containers Адреси із списку не повинні відкриватись через VPN - + Split tunneling Роздільне VPN-тунелювання - + Mode Режим - + Remove Видалити - + Continue Продовжити - + Cancel Відмінити @@ -2931,7 +3288,7 @@ Already installed containers were found on the server. All installed containers Сайт чи IP - + Import / Export Sites Імпорт / Експорт Сайтів @@ -2951,50 +3308,50 @@ Already installed containers were found on the server. All installed containers - + website or IP вебсайт або IP - + Import Імпорт - + Save site list Зберегти список сайтів - + Save sites Зберегти - - - + + + Sites files (*.json) Sites files (*.json) - + Import a list of sites Імпортувати список із сайтами - + Replace site list Замінити список із сайтами - - + + Open sites file Відкрити список із сайтами - + Add imported sites to existing ones Додати імпортовані сайти до існуючих @@ -3068,7 +3425,7 @@ It's okay as long as it's from someone you trust. Виберіть що у вас є - + File with connection settings Файл з налаштуваннями підключення @@ -3077,112 +3434,135 @@ It's okay as long as it's from someone you trust. Файл з налаштуваннями підключення або бекап - + Connection Підключення - + Settings Налаштування - + Enable logs + Export client logs + + + + + Save + Зберегти + + + + Logs files (*.log) + Logs files (*.log) + + + + Logs file saved + Файл з логами збережено + + + Support tag - + Copied Скопійовано - + Insert the key, add a configuration file or scan the QR-code Вставте ключ, додайте файл конфігурації або відскануйте QR-код - + Insert key Вставити ключ - + Insert Вставити - + Continue Продовжити - + Other connection options Інші параметри підключення - + Site Amnezia - + VPN by Amnezia VPN від Amnezia - + Connect to classic paid and free VPN services from Amnezia Підключайтеся до звичайних платних та безкоштовних VPN-сервісів від Amnezia - + Self-hosted VPN Self-hosted VPN - + Configure Amnezia VPN on your own server Налаштуйте Amnezia VPN на власному сервері - + Restore from backup Відновити із бекапа - + + + + - + Open backup file Відкрити бекап файл - + Backup files (*.backup) Файли резервної копії (*.backup) - + Open config file Відкрити файл з конфігурацією - + QR code QR-код - + I have nothing У мене нічого нема @@ -4165,37 +4545,47 @@ and will not be shared or disclosed to the Amnezia or any third parties - + + Docker error: runc doesn't work on cgroups v2 + + + + + Server error: cgroup mountpoint does not exist + + + + SSH request was denied SSH request was denied - + SSH request was interrupted SSH request was interrupted - + SSH internal error SSH internal error - + Invalid private key or invalid passphrase entered Invalid private key or invalid passphrase entered - + The selected private key format is not supported, use openssh ED25519 key types or PEM key types The selected private key format is not supported, use openssh ED25519 key types or PEM key types - + Timeout connecting to server Timeout connecting to server - + SCP error: Generic failure @@ -4252,23 +4642,23 @@ and will not be shared or disclosed to the Amnezia or any third parties Sftp error: No media was in remote drive - + The config does not contain any containers and credentials for connecting to the server Конфігурація не містить контейнерів і облікових даних для підключення до серверу - - + + Error when retrieving configuration from API - + This config has already been added to the application Ця конфігурація вже була додана в застосунок - + ErrorCode: %1. @@ -4277,139 +4667,149 @@ and will not be shared or disclosed to the Amnezia or any third parties Failed to save config to disk - + OpenVPN config missing OpenVPN config missing - + OpenVPN management server error OpenVPN management server error - + OpenVPN executable missing OpenVPN executable missing - + Shadowsocks (ss-local) executable missing Shadowsocks (ss-local) executable missing - + Cloak (ck-client) executable missing Cloak (ck-client) executable missing - + Amnezia helper service error Amnezia helper service error - + OpenSSL failed OpenSSL failed - + Can't connect: another VPN connection is active Can't connect: another VPN connection is active - + Can't setup OpenVPN TAP network adapter Can't setup OpenVPN TAP network adapter - + VPN pool error: no available addresses VPN pool error: no available addresses - + Unable to open config file - + VPN Protocols is not installed. Please install VPN container at first VPN протоколи не встановлено. Будь-ласка, встановіть VPN контейнер - + VPN connection error - + In the response from the server, an empty config was received - + SSL error occurred - + Server response timeout on api request - + Missing AGW public key - + Failed to decrypt response payload - + Missing list of available services - + The limit of allowed configurations per subscription has been exceeded - QFile error: The file could not be opened + A migration error has occurred. Please contact our technical support - QFile error: An error occurred when reading from the file - - - - - QFile error: The file could not be accessed - - - - - QFile error: An unspecified error occurred + Please update the application to use this feature - QFile error: A fatal error occurred + QFile error: The file could not be opened - QFile error: The operation was aborted + QFile error: An error occurred when reading from the file + + + + + QFile error: The file could not be accessed + + + + + QFile error: An unspecified error occurred + + + + + QFile error: A fatal error occurred + QFile error: The operation was aborted + + + + Internal error Internal error @@ -4506,7 +4906,6 @@ REALITY унікально ідентифікує цензорів під час На відміну від старіших протоколів, таких як VMess, VLESS та XTLS-Vision transport, продвиуте розпізнавання "Свій — Чужий" REALITY під час TLS-handshake підвищує безпеку та протидіє виявленню складними системами DPI, що використовують активні техніки аналізу. Це робить REALITY надійним рішенням для підтримання інтернет-свободи в середовищах з жорсткою цензурою. - IKEv2, paired with the IPSec encryption layer, stands as a modern and stable VPN protocol. One of its distinguishing features is its ability to swiftly switch between networks and devices, making it particularly adaptive in dynamic network environments. While it offers a blend of security, stability, and speed, it's essential to note that IKEv2 can be easily detected and is susceptible to blocking. @@ -4516,7 +4915,7 @@ While it offers a blend of security, stability, and speed, it's essential t * Minimal configuration * Recognised by DPI analysis systems * Works over UDP network protocol, ports 500 and 4500. - IKEv2 разом з шифруванням IPSec -- це сучасний та стабільний протокол VPN. + IKEv2 разом з шифруванням IPSec -- це сучасний та стабільний протокол VPN. Він може швидко переключись між мережами та пристроями, що робить його осболиво адаптованим під динамічні мережеві середовища. Потрібно зазначити, що незважаючи на стабільність та швидкість, IKEv2 легко розпізнається та вразливий до блокувань. @@ -4527,7 +4926,7 @@ While it offers a blend of security, stability, and speed, it's essential t * Працює по мережевому протоколу UDP, порти 500 і 4500. - + DNS Service DNS Сервіс @@ -4538,7 +4937,7 @@ While it offers a blend of security, stability, and speed, it's essential t - + Website in Tor network Веб-сайт в мережі Tor @@ -4577,16 +4976,101 @@ While it offers a blend of security, stability, and speed, it's essential t XRay with REALITY masks VPN traffic as web traffic and protects against active probing. It is highly resistant to detection and offers high speed. + + + + + - OpenVPN stands as one of the most popular and time-tested VPN protocols available. -It employs its unique security protocol, leveraging the strength of SSL/TLS for encryption and key exchange. Furthermore, OpenVPN's support for a multitude of authentication methods makes it versatile and adaptable, catering to a wide range of devices and operating systems. Due to its open-source nature, OpenVPN benefits from extensive scrutiny by the global community, which continually reinforces its security. With a strong balance of performance, security, and compatibility, OpenVPN remains a top choice for privacy-conscious individuals and businesses alike. + OpenVPN is one of the most popular and reliable VPN protocols. It uses SSL/TLS encryption, supports a wide variety of devices and operating systems, and is continuously improved by the community due to its open-source nature. It provides a good balance between speed and security but is easily recognized by DPI systems, making it susceptible to blocking. -* Available in the AmneziaVPN across all platforms -* Normal power consumption on mobile devices -* Flexible customisation to suit user needs to work with different operating systems and devices -* Recognised by DPI systems and therefore susceptible to blocking -* Can operate over both TCP and UDP network protocols. +Features: +* Available on all AmneziaVPN platforms +* Normal battery consumption on mobile devices +* Flexible customization for various devices and OS +* Operates over both TCP and UDP protocols + + + + + Shadowsocks is based on the SOCKS5 protocol and encrypts connections using AEAD cipher. Although designed to be discreet, it doesn't mimic a standard HTTPS connection and can be detected by some DPI systems. Due to limited support in Amnezia, we recommend using the AmneziaWG protocol. + +Features: +* Available in AmneziaVPN only on desktop platforms +* Customizable encryption protocol +* Detectable by some DPI systems +* Operates over TCP protocol + + + + + + This combination includes the OpenVPN protocol and the Cloak plugin, specifically designed to protect against blocking. + +OpenVPN securely encrypts all internet traffic between your device and the server. + +The Cloak plugin further protects the connection from DPI detection. It modifies traffic metadata to disguise VPN traffic as regular web traffic and prevents detection through active probing. If an incoming connection fails authentication, Cloak serves a fake website, making your VPN invisible to traffic analysis systems. + +In regions with heavy internet censorship, we strongly recommend using OpenVPN with Cloak from your first connection. + +Features: +* Available on all AmneziaVPN platforms +* High power consumption on mobile devices +* Flexible configuration options +* Undetectable by DPI systems +* Operates over TCP protocol on port 443 + + + + + WireGuard is a modern, streamlined VPN protocol offering stable connectivity and excellent performance across all devices. It uses fixed encryption settings, delivering lower latency and higher data transfer speeds compared to OpenVPN. However, WireGuard is easily identifiable by DPI systems due to its distinctive packet signatures, making it susceptible to blocking. + +Features: +* Available on all AmneziaVPN platforms +* Low power consumption on mobile devices +* Minimal configuration required +* Easily detected by DPI systems (susceptible to blocking) +* Operates over UDP protocol + + + + + AmneziaWG is a modern VPN protocol based on WireGuard, combining simplified architecture with high performance across all devices. It addresses WireGuard's main vulnerability (easy detection by DPI systems) through advanced obfuscation techniques, making VPN traffic indistinguishable from regular internet traffic. + +AmneziaWG is an excellent choice for those seeking a fast, stealthy VPN connection. + +Features: +* Available on all AmneziaVPN platforms +* Low battery consumption on mobile devices +* Minimal settings required +* Undetectable by traffic analysis systems (DPI) +* Operates over UDP protocol + + + + + REALITY is an innovative protocol developed by the creators of XRay, designed specifically to combat high levels of internet censorship. REALITY identifies censorship systems during the TLS handshake, redirecting suspicious traffic seamlessly to legitimate websites like google.com while providing genuine TLS certificates. This allows VPN traffic to blend indistinguishably with regular web traffic without special configuration. +Unlike older protocols such as VMess, VLESS, and XTLS-Vision, REALITY incorporates an advanced built-in "friend-or-foe" detection mechanism, effectively protecting against DPI and other traffic analysis methods. + +Features: +* Resistant to active probing and DPI detection +* No special configuration required to disguise traffic +* Highly effective in heavily censored regions +* Minimal battery consumption on devices +* Operates over TCP protocol + + + + + IKEv2, combined with IPSec encryption, is a modern and reliable VPN protocol. It reconnects quickly when switching networks or devices, making it ideal for dynamic network environments. While it provides good security and speed, it's easily recognized by DPI systems and susceptible to blocking. + +Features: +* Available in AmneziaVPN only on Windows +* Low battery consumption on mobile devices +* Minimal configuration required +* Detectable by DPI analysis systems(easily blocked) +* Operates over UDP protocol(ports 500 and 4500) @@ -4634,14 +5118,13 @@ It employs its unique security protocol, leveraging the strength of SSL/TLS for * Може працювати за протоколом TCP і UDP. - Shadowsocks, inspired by the SOCKS5 protocol, safeguards the connection using the AEAD cipher. Although Shadowsocks is designed to be discreet and challenging to identify, it isn't identical to a standard HTTPS connection.However, certain traffic analysis systems might still detect a Shadowsocks connection. Due to limited support in Amnezia, it's recommended to use AmneziaWG protocol. * Available in the AmneziaVPN only on desktop platforms * Configurable encryption protocol * Detectable by some DPI systems * Works over TCP network protocol. - Shadowsocks, створений на основі протоколу SOCKS5, захищає з'єднання AEAD шифруванням. Незважаючи на те, що протокол Shadowsocks розроблений таким чином, щоб бути незаметним і складним для ідентифікації, він не ідентичний стандартному HTTPS-з'єднанню. Однак деякі системи аналізу трафіку все-таки можуть знайти підключення Shadowsocks. У зв’язку з обмеженою підтримкою в Amnezia рекомендується використовувати протокол AmneziaWG або OpenVPN через Cloak. + Shadowsocks, створений на основі протоколу SOCKS5, захищає з'єднання AEAD шифруванням. Незважаючи на те, що протокол Shadowsocks розроблений таким чином, щоб бути незаметним і складним для ідентифікації, він не ідентичний стандартному HTTPS-з'єднанню. Однак деякі системи аналізу трафіку все-таки можуть знайти підключення Shadowsocks. У зв’язку з обмеженою підтримкою в Amnezia рекомендується використовувати протокол AmneziaWG або OpenVPN через Cloak. * Доступний в AmneziaVPN тільки на ПК. * Гнучке налаштування протоколу шифрування @@ -4649,61 +5132,7 @@ It employs its unique security protocol, leveraging the strength of SSL/TLS for * Працює по мережевому протоколу TCP. - - This is a combination of the OpenVPN protocol and the Cloak plugin designed specifically for protecting against detection. - -OpenVPN provides a secure VPN connection by encrypting all internet traffic between the client and the server. - -Cloak protects OpenVPN from detection. - -Cloak can modify packet metadata so that it completely masks VPN traffic as normal web traffic, and also protects the VPN from detection by Active Probing. This makes it very resistant to being detected - -Immediately after receiving the first data packet, Cloak authenticates the incoming connection. If authentication fails, the plugin masks the server as a fake website and your VPN becomes invisible to analysis systems. - -* Available in the AmneziaVPN across all platforms -* High power consumption on mobile devices -* Flexible settings -* Not recognised by detection systems -* Works over TCP network protocol, 443 port. - - - - - - A relatively new popular VPN protocol with a simplified architecture. -WireGuard provides stable VPN connection and high performance on all devices. It uses hard-coded encryption settings. WireGuard compared to OpenVPN has lower latency and better data transfer throughput. -WireGuard is very susceptible to detection and blocking due to its distinct packet signatures. Unlike some other VPN protocols that employ obfuscation techniques, the consistent signature patterns of WireGuard packets can be more easily identified and thus blocked by advanced Deep Packet Inspection (DPI) systems and other network monitoring tools. - -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Easily recognised by DPI analysis systems, susceptible to blocking -* Works over UDP network protocol. - - - - - A modern iteration of the popular VPN protocol, AmneziaWG builds upon the foundation set by WireGuard, retaining its simplified architecture and high-performance capabilities across devices. -While WireGuard is known for its efficiency, it had issues with being easily detected due to its distinct packet signatures. AmneziaWG solves this problem by using better obfuscation methods, making its traffic blend in with regular internet traffic. -This means that AmneziaWG keeps the fast performance of the original while adding an extra layer of stealth, making it a great choice for those wanting a fast and discreet VPN connection. - -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Not recognised by traffic analysis systems -* Works over UDP network protocol. - - - - - The REALITY protocol, a pioneering development by the creators of XRay, is designed to provide the highest level of protection against detection through its innovative approach to security and privacy. -It uniquely identifies attackers during the TLS handshake phase, seamlessly operating as a proxy for legitimate clients while diverting attackers to genuine websites, thus presenting an authentic TLS certificate and data. -This advanced capability differentiates REALITY from similar technologies by its ability to disguise web traffic as coming from random, legitimate sites without the need for specific configurations. -Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REALITY's innovative "friend or foe" recognition at the TLS handshake enhances security. This makes REALITY a robust solution for maintaining internet freedom. - - - - + After installation, Amnezia will create a file storage on your server. You will be able to access it using @@ -4814,7 +5243,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin - + SOCKS5 proxy server SOCKS5 proxy server @@ -5051,7 +5480,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin SettingsController - + All settings have been reset to default values Всі налаштування були скинуті до значення "По замовчуванню" @@ -5060,7 +5489,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin Кеш профілю очищено - + Backup file is corrupted Backup файл пошкодженно @@ -5192,7 +5621,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin VpnConnection - + Mbps Mbps @@ -5283,12 +5712,12 @@ This means that AmneziaWG keeps the fast performance of the original while addin Я просто хочу підвищити свій рівень безпеки в інтернеті. - + Automatic - + AmneziaWG protocol will be installed. It provides high connection speed and ensures stable operation even in the most challenging network conditions. diff --git a/client/translations/amneziavpn_ur_PK.ts b/client/translations/amneziavpn_ur_PK.ts index 3a8b8172..eac64da8 100644 --- a/client/translations/amneziavpn_ur_PK.ts +++ b/client/translations/amneziavpn_ur_PK.ts @@ -9,6 +9,54 @@ + + AllowedDnsController + + + The address does not look like a valid IP address + + + + + New DNS server added: %1 + + + + + DNS server already exists: %1 + + + + + DNS server removed: %1 + + + + + Can't open file: %1 + فائل نہیں کھول سکتا: %1 + + + + Failed to parse JSON data from file: %1 + فائل سے JSON ڈیٹا پارس کرنے میں ناکامی: %1 + + + + The JSON data is not an array in file: %1 + فائل میں JSON ڈیٹا ایک ایرے نہیں ہے: %1 + + + + Import completed + واردات مکمل ہوگئی ہے + + + + Export completed + ایکسپورٹ مکمل ہوگیا + + ApiAccountInfoModel @@ -33,39 +81,131 @@ - + Free unlimited access to a basic set of websites such as Facebook, Instagram, Twitter (X), Discord, Telegram and more. YouTube is not included in the free plan. - - - amnezia_free_support_bot - - - - - amnezia_premium_support_bot - - ApiConfigsController - + %1 installed successfully. - + API config reloaded - + Successfully changed the country of connection to %1 + + ApiPremV1MigrationDrawer + + + Switch to the new Amnezia Premium subscription + + + + + We'll preserve all remaining days of your current subscription and give you an extra month as a thank you. + + + + + This new subscription type will be actively developed with more locations and features added regularly. Currently available: + + + + + <li>13 locations (with more coming soon)</li> + + + + + <li>Easier switching between countries in the app</li> + + + + + <li>Personal dashboard to manage your subscription</li> + + + + + Old keys will be deactivated after switching. + + + + + Email + + + + + mail@example.com + + + + + No old format subscriptions for a given email + + + + + Enter the email you used for your current subscription + + + + + + Continue + + + + + Remind me later + + + + + Don't remind me again + + + + + No more reminders? You can always switch to the new format in the server settings + + + + + Cancel + + + + + ApiPremV1SubListDrawer + + + Choose Subscription + + + + + Order ID: + + + + + Purchase Date: + + + ApiServicesModel @@ -81,7 +221,7 @@ - AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan. + Amnezia Free provides unlimited, free access to a basic set of websites and apps, including Facebook, Instagram, Twitter (X), Discord, Telegram, and more. YouTube is not included in the free plan. @@ -99,6 +239,11 @@ %1 days + + + + + VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a> @@ -256,7 +401,7 @@ HomeContainersListView - + Unable change protocol while there is an active connection موجودہ کنکشن ہونے کے دوران پروٹوکول کو تبدیل کرنے سے قاصر ہے @@ -318,17 +463,17 @@ Can't be disabled for current server غلط کنفیگریشن فائل - + Scanned %1 of %2. سکین%1 کی%2. - + This configuration contains an OpenVPN setup. OpenVPN configurations can include malicious scripts, so only add it if you fully trust the provider of this config. - + <br>In the imported configuration, potentially dangerous lines were found: @@ -336,71 +481,71 @@ Can't be disabled for current server InstallController - + %1 installed successfully. %1 کامیابی سےنصب. - + %1 is already installed on the server. %1 پہلے ہی سرور پر انسٹال ہے. - + Added containers that were already installed on the server وہ کنٹینرز شامل کیے گئے جو پہلے سے سرور پر نصب تھے - + Already installed containers were found on the server. All installed containers have been added to the application سرور پر پہلے سے نصب کنٹینرز پائے گئے۔ تمام نصب کنٹینرز کو ایپلی کیشن میں شامل کر دیا گیا ہے - + Settings updated successfully ترتیب کامیابی کے ساتھ اپ ڈیٹ ہو گئی - + Server '%1' was rebooted سرور %1 دوبارہ چالو کیا گیا تھا - + Server '%1' was removed سرور %1 ہٹا دیا گیا تھا - + All containers from server '%1' have been removed سرور '%1' سے تمام کنٹینرز ہٹا دیے گئے ہیں - + %1 has been removed from the server '%2' سرور '%2' سے %1 ہٹا دیا گیا ہے - + Api config removed - + %1 cached profile cleared %1 کیش کردہ پروفائل ختم کر دی گئی - + Please login as the user براہ کرم صارف کے طور پر لاگ ان کریں - + Server added successfully سرور کامیابی سے شامل کیا گیا @@ -472,6 +617,24 @@ Already installed containers were found on the server. All installed containers غیر محفوظ نیٹ ورک کا پتہ لگایا گیا ہے: + + OtpCodeDrawer + + + OTP code was sent to your email + + + + + OTP Code + + + + + Continue + + + PageDeinstalling @@ -501,27 +664,43 @@ Already installed containers were found on the server. All installed containers PageHome - + + You've successfully switched to the new Amnezia Premium subscription! + + + + + Old keys will no longer work. Please use your new subscription key to connect. +Thank you for staying with us! + + + + + Continue + + + + Logging enabled لاگنگ فعال ہے - + Split tunneling enabled سپلٹ ٹنلنگ فعال ہے - + Split tunneling disabled سپلٹ ٹنلنگ غیر فعال ہے - + VPN protocol وی پی این پروٹوکول - + Servers سرور @@ -543,42 +722,87 @@ Already installed containers were found on the server. All installed containers ام ٹی یو - + Server settings - + Port پورٹ - + + I1 - First special junk packet + + + + + I2 - Second special junk packet + + + + + I3 - Third special junk packet + + + + + I4 - Fourth special junk packet + + + + + I5 - Fifth special junk packet + + + + + J1 - First controlled junk packet + + + + + J2 - Second controlled junk packet + + + + + J3 - Third controlled junk packet + + + + + Itime - Special handshake timeout + + + + Save - + Save settings? ترتیبات محفوظ کریں? - + Only the settings for this device will be changed - + Continue - + Cancel - + Unable change settings while there is an active connection جب ایک فعال کنکشن موجود ہو تو ترتیبات کو تبدیل نہیں کیا جا سکتا @@ -600,12 +824,12 @@ Already installed containers were found on the server. All installed containers ام ٹی یو - + All users with whom you shared a connection with will no longer be able to connect to it. آپ جن لوگوں کے ساتھ آپ نے اس کنکشن کا اشتراک کیا تھا، وہ اس سے مزید جڑ نہیں سکیں گے۔ - + Save محفوظ کریں @@ -651,41 +875,41 @@ Already installed containers were found on the server. All installed containers - H4 - Transport packet magic header - - - - H3 - Underload packet magic header - + + H4 - Transport packet magic header + + + + The values of the H1-H4 fields must be unique H1 تا H4 فیلڈز کی قیمتیں مخصوص ہونی چاہیے - + The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) S1 + پیغام شروع کار (148) کے فیلڈ کی قیمت S2 + پیغام جواب (92) کے سائز کے برابر نہیں ہونی چاہئے - + Save settings? ترتیبات محفوظ کریں? - + Continue جاری رکھیں - + Cancel منسوخ کریں - + Unable change settings while there is an active connection جب ایک فعال کنکشن موجود ہو تو ترتیبات کو تبدیل نہیں کیا جا سکتا @@ -1090,12 +1314,17 @@ Already installed containers were found on the server. All installed containers کے طور پر ٹریفک کی طرح - + + Port + پورٹ + + + Save محفوظ - + Unable change settings while there is an active connection جب ایک فعال کنکشن موجود ہو تو ترتیبات کو تبدیل نہیں کیا جا سکتا @@ -1544,7 +1773,7 @@ Already installed containers were found on the server. All installed containers - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -1837,7 +2066,7 @@ Already installed containers were found on the server. All installed containers - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -1873,31 +2102,16 @@ Already installed containers were found on the server. All installed containers Email - - - support@amnezia.org - - Email Billing & Orders - - - help@vpnpay.io - - Website ویب سائٹ - - - amnezia.org - - Support @@ -1909,12 +2123,12 @@ Already installed containers were found on the server. All installed containers - + Support tag - + Copied @@ -1950,37 +2164,37 @@ Already installed containers were found on the server. All installed containers ایپ اسپلٹ ٹنلنگ - + Mode موڈ - + Remove ہٹائیں - + Continue جاری رکھیں - + Cancel منسوخ - + application name ایپ کا نام - + Open executable file قابل اجراء فائل کو کھولیں - + Executable files (*.*) قابل اجراء فائل (*.*) @@ -2180,7 +2394,7 @@ Already installed containers were found on the server. All installed containers ایمنیزیا ڈی این ایس کو استعمال نہیں کیا گیا ہو یا اسے انسٹال نہیں کیا گیاہے - + Allows you to use the VPN only for certain Apps آپ کو صرف مخصوص ایپلیکیشنز کے لئے وی پی این استعمال کرنے کی اجازت دیتا ہے @@ -2210,23 +2424,18 @@ Already installed containers were found on the server. All installed containers آپ کو یہ امکان فراہم کرتا ہے کہ آپ وی پی این کے ذریعہ کس سائٹ کو دسترس دینا چاہتے ہیں وہ منتخب کریں - + App-based split tunneling ایپ کے بنیاد پر سپلٹ ٹنلنگ - + KillSwitch - - Disables your internet if your encrypted VPN connection drops out for any reason. - - - - - Cannot change KillSwitch settings during active connection + + Blocks network connections without VPN @@ -2293,6 +2502,155 @@ Already installed containers were found on the server. All installed containers ترتیبات محفوظ ہوگئیں + + PageSettingsKillSwitch + + + KillSwitch + + + + + Enable to ensure network traffic goes through a secure VPN tunnel, preventing accidental exposure of your IP and DNS queries if the connection drops + + + + + KillSwitch settings cannot be changed during an active connection + + + + + Soft KillSwitch + + + + + Internet access is blocked if the VPN disconnects unexpectedly + + + + + Strict KillSwitch + + + + + Internet connection is blocked even when VPN is turned off manually or hasn't started + + + + + Just a little heads-up + + + + + If the VPN disconnects or drops while Strict KillSwitch is enabled, internet access will be blocked. To restore access, reconnect VPN or disable/change the KillSwitch. + + + + + Continue + + + + + Cancel + + + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active. + + + + + PageSettingsKillSwitchExceptions + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active + + + + + Delete + + + + + Continue + + + + + Cancel + + + + + IPv4 address + + + + + Import / Export addresses + + + + + Import + درآمد + + + + Save address list + + + + + Save addresses + + + + + + + Address files (*.json) + + + + + Import address list + + + + + Replace address list + + + + + + Open address file + + + + + Add imported addresses to existing ones + + + PageSettingsLogging @@ -2422,11 +2780,6 @@ Already installed containers were found on the server. All installed containers Do you want to clear server from Amnezia software? هل تريد حذف الخادم من Amnezia?کیا آپ سرور کو Amnezia سافٹ ویئر سے صاف کرنا چاہتے ہیں؟ - - - - - @@ -2508,6 +2861,11 @@ Already installed containers were found on the server. All installed containers Cannot reset API config during active connection چالو کنکشن کے دوران API ترتیبات کو دوبارہ ترتیب نہیں دی جا سکتی + + + Switch to the new Amnezia Premium subscription + + All installed AmneziaVPN services will still remain on the server. @@ -2571,11 +2929,6 @@ Already installed containers were found on the server. All installed containers Cannot remove active container فعال کنٹینر کو ہٹانا ممکن نہیں - - - - - Remove @@ -2650,27 +3003,27 @@ Already installed containers were found on the server. All installed containers اس فہرست سے پتوں کا وی پی این کے ذریعے دسترس حاصل نہیں کیا جانا چاہئے - + Split tunneling اسپلٹ ٹنلنگ - + Mode موڈ - + Remove ہٹائیں - + Continue براہ کرم جاری رکھیں - + Cancel منسوخ @@ -2685,55 +3038,55 @@ Already installed containers were found on the server. All installed containers فعال کنکشن کے دوران سپلٹ ٹنلنگ کی ترتیبات تبدیل نہیں کی جا سکتیں - + website or IP ویب سائٹ یا آئی پی - + Import / Export Sites سائٹس درآمد / برآمد - + Import درآمد - + Save site list سائٹ کی فہرست کو محفوظ کریں - + Save sites سائٹس کو محفوظ کریں - - - + + + Sites files (*.json) سائٹس فائلیں (*.json) - + Import a list of sites ایک فہرست کو درآمد کریں - + Replace site list سائٹ کی فہرست کو بدلیں - - + + Open sites file سائٹس فائل کو کھولیں - + Add imported sites to existing ones آمدہ سائٹس کو موجودہ میں شامل کریں @@ -2803,117 +3156,140 @@ Already installed containers were found on the server. All installed containers کنکشن کی ترتیبات یا بیک اپ والی فائل - + Connection کنکشن - + Settings ترتیبات - + Enable logs - Support tag + Export client logs + + + + + Save - Copied - + Logs files (*.log) + لاگ فائلیں (*.log) + + + + Logs file saved + لاگ فائل محفوظ ہوگئی - Insert the key, add a configuration file or scan the QR-code - - - - - Insert key + Support tag + Copied + + + + + Insert the key, add a configuration file or scan the QR-code + + + + + Insert key + + + + Insert داخل کریں - + Continue - + Other connection options - + Site Amnezia - + VPN by Amnezia - + Connect to classic paid and free VPN services from Amnezia - + Self-hosted VPN - + Configure Amnezia VPN on your own server - + Restore from backup بیک اپ سے بحال کریں - + + + + - + Open backup file بیک اپ فائل کو کھولیں - + Backup files (*.backup) بیک اپ فائلیں (*.backup) - + File with connection settings کنکشن کی ترتیبات والی فائل - + Open config file کنفیگ فائل کو کھولیں - + QR code QR کوڈ - + I have nothing میرے پاس کچھ نہیں ہے @@ -3757,7 +4133,7 @@ Already installed containers were found on the server. All installed containers - + SOCKS5 proxy server @@ -3808,58 +4184,58 @@ Already installed containers were found on the server. All installed containers صارف sudo گروپ کا رکن نہیں ہے - + SSH request was denied SSH درخواست مسترد کر دی گئی - + SSH request was interrupted SSH درخواست میں خلل پڑ - + SSH internal error SSH اندرونی خرابی - + Invalid private key or invalid passphrase entered غلط نجی کلید یا غلط پاسفریز درج کیا گیا - + The selected private key format is not supported, use openssh ED25519 key types or PEM key types منتخب کردہ پرائیویٹ کلیدی فارمیٹ تعاون یافتہ نہیں ہے، openssh ED25519 کلیدی اقسام یا PEM کلیدی اقسام استعمال کریں - + Timeout connecting to server سرور سے منسلک ہونے کا ٹائم آؤٹ - + VPN connection error VPN کنکشن کی خرابی - - + + Error when retrieving configuration from API آپی سے کنفیگریشن بازیافت کرتے وقت خرابی - + This config has already been added to the application یہ تشکیل پہلے ہی ایپلی کیشن میں شامل کی جا چکی ہے - + ErrorCode: %1. ایرر کوڈ: %1. - + OpenVPN config missing OpenVPN تشکیل غائب ہے @@ -3899,138 +4275,158 @@ Already installed containers were found on the server. All installed containers - + + Docker error: runc doesn't work on cgroups v2 + + + + + Server error: cgroup mountpoint does not exist + + + + SCP error: Generic failure ایس سی پی کی خرابی: عام ناکامی - + OpenVPN management server error OpenVPN مینجمنٹ سرور کی خرابی - + OpenVPN executable missing OpenVPN قابل عمل غائب ہے - + Shadowsocks (ss-local) executable missing شیڈو ساکس (ss-local) قابل عمل غائب - + Cloak (ck-client) executable missing Cloak (ck-client) قابل عمل غائب - + Amnezia helper service error ایمنیزیا مددگار سروس کی خرابی - + OpenSSL failed OpenSSL ناکام ہوگیا - + Can't connect: another VPN connection is active منسلک نہیں ہو سکتا: دوسرا VPN کنکشن فعال ہے - + Can't setup OpenVPN TAP network adapter OpenVPN TAP نیٹ ورک اڈاپٹر سیٹ اپ نہیں کر سکتے - + VPN pool error: no available addresses VPN پول کی خرابی: کوئی پتہ دستیاب نہیں ہے - + The config does not contain any containers and credentials for connecting to the server ترتیب میں سرور سے منسلک ہونے کے لیے کوئی کنٹینرز اور اسناد نہیں ہیں - + Unable to open config file - + VPN Protocols is not installed. Please install VPN container at first وی پی این پروٹوکول انسٹال نہیں ہے,براہ کرم پہلےوی پی این کنٹینر انسٹال کریں - + In the response from the server, an empty config was received - + SSL error occurred - + Server response timeout on api request - + Missing AGW public key - + Failed to decrypt response payload - + Missing list of available services - + The limit of allowed configurations per subscription has been exceeded + A migration error has occurred. Please contact our technical support + + + + + Please update the application to use this feature + + + + QFile error: The file could not be opened QFile کی خرابی: فائل کو نہیں کھولا جا سکا - + QFile error: An error occurred when reading from the file کیو فائل کی خرابی: فائل سے پڑھتے وقت ایک خرابی پیش آگئی - + QFile error: The file could not be accessed QFile کی خرابی: فائل تک رسائی نہیں ہو سکی - + QFile error: An unspecified error occurred کیو فائل میں خرابی: ایک غیر متعینہ خرابی پیش آگئی - + QFile error: A fatal error occurred کیو فائل میں خرابی: ایک مہلک خرابی پیش آگئی - + QFile error: The operation was aborted کیو فائل کی خرابی: آپریشن روک دیا گیا تھا - + Internal error داخلی خامی @@ -4041,7 +4437,7 @@ Already installed containers were found on the server. All installed containers - + Website in Tor network ٹور نیٹ ورک میں ویب سائٹ @@ -4086,69 +4482,100 @@ Already installed containers were found on the server. All installed containers - - OpenVPN stands as one of the most popular and time-tested VPN protocols available. -It employs its unique security protocol, leveraging the strength of SSL/TLS for encryption and key exchange. Furthermore, OpenVPN's support for a multitude of authentication methods makes it versatile and adaptable, catering to a wide range of devices and operating systems. Due to its open-source nature, OpenVPN benefits from extensive scrutiny by the global community, which continually reinforces its security. With a strong balance of performance, security, and compatibility, OpenVPN remains a top choice for privacy-conscious individuals and businesses alike. - -* Available in the AmneziaVPN across all platforms -* Normal power consumption on mobile devices -* Flexible customisation to suit user needs to work with different operating systems and devices -* Recognised by DPI systems and therefore susceptible to blocking -* Can operate over both TCP and UDP network protocols. + + - - This is a combination of the OpenVPN protocol and the Cloak plugin designed specifically for protecting against detection. + + OpenVPN is one of the most popular and reliable VPN protocols. It uses SSL/TLS encryption, supports a wide variety of devices and operating systems, and is continuously improved by the community due to its open-source nature. It provides a good balance between speed and security but is easily recognized by DPI systems, making it susceptible to blocking. -OpenVPN provides a secure VPN connection by encrypting all internet traffic between the client and the server. +Features: +* Available on all AmneziaVPN platforms +* Normal battery consumption on mobile devices +* Flexible customization for various devices and OS +* Operates over both TCP and UDP protocols + + + + + Shadowsocks is based on the SOCKS5 protocol and encrypts connections using AEAD cipher. Although designed to be discreet, it doesn't mimic a standard HTTPS connection and can be detected by some DPI systems. Due to limited support in Amnezia, we recommend using the AmneziaWG protocol. -Cloak protects OpenVPN from detection. - -Cloak can modify packet metadata so that it completely masks VPN traffic as normal web traffic, and also protects the VPN from detection by Active Probing. This makes it very resistant to being detected - -Immediately after receiving the first data packet, Cloak authenticates the incoming connection. If authentication fails, the plugin masks the server as a fake website and your VPN becomes invisible to analysis systems. - -* Available in the AmneziaVPN across all platforms -* High power consumption on mobile devices -* Flexible settings -* Not recognised by detection systems -* Works over TCP network protocol, 443 port. +Features: +* Available in AmneziaVPN only on desktop platforms +* Customizable encryption protocol +* Detectable by some DPI systems +* Operates over TCP protocol - - A relatively new popular VPN protocol with a simplified architecture. -WireGuard provides stable VPN connection and high performance on all devices. It uses hard-coded encryption settings. WireGuard compared to OpenVPN has lower latency and better data transfer throughput. -WireGuard is very susceptible to detection and blocking due to its distinct packet signatures. Unlike some other VPN protocols that employ obfuscation techniques, the consistent signature patterns of WireGuard packets can be more easily identified and thus blocked by advanced Deep Packet Inspection (DPI) systems and other network monitoring tools. + + This combination includes the OpenVPN protocol and the Cloak plugin, specifically designed to protect against blocking. -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Easily recognised by DPI analysis systems, susceptible to blocking -* Works over UDP network protocol. +OpenVPN securely encrypts all internet traffic between your device and the server. + +The Cloak plugin further protects the connection from DPI detection. It modifies traffic metadata to disguise VPN traffic as regular web traffic and prevents detection through active probing. If an incoming connection fails authentication, Cloak serves a fake website, making your VPN invisible to traffic analysis systems. + +In regions with heavy internet censorship, we strongly recommend using OpenVPN with Cloak from your first connection. + +Features: +* Available on all AmneziaVPN platforms +* High power consumption on mobile devices +* Flexible configuration options +* Undetectable by DPI systems +* Operates over TCP protocol on port 443 + + + + + WireGuard is a modern, streamlined VPN protocol offering stable connectivity and excellent performance across all devices. It uses fixed encryption settings, delivering lower latency and higher data transfer speeds compared to OpenVPN. However, WireGuard is easily identifiable by DPI systems due to its distinctive packet signatures, making it susceptible to blocking. + +Features: +* Available on all AmneziaVPN platforms +* Low power consumption on mobile devices +* Minimal configuration required +* Easily detected by DPI systems (susceptible to blocking) +* Operates over UDP protocol + + + + + AmneziaWG is a modern VPN protocol based on WireGuard, combining simplified architecture with high performance across all devices. It addresses WireGuard's main vulnerability (easy detection by DPI systems) through advanced obfuscation techniques, making VPN traffic indistinguishable from regular internet traffic. + +AmneziaWG is an excellent choice for those seeking a fast, stealthy VPN connection. + +Features: +* Available on all AmneziaVPN platforms +* Low battery consumption on mobile devices +* Minimal settings required +* Undetectable by traffic analysis systems (DPI) +* Operates over UDP protocol - A modern iteration of the popular VPN protocol, AmneziaWG builds upon the foundation set by WireGuard, retaining its simplified architecture and high-performance capabilities across devices. -While WireGuard is known for its efficiency, it had issues with being easily detected due to its distinct packet signatures. AmneziaWG solves this problem by using better obfuscation methods, making its traffic blend in with regular internet traffic. -This means that AmneziaWG keeps the fast performance of the original while adding an extra layer of stealth, making it a great choice for those wanting a fast and discreet VPN connection. + REALITY is an innovative protocol developed by the creators of XRay, designed specifically to combat high levels of internet censorship. REALITY identifies censorship systems during the TLS handshake, redirecting suspicious traffic seamlessly to legitimate websites like google.com while providing genuine TLS certificates. This allows VPN traffic to blend indistinguishably with regular web traffic without special configuration. +Unlike older protocols such as VMess, VLESS, and XTLS-Vision, REALITY incorporates an advanced built-in "friend-or-foe" detection mechanism, effectively protecting against DPI and other traffic analysis methods. -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Not recognised by traffic analysis systems -* Works over UDP network protocol. +Features: +* Resistant to active probing and DPI detection +* No special configuration required to disguise traffic +* Highly effective in heavily censored regions +* Minimal battery consumption on devices +* Operates over TCP protocol - - The REALITY protocol, a pioneering development by the creators of XRay, is designed to provide the highest level of protection against detection through its innovative approach to security and privacy. -It uniquely identifies attackers during the TLS handshake phase, seamlessly operating as a proxy for legitimate clients while diverting attackers to genuine websites, thus presenting an authentic TLS certificate and data. -This advanced capability differentiates REALITY from similar technologies by its ability to disguise web traffic as coming from random, legitimate sites without the need for specific configurations. -Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REALITY's innovative "friend or foe" recognition at the TLS handshake enhances security. This makes REALITY a robust solution for maintaining internet freedom. + + IKEv2, combined with IPSec encryption, is a modern and reliable VPN protocol. It reconnects quickly when switching networks or devices, making it ideal for dynamic network environments. While it provides good security and speed, it's easily recognized by DPI systems and susceptible to blocking. + +Features: +* Available in AmneziaVPN only on Windows +* Low battery consumption on mobile devices +* Minimal configuration required +* Detectable by DPI analysis systems(easily blocked) +* Operates over UDP protocol(ports 500 and 4500) @@ -4219,7 +4646,7 @@ Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REAL یہ REALITY کو سخت سینسرشپ والے ماحولوں میں انٹرنیٹ کی آزادی کو برقرار رکھنے کے لئے ایک مضبوط حل بناتا ہے۔ - + After installation, Amnezia will create a file storage on your server. You will be able to access it using @@ -4264,14 +4691,13 @@ It employs its unique security protocol, leveraging the strength of SSL/TLS for OpenVPN دستیاب سب سے زیادہ مقبول اور وقتی آزمائشی VPN پروٹوکولز میں سے ایک ہے۔ یہ انکرپشن اور کلیدی تبادلے کے لیے SSL/TLS کی طاقت کا فائدہ اٹھاتے ہوئے اپنا منفرد سیکیورٹی پروٹوکول استعمال کرتا ہے۔ مزید برآں، توثیق کے بہت سے طریقوں کے لیے OpenVPN کی حمایت اسے ورسٹائل اور قابل موافق بناتی ہے، جو آلات اور آپریٹنگ سسٹم کی ایک وسیع رینج کو پورا کرتی ہے۔ اوپن سورس کی نوعیت کی وجہ سے، اوپن وی پی این کو عالمی برادری کی طرف سے وسیع جانچ سے فائدہ ہوتا ہے، جو اس کی سلامتی کو مسلسل تقویت دیتا ہے۔ کارکردگی، سیکورٹی اور مطابقت کے مضبوط توازن کے ساتھ، OpenVPN رازداری کے بارے میں شعور رکھنے والے افراد اور کاروباروں کے لیے یکساں انتخاب ہے۔ * تمام پلیٹ فارمز پر AmneziaVPN میں دستیاب ہے * موبائل آلات پر بجلی کی عام کھپت * صارف کو مختلف آپریٹنگ سسٹمز اور ڈیوائسز کے ساتھ کام کرنے کی ضرورت کے مطابق لچکدار تخصیص * DPI تجزیہ سسٹمز کے ذریعہ پہچانا جاتا ہے اور اس وجہ سے بلاک کرنے کا خطرہ ہوتا ہے * TCP اور UDP دونوں نیٹ ورک پر کام کر سکتا ہے۔ پروٹوکول - Shadowsocks, inspired by the SOCKS5 protocol, safeguards the connection using the AEAD cipher. Although Shadowsocks is designed to be discreet and challenging to identify, it isn't identical to a standard HTTPS connection.However, certain traffic analysis systems might still detect a Shadowsocks connection. Due to limited support in Amnezia, it's recommended to use AmneziaWG protocol. * Available in the AmneziaVPN only on desktop platforms * Configurable encryption protocol * Detectable by some DPI systems * Works over TCP network protocol. - شیڈو ساکس، SOCKS5 پروٹوکول سے متاثر، AEAD سائفر کا استعمال کرتے ہوئے کنکشن کی حفاظت کرتا ہے۔ اگرچہ شیڈو ساکس کو سمجھدار اور شناخت کرنے کے لیے چیلنج کرنے کے لیے ڈیزائن کیا گیا ہے، لیکن یہ معیاری HTTPS کنکشن سے مماثل نہیں ہے۔ تاہم، کچھ ٹریفک تجزیہ نظام اب بھی شیڈو ساکس کنکشن کا پتہ لگا سکتے ہیں۔ Amnezia میں محدود تعاون کی وجہ سے، AmneziaWG پروٹوکول استعمال کرنے کی سفارش کی جاتی ہے۔ * صرف ڈیسک ٹاپ پلیٹ فارمز پر AmneziaVPN میں دستیاب ہے * قابل ترتیب انکرپشن پروٹوکول * کچھ DPI سسٹمز کے ذریعے قابل شناخت * TCP نیٹ ورک پروٹوکول پر کام کرتا ہے. + شیڈو ساکس، SOCKS5 پروٹوکول سے متاثر، AEAD سائفر کا استعمال کرتے ہوئے کنکشن کی حفاظت کرتا ہے۔ اگرچہ شیڈو ساکس کو سمجھدار اور شناخت کرنے کے لیے چیلنج کرنے کے لیے ڈیزائن کیا گیا ہے، لیکن یہ معیاری HTTPS کنکشن سے مماثل نہیں ہے۔ تاہم، کچھ ٹریفک تجزیہ نظام اب بھی شیڈو ساکس کنکشن کا پتہ لگا سکتے ہیں۔ Amnezia میں محدود تعاون کی وجہ سے، AmneziaWG پروٹوکول استعمال کرنے کی سفارش کی جاتی ہے۔ * صرف ڈیسک ٹاپ پلیٹ فارمز پر AmneziaVPN میں دستیاب ہے * قابل ترتیب انکرپشن پروٹوکول * کچھ DPI سسٹمز کے ذریعے قابل شناخت * TCP نیٹ ورک پروٹوکول پر کام کرتا ہے. A modern iteration of the popular VPN protocol, AmneziaWG builds upon the foundation set by WireGuard, retaining its simplified architecture and high-performance capabilities across devices. @@ -4286,7 +4712,6 @@ This means that AmneziaWG keeps the fast performance of the original while addin ایک معاصر اشارہ جاتا ہے مقبول وی پی این پروٹوکول کا امنیزیہ ڈبلیو جی۔ امنیزیہ ڈبلیو جی وائر گارڈ کے بنیادی ڈھانچے پر مبنی ہے، جس نے اس کی آسانی سے معماری اور ایکسیلنٹ کارکردگی کی خصوصیات کو برقرار رکھا۔ جبکہ وائر گارڈ کو اس کی کارآمدی کے لئے جانا جاتا ہے، اس میں اپنے ممتاز پیکٹ سائنیچرز کی وجہ سے آسانی سے پہچان میں مسائل پیش آتے تھے۔ امنیزیہ ڈبلیو جی اس مسئلے کا حل پیش کرتا ہے بہتر اوبفسکیشن میتھڈس کے ذریعے، جس سے اس کی ٹریفک عام انٹرنیٹ ٹریفک کے ساتھ مل جل کر رہتی ہے۔ اس سے مطلب یہ ہے کہ امنیزیہ ڈبلیو جی نے اصل وائر گارڈ کی تیزی کارکردگی کو برقرار رکھا جبکہ اس میں ایک اضافی پردہ شامل کیا، جو اسے ایک تیز اور پرانے طریقہ سے وی پی این کنکشن کی درخواست کرنے والوں کے لئے ایک عمدہ چوئس بناتا ہے۔ * تمام پلیٹ فارمز پر دستیاب ہے * کم بجلی کی استعمال * کم سیٹنگز کی تعداد * ڈی پی آئی تجزیہ سسٹمز سے پہچانا نہیں جاتا، بند کرنے کے لئے مزید مضبوط ہے * یو ڈی پی نیٹ ورک پروٹوکول پر کام کرتا ہے۔ - IKEv2, paired with the IPSec encryption layer, stands as a modern and stable VPN protocol. One of its distinguishing features is its ability to swiftly switch between networks and devices, making it particularly adaptive in dynamic network environments. While it offers a blend of security, stability, and speed, it's essential to note that IKEv2 can be easily detected and is susceptible to blocking. @@ -4296,10 +4721,10 @@ While it offers a blend of security, stability, and speed, it's essential t * Minimal configuration * Recognised by DPI analysis systems * Works over UDP network protocol, ports 500 and 4500. - IKEv2، IPSec انکرپشن پرت کے ساتھ جوڑا، ایک جدید اور مستحکم VPN پروٹوکول کے طور پر کھڑا ہے۔ اس کی امتیازی خصوصیات میں سے ایک نیٹ ورکس اور ڈیوائسز کے درمیان تیزی سے سوئچ کرنے کی صلاحیت ہے، جو اسے متحرک نیٹ ورک کے ماحول میں خاص طور پر موافق بناتی ہے۔ اگرچہ یہ سیکیورٹی، استحکام اور رفتار کا امتزاج پیش کرتا ہے، لیکن یہ نوٹ کرنا ضروری ہے کہ IKEv2 کا آسانی سے پتہ لگایا جا سکتا ہے اور یہ بلاک کرنے کے لیے حساس ہے۔ * صرف ونڈوز پر AmneziaVPN میں دستیاب ہے * کم بجلی کی کھپت، موبائل ڈیوائسز پر * کم سے کم کنفیگریشن * DPI تجزیہ سسٹمز کے ذریعے پہچانا جاتا ہے * UDP نیٹ ورک پروٹوکول، پورٹ 500 اور 4500 پر کام .کرتا ہے + IKEv2، IPSec انکرپشن پرت کے ساتھ جوڑا، ایک جدید اور مستحکم VPN پروٹوکول کے طور پر کھڑا ہے۔ اس کی امتیازی خصوصیات میں سے ایک نیٹ ورکس اور ڈیوائسز کے درمیان تیزی سے سوئچ کرنے کی صلاحیت ہے، جو اسے متحرک نیٹ ورک کے ماحول میں خاص طور پر موافق بناتی ہے۔ اگرچہ یہ سیکیورٹی، استحکام اور رفتار کا امتزاج پیش کرتا ہے، لیکن یہ نوٹ کرنا ضروری ہے کہ IKEv2 کا آسانی سے پتہ لگایا جا سکتا ہے اور یہ بلاک کرنے کے لیے حساس ہے۔ * صرف ونڈوز پر AmneziaVPN میں دستیاب ہے * کم بجلی کی کھپت، موبائل ڈیوائسز پر * کم سے کم کنفیگریشن * DPI تجزیہ سسٹمز کے ذریعے پہچانا جاتا ہے * UDP نیٹ ورک پروٹوکول، پورٹ 500 اور 4500 پر کام .کرتا ہے - + DNS Service DNS سروس @@ -4536,12 +4961,12 @@ While it offers a blend of security, stability, and speed, it's essential t SettingsController - + Backup file is corrupted بیک اپ فائل خراب ہو گئی ہے - + All settings have been reset to default values تمام ترتیبات کو ڈیفالٹ اقدار پر دوبارہ ترتیب دیا گیا ہے @@ -4673,7 +5098,7 @@ While it offers a blend of security, stability, and speed, it's essential t VpnConnection - + Mbps ایم بی پی ایس @@ -4748,12 +5173,12 @@ While it offers a blend of security, stability, and speed, it's essential t زیادہ تر وی پی این پروٹوکولز بلاک ہوتے ہیں۔ اگر دوسرے اختیارات کام نہیں کر رہے ہیں تو یہ تجویز کی جاتی ہے. - + Automatic - + AmneziaWG protocol will be installed. It provides high connection speed and ensures stable operation even in the most challenging network conditions. diff --git a/client/translations/amneziavpn_zh_CN.ts b/client/translations/amneziavpn_zh_CN.ts index 2b0cf848..b8bb5b00 100644 --- a/client/translations/amneziavpn_zh_CN.ts +++ b/client/translations/amneziavpn_zh_CN.ts @@ -9,6 +9,54 @@ + + AllowedDnsController + + + The address does not look like a valid IP address + + + + + New DNS server added: %1 + + + + + DNS server already exists: %1 + + + + + DNS server removed: %1 + + + + + Can't open file: %1 + 无法打开文件: %1 + + + + Failed to parse JSON data from file: %1 + JSON解析失败,文件: %1 + + + + The JSON data is not an array in file: %1 + 文件中的JSON数据不是一个数组,文件: %1 + + + + Import completed + 完成导入 + + + + Export completed + 完成导出 + + ApiAccountInfoModel @@ -33,39 +81,131 @@ - + Free unlimited access to a basic set of websites such as Facebook, Instagram, Twitter (X), Discord, Telegram and more. YouTube is not included in the free plan. - - - amnezia_free_support_bot - - - - - amnezia_premium_support_bot - - ApiConfigsController - + %1 installed successfully. - + API config reloaded - + Successfully changed the country of connection to %1 + + ApiPremV1MigrationDrawer + + + Switch to the new Amnezia Premium subscription + + + + + We'll preserve all remaining days of your current subscription and give you an extra month as a thank you. + + + + + This new subscription type will be actively developed with more locations and features added regularly. Currently available: + + + + + <li>13 locations (with more coming soon)</li> + + + + + <li>Easier switching between countries in the app</li> + + + + + <li>Personal dashboard to manage your subscription</li> + + + + + Old keys will be deactivated after switching. + + + + + Email + + + + + mail@example.com + + + + + No old format subscriptions for a given email + + + + + Enter the email you used for your current subscription + + + + + + Continue + 继续 + + + + Remind me later + + + + + Don't remind me again + + + + + No more reminders? You can always switch to the new format in the server settings + + + + + Cancel + 取消 + + + + ApiPremV1SubListDrawer + + + Choose Subscription + + + + + Order ID: + + + + + Purchase Date: + + + ApiServicesModel @@ -81,7 +221,7 @@ - AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan. + Amnezia Free provides unlimited, free access to a basic set of websites and apps, including Facebook, Instagram, Twitter (X), Discord, Telegram, and more. YouTube is not included in the free plan. @@ -99,6 +239,11 @@ %1 days + + + + + VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a> @@ -252,7 +397,7 @@ HomeContainersListView - + Unable change protocol while there is an active connection 已建立连接时无法更改服务器配置 @@ -311,17 +456,17 @@ Can't be disabled for current server ImportController - + Scanned %1 of %2. 扫描 %1 of %2. - + This configuration contains an OpenVPN setup. OpenVPN configurations can include malicious scripts, so only add it if you fully trust the provider of this config. - + <br>In the imported configuration, potentially dangerous lines were found: @@ -337,60 +482,60 @@ Can't be disabled for current server 已安装在服务器上 - + %1 installed successfully. %1 安装成功。 - + %1 is already installed on the server. 服务器上已经安装 %1。 - + Added containers that were already installed on the server 添加已安装在服务器上的容器 - + Already installed containers were found on the server. All installed containers have been added to the application 在服务上发现已经安装协议并添加至应用 - + Settings updated successfully 配置更新成功 - + Server '%1' was rebooted 服务器 '%1' 已重新启动 - + Server '%1' was removed 已移除服务器 '%1' - + All containers from server '%1' have been removed 服务器 '%1' 的所有容器已移除 - + %1 has been removed from the server '%2' %1 已从服务器 '%2' 上移除 - + Api config removed - + %1 cached profile cleared @@ -411,12 +556,12 @@ Already installed containers were found on the server. All installed containers 协议已从 - + Please login as the user 请以用户身份登录 - + Server added successfully 增加服务器成功 @@ -486,6 +631,24 @@ Already installed containers were found on the server. All installed containers 发现不安全网络 + + OtpCodeDrawer + + + OTP code was sent to your email + + + + + OTP Code + + + + + Continue + 继续 + + PageDeinstalling @@ -515,27 +678,43 @@ Already installed containers were found on the server. All installed containers PageHome - + + You've successfully switched to the new Amnezia Premium subscription! + + + + + Old keys will no longer work. Please use your new subscription key to connect. +Thank you for staying with us! + + + + + Continue + 继续 + + + Logging enabled - + Split tunneling enabled 用户分隔隧道已启用 - + Split tunneling disabled 分隔隧道已禁用 - + VPN protocol VPN协议 - + Servers 服务器 @@ -557,42 +736,87 @@ Already installed containers were found on the server. All installed containers - + Server settings - + Port 端口 - + + I1 - First special junk packet + + + + + I2 - Second special junk packet + + + + + I3 - Third special junk packet + + + + + I4 - Fourth special junk packet + + + + + I5 - Fifth special junk packet + + + + + J1 - First controlled junk packet + + + + + J2 - Second controlled junk packet + + + + + J3 - Third controlled junk packet + + + + + Itime - Special handshake timeout + + + + Save 保存 - + Save settings? 保存设置? - + Only the settings for this device will be changed - + Continue 继续 - + Cancel 取消 - + Unable change settings while there is an active connection @@ -618,12 +842,12 @@ Already installed containers were found on the server. All installed containers 从服务上移除AmneziaWG? - + All users with whom you shared a connection with will no longer be able to connect to it. 与您共享连接的所有用户将无法再连接到该连接。 - + Save 保存 @@ -669,41 +893,41 @@ Already installed containers were found on the server. All installed containers - H4 - Transport packet magic header - - - - H3 - Underload packet magic header - + + H4 - Transport packet magic header + + + + The values of the H1-H4 fields must be unique - + The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) - + Save settings? 保存设置? - + Continue 继续 - + Cancel 取消 - + Unable change settings while there is an active connection @@ -1144,12 +1368,17 @@ Already installed containers were found on the server. All installed containers 伪装流量为 - + + Port + 端口 + + + Save 保存 - + Unable change settings while there is an active connection @@ -1604,7 +1833,7 @@ And if you don't like the app, all the more support it - the donation will - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -1897,7 +2126,7 @@ And if you don't like the app, all the more support it - the donation will - This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect. + This will unlink the device from your subscription. You can reconnect it anytime by pressing "Reload API config" in subscription settings on device. @@ -1933,31 +2162,16 @@ And if you don't like the app, all the more support it - the donation will Email - - - support@amnezia.org - - Email Billing & Orders - - - help@vpnpay.io - - Website 官网 - - - amnezia.org - - Support @@ -1969,12 +2183,12 @@ And if you don't like the app, all the more support it - the donation will - + Support tag - + Copied @@ -2002,37 +2216,37 @@ And if you don't like the app, all the more support it - the donation will - + Mode 规则 - + Remove - + Continue 继续 - + Cancel 取消 - + application name - + Open executable file - + Executable files (*.*) @@ -2244,23 +2458,18 @@ And if you don't like the app, all the more support it - the donation will 当未使用或未安装AmneziaDNS时 - + Allows you to use the VPN only for certain Apps 只允许在某些应用程序中使用 VPN - + KillSwitch - - Disables your internet if your encrypted VPN connection drops out for any reason. - - - - - Cannot change KillSwitch settings during active connection + + Blocks network connections without VPN @@ -2297,7 +2506,7 @@ And if you don't like the app, all the more support it - the donation will 配置想要通过VPN访问网站 - + App-based split tunneling 基于应用的隧道分离 @@ -2381,6 +2590,155 @@ And if you don't like the app, all the more support it - the donation will 配置已保存 + + PageSettingsKillSwitch + + + KillSwitch + + + + + Enable to ensure network traffic goes through a secure VPN tunnel, preventing accidental exposure of your IP and DNS queries if the connection drops + + + + + KillSwitch settings cannot be changed during an active connection + + + + + Soft KillSwitch + + + + + Internet access is blocked if the VPN disconnects unexpectedly + + + + + Strict KillSwitch + + + + + Internet connection is blocked even when VPN is turned off manually or hasn't started + + + + + Just a little heads-up + + + + + If the VPN disconnects or drops while Strict KillSwitch is enabled, internet access will be blocked. To restore access, reconnect VPN or disable/change the KillSwitch. + + + + + Continue + 继续 + + + + Cancel + 取消 + + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active. + + + + + PageSettingsKillSwitchExceptions + + + DNS Exceptions + + + + + DNS servers listed here will remain accessible when KillSwitch is active + + + + + Delete + + + + + Continue + 继续 + + + + Cancel + 取消 + + + + IPv4 address + + + + + Import / Export addresses + + + + + Import + 导入 + + + + Save address list + + + + + Save addresses + + + + + + + Address files (*.json) + + + + + Import address list + + + + + Replace address list + + + + + + Open address file + + + + + Add imported addresses to existing ones + + + PageSettingsLogging @@ -2518,11 +2876,6 @@ And if you don't like the app, all the more support it - the donation will Do you want to clear server from Amnezia software? 您要清除服务器上的Amnezia软件吗? - - - - - @@ -2604,6 +2957,11 @@ And if you don't like the app, all the more support it - the donation will Cannot reset API config during active connection + + + Switch to the new Amnezia Premium subscription + + Remove server? 移除本地服务器信息? @@ -2669,11 +3027,6 @@ And if you don't like the app, all the more support it - the donation will Clear %1 profile? - - - - - connection settings @@ -2786,27 +3139,27 @@ And if you don't like the app, all the more support it - the donation will 不使用VPN访问 - + Split tunneling 隧道分离 - + Mode 规则 - + Remove 移除 - + Continue 继续 - + Cancel 取消 @@ -2829,55 +3182,55 @@ And if you don't like the app, all the more support it - the donation will 只有这里列出的网站将通过VPN访问 - + website or IP 网站或IP - + Import / Export Sites 导入/导出网站 - + Import 导入 - + Save site list 保存网址 - + Save sites 保存网址 - - - + + + Sites files (*.json) - + Import a list of sites 导入网址列表 - + Replace site list 替换网址列表 - - + + Open sites file 打开网址文件 - + Add imported sites to existing ones 将导入的网址添加到现有网址中 @@ -2954,117 +3307,140 @@ It's okay as long as it's from someone you trust. 包含连接配置或备份的文件 - + Connection 连接 - + Settings 设置 - + Enable logs + Export client logs + + + + + Save + 保存 + + + + Logs files (*.log) + + + + + Logs file saved + 日志文件已保存 + + + Support tag - + Copied - + Insert the key, add a configuration file or scan the QR-code - + Insert key - + Insert 插入 - + Continue 继续 - + Other connection options - + Site Amnezia - + VPN by Amnezia - + Connect to classic paid and free VPN services from Amnezia - + Self-hosted VPN - + Configure Amnezia VPN on your own server - + Restore from backup 从备份还原 - + + + + - + Open backup file 打开备份文件 - + Backup files (*.backup) - + File with connection settings 包含连接配置的文件 - + Open config file 打开配置文件 - + QR code 二维码 - + I have nothing 我没有 @@ -3990,7 +4366,7 @@ and will not be shared or disclosed to the Amnezia or any third parties - + SOCKS5 proxy server @@ -4076,47 +4452,57 @@ and will not be shared or disclosed to the Amnezia or any third parties - + + Docker error: runc doesn't work on cgroups v2 + + + + + Server error: cgroup mountpoint does not exist + + + + SSH request was denied SSH请求被拒绝 - + SSH request was interrupted SSH请求中断 - + SSH internal error SSH内部错误 - + Invalid private key or invalid passphrase entered 输入的私钥或密码无效 - + The selected private key format is not supported, use openssh ED25519 key types or PEM key types 不支持所选私钥格式,请使用 openssh ED25519 密钥类型或 PEM 密钥类型 - + Timeout connecting to server 连接服务器超时 - + SCP error: Generic failure - + Unable to open config file - + VPN Protocols is not installed. Please install VPN container at first 请先安装VPN协议 @@ -4174,88 +4560,98 @@ and will not be shared or disclosed to the Amnezia or any third parties Sftp 错误: 远程驱动器中没有媒介 - + VPN connection error VPN 连接错误 - - + + Error when retrieving configuration from API 从 API 检索配置时出错 - + This config has already been added to the application 该配置已添加到应用程序中 - + In the response from the server, an empty config was received - + SSL error occurred - + Server response timeout on api request - + Missing AGW public key - + Failed to decrypt response payload - + Missing list of available services - + The limit of allowed configurations per subscription has been exceeded - QFile error: The file could not be opened + A migration error has occurred. Please contact our technical support - QFile error: An error occurred when reading from the file - - - - - QFile error: The file could not be accessed - - - - - QFile error: An unspecified error occurred + Please update the application to use this feature - QFile error: A fatal error occurred + QFile error: The file could not be opened + QFile error: An error occurred when reading from the file + + + + + QFile error: The file could not be accessed + + + + + QFile error: An unspecified error occurred + + + + + QFile error: A fatal error occurred + + + + QFile error: The operation was aborted - + ErrorCode: %1. 错误代码: %1. @@ -4264,57 +4660,57 @@ and will not be shared or disclosed to the Amnezia or any third parties 配置保存到磁盘失败 - + OpenVPN config missing OpenVPN配置丢失 - + OpenVPN management server error OpenVPN 管理服务器错误 - + OpenVPN executable missing OpenVPN 可执行文件丢失 - + Shadowsocks (ss-local) executable missing Shadowsocks (ss-local) 执行文件丢失 - + Cloak (ck-client) executable missing Cloak (ck-client) 执行文件丢失 - + Amnezia helper service error Amnezia 服务连接失败 - + OpenSSL failed OpenSSL错误 - + Can't connect: another VPN connection is active 无法连接:另一个VPN连接处于活跃状态 - + Can't setup OpenVPN TAP network adapter 无法设置 OpenVPN TAP 网络适配器 - + VPN pool error: no available addresses VPN 池错误:没有可用地址 - + The config does not contain any containers and credentials for connecting to the server 配置不包含任何用于连接服务器的容器和凭据 @@ -4323,7 +4719,7 @@ and will not be shared or disclosed to the Amnezia or any third parties 该配置不包含任何用于连接到服务器的容器和凭据。 - + Internal error @@ -4334,7 +4730,7 @@ and will not be shared or disclosed to the Amnezia or any third parties - + Website in Tor network 在 Tor 网络中架设网站 @@ -4378,72 +4774,6 @@ and will not be shared or disclosed to the Amnezia or any third parties XRay with REALITY masks VPN traffic as web traffic and protects against active probing. It is highly resistant to detection and offers high speed. - - - OpenVPN stands as one of the most popular and time-tested VPN protocols available. -It employs its unique security protocol, leveraging the strength of SSL/TLS for encryption and key exchange. Furthermore, OpenVPN's support for a multitude of authentication methods makes it versatile and adaptable, catering to a wide range of devices and operating systems. Due to its open-source nature, OpenVPN benefits from extensive scrutiny by the global community, which continually reinforces its security. With a strong balance of performance, security, and compatibility, OpenVPN remains a top choice for privacy-conscious individuals and businesses alike. - -* Available in the AmneziaVPN across all platforms -* Normal power consumption on mobile devices -* Flexible customisation to suit user needs to work with different operating systems and devices -* Recognised by DPI systems and therefore susceptible to blocking -* Can operate over both TCP and UDP network protocols. - - - - - This is a combination of the OpenVPN protocol and the Cloak plugin designed specifically for protecting against detection. - -OpenVPN provides a secure VPN connection by encrypting all internet traffic between the client and the server. - -Cloak protects OpenVPN from detection. - -Cloak can modify packet metadata so that it completely masks VPN traffic as normal web traffic, and also protects the VPN from detection by Active Probing. This makes it very resistant to being detected - -Immediately after receiving the first data packet, Cloak authenticates the incoming connection. If authentication fails, the plugin masks the server as a fake website and your VPN becomes invisible to analysis systems. - -* Available in the AmneziaVPN across all platforms -* High power consumption on mobile devices -* Flexible settings -* Not recognised by detection systems -* Works over TCP network protocol, 443 port. - - - - - - A relatively new popular VPN protocol with a simplified architecture. -WireGuard provides stable VPN connection and high performance on all devices. It uses hard-coded encryption settings. WireGuard compared to OpenVPN has lower latency and better data transfer throughput. -WireGuard is very susceptible to detection and blocking due to its distinct packet signatures. Unlike some other VPN protocols that employ obfuscation techniques, the consistent signature patterns of WireGuard packets can be more easily identified and thus blocked by advanced Deep Packet Inspection (DPI) systems and other network monitoring tools. - -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Easily recognised by DPI analysis systems, susceptible to blocking -* Works over UDP network protocol. - - - - - A modern iteration of the popular VPN protocol, AmneziaWG builds upon the foundation set by WireGuard, retaining its simplified architecture and high-performance capabilities across devices. -While WireGuard is known for its efficiency, it had issues with being easily detected due to its distinct packet signatures. AmneziaWG solves this problem by using better obfuscation methods, making its traffic blend in with regular internet traffic. -This means that AmneziaWG keeps the fast performance of the original while adding an extra layer of stealth, making it a great choice for those wanting a fast and discreet VPN connection. - -* Available in the AmneziaVPN across all platforms -* Low power consumption -* Minimum number of settings -* Not recognised by traffic analysis systems -* Works over UDP network protocol. - - - - - The REALITY protocol, a pioneering development by the creators of XRay, is designed to provide the highest level of protection against detection through its innovative approach to security and privacy. -It uniquely identifies attackers during the TLS handshake phase, seamlessly operating as a proxy for legitimate clients while diverting attackers to genuine websites, thus presenting an authentic TLS certificate and data. -This advanced capability differentiates REALITY from similar technologies by its ability to disguise web traffic as coming from random, legitimate sites without the need for specific configurations. -Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REALITY's innovative "friend or foe" recognition at the TLS handshake enhances security. This makes REALITY a robust solution for maintaining internet freedom. - - Shadowsocks - masks VPN traffic, making it similar to normal web traffic, but it may be recognized by analysis systems in some highly censored regions. Shadowsocks - 掩盖VPN流量,使其类似于正常的网络流量,但在一些高度审查的地区可能会被分析系统识别. @@ -4454,7 +4784,104 @@ Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REAL - + + + + + + + OpenVPN is one of the most popular and reliable VPN protocols. It uses SSL/TLS encryption, supports a wide variety of devices and operating systems, and is continuously improved by the community due to its open-source nature. It provides a good balance between speed and security but is easily recognized by DPI systems, making it susceptible to blocking. + +Features: +* Available on all AmneziaVPN platforms +* Normal battery consumption on mobile devices +* Flexible customization for various devices and OS +* Operates over both TCP and UDP protocols + + + + + Shadowsocks is based on the SOCKS5 protocol and encrypts connections using AEAD cipher. Although designed to be discreet, it doesn't mimic a standard HTTPS connection and can be detected by some DPI systems. Due to limited support in Amnezia, we recommend using the AmneziaWG protocol. + +Features: +* Available in AmneziaVPN only on desktop platforms +* Customizable encryption protocol +* Detectable by some DPI systems +* Operates over TCP protocol + + + + + + This combination includes the OpenVPN protocol and the Cloak plugin, specifically designed to protect against blocking. + +OpenVPN securely encrypts all internet traffic between your device and the server. + +The Cloak plugin further protects the connection from DPI detection. It modifies traffic metadata to disguise VPN traffic as regular web traffic and prevents detection through active probing. If an incoming connection fails authentication, Cloak serves a fake website, making your VPN invisible to traffic analysis systems. + +In regions with heavy internet censorship, we strongly recommend using OpenVPN with Cloak from your first connection. + +Features: +* Available on all AmneziaVPN platforms +* High power consumption on mobile devices +* Flexible configuration options +* Undetectable by DPI systems +* Operates over TCP protocol on port 443 + + + + + WireGuard is a modern, streamlined VPN protocol offering stable connectivity and excellent performance across all devices. It uses fixed encryption settings, delivering lower latency and higher data transfer speeds compared to OpenVPN. However, WireGuard is easily identifiable by DPI systems due to its distinctive packet signatures, making it susceptible to blocking. + +Features: +* Available on all AmneziaVPN platforms +* Low power consumption on mobile devices +* Minimal configuration required +* Easily detected by DPI systems (susceptible to blocking) +* Operates over UDP protocol + + + + + AmneziaWG is a modern VPN protocol based on WireGuard, combining simplified architecture with high performance across all devices. It addresses WireGuard's main vulnerability (easy detection by DPI systems) through advanced obfuscation techniques, making VPN traffic indistinguishable from regular internet traffic. + +AmneziaWG is an excellent choice for those seeking a fast, stealthy VPN connection. + +Features: +* Available on all AmneziaVPN platforms +* Low battery consumption on mobile devices +* Minimal settings required +* Undetectable by traffic analysis systems (DPI) +* Operates over UDP protocol + + + + + REALITY is an innovative protocol developed by the creators of XRay, designed specifically to combat high levels of internet censorship. REALITY identifies censorship systems during the TLS handshake, redirecting suspicious traffic seamlessly to legitimate websites like google.com while providing genuine TLS certificates. This allows VPN traffic to blend indistinguishably with regular web traffic without special configuration. +Unlike older protocols such as VMess, VLESS, and XTLS-Vision, REALITY incorporates an advanced built-in "friend-or-foe" detection mechanism, effectively protecting against DPI and other traffic analysis methods. + +Features: +* Resistant to active probing and DPI detection +* No special configuration required to disguise traffic +* Highly effective in heavily censored regions +* Minimal battery consumption on devices +* Operates over TCP protocol + + + + + IKEv2, combined with IPSec encryption, is a modern and reliable VPN protocol. It reconnects quickly when switching networks or devices, making it ideal for dynamic network environments. While it provides good security and speed, it's easily recognized by DPI systems and susceptible to blocking. + +Features: +* Available in AmneziaVPN only on Windows +* Low battery consumption on mobile devices +* Minimal configuration required +* Detectable by DPI analysis systems(easily blocked) +* Operates over UDP protocol(ports 500 and 4500) + + + + After installation, Amnezia will create a file storage on your server. You will be able to access it using @@ -4554,14 +4981,13 @@ It employs its unique security protocol, leveraging the strength of SSL/TLS for * 可以通过 TCP 和 UDP 网络协议运行. - Shadowsocks, inspired by the SOCKS5 protocol, safeguards the connection using the AEAD cipher. Although Shadowsocks is designed to be discreet and challenging to identify, it isn't identical to a standard HTTPS connection.However, certain traffic analysis systems might still detect a Shadowsocks connection. Due to limited support in Amnezia, it's recommended to use AmneziaWG protocol. * Available in the AmneziaVPN only on desktop platforms * Configurable encryption protocol * Detectable by some DPI systems * Works over TCP network protocol. - Shadowsocks 受到 SOCKS5 协议的启发,使用 AEAD 密码保护连接。尽管 Shadowsocks 设计得谨慎且难以识别,但它与标准 HTTPS 连接并不相同。但是,某些流量分析系统可能仍会检测到 Shadowsocks 连接。由于Amnezia支持有限,建议使用AmneziaWG协议。 + Shadowsocks 受到 SOCKS5 协议的启发,使用 AEAD 密码保护连接。尽管 Shadowsocks 设计得谨慎且难以识别,但它与标准 HTTPS 连接并不相同。但是,某些流量分析系统可能仍会检测到 Shadowsocks 连接。由于Amnezia支持有限,建议使用AmneziaWG协议。 * 仅在桌面平台上的 AmneziaVPN 中可用 * 可配置的加密协议 @@ -4646,7 +5072,6 @@ This means that AmneziaWG keeps the fast performance of the original while addin * 通过 UDP 网络协议工作。 - IKEv2, paired with the IPSec encryption layer, stands as a modern and stable VPN protocol. One of its distinguishing features is its ability to swiftly switch between networks and devices, making it particularly adaptive in dynamic network environments. While it offers a blend of security, stability, and speed, it's essential to note that IKEv2 can be easily detected and is susceptible to blocking. @@ -4656,7 +5081,7 @@ While it offers a blend of security, stability, and speed, it's essential t * Minimal configuration * Recognised by DPI analysis systems * Works over UDP network protocol, ports 500 and 4500. - IKEv2 与 IPSec 加密层配合使用,是一种现代且稳定的 VPN 协议。 + IKEv2 与 IPSec 加密层配合使用,是一种现代且稳定的 VPN 协议。 其显着特征之一是能够在网络和设备之间快速切换,使其特别适应动态网络环境。 虽然 IKEv2 兼具安全性、稳定性和速度,但必须注意的是,IKEv2 很容易被检测到,并且容易受到阻止。 @@ -4687,7 +5112,7 @@ While it offers a blend of security, stability, and speed, it's essential t IPsec 容器 - + DNS Service DNS 服务 @@ -4928,12 +5353,12 @@ While it offers a blend of security, stability, and speed, it's essential t SettingsController - + Backup file is corrupted 备份文件已损坏 - + All settings have been reset to default values 所配置恢复为默认值 @@ -5073,7 +5498,7 @@ While it offers a blend of security, stability, and speed, it's essential t VpnConnection - + Mbps @@ -5164,12 +5589,12 @@ While it offers a blend of security, stability, and speed, it's essential t 一些国外网站被屏蔽,但VPN提供商未被屏蔽 - + Automatic - + AmneziaWG protocol will be installed. It provides high connection speed and ensures stable operation even in the most challenging network conditions. diff --git a/client/ui/controllers/api/apiConfigsController.cpp b/client/ui/controllers/api/apiConfigsController.cpp index 0f42beb7..a89ba5c1 100644 --- a/client/ui/controllers/api/apiConfigsController.cpp +++ b/client/ui/controllers/api/apiConfigsController.cpp @@ -18,7 +18,6 @@ namespace { constexpr char cloak[] = "cloak"; constexpr char awg[] = "awg"; - constexpr char vless[] = "vless"; constexpr char apiEndpoint[] = "api_endpoint"; constexpr char accessToken[] = "api_key"; @@ -36,6 +35,10 @@ namespace constexpr char serviceInfo[] = "service_info"; constexpr char serviceProtocol[] = "service_protocol"; + constexpr char aesKey[] = "aes_key"; + constexpr char aesIv[] = "aes_iv"; + constexpr char aesSalt[] = "aes_salt"; + constexpr char apiPayload[] = "api_payload"; constexpr char keyPayload[] = "key_payload"; @@ -44,185 +47,6 @@ namespace constexpr char config[] = "config"; } - - struct ProtocolData - { - OpenVpnConfigurator::ConnectionData certRequest; - - QString wireGuardClientPrivKey; - QString wireGuardClientPubKey; - - QString xrayUuid; - }; - - struct GatewayRequestData - { - QString osVersion; - QString appVersion; - - QString installationUuid; - - QString userCountryCode; - QString serverCountryCode; - QString serviceType; - QString serviceProtocol; - - QJsonObject authData; - - QJsonObject toJsonObject() const - { - QJsonObject obj; - if (!osVersion.isEmpty()) { - obj[configKey::osVersion] = osVersion; - } - if (!appVersion.isEmpty()) { - obj[configKey::appVersion] = appVersion; - } - if (!installationUuid.isEmpty()) { - obj[configKey::uuid] = installationUuid; - } - if (!userCountryCode.isEmpty()) { - obj[configKey::userCountryCode] = userCountryCode; - } - if (!serverCountryCode.isEmpty()) { - obj[configKey::serverCountryCode] = serverCountryCode; - } - if (!serviceType.isEmpty()) { - obj[configKey::serviceType] = serviceType; - } - if (!serviceProtocol.isEmpty()) { - obj[configKey::serviceProtocol] = serviceProtocol; - } - if (!authData.isEmpty()) { - obj[configKey::authData] = authData; - } - return obj; - } - }; - - ProtocolData generateProtocolData(const QString &protocol) - { - ProtocolData protocolData; - if (protocol == configKey::cloak) { - protocolData.certRequest = OpenVpnConfigurator::createCertRequest(); - } else if (protocol == configKey::awg) { - auto connData = WireguardConfigurator::genClientKeys(); - protocolData.wireGuardClientPubKey = connData.clientPubKey; - protocolData.wireGuardClientPrivKey = connData.clientPrivKey; - } else if (protocol == configKey::vless) { - protocolData.xrayUuid = QUuid::createUuid().toString(QUuid::WithoutBraces); - } - - return protocolData; - } - - void appendProtocolDataToApiPayload(const QString &protocol, const ProtocolData &protocolData, QJsonObject &apiPayload) - { - if (protocol == configKey::cloak) { - apiPayload[configKey::certificate] = protocolData.certRequest.request; - } else if (protocol == configKey::awg) { - apiPayload[configKey::publicKey] = protocolData.wireGuardClientPubKey; - } else if (protocol == configKey::vless) { - apiPayload[configKey::publicKey] = protocolData.xrayUuid; - } - } - - ErrorCode fillServerConfig(const QString &protocol, const ProtocolData &apiPayloadData, const QByteArray &apiResponseBody, - QJsonObject &serverConfig) - { - QString data = QJsonDocument::fromJson(apiResponseBody).object().value(config_key::config).toString(); - - data.replace("vpn://", ""); - QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); - - if (ba.isEmpty()) { - qDebug() << "empty vpn key"; - return ErrorCode::ApiConfigEmptyError; - } - - QByteArray ba_uncompressed = qUncompress(ba); - if (!ba_uncompressed.isEmpty()) { - ba = ba_uncompressed; - } - - QString configStr = ba; - if (protocol == configKey::cloak) { - configStr.replace("", "\n"); - configStr.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey); - } else if (protocol == configKey::awg) { - configStr.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey); - auto newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object(); - auto containers = newServerConfig.value(config_key::containers).toArray(); - if (containers.isEmpty()) { - qDebug() << "missing containers field"; - return ErrorCode::ApiConfigEmptyError; - } - auto container = containers.at(0).toObject(); - QString containerName = ContainerProps::containerTypeToString(DockerContainer::Awg); - auto serverProtocolConfig = container.value(containerName).toObject(); - auto clientProtocolConfig = - QJsonDocument::fromJson(serverProtocolConfig.value(config_key::last_config).toString().toUtf8()).object(); - - //TODO looks like this block can be removed after v1 configs EOL - - serverProtocolConfig[config_key::junkPacketCount] = clientProtocolConfig.value(config_key::junkPacketCount); - serverProtocolConfig[config_key::junkPacketMinSize] = clientProtocolConfig.value(config_key::junkPacketMinSize); - serverProtocolConfig[config_key::junkPacketMaxSize] = clientProtocolConfig.value(config_key::junkPacketMaxSize); - serverProtocolConfig[config_key::initPacketJunkSize] = clientProtocolConfig.value(config_key::initPacketJunkSize); - serverProtocolConfig[config_key::responsePacketJunkSize] = clientProtocolConfig.value(config_key::responsePacketJunkSize); - serverProtocolConfig[config_key::initPacketMagicHeader] = clientProtocolConfig.value(config_key::initPacketMagicHeader); - serverProtocolConfig[config_key::responsePacketMagicHeader] = clientProtocolConfig.value(config_key::responsePacketMagicHeader); - serverProtocolConfig[config_key::underloadPacketMagicHeader] = clientProtocolConfig.value(config_key::underloadPacketMagicHeader); - serverProtocolConfig[config_key::transportPacketMagicHeader] = clientProtocolConfig.value(config_key::transportPacketMagicHeader); - - serverProtocolConfig[config_key::cookieReplyPacketJunkSize] = clientProtocolConfig.value(config_key::cookieReplyPacketJunkSize); - serverProtocolConfig[config_key::transportPacketJunkSize] = clientProtocolConfig.value(config_key::transportPacketJunkSize); - serverProtocolConfig[config_key::specialJunk1] = clientProtocolConfig.value(config_key::specialJunk1); - serverProtocolConfig[config_key::specialJunk2] = clientProtocolConfig.value(config_key::specialJunk2); - serverProtocolConfig[config_key::specialJunk3] = clientProtocolConfig.value(config_key::specialJunk3); - serverProtocolConfig[config_key::specialJunk4] = clientProtocolConfig.value(config_key::specialJunk4); - serverProtocolConfig[config_key::specialJunk5] = clientProtocolConfig.value(config_key::specialJunk5); - serverProtocolConfig[config_key::controlledJunk1] = clientProtocolConfig.value(config_key::controlledJunk1); - serverProtocolConfig[config_key::controlledJunk2] = clientProtocolConfig.value(config_key::controlledJunk2); - serverProtocolConfig[config_key::controlledJunk3] = clientProtocolConfig.value(config_key::controlledJunk3); - serverProtocolConfig[config_key::specialHandshakeTimeout] = clientProtocolConfig.value(config_key::specialHandshakeTimeout); - - // - - container[containerName] = serverProtocolConfig; - containers.replace(0, container); - newServerConfig[config_key::containers] = containers; - configStr = QString(QJsonDocument(newServerConfig).toJson()); - } - - QJsonObject newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object(); - serverConfig[config_key::dns1] = newServerConfig.value(config_key::dns1); - serverConfig[config_key::dns2] = newServerConfig.value(config_key::dns2); - serverConfig[config_key::containers] = newServerConfig.value(config_key::containers); - serverConfig[config_key::hostName] = newServerConfig.value(config_key::hostName); - - if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) { - serverConfig[config_key::configVersion] = newServerConfig.value(config_key::configVersion); - serverConfig[config_key::description] = newServerConfig.value(config_key::description); - serverConfig[config_key::name] = newServerConfig.value(config_key::name); - } - - auto defaultContainer = newServerConfig.value(config_key::defaultContainer).toString(); - serverConfig[config_key::defaultContainer] = defaultContainer; - - QVariantMap map = serverConfig.value(configKey::apiConfig).toObject().toVariantMap(); - map.insert(newServerConfig.value(configKey::apiConfig).toObject().toVariantMap()); - auto apiConfig = QJsonObject::fromVariantMap(map); - - if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) { - apiConfig.insert(apiDefs::key::supportedProtocols, - QJsonDocument::fromJson(apiResponseBody).object().value(apiDefs::key::supportedProtocols).toArray()); - } - - serverConfig[configKey::apiConfig] = apiConfig; - - return ErrorCode::NoError; - } } ApiConfigsController::ApiConfigsController(const QSharedPointer &serversModel, @@ -239,26 +63,24 @@ bool ApiConfigsController::exportNativeConfig(const QString &serverCountryCode, return false; } + GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs, + m_settings->isStrictKillSwitchEnabled()); + auto serverConfigObject = m_serversModel->getServerConfig(m_serversModel->getProcessedServerIndex()); auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject(); - GatewayRequestData gatewayRequestData { QSysInfo::productType(), - QString(APP_VERSION), - m_settings->getInstallationUuid(true), - apiConfigObject.value(configKey::userCountryCode).toString(), - serverCountryCode, - apiConfigObject.value(configKey::serviceType).toString(), - m_apiServicesModel->getSelectedServiceProtocol(), - serverConfigObject.value(configKey::authData).toObject() }; - QString protocol = apiConfigObject.value(configKey::serviceProtocol).toString(); - ProtocolData protocolData = generateProtocolData(protocol); + ApiPayloadData apiPayloadData = generateApiPayloadData(protocol); - QJsonObject apiPayload = gatewayRequestData.toJsonObject(); - appendProtocolDataToApiPayload(gatewayRequestData.serviceProtocol, protocolData, apiPayload); + QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData); + apiPayload[configKey::userCountryCode] = apiConfigObject.value(configKey::userCountryCode); + apiPayload[configKey::serverCountryCode] = serverCountryCode; + apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType); + apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData); + apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION); QByteArray responseBody; - ErrorCode errorCode = executeRequest(QString("%1v1/native_config"), apiPayload, responseBody); + ErrorCode errorCode = gatewayController.post(QString("%1v1/native_config"), apiPayload, responseBody); if (errorCode != ErrorCode::NoError) { emit errorOccurred(errorCode); return false; @@ -266,7 +88,7 @@ bool ApiConfigsController::exportNativeConfig(const QString &serverCountryCode, QJsonObject jsonConfig = QJsonDocument::fromJson(responseBody).object(); QString nativeConfig = jsonConfig.value(configKey::config).toString(); - nativeConfig.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", protocolData.wireGuardClientPrivKey); + nativeConfig.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey); SystemController::saveFile(fileName, nativeConfig); return true; @@ -274,22 +96,24 @@ bool ApiConfigsController::exportNativeConfig(const QString &serverCountryCode, bool ApiConfigsController::revokeNativeConfig(const QString &serverCountryCode) { + GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs, + m_settings->isStrictKillSwitchEnabled()); + auto serverConfigObject = m_serversModel->getServerConfig(m_serversModel->getProcessedServerIndex()); auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject(); - GatewayRequestData gatewayRequestData { QSysInfo::productType(), - QString(APP_VERSION), - m_settings->getInstallationUuid(true), - apiConfigObject.value(configKey::userCountryCode).toString(), - serverCountryCode, - apiConfigObject.value(configKey::serviceType).toString(), - m_apiServicesModel->getSelectedServiceProtocol(), - serverConfigObject.value(configKey::authData).toObject() }; + QString protocol = apiConfigObject.value(configKey::serviceProtocol).toString(); + ApiPayloadData apiPayloadData = generateApiPayloadData(protocol); - QJsonObject apiPayload = gatewayRequestData.toJsonObject(); + QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData); + apiPayload[configKey::userCountryCode] = apiConfigObject.value(configKey::userCountryCode); + apiPayload[configKey::serverCountryCode] = serverCountryCode; + apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType); + apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData); + apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION); QByteArray responseBody; - ErrorCode errorCode = executeRequest(QString("%1v1/revoke_native_config"), apiPayload, responseBody); + ErrorCode errorCode = gatewayController.post(QString("%1v1/revoke_native_config"), apiPayload, responseBody); if (errorCode != ErrorCode::NoError && errorCode != ErrorCode::ApiNotFoundError) { emit errorOccurred(errorCode); return false; @@ -320,11 +144,14 @@ void ApiConfigsController::copyVpnKeyToClipboard() bool ApiConfigsController::fillAvailableServices() { + GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs, + m_settings->isStrictKillSwitchEnabled()); + QJsonObject apiPayload; apiPayload[configKey::osVersion] = QSysInfo::productType(); QByteArray responseBody; - ErrorCode errorCode = executeRequest(QString("%1v1/services"), apiPayload, responseBody); + ErrorCode errorCode = gatewayController.post(QString("%1v1/services"), apiPayload, responseBody); if (errorCode == ErrorCode::NoError) { if (!responseBody.contains("services")) { errorCode = ErrorCode::ApiServicesMissingError; @@ -343,36 +170,34 @@ bool ApiConfigsController::fillAvailableServices() bool ApiConfigsController::importServiceFromGateway() { - GatewayRequestData gatewayRequestData { QSysInfo::productType(), - QString(APP_VERSION), - m_settings->getInstallationUuid(true), - m_apiServicesModel->getCountryCode(), - "", - m_apiServicesModel->getSelectedServiceType(), - m_apiServicesModel->getSelectedServiceProtocol(), - QJsonObject() }; - - if (m_serversModel->isServerFromApiAlreadyExists(gatewayRequestData.userCountryCode, gatewayRequestData.serviceType, - gatewayRequestData.serviceProtocol)) { + if (m_serversModel->isServerFromApiAlreadyExists(m_apiServicesModel->getCountryCode(), m_apiServicesModel->getSelectedServiceType(), + m_apiServicesModel->getSelectedServiceProtocol())) { emit errorOccurred(ErrorCode::ApiConfigAlreadyAdded); return false; } - ProtocolData protocolData = generateProtocolData(gatewayRequestData.serviceProtocol); + GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs, + m_settings->isStrictKillSwitchEnabled()); - QJsonObject apiPayload = gatewayRequestData.toJsonObject(); - appendProtocolDataToApiPayload(gatewayRequestData.serviceProtocol, protocolData, apiPayload); + auto installationUuid = m_settings->getInstallationUuid(true); + auto userCountryCode = m_apiServicesModel->getCountryCode(); + auto serviceType = m_apiServicesModel->getSelectedServiceType(); + auto serviceProtocol = m_apiServicesModel->getSelectedServiceProtocol(); + + ApiPayloadData apiPayloadData = generateApiPayloadData(serviceProtocol); + + QJsonObject apiPayload = fillApiPayload(serviceProtocol, apiPayloadData); + apiPayload[configKey::userCountryCode] = userCountryCode; + apiPayload[configKey::serviceType] = serviceType; + apiPayload[configKey::uuid] = installationUuid; + apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION); QByteArray responseBody; - ErrorCode errorCode = executeRequest(QString("%1v1/config"), apiPayload, responseBody); + ErrorCode errorCode = gatewayController.post(QString("%1v1/config"), apiPayload, responseBody); QJsonObject serverConfig; if (errorCode == ErrorCode::NoError) { - errorCode = fillServerConfig(gatewayRequestData.serviceProtocol, protocolData, responseBody, serverConfig); - if (errorCode != ErrorCode::NoError) { - emit errorOccurred(errorCode); - return false; - } + fillServerConfig(serviceProtocol, apiPayloadData, responseBody, serverConfig); QJsonObject apiConfig = serverConfig.value(configKey::apiConfig).toObject(); apiConfig.insert(configKey::userCountryCode, m_apiServicesModel->getCountryCode()); @@ -393,33 +218,39 @@ bool ApiConfigsController::importServiceFromGateway() bool ApiConfigsController::updateServiceFromGateway(const int serverIndex, const QString &newCountryCode, const QString &newCountryName, bool reloadServiceConfig) { + GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs, + m_settings->isStrictKillSwitchEnabled()); + auto serverConfig = m_serversModel->getServerConfig(serverIndex); auto apiConfig = serverConfig.value(configKey::apiConfig).toObject(); + auto authData = serverConfig.value(configKey::authData).toObject(); - GatewayRequestData gatewayRequestData { QSysInfo::productType(), - QString(APP_VERSION), - m_settings->getInstallationUuid(true), - apiConfig.value(configKey::userCountryCode).toString(), - newCountryCode, - apiConfig.value(configKey::serviceType).toString(), - apiConfig.value(configKey::serviceProtocol).toString(), - serverConfig.value(configKey::authData).toObject() }; + auto installationUuid = m_settings->getInstallationUuid(true); + auto userCountryCode = apiConfig.value(configKey::userCountryCode).toString(); + auto serviceType = apiConfig.value(configKey::serviceType).toString(); + auto serviceProtocol = apiConfig.value(configKey::serviceProtocol).toString(); - ProtocolData protocolData = generateProtocolData(gatewayRequestData.serviceProtocol); + ApiPayloadData apiPayloadData = generateApiPayloadData(serviceProtocol); - QJsonObject apiPayload = gatewayRequestData.toJsonObject(); - appendProtocolDataToApiPayload(gatewayRequestData.serviceProtocol, protocolData, apiPayload); + QJsonObject apiPayload = fillApiPayload(serviceProtocol, apiPayloadData); + apiPayload[configKey::userCountryCode] = userCountryCode; + apiPayload[configKey::serviceType] = serviceType; + apiPayload[configKey::uuid] = installationUuid; + apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION); + + if (!newCountryCode.isEmpty()) { + apiPayload[configKey::serverCountryCode] = newCountryCode; + } + if (!authData.isEmpty()) { + apiPayload[configKey::authData] = authData; + } QByteArray responseBody; - ErrorCode errorCode = executeRequest(QString("%1v1/config"), apiPayload, responseBody); + ErrorCode errorCode = gatewayController.post(QString("%1v1/config"), apiPayload, responseBody); QJsonObject newServerConfig; if (errorCode == ErrorCode::NoError) { - errorCode = fillServerConfig(gatewayRequestData.serviceProtocol, protocolData, responseBody, newServerConfig); - if (errorCode != ErrorCode::NoError) { - emit errorOccurred(errorCode); - return false; - } + fillServerConfig(serviceProtocol, apiPayloadData, responseBody, newServerConfig); QJsonObject newApiConfig = newServerConfig.value(configKey::apiConfig).toObject(); newApiConfig.insert(configKey::userCountryCode, apiConfig.value(configKey::userCountryCode)); @@ -428,12 +259,8 @@ bool ApiConfigsController::updateServiceFromGateway(const int serverIndex, const newApiConfig.insert(apiDefs::key::vpnKey, apiConfig.value(apiDefs::key::vpnKey)); newServerConfig.insert(configKey::apiConfig, newApiConfig); - newServerConfig.insert(configKey::authData, gatewayRequestData.authData); + newServerConfig.insert(configKey::authData, authData); - if (serverConfig.value(config_key::nameOverriddenByUser).toBool()) { - newServerConfig.insert(config_key::name, serverConfig.value(config_key::name)); - newServerConfig.insert(config_key::nameOverriddenByUser, true); - } m_serversModel->editServer(newServerConfig, serverIndex); if (reloadServiceConfig) { emit reloadServerFromApiFinished(tr("API config reloaded")); @@ -463,13 +290,10 @@ bool ApiConfigsController::updateServiceFromTelegram(const int serverIndex) auto installationUuid = m_settings->getInstallationUuid(true); QString serviceProtocol = serverConfig.value(configKey::protocol).toString(); - ProtocolData protocolData = generateProtocolData(serviceProtocol); + ApiPayloadData apiPayloadData = generateApiPayloadData(serviceProtocol); - QJsonObject apiPayload; - appendProtocolDataToApiPayload(serviceProtocol, protocolData, apiPayload); + QJsonObject apiPayload = fillApiPayload(serviceProtocol, apiPayloadData); apiPayload[configKey::uuid] = installationUuid; - apiPayload[configKey::osVersion] = QSysInfo::productType(); - apiPayload[configKey::appVersion] = QString(APP_VERSION); apiPayload[configKey::accessToken] = serverConfig.value(configKey::accessToken).toString(); apiPayload[configKey::apiEndpoint] = serverConfig.value(configKey::apiEndpoint).toString(); @@ -477,11 +301,7 @@ bool ApiConfigsController::updateServiceFromTelegram(const int serverIndex) ErrorCode errorCode = gatewayController.post(QString("%1v1/proxy_config"), apiPayload, responseBody); if (errorCode == ErrorCode::NoError) { - errorCode = fillServerConfig(serviceProtocol, protocolData, responseBody, serverConfig); - if (errorCode != ErrorCode::NoError) { - emit errorOccurred(errorCode); - return false; - } + fillServerConfig(serviceProtocol, apiPayloadData, responseBody, serverConfig); m_serversModel->editServer(serverConfig, serverIndex); emit updateServerFromApiFinished(); @@ -494,6 +314,9 @@ bool ApiConfigsController::updateServiceFromTelegram(const int serverIndex) bool ApiConfigsController::deactivateDevice() { + GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs, + m_settings->isStrictKillSwitchEnabled()); + auto serverIndex = m_serversModel->getProcessedServerIndex(); auto serverConfigObject = m_serversModel->getServerConfig(serverIndex); auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject(); @@ -502,19 +325,19 @@ bool ApiConfigsController::deactivateDevice() return true; } - GatewayRequestData gatewayRequestData { QSysInfo::productType(), - QString(APP_VERSION), - m_settings->getInstallationUuid(true), - apiConfigObject.value(configKey::userCountryCode).toString(), - apiConfigObject.value(configKey::serverCountryCode).toString(), - apiConfigObject.value(configKey::serviceType).toString(), - "", - serverConfigObject.value(configKey::authData).toObject() }; + QString protocol = apiConfigObject.value(configKey::serviceProtocol).toString(); + ApiPayloadData apiPayloadData = generateApiPayloadData(protocol); - QJsonObject apiPayload = gatewayRequestData.toJsonObject(); + QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData); + apiPayload[configKey::userCountryCode] = apiConfigObject.value(configKey::userCountryCode); + apiPayload[configKey::serverCountryCode] = apiConfigObject.value(configKey::serverCountryCode); + apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType); + apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData); + apiPayload[configKey::uuid] = m_settings->getInstallationUuid(true); + apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION); QByteArray responseBody; - ErrorCode errorCode = executeRequest(QString("%1v1/revoke_config"), apiPayload, responseBody); + ErrorCode errorCode = gatewayController.post(QString("%1v1/revoke_config"), apiPayload, responseBody); if (errorCode != ErrorCode::NoError && errorCode != ErrorCode::ApiNotFoundError) { emit errorOccurred(errorCode); return false; @@ -528,6 +351,9 @@ bool ApiConfigsController::deactivateDevice() bool ApiConfigsController::deactivateExternalDevice(const QString &uuid, const QString &serverCountryCode) { + GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs, + m_settings->isStrictKillSwitchEnabled()); + auto serverIndex = m_serversModel->getProcessedServerIndex(); auto serverConfigObject = m_serversModel->getServerConfig(serverIndex); auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject(); @@ -536,19 +362,19 @@ bool ApiConfigsController::deactivateExternalDevice(const QString &uuid, const Q return true; } - GatewayRequestData gatewayRequestData { QSysInfo::productType(), - QString(APP_VERSION), - uuid, - apiConfigObject.value(configKey::userCountryCode).toString(), - serverCountryCode, - apiConfigObject.value(configKey::serviceType).toString(), - "", - serverConfigObject.value(configKey::authData).toObject() }; + QString protocol = apiConfigObject.value(configKey::serviceProtocol).toString(); + ApiPayloadData apiPayloadData = generateApiPayloadData(protocol); - QJsonObject apiPayload = gatewayRequestData.toJsonObject(); + QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData); + apiPayload[configKey::userCountryCode] = apiConfigObject.value(configKey::userCountryCode); + apiPayload[configKey::serverCountryCode] = serverCountryCode; + apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType); + apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData); + apiPayload[configKey::uuid] = uuid; + apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION); QByteArray responseBody; - ErrorCode errorCode = executeRequest(QString("%1v1/revoke_config"), apiPayload, responseBody); + ErrorCode errorCode = gatewayController.post(QString("%1v1/revoke_config"), apiPayload, responseBody); if (errorCode != ErrorCode::NoError && errorCode != ErrorCode::ApiNotFoundError) { emit errorOccurred(errorCode); return false; @@ -587,29 +413,117 @@ bool ApiConfigsController::isConfigValid() return true; } -void ApiConfigsController::setCurrentProtocol(const QString &protocolName) +ApiConfigsController::ApiPayloadData ApiConfigsController::generateApiPayloadData(const QString &protocol) { - auto serverIndex = m_serversModel->getProcessedServerIndex(); - auto serverConfigObject = m_serversModel->getServerConfig(serverIndex); - auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject(); - - apiConfigObject[configKey::serviceProtocol] = protocolName; - - serverConfigObject.insert(configKey::apiConfig, apiConfigObject); - - m_serversModel->editServer(serverConfigObject, serverIndex); + ApiConfigsController::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; } -bool ApiConfigsController::isVlessProtocol() +QJsonObject ApiConfigsController::fillApiPayload(const QString &protocol, const ApiPayloadData &apiPayloadData) { - auto serverIndex = m_serversModel->getProcessedServerIndex(); - auto serverConfigObject = m_serversModel->getServerConfig(serverIndex); - auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject(); - - if (apiConfigObject[configKey::serviceProtocol].toString() == "vless") { - return true; + QJsonObject obj; + if (protocol == configKey::cloak) { + obj[configKey::certificate] = apiPayloadData.certRequest.request; + } else if (protocol == configKey::awg) { + obj[configKey::publicKey] = apiPayloadData.wireGuardClientPubKey; } - return false; + + obj[configKey::osVersion] = QSysInfo::productType(); + obj[configKey::appVersion] = QString(APP_VERSION); + + return obj; +} + +void ApiConfigsController::fillServerConfig(const QString &protocol, const ApiPayloadData &apiPayloadData, + const QByteArray &apiResponseBody, QJsonObject &serverConfig) +{ + QString data = QJsonDocument::fromJson(apiResponseBody).object().value(config_key::config).toString(); + + data.replace("vpn://", ""); + QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); + + if (ba.isEmpty()) { + emit errorOccurred(ErrorCode::ApiConfigEmptyError); + return; + } + + QByteArray ba_uncompressed = qUncompress(ba); + if (!ba_uncompressed.isEmpty()) { + ba = ba_uncompressed; + } + + QString configStr = ba; + if (protocol == configKey::cloak) { + configStr.replace("", "\n"); + configStr.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey); + } else if (protocol == configKey::awg) { + configStr.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey); + auto newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object(); + auto containers = newServerConfig.value(config_key::containers).toArray(); + if (containers.isEmpty()) { + return; // todo process error + } + auto container = containers.at(0).toObject(); + QString containerName = ContainerProps::containerTypeToString(DockerContainer::Awg); + auto containerConfig = container.value(containerName).toObject(); + auto protocolConfig = QJsonDocument::fromJson(containerConfig.value(config_key::last_config).toString().toUtf8()).object(); + containerConfig[config_key::junkPacketCount] = protocolConfig.value(config_key::junkPacketCount); + containerConfig[config_key::junkPacketMinSize] = protocolConfig.value(config_key::junkPacketMinSize); + containerConfig[config_key::junkPacketMaxSize] = protocolConfig.value(config_key::junkPacketMaxSize); + containerConfig[config_key::initPacketJunkSize] = protocolConfig.value(config_key::initPacketJunkSize); + containerConfig[config_key::responsePacketJunkSize] = protocolConfig.value(config_key::responsePacketJunkSize); + containerConfig[config_key::initPacketMagicHeader] = protocolConfig.value(config_key::initPacketMagicHeader); + containerConfig[config_key::responsePacketMagicHeader] = protocolConfig.value(config_key::responsePacketMagicHeader); + containerConfig[config_key::underloadPacketMagicHeader] = protocolConfig.value(config_key::underloadPacketMagicHeader); + containerConfig[config_key::transportPacketMagicHeader] = protocolConfig.value(config_key::transportPacketMagicHeader); + containerConfig[config_key::specialJunk1] = protocolConfig.value(config_key::specialJunk1); + containerConfig[config_key::specialJunk2] = protocolConfig.value(config_key::specialJunk2); + containerConfig[config_key::specialJunk3] = protocolConfig.value(config_key::specialJunk3); + containerConfig[config_key::specialJunk4] = protocolConfig.value(config_key::specialJunk4); + containerConfig[config_key::specialJunk5] = protocolConfig.value(config_key::specialJunk5); + containerConfig[config_key::controlledJunk1] = protocolConfig.value(config_key::controlledJunk1); + containerConfig[config_key::controlledJunk2] = protocolConfig.value(config_key::controlledJunk2); + containerConfig[config_key::controlledJunk3] = protocolConfig.value(config_key::controlledJunk3); + containerConfig[config_key::specialHandshakeTimeout] = protocolConfig.value(config_key::specialHandshakeTimeout); + container[containerName] = containerConfig; + containers.replace(0, container); + newServerConfig[config_key::containers] = containers; + configStr = QString(QJsonDocument(newServerConfig).toJson()); + } + + QJsonObject newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object(); + serverConfig[config_key::dns1] = newServerConfig.value(config_key::dns1); + serverConfig[config_key::dns2] = newServerConfig.value(config_key::dns2); + serverConfig[config_key::containers] = newServerConfig.value(config_key::containers); + serverConfig[config_key::hostName] = newServerConfig.value(config_key::hostName); + + if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) { + serverConfig[config_key::configVersion] = newServerConfig.value(config_key::configVersion); + serverConfig[config_key::description] = newServerConfig.value(config_key::description); + serverConfig[config_key::name] = newServerConfig.value(config_key::name); + } + + auto defaultContainer = newServerConfig.value(config_key::defaultContainer).toString(); + serverConfig[config_key::defaultContainer] = defaultContainer; + + QVariantMap map = serverConfig.value(configKey::apiConfig).toObject().toVariantMap(); + map.insert(newServerConfig.value(configKey::apiConfig).toObject().toVariantMap()); + auto apiConfig = QJsonObject::fromVariantMap(map); + + if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) { + apiConfig.insert(configKey::serviceInfo, QJsonDocument::fromJson(apiResponseBody).object().value(configKey::serviceInfo).toObject()); + } + + serverConfig[configKey::apiConfig] = apiConfig; + + return; } QList ApiConfigsController::getQrCodes() @@ -626,10 +540,3 @@ QString ApiConfigsController::getVpnKey() { return m_vpnKey; } - -ErrorCode ApiConfigsController::executeRequest(const QString &endpoint, const QJsonObject &apiPayload, QByteArray &responseBody) -{ - GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs, - m_settings->isStrictKillSwitchEnabled()); - return gatewayController.post(endpoint, apiPayload, responseBody); -} diff --git a/client/ui/controllers/api/apiConfigsController.h b/client/ui/controllers/api/apiConfigsController.h index a04a142c..2fe981e4 100644 --- a/client/ui/controllers/api/apiConfigsController.h +++ b/client/ui/controllers/api/apiConfigsController.h @@ -35,9 +35,6 @@ public slots: bool isConfigValid(); - void setCurrentProtocol(const QString &protocolName); - bool isVlessProtocol(); - signals: void errorOccurred(ErrorCode errorCode); @@ -49,12 +46,23 @@ signals: void vpnKeyExportReady(); private: + struct ApiPayloadData + { + OpenVpnConfigurator::ConnectionData certRequest; + + QString wireGuardClientPrivKey; + QString wireGuardClientPubKey; + }; + + ApiPayloadData generateApiPayloadData(const QString &protocol); + QJsonObject fillApiPayload(const QString &protocol, const ApiPayloadData &apiPayloadData); + void fillServerConfig(const QString &protocol, const ApiPayloadData &apiPayloadData, const QByteArray &apiResponseBody, + QJsonObject &serverConfig); + QList getQrCodes(); int getQrCodesCount(); QString getVpnKey(); - ErrorCode executeRequest(const QString &endpoint, const QJsonObject &apiPayload, QByteArray &responseBody); - QList m_qrCodes; QString m_vpnKey; diff --git a/client/ui/controllers/importController.cpp b/client/ui/controllers/importController.cpp index ea1d5d8e..c414f3df 100644 --- a/client/ui/controllers/importController.cpp +++ b/client/ui/controllers/importController.cpp @@ -12,7 +12,6 @@ #include "core/errorstrings.h" #include "core/qrCodeUtils.h" #include "core/serialization/serialization.h" -#include "protocols/protocols_defs.h" #include "systemController.h" #include "utilities.h" @@ -286,19 +285,15 @@ void ImportController::processNativeWireGuardConfig() clientProtocolConfig[config_key::responsePacketMagicHeader] = "2"; clientProtocolConfig[config_key::underloadPacketMagicHeader] = "3"; clientProtocolConfig[config_key::transportPacketMagicHeader] = "4"; - - // clientProtocolConfig[config_key::cookieReplyPacketJunkSize] = "0"; - // clientProtocolConfig[config_key::transportPacketJunkSize] = "0"; - - // clientProtocolConfig[config_key::specialJunk1] = ""; - // clientProtocolConfig[config_key::specialJunk2] = ""; - // clientProtocolConfig[config_key::specialJunk3] = ""; - // clientProtocolConfig[config_key::specialJunk4] = ""; - // clientProtocolConfig[config_key::specialJunk5] = ""; - // clientProtocolConfig[config_key::controlledJunk1] = ""; - // clientProtocolConfig[config_key::controlledJunk2] = ""; - // clientProtocolConfig[config_key::controlledJunk3] = ""; - // clientProtocolConfig[config_key::specialHandshakeTimeout] = "0"; + clientProtocolConfig[config_key::specialJunk1] = ""; + clientProtocolConfig[config_key::specialJunk2] = ""; + clientProtocolConfig[config_key::specialJunk3] = ""; + clientProtocolConfig[config_key::specialJunk4] = ""; + clientProtocolConfig[config_key::specialJunk5] = ""; + clientProtocolConfig[config_key::controlledJunk1] = ""; + clientProtocolConfig[config_key::controlledJunk2] = ""; + clientProtocolConfig[config_key::controlledJunk3] = ""; + clientProtocolConfig[config_key::specialHandshakeTimeout] = "0"; clientProtocolConfig[config_key::isObfuscationEnabled] = true; @@ -452,33 +447,39 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data) lastConfig[config_key::allowed_ips] = allowedIpsJsonArray; QString protocolName = "wireguard"; - - const QStringList requiredJunkFields = { config_key::junkPacketCount, config_key::junkPacketMinSize, - config_key::junkPacketMaxSize, config_key::initPacketJunkSize, - config_key::responsePacketJunkSize, config_key::initPacketMagicHeader, - config_key::responsePacketMagicHeader, config_key::underloadPacketMagicHeader, - config_key::transportPacketMagicHeader }; - - const QStringList optionalJunkFields = { // config_key::cookieReplyPacketJunkSize, - // config_key::transportPacketJunkSize, - config_key::specialJunk1, config_key::specialJunk2, config_key::specialJunk3, - config_key::specialJunk4, config_key::specialJunk5, config_key::controlledJunk1, - config_key::controlledJunk2, config_key::controlledJunk3, config_key::specialHandshakeTimeout - }; - - bool hasAllRequiredFields = std::all_of(requiredJunkFields.begin(), requiredJunkFields.end(), - [&configMap](const QString &field) { return !configMap.value(field).isEmpty(); }); - if (hasAllRequiredFields) { - for (const QString &field : requiredJunkFields) { - lastConfig[field] = configMap.value(field); - } - - for (const QString &field : optionalJunkFields) { - if (!configMap.value(field).isEmpty()) { - lastConfig[field] = configMap.value(field); - } - } - + if (!configMap.value(config_key::junkPacketCount).isEmpty() && !configMap.value(config_key::junkPacketMinSize).isEmpty() + && !configMap.value(config_key::junkPacketMaxSize).isEmpty() && !configMap.value(config_key::initPacketJunkSize).isEmpty() + && !configMap.value(config_key::responsePacketJunkSize).isEmpty() && !configMap.value(config_key::initPacketMagicHeader).isEmpty() + && !configMap.value(config_key::responsePacketMagicHeader).isEmpty() + && !configMap.value(config_key::underloadPacketMagicHeader).isEmpty() + && !configMap.value(config_key::transportPacketMagicHeader).isEmpty() + && !configMap.value(config_key::specialJunk1).isEmpty() + && !configMap.value(config_key::specialJunk2).isEmpty() + && !configMap.value(config_key::specialJunk3).isEmpty() + && !configMap.value(config_key::specialJunk4).isEmpty() + && !configMap.value(config_key::specialJunk5).isEmpty() + && !configMap.value(config_key::controlledJunk1).isEmpty() + && !configMap.value(config_key::controlledJunk2).isEmpty() + && !configMap.value(config_key::controlledJunk3).isEmpty() + && !configMap.value(config_key::specialHandshakeTimeout).isEmpty()) { + lastConfig[config_key::junkPacketCount] = configMap.value(config_key::junkPacketCount); + lastConfig[config_key::junkPacketMinSize] = configMap.value(config_key::junkPacketMinSize); + lastConfig[config_key::junkPacketMaxSize] = configMap.value(config_key::junkPacketMaxSize); + lastConfig[config_key::initPacketJunkSize] = configMap.value(config_key::initPacketJunkSize); + lastConfig[config_key::responsePacketJunkSize] = configMap.value(config_key::responsePacketJunkSize); + lastConfig[config_key::initPacketMagicHeader] = configMap.value(config_key::initPacketMagicHeader); + lastConfig[config_key::responsePacketMagicHeader] = configMap.value(config_key::responsePacketMagicHeader); + lastConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader); + lastConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader); + lastConfig[config_key::specialJunk1] = configMap.value(config_key::specialJunk1); + lastConfig[config_key::specialJunk2] = configMap.value(config_key::specialJunk2); + lastConfig[config_key::specialJunk3] = configMap.value(config_key::specialJunk3); + lastConfig[config_key::specialJunk4] = configMap.value(config_key::specialJunk4); + lastConfig[config_key::specialJunk5] = configMap.value(config_key::specialJunk5); + lastConfig[config_key::controlledJunk1] = configMap.value(config_key::controlledJunk1); + lastConfig[config_key::controlledJunk2] = configMap.value(config_key::controlledJunk2); + lastConfig[config_key::controlledJunk3] = configMap.value(config_key::controlledJunk3); + lastConfig[config_key::specialHandshakeTimeout] = configMap.value(config_key::specialHandshakeTimeout); protocolName = "awg"; m_configType = ConfigTypes::Awg; } diff --git a/client/ui/controllers/installController.cpp b/client/ui/controllers/installController.cpp index d7f9dfbc..a673af8a 100755 --- a/client/ui/controllers/installController.cpp +++ b/client/ui/controllers/installController.cpp @@ -8,7 +8,6 @@ #include #include -#include "core/api/apiUtils.h" #include "core/controllers/serverController.h" #include "core/controllers/vpnConfigurationController.h" #include "core/networkUtilities.h" @@ -16,6 +15,7 @@ #include "ui/models/protocols/awgConfigModel.h" #include "ui/models/protocols/wireguardConfigModel.h" #include "utilities.h" +#include "core/api/apiUtils.h" namespace { @@ -79,36 +79,12 @@ void InstallController::install(DockerContainer container, int port, TransportPr int s1 = QRandomGenerator::global()->bounded(15, 150); int s2 = QRandomGenerator::global()->bounded(15, 150); - // int s3 = QRandomGenerator::global()->bounded(15, 150); - // int s4 = QRandomGenerator::global()->bounded(15, 150); - - // Ensure all values are unique and don't create equal packet sizes - QSet usedValues; - usedValues.insert(s1); - - while (usedValues.contains(s2) || s1 + AwgConstant::messageInitiationSize == s2 + AwgConstant::messageResponseSize) { + while (s1 + AwgConstant::messageInitiationSize == s2 + AwgConstant::messageResponseSize) { s2 = QRandomGenerator::global()->bounded(15, 150); } - usedValues.insert(s2); - - // while (usedValues.contains(s3) - // || s1 + AwgConstant::messageInitiationSize == s3 + AwgConstant::messageCookieReplySize - // || s2 + AwgConstant::messageResponseSize == s3 + AwgConstant::messageCookieReplySize) { - // s3 = QRandomGenerator::global()->bounded(15, 150); - // } - // usedValues.insert(s3); - - // while (usedValues.contains(s4) - // || s1 + AwgConstant::messageInitiationSize == s4 + AwgConstant::messageTransportSize - // || s2 + AwgConstant::messageResponseSize == s4 + AwgConstant::messageTransportSize - // || s3 + AwgConstant::messageCookieReplySize == s4 + AwgConstant::messageTransportSize) { - // s4 = QRandomGenerator::global()->bounded(15, 150); - // } QString initPacketJunkSize = QString::number(s1); QString responsePacketJunkSize = QString::number(s2); - // QString cookieReplyPacketJunkSize = QString::number(s3); - // QString transportPacketJunkSize = QString::number(s4); QSet headersValue; while (headersValue.size() != 4) { @@ -134,9 +110,6 @@ void InstallController::install(DockerContainer container, int port, TransportPr containerConfig[config_key::transportPacketMagicHeader] = transportPacketMagicHeader; // TODO: - // containerConfig[config_key::cookieReplyPacketJunkSize] = cookieReplyPacketJunkSize; - // containerConfig[config_key::transportPacketJunkSize] = transportPacketJunkSize; - // containerConfig[config_key::specialJunk1] = specialJunk1; // containerConfig[config_key::specialJunk2] = specialJunk2; // containerConfig[config_key::specialJunk3] = specialJunk3; @@ -439,19 +412,16 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia serverConfigMap.value(config_key::underloadPacketMagicHeader); containerConfig[config_key::transportPacketMagicHeader] = serverConfigMap.value(config_key::transportPacketMagicHeader); + containerConfig[config_key::specialJunk1] = serverConfigMap.value(config_key::specialJunk1); + containerConfig[config_key::specialJunk2] = serverConfigMap.value(config_key::specialJunk2); + containerConfig[config_key::specialJunk3] = serverConfigMap.value(config_key::specialJunk3); + containerConfig[config_key::specialJunk4] = serverConfigMap.value(config_key::specialJunk4); + containerConfig[config_key::specialJunk5] = serverConfigMap.value(config_key::specialJunk5); + containerConfig[config_key::controlledJunk1] = serverConfigMap.value(config_key::controlledJunk1); + containerConfig[config_key::controlledJunk2] = serverConfigMap.value(config_key::controlledJunk2); + containerConfig[config_key::controlledJunk3] = serverConfigMap.value(config_key::controlledJunk3); + containerConfig[config_key::specialHandshakeTimeout] = serverConfigMap.value(config_key::specialHandshakeTimeout); - // containerConfig[config_key::cookieReplyPacketJunkSize] = serverConfigMap.value(config_key::cookieReplyPacketJunkSize); - // containerConfig[config_key::transportPacketJunkSize] = serverConfigMap.value(config_key::transportPacketJunkSize); - - // containerConfig[config_key::specialJunk1] = serverConfigMap.value(config_key::specialJunk1); - // containerConfig[config_key::specialJunk2] = serverConfigMap.value(config_key::specialJunk2); - // containerConfig[config_key::specialJunk3] = serverConfigMap.value(config_key::specialJunk3); - // containerConfig[config_key::specialJunk4] = serverConfigMap.value(config_key::specialJunk4); - // containerConfig[config_key::specialJunk5] = serverConfigMap.value(config_key::specialJunk5); - // containerConfig[config_key::controlledJunk1] = serverConfigMap.value(config_key::controlledJunk1); - // containerConfig[config_key::controlledJunk2] = serverConfigMap.value(config_key::controlledJunk2); - // containerConfig[config_key::controlledJunk3] = serverConfigMap.value(config_key::controlledJunk3); - // containerConfig[config_key::specialHandshakeTimeout] = serverConfigMap.value(config_key::specialHandshakeTimeout); } else if (protocol == Proto::WireGuard) { QString serverConfig = serverController->getTextFileFromContainer(container, credentials, diff --git a/client/ui/models/api/apiAccountInfoModel.cpp b/client/ui/models/api/apiAccountInfoModel.cpp index bd3027a4..fdd4e2ca 100644 --- a/client/ui/models/api/apiAccountInfoModel.cpp +++ b/client/ui/models/api/apiAccountInfoModel.cpp @@ -75,12 +75,6 @@ QVariant ApiAccountInfoModel::data(const QModelIndex &index, int role) const } return false; } - case IsProtocolSelectionSupportedRole: { - if (m_accountInfoData.supportedProtocols.size() > 1) { - return true; - } - return false; - } } return QVariant(); @@ -101,10 +95,6 @@ void ApiAccountInfoModel::updateModel(const QJsonObject &accountInfoObject, cons accountInfoData.configType = apiUtils::getConfigType(serverConfig); - for (const auto &protocol : accountInfoObject.value(apiDefs::key::supportedProtocols).toArray()) { - accountInfoData.supportedProtocols.push_back(protocol.toString()); - } - m_accountInfoData = accountInfoData; m_supportInfo = accountInfoObject.value(apiDefs::key::supportInfo).toObject(); @@ -169,7 +159,6 @@ QHash ApiAccountInfoModel::roleNames() const roles[ServiceDescriptionRole] = "serviceDescription"; roles[IsComponentVisibleRole] = "isComponentVisible"; roles[HasExpiredWorkerRole] = "hasExpiredWorker"; - roles[IsProtocolSelectionSupportedRole] = "isProtocolSelectionSupported"; return roles; } diff --git a/client/ui/models/api/apiAccountInfoModel.h b/client/ui/models/api/apiAccountInfoModel.h index f0203967..ead92488 100644 --- a/client/ui/models/api/apiAccountInfoModel.h +++ b/client/ui/models/api/apiAccountInfoModel.h @@ -18,8 +18,7 @@ public: ServiceDescriptionRole, EndDateRole, IsComponentVisibleRole, - HasExpiredWorkerRole, - IsProtocolSelectionSupportedRole + HasExpiredWorkerRole }; explicit ApiAccountInfoModel(QObject *parent = nullptr); @@ -52,8 +51,6 @@ private: int maxDeviceCount; apiDefs::ConfigType configType; - - QStringList supportedProtocols; }; AccountInfoData m_accountInfoData; diff --git a/client/ui/models/protocols/awgConfigModel.cpp b/client/ui/models/protocols/awgConfigModel.cpp index e14a3152..a05aa64f 100644 --- a/client/ui/models/protocols/awgConfigModel.cpp +++ b/client/ui/models/protocols/awgConfigModel.cpp @@ -25,34 +25,61 @@ bool AwgConfigModel::setData(const QModelIndex &index, const QVariant &value, in case Roles::PortRole: m_serverProtocolConfig.insert(config_key::port, value.toString()); break; case Roles::ClientMtuRole: m_clientProtocolConfig.insert(config_key::mtu, value.toString()); break; - case Roles::ClientJunkPacketCountRole: m_clientProtocolConfig.insert(config_key::junkPacketCount, value.toString()); break; - case Roles::ClientJunkPacketMinSizeRole: m_clientProtocolConfig.insert(config_key::junkPacketMinSize, value.toString()); break; - case Roles::ClientJunkPacketMaxSizeRole: m_clientProtocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); break; - case Roles::ClientSpecialJunk1Role: m_clientProtocolConfig.insert(config_key::specialJunk1, value.toString()); break; - case Roles::ClientSpecialJunk2Role: m_clientProtocolConfig.insert(config_key::specialJunk2, value.toString()); break; - case Roles::ClientSpecialJunk3Role: m_clientProtocolConfig.insert(config_key::specialJunk3, value.toString()); break; - case Roles::ClientSpecialJunk4Role: m_clientProtocolConfig.insert(config_key::specialJunk4, value.toString()); break; - case Roles::ClientSpecialJunk5Role: m_clientProtocolConfig.insert(config_key::specialJunk5, value.toString()); break; - case Roles::ClientControlledJunk1Role: m_clientProtocolConfig.insert(config_key::controlledJunk1, value.toString()); break; - case Roles::ClientControlledJunk2Role: m_clientProtocolConfig.insert(config_key::controlledJunk2, value.toString()); break; - case Roles::ClientControlledJunk3Role: m_clientProtocolConfig.insert(config_key::controlledJunk3, value.toString()); break; + case Roles::ClientJunkPacketCountRole: + m_clientProtocolConfig.insert(config_key::junkPacketCount, value.toString()); + break; + case Roles::ClientJunkPacketMinSizeRole: + m_clientProtocolConfig.insert(config_key::junkPacketMinSize, value.toString()); + break; + case Roles::ClientJunkPacketMaxSizeRole: + m_clientProtocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); + break; + case Roles::ClientSpecialJunk1Role: + m_clientProtocolConfig.insert(config_key::specialJunk1, value.toString()); + break; + case Roles::ClientSpecialJunk2Role: + m_clientProtocolConfig.insert(config_key::specialJunk2, value.toString()); + break; + case Roles::ClientSpecialJunk3Role: + m_clientProtocolConfig.insert(config_key::specialJunk3, value.toString()); + break; + case Roles::ClientSpecialJunk4Role: + m_clientProtocolConfig.insert(config_key::specialJunk4, value.toString()); + break; + case Roles::ClientSpecialJunk5Role: + m_clientProtocolConfig.insert(config_key::specialJunk5, value.toString()); + break; + case Roles::ClientControlledJunk1Role: + m_clientProtocolConfig.insert(config_key::controlledJunk1, value.toString()); + break; + case Roles::ClientControlledJunk2Role: + m_clientProtocolConfig.insert(config_key::controlledJunk2, value.toString()); + break; + case Roles::ClientControlledJunk3Role: + m_clientProtocolConfig.insert(config_key::controlledJunk3, value.toString()); + break; case Roles::ClientSpecialHandshakeTimeoutRole: m_clientProtocolConfig.insert(config_key::specialHandshakeTimeout, value.toString()); break; - case Roles::ServerJunkPacketCountRole: m_serverProtocolConfig.insert(config_key::junkPacketCount, value.toString()); break; - case Roles::ServerJunkPacketMinSizeRole: m_serverProtocolConfig.insert(config_key::junkPacketMinSize, value.toString()); break; - case Roles::ServerJunkPacketMaxSizeRole: m_serverProtocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); break; - case Roles::ServerInitPacketJunkSizeRole: m_serverProtocolConfig.insert(config_key::initPacketJunkSize, value.toString()); break; + + case Roles::ServerJunkPacketCountRole: + m_serverProtocolConfig.insert(config_key::junkPacketCount, value.toString()); + break; + case Roles::ServerJunkPacketMinSizeRole: + m_serverProtocolConfig.insert(config_key::junkPacketMinSize, value.toString()); + break; + case Roles::ServerJunkPacketMaxSizeRole: + m_serverProtocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); + break; + case Roles::ServerInitPacketJunkSizeRole: + m_serverProtocolConfig.insert(config_key::initPacketJunkSize, value.toString()); + break; case Roles::ServerResponsePacketJunkSizeRole: m_serverProtocolConfig.insert(config_key::responsePacketJunkSize, value.toString()); break; - // case Roles::ServerCookieReplyPacketJunkSizeRole: - // m_serverProtocolConfig.insert(config_key::cookieReplyPacketJunkSize, value.toString()); - // break; - // case Roles::ServerTransportPacketJunkSizeRole: - // m_serverProtocolConfig.insert(config_key::transportPacketJunkSize, value.toString()); - // break; - case Roles::ServerInitPacketMagicHeaderRole: m_serverProtocolConfig.insert(config_key::initPacketMagicHeader, value.toString()); break; + case Roles::ServerInitPacketMagicHeaderRole: + m_serverProtocolConfig.insert(config_key::initPacketMagicHeader, value.toString()); + break; case Roles::ServerResponsePacketMagicHeaderRole: m_serverProtocolConfig.insert(config_key::responsePacketMagicHeader, value.toString()); break; @@ -90,19 +117,22 @@ QVariant AwgConfigModel::data(const QModelIndex &index, int role) const case Roles::ClientControlledJunk1Role: return m_clientProtocolConfig.value(config_key::controlledJunk1); case Roles::ClientControlledJunk2Role: return m_clientProtocolConfig.value(config_key::controlledJunk2); case Roles::ClientControlledJunk3Role: return m_clientProtocolConfig.value(config_key::controlledJunk3); - case Roles::ClientSpecialHandshakeTimeoutRole: return m_clientProtocolConfig.value(config_key::specialHandshakeTimeout); + case Roles::ClientSpecialHandshakeTimeoutRole: + return m_clientProtocolConfig.value(config_key::specialHandshakeTimeout); case Roles::ServerJunkPacketCountRole: return m_serverProtocolConfig.value(config_key::junkPacketCount); case Roles::ServerJunkPacketMinSizeRole: return m_serverProtocolConfig.value(config_key::junkPacketMinSize); case Roles::ServerJunkPacketMaxSizeRole: return m_serverProtocolConfig.value(config_key::junkPacketMaxSize); case Roles::ServerInitPacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::initPacketJunkSize); - case Roles::ServerResponsePacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::responsePacketJunkSize); - // case Roles::ServerCookieReplyPacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize); - // case Roles::ServerTransportPacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::transportPacketJunkSize); + case Roles::ServerResponsePacketJunkSizeRole: + return m_serverProtocolConfig.value(config_key::responsePacketJunkSize); case Roles::ServerInitPacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::initPacketMagicHeader); - case Roles::ServerResponsePacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::responsePacketMagicHeader); - case Roles::ServerUnderloadPacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::underloadPacketMagicHeader); - case Roles::ServerTransportPacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::transportPacketMagicHeader); + case Roles::ServerResponsePacketMagicHeaderRole: + return m_serverProtocolConfig.value(config_key::responsePacketMagicHeader); + case Roles::ServerUnderloadPacketMagicHeaderRole: + return m_serverProtocolConfig.value(config_key::underloadPacketMagicHeader); + case Roles::ServerTransportPacketMagicHeaderRole: + return m_serverProtocolConfig.value(config_key::transportPacketMagicHeader); } return QVariant(); @@ -117,13 +147,15 @@ void AwgConfigModel::updateModel(const QJsonObject &config) QJsonObject serverProtocolConfig = config.value(config_key::awg).toObject(); - auto defaultTransportProto = ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::Awg), Proto::Awg); + auto defaultTransportProto = + ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::Awg), Proto::Awg); m_serverProtocolConfig.insert(config_key::transport_proto, serverProtocolConfig.value(config_key::transport_proto).toString(defaultTransportProto)); m_serverProtocolConfig[config_key::last_config] = serverProtocolConfig.value(config_key::last_config); m_serverProtocolConfig[config_key::subnet_address] = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress); - m_serverProtocolConfig[config_key::port] = serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort); + m_serverProtocolConfig[config_key::port] = + serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort); m_serverProtocolConfig[config_key::junkPacketCount] = serverProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount); m_serverProtocolConfig[config_key::junkPacketMinSize] = @@ -133,29 +165,33 @@ void AwgConfigModel::updateModel(const QJsonObject &config) m_serverProtocolConfig[config_key::initPacketJunkSize] = serverProtocolConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize); m_serverProtocolConfig[config_key::responsePacketJunkSize] = - serverProtocolConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize); - // m_serverProtocolConfig[config_key::cookieReplyPacketJunkSize] = - // serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize); - // m_serverProtocolConfig[config_key::transportPacketJunkSize] = - // serverProtocolConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize); + serverProtocolConfig.value(config_key::responsePacketJunkSize) + .toString(protocols::awg::defaultResponsePacketJunkSize); m_serverProtocolConfig[config_key::initPacketMagicHeader] = - serverProtocolConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader); + serverProtocolConfig.value(config_key::initPacketMagicHeader) + .toString(protocols::awg::defaultInitPacketMagicHeader); m_serverProtocolConfig[config_key::responsePacketMagicHeader] = - serverProtocolConfig.value(config_key::responsePacketMagicHeader).toString(protocols::awg::defaultResponsePacketMagicHeader); + serverProtocolConfig.value(config_key::responsePacketMagicHeader) + .toString(protocols::awg::defaultResponsePacketMagicHeader); m_serverProtocolConfig[config_key::underloadPacketMagicHeader] = - serverProtocolConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader); + serverProtocolConfig.value(config_key::underloadPacketMagicHeader) + .toString(protocols::awg::defaultUnderloadPacketMagicHeader); m_serverProtocolConfig[config_key::transportPacketMagicHeader] = - serverProtocolConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader); + serverProtocolConfig.value(config_key::transportPacketMagicHeader) + .toString(protocols::awg::defaultTransportPacketMagicHeader); auto lastConfig = m_serverProtocolConfig.value(config_key::last_config).toString(); QJsonObject clientProtocolConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object(); m_clientProtocolConfig[config_key::mtu] = clientProtocolConfig[config_key::mtu].toString(protocols::awg::defaultMtu); m_clientProtocolConfig[config_key::junkPacketCount] = - clientProtocolConfig.value(config_key::junkPacketCount).toString(m_serverProtocolConfig[config_key::junkPacketCount].toString()); + clientProtocolConfig.value(config_key::junkPacketCount) + .toString(m_serverProtocolConfig[config_key::junkPacketCount].toString()); m_clientProtocolConfig[config_key::junkPacketMinSize] = - clientProtocolConfig.value(config_key::junkPacketMinSize).toString(m_serverProtocolConfig[config_key::junkPacketMinSize].toString()); + clientProtocolConfig.value(config_key::junkPacketMinSize) + .toString(m_serverProtocolConfig[config_key::junkPacketMinSize].toString()); m_clientProtocolConfig[config_key::junkPacketMaxSize] = - clientProtocolConfig.value(config_key::junkPacketMaxSize).toString(m_serverProtocolConfig[config_key::junkPacketMaxSize].toString()); + clientProtocolConfig.value(config_key::junkPacketMaxSize) + .toString(m_serverProtocolConfig[config_key::junkPacketMaxSize].toString()); m_clientProtocolConfig[config_key::specialJunk1] = clientProtocolConfig.value(config_key::specialJunk1).toString(protocols::awg::defaultSpecialJunk1); m_clientProtocolConfig[config_key::specialJunk2] = @@ -173,7 +209,8 @@ void AwgConfigModel::updateModel(const QJsonObject &config) m_clientProtocolConfig[config_key::controlledJunk3] = clientProtocolConfig.value(config_key::controlledJunk3).toString(protocols::awg::defaultControlledJunk3); m_clientProtocolConfig[config_key::specialHandshakeTimeout] = - clientProtocolConfig.value(config_key::specialHandshakeTimeout).toString(protocols::awg::defaultSpecialHandshakeTimeout); + clientProtocolConfig.value(config_key::specialHandshakeTimeout) + .toString(protocols::awg::defaultSpecialHandshakeTimeout); endResetModel(); } @@ -218,17 +255,6 @@ bool AwgConfigModel::isPacketSizeEqual(const int s1, const int s2) return (AwgConstant::messageInitiationSize + s1 == AwgConstant::messageResponseSize + s2); } -// bool AwgConfigModel::isPacketSizeEqual(const int s1, const int s2, const int s3, const int s4) -// { -// int initSize = AwgConstant::messageInitiationSize + s1; -// int responseSize = AwgConstant::messageResponseSize + s2; -// int cookieSize = AwgConstant::messageCookieReplySize + s3; -// int transportSize = AwgConstant::messageTransportSize + s4; - -// return (initSize == responseSize || initSize == cookieSize || initSize == transportSize || responseSize == cookieSize -// || responseSize == transportSize || cookieSize == transportSize); -// } - bool AwgConfigModel::isServerSettingsEqual() { const AwgConfig oldConfig(m_fullConfig.value(config_key::awg).toObject()); @@ -263,9 +289,6 @@ QHash AwgConfigModel::roleNames() const roles[ServerJunkPacketMaxSizeRole] = "serverJunkPacketMaxSize"; roles[ServerInitPacketJunkSizeRole] = "serverInitPacketJunkSize"; roles[ServerResponsePacketJunkSizeRole] = "serverResponsePacketJunkSize"; - roles[ServerCookieReplyPacketJunkSizeRole] = "serverCookieReplyPacketJunkSize"; - roles[ServerTransportPacketJunkSizeRole] = "serverTransportPacketJunkSize"; - roles[ServerInitPacketMagicHeaderRole] = "serverInitPacketMagicHeader"; roles[ServerResponsePacketMagicHeaderRole] = "serverResponsePacketMagicHeader"; roles[ServerUnderloadPacketMagicHeaderRole] = "serverUnderloadPacketMagicHeader"; @@ -279,49 +302,61 @@ AwgConfig::AwgConfig(const QJsonObject &serverProtocolConfig) auto lastConfig = serverProtocolConfig.value(config_key::last_config).toString(); QJsonObject clientProtocolConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object(); clientMtu = clientProtocolConfig[config_key::mtu].toString(protocols::awg::defaultMtu); - clientJunkPacketCount = clientProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount); - clientJunkPacketMinSize = clientProtocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize); - clientJunkPacketMaxSize = clientProtocolConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize); - clientSpecialJunk1 = clientProtocolConfig.value(config_key::specialJunk1).toString(protocols::awg::defaultSpecialJunk1); - clientSpecialJunk2 = clientProtocolConfig.value(config_key::specialJunk2).toString(protocols::awg::defaultSpecialJunk2); - clientSpecialJunk3 = clientProtocolConfig.value(config_key::specialJunk3).toString(protocols::awg::defaultSpecialJunk3); - clientSpecialJunk4 = clientProtocolConfig.value(config_key::specialJunk4).toString(protocols::awg::defaultSpecialJunk4); - clientSpecialJunk5 = clientProtocolConfig.value(config_key::specialJunk5).toString(protocols::awg::defaultSpecialJunk5); - clientControlledJunk1 = clientProtocolConfig.value(config_key::controlledJunk1).toString(protocols::awg::defaultControlledJunk1); - clientControlledJunk2 = clientProtocolConfig.value(config_key::controlledJunk2).toString(protocols::awg::defaultControlledJunk2); - clientControlledJunk3 = clientProtocolConfig.value(config_key::controlledJunk3).toString(protocols::awg::defaultControlledJunk3); - clientSpecialHandshakeTimeout = - clientProtocolConfig.value(config_key::specialHandshakeTimeout).toString(protocols::awg::defaultSpecialHandshakeTimeout); + clientJunkPacketCount = + clientProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount); + clientJunkPacketMinSize = + clientProtocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize); + clientJunkPacketMaxSize = + clientProtocolConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize); + clientSpecialJunk1 = + clientProtocolConfig.value(config_key::specialJunk1).toString(protocols::awg::defaultSpecialJunk1); + clientSpecialJunk2 = + clientProtocolConfig.value(config_key::specialJunk2).toString(protocols::awg::defaultSpecialJunk2); + clientSpecialJunk3 = + clientProtocolConfig.value(config_key::specialJunk3).toString(protocols::awg::defaultSpecialJunk3); + clientSpecialJunk4 = + clientProtocolConfig.value(config_key::specialJunk4).toString(protocols::awg::defaultSpecialJunk4); + clientSpecialJunk5 = + clientProtocolConfig.value(config_key::specialJunk5).toString(protocols::awg::defaultSpecialJunk5); + clientControlledJunk1 = + clientProtocolConfig.value(config_key::controlledJunk1).toString(protocols::awg::defaultControlledJunk1); + clientControlledJunk2 = + clientProtocolConfig.value(config_key::controlledJunk2).toString(protocols::awg::defaultControlledJunk2); + clientControlledJunk3 = + clientProtocolConfig.value(config_key::controlledJunk3).toString(protocols::awg::defaultControlledJunk3); + clientSpecialHandshakeTimeout = clientProtocolConfig.value(config_key::specialHandshakeTimeout) + .toString(protocols::awg::defaultSpecialHandshakeTimeout); - subnetAddress = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress); + subnetAddress = + serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress); port = serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort); - serverJunkPacketCount = serverProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount); - serverJunkPacketMinSize = serverProtocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize); - serverJunkPacketMaxSize = serverProtocolConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize); - serverInitPacketJunkSize = serverProtocolConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize); - serverResponsePacketJunkSize = - serverProtocolConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize); - // serverCookieReplyPacketJunkSize = - // serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize); - // serverTransportPacketJunkSize = - // serverProtocolConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize); - serverInitPacketMagicHeader = - serverProtocolConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader); - serverResponsePacketMagicHeader = - serverProtocolConfig.value(config_key::responsePacketMagicHeader).toString(protocols::awg::defaultResponsePacketMagicHeader); - serverUnderloadPacketMagicHeader = - serverProtocolConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader); - serverTransportPacketMagicHeader = - serverProtocolConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader); + serverJunkPacketCount = + serverProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount); + serverJunkPacketMinSize = + serverProtocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize); + serverJunkPacketMaxSize = + serverProtocolConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize); + serverInitPacketJunkSize = + serverProtocolConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize); + serverResponsePacketJunkSize = serverProtocolConfig.value(config_key::responsePacketJunkSize) + .toString(protocols::awg::defaultResponsePacketJunkSize); + serverInitPacketMagicHeader = serverProtocolConfig.value(config_key::initPacketMagicHeader) + .toString(protocols::awg::defaultInitPacketMagicHeader); + serverResponsePacketMagicHeader = serverProtocolConfig.value(config_key::responsePacketMagicHeader) + .toString(protocols::awg::defaultResponsePacketMagicHeader); + serverUnderloadPacketMagicHeader = serverProtocolConfig.value(config_key::underloadPacketMagicHeader) + .toString(protocols::awg::defaultUnderloadPacketMagicHeader); + serverTransportPacketMagicHeader = serverProtocolConfig.value(config_key::transportPacketMagicHeader) + .toString(protocols::awg::defaultTransportPacketMagicHeader); } bool AwgConfig::hasEqualServerSettings(const AwgConfig &other) const { if (subnetAddress != other.subnetAddress || port != other.port || serverJunkPacketCount != other.serverJunkPacketCount - || serverJunkPacketMinSize != other.serverJunkPacketMinSize || serverJunkPacketMaxSize != other.serverJunkPacketMaxSize - || serverInitPacketJunkSize != other.serverInitPacketJunkSize || serverResponsePacketJunkSize != other.serverResponsePacketJunkSize - // || serverCookieReplyPacketJunkSize != other.serverCookieReplyPacketJunkSize - // || serverTransportPacketJunkSize != other.serverTransportPacketJunkSize + || serverJunkPacketMinSize != other.serverJunkPacketMinSize + || serverJunkPacketMaxSize != other.serverJunkPacketMaxSize + || serverInitPacketJunkSize != other.serverInitPacketJunkSize + || serverResponsePacketJunkSize != other.serverResponsePacketJunkSize || serverInitPacketMagicHeader != other.serverInitPacketMagicHeader || serverResponsePacketMagicHeader != other.serverResponsePacketMagicHeader || serverUnderloadPacketMagicHeader != other.serverUnderloadPacketMagicHeader @@ -334,11 +369,12 @@ bool AwgConfig::hasEqualServerSettings(const AwgConfig &other) const bool AwgConfig::hasEqualClientSettings(const AwgConfig &other) const { if (clientMtu != other.clientMtu || clientJunkPacketCount != other.clientJunkPacketCount - || clientJunkPacketMinSize != other.clientJunkPacketMinSize || clientJunkPacketMaxSize != other.clientJunkPacketMaxSize - || clientSpecialJunk1 != other.clientSpecialJunk1 || clientSpecialJunk2 != other.clientSpecialJunk2 - || clientSpecialJunk3 != other.clientSpecialJunk3 || clientSpecialJunk4 != other.clientSpecialJunk4 - || clientSpecialJunk5 != other.clientSpecialJunk5 || clientControlledJunk1 != other.clientControlledJunk1 - || clientControlledJunk2 != other.clientControlledJunk2 || clientControlledJunk3 != other.clientControlledJunk3 + || clientJunkPacketMinSize != other.clientJunkPacketMinSize + || clientJunkPacketMaxSize != other.clientJunkPacketMaxSize || clientSpecialJunk1 != other.clientSpecialJunk1 + || clientSpecialJunk2 != other.clientSpecialJunk2 || clientSpecialJunk3 != other.clientSpecialJunk3 + || clientSpecialJunk4 != other.clientSpecialJunk4 || clientSpecialJunk5 != other.clientSpecialJunk5 + || clientControlledJunk1 != other.clientControlledJunk1 || clientControlledJunk2 != other.clientControlledJunk2 + || clientControlledJunk3 != other.clientControlledJunk3 || clientSpecialHandshakeTimeout != other.clientSpecialHandshakeTimeout) { return false; } diff --git a/client/ui/models/protocols/awgConfigModel.h b/client/ui/models/protocols/awgConfigModel.h index 0c2374fc..e1f38f71 100644 --- a/client/ui/models/protocols/awgConfigModel.h +++ b/client/ui/models/protocols/awgConfigModel.h @@ -6,12 +6,9 @@ #include "containers/containers_defs.h" -namespace AwgConstant -{ +namespace AwgConstant { const int messageInitiationSize = 148; const int messageResponseSize = 92; - const int messageCookieReplySize = 64; - const int messageTransportSize = 32; } struct AwgConfig @@ -40,8 +37,6 @@ struct AwgConfig QString serverJunkPacketMaxSize; QString serverInitPacketJunkSize; QString serverResponsePacketJunkSize; - QString serverCookieReplyPacketJunkSize; - QString serverTransportPacketJunkSize; QString serverInitPacketMagicHeader; QString serverResponsePacketMagicHeader; QString serverUnderloadPacketMagicHeader; @@ -79,9 +74,6 @@ public: ServerJunkPacketMaxSizeRole, ServerInitPacketJunkSizeRole, ServerResponsePacketJunkSizeRole, - ServerCookieReplyPacketJunkSizeRole, - ServerTransportPacketJunkSizeRole, - ServerInitPacketMagicHeaderRole, ServerResponsePacketMagicHeaderRole, ServerUnderloadPacketMagicHeaderRole, @@ -100,7 +92,7 @@ public slots: QJsonObject getConfig(); bool isHeadersEqual(const QString &h1, const QString &h2, const QString &h3, const QString &h4); - bool isPacketSizeEqual(const int s1, const int s2/*, const int s3, const int s4*/); + bool isPacketSizeEqual(const int s1, const int s2); bool isServerSettingsEqual(); diff --git a/client/ui/models/servers_model.cpp b/client/ui/models/servers_model.cpp index 22813312..0a7b2526 100644 --- a/client/ui/models/servers_model.cpp +++ b/client/ui/models/servers_model.cpp @@ -8,8 +8,6 @@ #include #endif -#include "core/api/apiUtils.h" - namespace { namespace configKey @@ -68,7 +66,6 @@ bool ServersModel::setData(const QModelIndex &index, const QVariant &value, int } else { server.insert(config_key::description, value.toString()); } - server.insert(config_key::nameOverriddenByUser, true); m_settings->editServer(index.row(), server); m_servers.replace(index.row(), server); if (index.row() == m_defaultServerIndex) { @@ -429,7 +426,7 @@ void ServersModel::updateDefaultServerContainersModel() emit defaultServerContainersUpdated(containers); } -QJsonObject ServersModel::getServerConfig(const int serverIndex) const +QJsonObject ServersModel::getServerConfig(const int serverIndex) { return m_servers.at(serverIndex).toObject(); } @@ -816,8 +813,3 @@ const QString ServersModel::getDefaultServerImagePathCollapsed() } return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(countryCode.toUpper()); } - -bool ServersModel::processedServerIsPremium() const -{ - return apiUtils::isPremiumServer(getServerConfig(m_processedServerIndex)); -} diff --git a/client/ui/models/servers_model.h b/client/ui/models/servers_model.h index c36b6534..c4803708 100644 --- a/client/ui/models/servers_model.h +++ b/client/ui/models/servers_model.h @@ -63,9 +63,6 @@ public: Q_PROPERTY(bool isDefaultServerFromApi READ isDefaultServerFromApi NOTIFY defaultServerIndexChanged) Q_PROPERTY(int processedIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged) - Q_PROPERTY(bool processedServerIsPremium READ processedServerIsPremium NOTIFY processedServerChanged) - - bool processedServerIsPremium() const; public slots: void setDefaultServerIndex(const int index); @@ -95,7 +92,7 @@ public slots: void removeServer(); void removeServer(const int serverIndex); - QJsonObject getServerConfig(const int serverIndex) const; + QJsonObject getServerConfig(const int serverIndex); void reloadDefaultServerContainerConfig(); void updateContainerConfig(const int containerIndex, const QJsonObject config); diff --git a/client/ui/qml/Components/AwgTextField.qml b/client/ui/qml/Components/AwgTextField.qml deleted file mode 100644 index 87b023d9..00000000 --- a/client/ui/qml/Components/AwgTextField.qml +++ /dev/null @@ -1,15 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import QtQuick.Layouts - -import "../Controls2" - -TextFieldWithHeaderType { - Layout.fillWidth: true - Layout.topMargin: 16 - - textField.validator: IntValidator { bottom: 0 } - - checkEmptyText: true -} diff --git a/client/ui/qml/Pages2/PageProtocolAwgClientSettings.qml b/client/ui/qml/Pages2/PageProtocolAwgClientSettings.qml index d97d09e8..24755e09 100644 --- a/client/ui/qml/Pages2/PageProtocolAwgClientSettings.qml +++ b/client/ui/qml/Pages2/PageProtocolAwgClientSettings.qml @@ -115,10 +115,14 @@ PageType { KeyNavigation.tab: junkPacketCountTextField.textField } - AwgTextField { + TextFieldWithHeaderType { id: junkPacketCountTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: "Jc - Junk packet count" textField.text: clientJunkPacketCount + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { if (textField.text !== clientJunkPacketCount) { @@ -126,13 +130,19 @@ PageType { } } + checkEmptyText: true + KeyNavigation.tab: junkPacketMinSizeTextField.textField } - AwgTextField { + TextFieldWithHeaderType { id: junkPacketMinSizeTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: "Jmin - Junk packet minimum size" textField.text: clientJunkPacketMinSize + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { if (textField.text !== clientJunkPacketMinSize) { @@ -140,27 +150,36 @@ PageType { } } + checkEmptyText: true + KeyNavigation.tab: junkPacketMaxSizeTextField.textField } - AwgTextField { + TextFieldWithHeaderType { id: junkPacketMaxSizeTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: "Jmax - Junk packet maximum size" textField.text: clientJunkPacketMaxSize + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { if (textField.text !== clientJunkPacketMaxSize) { clientJunkPacketMaxSize = textField.text } } + + checkEmptyText: true } - AwgTextField { + TextFieldWithHeaderType { id: specialJunk1TextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("I1 - First special junk packet") textField.text: clientSpecialJunk1 - textField.validator: null - checkEmptyText: false textField.onEditingFinished: { if (textField.text !== clientSpecialJunk1) { @@ -169,12 +188,13 @@ PageType { } } - AwgTextField { + TextFieldWithHeaderType { id: specialJunk2TextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("I2 - Second special junk packet") textField.text: clientSpecialJunk2 - textField.validator: null - checkEmptyText: false textField.onEditingFinished: { if (textField.text !== clientSpecialJunk2) { @@ -183,12 +203,13 @@ PageType { } } - AwgTextField { + TextFieldWithHeaderType { id: specialJunk3TextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("I3 - Third special junk packet") textField.text: clientSpecialJunk3 - textField.validator: null - checkEmptyText: false textField.onEditingFinished: { if (textField.text !== clientSpecialJunk3) { @@ -197,12 +218,13 @@ PageType { } } - AwgTextField { + TextFieldWithHeaderType { id: specialJunk4TextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("I4 - Fourth special junk packet") textField.text: clientSpecialJunk4 - textField.validator: null - checkEmptyText: false textField.onEditingFinished: { if (textField.text !== clientSpecialJunk4) { @@ -211,12 +233,13 @@ PageType { } } - AwgTextField { + TextFieldWithHeaderType { id: specialJunk5TextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("I5 - Fifth special junk packet") textField.text: clientSpecialJunk5 - textField.validator: null - checkEmptyText: false textField.onEditingFinished: { if (textField.text !== clientSpecialJunk5 ) { @@ -225,12 +248,13 @@ PageType { } } - AwgTextField { + TextFieldWithHeaderType { id: controlledJunk1TextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("J1 - First controlled junk packet") textField.text: clientControlledJunk1 - textField.validator: null - checkEmptyText: false textField.onEditingFinished: { if (textField.text !== clientControlledJunk1) { @@ -239,12 +263,13 @@ PageType { } } - AwgTextField { + TextFieldWithHeaderType { id: controlledJunk2TextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("J2 - Second controlled junk packet") textField.text: clientControlledJunk2 - textField.validator: null - checkEmptyText: false textField.onEditingFinished: { if (textField.text !== clientControlledJunk2) { @@ -253,12 +278,13 @@ PageType { } } - AwgTextField { + TextFieldWithHeaderType { id: controlledJunk3TextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("J3 - Third controlled junk packet") textField.text: clientControlledJunk3 - textField.validator: null - checkEmptyText: false textField.onEditingFinished: { if (textField.text !== clientControlledJunk3) { @@ -267,11 +293,14 @@ PageType { } } - AwgTextField { + TextFieldWithHeaderType { id: iTimeTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("Itime - Special handshake timeout") textField.text: clientSpecialHandshakeTimeout - checkEmptyText: false + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { if (textField.text !== clientSpecialHandshakeTimeout) { @@ -287,72 +316,77 @@ PageType { text: qsTr("Server settings") } - AwgTextField { + TextFieldWithHeaderType { id: portTextField + Layout.fillWidth: true + Layout.topMargin: 8 + enabled: false headerText: qsTr("Port") textField.text: port } - AwgTextField { + TextFieldWithHeaderType { id: initPacketJunkSizeTextField + Layout.fillWidth: true + Layout.topMargin: 16 + enabled: false headerText: "S1 - Init packet junk size" textField.text: serverInitPacketJunkSize } - AwgTextField { + TextFieldWithHeaderType { id: responsePacketJunkSizeTextField + Layout.fillWidth: true + Layout.topMargin: 16 + enabled: false headerText: "S2 - Response packet junk size" textField.text: serverResponsePacketJunkSize } - // AwgTextField { - // id: cookieReplyPacketJunkSizeTextField - // enabled: false - - // headerText: "S3 - Cookie Reply packet junk size" - // textField.text: serverCookieReplyPacketJunkSize - // } - - // AwgTextField { - // id: transportPacketJunkSizeTextField - // enabled: false - - // headerText: "S4 - Transport packet junk size" - // textField.text: serverTransportPacketJunkSize - // } - - AwgTextField { + TextFieldWithHeaderType { id: initPacketMagicHeaderTextField + Layout.fillWidth: true + Layout.topMargin: 16 + enabled: false headerText: "H1 - Init packet magic header" textField.text: serverInitPacketMagicHeader } - AwgTextField { + TextFieldWithHeaderType { id: responsePacketMagicHeaderTextField + Layout.fillWidth: true + Layout.topMargin: 16 + enabled: false headerText: "H2 - Response packet magic header" textField.text: serverResponsePacketMagicHeader } - AwgTextField { + TextFieldWithHeaderType { id: underloadPacketMagicHeaderTextField + Layout.fillWidth: true + Layout.topMargin: 16 + enabled: false headerText: "H3 - Underload packet magic header" textField.text: serverUnderloadPacketMagicHeader } - AwgTextField { + TextFieldWithHeaderType { id: transportPacketMagicHeaderTextField + Layout.fillWidth: true + Layout.topMargin: 16 + enabled: false headerText: "H4 - Transport packet magic header" diff --git a/client/ui/qml/Pages2/PageProtocolAwgSettings.qml b/client/ui/qml/Pages2/PageProtocolAwgSettings.qml index 699ae724..906e7ceb 100644 --- a/client/ui/qml/Pages2/PageProtocolAwgSettings.qml +++ b/client/ui/qml/Pages2/PageProtocolAwgSettings.qml @@ -138,136 +138,182 @@ PageType { checkEmptyText: true } - AwgTextField { + TextFieldWithHeaderType { id: junkPacketCountTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("Jc - Junk packet count") textField.text: serverJunkPacketCount + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { + if (textField.text === "") { + textField.text = "0" + } + if (textField.text !== serverJunkPacketCount) { serverJunkPacketCount = textField.text } } + + checkEmptyText: true } - AwgTextField { + TextFieldWithHeaderType { id: junkPacketMinSizeTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("Jmin - Junk packet minimum size") textField.text: serverJunkPacketMinSize + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { if (textField.text !== serverJunkPacketMinSize) { serverJunkPacketMinSize = textField.text } } + + checkEmptyText: true } - AwgTextField { + TextFieldWithHeaderType { id: junkPacketMaxSizeTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("Jmax - Junk packet maximum size") textField.text: serverJunkPacketMaxSize + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { if (textField.text !== serverJunkPacketMaxSize) { serverJunkPacketMaxSize = textField.text } } + + checkEmptyText: true } - AwgTextField { + TextFieldWithHeaderType { id: initPacketJunkSizeTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("S1 - Init packet junk size") textField.text: serverInitPacketJunkSize + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { if (textField.text !== serverInitPacketJunkSize) { serverInitPacketJunkSize = textField.text } } + + checkEmptyText: true + + onActiveFocusChanged: { + if(activeFocus) { + listview.positionViewAtEnd() + } + } } - AwgTextField { + TextFieldWithHeaderType { id: responsePacketJunkSizeTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("S2 - Response packet junk size") textField.text: serverResponsePacketJunkSize + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { if (textField.text !== serverResponsePacketJunkSize) { serverResponsePacketJunkSize = textField.text } } + + checkEmptyText: true + + onActiveFocusChanged: { + if(activeFocus) { + listview.positionViewAtEnd() + } + } } - // AwgTextField { - // id: cookieReplyPacketJunkSizeTextField - // headerText: qsTr("S3 - Cookie reply packet junk size") - // textField.text: serverCookieReplyPacketJunkSize - - // textField.onEditingFinished: { - // if (textField.text !== serverCookieReplyPacketJunkSize) { - // serverCookieReplyPacketJunkSize = textField.text - // } - // } - // } - - // AwgTextField { - // id: transportPacketJunkSizeTextField - // headerText: qsTr("S4 - Transport packet junk size") - // textField.text: serverTransportPacketJunkSize - - // textField.onEditingFinished: { - // if (textField.text !== serverTransportPacketJunkSize) { - // serverTransportPacketJunkSize = textField.text - // } - // } - // } - - AwgTextField { + TextFieldWithHeaderType { id: initPacketMagicHeaderTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("H1 - Init packet magic header") textField.text: serverInitPacketMagicHeader + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { if (textField.text !== serverInitPacketMagicHeader) { serverInitPacketMagicHeader = textField.text } } + + checkEmptyText: true } - AwgTextField { + TextFieldWithHeaderType { id: responsePacketMagicHeaderTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("H2 - Response packet magic header") textField.text: serverResponsePacketMagicHeader + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { if (textField.text !== serverResponsePacketMagicHeader) { serverResponsePacketMagicHeader = textField.text } } + + checkEmptyText: true } - AwgTextField { + TextFieldWithHeaderType { id: underloadPacketMagicHeaderTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("H3 - Underload packet magic header") textField.text: serverUnderloadPacketMagicHeader + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { if (textField.text !== serverUnderloadPacketMagicHeader) { serverUnderloadPacketMagicHeader = textField.text } } + + checkEmptyText: true } - AwgTextField { + TextFieldWithHeaderType { id: transportPacketMagicHeaderTextField + Layout.fillWidth: true + Layout.topMargin: 16 + headerText: qsTr("H4 - Transport packet magic header") textField.text: serverTransportPacketMagicHeader + textField.validator: IntValidator { bottom: 0 } textField.onEditingFinished: { if (textField.text !== serverTransportPacketMagicHeader) { serverTransportPacketMagicHeader = textField.text } } + + checkEmptyText: true } @@ -283,12 +329,19 @@ PageType { responsePacketMagicHeaderTextField.errorText === "" && initPacketMagicHeaderTextField.errorText === "" && responsePacketJunkSizeTextField.errorText === "" && - // cookieReplyHeaderJunkTextField.errorText === "" && - // transportHeaderJunkTextField.errorText === "" && initPacketJunkSizeTextField.errorText === "" && junkPacketMaxSizeTextField.errorText === "" && junkPacketMinSizeTextField.errorText === "" && junkPacketCountTextField.errorText === "" && + // specialJunk1TextField.errorText === "" && + // specialJunk2TextField.errorText === "" && + // specialJunk3TextField.errorText === "" && + // specialJunk4TextField.errorText === "" && + // specialJunk5TextField.errorText === "" && + // controlledJunk1TextField.errorText === "" && + // controlledJunk2TextField.errorText === "" && + // controlledJunk3TextField.errorText === "" && + // iTimeTextField.errorText === "" && portTextField.errorText === "" && vpnAddressSubnetTextField.errorText === "" @@ -317,13 +370,6 @@ PageType { PageController.showErrorMessage(qsTr("The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92)")) return } - // if (AwgConfigModel.isPacketSizeEqual(parseInt(initPacketJunkSizeTextField.textField.text), - // parseInt(responsePacketJunkSizeTextField.textField.text), - // parseInt(cookieReplyPacketJunkSizeTextField.textField.text), - // parseInt(transportPacketJunkSizeTextField.textField.text))) { - // PageController.showErrorMessage(qsTr("The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) + S3 + cookie reply size (64) + S4 + transport packet size (32)")) - // return - // } } var headerText = qsTr("Save settings?") diff --git a/client/ui/qml/Pages2/PageProtocolCloakSettings.qml b/client/ui/qml/Pages2/PageProtocolCloakSettings.qml index 8e5129b0..7a0fafbd 100644 --- a/client/ui/qml/Pages2/PageProtocolCloakSettings.qml +++ b/client/ui/qml/Pages2/PageProtocolCloakSettings.qml @@ -59,14 +59,11 @@ PageType { model: CloakConfigModel delegate: Item { - id: delegateItem - - property alias trafficFromField: trafficFromField - property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess() - implicitWidth: listview.width implicitHeight: col.implicitHeight + property alias trafficFromField: trafficFromField + ColumnLayout { id: col @@ -81,6 +78,7 @@ PageType { BaseHeaderType { Layout.fillWidth: true + headerText: qsTr("Cloak settings") } @@ -90,8 +88,6 @@ PageType { Layout.fillWidth: true Layout.topMargin: 32 - enabled: delegateItem.isEnabled - headerText: qsTr("Disguised as traffic from") textField.text: site @@ -108,8 +104,6 @@ PageType { } } } - - checkEmptyText: true } TextFieldWithHeaderType { @@ -118,8 +112,6 @@ PageType { Layout.fillWidth: true Layout.topMargin: 16 - enabled: delegateItem.isEnabled - headerText: qsTr("Port") textField.text: port textField.maximumLength: 5 @@ -130,8 +122,6 @@ PageType { port = textField.text } } - - checkEmptyText: true } DropDownType { @@ -139,8 +129,6 @@ PageType { Layout.fillWidth: true Layout.topMargin: 16 - enabled: delegateItem.isEnabled - descriptionText: qsTr("Cipher") headerText: qsTr("Cipher") @@ -178,46 +166,25 @@ PageType { } BasicButtonType { - id: saveButton + id: saveRestartButton Layout.fillWidth: true Layout.topMargin: 24 Layout.bottomMargin: 24 - enabled: trafficFromField.errorText === "" && - portTextField.errorText === "" - text: qsTr("Save") clickedFunc: function() { forceActiveFocus() - var headerText = qsTr("Save settings?") - 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() { - if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) { - PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection")) - return - } - - PageController.goToPage(PageEnum.PageSetupWizardInstalling) - InstallController.updateContainer(CloakConfigModel.getConfig()) + if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) { + PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection")) + return } - var noButtonFunction = function() { - if (!GC.isMobile()) { - saveButton.forceActiveFocus() - } - } - - showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) + PageController.goToPage(PageEnum.PageSetupWizardInstalling); + InstallController.updateContainer(CloakConfigModel.getConfig()) } - - Keys.onEnterPressed: saveButton.clicked() - Keys.onReturnPressed: saveButton.clicked() } } } diff --git a/client/ui/qml/Pages2/PageProtocolOpenVpnSettings.qml b/client/ui/qml/Pages2/PageProtocolOpenVpnSettings.qml index 62cbd1f6..2e00d54a 100644 --- a/client/ui/qml/Pages2/PageProtocolOpenVpnSettings.qml +++ b/client/ui/qml/Pages2/PageProtocolOpenVpnSettings.qml @@ -58,14 +58,11 @@ PageType { model: OpenVpnConfigModel delegate: Item { - id: delegateItem - - property alias vpnAddressSubnetTextField: vpnAddressSubnetTextField - property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess() - implicitWidth: listview.width implicitHeight: col.implicitHeight + property alias vpnAddressSubnetTextField: vpnAddressSubnetTextField + ColumnLayout { id: col @@ -80,6 +77,7 @@ PageType { BaseHeaderType { Layout.fillWidth: true + headerText: qsTr("OpenVPN settings") } @@ -89,8 +87,6 @@ PageType { Layout.fillWidth: true Layout.topMargin: 32 - enabled: delegateItem.isEnabled - headerText: qsTr("VPN address subnet") textField.text: subnetAddress @@ -101,8 +97,6 @@ PageType { subnetAddress = textField.text } } - - checkEmptyText: true } ParagraphTextType { @@ -140,7 +134,7 @@ PageType { Layout.topMargin: 40 parentFlickable: fl - enabled: delegateItem.isEnabled + enabled: isPortEditable headerText: qsTr("Port") textField.text: port @@ -152,8 +146,6 @@ PageType { port = textField.text } } - - checkEmptyText: true } SwitcherType { @@ -396,45 +388,26 @@ PageType { } BasicButtonType { - id: saveButton + id: saveRestartButton Layout.fillWidth: true Layout.topMargin: 24 Layout.bottomMargin: 24 - enabled: vpnAddressSubnetTextField.errorText === "" && - portTextField.errorText === "" - text: qsTr("Save") parentFlickable: fl - onClicked: function() { + clickedFunc: function() { forceActiveFocus() - var headerText = qsTr("Save settings?") - 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() { - if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) { - PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection")) - return - } - - PageController.goToPage(PageEnum.PageSetupWizardInstalling); - InstallController.updateContainer(OpenVpnConfigModel.getConfig()) + if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) { + PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection")) + return } - var noButtonFunction = function() { - if (!GC.isMobile()) { - saveButton.forceActiveFocus() - } - } - showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) + + PageController.goToPage(PageEnum.PageSetupWizardInstalling); + InstallController.updateContainer(OpenVpnConfigModel.getConfig()) } - - Keys.onEnterPressed: saveButton.clicked() - Keys.onReturnPressed: saveButton.clicked() } } } diff --git a/client/ui/qml/Pages2/PageProtocolShadowSocksSettings.qml b/client/ui/qml/Pages2/PageProtocolShadowSocksSettings.qml index 92df3ec7..63e60dcb 100644 --- a/client/ui/qml/Pages2/PageProtocolShadowSocksSettings.qml +++ b/client/ui/qml/Pages2/PageProtocolShadowSocksSettings.qml @@ -57,13 +57,15 @@ PageType { model: ShadowSocksConfigModel delegate: Item { - id: delegateItem - - property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess() - implicitWidth: listview.width implicitHeight: col.implicitHeight + property var focusItemId: portTextField.enabled ? + portTextField : + cipherDropDown.enabled ? + cipherDropDown : + saveRestartButton + ColumnLayout { id: col @@ -78,6 +80,7 @@ PageType { BaseHeaderType { Layout.fillWidth: true + headerText: qsTr("Shadowsocks settings") } @@ -87,7 +90,7 @@ PageType { Layout.fillWidth: true Layout.topMargin: 40 - enabled: delegateItem.isEnabled + enabled: isPortEditable headerText: qsTr("Port") textField.text: port @@ -99,8 +102,6 @@ PageType { port = textField.text } } - - checkEmptyText: true } DropDownType { @@ -108,7 +109,7 @@ PageType { Layout.fillWidth: true Layout.topMargin: 20 - enabled: delegateItem.isEnabled + enabled: isCipherEditable descriptionText: qsTr("Cipher") headerText: qsTr("Cipher") @@ -148,43 +149,27 @@ PageType { } BasicButtonType { - id: saveButton + id: saveRestartButton Layout.fillWidth: true Layout.topMargin: 24 Layout.bottomMargin: 24 - enabled: portTextField.errorText === "" + enabled: isPortEditable | isCipherEditable text: qsTr("Save") clickedFunc: function() { forceActiveFocus() - var headerText = qsTr("Save settings?") - 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() { - if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) { - PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection")) - return - } - - PageController.goToPage(PageEnum.PageSetupWizardInstalling); - InstallController.updateContainer(ShadowSocksConfigModel.getConfig()) + if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) { + PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection")) + return } - var noButtonFunction = function() { - if (!GC.isMobile()) { - saveButton.forceActiveFocus() - } - } - showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) + + PageController.goToPage(PageEnum.PageSetupWizardInstalling); + InstallController.updateContainer(ShadowSocksConfigModel.getConfig()) } - - Keys.onEnterPressed: saveButton.clicked() - Keys.onReturnPressed: saveButton.clicked() } } } diff --git a/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml b/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml index 21b35bc1..7b5180f3 100644 --- a/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml +++ b/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml @@ -152,7 +152,7 @@ PageType { } var noButtonFunction = function() { if (!GC.isMobile()) { - saveButton.forceActiveFocus() + saveRestartButton.forceActiveFocus() } } showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) diff --git a/client/ui/qml/Pages2/PageProtocolXraySettings.qml b/client/ui/qml/Pages2/PageProtocolXraySettings.qml index 0bcd14de..d22e31a2 100644 --- a/client/ui/qml/Pages2/PageProtocolXraySettings.qml +++ b/client/ui/qml/Pages2/PageProtocolXraySettings.qml @@ -58,10 +58,7 @@ PageType { model: XrayConfigModel delegate: Item { - id: delegateItem - property alias focusItemId: textFieldWithHeaderType.textField - property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess() implicitWidth: listview.width implicitHeight: col.implicitHeight @@ -88,8 +85,6 @@ PageType { Layout.fillWidth: true Layout.topMargin: 32 - enabled: delegateItem.isEnabled - headerText: qsTr("Disguised as traffic from") textField.text: site @@ -106,8 +101,6 @@ PageType { } } } - - checkEmptyText: true } TextFieldWithHeaderType { @@ -137,38 +130,23 @@ PageType { Layout.topMargin: 24 Layout.bottomMargin: 24 - enabled: portTextField.errorText === "" - text: qsTr("Save") - onClicked: function() { + onClicked: { forceActiveFocus() - var headerText = qsTr("Save settings?") - 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() { - if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) { - PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection")) - return - } - - PageController.goToPage(PageEnum.PageSetupWizardInstalling); - InstallController.updateContainer(XrayConfigModel.getConfig()) - //focusItem.forceActiveFocus() + if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) { + PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection")) + return } - var noButtonFunction = function() { - if (!GC.isMobile()) { - saveButton.forceActiveFocus() - } - } - showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) + + PageController.goToPage(PageEnum.PageSetupWizardInstalling); + InstallController.updateContainer(XrayConfigModel.getConfig()) + focusItem.forceActiveFocus() } - Keys.onEnterPressed: saveButton.clicked() - Keys.onReturnPressed: saveButton.clicked() + Keys.onEnterPressed: basicButton.clicked() + Keys.onReturnPressed: basicButton.clicked() } } } diff --git a/client/ui/qml/Pages2/PageSettingsApiServerInfo.qml b/client/ui/qml/Pages2/PageSettingsApiServerInfo.qml index 75832fa6..93118755 100644 --- a/client/ui/qml/Pages2/PageSettingsApiServerInfo.qml +++ b/client/ui/qml/Pages2/PageSettingsApiServerInfo.qml @@ -158,32 +158,6 @@ PageType { readonly property bool isVisibleForAmneziaFree: ApiAccountInfoModel.data("isComponentVisible") - SwitcherType { - id: switcher - - readonly property bool isVlessProtocol: ApiConfigsController.isVlessProtocol() - - Layout.fillWidth: true - Layout.topMargin: 24 - Layout.rightMargin: 16 - Layout.leftMargin: 16 - - visible: ApiAccountInfoModel.data("isProtocolSelectionSupported") - - text: qsTr("Use VLESS protocol") - checked: switcher.isVlessProtocol - onToggled: function() { - if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) { - PageController.showNotificationMessage(qsTr("Cannot change protocol during active connection")) - } else { - PageController.showBusyIndicator(true) - ApiConfigsController.setCurrentProtocol(switcher.isVlessProtocol ? "awg" : "vless") - ApiConfigsController.updateServiceFromGateway(ServersModel.processedIndex, "", "", true) - PageController.showBusyIndicator(false) - } - } - } - WarningType { id: warning diff --git a/client/ui/qml/Pages2/PageSettingsKillSwitch.qml b/client/ui/qml/Pages2/PageSettingsKillSwitch.qml index d6d73b20..1ffcc8cf 100644 --- a/client/ui/qml/Pages2/PageSettingsKillSwitch.qml +++ b/client/ui/qml/Pages2/PageSettingsKillSwitch.qml @@ -82,8 +82,7 @@ PageType { Layout.rightMargin: 16 visible: false - enabled: false - // enabled: SettingsController.isKillSwitchEnabled && !ConnectionController.isConnected + enabled: false //SettingsController.isKillSwitchEnabled && !ConnectionController.isConnected checked: SettingsController.strictKillSwitchEnabled text: qsTr("Strict KillSwitch") diff --git a/client/ui/qml/Pages2/PageSettingsServerData.qml b/client/ui/qml/Pages2/PageSettingsServerData.qml index 82552958..995ca74b 100644 --- a/client/ui/qml/Pages2/PageSettingsServerData.qml +++ b/client/ui/qml/Pages2/PageSettingsServerData.qml @@ -260,7 +260,7 @@ PageType { LabelWithButtonType { id: labelWithButton6 - visible: ServersModel.getProcessedServerData("isServerFromTelegramApi") && ServersModel.processedServerIsPremium + visible: ServersModel.getProcessedServerData("isServerFromTelegramApi") Layout.fillWidth: true text: qsTr("Switch to the new Amnezia Premium subscription") @@ -273,7 +273,7 @@ PageType { } DividerType { - visible: ServersModel.getProcessedServerData("isServerFromTelegramApi") && ServersModel.processedServerIsPremium + visible: ServersModel.getProcessedServerData("isServerFromTelegramApi") } } } diff --git a/client/ui/qml/Pages2/PageShare.qml b/client/ui/qml/Pages2/PageShare.qml index 0f0976bc..48f74acf 100644 --- a/client/ui/qml/Pages2/PageShare.qml +++ b/client/ui/qml/Pages2/PageShare.qml @@ -429,11 +429,6 @@ PageType { fillConnectionTypeModel() - if (exportTypeSelector.currentIndex >= root.connectionTypesModel.length) { - exportTypeSelector.currentIndex = 0 - exportTypeSelector.text = root.connectionTypesModel[0].name - } - if (accessTypeSelector.currentIndex === 1) { PageController.showBusyIndicator(true) ExportController.updateClientManagementModel(ContainersModel.getProcessedContainerIndex(), diff --git a/deploy/DeveloperIDG2CA.cer b/deploy/DeveloperIDG2CA.cer deleted file mode 100644 index 8cbcf6f4..00000000 Binary files a/deploy/DeveloperIDG2CA.cer and /dev/null differ diff --git a/deploy/build_macos.sh b/deploy/build_macos.sh old mode 100644 new mode 100755 index 03f286fc..5f6e9786 --- a/deploy/build_macos.sh +++ b/deploy/build_macos.sh @@ -1,15 +1,4 @@ #!/bin/bash -# ----------------------------------------------------------------------------- -# Usage: -# Export the required signing credentials before running this script, e.g.: -# export MAC_APP_CERT_PW='pw-for-DeveloperID-Application' -# export MAC_INSTALL_CERT_PW='pw-for-DeveloperID-Installer' -# export MAC_SIGNER_ID='Developer ID Application: Some Company Name (XXXXXXXXXX)' -# export MAC_INSTALLER_SIGNER_ID='Developer ID Installer: Some Company Name (XXXXXXXXXX)' -# export APPLE_DEV_EMAIL='your@email.com' -# export APPLE_DEV_PASSWORD='' -# bash deploy/build_macos.sh [-n] -# ----------------------------------------------------------------------------- echo "Build script started ..." set -o errexit -o nounset @@ -25,10 +14,10 @@ done PROJECT_DIR=$(pwd) DEPLOY_DIR=$PROJECT_DIR/deploy -mkdir -p "$DEPLOY_DIR/build" -BUILD_DIR="$DEPLOY_DIR/build" +mkdir -p $DEPLOY_DIR/build +BUILD_DIR=$DEPLOY_DIR/build -echo "Project dir: ${PROJECT_DIR}" +echo "Project dir: ${PROJECT_DIR}" echo "Build dir: ${BUILD_DIR}" APP_NAME=AmneziaVPN @@ -39,45 +28,39 @@ PLIST_NAME=$APP_NAME.plist OUT_APP_DIR=$BUILD_DIR/client BUNDLE_DIR=$OUT_APP_DIR/$APP_FILENAME -# Prebuilt deployment assets are available via the symlink under deploy/data PREBUILT_DEPLOY_DATA_DIR=$PROJECT_DIR/deploy/data/deploy-prebuilt/macos DEPLOY_DATA_DIR=$PROJECT_DIR/deploy/data/macos +INSTALLER_DATA_DIR=$BUILD_DIR/installer/packages/$APP_DOMAIN/data +INSTALLER_BUNDLE_DIR=$BUILD_DIR/installer/$APP_FILENAME +DMG_FILENAME=$PROJECT_DIR/${APP_NAME}.dmg # Search Qt if [ -z "${QT_VERSION+x}" ]; then -QT_VERSION=6.8.3; +QT_VERSION=6.4.3; +QIF_VERSION=4.6 QT_BIN_DIR=$HOME/Qt/$QT_VERSION/macos/bin +QIF_BIN_DIR=$QT_BIN_DIR/../../../Tools/QtInstallerFramework/$QIF_VERSION/bin fi echo "Using Qt in $QT_BIN_DIR" +echo "Using QIF in $QIF_BIN_DIR" # Checking env -"$QT_BIN_DIR/qt-cmake" --version +$QT_BIN_DIR/qt-cmake --version cmake --version clang -v # Build App echo "Building App..." -cd "$BUILD_DIR" +cd $BUILD_DIR -"$QT_BIN_DIR/qt-cmake" -S "$PROJECT_DIR" -B "$BUILD_DIR" +$QT_BIN_DIR/qt-cmake -S $PROJECT_DIR -B $BUILD_DIR cmake --build . --config release --target all # Build and run tests here -# Create a temporary keychain and import certificates -KEYCHAIN_PATH="$PROJECT_DIR/mac_sign.keychain" -trap 'echo "Cleaning up mac_sign.keychain..."; security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true; rm -f "$KEYCHAIN_PATH" 2>/dev/null || true' EXIT -KEYCHAIN=$(security default-keychain -d user | tr -d '"[:space:]"') -security list-keychains -d user -s "$KEYCHAIN_PATH" "$KEYCHAIN" "$(security list-keychains -d user | tr '\n' ' ')" -security create-keychain -p "" "$KEYCHAIN_PATH" -security import "$DEPLOY_DIR/DeveloperIdApplicationCertificate.p12" -k "$KEYCHAIN_PATH" -P "$MAC_APP_CERT_PW" -T /usr/bin/codesign -security import "$DEPLOY_DIR/DeveloperIdInstallerCertificate.p12" -k "$KEYCHAIN_PATH" -P "$MAC_INSTALL_CERT_PW" -T /usr/bin/codesign -security import "$DEPLOY_DIR/DeveloperIDG2CA.cer" -k "$KEYCHAIN_PATH" -T /usr/bin/codesign -security list-keychains -d user -s "$KEYCHAIN_PATH" - echo "____________________________________" echo "............Deploy.................." echo "____________________________________" @@ -86,159 +69,102 @@ echo "____________________________________" echo "Packaging ..." -cp -Rv "$PREBUILT_DEPLOY_DATA_DIR"/* "$BUNDLE_DIR/Contents/macOS" -"$QT_BIN_DIR/macdeployqt" "$OUT_APP_DIR/$APP_FILENAME" -always-overwrite -qmldir="$PROJECT_DIR" -cp -av "$BUILD_DIR/service/server/$APP_NAME-service" "$BUNDLE_DIR/Contents/macOS" -rsync -av --exclude="$PLIST_NAME" --exclude=post_install.sh --exclude=post_uninstall.sh "$DEPLOY_DATA_DIR/" "$BUNDLE_DIR/Contents/macOS/" +cp -Rv $PREBUILT_DEPLOY_DATA_DIR/* $BUNDLE_DIR/Contents/macOS +$QT_BIN_DIR/macdeployqt $OUT_APP_DIR/$APP_FILENAME -always-overwrite -qmldir=$PROJECT_DIR +cp -av $BUILD_DIR/service/server/$APP_NAME-service $BUNDLE_DIR/Contents/macOS +cp -Rv $PROJECT_DIR/deploy/data/macos/* $BUNDLE_DIR/Contents/macOS +rm -f $BUNDLE_DIR/Contents/macOS/post_install.sh $BUNDLE_DIR/Contents/macOS/post_uninstall.sh -if [ "${MAC_APP_CERT_PW+x}" ]; then +if [ "${MAC_CERT_PW+x}" ]; then - # Path to the p12 that contains the Developer ID *Application* certificate - CERTIFICATE_P12=$DEPLOY_DIR/DeveloperIdApplicationCertificate.p12 + CERTIFICATE_P12=$DEPLOY_DIR/PrivacyTechAppleCertDeveloperId.p12 + WWDRCA=$DEPLOY_DIR/WWDRCA.cer + KEYCHAIN=amnezia.build.macos.keychain + TEMP_PASS=tmp_pass - # Ensure launchd plist is bundled, but place it inside Resources so that - # the bundle keeps a valid structure (nothing but `Contents` at the root). - mkdir -p "$BUNDLE_DIR/Contents/Resources" - cp "$DEPLOY_DATA_DIR/$PLIST_NAME" "$BUNDLE_DIR/Contents/Resources/$PLIST_NAME" + security create-keychain -p $TEMP_PASS $KEYCHAIN || true + security default-keychain -s $KEYCHAIN + security unlock-keychain -p $TEMP_PASS $KEYCHAIN - # Show available signing identities (useful for debugging) - security find-identity -p codesigning || true + security default-keychain + security list-keychains + + security import $WWDRCA -k $KEYCHAIN -T /usr/bin/codesign || true + security import $CERTIFICATE_P12 -k $KEYCHAIN -P $MAC_CERT_PW -T /usr/bin/codesign || true + + security set-key-partition-list -S apple-tool:,apple: -k $TEMP_PASS $KEYCHAIN + security find-identity -p codesigning echo "Signing App bundle..." - /usr/bin/codesign --deep --force --verbose --timestamp -o runtime --keychain "$KEYCHAIN_PATH" --sign "$MAC_SIGNER_ID" "$BUNDLE_DIR" - /usr/bin/codesign --verify -vvvv "$BUNDLE_DIR" || true - spctl -a -vvvv "$BUNDLE_DIR" || true + /usr/bin/codesign --deep --force --verbose --timestamp -o runtime --sign "$MAC_SIGNER_ID" $BUNDLE_DIR + /usr/bin/codesign --verify -vvvv $BUNDLE_DIR || true + spctl -a -vvvv $BUNDLE_DIR || true + if [ "${NOTARIZE_APP+x}" ]; then + echo "Notarizing App bundle..." + /usr/bin/ditto -c -k --keepParent $BUNDLE_DIR $PROJECT_DIR/Bundle_to_notarize.zip + xcrun notarytool submit $PROJECT_DIR/Bundle_to_notarize.zip --apple-id $APPLE_DEV_EMAIL --team-id $MAC_TEAM_ID --password $APPLE_DEV_PASSWORD + rm $PROJECT_DIR/Bundle_to_notarize.zip + sleep 300 + xcrun stapler staple $BUNDLE_DIR + xcrun stapler validate $BUNDLE_DIR + spctl -a -vvvv $BUNDLE_DIR || true + fi fi echo "Packaging installer..." -PKG_DIR=$BUILD_DIR/pkg -# Remove any stale packaging data from previous runs -rm -rf "$PKG_DIR" -PKG_ROOT=$PKG_DIR/root -SCRIPTS_DIR=$PKG_DIR/scripts -RESOURCES_DIR=$PKG_DIR/resources -INSTALL_PKG=$PKG_DIR/${APP_NAME}_install.pkg -UNINSTALL_PKG=$PKG_DIR/${APP_NAME}_uninstall.pkg -FINAL_PKG=$PKG_DIR/${APP_NAME}.pkg -UNINSTALL_SCRIPTS_DIR=$PKG_DIR/uninstall_scripts +mkdir -p $INSTALLER_DATA_DIR +cp -av $PROJECT_DIR/deploy/installer $BUILD_DIR +cp -av $DEPLOY_DATA_DIR/post_install.sh $INSTALLER_DATA_DIR/post_install.sh +cp -av $DEPLOY_DATA_DIR/post_uninstall.sh $INSTALLER_DATA_DIR/post_uninstall.sh +cp -av $DEPLOY_DATA_DIR/$PLIST_NAME $INSTALLER_DATA_DIR/$PLIST_NAME -mkdir -p "$PKG_ROOT/Applications" "$SCRIPTS_DIR" "$RESOURCES_DIR" "$UNINSTALL_SCRIPTS_DIR" +chmod a+x $INSTALLER_DATA_DIR/post_install.sh $INSTALLER_DATA_DIR/post_uninstall.sh -cp -R "$BUNDLE_DIR" "$PKG_ROOT/Applications" -# launchd plist is already inside the bundle; no need to add it again after signing -/usr/bin/codesign --deep --force --verbose --timestamp -o runtime --keychain "$KEYCHAIN_PATH" --sign "$MAC_SIGNER_ID" "$PKG_ROOT/Applications/$APP_FILENAME" -/usr/bin/codesign --verify --deep --strict --verbose=4 "$PKG_ROOT/Applications/$APP_FILENAME" || true -cp "$DEPLOY_DATA_DIR/post_install.sh" "$SCRIPTS_DIR/post_install.sh" -cp "$DEPLOY_DATA_DIR/post_uninstall.sh" "$UNINSTALL_SCRIPTS_DIR/postinstall" -mkdir -p "$RESOURCES_DIR/scripts" -cp "$DEPLOY_DATA_DIR/check_install.sh" "$RESOURCES_DIR/scripts/check_install.sh" -cp "$DEPLOY_DATA_DIR/check_uninstall.sh" "$RESOURCES_DIR/scripts/check_uninstall.sh" +cd $BUNDLE_DIR +tar czf $INSTALLER_DATA_DIR/$APP_NAME.tar.gz ./ -cat > "$SCRIPTS_DIR/postinstall" <<'EOS' -#!/bin/bash -SCRIPT_DIR="$(dirname "$0")" -bash "$SCRIPT_DIR/post_install.sh" -exit 0 -EOS +echo "Building installer..." +$QIF_BIN_DIR/binarycreator --offline-only -v -c $BUILD_DIR/installer/config/macos.xml -p $BUILD_DIR/installer/packages -f $INSTALLER_BUNDLE_DIR -chmod +x "$SCRIPTS_DIR"/* -chmod +x "$UNINSTALL_SCRIPTS_DIR"/* -chmod +x "$RESOURCES_DIR/scripts"/* -cp "$PROJECT_DIR/LICENSE" "$RESOURCES_DIR/LICENSE" +if [ "${MAC_CERT_PW+x}" ]; then + echo "Signing installer bundle..." + security unlock-keychain -p $TEMP_PASS $KEYCHAIN + /usr/bin/codesign --deep --force --verbose --timestamp -o runtime --sign "$MAC_SIGNER_ID" $INSTALLER_BUNDLE_DIR + /usr/bin/codesign --verify -vvvv $INSTALLER_BUNDLE_DIR || true -APP_VERSION=$(grep -m1 -E 'project\(' "$PROJECT_DIR/CMakeLists.txt" | sed -E 's/.*VERSION ([0-9.]+).*/\1/') -echo "Building component package $INSTALL_PKG ..." - -# Disable bundle relocation so the app always ends up in /Applications even if -# another copy is lying around somewhere. We do this by letting pkgbuild -# analyse the contents, flipping the BundleIsRelocatable flag to false for every -# bundle it discovers and then feeding that plist back to pkgbuild. - -COMPONENT_PLIST="$PKG_DIR/component.plist" -# Create the component description plist first -pkgbuild --analyze --root "$PKG_ROOT" "$COMPONENT_PLIST" - -# Turn all `BundleIsRelocatable` keys to false (PlistBuddy is available on all -# macOS systems). We first convert to xml1 to ensure predictable formatting. - -# Turn relocation off for every bundle entry in the plist. PlistBuddy cannot -# address keys that contain slashes without quoting, so we iterate through the -# top-level keys it prints. -plutil -convert xml1 "$COMPONENT_PLIST" -for bundle_key in $(/usr/libexec/PlistBuddy -c "Print" "$COMPONENT_PLIST" | awk '/^[ \t]*[A-Za-z0-9].*\.app/ {print $1}'); do - /usr/libexec/PlistBuddy -c "Set :'${bundle_key}':BundleIsRelocatable false" "$COMPONENT_PLIST" || true -done - -# Now build the real payload package with the edited plist so that the final -# PackageInfo contains relocatable="false". -pkgbuild --root "$PKG_ROOT" \ - --identifier "$APP_DOMAIN" \ - --version "$APP_VERSION" \ - --install-location "/" \ - --scripts "$SCRIPTS_DIR" \ - --component-plist "$COMPONENT_PLIST" \ - --sign "$MAC_INSTALLER_SIGNER_ID" \ - "$INSTALL_PKG" - -# Build uninstaller component package -UNINSTALL_COMPONENT_PKG=$PKG_DIR/${APP_NAME}_uninstall_component.pkg -echo "Building uninstaller component package $UNINSTALL_COMPONENT_PKG ..." -pkgbuild --nopayload \ - --identifier "$APP_DOMAIN.uninstall" \ - --version "$APP_VERSION" \ - --scripts "$UNINSTALL_SCRIPTS_DIR" \ - --sign "$MAC_INSTALLER_SIGNER_ID" \ - "$UNINSTALL_COMPONENT_PKG" - -# Wrap uninstaller component in a distribution package for clearer UI -echo "Building uninstaller distribution package $UNINSTALL_PKG ..." -UNINSTALL_RESOURCES=$PKG_DIR/uninstall_resources -rm -rf "$UNINSTALL_RESOURCES" -mkdir -p "$UNINSTALL_RESOURCES" -cp "$DEPLOY_DATA_DIR/uninstall_welcome.html" "$UNINSTALL_RESOURCES" -cp "$DEPLOY_DATA_DIR/uninstall_conclusion.html" "$UNINSTALL_RESOURCES" -productbuild \ - --distribution "$DEPLOY_DATA_DIR/distribution_uninstall.xml" \ - --package-path "$PKG_DIR" \ - --resources "$UNINSTALL_RESOURCES" \ - --sign "$MAC_INSTALLER_SIGNER_ID" \ - "$UNINSTALL_PKG" - -cp "$PROJECT_DIR/deploy/data/macos/distribution.xml" "$PKG_DIR/distribution.xml" - -echo "Creating final installer $FINAL_PKG ..." -productbuild --distribution "$PKG_DIR/distribution.xml" \ - --package-path "$PKG_DIR" \ - --resources "$RESOURCES_DIR" \ - --sign "$MAC_INSTALLER_SIGNER_ID" \ - "$FINAL_PKG" - -if [ "${MAC_INSTALL_CERT_PW+x}" ] && [ "${NOTARIZE_APP+x}" ]; then - echo "Notarizing installer package..." - xcrun notarytool submit "$FINAL_PKG" \ - --apple-id "$APPLE_DEV_EMAIL" \ - --team-id "$MAC_TEAM_ID" \ - --password "$APPLE_DEV_PASSWORD" \ - --wait - - echo "Stapling ticket..." - xcrun stapler staple "$FINAL_PKG" - xcrun stapler validate "$FINAL_PKG" + if [ "${NOTARIZE_APP+x}" ]; then + echo "Notarizing installer bundle..." + /usr/bin/ditto -c -k --keepParent $INSTALLER_BUNDLE_DIR $PROJECT_DIR/Installer_bundle_to_notarize.zip + xcrun notarytool submit $PROJECT_DIR/Installer_bundle_to_notarize.zip --apple-id $APPLE_DEV_EMAIL --team-id $MAC_TEAM_ID --password $APPLE_DEV_PASSWORD + rm $PROJECT_DIR/Installer_bundle_to_notarize.zip + sleep 300 + xcrun stapler staple $INSTALLER_BUNDLE_DIR + xcrun stapler validate $INSTALLER_BUNDLE_DIR + spctl -a -vvvv $INSTALLER_BUNDLE_DIR || true + fi fi -if [ "${MAC_INSTALL_CERT_PW+x}" ]; then - /usr/bin/codesign --verify -vvvv "$FINAL_PKG" || true - spctl -a -vvvv "$FINAL_PKG" || true +echo "Building DMG installer..." +# Allow Terminal to make changes in Privacy & Security > App Management +hdiutil create -size 256mb -volname AmneziaVPN -srcfolder $BUILD_DIR/installer/$APP_NAME.app -ov -format UDZO $DMG_FILENAME + +if [ "${MAC_CERT_PW+x}" ]; then + echo "Signing DMG installer..." + security unlock-keychain -p $TEMP_PASS $KEYCHAIN + /usr/bin/codesign --deep --force --verbose --timestamp -o runtime --sign "$MAC_SIGNER_ID" $DMG_FILENAME + /usr/bin/codesign --verify -vvvv $DMG_FILENAME || true + + if [ "${NOTARIZE_APP+x}" ]; then + echo "Notarizing DMG installer..." + xcrun notarytool submit $DMG_FILENAME --apple-id $APPLE_DEV_EMAIL --team-id $MAC_TEAM_ID --password $APPLE_DEV_PASSWORD + sleep 300 + xcrun stapler staple $DMG_FILENAME + xcrun stapler validate $DMG_FILENAME + fi fi -# Sign app bundle -/usr/bin/codesign --deep --force --verbose --timestamp -o runtime --keychain "$KEYCHAIN_PATH" --sign "$MAC_SIGNER_ID" "$BUNDLE_DIR" -spctl -a -vvvv "$BUNDLE_DIR" || true +echo "Finished, artifact is $DMG_FILENAME" -# Restore login keychain as the only user keychain and delete the temporary keychain -KEYCHAIN="$HOME/Library/Keychains/login.keychain-db" -security list-keychains -d user -s "$KEYCHAIN" -security delete-keychain "$KEYCHAIN_PATH" - -echo "Finished, artifact is $FINAL_PKG" +# restore keychain +security default-keychain -s login.keychain diff --git a/deploy/data/macos/check_install.sh b/deploy/data/macos/check_install.sh deleted file mode 100755 index adf63550..00000000 --- a/deploy/data/macos/check_install.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -if [ -d "/Applications/AmneziaVPN.app" ] || pgrep -x "AmneziaVPN-service" >/dev/null; then - exit 1 -fi -exit 0 diff --git a/deploy/data/macos/check_uninstall.sh b/deploy/data/macos/check_uninstall.sh deleted file mode 100755 index e7a6f7e0..00000000 --- a/deploy/data/macos/check_uninstall.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -if [ -d "/Applications/AmneziaVPN.app" ] || pgrep -x "AmneziaVPN-service" >/dev/null; then - exit 0 -fi -exit 1 diff --git a/deploy/data/macos/distribution.xml b/deploy/data/macos/distribution.xml deleted file mode 100644 index c0a1dc68..00000000 --- a/deploy/data/macos/distribution.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - AmneziaVPN Installer - - - - - - - - - - - - AmneziaVPN_install.pkg - AmneziaVPN_uninstall_component.pkg - diff --git a/deploy/data/macos/distribution_uninstall.xml b/deploy/data/macos/distribution_uninstall.xml deleted file mode 100644 index cf8932b9..00000000 --- a/deploy/data/macos/distribution_uninstall.xml +++ /dev/null @@ -1,13 +0,0 @@ - - Uninstall AmneziaVPN - - - - - - - - - - AmneziaVPN_uninstall_component.pkg - diff --git a/deploy/data/macos/post_install.sh b/deploy/data/macos/post_install.sh index 053c8e13..acd3f93f 100755 --- a/deploy/data/macos/post_install.sh +++ b/deploy/data/macos/post_install.sh @@ -7,42 +7,29 @@ LOG_FOLDER=/var/log/$APP_NAME LOG_FILE="$LOG_FOLDER/post-install.log" APP_PATH=/Applications/$APP_NAME.app -# Handle new installations unpacked into localized folder -if [ -d "/Applications/${APP_NAME}.localized" ]; then - echo "`date` Detected ${APP_NAME}.localized, migrating to standard path" >> $LOG_FILE - sudo rm -rf "$APP_PATH" - sudo mv "/Applications/${APP_NAME}.localized/${APP_NAME}.app" "$APP_PATH" - sudo rm -rf "/Applications/${APP_NAME}.localized" -fi - if launchctl list "$APP_NAME-service" &> /dev/null; then - launchctl unload "$LAUNCH_DAEMONS_PLIST_NAME" - rm -f "$LAUNCH_DAEMONS_PLIST_NAME" + launchctl unload $LAUNCH_DAEMONS_PLIST_NAME + rm -f $LAUNCH_DAEMONS_PLIST_NAME fi -sudo chmod -R a-w "$APP_PATH/" -sudo chown -R root "$APP_PATH/" -sudo chgrp -R wheel "$APP_PATH/" +tar xzf $APP_PATH/$APP_NAME.tar.gz -C $APP_PATH +rm -f $APP_PATH/$APP_NAME.tar.gz +sudo chmod -R a-w $APP_PATH/ +sudo chown -R root $APP_PATH/ +sudo chgrp -R wheel $APP_PATH/ rm -rf $LOG_FOLDER mkdir -p $LOG_FOLDER echo "`date` Script started" > $LOG_FILE -echo "Requesting ${APP_NAME} to quit gracefully" >> "$LOG_FILE" -osascript -e 'tell application "AmneziaVPN" to quit' +killall -9 $APP_NAME-service 2>> $LOG_FILE -PLIST_SOURCE="$APP_PATH/Contents/Resources/$PLIST_NAME" -if [ -f "$PLIST_SOURCE" ]; then - mv -f "$PLIST_SOURCE" "$LAUNCH_DAEMONS_PLIST_NAME" 2>> $LOG_FILE -else - echo "`date` ERROR: service plist not found at $PLIST_SOURCE" >> $LOG_FILE -fi - -chown root:wheel "$LAUNCH_DAEMONS_PLIST_NAME" -launchctl load "$LAUNCH_DAEMONS_PLIST_NAME" -echo "`date` Launching ${APP_NAME} application" >> $LOG_FILE -open -a "$APP_PATH" 2>> $LOG_FILE || true +mv -f $APP_PATH/$PLIST_NAME $LAUNCH_DAEMONS_PLIST_NAME 2>> $LOG_FILE +chown root:wheel $LAUNCH_DAEMONS_PLIST_NAME +launchctl load $LAUNCH_DAEMONS_PLIST_NAME echo "`date` Service status: $?" >> $LOG_FILE echo "`date` Script finished" >> $LOG_FILE + +#rm -- "$0" diff --git a/deploy/data/macos/post_uninstall.sh b/deploy/data/macos/post_uninstall.sh index d6c5cdbd..de7846db 100755 --- a/deploy/data/macos/post_uninstall.sh +++ b/deploy/data/macos/post_uninstall.sh @@ -9,19 +9,6 @@ SYSTEM_APP_SUPPORT="/Library/Application Support/$APP_NAME" LOG_FOLDER="/var/log/$APP_NAME" CACHES_FOLDER="$HOME/Library/Caches/$APP_NAME" -# Attempt to quit the GUI application if it's currently running -if pgrep -x "$APP_NAME" > /dev/null; then - echo "Quitting $APP_NAME..." - osascript -e 'tell application "'"$APP_NAME"'" to quit' || true - # Wait up to 10 seconds for the app to terminate gracefully - for i in {1..10}; do - if ! pgrep -x "$APP_NAME" > /dev/null; then - break - fi - sleep 1 - done -fi - # Stop the running service if it exists if pgrep -x "${APP_NAME}-service" > /dev/null; then sudo killall -9 "${APP_NAME}-service" @@ -45,40 +32,3 @@ sudo rm -rf "$LOG_FOLDER" # Remove any caches left behind rm -rf "$CACHES_FOLDER" - -# Remove PF data directory created by firewall helper, if present -sudo rm -rf "/Library/Application Support/${APP_NAME}/pf" - -# ---------------- PF firewall cleanup ---------------------- -# Rules are loaded under the anchor "amn" (see macosfirewall.cpp) -# Flush only that anchor to avoid destroying user/system rules. - -PF_ANCHOR="amn" - -### Flush all PF rules, NATs, and tables under our anchor and sub-anchors ### -anchors=$(sudo pfctl -s Anchors 2>/dev/null | awk '/^'"${PF_ANCHOR}"'/ {sub(/\*$/, "", $1); print $1}') -for anc in $anchors; do - echo "Flushing PF anchor $anc" - sudo pfctl -a "$anc" -F all 2>/dev/null || true - # flush tables under this anchor - tables=$(sudo pfctl -s Tables 2>/dev/null | awk '/^'"$anc"'/ {print}') - for tbl in $tables; do - echo "Killing PF table $tbl" - sudo pfctl -t "$tbl" -T kill 2>/dev/null || true - done -done - -### Reload default PF config to restore system rules ### -if [ -f /etc/pf.conf ]; then - echo "Restoring system PF config" - sudo pfctl -f /etc/pf.conf 2>/dev/null || true -fi - -### Disable PF if no rules remain ### -if sudo pfctl -s info 2>/dev/null | grep -q '^Status: Enabled' && \ - ! sudo pfctl -sr 2>/dev/null | grep -q .; then - echo "Disabling PF" - sudo pfctl -d 2>/dev/null || true -fi - -# ----------------------------------------------------------- diff --git a/deploy/data/macos/uninstall_conclusion.html b/deploy/data/macos/uninstall_conclusion.html deleted file mode 100644 index f5b8bb63..00000000 --- a/deploy/data/macos/uninstall_conclusion.html +++ /dev/null @@ -1,7 +0,0 @@ - -Uninstall Complete - -

AmneziaVPN has been uninstalled

-

Thank you for using AmneziaVPN. The application and its components have been removed.

- - \ No newline at end of file diff --git a/deploy/data/macos/uninstall_welcome.html b/deploy/data/macos/uninstall_welcome.html deleted file mode 100644 index 9f3d97cb..00000000 --- a/deploy/data/macos/uninstall_welcome.html +++ /dev/null @@ -1,7 +0,0 @@ - -Uninstall AmneziaVPN - -

Uninstall AmneziaVPN

-

This process will remove AmneziaVPN from your system. Click Continue to proceed.

- - \ No newline at end of file diff --git a/deploy/installer/config.cmake b/deploy/installer/config.cmake index 3c33a33c..13f09986 100644 --- a/deploy/installer/config.cmake +++ b/deploy/installer/config.cmake @@ -4,6 +4,11 @@ if(WIN32) ${CMAKE_CURRENT_LIST_DIR}/config/windows.xml.in ${CMAKE_BINARY_DIR}/installer/config/windows.xml ) +elseif(APPLE AND NOT IOS) + configure_file( + ${CMAKE_CURRENT_LIST_DIR}/config/macos.xml.in + ${CMAKE_BINARY_DIR}/installer/config/macos.xml + ) elseif(LINUX) set(ApplicationsDir "@ApplicationsDir@") configure_file( diff --git a/deploy/installer/config/AmneziaVPN.desktop.in b/deploy/installer/config/AmneziaVPN.desktop.in index 03ab570c..2a53074e 100755 --- a/deploy/installer/config/AmneziaVPN.desktop.in +++ b/deploy/installer/config/AmneziaVPN.desktop.in @@ -2,7 +2,7 @@ [Desktop Entry] Type=Application Name=AmneziaVPN -Version=1.0 +Version=@CMAKE_PROJECT_VERSION@ Comment=Client of your self-hosted VPN Exec=AmneziaVPN Icon=/usr/share/pixmaps/AmneziaVPN.png diff --git a/deploy/installer/config/macos.xml.in b/deploy/installer/config/macos.xml.in new file mode 100644 index 00000000..3888d08d --- /dev/null +++ b/deploy/installer/config/macos.xml.in @@ -0,0 +1,27 @@ + + + AmneziaVPN + @CMAKE_PROJECT_VERSION@ + AmneziaVPN + AmneziaVPN + AmneziaVPN + /Applications/AmneziaVPN.app + 600 + 380 + Mac + true + true + false + controlscript.js + false + true + false + true + + + https://amneziavpn.org/updates/macos + true + AmneziaVPN - repository for macOS + + + diff --git a/service/server/killswitch.cpp b/service/server/killswitch.cpp index d0cba03a..c44bd6a2 100644 --- a/service/server/killswitch.cpp +++ b/service/server/killswitch.cpp @@ -192,14 +192,7 @@ bool KillSwitch::addAllowedRange(const QStringList &ranges) { bool KillSwitch::enablePeerTraffic(const QJsonObject &configStr) { #ifdef Q_OS_WIN InterfaceConfig config; - - config.m_primaryDnsServer = configStr.value(amnezia::config_key::dns1).toString(); - - // We don't use secondary DNS if primary DNS is AmneziaDNS - if (!config.m_primaryDnsServer.contains(amnezia::protocols::dns::amneziaDnsIp)) { - config.m_secondaryDnsServer = configStr.value(amnezia::config_key::dns2).toString(); - } - + config.m_dnsServer = configStr.value(amnezia::config_key::dns1).toString(); config.m_serverPublicKey = "openvpn"; config.m_serverIpv4Gateway = configStr.value("vpnGateway").toString(); config.m_serverIpv4AddrIn = configStr.value("vpnServer").toString(); @@ -262,9 +255,6 @@ bool KillSwitch::enablePeerTraffic(const QJsonObject &configStr) { bool KillSwitch::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterIndex) { #ifdef Q_OS_WIN - if (configStr.value("splitTunnelType").toInt() != 0) { - WindowsFirewall::create(this)->allowAllTraffic(); - } return WindowsFirewall::create(this)->enableInterface(vpnAdapterIndex); #endif @@ -314,14 +304,8 @@ bool KillSwitch::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterIn LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("300.allowLAN"), true); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("310.blockDNS"), true); QStringList dnsServers; - dnsServers.append(configStr.value(amnezia::config_key::dns1).toString()); - - // We don't use secondary DNS if primary DNS is AmneziaDNS - if (!configStr.value(amnezia::config_key::dns1).toString().contains(amnezia::protocols::dns::amneziaDnsIp)) { - dnsServers.append(configStr.value(amnezia::config_key::dns2).toString()); - } - + dnsServers.append(configStr.value(amnezia::config_key::dns2).toString()); dnsServers.append("127.0.0.1"); dnsServers.append("127.0.0.53"); @@ -358,11 +342,7 @@ bool KillSwitch::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterIn QStringList dnsServers; dnsServers.append(configStr.value(amnezia::config_key::dns1).toString()); - - // We don't use secondary DNS if primary DNS is AmneziaDNS - if (!configStr.value(amnezia::config_key::dns1).toString().contains(amnezia::protocols::dns::amneziaDnsIp)) { - dnsServers.append(configStr.value(amnezia::config_key::dns2).toString()); - } + dnsServers.append(configStr.value(amnezia::config_key::dns2).toString()); for (auto dns : configStr.value(amnezia::config_key::allowedDnsServers).toArray()) { if (!dns.isString()) {